## 概要
このドキュメントは[【wantedly】custom controllerを使ってk8sを学ぶハンズオン](https://camphor.connpass.com/event/208770/) で利用した資料です。イベント当日は hackmd をメインのドキュメントとして用いますが、アーカイブでは適宜別の場所に移すかもしれません。その場合はわかり易い場所にリンクを置いておきます。
### 参考リンク
- [youtube](https://www.youtube.com/watch?v=hpwzrcok9ne)
- [@potsbo](https://www.wantedly.com/id/potsbo)
- [@onsd_](https://www.wantedly.com/id/onsd_)
- [完成品](https://github.com/potsbo/math-controller)
## 前提
- kubernetes の中身の雰囲気を理解することに主眼をおいています
- このため簡単のために次のようなことを大きく犠牲にしています。
- 一般的なソフトウェア設計のベストプラクティス
- go の模範的な書き方
- custom resource の模範的な設計
- custom controller の模範的な書き方
- 実際に custom controller を作る場合にはより詳しくドキュメントを見ることをおすすめします。
- 良くない場所に気づいた人は「どうすればよいか」を考えることがよい学びになると思います。
- どこが良くない場所がよくわからない人もそれで ok で、今回の作成物を色々いじくり回して遊んでみると良いと思います。
- 楽しいのが一番です!
- 適宜完成品を見てもらって構いません
- commit hash は変わる可能性があります。
- tag は変えないつもりです。
## kubernetesとは何か?
[公式ドキュメント](https://kubernetes.io/ja/docs/concepts/overview/what-is-kubernetes/)
色々あるけど今日は下の2点に集中します。
- 理想の状態を指定する (変化を指定するわけではない)
- 現実とのギャップを吸収する (どんな理由で生じたギャップであるかは関係ない)
## ちょっとだけ使ってみる
`minikube start` で手元に kubernetes クラスタを用意できる。
minikube に関しては [公式ドキュメント](https://minikube.sigs.k8s.io/docs/start/) を参照
下の yaml を `nginx.yaml` として保存してみる
```yaml
apiversion: apps/v1
kind: deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchlabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerport: 80
```
https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
pod (よく知らない人はプロセスと思ってもらってここでは大丈夫)が起動します。
ここで一つどれか消してみると勝手に復活してきます。
```
$ kubectl get po
name ready status restarts age
nginx-deployment-6b474476c4-2z547 1/1 running 0 10m
nginx-deployment-6b474476c4-gbgck 1/1 running 0 10m
nginx-deployment-6b474476c4-zhvrl 1/1 running 0 10m
$ kubectl delete po nginx-deployment-6b474476c4-zhvrl
pod "nginx-deployment-6b474476c4-zhvrl" deleted
$ kubectl get po
name ready status restarts age
nginx-deployment-6b474476c4-2z547 1/1 running 0 10m
nginx-deployment-6b474476c4-8kmqf 1/1 running 0 8s
nginx-deployment-6b474476c4-gbgck 1/1 running 0 10m
```
勝手に復活してきたことに注目 -> 自己修復
## kubernetes の重要な概念
- resource
- 例: pod, deployment, replicaset...
- kubernetes で扱うデータの単位
- プログラミング言語におけるクラスやコンポーネントだと思うと実感がある?
- controller
- resource の「理想」の変化を検知
- あるべき姿への差分吸収を行う
- pod や deployment にも対応する controller がある
このペアが作れれば自分 kubernetes を拡張できる!
## 今回のテーマ
実際に controller を書いてみることで kubernetes の中身がわかった気になる。というのが今回の目標です。
## セットアップ
[`417872`](https://github.com/potsbo/math-controller/commit/41787270df90225665807703eb904e6ab0158756) まで行く
kubebuilder は `curl -l -o kubebuilder https://go.kubebuilder.io/dl/latest/$(go env goos)/$(go env goarch)` で install できる
ここでは repository と kubernetes cluster を用意します。
```markdown
$ minikube start
$ mkdir math-controller
$ kubebuilder init --domain potsbo.k8s.wantedly.com
$ git init
$ git add .
$ git commit
```
init が失敗する場合は`--skip-go-version-check` をつけるといいかもしれない
## api定義
```markdown
$ kubebuilder create api --group math --version v1beta1 --kind number --controller --resource
$ make manifests
```
これで resource を作ることができる。
下のように resource の定義を変えてみる。
```diff
diff --git a/api/v1beta1/number_types.go b/api/v1beta1/number_types.go
index 95f25ea..9cd3a7d 100644
--- a/api/v1beta1/number_types.go
+++ b/api/v1beta1/number_types.go
@@ -28,8 +28,8 @@ type numberspec struct {
// insert additional spec fields - desired state of cluster
// important: run "make" to regenerate code after modifying this file
- // foo is an example field of number. edit number_types.go to remove/update
- foo string `json:"foo,omitempty"`
+ // value is an example field of number. edit number_types.go to remove/update
+ value int64 `json:"value,omitempty"`
}
// numberstatus defines the observed state of number
```
したのコマンドで kubernetes に適応できる。
```diff
$ make manifests
$ make install
```
## apiを使ってみる
[`c6c09d8b`](https://github.com/potsbo/math-controller/commit/c6c09d8bd2b9d420177dff34966bacdf1cf286f9) まで
```diff
$ make install
$ make run
$ kubectl apply -f config/samples/math_v1beta1_number.yaml
$ kubectl get number
```
ここまでで好きな resource が作れるということがわかった。
なにかを作ったり消したりすることしか出来なくて面白くない
下のことをやっていく
- fizzbuzz status の追加
- fizzbuzz status の更新
- fizzbuzz field の更新
## 親 resource を作ってみる
```diff
kubebuilder create api --group math --version v1beta1 --kind tuple --controller --resource
```
https://github.com/potsbo/math-controller/commit/bca73cffec800fafe944637d03791ffccd9e18db
1. number を create or update で作る
2. いらないものを消す
3. self healing
https://github.com/potsbo/math-controller/commit/9685d6b657a6e1bdbb5690af2810a1be185696b5
## 更に親 resource を作ってみる
```diff
kubebuilder create api --group math --version v1beta1 --kind fermat --controller --resource
```
数学の問題
4を法として1に合同な素数は二個の平方数の和で表される。