[小ネタ]EKSノードに直接ssm-agentをインストールせず、DaemonSetで動かす方法
やりたい事
AWSでECSやEKSを使用している際に、メンテナンスなどの理由でホストにSSH接続したい事があります。
AWS Systems Manager Session Managerという機能があり、これを使うことでSSHを使わずにシェル操作が可能です。
これを使うにはホストにssm-agent
をインストールする必要があります。Amazon Linux 2のAMIはデフォルトでSession Managerに対応したバージョンのssm-agent
がインストールされていましたが、EKS最適化AMI(amazon-eks-node-1.11-v20181210 (ami-063650732b3e8b38c))に含まれているssm-agent
はSession Managerに対応していません。
シンプルに考えれば、EKS最適化AMIをベースにカスタマイズしたAMIを作成すれば良いのですが、できればカスタムAMIの運用は避けたく何か手段を探していました。
解決策
mumoshu/kube-ssm-agent: Secure, access-controlled, and audited terminal sessions to EKS nodes without SSH
上記の素晴らしいリポジトリでコンテナの上でssm-agent
を動かすDockerfile
とk8sのマニフェストファイルが公開されていました!!
EKSで実際に利用してみます。
- EKSを構築する(eksctlなど)
- WorkerNodesのインスタンスプロファイルに権限(AWS管理ポリシー: AmazonEC2RoleforSSM)を追加する
- Daemonsetで
ssm-agent
コンテナを動かす
Daemonsetで展開します。
git clone git@github.com:mumoshu/kube-ssm-agent.git kubectl apply -f daemonset.yaml kubectl get daemonset -w #全ノードでAvailableになるのを待ち、Ctrl + C で抜ける
接続をテストする。 ローカル端末からSession Managerを利用する方法は下記を参考にしてください。 AWS Systems Manager Session Manager for Shell AccessでMacからLinux EC2インスタンスに端末でアクセスする | DevelopersIO
NODE_TAG_NAME='shared-cluster-ng-2a73f2d0-Node' TARGET_ID_1=$(aws ec2 describe-tags \ --filters \ "Name=tag-key,Values=Name" \ "Name=tag-value,Values=${NODE_TAG_NAME}" \ | jq -r '.Tags[].ResourceId' \ | head -n 1) aws ssm start-session --target ${TARGET_ID_1}
削除は下記のコマンドです。GitHubでも案内されていますが、このAgentは常時利用はせず必要な時にだけデプロイするのが安全です。
kubectl delete -f daemonset.yaml
なぜこのような事ができるのか気になり、daemonset.yaml
を確認してみると、dbusやrun
などをマウントする事で実現している事がわかりました。
あとがき
本当はDockerfileやこれがなぜ動作しているかという解説を深く行いたかったですが、正直理解が浅すぎて書けず断念しました... 単なるリポジトリ紹介になってしまいましたが、とても便利な仕組みなので誰かの役に立てれば幸いです。