6 つくって、壊して、直して学ぶ Kubernetes入門 Chapter6 Kubernetesリソースをつくって壊そう
正誤表
自分でやってみているリポジトリ
Kubectl Cheat Sheet
Chapter6 Kubernetesリソースをつくって壊そう
6.1 Podのライフサイクルを知ろう
Pod は、マニフェストが登録されてから Node にスケジュールされ、kubelet がコンテナを起動し、異常があったり完了条件を満たした場合に、終了して一生を遂げる
コンテナが起動している間はずっと Running
Pending -> Running -> Succeed or Failed
6.2 Pod を冗長化するための ReplicaSet と Deployment
Pod 単体ではコンテナ冗長化できない
Deployment というリソースを使う
Deployment →→(作成)→→ ReplicaSet →→(作成)→→ Pod
6.2.1 ReplicaSet
ReplicaSet: 指定した数の Pod を複製するリソース
Pod を複製できるところが Pod と違う
replicase で複製する Pod の数を指定
code:yaml
❯ cat replicaset.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: httpserver
labels:
app: httpserver
spec:
replicas: 3
selector:
matchLabels:
app: httpserver
template:
metadata:
labels:
app: httpserver
spec:
containers:
- name: nginx
image: nginx:1.25.3
code:sh
⛵ kind-kind bbf-k8s-learn/06 on main !⇡ took 5s ❯ k apply --filename replicaset.yaml -n default
replicaset.apps/httpserver created
⛵ kind-kind bbf-k8s-learn/06 on main !⇡ ❯ k get po
NAME READY STATUS RESTARTS AGE
httpserver-g57kt 1/1 Running 0 12s
httpserver-jlcsj 1/1 Running 0 12s
httpserver-wc9c7 1/1 Running 0 12s
ちなみに、--filename の短縮系は -f でOK
kubectl get replicasetでリソースを参照できる
rsはreplicasetのSHORTEN_NAME
DESIREDカラムから、いくつ Pod が作成されるべきかわかる
code:sh
⛵ kind-kind bbf-k8s-learn/06 on main
❯ k get rs -n default
NAME DESIRED CURRENT READY AGE
httpserver 3 3 3 3m3s
お掃除
code:sh
⛵ kind-kind bbf-k8s-learn/06 on main
❯ k delete rs httpserver -n default
replicaset.apps "httpserver" deleted
6.2.2 Deployment
ReplicaSet も直接利用することは推奨されていない
より本番運用に向いている Deployment を利用することが推奨
本番の運用時、Pod の更新時に「無停止で更新する」が求められる
コンテナイメージがv1のPodのReplicaSet
コンテなイメージがv2のPodのReplicaSet
v1とv2を切り替えるには、ReplicaSetの上位の概念が必要
ReplicaSetを複数紐づけるのが Deployment
code: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.24.0
ports:
- containerPort: 80
Deployment の作成
code:sh
❯ k apply -f deployment.yaml -n default
deployment.apps/nginx-deployment created
❯ k get deploy -n default
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 3m21s
# Podも
❯ k get po -n default
NAME READY STATUS RESTARTS AGE
nginx-deployment-595dff4799-6r49x 1/1 Running 0 5m2s
nginx-deployment-595dff4799-mdmfx 1/1 Running 0 5m2s
nginx-deployment-595dff4799-vp268 1/1 Running 0 5m2s
# ReplicaSetもある
⛵ kind-kind bbf-k8s-learn/06 on main
❯ k get rs -n default
NAME DESIRED CURRENT READY AGE
nginx-deployment-595dff4799 3 3 3 5m4s
短い省略形を見るコマンドは、kubectl api-resources
deployment.yamlのイメージタグを変更して、もう一度applyした
code:sh
⛵ kind-kind bbf-k8s-learn/06 on main took 2s
❯ k apply -f deployment.yaml -n default
deployment.apps/nginx-deployment configured
# pod名が新しい
⛵ kind-kind bbf-k8s-learn/06 on main
❯ k get po -n default
NAME READY STATUS RESTARTS AGE
nginx-deployment-789bf7b8fc-6xzfb 1/1 Running 0 6s
nginx-deployment-789bf7b8fc-gkdrv 1/1 Running 0 5s
nginx-deployment-789bf7b8fc-l4s7t 1/1 Running 0 7s
# replicasetも新しい
⛵ kind-kind bbf-k8s-learn/06 on main
❯ k get rs -n default
NAME DESIRED CURRENT READY AGE
nginx-deployment-595dff4799 0 0 0 103s
nginx-deployment-789bf7b8fc 3 3 3 60s
# deploymentも新しい
⛵ kind-kind bbf-k8s-learn/06 on main
❯ k get deploy -n default
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 115s
# イメージの確認、新しいイメージになっている
⛵ kind-kind bbf-k8s-learn/06 on main
❯ k get deploy nginx-deployment -o=jsonpath='{.spec.template.spec.containers0.image}' nginx:1.25.3%
Deploymentでは、新規バージョン追加時の挙動を制御することもできる
StrategyType, RollingUpdateStrategy
code:sh
❯ k describe deploy nginx-deployment
Name: nginx-deployment
Namespace: default
CreationTimestamp: Wed, 26 Jun 2024 09:18:27 +0900
Labels: app=nginx
Annotations: deployment.kubernetes.io/revision: 2
Selector: app=nginx
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=nginx
Containers:
nginx:
Image: nginx:1.25.3
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Node-Selectors: <none>
Tolerations: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: nginx-deployment-595dff4799 (0/0 replicas created)
NewReplicaSet: nginx-deployment-789bf7b8fc (3/3 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 4m12s deployment-controller Scaled up replica set nginx-deployment-595dff4799 to 3
Normal ScalingReplicaSet 3m29s deployment-controller Scaled up replica set nginx-deployment-789bf7b8fc to 1
Normal ScalingReplicaSet 3m28s deployment-controller Scaled down replica set nginx-deployment-595dff4799 to 2 from 3
Normal ScalingReplicaSet 3m28s deployment-controller Scaled up replica set nginx-deployment-789bf7b8fc to 2 from 1
Normal ScalingReplicaSet 3m27s deployment-controller Scaled down replica set nginx-deployment-595dff4799 to 1 from 2
Normal ScalingReplicaSet 3m27s deployment-controller Scaled up replica set nginx-deployment-789bf7b8fc to 3 from 2
Normal ScalingReplicaSet 3m26s deployment-controller Scaled down replica set nginx-deployment-595dff4799 to 0 from 1
StrategyType
Deploymentを利用してPodを更新するとき、どんな戦略で更新するかを指定する
以下の2つが選択可能
Recreate: 全部のPodを同時に更新
RollingUpdate: Podを順番に更新
こちらを選んだ場合、RollingUpdateStrategyを記載することができる
デフォルトでは、RollingUpdateで更新し、25% max unavailable, 25% max surgeが指定される
RollingUpdateStrategy
このフィールドには、Rolling Updateをどのように実現するかを書くことができる
k8sは、RollingUpdateをサポートするために、ReplicaSet より上位概念の Deployment を導入している
RollingUpdateStrategyで指定できるのは以下の2つ
max Unavailable: 最大いくつのPodを同時にシャットダウンできるか
デフォルトの25%は、「Pod全体の25%まで同時にシャットダウン可能」
パーセンテージ以外に固定値を書くこともOK
maxSurge: 最大いくつのPodを新規作成できるか
Rolling Update では、古いPodをシャットダウンしながら、更新先の新しいPodを作っていく
kubectl get pod --watchで、--watchをつけることで、kubectl get podの結果を監視し続けられる!(便利)
Recreateで試す
以下のマニフェストで、strategyにRecreateを指定した場合
code:yaml
spec:
replicas: 10
strategy:
type: Recreate # strategy type
マニフェストを適用した後、イメージタグを変更してapplyした時の監視の様子
Podが一気に、Terminating -> ContainerCreating -> Running と遷移
Recreateは同時に全てのPodを再作成するため、Podが更新完了するまでの速度は速いが、再作成時にアプリケーションが接続不能になってしまう
code:sh
❯ k get po --watch
NAME READY STATUS RESTARTS AGE
nginx-deployment-58556b4d6b-59mfp 1/1 Running 0 51s
nginx-deployment-58556b4d6b-5m829 1/1 Running 0 51s
nginx-deployment-58556b4d6b-794t9 1/1 Running 0 51s
nginx-deployment-58556b4d6b-9rwdj 1/1 Running 0 51s
nginx-deployment-58556b4d6b-b77tp 1/1 Running 0 51s
nginx-deployment-58556b4d6b-drrbj 1/1 Running 0 51s
nginx-deployment-58556b4d6b-mnvqf 1/1 Running 0 51s
nginx-deployment-58556b4d6b-t4lt2 1/1 Running 0 51s
nginx-deployment-58556b4d6b-vcnx4 1/1 Running 0 51s
nginx-deployment-58556b4d6b-zj7ql 1/1 Running 0 51s
nginx-deployment-58556b4d6b-drrbj 1/1 Terminating 0 104s
nginx-deployment-58556b4d6b-59mfp 1/1 Terminating 0 104s
nginx-deployment-58556b4d6b-zj7ql 1/1 Terminating 0 104s
nginx-deployment-58556b4d6b-5m829 1/1 Terminating 0 104s
nginx-deployment-58556b4d6b-9rwdj 1/1 Terminating 0 104s
nginx-deployment-58556b4d6b-794t9 1/1 Terminating 0 104s
nginx-deployment-58556b4d6b-mnvqf 1/1 Terminating 0 104s
nginx-deployment-58556b4d6b-b77tp 1/1 Terminating 0 104s
nginx-deployment-58556b4d6b-t4lt2 1/1 Terminating 0 104s
nginx-deployment-58556b4d6b-vcnx4 1/1 Terminating 0 104s
nginx-deployment-58556b4d6b-794t9 0/1 Terminating 0 114s
nginx-deployment-58556b4d6b-9rwdj 0/1 Terminating 0 114s
nginx-deployment-58556b4d6b-5m829 0/1 Terminating 0 114s
nginx-deployment-58556b4d6b-b77tp 0/1 Terminating 0 114s
nginx-deployment-58556b4d6b-59mfp 0/1 Terminating 0 114s
nginx-deployment-58556b4d6b-mnvqf 0/1 Terminating 0 114s
nginx-deployment-58556b4d6b-vcnx4 0/1 Terminating 0 114s
nginx-deployment-58556b4d6b-drrbj 0/1 Terminating 0 114s
nginx-deployment-58556b4d6b-t4lt2 0/1 Terminating 0 114s
nginx-deployment-58556b4d6b-zj7ql 0/1 Terminating 0 114s
nginx-deployment-58556b4d6b-drrbj 0/1 Terminating 0 115s
nginx-deployment-58556b4d6b-b77tp 0/1 Terminating 0 115s
nginx-deployment-58556b4d6b-794t9 0/1 Terminating 0 115s
nginx-deployment-58556b4d6b-vcnx4 0/1 Terminating 0 115s
nginx-deployment-58556b4d6b-9rwdj 0/1 Terminating 0 115s
nginx-deployment-58556b4d6b-mnvqf 0/1 Terminating 0 115s
nginx-deployment-58556b4d6b-zj7ql 0/1 Terminating 0 115s
nginx-deployment-58556b4d6b-mnvqf 0/1 Terminating 0 115s
nginx-deployment-58556b4d6b-mnvqf 0/1 Terminating 0 115s
nginx-deployment-58556b4d6b-9rwdj 0/1 Terminating 0 115s
nginx-deployment-58556b4d6b-9rwdj 0/1 Terminating 0 115s
nginx-deployment-58556b4d6b-5m829 0/1 Terminating 0 115s
nginx-deployment-58556b4d6b-5m829 0/1 Terminating 0 115s
nginx-deployment-58556b4d6b-5m829 0/1 Terminating 0 115s
nginx-deployment-58556b4d6b-drrbj 0/1 Terminating 0 115s
nginx-deployment-58556b4d6b-drrbj 0/1 Terminating 0 115s
nginx-deployment-58556b4d6b-zj7ql 0/1 Terminating 0 115s
nginx-deployment-58556b4d6b-zj7ql 0/1 Terminating 0 115s
nginx-deployment-58556b4d6b-b77tp 0/1 Terminating 0 115s
nginx-deployment-58556b4d6b-b77tp 0/1 Terminating 0 115s
nginx-deployment-58556b4d6b-794t9 0/1 Terminating 0 115s
nginx-deployment-58556b4d6b-794t9 0/1 Terminating 0 115s
nginx-deployment-58556b4d6b-t4lt2 0/1 Terminating 0 115s
nginx-deployment-58556b4d6b-t4lt2 0/1 Terminating 0 115s
nginx-deployment-58556b4d6b-t4lt2 0/1 Terminating 0 115s
nginx-deployment-58556b4d6b-vcnx4 0/1 Terminating 0 115s
nginx-deployment-58556b4d6b-vcnx4 0/1 Terminating 0 115s
nginx-deployment-58556b4d6b-59mfp 0/1 Terminating 0 115s
nginx-deployment-58556b4d6b-59mfp 0/1 Terminating 0 115s
nginx-deployment-58556b4d6b-59mfp 0/1 Terminating 0 115s
nginx-deployment-7947b6d4f6-lk9v4 0/1 Pending 0 0s
nginx-deployment-7947b6d4f6-mj5v6 0/1 Pending 0 0s
nginx-deployment-7947b6d4f6-s6plf 0/1 Pending 0 0s
nginx-deployment-7947b6d4f6-lk9v4 0/1 Pending 0 0s
nginx-deployment-7947b6d4f6-mj5v6 0/1 Pending 0 0s
nginx-deployment-7947b6d4f6-s6plf 0/1 Pending 0 0s
nginx-deployment-7947b6d4f6-fjlwf 0/1 Pending 0 0s
nginx-deployment-7947b6d4f6-4hks8 0/1 Pending 0 0s
nginx-deployment-7947b6d4f6-f9qg9 0/1 Pending 0 0s
nginx-deployment-7947b6d4f6-6pc29 0/1 Pending 0 0s
nginx-deployment-7947b6d4f6-lk9v4 0/1 ContainerCreating 0 0s
nginx-deployment-7947b6d4f6-4hks8 0/1 Pending 0 0s
nginx-deployment-7947b6d4f6-566k7 0/1 Pending 0 0s
nginx-deployment-7947b6d4f6-h426t 0/1 Pending 0 0s
nginx-deployment-7947b6d4f6-f9qg9 0/1 Pending 0 0s
nginx-deployment-7947b6d4f6-j8m8p 0/1 Pending 0 0s
nginx-deployment-7947b6d4f6-fjlwf 0/1 Pending 0 0s
nginx-deployment-7947b6d4f6-6pc29 0/1 Pending 0 0s
nginx-deployment-7947b6d4f6-h426t 0/1 Pending 0 0s
nginx-deployment-7947b6d4f6-566k7 0/1 Pending 0 0s
nginx-deployment-7947b6d4f6-j8m8p 0/1 Pending 0 0s
nginx-deployment-7947b6d4f6-mj5v6 0/1 ContainerCreating 0 0s
nginx-deployment-7947b6d4f6-s6plf 0/1 ContainerCreating 0 0s
nginx-deployment-7947b6d4f6-j8m8p 0/1 ContainerCreating 0 0s
nginx-deployment-7947b6d4f6-h426t 0/1 ContainerCreating 0 0s
nginx-deployment-7947b6d4f6-566k7 0/1 ContainerCreating 0 0s
nginx-deployment-7947b6d4f6-4hks8 0/1 ContainerCreating 0 0s
nginx-deployment-7947b6d4f6-6pc29 0/1 ContainerCreating 0 0s
nginx-deployment-7947b6d4f6-fjlwf 0/1 ContainerCreating 0 0s
nginx-deployment-7947b6d4f6-f9qg9 0/1 ContainerCreating 0 0s
nginx-deployment-7947b6d4f6-f9qg9 1/1 Running 0 1s
nginx-deployment-7947b6d4f6-566k7 1/1 Running 0 1s
nginx-deployment-7947b6d4f6-lk9v4 1/1 Running 0 1s
nginx-deployment-7947b6d4f6-s6plf 1/1 Running 0 1s
nginx-deployment-7947b6d4f6-4hks8 1/1 Running 0 1s
nginx-deployment-7947b6d4f6-fjlwf 1/1 Running 0 1s
nginx-deployment-7947b6d4f6-j8m8p 1/1 Running 0 1s
nginx-deployment-7947b6d4f6-h426t 1/1 Running 0 1s
nginx-deployment-7947b6d4f6-mj5v6 1/1 Running 0 1s
nginx-deployment-7947b6d4f6-6pc29 1/1 Running 0 1s
nginx-deployment-7947b6d4f6-f9qg9 1/1 Terminating 0 40s
nginx-deployment-7947b6d4f6-lk9v4 1/1 Terminating 0 40s
nginx-deployment-7947b6d4f6-4hks8 1/1 Terminating 0 40s
nginx-deployment-7947b6d4f6-6pc29 1/1 Terminating 0 40s
nginx-deployment-7947b6d4f6-mj5v6 1/1 Terminating 0 40s
nginx-deployment-7947b6d4f6-566k7 1/1 Terminating 0 40s
nginx-deployment-7947b6d4f6-s6plf 1/1 Terminating 0 40s
nginx-deployment-7947b6d4f6-h426t 1/1 Terminating 0 40s
nginx-deployment-7947b6d4f6-j8m8p 1/1 Terminating 0 40s
nginx-deployment-7947b6d4f6-fjlwf 1/1 Terminating 0 40s
Rolling Updateで試す
code:yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 10
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 25%
maxSurge: 100%
(以下略)
Podが更新されていく様子
Podの数が途中で倍になっている(?)
max surgeが100%は、元あったPodの数と同じ数だけ新規Podを作成すること
Podの更新が最も早く、かつ安全ではあるが、必要なリソースが倍になるため、リソースキャパシティに注意
code:sh
❯ k get po --watch
NAME READY STATUS RESTARTS AGE
nginx-deployment-58556b4d6b-2cbkx 1/1 Running 0 71s
nginx-deployment-58556b4d6b-4td4j 1/1 Running 0 71s
nginx-deployment-58556b4d6b-6vdbf 1/1 Running 0 71s
nginx-deployment-58556b4d6b-9qqpp 1/1 Running 0 71s
nginx-deployment-58556b4d6b-czwcv 1/1 Running 0 71s
nginx-deployment-58556b4d6b-d9qhj 1/1 Running 0 71s
nginx-deployment-58556b4d6b-k6vls 1/1 Running 0 71s
nginx-deployment-58556b4d6b-kpfnj 1/1 Running 0 71s
nginx-deployment-58556b4d6b-r4vw4 1/1 Running 0 71s
nginx-deployment-58556b4d6b-x7q4h 1/1 Running 0 71s
nginx-deployment-7947b6d4f6-4cz42 0/1 Pending 0 0s
nginx-deployment-7947b6d4f6-4cz42 0/1 Pending 0 0s
nginx-deployment-7947b6d4f6-ffk8g 0/1 Pending 0 0s
nginx-deployment-7947b6d4f6-vb5tb 0/1 Pending 0 0s
nginx-deployment-7947b6d4f6-ffk8g 0/1 Pending 0 0s
nginx-deployment-7947b6d4f6-t9c7z 0/1 Pending 0 0s
nginx-deployment-7947b6d4f6-jdtnj 0/1 Pending 0 0s
nginx-deployment-7947b6d4f6-vsbvx 0/1 Pending 0 0s
nginx-deployment-7947b6d4f6-vb5tb 0/1 Pending 0 0s
nginx-deployment-7947b6d4f6-zbm5n 0/1 Pending 0 0s
nginx-deployment-58556b4d6b-2cbkx 1/1 Terminating 0 82s
nginx-deployment-7947b6d4f6-t9c7z 0/1 Pending 0 0s
nginx-deployment-58556b4d6b-k6vls 1/1 Terminating 0 82s
nginx-deployment-7947b6d4f6-jdtnj 0/1 Pending 0 0s
nginx-deployment-7947b6d4f6-vsbvx 0/1 Pending 0 0s
nginx-deployment-7947b6d4f6-rbd5v 0/1 Pending 0 0s
nginx-deployment-7947b6d4f6-7n7dl 0/1 Pending 0 0s
nginx-deployment-7947b6d4f6-qqlzj 0/1 Pending 0 0s
nginx-deployment-7947b6d4f6-4cz42 0/1 ContainerCreating 0 0s
nginx-deployment-7947b6d4f6-zbm5n 0/1 Pending 0 0s
nginx-deployment-7947b6d4f6-rbd5v 0/1 Pending 0 0s
nginx-deployment-7947b6d4f6-7n7dl 0/1 Pending 0 0s
nginx-deployment-7947b6d4f6-qqlzj 0/1 Pending 0 0s
nginx-deployment-7947b6d4f6-t9c7z 0/1 ContainerCreating 0 0s
nginx-deployment-7947b6d4f6-vsbvx 0/1 ContainerCreating 0 0s
nginx-deployment-7947b6d4f6-ffk8g 0/1 ContainerCreating 0 0s
nginx-deployment-7947b6d4f6-vb5tb 0/1 ContainerCreating 0 0s
nginx-deployment-7947b6d4f6-jdtnj 0/1 ContainerCreating 0 0s
nginx-deployment-7947b6d4f6-7n7dl 0/1 ContainerCreating 0 0s
nginx-deployment-7947b6d4f6-rbd5v 0/1 ContainerCreating 0 0s
nginx-deployment-7947b6d4f6-qqlzj 0/1 ContainerCreating 0 0s
nginx-deployment-7947b6d4f6-zbm5n 0/1 ContainerCreating 0 0s
nginx-deployment-7947b6d4f6-t9c7z 1/1 Running 0 1s
nginx-deployment-7947b6d4f6-vb5tb 1/1 Running 0 1s
nginx-deployment-58556b4d6b-czwcv 1/1 Terminating 0 83s
nginx-deployment-7947b6d4f6-4cz42 1/1 Running 0 1s
nginx-deployment-58556b4d6b-kpfnj 1/1 Terminating 0 83s
nginx-deployment-58556b4d6b-d9qhj 1/1 Terminating 0 83s
nginx-deployment-7947b6d4f6-qqlzj 1/1 Running 0 2s
nginx-deployment-7947b6d4f6-zbm5n 1/1 Running 0 2s
nginx-deployment-58556b4d6b-9qqpp 1/1 Terminating 0 84s
nginx-deployment-7947b6d4f6-jdtnj 1/1 Running 0 2s
nginx-deployment-7947b6d4f6-7n7dl 1/1 Running 0 2s
nginx-deployment-58556b4d6b-4td4j 1/1 Terminating 0 84s
nginx-deployment-58556b4d6b-6vdbf 1/1 Terminating 0 84s
nginx-deployment-7947b6d4f6-ffk8g 1/1 Running 0 2s
nginx-deployment-7947b6d4f6-rbd5v 1/1 Running 0 2s
nginx-deployment-7947b6d4f6-vsbvx 1/1 Running 0 2s
nginx-deployment-58556b4d6b-x7q4h 1/1 Terminating 0 84s
nginx-deployment-58556b4d6b-r4vw4 1/1 Terminating 0 84s
nginx-deployment-58556b4d6b-2cbkx 0/1 Terminating 0 92s
nginx-deployment-58556b4d6b-k6vls 0/1 Terminating 0 92s
nginx-deployment-58556b4d6b-2cbkx 0/1 Terminating 0 93s
nginx-deployment-58556b4d6b-k6vls 0/1 Terminating 0 93s
nginx-deployment-58556b4d6b-k6vls 0/1 Terminating 0 93s
nginx-deployment-58556b4d6b-k6vls 0/1 Terminating 0 93s
nginx-deployment-58556b4d6b-2cbkx 0/1 Terminating 0 93s
nginx-deployment-58556b4d6b-2cbkx 0/1 Terminating 0 93s
nginx-deployment-58556b4d6b-czwcv 0/1 Terminating 0 93s
nginx-deployment-58556b4d6b-kpfnj 0/1 Terminating 0 93s
nginx-deployment-58556b4d6b-d9qhj 0/1 Terminating 0 93s
nginx-deployment-58556b4d6b-d9qhj 0/1 Terminating 0 94s
nginx-deployment-58556b4d6b-czwcv 0/1 Terminating 0 94s
nginx-deployment-58556b4d6b-czwcv 0/1 Terminating 0 94s
nginx-deployment-58556b4d6b-czwcv 0/1 Terminating 0 94s
nginx-deployment-58556b4d6b-d9qhj 0/1 Terminating 0 94s
nginx-deployment-58556b4d6b-d9qhj 0/1 Terminating 0 94s
nginx-deployment-58556b4d6b-kpfnj 0/1 Terminating 0 94s
nginx-deployment-58556b4d6b-kpfnj 0/1 Terminating 0 94s
nginx-deployment-58556b4d6b-kpfnj 0/1 Terminating 0 94s
nginx-deployment-58556b4d6b-4td4j 0/1 Terminating 0 94s
nginx-deployment-58556b4d6b-r4vw4 0/1 Terminating 0 94s
nginx-deployment-58556b4d6b-9qqpp 0/1 Terminating 0 94s
nginx-deployment-58556b4d6b-6vdbf 0/1 Terminating 0 94s
nginx-deployment-58556b4d6b-x7q4h 0/1 Terminating 0 94s
nginx-deployment-58556b4d6b-6vdbf 0/1 Terminating 0 95s
nginx-deployment-58556b4d6b-9qqpp 0/1 Terminating 0 95s
nginx-deployment-58556b4d6b-4td4j 0/1 Terminating 0 95s
nginx-deployment-58556b4d6b-6vdbf 0/1 Terminating 0 95s
nginx-deployment-58556b4d6b-6vdbf 0/1 Terminating 0 95s
nginx-deployment-58556b4d6b-r4vw4 0/1 Terminating 0 95s
nginx-deployment-58556b4d6b-r4vw4 0/1 Terminating 0 95s
nginx-deployment-58556b4d6b-r4vw4 0/1 Terminating 0 95s
nginx-deployment-58556b4d6b-x7q4h 0/1 Terminating 0 95s
nginx-deployment-58556b4d6b-x7q4h 0/1 Terminating 0 95s
nginx-deployment-58556b4d6b-x7q4h 0/1 Terminating 0 95s
nginx-deployment-58556b4d6b-9qqpp 0/1 Terminating 0 95s
nginx-deployment-58556b4d6b-9qqpp 0/1 Terminating 0 95s
nginx-deployment-58556b4d6b-4td4j 0/1 Terminating 0 95s
nginx-deployment-58556b4d6b-4td4j 0/1 Terminating 0 95s
6.2.3 つくって、直す Deploymentをつくって壊そう
Podが消されたら、代わりのPodが新しく作られる
Deploymentを利用することで、Podが消されても必ずDesiredなPod数に一致するようKubernetesが自動で再作成してくれる
deploymnentのUP-TO-DATEが1
古いバージョンのPodをそのままに、新規バージョンのPodを1個作成中にエラーになっている
デフォルトの maxUnavailable:25%、maxSurge: 25% は、Pod数が3つの場合、25%は0.75になる
code:sh
❯ k get deployment -n default
NAME READY UP-TO-DATE AVAILABLE AGE
hello-server 3/3 1 3 2m5s
bbf-kubernetes on main ! ❯ k get rs -n default
NAME DESIRED CURRENT READY AGE
hello-server-6cc6b44795 3 3 3 3m26s
hello-server-6fb85ff748 1 1 0 2m10s
# エラーでているpodをdescribe、1.3のタグは見つからないというエラー
❯ k describe po hello-server-6fb85ff748-c5vld -n default
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal BackOff 13m (x502 over 10h) kubelet Back-off pulling image "blux2/hello-server:1.3"
# deploymentのマニフェストファイルのタグを変更
❯ k edit deployment hello-server -n default
deployment.apps/hello-server edited
# podとreplicasetを見る、Rolloing Updateが完了している
❯ k get po,rs -n default
NAME READY STATUS RESTARTS AGE
pod/hello-server-5d6fd6dbb9-85k5t 1/1 Running 0 56s
pod/hello-server-5d6fd6dbb9-m8pbh 1/1 Running 0 50s
pod/hello-server-5d6fd6dbb9-q6cvd 1/1 Running 0 49s
NAME DESIRED CURRENT READY AGE
replicaset.apps/hello-server-5d6fd6dbb9 3 3 3 56s
replicaset.apps/hello-server-6cc6b44795 0 0 0 10h
replicaset.apps/hello-server-6fb85ff748 0 0 0 10h
# curlして疎通確認、新しいメッセージがでているので、Rolling Updateが完了している
❯ curl localhost:8080
Hello, world! Let's learn Kubernetes!%
6.3 Pod へのアクセスを助ける Service
DeploymentはIPアドレスを持たない
Deploymentで作ったリソースにアクセスするには、IPアドレスが割り振られているPod個々にアクセスする必要がある
RollingUpdateでPodが消えてしまえば接続は切れてしまう
Deploymentで作成した複数Podへのアクセスを適切にルーティングしてもらうために、Serviceというリソースを利用する
code:yaml
apiVersion: v1
kind: Service
metadata:
name: hello-server-service
spec:
selector:
ports:
- protocol: TCP
port: 8080
code:sh
❯ k apply -f chapter-06/deployment-hello-server.yaml -n default
deployment.apps/hello-server created
bbf-kubernetes on main ! ❯ k get po -n default
NAME READY STATUS RESTARTS AGE
hello-server-6cc6b44795-5lxnq 1/1 Running 0 5s
hello-server-6cc6b44795-82hnl 1/1 Running 0 5s
hello-server-6cc6b44795-vjzh6 1/1 Running 0 5s
# Service作成
bbf-kubernetes on main ! ❯ k apply -f chapter-06/service.yaml -n default
service/hello-server-service created
# Serviceができている
bbf-kubernetes on main ! ❯ k get service hello-server-service -n default
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-server-service ClusterIP 10.96.176.27 <none> 8080/TCP 9s
# port-forwardして疎通確認OK(別ターミナルでcurlした)
bbf-kubernetes on main ! ❯ k port-forward svc/hello-server-service 8080:8080 -n default
Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from ::1:8080 -> 8080 Handling connection for 8080
^C%
code:sh
bbf-kubernetes on main ! took 46s ❯ curl localhost:8080
Hello, world!%
6.3.1 ServiceのTypeを知ろう
kubectl get serviceの出力に、TYPEがある
ServiceにはいくつかのTypeがあり、作成時に指定できる
Type未指定の場合、デフォルトでClusterIPが指定される
ClusterIP:
クラスタ内部のIPアドレスでServiceを公開
このIPはクラスタ内部からしか疎通できない
Ingressというリソースを使って外部公開が可能
NodePort:
全てのNodeのIPで指定したポート番号(NodePort)を公開
LoadBalancer:
外部ロードバランサを利用して外部IPを公開
ロードバランサは別で用意する
ExternalName:
ServiceをexternalNameフィールドの内容にマッピング
このマッピングにより、クラスタのDNSサーバがその外部ホスト名を持つCNAMEレコードを返すように設定される
Type: ClusterIP
code:sh
❯ k get service hello-server-service -n default
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-server-service ClusterIP 10.96.176.27 <none> 8080/TCP 23h
❯ k run curl --image curlimages/curl --rm --stdin --tty -- restart=Never -- curl 10.96.176.27:8080
❯ k logs curl
curl: (3) URL rejected: Bad hostname
curl: (7) Failed to connect to curl port 80 after 0 ms: Couldn't connect to server
Hello, world!%
なんかうまくいかない
テキストでは、k runのプロンプトで、Hello, world!が返るのに、ログで見ないと見れないし、ログにもエラーが出てるぞ
Type: NodePort
NodePortを利用するとクラスタ外からもアクセスが可能になる
port-forwardする必要なくなる
Docker Desktop + kind の人は事前準備が必要
以下のkind createコマンドで、NodePortを利用できるkindクラスタを構築(事前準備)
code:sh
❯ kind create cluster -n kind-nodeport --config kind/export-mapping.yaml --image=kindest/node:v1.29.0
Creating cluster "kind-nodeport" ...
✓ Ensuring node image (kindest/node:v1.29.0) 🖼
✓ Preparing nodes 📦
✓ Writing configuration 📜
✓ Starting control-plane 🕹️
✓ Installing CNI 🔌
✓ Installing StorageClass 💾
Set kubectl context to "kind-kind-nodeport"
You can now use your cluster with:
kubectl cluster-info --context kind-kind-nodeport
Thanks for using kind! 😊
NodePortのServiceを作成
code:yaml
❯ cat chapter-06/service-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
name: hello-server-external
spec:
type: NodePort
selector:
app: hello-server
ports:
- port: 8080
targetPort: 8080
nodePort: 30599
code:sh
# Deployment作成し直し
❯ k apply -f chapter-06/deployment-hello-server.yaml -n default
deployment.apps/hello-server created
# NodePortのServiceを作成
❯ k apply -f chapter-06/service-nodeport.yaml -n default
service/hello-server-external created
# 作成したService
❯ k get service hello-server-external -n default
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-server-external NodePort 10.96.60.99 <none> 8080:30599/TCP 97s
アクセスしてみる
code:sh
# NodeのIPを取得
172.18.0.3%
❯ curl 172.18.0.3:30599
# DockerDesktop + kindの人はこれでアクセス
❯ curl localhost:30599
Hello, world!%
NodePortは、全Nodeに対してPortを紐づけるので、port-forwardをしなくてもhello-serverにアクセスできる
便利だけど、NodePortはNodeが故障で利用できなくなると使えない、ローカル開発では便利だけど、本番では、ClusterIP やLoadBalancerを使う方が良いよ
6.3.2 Serviceを利用したDNS
クラスタ内アクセスする時、IPアドレスでアクセスすると、IPが変わるとアプリに接続できなくなっちゃう
k8sでは、Service用のDNSレコードを自動で作成してくれるため、FQDNを覚えておくと便利
FQDN(Fully Qualified Domain Name)は、完全修飾ドメイン名の略称
code:sh
<ホスト名>.<サブドメイン>.<ドメイン>.<トップレベルドメイン>
www.example.com
#www はホスト名、example はドメイン名、 com はトップレベルドメイン(TLD) 通常、Serviceは、次のコマンドで接続可能
code:sh
<Service名>.<Namespace名>.svc.cluster.local
kubectl runで、Pod内からcurlして、hello-servcer-serviceにアクセスできた🙌
code:sh
❯ k -n default run curl --image curlimages/curl --rm --stdin --tty --restart=Never --command -- curl hello-server-service.default.svc.cluster.local:8080
Hello, world!pod "curl" deleted
6.3.3 壊す Serviceを壊してみる
壊したら、curlで失敗するようになった
code:sh
❯ curl localhost:30599
curl: (52) Empty reply from server
Pod、Deployment、Serviceのリソース問題なさそう
なるべくアプリケーションに近いところから切り分けていく
1.Pod内からアプリケーションの接続確認
2.クラスタ内かつ別Podから接続確認
3.クラスタ内かつ別PodからService経由で接続確認
1.Pod内からアプリケーションの接続確認
コンテナにはシェルが入ってないのでデバッグ用コンテナを起動して確認する
kubectl debugは、デバッグ用のサイドカーコンテナを立ち上げるコマンド
default名前空間のhello-server-6cc6b44795-9xvhlというPodに対して、curlimages/curlイメージを使用してインタラクティブなシェルセッションが開始される
これにより、そのPod内のhello-serverコンテナをターゲットにしたデバッグが可能
問題なかった
code:sh
❯ k -n default debug --stdin --tty hello-server-6cc6b44795-9xvhl --image curlimages/curl --target=hello-server -- sh
Targeting container "hello-server". If you don't see processes from this container it may be because the container runtime doesn't support this feature.
Defaulting debug container name to debugger-gc9zw.
If you don't see a command prompt, try pressing enter.
~ $ curl localhost:8080
Hello, world!~ $ exit
Session ended, the ephemeral container will not be restarted but may be reattached using 'kubectl attach hello-server-6cc6b44795-9xvhl -c debugger-gc9zw -i -t' if it is still running
2.クラスタ内かつ別Podから接続確認
code:sh
❯ k get po -o custom-columns=NAME:metadata.name,IP:.status.podIP
NAME IP
hello-server-6cc6b44795-9xvhl 10.244.0.13
hello-server-6cc6b44795-gm5h2 10.244.0.15
hello-server-6cc6b44795-zn6jb 10.244.0.14
❯ k -n default run curl --image curlimages/curl --rm --stdin --tty --restart=Never --command -- curl 10.244.0.13:8080
Hello, world!pod "curl" deleted
こうやって欲しい情報だけcustom-columnsを使って k get podできるよう!便利そうー
今度は、debugコマンドでなく、kubectl runコマンドを使った(特定のPodに対するdebugではなく、新たにPodを立ち上げて接続確認したいからだと思う)
クラスタ内かつ別Podからもアクセスできるので、Podの問題ではなさそう
3.クラスタ内かつ別PodからService経由で接続確認
code:sh
bbf-kubernetes on main ! took 6s ❯ k get svc -o custom-columns=NAME:.metadata.name,IP:.spec.clusterIP
NAME IP
hello-server-external 10.96.166.198
kubernetes 10.96.0.1
# hello-server-externalのIP経由でアクセス
bbf-kubernetes on main ! ❯ k -n default run curl --image curlimages/curl --rm --stdin --tty --restart=Never --command -- curl 10.96.166.198:8080
curl: (7) Failed to connect to 10.96.166.198 port 8080 after 0 ms: Could not connect to server
pod "curl" deleted
pod default/curl terminated (Error)
Serviceを経由するとアクセスできなくなることがわかった💡
code:sh
❯ k describe svc hello-server-external -n default
Name: hello-server-external
Namespace: default
Labels: <none>
Annotations: <none>
Selector: app=hello-serve
Type: NodePort
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.96.166.198
IPs: 10.96.166.198
Port: <unset> 8080/TCP
TargetPort: 8080/TCP
NodePort: <unset> 30599/TCP
Endpoints: <none>
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
Selectorのapp=hello-serveの末尾のrがない!
diffを以下のコマンドで取ると、差異がわかりやすい
kubectl diffコマンドは、Kubernetesクラスタ上のリソースとローカルファイルやマニフェストで定義されているリソースの差分を表示するために使用するコマンド
code:sh
❯ k diff -f chapter-06/service-nodeport.yaml
diff -u -N /var/folders/w4/71pzh9dx2t7657lm69xggmqc0000gn/T/LIVE-118449844/v1.Service.default.hello-server-external /var/folders/w4/71pzh9dx2t7657lm69xggmqc0000gn/T/MERGED-3309186319/v1.Service.default.hello-server-external
--- /var/folders/w4/71pzh9dx2t7657lm69xggmqc0000gn/T/LIVE-118449844/v1.Service.default.hello-server-external 2024-08-07 08:10:04
+++ /var/folders/w4/71pzh9dx2t7657lm69xggmqc0000gn/T/MERGED-3309186319/v1.Service.default.hello-server-external 2024-08-07 08:10:04
@@ -24,7 +24,7 @@
protocol: TCP
targetPort: 8080
selector:
- app: hello-serve
+ app: hello-server
sessionAffinity: None
type: NodePort
status:
元々のマニフェストをapplyし直すことで修正
code:sh
bbf-kubernetes on main ! ❯ k apply -f chapter-06/service-nodeport.yaml -n default
service/hello-server-external configured
bbf-kubernetes on main ! ❯ curl localhost:30599
Hello, world!%
6.4 Pod の外部から情報を読み込む ConfigMap
環境変数など、コンテナの外部から値を設定したい時に利用するリソース
環境ごとに異なるデータベース名、ユーザー名などを変更する可能性がある全ての設定情報に使える
利用方法3つ、2と3をよく利用する
1. コンテナ内のコマンドの引数として読み込む
2. コンテナの環境変数として読み込む
3. ボリュームを利用してアプリケーションのファイルとして読み込む
6.4.1 コンテナの環境変数として読み込む
環境変数を利用してアプリケーションに値を渡す
code:yml
apiVersion: apps/v1
kind: Deployment
(略)
spec:
containers:
- name: hello-server
image: blux2/hello-server:1.4
env: # コンテナの環境変数を設定
- name: PORT
valueFrom:
configMapKeyRef:
name: hello-server-configmap # ConfigMapの名前
key: PORT # 利用するkey
(略)
apiVersion: v1
kind: ConfigMap
metadata:
name: hello-server-configmap
data:
PORT: "8081"
configmapをapplyしようとするとこのようなエラーになる :cry
クラスタがおかしいかもしれない・・・
code:sh
❯ k get po
The connection to the server localhost:8080 was refused - did you specify the right host or port?
bbf-kubernetes on main ! ❯ k apply -f chapter-06/configmap/hello-server-env.yaml -n default
error: error validating "chapter-06/configmap/hello-server-env.yaml": error validating data: failed to download openapi: Get "http://localhost:8080/openapi/v2?timeout=32s": dial tcp ::1:8080: connect: connection refused; if you choose to ignore these errors, turn validation off with --validate=false 2.2章 kindでのクラスタ構築手順を見て、kindクラスタを作成しなおしたらapplyできるようになった
kindクラスタはあるのに、kubectlコマンドでget nodesなどするとエラーが返ってくる状態だった
環境変数を変更するためにアプリケーションの再作成(k rollout deployment/xxx)をしたが、これだと運用が現実的ではないので、「ボリュームを利用してコンテナに設定ファイルと読み込ませる」をすると、アプリケーションの再作成する必要ない
code:sh
bbf-kubernetes on main ! ❯ kind get clusters
kind
bbf-kubernetes on main ! ❯ kubectl get nodes
The connection to the server localhost:8080 was refused - did you specify the right host or port?
bbf-kubernetes on main ! ❯ kubectl cluster-info --context kind-kind
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
bbf-kubernetes on main ! ❯ kind delete cluster
Deleting cluster "kind" ...
bbf-kubernetes on main ! ❯ kind version
kind v0.22.0 go1.21.7 darwin/arm64
bbf-kubernetes on main ! ❯ kind get clusters
No kind clusters found.
bbf-kubernetes on main ! ❯ kind create cluster --image=kindest/node:v1.29.0
Creating cluster "kind" ...
✓ Ensuring node image (kindest/node:v1.29.0) 🖼
✓ Preparing nodes 📦
✓ Writing configuration 📜
✓ Starting control-plane 🕹️
✓ Installing CNI 🔌
✓ Installing StorageClass 💾
Set kubectl context to "kind-kind"
You can now use your cluster with:
kubectl cluster-info --context kind-kind
Thanks for using kind! 😊
bbf-kubernetes on main ! took 12s ❯ kind get clusters
kind
bbf-kubernetes on main ! ❯ k apply -f chapter-06/configmap/hello-server-env.yaml -n default
deployment.apps/hello-server created
configmap/hello-server-configmap created
❯ k get deployment,configmap -n default
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/hello-server 1/1 1 1 2m22s
NAME DATA AGE
configmap/hello-server-configmap 1 2m22s
configmap/kube-root-ca.crt 1 2m23s
6.4.2 ボリュームを利用してアプリケーションのファイルとして読み込む
Podにはボリュームを設定できる
消えてほしくないファイルを保存したり、Pod間でファイルを共有したりするファイルシステムを利用するために利用
ConfigMapからボリュームを作成し、コンテナにボリュームを読み込む
6.4.3 壊す ConfigMap を設定したら壊れた!
ConfigMapを変更したら壊れることはよくある、変更してないせいで壊れることも
ConfigMapに値を書き忘れていたり、デプロイされていなかったり
トラブルシューティング
アプリケーションが壊れた!
code:sh
bbf-kubernetes on main ! ❯ curl localhost:8081
curl: (52) Empty reply from server
bbf-kubernetes on main ! ❯ k get po -n default
NAME READY STATUS RESTARTS AGE
hello-server-67588987f-2xpk9 0/1 CreateContainerConfigError 0 18s
k describe po した結果
Eventに、configmapにHOSTというkeyがないと出ている
code:sh
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 74s default-scheduler Successfully assigned default/hello-server-67588987f-2xpk9 to kind-control-plane
Normal Pulled 6s (x7 over 74s) kubelet Container image "blux2/hello-server:1.4" already present on machine
Warning Failed 6s (x7 over 74s) kubelet Error: couldn't find key HOST in ConfigMap default/hello-server-configmap
k get deployment hello-server --output yaml してマニフェストを確認する
hello-server-configmapにHOSTというkeyがあることを想定している
code:sh
- name: HOST
valueFrom:
configMapKeyRef:
key: HOST
name: hello-server-configmap
k describe configmapしてみた
PORTのkeyしかなさそう
code:sh
❯ k describe configmap
Name: hello-server-configmap
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
PORT:
----
8081
BinaryData
====
Events: <none>
Name: kube-root-ca.crt
Namespace: default
Labels: <none>
Annotations: kubernetes.io/description:
Contains a CA bundle that can be used to verify the kube-apiserver when using internal endpoints such as the internal service IP or kubern...
Data
====
(略)
k get configでいいらしい
--output yamlで指定するとみれた
やっぱりPORTしかない
DeploymentではHOSTというkeyを想定してるけど、configmap側にHOSTがないのでダメだった
code:sh
❯ k get configmap hello-server-configmap --output yaml
apiVersion: v1
data:
PORT: "8081"
kind: ConfigMap
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","data":{"PORT":"8081"},"kind":"ConfigMap","metadata":{"annotations":{},"name":"hello-server-configmap","namespace":"default"}}
creationTimestamp: "2024-08-27T23:07:36Z"
name: hello-server-configmap
namespace: default
resourceVersion: "42338"
uid: 52b7b0de-1dfd-4c86-8f91-3e65d17c5d0e
DeploymentのRollingUpgradeを使えば、接続不能になることを防いでくれるはずだけど、何が悪かったの?
改めて、k get deployment hello-server --output yaml をすると、maxSurgeが0になってた
1以上になってれば、正常動作するpodが残っていたので壊れることはなかったはず・・・
code:sh
strategy:
rollingUpdate:
maxSurge: 0
maxUnavailable: 25%
type: RollingUpdate
直そう、deployment.ymlのconfigmap部分を修正、HOSTを加える、applyする、治った!
code:sh
name: hello-server-configmap
data:
PORT: "8081"
+ HOST: "localhost"
6.5 機密データを扱うためのSecret
Secret というリソースを使用することで、アクセス権を分けられる
Secret のデータは Base64 でエンコードして登録する必要がある
Base64 のエンコードは次のコマンドで実施できる(macOSは brew install base64する必要あり)
code:sh
echo -n <エンコードしたい文字列> | base64
Secret を Pod に読み込む方法は2種類ある
1.コンテナの環境変数として読み込む
2.ボリュームを利用してコンテナに設定ファイルを読み込む
6.5.1 コンテナの環境変数として読み込む
Secret データを作成する
code:sh
bbf-kubernetes on main ! took 13s ❯ echo -n 'admin' | base64
YWRtaW4=
bbf-kubernetes on main ! ❯ echo -n 'admin123' | base64
YWRtaW4xMjM=
code:yml
❯ cat chapter-06/secret/nginx-sample.yaml
---
apiVersion: v1
kind: Pod
metadata:
name: nginx-sample
spec:
containers:
- name: nginx-container
image: nginx:1.25.3
env:
- name: USERNAME
valueFrom:
secretKeyRef:
name: nginx-secret
key: username
- name: PASSWORD
valueFrom:
secretKeyRef:
name: nginx-secret
key: password
---
apiVersion: v1
kind: Secret
metadata:
name: nginx-secret
type: Opaque
data:
username: YWRtaW4=
password: YWRtaW4xMjM=
↑ Pod と Secret のマニフェスト
code:sh
❯ k get pod,secrets
NAME READY STATUS RESTARTS AGE
pod/nginx-sample 1/1 Running 0 15s
NAME TYPE DATA AGE
secret/nginx-secret Opaque 2 15s
Podに入って、環境変数を確認
code:sh
❯ k exec -it nginx-sample -- /bin/sh
# echo $USERNAME
admin
# echo $PASSWORD
admin123
6.5.2 ボリュームを利用してコンテナに設定ファイルを読み込む
マニフェスト、nginxコンテナ内の/etc/configのパスにSecretを読み込んでいる
code:yaml
❯ cat chapter-06/secret/nginx-volume.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-sample
spec:
containers:
- name: nginx-container
image: nginx:1.25.3
volumeMounts:
- name: nginx-secret
mountPath: /etc/config
volumes:
- name: nginx-secret
secret:
secretName: nginx-secret
---
apiVersion: v1
kind: Secret
metadata:
name: nginx-secret
data:
server.key: ZU05a3UzZWNDcFVMOXpQb0lJdUcycHRaWkM1Q3U0WkNRWFJ5bWxIYWpZdlp5ZmZwTTYK
立ち上げたpodに入ってserver.keyを見てみる
code:sh
❯ k exec -it nginx-sample -- /bin/sh
# cat /etc/config/server.key
eM9ku3ecCpUL9zPoIIuG2ptZZC5Cu4ZCQXRymlHajYvZyffpM6
# exit
6.6 1回限りのタスクを実行するための Job
Job は1回限り実行したい Pod に利用する
Job を実行すると、Pod の実行が成功するまで指定した回数リトライする
Pod は複数同時に実行することも可能
code:yaml
apiVersion: batch/v1
kind: Job
metadata:
name: date-checker
spec:
template:
spec:
containers:
- name: date
image: ubuntu:22.04
restartPolicy: Never
backoffLimit: 4
Ubuntu 22:04上でdateコマンドを打つジョブ ↑
実行結果
describe jobのPods Statusesに実行結果が現れる
code:sh
bbf-kubernetes on main ! ❯ k apply -f chapter-06/job.yaml
job.batch/date-checker created
bbf-kubernetes on main ! ❯ k get job
NAME COMPLETIONS DURATION AGE
date-checker 0/1 6s 6s
bbf-kubernetes on main ! ❯ k get po
NAME READY STATUS RESTARTS AGE
date-checker-wkdl6 0/1 Completed 0 13s
bbf-kubernetes on main ! ❯ k logs -f date-checker-wkdl6
Wed Sep 4 00:23:40 UTC 2024
❯ k describe job date-checker
Name: date-checker
Namespace: default
Selector: batch.kubernetes.io/controller-uid=88bde89f-5764-4d14-9366-848a742ee31b
Labels: batch.kubernetes.io/controller-uid=88bde89f-5764-4d14-9366-848a742ee31b
batch.kubernetes.io/job-name=date-checker
controller-uid=88bde89f-5764-4d14-9366-848a742ee31b
job-name=date-checker
Annotations: <none>
Parallelism: 1
Completions: 1
Completion Mode: NonIndexed
Suspend: false
Backoff Limit: 4
Start Time: Wed, 04 Sep 2024 09:23:31 +0900
Completed At: Wed, 04 Sep 2024 09:23:43 +0900
Duration: 12s
Pods Statuses: 0 Active (0 Ready) / 1 Succeeded / 0 Failed
Pod Template:
Labels: batch.kubernetes.io/controller-uid=88bde89f-5764-4d14-9366-848a742ee31b
batch.kubernetes.io/job-name=date-checker
controller-uid=88bde89f-5764-4d14-9366-848a742ee31b
job-name=date-checker
Containers:
date:
Image: ubuntu:22.04
Port: <none>
Host Port: <none>
Command:
date
Environment: <none>
Mounts: <none>
Volumes: <none>
Node-Selectors: <none>
Tolerations: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 78s job-controller Created pod: date-checker-wkdl6
Normal Completed 66s job-controller Job completed
bbf-k
6.7 定期的に実行するための CronJob
CronJob は定期的に Job を生成するリソース
定期的に実行したいジョブがある場合、このリソース使う
CronJob → Job作成 → Pod作成
scheduleにいつJobを実行するか書く
指定した日時のタイムゾーンは、デフォルトでは、kube-controller-manater のタイムゾーンに基づいている
.spec.timeZone に特定のタイムゾーンを指定することもできる
code:yaml
apiVersion: batch/v1
kind: CronJob
metadata:
name: date
spec:
schedule: "*/2 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: date
image: ubuntu:22.04
restartPolicy: Never
マニフェストを適用、cronjob確認すると2分ごとのスケジュール
code:sh
❯ k get cronjob
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
date */2 * * * * False 0 <none> 4s
少し経ってJobとPodを確認、AGEをみると、2分ごとに実行されることがわかる
code:sh
bbf-kubernetes on main ! ❯ k get job
NAME COMPLETIONS DURATION AGE
date-28761124 1/1 2s 2m4s
date-28761126 1/1 3s 4s
bbf-kubernetes on main ! ❯ k get po
NAME READY STATUS RESTARTS AGE
date-28761124-6xk82 0/1 Completed 0 2m6s
date-28761126-gm5j6 0/1 Completed 0 6s