github.com/sealerio/sealer@v0.11.1-0.20240507115618-f4f89c5853ae/pkg/debug/node.go (about) 1 // Copyright © 2021 Alibaba Group Holding Ltd. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package debug 16 17 import ( 18 "context" 19 "fmt" 20 21 "github.com/pkg/errors" 22 corev1 "k8s.io/api/core/v1" 23 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 24 utilrand "k8s.io/apimachinery/pkg/util/rand" 25 ) 26 27 // DebugNode can debug a node. 28 func (debugger *Debugger) DebugNode(ctx context.Context) (*corev1.Pod, error) { 29 // get the target node object 30 targetNode, err := debugger.kubeClientCorev1.Nodes().Get(ctx, debugger.TargetName, metav1.GetOptions{}) 31 if err != nil { 32 return nil, errors.Wrapf(err, "failed to find the target node %s", debugger.TargetName) 33 } 34 35 if err := debugger.addClusterInfoIntoEnv(ctx); err != nil { 36 return nil, err 37 } 38 39 // add a pod into target node 40 debugPod, err := debugger.debugNodeByPod(ctx, targetNode) 41 if err != nil { 42 return nil, errors.Wrapf(err, "failed to add a pod into node: %s", targetNode.Name) 43 } 44 45 return debugPod, nil 46 } 47 48 // debugNodeByPod runs a pod in target node and use as a debug pod. 49 func (debugger *Debugger) debugNodeByPod(ctx context.Context, node *corev1.Node) (*corev1.Pod, error) { 50 pods := debugger.kubeClientCorev1.Pods(debugger.Namespace) 51 52 debugPod, err := pods.Create(ctx, debugger.generateDebugPod(node.Name), metav1.CreateOptions{}) 53 if err != nil { 54 return nil, err 55 } 56 57 return debugPod, nil 58 } 59 60 // generateDebugPod generates a debug pod that schedules on the specified node. 61 // The generated pod will run in the host PID, Network & IPC namespace, and it will 62 // have the node's filesystem mounted at /hostfs. 63 func (debugger *Debugger) generateDebugPod(nodeName string) *corev1.Pod { 64 cn := PodDebugPrefix 65 if len(debugger.DebugContainerName) > 0 { 66 cn = debugger.DebugContainerName 67 } else { 68 debugger.DebugContainerName = cn 69 } 70 71 pn := fmt.Sprintf("%s-%s-%s", NodeDebugPrefix, nodeName, utilrand.String(7)) 72 73 pod := &corev1.Pod{ 74 ObjectMeta: metav1.ObjectMeta{ 75 Name: pn, 76 }, 77 Spec: corev1.PodSpec{ 78 Containers: []corev1.Container{ 79 { 80 Name: cn, 81 Env: debugger.Env, 82 Image: debugger.Image, 83 ImagePullPolicy: corev1.PullPolicy(debugger.PullPolicy), 84 Stdin: true, 85 TTY: true, 86 TerminationMessagePolicy: corev1.TerminationMessageReadFile, 87 VolumeMounts: []corev1.VolumeMount{ 88 { 89 MountPath: "/hostfs", 90 Name: "host-root", 91 }, 92 }, 93 }, 94 }, 95 HostIPC: true, 96 HostNetwork: true, 97 HostPID: true, 98 NodeName: nodeName, 99 RestartPolicy: corev1.RestartPolicyNever, 100 Volumes: []corev1.Volume{ 101 { 102 Name: "host-root", 103 VolumeSource: corev1.VolumeSource{ 104 HostPath: &corev1.HostPathVolumeSource{Path: "/"}, 105 }, 106 }, 107 }, 108 }, 109 } 110 111 return pod 112 }