GitHub Actions で EKS を触る

GitHub Actions で EKS を触ることのできる kubectl をセットアップします。

kubectl だけほしい

github actions kubectl」などのワードで検索すると、「Azure がどうのこうの」「個人が作った Docker な GitHub Actions」といったページがヒットします。もちろん後者が悪いわけではないのですが、kubectl がほしいだけなのに、Docker イメージになっているのはちょっとオーバースペックです。かといって、自分でアクションを作るのは手間ですし、「見つけ切れていないだけでなんかあるんじゃないか」と不安になります。

というわけで、azure/setup-kubectl アクションを使います。「あれ?Azure じゃん」と思われがちですが、このアクションは正真正銘の「kubectl をセットアップするだけのアクション」です。

  • 手軽
  • 余計なものが入らない
  • 認証済みプロバイダによる公開 (Microsoft)

といったメリットが挙げられます。

使い方

https://github.com/Azure/setup-kubectl

README に記載されているままですが、アクションに

- uses: azure/setup-kubectl@v1

を追加するだけです。これでこのステップ以降にて kubectl が使えるようになりました。

EKS との連携

ただし、もちろんこのままでは EKS に接続ができません。EKS に接続できる kubeconfig (.kube/config) を食わせる必要があります。

最近の aws-cli で EKS の設定を行った (aws eks update-kubeconfig) 場合、kubeconfig の users はだいたい下記のようになっているはずです。

- name: arn:aws:eks:ap-northeast-1:XXXXX:cluster/XXX
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1alpha1
      args:
      - --region
      - ap-northeast-1
      - eks
      - get-token
      - --cluster-name
      - XXX
      command: aws

一昔前のやり方だと aws-iam-authenticator を使う (command: aws-iam-authenticator になっている) ようになっているので、その場合は aws-cli をアップデートして再度 update-kubeconfig するか、GitHub Actions 上で aws-iam-authenticator をセットアップする必要があります。

この kubeconfig を GitHub リポジトリの Secrets に登録します。名前は KUBE_CONFIG_DATA としておきます (なんでもいいです)。kubeconfig はテキストファイルですが、ファイルをそのまま Secrets に置くという意味では base64 エンコードするべきですので、

cat .kube/config | base64 --encode

この結果を Secrets の値として入れておきます。

さて、この kubeconfig は aws コマンド (aws-cli) を必要とします。これを使うためのアクションは AWS 公式に用意されています。

- uses: aws-actions/configure-aws-credentials@v1
  with:
    aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
    aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
    aws-region: ap-northeast-1

これで aws configure が完了した状態で aws コマンドが使用できます。

そして、リポジトリ Secrets の AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY に、EKS にアクセスできる IAM ユーザーを入れておきます。

kubectl が Secrets 内の kubeconfig を使えるようにファイルに書き出し、ファイルパスを環境変数 KUBECONFIG にて設定します。そうすると EKS に接続できる kubectl が使えるようになります。

- env:
    KUBE_CONFIG_DATA: ${{ secrets.KUBE_CONFIG_DATA }}
  run: |
    echo "$KUBE_CONFIG_DATA" | base64 --decode > /tmp/kube_config
    export KUBECONFIG=/tmp/kube_config
    kubectl get pods

うまくいっていればポッドの一覧が出力されます。

もちろん、実際に運用するときは、CI 専用の IAM ユーザー/ロールを作り、対応する Kubernetes RBAC を割り当てる必要があります。

完成形

最小限のワークフローはこんな感じになります。

name: CI

on:
  - push

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ap-northeast-1

      - name: Install kubectl
        uses: azure/setup-kubectl@v1

      - name: Run kubectl
        env:
          KUBE_CONFIG_DATA: ${{ secrets.KUBE_CONFIG_DATA }}
        run: |
          echo "$KUBE_CONFIG_DATA" | base64 --decode > /tmp/kube_config
          export KUBECONFIG=/tmp/kube_config
          kubectl get pods