はじめに
Kubernetesの勉強を行いたいと思いネットで探せる手軽な情報がないか調べていた。ちょっと古いがとっつきやすい資料に巡り会ったのでこちらで勉強してみた。
なお、上記の作成者の@cstokuさんはKubernetes Documentaionの日本語化を行なっており、Owner/Approverをされている方との事。その点も情報として信頼できる。
一連の記事は2018年のアドベントカレンダーのものなので、恐らく現在とは異なる部分が少なからずあるはず、もしその点があったら調べ現在の方法を探していく(他のk8s関連の記事にあるものを動作確認してもそのままでは動かないことが多々あった)。また各章を読んで自分なりに理解したことや所管などがあったらメモしていく。
入門者について
AWSとAzureとGCPの案件に参画したことはあり、主にインフラ設計しTerraform等で構築していた。しかし各社の独自機能だけを使っておりk8sには全くといって触れた事がなかった。コンテナー系だとFargateやApp ServiceやCloud Runなど。今更ながらk8sの知識がないとなぁと思い勉強することにした。資格目的ではなく、いざ実開発を始めるためのとっかかりのための基礎知識を得る感じ。公式ドキュメントを読み進めたり書籍を買うのも良いが、まずは概要をつかむためネットを探して進めて行った。
いざ入門
1日目 Kubernetesの概要
導入部。とっかかりとしてありがたい。Master部分が公式ドキュメントだとコントロールプレーンという呼び方になっていた。多少の名称の差異こそあれ、基本的なアーキテクチャーは現在でもこの通りらしい。他の古い記事でもMasterと読んでいるのでどこかで呼び方を変えたのだろうか?後で調べたらBLM運動あたりで名称変更があったらしい。また公式ドキュメントによると素のk8sにはないがクラウドベンダー固有にcloud-controller-managerというのがありここでクラウドベンダー特有の機能を提供するらしい。AWSならEKSとALBを連携させるのに使われるのかなぁと理解した。
2日目 Kubernetesのローカル環境について
この記事に辿り着く前にローカル開発環境に関する記事を漁っていたらMinikubeでの説明が多かった。この記事ではいくつかの選択肢からMinikubeを出している。他の記事を探したところ実行環境の選択肢はもっと増えているようだ。恐らく現状Minikubeで始めるのが一番簡単なのだろう。公式ドキュメントを見るとチュートリアルはMinikubeだ。2日以降の記事もMinikube前提なのでMinikubeで進める。他の開発用実行環境を調べてみるとkind(Kubernetes in Docker)というのが複数ノードを作成できてCI等で使うのに良いらしい。kindについては実開発する機会があったら考えてみたい。
3日目 Podについてとkubectlの簡単な使い方
実際の環境ではPod単体での運用することはほぼ無いみたいなのでざっくり複数のコンテナが動くところと理解し動作確認したのみ。
4日目 Container Objectのフィールドについて
次のエラーが発生した。
kubectl exec nginx ps
error: exec [POD] [COMMAND] is not supported anymore. Use exec [POD] -- [COMMAND] instead
See 'kubectl exec -h' for help and examples
エラー結果に書いてあるように現在は次の通り--
を入れるのが現在は正しいようだ(後半の記事だと--
が入っていた)
kubectl exec nginx -- ps
公式ドキュメントによると
ダブルダッシュ(--)のセパレーターは、コマンドに渡す引数とkubectlの引数を分離します。
とのこと。なるほど。
おおよそDocker Composeでの起動コマンドや環境変数などの指定に近いと理解した。
5日目 Volumeについて
$ kubectl apply date-tail.yaml
error: Unexpected args: [date-tail.yaml]
See 'kubectl apply -h' for help and examples
単純に書き忘れか?それとも昔はオプション指定なしで良かったのか?わからないがファイルを指定する-f
が必要あり。
4日目でわかった通りの変更でkubectl execコマンドは--
で区切る必要がある。
k8sの本質的なことではないがlogs tail
だとのんびりしてるとログが流れてしまい確認できないのでkubectl logs date-tail -c tail | head
で確認した。
terminationGracePeriodSecondsが0で設定されているが、これはシェルスクリプトでファイルの読み書きをしているだけなので即終了しても良いと理解した。
結局のところ実運用では外部のストレージが必要。
6日目 Init Container / Lifecycleについて
これまたk8sの本質的なことではないがコンテナーが実行しているシェルスクリプトの先頭のechoで()
が使われているがクォートされていないのでシンタックスエラーとなりPodの状態がCrashLoopBackOffとやらになる(CrashLoopBackOffに関しては将来的に調べようと思う)。
echo "Initialize... (Started at `date`)"
として確認できた(あるいは()
を取るか)
Lifecycleに関してはマニフェストを変更するなりして次の様に確認した。
kubectl exec -it lifecycle-check -- kill -TERM 1
kubectl logs lifecycle-check -c app
kubectl describe pod lifecycle-check
だんだんコマンドの例示が減ってきたので自分で調べて確認しないといけない感じ。
7日目 Resource Requirements / Security Contextについて
Resource Requirementsに関してはVS CodeのKubernetes機能拡張でresource limitが指定されとらんと警告されている部分だった前から気になってた部分だったので納得。Security Contextに関しても厳しい実運用では使う項目を吟味しながら適用したいと感じた。
8日目 ReplicaSet / Deploymentについて
マニフェストを書き直し適用するのとコマンドで変更するのは運用的にどうしているのだろうか?実際は何らかの周辺管理ツールで運用するのか?コマンドで変えてたら失敗するだろうなぁ。もし運用する場合は周辺ツールに関して調べたい。
9日目 Serviceについて
とりあえずLBということなので理解できた(?)がどういうシチュエーションで使うのか?
とりあえず先に進もう。
10日目 LivenessProbe / ReadinessProbeについて
確認用のPodは別ターミナルで起動するのが便利かな。
ReadinessProbeはロードバランサーで普通に設定するやつ、LivenessProbeはPod自身が自己回復してくれるものと理解した。
11日目 ConfigMap / Secretについて
AWSだとParameter StoreとかSecrets Managerみたいなものだと理解した。しかし、例えばEKSと他のサービスを併用したく、これらの値を共用したい場合はどうするのだろう? → ASCPというのがあるようだ。恐らく他のクラウドベンダーにも同様のものがあるのだろう。
なおConfigMapのKey指定の前には一旦消してあげる必要あり
kubectl delete cm params
12日目 PersistentVolume / PersistentVolumeClaim / StorageClassについて
これまた実際の運用ではクラウドベンダーのものを利用することが多いのかな?その時。
13日目 StatefulSet / DaemonSetについて
StatefulSetはどんなシチュエーションで使われるのか調べてみたが複数データベースでレプリケーションする例が出ていたが…クラウドベンダーで動かす場合はマネージドサービスを利用することが多いと思う。その他どんなところで利用する事が多いのだろうか?
DeamonSetのサンプルだが、fluentdのlatestタグが廃止された様なので、ErrImagePullとなってしまう。とりあえずedgeタグを指定した。image: fluent/fluentd:edge
14日目 Job / CronJobについて
apiVersionがベータから昇格した様なのでv1beta1だとエラーになる。batch/v1beta1
-> batch/v1
で動く様になる。
複雑なジョブ制御はどうするのだろうか?AirflowとかAzkabanなどのワークフロー管理ツール。と思って調べてみるとAirflow on KubenetesとかAzkaban on Kubernetesなどが見つかった、またAWS Step FunctionsとEKSを連携させる記事も。恐らく実運用では簡単なJobはk8s組み込みのジョブ制御で行い複雑なフローが必要なものはこれらのツールを用いる事が多いのだろう。
15日目 Namespace / Resource QoS / ResourceQuota / LimitRangeについて
書かれていないnsにkube-node-leaseというのが存在していた。新規にリースという仕組みが追加されそこで利用されているっぽい。いずれにせよk8s側の機能なのでそんなものだろうという感じで今のところは覚えておく。
しばしば分散システムでは共有リソースをロックしたりノード間の活動を調整する機構として"リース"が必要になります。
QoSの確認に-o jsonpath='{.status.qosClass}'
というのが出てきたが、-o
オプションでJSONやYAMLなど出力形式を選べるらしい、JSONPathだと必要なものをセレクトしやすいっぽい。多分運用的にはkubectl単体よりもjqでやると色付けされるので良いかも。
Resource QoS / ResourceQuota / LimitRange に関してはさらっと流して実際に運用する場合に考えたい。
16日目 NetworkPolicyについて
デフォルトではNetworkPolicyが動作しないとのことで、オプション付きでminikubeを再作成するが、調べてみると次の方法に変わった様子。
minikube start --network-plugin=cni --cni=calico
またkubectl run
で--generator=run-pod/v1
というオプションを指定するとunknown flagとエラーとなるので、削除してやってみた。これで良いのかは不明。以前はDeploymentが作られていたが現在はPodが作られるとのこと。単純に取れば良いらしい。
17日目 Label / NodeSelector / Annotationについて
特になし
18日目 Affinity / Anti-Affinity / Taint / Tolerationについて
Taint / Toleration をどんなところで運用するのかいまいち掴めなかったが…。
19日目 Authn / Authz / ServiceAccountについて
クラウドベンダーのサービスを利用する場合はどうなるのだろうか?AWSの場合IAMやOIDCでの話を見つけた。実際に使うときに改めて調べる必要あり。
20日目 Role / RoleBinding / ClusterRole / ClusterRoleBindingについて
サービスアカウントでTokenが作られない。仕様が変わったとのこと。別記事にまとめました。
21日目 Cordon / Drain / PodDisruptionBudgetについて
次のエラーでDrainできない
$ kubectl drain minikube
node/minikube cordoned
error: unable to drain node "minikube" due to error: [cannot delete DaemonSet-managed Pods (use --ignore-daemonsets to ignore): kube-system/kube-proxy-pvtmc, cannot delete cannot delete Pods that declare no controller (use --force to override): kube-system/storage-provisioner], continuing command...
There are pending nodes to be drained:
minikube
cannot delete DaemonSet-managed Pods (use --ignore-daemonsets to ignore): kube-system/kube-proxy-pvtmc
cannot delete cannot delete Pods that declare no controller (use --force to override): kube-system/storage-provisioner
多分
- minikubeは1Nodeで動いておりControl Planeのものも含んでいる
- kube-proxyがdaemonsetで動けない
- ReplicaSetで管理されていないPodを含めて退避
だからっぽい。言われたオプションを指定するとDrainできた。
$ kubectl drain minikube --ignore-daemonsets --force
この様な検証にはminikubeよりkindの方が良いのか??
22日目 Ingressについて
この当時はbetaだった様でIngressの仕様が変わり次の様に変更した。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-test
spec:
rules:
- http:
paths:
- path: /nginx
pathType: Prefix
backend:
service:
name: nginx
port:
number: 80
- path: /httpd
pathType: Prefix
backend:
service:
name: httpd
port:
number: 80
- apiVersionが
extensions/v1beta1
→networking.k8s.io/v1
- pathの指定が結構変わった
また、実際にIngressにアクセスするためにはトンネルが必要。別ターミナル(起動している間有効なので)にて次のコマンドの実行が必要。
$ minikube tunnel
ループバックで公開される様なので、minikube ip
で得られるアドレスでなく
$ curl -I http://127.0.0.1/nginx
$ curl -I http://127.0.0.1/httpd
で確認。
23日目 kubectlを網羅する
ざっくり読んだ。恐らくオプションの変更とかもありそうなので章立てをみる程度で実際に使用するときにhelpやwebのドキュメントを見たい。
24日目 Kubernetesの各コンポーネントについて
1日目でざっくり触れていた話をもう少し詳細に説明している部分。Master → Control Plane
ざっと読んだ。
25日目 Kubernetesの情報元やコミュニティについて
リンク集になるのでざっくりみる程度。必要に応じてたどりたい。有用なリンクや書籍も変わっているはず。
感想
ちょっとの修正でハンズオンでき概要を学べる良い記事だったと感じた。まずはこれをきっかけに公式ドキュメントや何らかの書籍を読んだりしてk8sについて理解を深めていきたい。