とことんDevOps | 日本仮想化技術が提供するDevOps技術情報メディア

DevOpsに関連する技術情報を幅広く提供していきます。

日本仮想化技術がお届けするとことんDevOpsでは、DevOpsに関する技術情報や、日々のDevOps業務の中での検証結果など、DevOpsのお役立ち情報をお届けします。
主なテーマ: DevOps、CI/CD、アジャイル開発、コンテナ開発など

開催予定の勉強会

各種SNSのフォローもよろしくお願いいたします。

GitOpsツール Flux v2を触ってみた

今回も前回に引き続き、GitOpsツールのFluxについて書いていきたいと思います。 前回はEKS Anywhereを使って手持ちのvSphere環境にKubernetesとFluxを導入してGitOpsを体験してみました。

devops-blog.virtualtech.jp

今回は、もう少しどこでも動くようにmicrok8sを使ってFluxを動かしてみます。

この記事の内容はほぼ公式のGet Started with Fluxと同様ですが、手順を追ってGitOpsを体験していただけるように、microk8sを使ってKubernetesクラスターを作成するところから記載しています。本例ではGitHubアカウントが必要になります。

GitOpsとは

GitOpsは、インフラストラクチャとアプリケーションを管理する方法であり、システム全体がGitのよって宣言的に記述され、バージョン管理され(ほとんどの場合Gitリポジトリで)、デプロイされた環境がリポジトリで指定された状態と一致することを保証する自動化されたプロセスの仕組みです。

Fluxとは

Kubernetesへのコンテナの展開を自動化するツールです。 GitOpsを提唱したWeaveworks社が作成しました。現在はOSSで開発されており、CNCFのインキュベーションプロジェクトとして登録されています。

Flux開発者はGitOpsを次のようなものだと紹介しています。

  • システムの望ましい状態をGitで宣言的に記述できる
  • 宣言できることは自動化できる
  • コンテナではなくコードをプッシュするためのもの

Fluxはバージョン1とバージョン2があり、本例はバージョン2のFluxを想定しています。 Webで検索する場合、fluxctlを使った操作をおこなっているものはバージョン1のFluxなのでご注意ください。

Fluxの利用に必要な要件

このガイドに従って、GitopsツールのFluxを導入して、Gitopsでアプリケーションの継続的デプロイを実行するには次の2つが必要です。

  • Kubernetesクラスター
  • repoの権限があるGitHub personal access token

なお、私は次の環境で今回の環境をセットアップしました。うまくいかない場合は環境を合わせてみてください。

  • プラットフォーム: MicroStack ussuri (Rev.245)
  • 環境: OpenStackインスタンス上のUbuntu Server 20.04.4
  • microk8sのバージョン:
    • v1.22.9 Rev.3203 (本例はこちらのバージョンで実施)
    • v1.23.6 Rev.3204 (こちらでも動作確認済)

以下のバージョンのmicrok8sではうまく動かせませんでした。flux bootstrap githubの実行中にmicrok8sクラスターがcontext deadline exceededを返すんですよね。これについては調査中です。

  • v1.24.0 Rev.3272 (Date 2022-05-13)

Kubernetesクラスター

まず、なんらかの方法でセットアップしたKubernetesクラスターが必要です。 例えばUbuntu + microk8sを使う場合は、次の様に実行します。他のOSの場合はこちらの方法で。

バージョンを指定する場合は--channelオプションを使います。インストールできるバージョンはsnap info microk8sで確認します。

$ sudo snap install microk8s --classic --channel=1.22/stable
$ sudo microk8s.enable dns rbac

インストール後、いつもは組み込みのkubectlコマンドのエイリアスを張ったりしますが、Flux CLIの利用のためにkubeconfigが必要なので、 次のようにkubeconfigのエクスポートとkubectlのインストールをします。Ubuntuの場合は同じくsnapインストールでインストール可能です。

kubeconfigのエクスポートは次のように行います。

$ mkdir ~/.kube/ && touch ~/.kube/config
$ sudo microk8s config > ~/.kube/config

kubectlのインストールは次のように行います。インストールするバージョンはクラスターのバージョンに合わせます。

$ sudo snap install kubectl --classic --channel=1.22/stable

repoの権限があるGitHubパーソナルアクセストークンの準備

自分のGitHubアカウントにログインして、パーソナルアクセストークンを作成します。作成時にrepoの各権限を実行できる様にチェックマークを入れます。

Flux CLIを実行する前に、ユーザー名とGitHubトークンを環境変数に設定しておきます。

$ export GITHUB_TOKEN=<your-token>
$ export GITHUB_USER=<your-username>

Flux CLIのインストール

Fluxを利用するにはFlux CLIをインストールしておくと便利です。インストールガイドを参考に、OS向けにCLIをインストールします。

Flux CLIをインストール後、次のように実行してKubernetesクラスターの要件を満たしていることを確認します。

$ flux check --pre
► checking prerequisites
✔ Kubernetes 1.22.9-3+b6876a8b1b090b >=1.20.6-0
✔ prerequisites checks passed

Fluxのインストール

クラスターでFluxを実行するにはflux bootstrapを実行します。 これによりFluxの設定用マニフェストが生成されGitHubリポジトリーにコミットされます。

$ flux bootstrap github \
  --owner=$GITHUB_USER \
  --repository=fleet-infra \
  --branch=main \
  --path=./clusters/my-cluster \
  --personal

microk8sは最小構成のKubernetesクラスターを構築します。FluxはどうやらCore-DNSとRBACを要件としているようなので、 事前にアドオンを追加してからflux bootstrap githubを実行してください。

また次の症例によると、プロキシーが原因になる場合があるとのことです。

実行すると進捗がログとして出力されます(出力例)。

► connecting to github.com
✔ repository "https://github.com/ytooyama/fleet-infra" created
► cloning branch "main" from Git repository "https://github.com/ytooyama/fleet-infra.git"
✔ cloned repository
► generating component manifests
✔ generated component manifests
✔ committed sync manifests to "main" ("8c8bedd18acae6c323d70ec1137d9a587fdbf681")
► pushing component manifests to "https://github.com/ytooyama/fleet-infra.git"
✔ installed components
✔ reconciled components
► determining if source secret "flux-system/flux-system" exists
► generating source secret
✔ public key: ecdsa-sha2-nistp384 HogeHugaKey5656  #アカウントにSSHキーが登録されている場合、公開鍵が出力
✔ configured deploy key "flux-system-main-flux-system-./clusters/my-cluster" for "https://github.com/ytooyama/fleet-infra"
► applying source secret "flux-system/flux-system"
✔ reconciled source secret
► generating sync manifests
✔ generated sync manifests
✔ committed sync manifests to "main" ("4085e30aea1a8c159478f76cdd3db47f7076dd5a")
► pushing sync manifests to "https://github.com/ytooyama/fleet-infra.git"
► applying sync manifests
✔ reconciled sync configuration
◎ waiting for Kustomization "flux-system/flux-system" to be reconciled
✔ Kustomization reconciled successfully
► confirming components are healthy
✔ helm-controller: deployment ready
✔ kustomize-controller: deployment ready
✔ notification-controller: deployment ready
✔ source-controller: deployment ready
✔ all components are healthy

以上の実行で、KubernetesクラスターでFluxサービスが実行されます。 fleet-infraというGitリポジトリーがGitHubアカウントに作成されます。このディレクトリーにはFluxのマニフェストがコミットされます。 パスで指定している./clusters/my-clusterがGitOpsツールで監視されます。このディレクトリー配下の変更を元として、クラスターにアプリケーションが展開されます。

コマンドを実行すると、Fluxサービスが手元のK8sで動いて、flux-systemのサービスがGitで管理されたことが示されます。

$ flux get kustomizations 
NAME        REVISION        SUSPENDED   READY   MESSAGE                        
flux-system main/18d43d6    False       True    Applied revision: main/18d43d6  

FluxでGitOpsを試す

アプリケーション実行の事前準備

まず、GitHubにSSHプロトコルでアクセスできるように設定をします。公開鍵は事前に作ったものを.ssh/configに記述します。鍵はパスフレーズを要求するものを使うことをお勧めします。

$ cat .ssh/config 
Host github github.com
  HostName github.com
  IdentityFile ~/.ssh/id_ecdsa
  User git

作成されたGitHubリポジトリーをクローンします。

$ git clone git@github.com:$GITHUB_USER/fleet-infra.git
$ cd fleet-infra

ディレクトリー構成は次のとおりです。

$ tree
.
└── clusters
    └── my-cluster
        └── flux-system
            ├── gotk-components.yaml
            ├── gotk-sync.yaml
            └── kustomization.yaml
3 directories, 3 files

cluster/my-cluster配下にアプリケーション用のディレクトリーを作りましょう。

$ mkdir -p ./clusters/my-cluster/podinfo

早速Fluxにアプリケーションを追加してみます。次のように実行して、GitRepositoryマニフェストを作成します。

$ flux create source git podinfo \
  --url=https://github.com/stefanprodan/podinfo \
  --branch=master \
  --interval=30s \
  --export > ./clusters/my-cluster/podinfo/podinfo-source.yaml

コマンドを実行すると、GitRepositoryマニフェストが作成されます。

$ cat ./clusters/my-cluster/podinfo/podinfo-source.yaml
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: GitRepository
metadata:
  name: podinfo
  namespace: flux-system
spec:
  interval: 30s
  ref:
    branch: master
  url: https://github.com/stefanprodan/podinfo

このコードをGitHubにコミットします。

$ git add -A && git commit -m "Add podinfo GitRepository"
$ git push

git-configの設定を要求された場合は、適切な設定を行なってください。

$ git config --global user.email "you@example.com"
$ git config --global user.name "Your Name"

これでFluxによってGitに登録されたアプリケーションが管理されましたが、現時点ではアプリケーションがクラスタではうふごいていません。

$ flux get sources git
NAME        REVISION        SUSPENDED   READY   MESSAGE                                                                        
flux-system main/02b0e5e    False       True    stored artifact for revision 'main/02b0e5e20537c38b49368b7f958996b5b5bbc355'
podinfo     master/bf09377  False       True    stored artifact for revision 'master/bf09377bfd5d3bcac1e895fa8ce52dc76695c060'

$ flux get kustomizations
NAME        REVISION        SUSPENDED   READY   MESSAGE                        
flux-system main/02b0e5e    False       True    Applied revision: main/02b0e5e

アプリケーションの実行

いよいよFluxでアプリケーションのデプロイを行ってみます。 次のように実行して、podinfoデプロイメントを適用するKustomizationを作成します。

$ flux create kustomization podinfo \
  --target-namespace=default \
  --source=podinfo \
  --path="./kustomize" \
  --prune=true \
  --interval=5m \
  --export > ./clusters/my-cluster/podinfo/podinfo-kustomization.yaml

コマンドを実行すると、Kustomizationマニフェストが作成されます。

$ cat ./clusters/my-cluster/podinfo/podinfo-kustomization.yaml
---
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
  name: podinfo
  namespace: flux-system
spec:
  interval: 5m0s
  path: ./kustomize
  prune: true
  sourceRef:
    kind: GitRepository
    name: podinfo
  targetNamespace: default

このコードをGitHubにコミットします。

$ git add -A && git commit -m "Add podinfo Kustomization"
$ git push

これにより、GitHubにアプリケーションの事項マニフェストが登録され、GitopsツールであるFluxでアプリケーションの継続的デプロイが実行されます。 アプリケーションの実行状況は以下のコマンドで確認できます。

$ flux get kustomizations
NAME        REVISION        SUSPENDED   READY   MESSAGE                          
flux-system main/84f7718    False       True    Applied revision: main/84f7718      
podinfo     master/bf09377  False       True    Applied revision: master/bf09377

$ kubectl -n default get deployments,services
NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/podinfo   2/2     2            2           82s

NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)             AGE
service/kubernetes   ClusterIP   10.152.183.1     <none>        443/TCP             54m
service/podinfo      ClusterIP   10.152.183.117   <none>        9898/TCP,9999/TCP   82s

以上で、GitOpsツールFluxを使った継続的デプロイを試すことができました。