kubernetesでsshできるpodを作る
普段自分は機械学習の研究用途でkubernetes (k8s)上のクラスターでjupyterlabを立ててそこでコーディングをしています。
なんですが、jupyterlabだと補完がいまいちだったり、pyファイルの編集においては補完が全く効かなかったりで何かいい方法はないか模索していたんですが、最近VSCodeでremote serverに接続して開発できる機能が追加されました。
この機能を使うことで、リモートのサーバにsshしてファイルを編集できますし、pythonのインタープリタもサーバの環境を使えます。
つまり、dockerで機械学習・ディープラーニング用の環境を作ってGPUが乗ったサーバでコンテナを立ててしまえば、Pytorchやkerasの補完がモリモリ効いたままコーディングができて実行もすぐできて超絶便利になりそうです。
単なるDockerでsshできるコンテナを建てることは簡単なんですが、Kubernetes上でやろうとすると少しハマったのでその備忘録を残しておきます。
ちなみに、単なるDockerでsshできるコンテナを建てるには以下の方法で簡単にできます。
上記と同様のパスワード認証の方法でk8sにpodを立ててsshしようとしてもPermission Deny(Publickey, password)でアクセスできませんでした。
いろいろ調査したところ、鍵認証の方法ならsshに成功しました。
基本的なやり方は下記と同じです。
GitHub - ruediste/docker-sshd: Dockerized SSH server prepared for Kubernetes
まず、下記のようなDockerfileでssh用imageを作って適当なrepositoryにpush しておきます。
FROM ubuntu:16.04 RUN apt-get update RUN apt-get install -y openssh-server RUN mkdir /var/run/sshd RUN apt-get install -y less curl iputils-ping RUN sed -ri 's/^PermitRootLogin\s+.*/PermitRootLogin yes/' /etc/ssh/sshd_config \ && sed -ri 's/UsePAM yes/#UsePAM yes/g' /etc/ssh/sshd_config \ && sed -ri 's/^StrictModes\s+.*/StrictModes no/' /etc/ssh/sshd_config \ && sed -ri 's/HostKey \/etc\/ssh\//HostKey \/etc\/ssh\/hostKeys\//g' /etc/ssh/sshd_config \ && echo "PasswordAuthentication no" >> /etc/ssh/sshd_config \ && echo "GatewayPorts yes" >> /etc/ssh/sshd_config RUN rm /etc/ssh/ssh_host* EXPOSE 22 CMD ["/usr/sbin/sshd", "-De"]
次に、ホスト鍵関連のファイルを生成するgenerateHostKeys.shのようなシェルスクリプトを作って実行します。
#!/bin/bash rm -rf hostKeys mkdir hostKeys ssh-keygen -q -t rsa -f hostKeys/ssh_host_rsa_key -N "" -C "" ssh-keygen -q -t dsa -f hostKeys/ssh_host_dsa_key -N "" -C "" ssh-keygen -q -t ecdsa -f hostKeys/ssh_host_ecdsa_key -N "" -C "" ssh-keygen -q -t ed25519 -f hostKeys/ssh_host_ed25519_key -N "" -C "" kubectl --namespace default delete secret ssh-host-keys kubectl --namespace default create secret generic ssh-host-keys \ --from-file=hostKeys/ssh_host_rsa_key \ --from-file=hostKeys/ssh_host_rsa_key.pub \ --from-file=hostKeys/ssh_host_dsa_key \ --from-file=hostKeys/ssh_host_dsa_key.pub \ --from-file=hostKeys/ssh_host_ecdsa_key \ --from-file=hostKeys/ssh_host_ecdsa_key.pub \ --from-file=hostKeys/ssh_host_ed25519_key \ --from-file=hostKeys/ssh_host_ed25519_key.pub
また、ユーザ認証用の公開鍵をauthorized_keysとして保存しておきます。
次に、先ほどつくったホスト鍵ファイルたちとauthorized_keysをk8s上でセキュアに扱うためにSecretsを使います。
k8sのSecretsに関しては下記のサイトがわかりやすかったです。
上で作ったファイルたちをSecretsとして登録するUpdateKeys.shを作って実行します。
#!/bin/sh # Update the keys stored in ssh.yaml from the authorized-keys file kubectl --namespace default delete secret ssh-keys kubectl --namespace default create secret generic ssh-keys --from-file=./authorized_keys
あとはk8sでsshサーバを立てるマニフェストを書いて下記の設定を追加した上でpodを立ててあげればOKです。
volumeMounts: - mountPath: /root/.ssh/ name: ssh-dir - mountPath: /etc/ssh/hostKeys/ name: ssh-host-keys volumes: - name: ssh-dir secret: secretName: ssh-keys defaultMode: 0600 - name: ssh-host-keys secret: secretName: ssh-host-keys defaultMode: 0600
あとは普通にsshできます。
$ ssh root@<PodのIPアドレス>