From bfa4119425152e9883dc0e139830ff0c0fb35a34 Mon Sep 17 00:00:00 2001 From: Andrei Kvapil Date: Wed, 16 Aug 2023 23:11:06 +0200 Subject: [PATCH] Add X-mode for debugging minimal systens (#51) Signed-off-by: Andrei Kvapil --- README.md | 37 +++++++++++++++++++++++++++++++++++++ kubectl-node_shell | 33 +++++++++++++++++++++++++++------ 2 files changed, 64 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 855afc1..f4c3b4f 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,9 @@ sudo mv ./kubectl-node_shell /usr/local/bin/kubectl-node_shell # Get standard bash shell kubectl node-shell +# Use X-mode (mount /host, and do not enter host namespace) +kubectl node-shell -x + # Execute custom command kubectl node-shell -- echo 123 @@ -38,4 +41,38 @@ cat /etc/passwd | kubectl node-shell -- sh -c 'cat > /tmp/passwd' kubectl node-shell -- sh -c 'cat /tmp/passwd; rm -f /tmp/passwd' ``` +## X-mode + +X-mode can be useful for debugging minimal systems that do not have a built-in shell (eg. Talos). +Here's an example of how you can debug the network for a rootless kube-apiserver container without a filesystem: + +```bash +kubectl node-shell -x + +# Download crictl +wget https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.28.0/crictl-v1.28.0-linux-amd64.tar.gz -O- | \ + tar -xzf- -C /usr/local/bin/ + +# Setup CRI endpoint +export CONTAINER_RUNTIME_ENDPOINT=unix:///host/run/containerd/containerd.sock + +# Find your container +crictl ps | grep kube-apiserver +#3ff4626a9f10e e7972205b6614 6 hours ago Running kube-apiserver 0 215107b47bd7e kube-apiserver-talos-rzq-nkg + +# Find pid of the container +crictl inspect 3ff4626a9f10e | grep pid +# "pid": 2152, +# "pid": 1 +# "type": "pid" +# "getpid", +# "getppid", +# "pidfd_open", +# "pidfd_send_signal", +# "waitpid", + +# Go to network namespace of the pid, but keep mount namespace of the debug container +nsenter -t 2152 -n +``` + *You need to be able to start privileged containers for that.* diff --git a/kubectl-node_shell b/kubectl-node_shell index 3739adf..be488f0 100755 --- a/kubectl-node_shell +++ b/kubectl-node_shell @@ -2,13 +2,16 @@ set -e kubectl=kubectl -version=1.7.0 +version=1.8.0 generator="" node="" nodefaultctx=0 nodefaultns=0 container_cpu="${KUBECTL_NODE_SHELL_POD_CPU:-100m}" container_memory="${KUBECTL_NODE_SHELL_POD_MEMORY:-256Mi}" +volumes="[]" +volume_mounts="[]" +x_mode=0 labels="${KUBECTL_NODE_SHELL_LABELS}" if [ -t 0 ]; then @@ -55,6 +58,12 @@ while [ $# -gt 0 ]; do kubectl="$kubectl --namespace=${key##*=}" shift ;; + -x) + x_mode=1 + volumes='[{"hostPath":{"path":"/","type":""},"name":"host-root"}]' + volume_mounts='[{"mountPath":"/host","name":"host-root"}]' + shift + ;; --) shift break @@ -106,16 +115,26 @@ fi # Build the container command if [ $# -gt 0 ]; then - cmd="[ $cmd_start $cmd_arg_prefix" + if [ "$x_mode" -eq 1 ]; then + cmd='[' + else + cmd="[ $cmd_start $cmd_arg_prefix," + fi + c="" while [ $# -gt 0 ]; do - cmd="$cmd, \"$(echo "$1" | \ + cmd="${cmd}${c} \"$(echo "$1" | \ awk '{gsub(/["\\]/,"\\\\&");gsub(/\x1b/,"\\u001b");printf "%s",last;last=$0"\\n"} END{print $0}' \ )\"" + c=, shift done cmd="$cmd ]" else - cmd="[ $cmd_start $cmd_default ]" + if [ "$x_mode" = 1 ]; then + cmd='null' + else + cmd="[ $cmd_start $cmd_default ]" + fi fi overrides="$( @@ -137,13 +156,15 @@ cat <