SRE兼スクラムマスターのブログ

チーム開発が好きなエンジニアブログです。検証した技術やチームの取り組みを書いていきます。

Fluxを使ってGitOpsを実現する

概要

  • GitOpsという概念は知っているが実現はできていなかった
  • GitOps実践ツールではAgro CD,Flux,Jenkins Xなどが有るけど,GitOps提唱元のFluxを試してみる

モチベーション

  • kubernetesを運用するにあたってmanifestを使って宣言的に運用したい
  • codeと実際の環境差異をなくしたい

GitOpsとは?

Weaveworks社が提唱した,Kubernetesの運用ベストプラクティス

詳しくはGitOpsを参照

Fluxとは?

Kubernetesへのコンテナの展開を自動化するツール

Githubを見ると以下のことが書かれていた

  • gitでシステムの望ましい状態を宣言的に記述できる

  • 宣言出来るものは自動化できる

  • コンテナをpushするのではなくコードをpushするのだ

github.com

詳細はここでは割愛するが 実現できることを簡潔に表現すると kubernetes Clusterの状態とGit管理されているmanifestと同期を取り 変更検知された場合に自動的にclusterを更新してくれるものらしい

事前準備

fluxctlのインストール

brew install fluxctl

Kubernetes Clusterの構築

  • 今回はdocker desktop for windowsを使ってlocal環境にclusterを構築しました。

qiita.com

qiita.com

Flux同期用のリポジトリを作成

flux導入

  • 導入はこちらを参考に進めました

https://docs.fluxcd.io/en/stable/tutorials/get-started.html

基本は手順通りなのだが自分は英語を読むのに時間がかかるので実行したコマンドをメモしておきます

clusterにflux用のnamespaceを作成する

kubectl create ns flux

fluxをinstallする GHUSERはgithubのアカウント名に変更する 今回はgithubを利用しているが他のversion管理ツールを利用している場合は検証が必要そう

export GHUSER="hogehoe"
fluxctl install \
--git-user=${GHUSER} \
--git-email=${GHUSER}@users.noreply.github.com \
--git-url=git@github.com:${GHUSER}/flux-get-started \
--git-paths=namespaces,workloads \
--namespace=flux | kubectl apply -f -

コマンドを実行するとfluxがデプロイされているか確認します。

kubectl get all -n flux

NAME                             READY   STATUS    RESTARTS   AGE
pod/flux-69f4b44484-t6lrt        1/1     Running   0          178m
pod/memcached-7c45dbdb45-s4m95   1/1     Running   0          178m

NAME                TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)     AGE
service/memcached   ClusterIP   10.97.207.98   <none>        11211/TCP   178m

NAME                        READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/flux        1/1     1            1           178m
deployment.apps/memcached   1/1     1            1           178m

NAME                                   DESIRED   CURRENT   READY   AGE
replicaset.apps/flux-69f4b44484        1         1         1       178m
replicaset.apps/memcached-7c45dbdb45   1         1         1       178m

Fluxの公開鍵をリポジトリに登録します Clusterの状態をgitと同期するには,公開鍵を使ってGitHubリポジトリに書き込みアクセス権を持つデプロイキーを作成する必要があるようです。 デプロイキーの作成はこちらを参照

fluxctl identity --k8s-fwd-ns flux

ちなみにこの時点で Flux同期用のリポジトリに管理されているmanifestがcluster上にデプロイされていました。 guthubのmanifest抜粋

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: podinfo
  namespace: demo
  labels:
    app: podinfo
  annotations:
    flux.weave.works/automated: "true"
    flux.weave.works/tag.init: regex:^3.10.*
    flux.weave.works/tag.podinfod: semver:~2.1
spec:
  strategy:
    rollingUpdate:
      maxUnavailable: 0
    type: RollingUpdate
  selector:
    matchLabels:
      app: podinfo
  template:
    metadata:
      annotations:
        prometheus.io/scrape: "true"
      labels:
        app: podinfo
    spec:
      initContainers:
        - name: init
          image: alpine:3.10
          command:
            - sleep
            - "1"
      containers:
        - name: podinfod
          image: stefanprodan/podinfo:2.1.3
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 9898
              name: http
              protocol: TCP
          command:
            - ./podinfo
            - --port=9898
            - --level=info
            - --random-delay=false
            - --random-error=false
          env:
            - name: PODINFO_UI_MESSAGE
              value: "Greetings change pod!"
          livenessProbe:
            httpGet:
              path: /healthz
              port: 9898
          readinessProbe:
            httpGet:
              path: /readyz
              port: 9898
          resources:
            limits:
              cpu: 1000m
              memory: 128Mi
            requests:
              cpu: 10m
              memory: 64Mi
kubectl get pod -n demo
NAME                       READY   STATUS    RESTARTS   AGE
podinfo-5645bc6c54-lmcnk   1/1     Running   0          146m
podinfo-5645bc6c54-tln7j   1/1     Running   0          146m

sampleのServiceはclusterIPなのでportforwadしてブラウザでアクセスしてみます

kubectl port-forward svc/podinfo 8080:9898 -n demo
Forwarding from 127.0.0.1:8080 -> 9898
Forwarding from [::1]:8080 -> 9898

manifestのenvで定義されている「PODINFO_UI_MESSAGE」の値が表示されているっぽい f:id:JunichiMitsunaga:20191003190816p:plain

ここからはmanifestの内容を変更してgithubにpushしてみます PODINFO_UI_MESSAGEの内容を「Hello!!」に変更後,push

          env:
            - name: PODINFO_UI_MESSAGE
              value: "Hello!!"
          livenessProbe:
            httpGet:
              path: /healthz
              port: 9898
          readinessProbe:

Defaultでは5分単位で同期を取るようですがすぐに確認したかったためコマンドを実行します

fluxctl sync --k8s-fwd-ns flux

同期を取った時に監視していると差分検知されて自動的デプロイされたことがわかりました

kubectl get po -n demo -w

NAME                       READY   STATUS    RESTARTS   AGE
podinfo-f55d5f6d9-v4phs    0/1     Pending   0          0s
podinfo-f55d5f6d9-v4phs    0/1     Pending   0          0s
podinfo-f55d5f6d9-v4phs    0/1     Init:0/1   0          0s
podinfo-f55d5f6d9-v4phs    0/1     Init:0/1   0          2s
podinfo-f55d5f6d9-v4phs    0/1     PodInitializing   0          3s
podinfo-f55d5f6d9-v4phs    0/1     Running           0          4s

再度アクセスしてみると表示が「Hello!!」に変わっています f:id:JunichiMitsunaga:20191003191555p:plain

所感

ひとまず動作させることを目的としていたので思っていたより簡単に導入出来て良かったです。 GitOpsはkubernetesを運用していくにあたって非常に強力なプラクティスになると思うので引き続きfluxを掘り下げていこうと思います。

参考

今回は全体的に公式ページを参考にさせて頂きました。 チュートリアルはシンプルでイメージを掴むのに最適だと思います。

https://docs.fluxcd.io/en/stable/index.html

現在はKustomizeを使ってmanifestを管理しているのでゆくゆくはこちらも試してみたいです。

https://docs.fluxcd.io/en/stable/tutorials/get-started-kustomize.html

local環境でのcluster構築はminikubeでも良かったのですがdocker desktopが既にinstallされていたのでそちらを使っています

https://qiita.com/yoichiwo7/items/0b2aaa3a8c26ce8e87fe

https://qiita.com/comefigo/items/f7bc852a63797934d641