以前、「EKS AnywhereをvSphereプロバイダーで利用してみる」というブログ記事を以下に書いたことがあります。
EKS AnywhereにはオプションでGitOpsツールのFluxをセットアップするオプションが用意されていてそれを試してみましたので、 今回はその話題を取り上げたいと思います。
まず必要なものはこちらです。
- GitHubアカウント
- GitHubトークンキー(repoへのアクセス権限。詳細はManage cluster with GitOps)
- 設定ファイルにGitopsオプション関連の設定の追記
一つ一つ設定してみます。
その前にGitOpsとFluxについておさらい
GitOpsはWeaveworksが提唱するCDの手法です。Gitのみを信頼できるソースとして利用して、アプリケーションをクラスターにデプロイするという開発の手法です。 GitOpsを実践するにはいくつかあるGitOpsツールを選んで動かしてみることです。
数あるGitOpsツールの中で今回取り上げるFluxはWeaveworksが開発をした、OSSのGitOpsツールの一つです。
大抵の場合はKubernetesにKubernetes Helmやマニフェストファイルを使ってGitOpsツールを追加する格好をとりますが、EKS Anywhereではセットアップ時にEKS Anywhereのデプロイマニフェストファイルに必要な設定を書いた上でデプロイを実行すると、Fluxも最初からインストールできます。
これのメリットとして、EKS AnywhereによってデプロイされたKubernetes環境のマニフェストもGitで管理され、設定変更やスケールアップ、スケールダウンなどが容易に行えます。
GitHubアカウントとGitHubトークンキーの用意
自分のGitHubアカウント使って、リポジトリーの操作を行うため、GitHubアクセストークンキーの用意が必要です、 Manage cluster with GitOpsに書かれているような設定のアクセストークンを設定します。
このような感じでSSHキーペアを作成して、GitHubにSSH公開鍵を登録しておきます。
% ssh-keygen -t ecdsa -C "my_email@example.com"
これをGitHubアカウントのSSH公開鍵として登録します。
以上です。
管理用のマシンにDockerをインストール
前回のブログではあまり詳しく説明していませんでしたが、EKS Anywhereの管理用クライアントではDockerのインストールとサービスの起動が必要です。 Docker自体はbootstrapの実行に一時的に必要であるようです。クラスターができたら一時的に作られたコンテナーは削除されるようです。
設定ファイルにGitopsオプション関連の設定の追記
デプロイ用のマニフェストファイルにGitOpsオプションが必要な点、環境変数EKSA_GITHUB_TOKEN
でトークンキーの設定が必要です。
デプロイの時と削除の時にこの環境変数が必要であるため、次のようにスクリプトファイルとして作成しておくほうが良いと思います。
% cat eksa-env.sh #!/bin/bash export EKSA_VSPHERE_USERNAME='administrator@vsphere.local' export EKSA_VSPHERE_PASSWORD='hogehuga5656' export EKSA_GITHUB_TOKEN=ghp_hogehugg
次にマニフェストファイルを編集します。gitOpsRefをspec行に追加して、最後あたりにkind: GitOpsConfig
の設定を追加します。
その他のオプションについては今回は省略します。
apiVersion: anywhere.eks.amazonaws.com/v1alpha1 kind: Cluster metadata: name: prod spec: clusterNetwork: cniConfig: cilium: {} pods: cidrBlocks: - 192.168.0.0/16 services: cidrBlocks: - 10.96.0.0/12 ... gitOpsRef: #追加行 kind: GitOpsConfig #追加行 name: eksacl #追加行 --- apiVersion: anywhere.eks.amazonaws.com/v1alpha1 kind: GitOpsConfig metadata: name: eksacl spec: flux: github: branch: main clusterConfigPath: clusters/eksacl fluxSystemNamespace: flux-system owner: githubuser #GitHubユーザー名 personal: true repository: eksagitops
設定が終わったらスクリプトによって環境変数を読み込み、クラスターのデプロイを実行します。
% source eksa-env.sh && eksctl anywhere create cluster -f eksa-cluster.yaml
デプロイを実行すると、次のような出力があります。
Checking Github Access Token permissions ✅ Github personal access token has the required repo permissions Performing setup and validations Warning: VSphereDatacenterConfig configured in insecure mode ✅ Connected to server ✅ Authenticated to vSphere ✅ Datacenter validated ✅ Network validated Creating template. This might take a while. ✅ Datastore validated ✅ Folder validated ✅ Resource pool validated ✅ Datastore validated ✅ Folder validated ✅ Resource pool validated ✅ Datastore validated ✅ Folder validated ✅ Resource pool validated ✅ Control plane and Workload templates validated ✅ Vsphere Provider setup is valid ✅ Flux path ✅ Validate certificate for registry mirror ✅ Create preflight validations pass Creating new bootstrap cluster Provider specific pre-capi-install-setup on bootstrap cluster Installing cluster-api providers on bootstrap cluster Provider specific post-setup Creating new workload cluster Installing networking on workload cluster Installing storage class on cluster Installing cluster-api providers on workload cluster Installing EKS-A secrets on workload cluster Moving cluster management from bootstrap to workload cluster Installing EKS-A custom components (CRD and controller) on workload cluster Installing EKS-D components on workload cluster Creating EKS-A CRDs instances on workload cluster Installing AddonManager and GitOps Toolkit on workload cluster Finalized commit and committed to local repository {"hash": "snip"} Adding cluster configuration files to Git Finalized commit and committed to local repository {"hash": "snip"} Writing cluster config file Deleting bootstrap cluster 🎉 Cluster created!
GitHubにログインすると、eksagitopsのようなGitリポジトリーが自分のアカウントに追加されていると思います。 flux-systemとprod/eksa-systemというディレクトリーがリポジトリーに作られています。
このリポジトリーに登録されているファイルは、管理用のマシンのホームディレクトリーの中身と一緒です(流石にkubeconfigは含まれていません)。
これで、GitOpsツールであるFluxにより、このEKS AnywhereのKubernetesクラスターが管理されたことになります。
動作確認
念の為、動作確認をしましょう。 まず、kubeconfigを読み込みます。
% export KUBECONFIG=~/prod/prod-eks-a-cluster.kubeconfig
次にノードの確認。
% kubectl get no NAME STATUS ROLES AGE VERSION 172-16-5-128.local.virtualtech.jp Ready <none> 52m v1.22.6-eks-b18cdc9 172-16-5-38.local.virtualtech.jp Ready control-plane,master 56m v1.22.6-eks-b18cdc9 172-16-5-46.local.virtualtech.jp Ready <none> 53m v1.22.6-eks-b18cdc9 172-16-6-218.local.virtualtech.jp Ready control-plane,master 53m v1.22.6-eks-b18cdc9
GitOpsツールが動いていることを確認します。
% kubectl get pod -n flux-system NAME READY STATUS RESTARTS AGE helm-controller-5f44848d46-qhzpw 1/1 Running 0 57m kustomize-controller-67c64964fd-pbqxk 1/1 Running 0 57m notification-controller-55d8568f4-7pblk 1/1 Running 0 57m source-controller-d64cbf95c-fvdzj 1/1 Running 0 57m
「GitOps」を試してみる
とりあえずKubernetes環境とGitOpsツール Fluxの導入は完了していますので、簡単に「GitOps」を試してみましょう。
それにはまず、開発用のクライアントで、作成されたGitHubリポジトリーをクローンします。 当然ながら、クライアントにはgitコマンドがインストールされており、次のコマンドでsshでGitHubにアクセスできるような設定が必要です。
こちらが参考になります。
https://qiita.com/shizuma/items/2b2f873a0034839e47ce
% ssh -T git@github.com Enter passphrase for key '/Users/ytooyama/.ssh/id_eksa_ecdsa': Hi ytooyama! You've successfully authenticated, but GitHub does not provide shell access.
あとはソースコード一式をクローンし、その中にディレクトリーを作成してコンテナアプリケーションのマニフェストファイルを作成します。
% cd ~/working/github/eksagitops % tree . └── clusters └── eksacl ├── flux-system │ ├── gotk-components.yaml │ ├── gotk-patches.yaml │ ├── gotk-sync.yaml │ └── kustomization.yaml └── prod └── eksa-system ├── eksa-cluster.yaml └── kustomization.yaml 5 directories, 6 files
このディレクトリー配下にGitOpsで管理するアプリケーションのマニフェストファイルを格納するディレクトリーを作って、その中にマニフェストファイルを作成します。
clusters └── eksacl
nginx.yamlサンプル
apiVersion: v1 kind: Namespace metadata: name: test --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: nginx name: nginx namespace: test spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - image: nginx:alpine name: nginx --- apiVersion: v1 kind: Service metadata: name: nginx namespace: test spec: selector: app: nginx type: NodePort ports: - port: 80 targetPort: 80 nodePort: 30080
追加後のディレクトリー構成
% tree . └── clusters └── eksacl ├── flux-system │ ├── gotk-components.yaml │ ├── gotk-patches.yaml │ ├── gotk-sync.yaml │ └── kustomization.yaml ├── prod │ └── eksa-system │ ├── eksa-cluster.yaml │ └── kustomization.yaml └── test └── nginx.yaml 6 directories, 7 files
この状態で、該当のGitリポジトリーにコードをPushします(以下実行例)。
% git add . % git commit -m "Added demo code for gitops" % git push -u origin main
Push後にしばらくすると、クラスター上でそのアプリケーションが実行されます。 設定を変更してさらにPushすると、Git上の変更を基として、Kubernetesクラスターに新しいバージョンのアプリケーションがデプロイされます。
% kubectl get ns test NAME STATUS AGE test Active 111s % kubectl get all -n test NAME READY STATUS RESTARTS AGE pod/nginx-565785f75c-mczss 1/1 Running 0 2m14s pod/nginx-565785f75c-z86ms 1/1 Running 0 2m14s pod/nginx-565785f75c-zw6h2 1/1 Running 0 2m14s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/nginx NodePort 10.99.133.220 <none> 80:30080/TCP 2m14s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/nginx 3/3 3 3 2m14s NAME DESIRED CURRENT READY AGE replicaset.apps/nginx-565785f75c 3 3 3 2m14s
ログを見ると、Deployment/test/nginxとService/test/nginxがFlux監視対象になっていることがわかります。
% kubectl logs kustomize-controller-67c64964fd-pbqxk -n flux-system ... {"level":"info","ts":"2022-05-16T09:56:32.506Z","logger":"controller.kustomization","msg":"server-side apply completed","reconciler group":"kustomize.toolkit.fluxcd.io","reconciler kind":"Kustomization","name":"flux-system","namespace":"flux-system","output":{"Cluster/default/prod":"unchanged","ClusterRole/crd-controller-flux-system":"unchanged","ClusterRoleBinding/cluster-reconciler-flux-system":"unchanged","ClusterRoleBinding/crd-controller-flux-system":"unchanged","Deployment/flux-system/helm-controller":"unchanged","Deployment/flux-system/kustomize-controller":"unchanged","Deployment/flux-system/notification-controller":"unchanged","Deployment/flux-system/source-controller":"unchanged","Deployment/test/nginx":"unchanged","GitOpsConfig/default/eksacl":"unchanged","GitRepository/flux-system/flux-system":"unchanged","Kustomization/flux-system/flux-system":"unchanged","NetworkPolicy/flux-system/allow-egress":"unchanged","NetworkPolicy/flux-system/allow-scraping":"unchanged","NetworkPolicy/flux-system/allow-webhooks":"unchanged","Service/flux-system/notification-controller":"unchanged","Service/flux-system/source-controller":"unchanged","Service/flux-system/webhook-receiver":"unchanged","Service/test/nginx":"unchanged","ServiceAccount/flux-system/helm-controller":"unchanged","ServiceAccount/flux-system/kustomize-controller":"unchanged","ServiceAccount/flux-system/notification-controller":"unchanged","ServiceAccount/flux-system/source-controller":"unchanged","VSphereDatacenterConfig/default/prod":"unchanged","VSphereMachineConfig/default/prod":"unchanged","VSphereMachineConfig/default/prod-cp":"unchanged","VSphereMachineConfig/default/prod-etcd":"unchanged"}} {"level":"info","ts":"2022-05-16T09:56:32.527Z","logger":"controller.kustomization","msg":"Reconciliation finished in 2.466196559s, next run in 10m0s","reconciler group":"kustomize.toolkit.fluxcd.io","reconciler kind":"Kustomization","name":"flux-system","namespace":"flux-system","revision":"main/c7f0fecf009c2823d244b52c45eacd7af49695d3"}
kubectlコマンドを使って、Fluxの動作状況はある程度把握できますが、Flux CLIをインストールしていれば、Gitソース上でコマンドを実行すると、Gitと設定が同期されているかとどのバージョンと同期しているかがわかります。
% cd ~/working/github/eksagitops % flux get kustomizations NAME REVISION SUSPENDED READY MESSAGE flux-system main/c7f0fec False True Applied revision: main/c7f0fec
これで、vSphereプロバイダーのEKS AnywhereでKubernetes + GitOps環境を利用することができるようになりました。