以前特定ミドルウェアやトレンド技術に対応できるエビデンスを作っていきたいという話をしました。ということでKubernetesに入門してみることにしました。上で動かすアプリケーションが無いのにKubernetesだけを学ぶのはiPhoneのマニュアルだけ読んでアプリをインストールしないのに似ています。それだとつまらないので最終的に何かしらサービスを作っていくことを目標にします1。
Kubernetesとは
たくさんのマシン上でたくさんコンテナを実行するためのミドルウェアです。デプロイ・スケーリングなどの管理が自動化できます。Dockerだと単体のマシンでコンテナを動かすことはできても複数台で協調させることは難しいです。ロードバランシングやサービスディスカバリを設定したりできるらしいです。AWSならECS、Route53、ELB等がありますが、同等のことをオンプレで実現できるのが嬉しさなのかなと思います。自前のデータセンターを持っている場合はこれを使うことになるんだと思います。あとはGoogleが原型を作っていたけれども今はオープンソースなのでベンダーロックインが少ないあたりが嬉しさになってくるんでしょうか。マネージドの場合でもKubernetesのレイヤーが噛んでいるのでAWSからGCP、GCPからAzureなどの移行が比較的簡単にできたりするんですかね。
リソースの定義はマニフェストというyamlを書いて行います。マニフェストは以下みたいなものです。
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-deployment
spec:
replicas: 3
selector:
matchLabels:
app: sample-app
template:
metadata:
labels:
app: sample-app
spec:
containers:
- name: nginx-container
image: nginx:1.16
マニフェストにあるべき姿を書いて、現状にズレがあったらKubernetesが戻そうとするとのことです。ここらへんはCloudFormationとECSのタスク数設定をあわせたような動きになりそうです。更に、ノードの障害があっても、Kubernetesが死活監視しているので別ノードでコンテナを実行するよう復旧するなどの賢い動きができるそうです。
コンテナはどこのノードで実行されるのかユーザーは考えなくてよく、Kubernetesによって賢くスケジューリングされます。スケジューリングではコンテナのディスクIOの量を加味してSSDを持つノードで実行するなどができます。特に指定がなければ現在使用中のリソース状況に応じてスケジューリングされます2。
Kubernetes環境
Kubernetesを動かす環境はローカル・Kubernetes構築ツール・マネージドKubernetesサービスがあります。個人で勉強するためには費用的にローカルしか選択肢がないですが、ローカルの選択肢としてはMinikubeとkindがあります。前者ではマルチノードを再現することができないため、kindを使うべきです。kindはローカルマシンにDockerをインストールしておき、Docker上のコンテナをノードに見立ててKubernetesを実行します。
WSL2での実行方法としては、Dockerをインストールし、以下を実行してください。
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.17.0/kind-linux-amd64
chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind
次に以下kind.yamlを作成し、
apiVersion: kind.x-k8s.io/v1alpha4
kind: Cluster
nodes:
- role: control-plane
image: kindest/node:v1.18.2
- role: control-plane
image: kindest/node:v1.18.2
- role: control-plane
image: kindest/node:v1.18.2
- role: worker
image: kindest/node:v1.18.2
- role: worker
image: kindest/node:v1.18.2
- role: worker
image: nginx:1.17
kind create cluster --config kind.yml --name kindcluster
することでクラスタを作れます。
あれ、ノードの中でpodが複数動くはずだから、kindの場合Dockerコンテナの中で複数のコンテナが動くdocker in docker状態になるということでしょうか?
apiVersion: v1
kind: Pod
metadata:
name: sample-pod
spec:
containers:
- name: nginx-container
image: nginx:1.16
上のようなymlを作成し、
kubectl apply -f sample-pod.yml
docker ps
すると
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4117db094f2c kindest/node:v1.18.2 "/usr/local/bin/entr…" 5 hours ago Up 5 hours 127.0.0.1:37973->6443/tcp kindcluster-control-plane2
798151edb29a kindest/node:v1.18.2 "/usr/local/bin/entr…" 5 hours ago Up 5 hours 127.0.0.1:37639->6443/tcp kindcluster-control-plane3
c2b7dc9b10de kindest/node:v1.18.2 "/usr/local/bin/entr…" 5 hours ago Up 5 hours kindcluster-worker
16df365d3d35 kindest/node:v1.18.2 "/usr/local/bin/entr…" 5 hours ago Up 5 hours kindcluster-worker3
311ce81d8d9b kindest/node:v1.18.2 "/usr/local/bin/entr…" 5 hours ago Up 5 hours kindcluster-worker2
6e79ead44109 kindest/haproxy:v20220207-ca68f7d4 "haproxy -sf 7 -W -d…" 5 hours ago Up 5 hours 127.0.0.1:41061->6443/tcp kindcluster-external-load-balancer
74f5e62640ed kindest/node:v1.18.2 "/usr/local/bin/entr…" 5 hours ago Up 5 hours 127.0.0.1:43043->6443/tcp kindcluster-control-plane
と出てきてどこにもnginxの姿が無いので多分コンテナ内でコンテナが動いているんでしょう。
リソース
Kubernetesでは配置するオブジェクトのことをリソースと言っています。リソースにはWorkloads APIs、Service APIs、Config & Storage APIs、Cluster APIs、Metadata APIsがあります。
kubectl
Kubernetesをインタラクティブにいじる際はkubectlというコマンドラインツールを使います。Kubernetes Masterが提供しているAPIをkubectlは叩いているだけなので、クライアントプログラムからもkubectlと同じ事ができます。kubectlは接続先の認証情報を~/.kube/configに保存しています。kindでクラスタを作ると自動で認証情報も書き出されます。
リソースの作成・変更・削除ではcreate/apply/deleteというコマンドを使います。例えば、
kubectl apply -f hoge.yml
のような形です。ただし、kubectl createでリソースを作成するのはベストプラクティスではなく、常にkubectl applyでリソースを作るべきとのことです。なぜなら、–save-configをつけずにkubectl createすると初回のマニフェストを忘れ、次回apply時に正しく差分検出できないからです。また、applyとcreateを使い分けるのも面倒です。
マニフェストの設計
マニフェストは個別にkubectl apply -f ファイル名 すればクラスタに反映されます。また、”—“で区切れば同じymlに複数のリソースを書くことができたり、kubectl apply -f ./ すれば、同一ディレクトリのマニフェストをいっぺんに適用する事もできます。では、どういうファイル分割・管理が適切かという疑問が生じますが、
- 全システムを1ディレクトリで管理
- サブシステムごとにディレクトリを分けて管理
- マイクロサービスごとに分けて管理
などのパターンがあります。ベストプラクティスやアンチパターンはこの本では紹介されていないようです。
アノテーション・ラベル
リソースにはアノテーションとラベルというものを付与できます。前者はシステムコンポーネントが使用し、後者はユーザーが検索しやすくするなどリソース管理で利用するものです。アノテーションはGKE等固有の機能を利用したい場合に付与したり、Kubernetesの実験的機能を使う時付与します。
所感
やっぱり単なる教科書の抜粋になっていてエビデンスになっていないので、この活動のやり方も考えなきゃならないですね…この本を読み進める前にもうnostrのなにかを作ってその記録をここに書くか…
コメント