Skip to content

Commit 4717bd2

Browse files
authored
Add support for Windows nodes (#45)
1 parent e4e79ee commit 4717bd2

File tree

2 files changed

+45
-40
lines changed

2 files changed

+45
-40
lines changed

Diff for: README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# kubectl node-shell
22
*(formerly known as **kubectl-enter**)*
33

4-
Start a root shell in the node's host OS running.
4+
Start a root shell in the node's host OS running. Uses an alpine pod with nsenter for Linux nodes and a [HostProcess pod](https://kubernetes.io/docs/tasks/configure-pod-container/create-hostprocess-pod/) with PowerShell for Windows nodes.
55

66
![demo](https://gist.githubusercontent.com/kvaps/2e3d77975a844654ec297893e21a0829/raw/c778a8405ff8c686e4e807a97e9721b423e7208f/kubectl-node-shell.gif)
77

Diff for: kubectl-node_shell

+44-39
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@
22
set -e
33

44
kubectl=kubectl
5-
version=1.5.5
5+
version=1.7.0
66
generator=""
77
node=""
88
nodefaultctx=0
99
nodefaultns=0
10-
cmd='[ "nsenter", "--target", "1", "--mount", "--uts", "--ipc", "--net", "--pid", "--"'
10+
container_cpu="${KUBECTL_NODE_SHELL_POD_CPU:-100m}"
11+
container_memory="${KUBECTL_NODE_SHELL_POD_MEMORY:-256Mi}"
12+
labels="${KUBECTL_NODE_SHELL_LABELS}"
13+
1114
if [ -t 0 ]; then
1215
tty=true
1316
else
@@ -68,11 +71,42 @@ while [ $# -gt 0 ]; do
6871
esac
6972
done
7073

74+
if [ -z "$node" ]; then
75+
echo "Please specify node name"
76+
exit 1
77+
fi
78+
7179
# Set the default context and namespace to avoid situations where the user switch them during the build process
7280
[ "$nodefaultctx" = 1 ] || kubectl="$kubectl --context=$(${kubectl} config current-context)"
7381
[ "$nodefaultns" = 1 ] || kubectl="$kubectl --namespace=$(${kubectl} config view --minify --output 'jsonpath={.contexts..namespace}')"
7482

83+
# Check the node and retrieve the node OS label
84+
os="$($kubectl get node $node -o jsonpath="{.metadata.labels.kubernetes\.io/os}" || exit 1)"
85+
86+
# Set pod configuration per operating system
87+
if [ "$os" = "windows" ]; then
88+
image="${KUBECTL_NODE_SHELL_IMAGE_WINDOWS:-mcr.microsoft.com/powershell}"
89+
name="pwsh"
90+
pod="${name}-$(env LC_ALL=C tr -dc a-z0-9 </dev/urandom | head -c 6)"
91+
# pwsh has to be launched via cmd.exe because of how containerd 1.6 handles the mount of the container filesystem
92+
# see https://kubernetes.io/docs/tasks/configure-pod-container/create-hostprocess-pod/#volume-mounts
93+
cmd_start='"cmd.exe", "/c", "%CONTAINER_SANDBOX_MOUNT_POINT%\\Program Files\\PowerShell\\latest\\pwsh.exe", "-nol", "-wd", "C:\\"'
94+
cmd_arg_prefix=', "-Command"'
95+
cmd_default=''
96+
security_context='{"privileged":true,"windowsOptions":{"hostProcess":true,"runAsUserName":"NT AUTHORITY\\SYSTEM"}}'
97+
else # If the OS isn't windows, assume linux
98+
image="${KUBECTL_NODE_SHELL_IMAGE:-docker.io/library/alpine}"
99+
name="nsenter"
100+
pod="${name}-$(env LC_ALL=C tr -dc a-z0-9 </dev/urandom | head -c 6)"
101+
cmd_start='"nsenter", "--target", "1", "--mount", "--uts", "--ipc", "--net", "--pid"'
102+
cmd_arg_prefix=', "--"'
103+
cmd_default=', "bash", "-l"'
104+
security_context='{"privileged":true}'
105+
fi
106+
107+
# Build the container command
75108
if [ $# -gt 0 ]; then
109+
cmd="[ $cmd_start $cmd_arg_prefix"
76110
while [ $# -gt 0 ]; do
77111
cmd="$cmd, \"$(echo "$1" | \
78112
awk '{gsub(/["\\]/,"\\\\&");gsub(/\x1b/,"\\u001b");printf "%s",last;last=$0"\\n"} END{print $0}' \
@@ -81,63 +115,34 @@ if [ $# -gt 0 ]; then
81115
done
82116
cmd="$cmd ]"
83117
else
84-
cmd="$cmd, \"bash\", \"-l\" ]"
85-
fi
86-
87-
if [ -z "$node" ]; then
88-
echo "Please specify node name"
89-
exit 1
118+
cmd="[ $cmd_start $cmd_default ]"
90119
fi
91120

92-
image="${KUBECTL_NODE_SHELL_IMAGE:-docker.io/library/alpine}"
93-
pod="nsenter-$(env LC_ALL=C tr -dc a-z0-9 </dev/urandom | head -c 6)"
94-
95-
# Check the node
96-
$kubectl get node "$node" >/dev/null || exit 1
97-
98-
container_cpu="${KUBECTL_NODE_SHELL_POD_CPU:-100m}"
99-
container_memory="${KUBECTL_NODE_SHELL_POD_MEMORY:-256Mi}"
100-
labels="${KUBECTL_NODE_SHELL_LABELS}"
101-
102121
overrides="$(
103-
cat <<EOT
122+
cat <<EOT
104123
{
105124
"spec": {
106125
"nodeName": "$node",
107126
"hostPID": true,
108127
"hostNetwork": true,
109128
"containers": [
110129
{
111-
"securityContext": {
112-
"privileged": true
113-
},
130+
"securityContext": $security_context,
114131
"image": "$image",
115-
"name": "nsenter",
132+
"name": "$name",
116133
"stdin": true,
117134
"stdinOnce": true,
118135
"tty": $tty,
119136
"command": $cmd,
120137
"resources": {
121-
"limits": {
122-
"cpu": "${container_cpu}",
123-
"memory": "${container_memory}"
124-
},
125-
"requests": {
126-
"cpu": "${container_cpu}",
127-
"memory": "${container_memory}"
128-
}
138+
"limits": { "cpu": "${container_cpu}", "memory": "${container_memory}" },
139+
"requests": { "cpu": "${container_cpu}", "memory": "${container_memory}" }
129140
}
130141
}
131142
],
132143
"tolerations": [
133-
{
134-
"key": "CriticalAddonsOnly",
135-
"operator": "Exists"
136-
},
137-
{
138-
"effect": "NoExecute",
139-
"operator": "Exists"
140-
}
144+
{ "key": "CriticalAddonsOnly", "operator": "Exists" },
145+
{ "effect": "NoExecute", "operator": "Exists" }
141146
]
142147
}
143148
}

0 commit comments

Comments
 (0)