forked from jordanwilson230/kubectl-plugins
-
Notifications
You must be signed in to change notification settings - Fork 0
/
kubectl-ssh
executable file
·116 lines (98 loc) · 3.61 KB
/
kubectl-ssh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#!/usr/bin/env bash
trap 'kubectl delete pod $container >/dev/null 2>&1 &' 0 1 2 3 15
usage() { echo -e "Usage: kubectl ssh <options> <pod name>" && grep " .)\ #" $0; exit 0; }
[ $# -eq 0 ] && usage
while getopts ":u:c:p:h" arg; do
case $arg in
p) # Specify pod name.
POD=${OPTARG}
;;
u) # Specify user
USERNAME=${OPTARG}
;;
c) # Specify container
CONTAINER=${OPTARG}
;;
h) # Display help.
usage
exit 0
;;
-- ) # Optional command to execute. Defaults to /bin/sh
;;
*)
;;
esac
done
COMMAND=$(echo $@ | grep '\-\-' | sed 's|\(.*\) -- \(.*\)|\2|g')
COMMAND="${COMMAND:-/bin/sh}"
if [ -z "$POD" ] && [ -z "$CONTAINER" ] && [ -z "$USERNAME" ]; then
POD="$1"
fi
USERNAME="${USERNAME:-root}"
[ -z $POD ] && echo -e "\nMissing Pod Name" && exit 1
echo -e "\nConnecting...\nPod: ${POD}\nUser: ${USERNAME}\nContainer:$CONTAINER\nCommand:$COMMAND\n"
KUBECTL=$(which kubectl)
# Limits concurrent ssh sessions (each session deploys a pod) to 2. It's not necessary, just a preference.
test "$(exec $KUBECTL get po "$(whoami)-1" 2>/dev/null)" && container="$(whoami)-2" || container="$(whoami)-1"
# We want to mount the docker socket on the node of the pod we're exec'ing into.
NODENAME=$( ${KUBECTL} get pod ${POD} -o go-template='{{.spec.nodeName}}' )
NODESELECTOR='"nodeSelector": {"kubernetes.io/hostname": "'$NODENAME'"},'
# Adds toleration if the target container runs on a tainted node. Assumes no more than one taint. Change if yours have more than one or are configured differently.
TOLERATION_VALUE=$($KUBECTL get pod ${POD} -ojsonpath='{.spec.tolerations[].value}') >/dev/null 2>&1
if [[ "$TOLERATION_VALUE" ]]; then
TOLERATION_KEY=$($KUBECTL get pod ${POD} -ojsonpath='{.spec.tolerations[].key}')
TOLERATION_OPERATOR=$($KUBECTL get pod ${POD} -ojsonpath='{.spec.tolerations[].operator}')
TOLERATION_EFFECT=$($KUBECTL get pod ${POD} -ojsonpath='{.spec.tolerations[].effect}')
TOLERATIONS='"tolerations": [{"effect": "'$TOLERATION_EFFECT'","key": "'$TOLERATION_KEY'","operator": "'$TOLERATION_OPERATOR'","value": "'$TOLERATION_VALUE'"}],'
else
TOLERATIONS=''
fi
if [[ -n ${CONTAINER} ]]; then
DOCKER_CONTAINERID=$( eval $KUBECTL get pod ${POD} -o go-template="'{{ range .status.containerStatuses }}{{ if eq .name \"${CONTAINER}\" }}{{ .containerID }}{{ end }}{{ end }}'" )
else
DOCKER_CONTAINERID=$( $KUBECTL get pod ${POD} -o go-template='{{ (index .status.containerStatuses 0).containerID }}' )
fi
CONTAINERID=${DOCKER_CONTAINERID#*//}
read -r -d '' OVERRIDES <<EOF
{
"apiVersion": "v1",
"spec": {
"containers": [
{
"image": "docker",
"name": "'$container'",
"stdin": true,
"stdinOnce": true,
"tty": true,
"restartPolicy": "Never",
"args": [
"exec",
"-it",
"-u",
"${USERNAME}",
"${CONTAINERID}",
"${COMMAND}"
],
"volumeMounts": [
{
"mountPath": "/var/run/docker.sock",
"name": "docker"
}
]
}
],
$NODESELECTOR
$TOLERATIONS
"volumes": [
{
"name": "docker",
"hostPath": {
"path": "/var/run/docker.sock",
"type": "File"
}
}
]
}
}
EOF
eval $KUBECTL run -it --restart=Never --image=docker --overrides="'${OVERRIDES}'" $container