Secure Shell (SSH)
Access your Pod on external networks through SSH on a randomly assigned port at nodeport.icedc.se
.
Example
In this example, we create a
- Pod with Alpine Linux and expose SSH port 22.
- Service that maps this port to a random NodePort.
- Secret that contains the
authorized_key
using ourid_rsa.pub
.
When the Pod starts
- Install
openssh-server
and generate a random host key. - Copy the Secret into
/root/.ssh/authorized_keys
and set permissions - Start
sshd
while logging to standard output.
apiVersion: v1
kind: Pod
metadata:
name: testpod
labels:
app: testapp
spec:
containers:
- name: testssh
image: alpine
ports:
- name: ssh-port
containerPort: 22
command:
- sh
- -c
- |
/bin/sh <<'EOF'
apk update && apk add openssh-server
ssh-keygen -f /etc/ssh/ssh_host_rsa_key -C '' -N '' -t rsa
mkdir -p /root/.ssh
cp /config/authorized_keys /root/.ssh/
chmod -R og-rwx /root/.ssh
/usr/sbin/sshd -eD
EOF
volumeMounts:
- name: config-keys
mountPath: /config
resources:
requests:
memory: "64Mi"
cpu: "100m"
limits:
memory: "64Mi"
volumes:
- name: config-keys
secret:
secretName: testpod-keys
defaultMode: 0400
---
apiVersion: v1
kind: Service
metadata:
name: testpod-ssh
spec:
selector:
app: testapp
type: NodePort
ports:
- name: ssh
port: 22
targetPort: ssh-port
---
apiVersion: v1
kind: Secret
metadata:
name: testpod-keys
type: Opaque
stringData:
authorized_keys: |
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDtcmW6eVcIFSmWOD...
Create the objects
List services in the namespace
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
testpod-ssh NodePort 10.43.199.42 <none> 22:32319/TCP 9s
Here, 32319
is the external port. You can now log in with
Welcome to Alpine!
The Alpine Wiki contains a large amount of how-to guides and general
information about administrating Alpine systems.
See <https://wiki.alpinelinux.org/>.
You can setup the system with the command: setup-alpine
You may change this message by editing /etc/motd.
testpod:~#
SSH configuration
Following are some tips when working with Kubernetes containers over SSH.
Read NodePort number into an environment variable
To automatically parse the NodePort number for your namespace, you can use kubectl
.
Store the name of your namespace in the environment variable $NS
.
Read the NodePort number into the variable $NODEPORT
.
NODEPORT=$(kubectl get svc -n $NS -o go-template='{{range .items}}{{range.spec.ports}}{{if .nodePort}}{{.nodePort}}{{"\n"}}{{end}}{{end}}{{end}}');
You can then use $NODEPORT
in your SSH command.
Local SSH configuration
Store the SSH configuration for nodeport.icedc.se
in ~/.ssh/config
.
Host nodeport.icedc.se
User root
Port 32293
HostName nodeport.icedc.se
StrictHostKeyChecking no
LogLevel=quiet
UserKnownHostsFile=/dev/null
The last three lines are optional. They disable the warning IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
when the host key in ~/.ssh/known_hosts
does not match the host key of the server. Since Kubernetes pods may be restarted at any time, this may become annoying.
Scripted update of NodePort in SSH configuration
You can split your ~/.ssh/config
into multiple files in the folder ~/.ssh/config.d/
.
Update the Port
line in ~/.ssh/config.d/nodeport
with
Then recombine all files into a single ~/.ssh/config
with