🗂

【k8s・Kubernetes】Fluxでprivate gtihub repositoryをGKEにデプロイする【CD・GitOps】

2022/11/14に公開約9,000字

内容

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

の削除も忘れずに実行してください。

Discussion

ログインするとコメントできます