[小ネタ]EKSノードに直接ssm-agentをインストールせず、DaemonSetで動かす方法

2019.03.07

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

やりたい事

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で実際に利用してみます。

  1. EKSを構築する(eksctlなど)
  2. WorkerNodesのインスタンスプロファイルに権限(AWS管理ポリシー: AmazonEC2RoleforSSM)を追加する
  3. 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やこれがなぜ動作しているかという解説を深く行いたかったですが、正直理解が浅すぎて書けず断念しました... 単なるリポジトリ紹介になってしまいましたが、とても便利な仕組みなので誰かの役に立てれば幸いです。