【k8s・Kubernetes】Fluxでprivate gtihub repositoryをGKEにデプロイする【CD・GitOps】
内容
GitOpsにてデプロイパイプラインを構築するために、flux(https://fluxcd.io/)を使ってKubernetesへのデプロイを自動化する
対象読者
- fluxやargocdのようなgitopsに興味がある人
- fluxでKubernetesへのdeployを実行したい人
- Kubernetesを触ったことがある人
fluxとは
- KubernetesにてGitOpsを実現できるツール
- gitにmanifestファイルをpushするだけで、そのmanifestファイル通りにKubernetesへのデプロイが行われる
- Kubernetes上でリソースの変更・削除があったとしても、github上のmanifestファイルを正として、githubのmanifestファイルと同じ状態になるようにKubernetesクラスターを自動で修正する(宣言的アプローチ)
- pull型のCDツール
- Kubernetesクラスターの内部でfluxを動作させることにより、Kubernetes側からgithubにアクセスしmanifestファイルを参照する
- push型のCDパイプラインと異なり、Kubernetesへのアクセスキーを外部で保持する必要がないため、セキュリティ的に良い
準備
- Kubernetes Cluster
- github repository
- manifestファイル置き場
- github personal access token(PAT)
- flux cli
を用意します。
Kubernetesクラスターの作成
今回はGKEを使って、Kubernetesクラスターを作成します。
$ gcloud container clusters create-auto flux-demo-cluster --region=us-west1
Clusterにアクセスするためのcredentialsも取得します。
$ gcloud container clusters get-credentials flux-demo-cluster --region us-west1
github repositoryの作成
manifestファイルをpushするgithub repositoryを作成してください。
本記事の解説では以下のrepoで進めます
https://github.com/rara-tan/flux-demo
※本記事では、private repositoryで作成しましたが、publicで作成すると、secretの認証フローは不要になります。
PAT(personal access token)の発行
fluxからgithub repositoryにアクセスするためにPATを発行します。
https://github.com/settings/tokens
ここから新しくTokenをGenerateしてください。(権限は、repoのみチェックすれば大丈夫です。)
Clusterに実行したいmanifestを作成する
fluxでデプロイしたいテストmanifestを先ほど作成したgithub repoに作成します。
$ git clone https://github.com/rara-tan/flux-demo
$ cd flux-demo
$ mkdir manifests
$ touch kustomization.yaml
$ touch deployment.yaml
kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ./deployment.yaml
deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo
spec:
replicas: 1
selector:
matchLabels:
app: demo
template:
metadata:
labels:
app: demo
spec:
containers:
- name: demo
image: nginx
ports:
- containerPort: 80
試しに手元で実行してみます
$ kubectl apply -k manifests
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
demo-74c44f4fbc-z9wkh 1/1 Running 0 30m
正常にPodが作成されています。
このマニフェストファイルの更新をgithubにpushするだけで、Kubernetesクラスターに反映されるようにするのがゴールです。
構成
$ tree
.
└── manifests
├── deployment.yaml
└── kustomization.yaml
Instal the Flux CLI
flux cliが手元のPCにインストールされていない場合は、以下コマンドでインストールしてください。
$ brew install fluxcd/tap/flux
ClusterへのFluxのinstall
FluxはKubernetesクラスター上で動作します、そのため、まずはFluxをKubernetesにinstallします。
Set Environment Variables
先ほど取得したPATとgithub user nameを環境変数に登録します。
$ export GITHUB_TOKEN=<your-token>
$ export GITHUB_USER=<your-username>
そして、Fluxが実行可能かどうかを以下のコマンドで確認します。
$ flux check --pre
► checking prerequisites
✔ Kubernetes 1.23.8-gke.1900 >=1.20.6-0
✔ prerequisites checks passed
prerequisites checks passedと表示されていたら、FluxをKubernetes Clusterにインストールする準備ができている状態です。
※もし表示されない場合は、なにかしらの準備不足のため、もう一度準備の欄を確認してください。
KubernetesクラスターへのFluxのインストールの実行
$ flux bootstrap github \
--owner=$GITHUB_USER \
--repository=flux-demo-infra \
--branch=main \
--path=./manifests \
--personal
上記コマンドにて、flux-demo-infra
というgithub repositoryが自動で作成されます。(このrepoに、fluxの設定をpushしていきます)
fluxの設定
先ほど作成されたflux-demo-infra
repoに対して、fluxで監視したいmanifestファイルを設定していきます。
clone github repository & create source file
git repoをcloneして、fluxの設定ファイルをfluxコマンドで作成してきます。
$ git clone git@github.com:rara-tan/flux-demo-infra.git
$ cd flux-demo-infra
$ flux create source git demo-app \
--url=https://github.com/rara-tan/flux-demo.git \
--branch=main \
--interval=30s \
--export > ./manifests/demo-app-source.yaml
# ./manifests/demo-app-source.yaml ファイルが作成される
$ cat ./manifests/demo-app-source.yaml
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: GitRepository
metadata:
name: demo-app
namespace: flux-system
spec:
interval: 30s
ref:
branch: main
url: https://github.com/rara-tan/flux-demo.git
# https://github.com/rara-tan/flux-demoのmainブランチを30sごとに監視するGitRepositoryリソースを作成するためのyamlファイル
$ git add -A && git commit -m "Add demo-app GitRepository"
$ git push
上記にて、flux-demo-infra
repoにGitRepositoryのmanifestファイルが追加され、fluxによって、demo-app
というGitRepositoryリソースがKubernetes clusterに自動で追加されます。
flux-demo と flux-demo-infra repoがKubernetes clusterのGitRepositoryに登録されている
$ kubectl get GitRepository -n flux-system
NAME URL AGE READY STATUS
demo-app https://github.com/rara-tan/flux-demo.git 1s False failed to checkout and determine revision: unable to clone 'https://github.com/rara-tan/flux-demo.git': authentication required
flux-system ssh://git@github.com/rara-tan/flux-demo-infra 14m True stored artifact for revision 'main/2a751988e6a2f78ce1d4b9d50abcabe28de3cdfb'
※flux-demoの方のrepoは、Kubernetes Clusterからの認証ができていないため、現状はfailしています。(public repoの場合は、Successしますので、次のPATの登録はSkipしてください)
Kubernetes ClusterにPATを登録する
先ほど追加したGitRepositoryに対して、Kubernetes Clusterはアクセスする権限がないため、StatusがFailになっています。そのため、PATをKubernetes ClusterにSecretとして追加します。
$ kubectl create secret generic github-token \
--namespace flux-system \
--from-literal=username="Base64加工したgithub user_name" \
--from-literal=password="Base64加工したPAT"
Secret登録後、manifests/demo-app-source.yaml
に作成したsecretへの参照を追記し、git pushします。
# secretRefを追記
$ vi manifests/demo-app-source.yaml
$ cat manifests/demo-app-source.yaml
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: GitRepository
metadata:
name: demo-app
namespace: flux-system
spec:
interval: 30s
ref:
branch: main
secretRef:
name: github-token
url: https://github.com/rara-tan/flux-demo.git
$ git add -A && git commit -m "Add secretRef"
Secret Refが追加されたことで、manifestファイルを配置しているrepositoryへのアクセスができるようになり、remote repository is empty
という表示に変わりました。(manifestファイルをgithub repoにpushしていないため、emptyになっています)
$ kubectl get gitrepository -n flux-system
NAME URL AGE READY STATUS
demo-app https://github.com/rara-tan/flux-demo.git 59m False failed to checkout and determine revision: unable to clone 'https://github.com/rara-tan/flux-demo.git': remote repository is empty
flux-system ssh://git@github.com/rara-tan/flux-demo-infra 73m True stored artifact for revision 'main/f062c4289742471f34cec87121e599c63f02676b'
kustomizationを作成する
最後に、リリース対象のパスやリリースのためのinterval等を設定するkustomizationを作成するyamlファイルをfluxコマンドで作成し、pushします。
$ flux create kustomization demo-app \
--target-namespace=default \
--source=demo-app \
--path="./manifests" \
--prune=true \
--interval=5m \
--export > ./manifests/demo-app-kustomization.yaml
$ cat manifests/demo-app-kustomization.yaml
---
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
name: demo-app
namespace: flux-system
spec:
interval: 5m0s
path: ./manifests
prune: true
sourceRef:
kind: GitRepository
name: demo-app
targetNamespace: default
$ git add -A && git commit -m "Add demo-app Kustomization"
$ git push
これで、fluxの設定は完了です!
GitOpsで自動デプロイしてみる
fluxの設定が完了したため、flux-demo
repoにmanifestファイルをpushすると、Kubernetes Clusterに自動でリソースがデプロイされます。
試しに、flux-demo repoに準備の際に作成したmanifestファイルのdeploymentのreplicaを3にしてpushしてみます。
flux-demo repo
# replica 1 → 3
$ vi manifests/deployment.yaml
$ cat manifests/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo
spec:
replicas: 3
selector:
matchLabels:
app: demo
template:
metadata:
labels:
app: demo
spec:
containers:
- name: demo
image: nginx
ports:
- containerPort: 80
$ git add -A && git commit -m "Change replica count"
$ git push
git pushから、1分ほど経過すると、Kubernetes ClusterにPodが追加されている(manifestファイルが反映されている)ことがわかるかと思います!
$ rara@MacBook-Pro flux-demo-infra % kubectl get pod
NAME READY STATUS RESTARTS AGE
demo-74c44f4fbc-dwkjx 1/1 Running 0 72m
demo-74c44f4fbc-r8nm9 1/1 Running 0 72m
demo-74c44f4fbc-z9wkh 1/1 Running 0 3h26m
最終的なファイル構成
flux-demo
$ tree
.
└── manifests
├── deployment.yaml
└── kustomization.yaml
flux-demo-infra
$ tree
.
└── manifests
├── demo-app-kustomization.yaml
├── demo-app-source.yaml
└── flux-system
├── gotk-components.yaml
├── gotk-sync.yaml
└── kustomization.yaml
Clean Up
お金がかかってしまうので、Kubernetes Clusterは削除しましょう。
$ gcloud container clusters delete flux-demo-cluster --region us-west1
また、
- manifestファイルを配置したgithub repository
- fluxが自動で作成したgithub repository
- 発行したgithub token
の削除も忘れずに実行してください。
note
勉強法やキャリア構築法など、エンジニアに役立つ記事をnoteで配信しています。
Discussion