k8s開啟臨時容器進(jìn)行debug
工作中在調(diào)試集群中未包含bash sh等工具的pod往往比較麻煩,k8s提供了一個臨時容器供我們添加到要調(diào)試的pod中進(jìn)行工作。
什么是臨時容器?
臨時容器與其他容器的不同之處在于,它們?nèi)鄙賹Y源或執(zhí)行的保證,并且永遠(yuǎn)不會自動重啟, 因此不適用于構(gòu)建應(yīng)用程序。臨時容器使用與常規(guī)容器相同的 ContainerSpec 節(jié)來描述,但許多字段是不兼容和不允許的。
臨時容器沒有端口配置,因此像 ports,livenessProbe,readinessProbe這樣的字段是不允許的。Pod 資源分配是不可變的,因此 resources配置是不允許的。有關(guān)允許字段的完整列表,請參見 EphemeralContainer 參考文檔。
臨時容器是使用 API 中的一種特殊的 ephemeralcontainers 處理器進(jìn)行創(chuàng)建的, 而不是直接添加到 pod.spec 段,因此無法使用 kubectl edit 來添加一個臨時容器。
與常規(guī)容器一樣,將臨時容器添加到 Pod 后,將不能更改或刪除臨時容器。
使用臨時容器需要開啟 EphemeralContainers 特性門控, kubectl 版本為 v1.18 或者更高。
開啟EphemeralContainers
本次操作使用k8s版本:1.20.9
master節(jié)點上操作
修改apiserver
編輯/etc/kubernetes/manifests/kube-apiserver.yaml
將--feature-gates=TTLAfterFinished=true修改為--feature-gates=TTLAfterFinished=true,EphemeralContainers=true
修改controller-manager
編輯/etc/kubernetes/manifests/kube-controller-manager.yaml
將--feature-gates=TTLAfterFinished=true修改為--feature-gates=TTLAfterFinished=true,EphemeralContainers=true
修改kube-scheduler
編輯/etc/kubernetes/manifests/kube-scheduler.yaml
將--feature-gates=TTLAfterFinished=true修改為--feature-gates=TTLAfterFinished=true,EphemeralContainers=true
所以節(jié)點上操作
修改kubelet
編輯/var/lib/kubelet/kubeadm-flags.env
添加--feature-gates=EphemeralContainers=true
修改后如下
KUBELET_KUBEADM_ARGS="--cgroup-driver=systemd?--network-plugin=cni?--pod-infra-container-image=k8s.gcr.io/pause:3.2?--feature-gates=EphemeralContainers=true"
重啟kubelet
systemctl?daemon-reload
systemctl?restat?kubelet?
驗證
如下,我們創(chuàng)建了一個pod,pod中運(yùn)行的鏡像不包含任何調(diào)試程序 ,我們無法進(jìn)入調(diào)試
[root@master-01?kubectl-debug]#?kubectl?run?ephemeral-demo?--image=k8s.gcr.io/pause:3.2?--restart=Never
pod/ephemeral-demo?created
[root@master-01?kubectl-debug]#?kubectl??get?pod?
NAME???????????????????????????????READY???STATUS????RESTARTS???AGE
check-ecs-price-7cdc97b997-khvg2???1/1?????Running???1??????????3h42m
ephemeral-demo?????????????????????1/1?????Running???0??????????5s
go-7c9c5496fb-dbrv5????????????????1/1?????Running???0??????????18m
web-show-768dd97986-nrg9t??????????1/1?????Running???0??????????3h42m
[root@master-01?kubectl-debug]#?kubectl??get?pod?ephemeral-demo???-o?json|jq?.spec
{
??"containers":?[
????{
??????"image":?"k8s.gcr.io/pause:3.2",
??????"imagePullPolicy":?"IfNotPresent",
??????"name":?"ephemeral-demo",
??????"resources":?{},
??????"terminationMessagePath":?"/dev/termination-log",
??????"terminationMessagePolicy":?"File",
??????"volumeMounts":?[
????????{
??????????"mountPath":?"/var/run/secrets/kubernetes.io/serviceaccount",
??????????"name":?"default-token-4jhw7",
??????????"readOnly":?true
????????}
??????]
????}
??],
??"dnsPolicy":?"ClusterFirst",
??"enableServiceLinks":?true,
??"nodeName":?"node-02",
??"preemptionPolicy":?"PreemptLowerPriority",
??"priority":?0,
??"restartPolicy":?"Never",
??"schedulerName":?"default-scheduler",
??"securityContext":?{},
??"serviceAccount":?"default",
??"serviceAccountName":?"default",
??"terminationGracePeriodSeconds":?30,
??"tolerations":?[
????{
??????"effect":?"NoExecute",
??????"key":?"node.kubernetes.io/not-ready",
??????"operator":?"Exists",
??????"tolerationSeconds":?300
????},
????{
??????"effect":?"NoExecute",
??????"key":?"node.kubernetes.io/unreachable",
??????"operator":?"Exists",
??????"tolerationSeconds":?300
????}
??],
??"volumes":?[
????{
??????"name":?"default-token-4jhw7",
??????"secret":?{
????????"defaultMode":?420,
????????"secretName":?"default-token-4jhw7"
??????}
????}
??]
}
[root@master-01?kubectl-debug]#?kubectl??exec?-it?ephemeral-demo??--?sh
OCI?runtime?exec?failed:?exec?failed:?container_linux.go:380:?starting?container?process?caused:?exec:?"sh":?executable?file?not?found?in?$PATH:?unknown
command?terminated?with?exit?code?126
[root@master-01?kubectl-debug]#?kubectl??exec?-it?ephemeral-demo??--?bash
OCI?runtime?exec?failed:?exec?failed:?container_linux.go:380:?starting?container?process?caused:?exec:?"bash":?executable?file?not?found?in?$PATH:?unknown
command?terminated?with?exit?code?126
我們創(chuàng)建一個臨時容器添加到這個pod里
加上-i參數(shù)將直接進(jìn)入添加的臨時容器的控制臺界面,因為是使用kubectl run 創(chuàng)建的pod ,所以需要-target 參數(shù)指定另一個容器的進(jìn)程命名空間。因為 kubectl run 不能在它創(chuàng)建的pod中啟用 共享進(jìn)程命名空間。
[root@master-01?kubectl-debug]#?kubectl?debug?-it?ephemeral-demo?--image=busybox?--target=ephemeral-demo
Defaulting?debug?container?name?to?debugger-nkrn9.
If?you?don't?see?a?command?prompt,?try?pressing?enter.
/?#?ls
bin???dev???etc???home??proc??root??sys???tmp???usr???var
/?#?
我們此時再去看pod 的信息會發(fā)現(xiàn)已經(jīng)被添加了一個類型為ephemeralContainers的容器
[root@master-01?kubernetes]#?kubectl??get?pod?ephemeral-demo???-o?json|jq?.spec
{
??"containers":?[
????{
??????"image":?"k8s.gcr.io/pause:3.2",
??????"imagePullPolicy":?"IfNotPresent",
??????"name":?"ephemeral-demo",
??????"resources":?{},
??????"terminationMessagePath":?"/dev/termination-log",
??????"terminationMessagePolicy":?"File",
??????"volumeMounts":?[
????????{
??????????"mountPath":?"/var/run/secrets/kubernetes.io/serviceaccount",
??????????"name":?"default-token-4jhw7",
??????????"readOnly":?true
????????}
??????]
????}
??],
??"dnsPolicy":?"ClusterFirst",
??"enableServiceLinks":?true,
??"ephemeralContainers":?[
????{
??????"image":?"busybox",
??????"imagePullPolicy":?"Always",
??????"name":?"debugger-nkrn9",
??????"resources":?{},
??????"stdin":?true,
??????"targetContainerName":?"ephemeral-demo",
??????"terminationMessagePath":?"/dev/termination-log",
??????"terminationMessagePolicy":?"File",
??????"tty":?true
????}
??],
??"nodeName":?"node-02",
??"preemptionPolicy":?"PreemptLowerPriority",
??"priority":?0,
??"restartPolicy":?"Never",
??"schedulerName":?"default-scheduler",
??"securityContext":?{},
??"serviceAccount":?"default",
??"serviceAccountName":?"default",
??"terminationGracePeriodSeconds":?30,
??"tolerations":?[
????{
??????"effect":?"NoExecute",
??????"key":?"node.kubernetes.io/not-ready",
??????"operator":?"Exists",
??????"tolerationSeconds":?300
????},
????{
??????"effect":?"NoExecute",
??????"key":?"node.kubernetes.io/unreachable",
??????"operator":?"Exists",
??????"tolerationSeconds":?300
????}
??],
??"volumes":?[
????{
??????"name":?"default-token-4jhw7",
??????"secret":?{
????????"defaultMode":?420,
????????"secretName":?"default-token-4jhw7"
??????}
????}
??]
}
創(chuàng)建pod的副本進(jìn)行調(diào)試
有些時候 Pod 的配置參數(shù)使得在某些情況下很難執(zhí)行故障排查。例如,在容器鏡像中不包含 shell 或者你的應(yīng)用程序在啟動時崩潰的情況下, 就不能通過運(yùn)行 kubectl exec 來排查容器故障。在這些情況下,你可以使用 kubectl debug 來創(chuàng)建 Pod 的副本,通過更改配置幫助調(diào)試。
例如我們以go-7c9c5496fb-dbrv5這個pod 為基礎(chǔ)復(fù)制了一個名為myapp-debug的pod 并添加了一個臨時容器nginx
[root@master-01?kubernetes]#?kubectl??get?pod?
NAME???????????????????????????????READY???STATUS????RESTARTS???AGE
check-ecs-price-7cdc97b997-khvg2???1/1?????Running???1??????????3h53m
go-7c9c5496fb-dbrv5????????????????1/1?????Running???0??????????29m
web-show-768dd97986-nrg9t??????????1/1?????Running???0??????????3h53m
[root@master-01?kubernetes]#?kubectl??debug?go-7c9c5496fb-dbrv5??--image=nginx?--share-processes?--copy-to=myapp-debug
Defaulting?debug?container?name?to?debugger-67hrx.
[root@master-01?kubernetes]#?kubectl??exec?-it?myapp-debug?-c?debugger-67hrx??--?bash?
root@myapp-debug:/#?ls
bin??boot??dev??docker-entrypoint.d??docker-entrypoint.sh??etc??home??lib??lib64??media??mnt??opt??proc??root??run??sbin??srv??sys??tmp??usr??var
root@myapp-debug:/#?cat?/etc/nginx/
conf.d/?????????fastcgi_params??mime.types??????modules/????????nginx.conf??????scgi_params?????uwsgi_params????
root@myapp-debug:/#?ls?/etc/nginx/??
conf.d??fastcgi_params??mime.types??modules??nginx.conf??scgi_params??uwsgi_param
故障
如果執(zhí)行kubectl debug xxx出現(xiàn)如下,則是未成功開啟ephemeralContainers特性
error:?ephemeral?containers?are?disabled?for?this?cluster?(error?from?server:?"the?server?could?not?find?the?requested?resource").
