概要
- GitOpsを概念としては知っているけど、実際に触れたことは無かったのでハンズオンしてみる。
- GitOpsを知らない人は、まずこちらを参照
- weaveworks GitOps
- weaveworks社が提唱しはじめた、Kubernetesの運用ベストプラクティス
- GitOpsを知らない人は、まずこちらを参照
- GitOpsを実践できるツールに、Agro CD、Flux、Jenkins X、の3種類が有るけど、GitOps提唱元のFluxをまずは使ってみる。
Fluxハンズオン
- 以下を読みながら進めていく
事前準備
fluxctlのインストール
- Windows環境での利用は想定していない?
- 気にせずインストール
- CLIでインストールしたいので、chocolateyをインストール
- https://chocolatey.org/install#installing-chocolatey
- scoop対応していないみたい。
- インストール
$choco install -y fluxctl
$ fluxctl version
1.12.3
Kubernetesクラスタの構築
- 以下の記事の通りに進めて、GKEクラスタを構築
$ gcloud container clusters create flux-handson
$ gcloud container clusters list
NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS
flux-handson asia-northeast1-a 1.12.7-gke.10 35.243.120.194 n1-standard-1 1.12.7-gke.10 3 RUNNING
Fluxの同期先のリポジトリを用意
- GitHubで適当な空のリポジトリを作る
- 今回は使用しないが、Fluxが用意しているサンプルリポジトリもあるみたい。
Fluxの導入
FluxのリポジトリをClone
$ git clone https://github.com/weaveworks/flux
$ cd flux
同期先のリポジトリを変更
-
--git-url
のURLを事前に準備したリポジトリに変更
#書き換え
$ vim ./deploy/flux-deployment
$ git add .
$ git commit -m "edit --git-url"
#差分
$ git diff HEAD^
diff --git a/deploy/flux-deployment.yaml b/deploy/flux-deployment.yaml
index a75d636e..bf46be90 100644
--- a/deploy/flux-deployment.yaml
+++ b/deploy/flux-deployment.yaml
@@ -118,7 +118,7 @@ spec:
- --ssh-keygen-dir=/var/fluxd/keygen
# Replace or remove the following URL.
- - --git-url=git@github.com:weaveworks/flux-get-started
+ - --git-url=git@github.com:ssbtn/flux-handson.git
- --git-branch=master
# include this if you want to restrict the manifests considered by flux
# to those under the following relative paths in the git repository
Fluxをクラスタにデプロイ
deployフォルダ配下で定義されているオブジェクトをデプロイ
$ kubectl apply -f deploy
serviceaccount/flux created
clusterrole.rbac.authorization.k8s.io/flux created
clusterrolebinding.rbac.authorization.k8s.io/flux created
deployment.apps/flux created
secret/flux-git-deploy created
deployment.apps/memcached created
service/memcached created
Podが起動していることを確認
$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/flux-6c99dbcd46-g47m5 1/1 Running 0 5m4s
pod/memcached-5d46855d78-ww5hd 1/1 Running 0 5m3s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.23.240.1 <none> 443/TCP 138m
service/memcached ClusterIP 10.23.245.54 <none> 11211/TCP 5m2s
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
deployment.apps/flux 1 1 1 1 5m4s
deployment.apps/memcached 1 1 1 1 5m3s
NAME DESIRED CURRENT READY AGE
replicaset.apps/flux-6c99dbcd46 1 1 1 5m4s
replicaset.apps/memcached-5d46855d78 1 1 1 5m3s
Fluxの公開鍵をリポジトリに登録
Flux起動時に作られた公開鍵の取得
$ fluxctl identity
#fluxctlが無くても、以下のコマンドでも可能
$ kubectl logs deployment/flux | grep identity.pub
GitHubにデプロイキーとして登録。
作成したリポジトリで
Setting
→Deploy Keys
→Add deploy key
→鍵入力
→Add key
Key | Value |
---|---|
Title | Flux-key |
Key | 取得した公開鍵 |
Allow write access | 許可 |
動作確認
Namespaceを作成するmanifestをpushしてみる
作成したmanifest
apiVersion: v1
kind: Namespace
metadata:
labels:
name: flux-handson
name: flux-handson
リモートリポジトリにpush
$ git clone git@github.com:ssbtn/flux-handson.git
$ cd flux-handson
$ mkdir namespaces
#上記のmenifestを配置
$ vim namespaces/namespace-flux-handson.yml
$ git add .
$ git commit -m "Create namespace of flux-handson"
$ git push
2分ぐらい待機してnamespaceを取得。
ちゃんと反映されてる!
$ kubectl get namespaces
NAME STATUS AGE
default Active 5h21m
flux-handson Active 2m27s
kube-public Active 5h21m
kube-system Active 5h21m
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
flux-6c99dbcd46-g47m5 1/1 Running 0 3h7m
memcached-5d46855d78-ww5hd 1/1 Running 0 3h7m
$ kubectl logs flux-6c99dbcd46-g47m5
~~~~~~~中略~~~~~~~~~
ts=2019-06-01T09:52:58.54924271Z caller=sync.go:542 component=cluster method=Sync cmd="kubectl apply -f -" took=623.753268ms err=null output="namespace/flux-handson created"
ts=2019-06-01T09:52:58.557341121Z caller=daemon.go:624 component=daemon event="Sync: c1a8c33, <cluster>:namespace/flux-handson" logupstream=false
ts=2019-06-01T09:53:02.404396193Z caller=loop.go:441 component=sync-loop tag=flux-sync old=76fa76fb551c93ed72413ad8a603cac6c60b4ccc new=c1a8c3341d7ce8b47251e7d002a0aeb0f5bf91ce
ts=2019-06-01T09:53:05.788483492Z caller=loop.go:103 component=sync-loop event=refreshed url=git@github.com:ssbtn/flux-handson.git branch=master HEAD=c1a8c3341d7ce8b47251e7d002a0aeb0f5bf91ce
ts=2019-06-01T09:53:56.006830168Z caller=images.go:18 component=sync-loop msg="polling images"
ts=2019-06-01T09:53:56.126944631Z caller=images.go:28 component=sync-loop msg="no automated workload
Gitの状態を真としてくれることを期待して、namespaceを削除してみる。
リアルタイム(5分間隔?)に差分検出して、同期してくれた。
$ kubectl delete namespace/flux-handson
namespace "flux-handson" deleted
#上記コマンドの直後
$ kubectl get namespaces
NAME STATUS AGE
default Active 5h25m
kube-public Active 5h25m
kube-system Active 5h25m
#上記コマンドから5分後
$ kubectl get namespaces
NAME STATUS AGE
default Active 5h29m
flux-handson Active 16s
kube-public Active 5h29m
kube-system Active 5h29m
Deploymentとか、Serviceとかも同じ要領でデプロイしてみる。
- manifestの詳細は長くなるのでこちら
Namespaceを指定しないとdefaultにデプロイされた。当然だが。
Serviceも公開されている。
$ kubectl get pod --namespace default
NAME READY STATUS RESTARTS AGE
flux-6c99dbcd46-g47m5 1/1 Running 0 3h27m
memcached-5d46855d78-ww5hd 1/1 Running 0 3h27m
nginx-5947c4dd86-24qm7 1/1 Running 0 102s
nginx-5947c4dd86-7s767 1/1 Running 0 102s
nginx-5947c4dd86-lp5nz 1/1 Running 0 102s
nginx-5947c4dd86-lzd9c 1/1 Running 0 102s
nginx-5947c4dd86-ptwz5 1/1 Running 0 102s
$ curl 104.198.119.148:30080
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 612 100 612 0 0 38250 0 --:--:-- --:--:-- --:--:-- 38250<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
正しい手順か分からないが、ロールバックを試してみる。
#リモートリポジトリの状態を1つ前のコミットを取り消す
$ git push -f origin HEAD~:master
#10分後
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
flux-6c99dbcd46-g47m5 1/1 Running 0 3h48m
memcached-5d46855d78-ww5hd 1/1 Running 0 3h48m
nginx-5947c4dd86-24qm7 1/1 Running 0 22m
nginx-5947c4dd86-7s767 1/1 Running 0 22m
nginx-5947c4dd86-lp5nz 1/1 Running 0 22m
nginx-5947c4dd86-lzd9c 1/1 Running 0 22m
nginx-5947c4dd86-ptwz5 1/1 Running 0 22m
Git上からmanifestは無くなったが、クラスタ上に各objectが残ってしまった。
コミットを取り消すとファイルが消えてしまう=管理対象から離れてしまったため、ロールバックできなかったのだと思われる。
探したけど見つからなかったので、公式なロールバック手順があればコメントください。
所感
予想していたよりも簡単に導入することができた。
次回はhelmのデプロイや、ロールバックの手順、manifestとpull requestの自動作成、GitOps製品の比較をやっていきたい。
参考
- 今回は使用しなかったけど、FluxをHelmでセットアップする方法も用意されている。
- https://github.com/weaveworks/flux/blob/master/site/helm-get-started.md
- Helmが使える環境ならば、こちらの手順が良さそう。
- スタンドアローンな環境へのインストールは以下を参照
- FluxについてのFAQ
-
https://github.com/weaveworks/flux/blob/master/site/faq.md#does-it-work-only-with-one-git-repository
- Fluxで制御できるNamespaceはFluxのサービスアカウントのRBACを設定することで制限できるみたい。
- 同期先のリポジトリ1つしか選べない。マイクロサービスで使うには運用方法を考える必要が有りそう。
- 公式見解では、複数のFluxを起動してそれぞれのサービスアカウントに適切なRBACを与えなさいってことみたい。
-
https://github.com/weaveworks/flux/blob/master/site/faq.md#does-it-work-only-with-one-git-repository
- fluxctlのインストール
- MinikubeへのFluxセットアップ