Skip to content

Commit f923a9c

Browse files
committed
ADD: add the pod labels configmap in fork mode
1 parent f08222f commit f923a9c

File tree

4 files changed

+127
-25
lines changed

4 files changed

+127
-25
lines changed

README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,12 @@ kubectl debug POD_NAME --agentless
8585
# you can fork a new pod and diagnose the problem in the forked pod
8686
kubectl debug POD_NAME --fork
8787

88+
# in fork mode, if you want to copy pod with labels,you can use kubernetes configMap to set labels
89+
# configmap's data need to be labels key:value
90+
# configMap name use --pod-labels-configmap-name to set, default is kubectl-debug-pod-labels-configmap
91+
# configMap namespace use --pod-labels-configmap-namespace to set, default is default
92+
kubectl debug POD_NAME --fork --pod-labels-configmap-name <k8s_configmap_name> --pod-labels-configmap-namespace <namespace>
93+
8894
# if the node ip is not directly accessible, try port-forward mode
8995
kubectl debug POD_NAME --port-forward --daemonset-ns=kube-system --daemonset-name=debug-agent
9096

@@ -105,6 +111,23 @@ Example:
105111
# https://kubernetes.io/docs/concepts/configuration/secret/
106112
echo -n '{Username: calmkart, Password: calmkart}' > ./registrySecret.txt
107113
kubectl create secret generic kubectl-debug-registry-secret --from-file=./registrySecret.txt
114+
115+
# how to create a pod labels configmap in fork mode
116+
# take the labels <calmkart=calmkart, test=test, app=app> as an example
117+
# refer to the official kubernetes documentation for more ways to create
118+
# https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#create-a-configmap
119+
cat <<EOF >./pod-labels-configmap.yaml
120+
apiVersion: v1
121+
kind: ConfigMap
122+
metadata:
123+
name: kubectl-debug-pod-labels-configmap
124+
namespace: default
125+
data:
126+
test: test
127+
app: app
128+
calmkart: calmkart
129+
EOF
130+
kubectl apply -f ./pod-labels-configmap.yaml
108131
```
109132

110133
* You can configure the default arguments to simplify usage, refer to [Configuration](#configuration)
@@ -177,6 +200,12 @@ command:
177200
# default namspace is default
178201
RegistrySecretName: my-debug-secret
179202
RegistrySecretNamespace: debug
203+
# in fork mode, if you want to copy pod with labels,you can use kubernetes configMap to set labels
204+
# configmap's data need to be labels key:value
205+
# configMap name use --pod-labels-configmap-name to set, default is kubectl-debug-pod-labels-configmap
206+
# configMap namespace use --pod-labels-configmap-namespace to set, default is default
207+
podLabelsConfigmapName: my-fork-pod-labels-configmap
208+
podLabelsConfigmapNamespace: debug
180209
```
181210
182211
If the debug-agent is not accessible from host port, it is recommended to set `portForward: true` to using port-forawrd mode.

docs/zh-cn.md

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ sudo mv kubectl-debug /usr/local/bin/
5252
Windows 用户可以从 [release page](https://github.com/aylei/kubectl-debug/releases/tag/v0.1.1) 进行下载并添加到 PATH 中
5353

5454
## (可选) 安装 debug-agent DaemonSet
55-
5655
`kubectl-debug` 包含两部分, 一部分是用户侧的 kubectl 插件, 另一部分是部署在所有 k8s 节点上的 agent(用于启动"新容器", 同时也作为 SPDY 连接的中继). 在 `agentless` 中, `kubectl-debug` 会在 debug 开始时创建 debug-agent Pod, 并在结束后自动清理.
5756

5857
`agentless` 虽然方便, 但会让 debug 的启动速度显著下降, 你可以通过预先安装 debug-agent 的 DaemonSet 来使用 agent 模式, 加快启动速度:
@@ -79,6 +78,12 @@ kubectl debug POD_NAME --agentless
7978
# 假如 Pod 处于 CrashLookBackoff 状态无法连接, 可以复制一个完全相同的 Pod 来进行诊断
8079
kubectl debug POD_NAME --fork
8180

81+
# 当使用fork mode时,如果需要复制出来的pod带有labels,可以通过kubernetes的configMap设置labels
82+
# configMap的data应为labels键值对
83+
# 使用的configMap名通过 --pod-labels-configmap-name 设置,默认为kubectl-debug-pod-labels-configmap
84+
# 使用的configMap命名空间通过 --pod-labels-configmap-namespace 设置,默认为default
85+
kubectl debug POD_NAME --fork --pod-labels-configmap-name <k8s_configmap_name> --pod-labels-configmap-namespace <namespace>
86+
8287
# 假如 Node 没有公网 IP 或无法直接访问(防火墙等原因), 请使用 port-forward 模式
8388
kubectl debug POD_NAME --port-forward --daemonset-ns=kube-system --daemonset-name=debug-agent
8489

@@ -99,6 +104,23 @@ kubectl-debug POD_NAME --image calmkart/netshoot:latest --registry-secret-name <
99104
# https://kubernetes.io/docs/concepts/configuration/secret/
100105
echo -n '{Username: calmkart, Password: calmkart}' > ./registrySecret.txt
101106
kubectl create secret generic kubectl-debug-registry-secret --from-file=./registrySecret.txt
107+
108+
# 怎样创建一个用于fork mode的pod labels configmap
109+
# 以labels为 <calmkart=calmkart, test=test, app=app> 为例
110+
# 更多创建方式可以参考kubernets官方文档
111+
# https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#create-a-configmap
112+
cat <<EOF >./pod-labels-configmap.yaml
113+
apiVersion: v1
114+
kind: ConfigMap
115+
metadata:
116+
name: kubectl-debug-pod-labels-configmap
117+
namespace: default
118+
data:
119+
test: test
120+
app: app
121+
calmkart: calmkart
122+
EOF
123+
kubectl apply -f ./pod-labels-configmap.yaml
102124
```
103125

104126
# 构建项目
@@ -168,6 +190,12 @@ command:
168190
# 默认RegistrySecretName为kubectl-debug-registry-secret,默认RegistrySecretNamespace为default
169191
RegistrySecretName: my-debug-secret
170192
RegistrySecretNamespace: debug
193+
# 当使用fork mode时,如果需要复制出来的pod带有labels,可以通过kubernetes的configMap设置labels
194+
# configMap的data应为labels键值对
195+
# 使用的configMap名通过 --pod-labels-configmap-name 设置,默认为kubectl-debug-pod-labels-configmap
196+
# 使用的configMap命名空间通过 --pod-labels-configmap-namespace 设置,默认为default
197+
podLabelsConfigmapName: my-fork-pod-labels-configmap
198+
podLabelsConfigmapNamespace: debug
171199
```
172200
173201
> `kubectl-debug` 会将容器的 entrypoint 直接覆盖掉, 这是为了避免在 debug 时不小心启动非 shell 进程.

pkg/plugin/cmd.go

Lines changed: 55 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ You may set default configuration such as image and command in the config file,
7777

7878
defaultRegistrySecretName = "kubectl-debug-registry-secret"
7979
defaultRegistrySecretNamespace = "default"
80+
81+
defaultPodLabelsConfigMapName = "kubectl-debug-pod-labels-configmap"
82+
defaultPodLabelsConfigMapNamespace = "default"
8083
)
8184

8285
// DebugOptions specify how to run debug container in a running pod
@@ -87,15 +90,17 @@ type DebugOptions struct {
8790
PodName string
8891

8992
// Debug options
90-
Image string
91-
RegistrySecretName string
92-
RegistrySecretNamespace string
93-
ContainerName string
94-
Command []string
95-
AgentPort int
96-
AppName string
97-
ConfigLocation string
98-
Fork bool
93+
Image string
94+
RegistrySecretName string
95+
RegistrySecretNamespace string
96+
PodLabelsConfigMapName string
97+
PodLabelsConfigMapNamespace string
98+
ContainerName string
99+
Command []string
100+
AgentPort int
101+
AppName string
102+
ConfigLocation string
103+
Fork bool
99104

100105
//used for agentless mode
101106
AgentLess bool
@@ -164,6 +169,10 @@ func NewDebugCmd(streams genericclioptions.IOStreams) *cobra.Command {
164169
"private registry secret name, default is kubectl-debug-registry-secret")
165170
cmd.Flags().StringVar(&opts.RegistrySecretNamespace, "registry-secret-namespace", "",
166171
"private registry secret namespace, default is default")
172+
cmd.Flags().StringVar(&opts.PodLabelsConfigMapName, "pod-labels-configmap-name", "",
173+
"in fork mode the pod labels configmap name, default is kubectl-debug-pod-labels-configmap")
174+
cmd.Flags().StringVar(&opts.PodLabelsConfigMapNamespace, "pod-labels-configmap-namespace", "",
175+
"in fork mode the pod labels configmap namespaces, default is default")
167176
cmd.Flags().StringVarP(&opts.ContainerName, "container", "c", "",
168177
"Target container to debug, default to the first container in pod")
169178
cmd.Flags().IntVarP(&opts.AgentPort, "port", "p", 0,
@@ -261,6 +270,20 @@ func (o *DebugOptions) Complete(cmd *cobra.Command, args []string, argsLenAtDash
261270
o.RegistrySecretNamespace = defaultRegistrySecretNamespace
262271
}
263272
}
273+
if len(o.PodLabelsConfigMapName) < 1 {
274+
if len(config.PodLabelsConfigMapName) > 0 {
275+
o.PodLabelsConfigMapName = config.PodLabelsConfigMapName
276+
} else {
277+
o.PodLabelsConfigMapName = defaultPodLabelsConfigMapName
278+
}
279+
}
280+
if len(o.PodLabelsConfigMapNamespace) < 1 {
281+
if len(config.PodLabelsConfigMapNamespace) > 0 {
282+
o.PodLabelsConfigMapNamespace = config.PodLabelsConfigMapNamespace
283+
} else {
284+
o.PodLabelsConfigMapNamespace = defaultPodLabelsConfigMapNamespace
285+
}
286+
}
264287
if o.AgentPort < 1 {
265288
if config.AgentPort > 0 {
266289
o.AgentPort = config.AgentPort
@@ -378,7 +401,14 @@ func (o *DebugOptions) Run() error {
378401
// and hack the entry point of the target container with sleep command
379402
// which keeps the container running.
380403
if o.Fork {
381-
pod = copyAndStripPod(pod, containerName)
404+
// build the fork pod labels
405+
podLabels, err := o.buildForkPodLabels()
406+
if err != nil {
407+
o.deleteAgent(agentPod)
408+
return err
409+
}
410+
// copy pod and run
411+
pod = copyAndStripPod(pod, containerName, podLabels)
382412
pod, err = o.launchPod(pod)
383413
if err != nil {
384414
fmt.Fprintf(o.Out, "the ForkedPod is not running, you should check the reason and delete the failed ForkedPod and retry\n")
@@ -591,15 +621,28 @@ func (o *DebugOptions) setupTTY() term.TTY {
591621
return t
592622
}
593623

624+
func (o *DebugOptions) buildForkPodLabels() (map[string]string, error) {
625+
podLabelConfigMap, err := o.CoreClient.ConfigMaps(o.PodLabelsConfigMapNamespace).Get(o.PodLabelsConfigMapName, v1.GetOptions{})
626+
if err != nil {
627+
if errors.IsNotFound(err) {
628+
return nil, nil
629+
} else {
630+
return nil, err
631+
}
632+
} else {
633+
return podLabelConfigMap.Data, nil
634+
}
635+
}
636+
594637
// copyAndStripPod copy the given pod template, strip the probes and labels,
595638
// and replace the entry point
596-
func copyAndStripPod(pod *corev1.Pod, targetContainer string) *corev1.Pod {
639+
func copyAndStripPod(pod *corev1.Pod, targetContainer string, podLabels map[string]string) *corev1.Pod {
597640
copied := &corev1.Pod{
598641
ObjectMeta: *pod.ObjectMeta.DeepCopy(),
599642
Spec: *pod.Spec.DeepCopy(),
600643
}
601644
copied.Name = fmt.Sprintf("%s-%s-debug", pod.Name, uuid.NewUUID())
602-
copied.Labels = nil
645+
copied.Labels = podLabels
603646
copied.Spec.RestartPolicy = corev1.RestartPolicyNever
604647
for i, c := range copied.Spec.Containers {
605648
copied.Spec.Containers[i].LivenessProbe = nil

pkg/plugin/config.go

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,20 @@ type RegistryAuthConfig struct {
1111
Password string `yaml:"password,omitempty"`
1212
}
1313
type Config struct {
14-
AgentPort int `yaml:"agentPort,omitempty"`
15-
Image string `yaml:"image,omitempty"`
16-
RegistrySecretName string `yaml:"registrySecretName,omitempty"`
17-
RegistrySecretNamespace string `yaml:"registrySecretNamespace,omitempty"`
18-
DebugAgentDaemonSet string `yaml:"debugAgentDaemonset,omitempty"`
19-
DebugAgentNamespace string `yaml:"debugAgentNamespace,omitempty"`
20-
Command []string `yaml:"command,omitempty"`
21-
PortForward bool `yaml:"portForward,omitempty"`
22-
Agentless bool `yaml:"agentless,omitempty"`
23-
AgentPodNamePrefix string `yaml:"agentPodNamePrefix,omitempty"`
24-
AgentPodNamespace string `yaml:"agentPodNamespace,omitempty"`
25-
AgentImage string `yaml:"agentImage,omitempty"`
14+
AgentPort int `yaml:"agentPort,omitempty"`
15+
Image string `yaml:"image,omitempty"`
16+
RegistrySecretName string `yaml:"registrySecretName,omitempty"`
17+
RegistrySecretNamespace string `yaml:"registrySecretNamespace,omitempty"`
18+
PodLabelsConfigMapName string `yaml:"podLabelsConfigmapName,omitempty"`
19+
PodLabelsConfigMapNamespace string `yaml:"podLabelsConfigmapNamespace,omitempty"`
20+
DebugAgentDaemonSet string `yaml:"debugAgentDaemonset,omitempty"`
21+
DebugAgentNamespace string `yaml:"debugAgentNamespace,omitempty"`
22+
Command []string `yaml:"command,omitempty"`
23+
PortForward bool `yaml:"portForward,omitempty"`
24+
Agentless bool `yaml:"agentless,omitempty"`
25+
AgentPodNamePrefix string `yaml:"agentPodNamePrefix,omitempty"`
26+
AgentPodNamespace string `yaml:"agentPodNamespace,omitempty"`
27+
AgentImage string `yaml:"agentImage,omitempty"`
2628

2729
// deprecated
2830
AgentPortOld int `yaml:"agent_port,omitempty"`

0 commit comments

Comments
 (0)