はじめに
CKAD&CKA対策用の個人的なメモです。
試験中に公式ドキュメントやkubectlのhelpオプションによる確認ができるため、本メモの内容を全て暗記する必要はないです。しかしながら、時間がシビアなので、ある程度覚えておかないときついです。(毎回調べていたら多分時間が足りない)また、実務のことを考えると、やはりある程度は頭に入っていた方がよいと思います。
一部、too muchな内容もありますが、理解を深めるために記載しています。
よろしければご活用ください。メモなので表記揺れとかはご容赦ください。
▼Container
Docker
dockerコマンド
- カレントディレクトリにDockerfileからDockerイメージをbuildする
docker image build -t <image>:<tag> -f <Dockerfile> .
- イメージタグの変更
docker image tag <before> <after>
- つけられるタグは一つだけ
- イメージpush
docker image push <image>:<tag>
- Dockerイメージをダウンロードする
docker image pull <image>
- Dockerイメージをtarにする
docker save <image> -o <tar>
- tarを解凍してDockerイメージにする
docker load -i <tar>
- イメージを軽くする(一例)
- Alpineイメージを使う。python:3.6-alipneなど。
- イメージからコンテナ起動する。公開ポート8282のコンテナポート8080。
docker container run -p 8282:8080 <image>
- イメージからコンテナを起動してコマンド実行する
docker container run <image> cat /etc
- 起動中コンテナに擬似的なSSHする
docker container exec -it <container> /bin/sh
- コンテナのリソース使用状況を確認する
docker container stats <container>
- コンテナのログを確認する
docker container logs <container>
Dockerfile
- Dockerfileから独自のDockerイメージを定義して、
docker run
で起動する。 -
ADD <url> <container path>
でリモートファイルをコンテナ上にコピーする。 -
COPY <local path> <container path>
でローカルファイルをコンテナ上にコピーする。 - RUNはビルド時に実行するコマンド
- ENTRYPOINTはコンテナ起動時に実行するコマンド
- CMDはENTRYPOINTと併用する際にはENTRYPOINTのコマンドの引数になる。
- kubernetesのYAMLのspec.containers[].commandでENTRYPOINTを上書きする。spec.containers[].argsでCMDを上書きする。commandでCMDを上書きではない。
Podman
- Dockerと同様のコンテナエンジン。Dockerfileも使える。
- イメージビルド
podman build -t <image>:<tag> -f <Dockerfile> .
- イメージ一覧
podman image ls
- イメージpush
podman push <image>:<tag>
- バックグラウントで実行
podman run -d --name <conatiner name> <image>:<tag>
- コンテナ一覧
podman ps
- コンテナログ出力
podman logs <container>
cri-o
- Kubernetesに最適化された軽量なOCI準拠なコンテナランタイム。crictlでCLI操作する。
- Dockerほど柔軟なCLIは用意されていないためローカル開発ではDockerが選択されるケースは依然として多いだろうが、今後のサーバ環境ではDockerからcri-oに置き換わるかもしれない。
- コンテナの一覧を表示する
crictl ps -a
- podの一覧を表示する
crictl pods
- コンテナのイメージ一覧を表示する
crictl images
- 実行中コンテナでコマンド実行
crictl exec -it <container id> <command>
- ログを確認する
crictl logs <container id>
▼Workloads
Pod
kubectl
- podを起動して環境変数を設定する
kubectl run <pod name> --image <image> --env=key1=val1
- podを起動してClusterIPで公開する
kubectl run <pod name> --image <image> --expose=true --port=<port> --target-port=<target port>
- podを起動してコマンドを実行する。
kubectl run <pod name> --image <image> --command -- <command> <args>
- containers[].commandとcontainers[].argsが設定される。
- podを起動してシェル経由でコマンドを実行する。
kubectl run <pod name> --image <image> -- /bin/sh -c '<command and args>'
- containers[].commandは無しで、containers[].args配下に全て設定される。
- 起動中のpod(メインコンテナ)に擬似的なSSH接続する
kubectl exec -it <pod name> -- /bin/sh
- pod内の特定コンテナに擬似的なSSH接続する
kubectl exec -it <pod name> -c <container name> -- /bin/sh
- 前のリビジョンのpodのログを取る
kubectl logs <pod> --previous
- Pod中の特定コンテナのログを取る
kubectl logs <pod> -c <container>
- 各podの少し詳しい情報を取得する
kubectl get pods -o wide
- 各podの詳細情報を取得する
kubectl describe pods
- 適当なpodを起動してpodに疎通確認
kubectl run tmp --image <image> --rm -it -- curl -m 5 <pod ip>
- Serviceと違ってPod名では名前解決されないので要注意
YAML
- spec.nodeNameで起動するNodeを指定する。
- spec.terminationGracePeriodSecondsに削除するまで何秒かを設定する。
- Podの削除命令がされた場合に、「Serviceからの除外処理」と「preStop処理+SIGTERM処理」が同時に実行される。terminationGracePeriodSecondsにこれらにかかるであろう時間を設定する。
- spec.containers[].ports.containerPortでコンテナのポートを設定する。
- spec.containers[].lifecycle.postStartにコンテナ起動直後に実行する処理(execかhttpGet)を指定する。
- spec.containers[].lifecycle.preStopにコンテナ停止直前に実行する処理(execかhttpGet)を指定する。
- podのyamlにcommandと引数を記述する場合は、リストで記述する。あるいはargsを活用する。
- command: ['sh', '-c', 'echo "Hello, Kubernetes!" && sleep 3600']
- command: ["printenv"]
- args: ["HOSTNAME", "KUBERNETES_PORT"]
マルチコンテナ
- マルチコンテナのpodを作成する
- まず1コンテナのpodのyamlを作って、そのyamlに他podの情報を追記していく。kubectlだけではマルチコンテナpodは作れない。
- initコンテナの設定はspec.initContainersで設定する
- initコンテナが複数ある場合は順列に実行される。initコンテナ1 -> initコンテナ2 ...
- initコンテナの情報を取得する
kubectl describe pod <pod>
Pod(Container)のリソース制限
- spec.containers[].resources.requestsでcpuとmemoryの下限を指定。
- spec.containers[].resources.limitsでcpuとmemoryの上限を指定。
- containerの合計がPodのリソース制限になる
- OOMKilledはPodに割り当てたメモリが不足している可能性。ノードに余裕あればlimitsのmemoryを増やすと起動するようになるかも。
ContainerのHealthCheck
- spec.containers[].startupProbeはPodの初回起動が完了しているかをチェックする。失敗したら他のProbeは実行しない。
- spec.containers[].readinessProbeはPodがリクエストを受け付けることができるかをチェックする。失敗したらトラフィックを流さない。再起動はしない。
- spec.containers[].livenessProbeはPodが正常に動作しているかをチェックする。失敗したらPodを再起動する。
- httpGetでヘルスチェック用エンドポイントを叩く。
- exec.commandでヘルスチェック用のコマンドを実行する。
- tcpSocketで特定ポートとの疎通を確認する。
- initialDelaySeconds、periodSeconds、timeoutSeconds、successThreshold、failureThresholdを設定する。
ReplicaSet
- spec.selector.matchLablesで指定したラベルのpod数を管理する。ラベルしか注目しないため、そのReplicaSet外のpodのラベルも見てしまう点に注意する。
- Podの増減履歴を確認する
kubectl describe replicaset <rs>
- editしてもpodは自動で更新されないので、手動でpodをdeleteする。
Deployment
- Deploymentのimageを変更する
kubectl set image deployment <deployment> <container>=<new image>
- Podは自動で再起動する
- replicasの数を変更する
kubectl scale deployment <deployment> --replicas=<number>
- HPAを設定する
kubectl autoscale deployment <deployment> --min=5 --max=10 --cpu-percent=80
- HPAを削除する
kubectl delete hpa <hpa>
- DeploymentをRolling Updateする
kubectl rollout restart deployment <name>
- Deploymentによる変更履歴を確認する
kubectl rollout history
- Deploymentを1つ前に戻す
kubectl rollout undo deployment <deployment>
- (さらにもう一回実行すると元に戻る)
- Deploymentを指定のバージョンに戻す
kubectl rollout undo deployment <deployment> --to-revision=<revision number>
- DeploymentのStrategyを確認する
kubectl describe deployment <deployment>
- spec.selectorは.spec.template.metadata.labelsと一致している必要がある
- spec.strategy.typeはRecreateとRollingUpdateの二種類がある。RollingUpdateではmaxUnavailable(アップデート中にdesiredから何個減っても許容するか)とmaxSurge(アップデート中にdesiredから何個増えても許容するか)を調整する。
- 複数のDeploymentが存在する環境において、特定のDeploymentへのトラフィックを少なくす。
- 特定のDeploymentのpodの数を少なくすると、そのDeploymentへのトラフィックを少なくできる。各Deploymentが抱えるpodへのリクエスト加重は均等。
- カナリアリリースする
- 既存のDeploymentをコピーしてcanary用Deploymentを用意して、それぞれのDeploymentのPod数が目標の加重比率になるように調整する。例えばPrimary:Canary=80:20にする場合でPrimaryのDeploymentのPod数が4であれば、CanaryのDeploymentのPod数は1にする。
- replaceやrollout restartしてもDeploymentのAGEは変わらない。PodのAGEを確認するとよい。
Label&Annotation
- podにラベルをつける
kubectl label pod <pod> <key>=<value>
- podのラベルを削除する
kubectl label pod <pod> <key>-
- 特定のラベルが付いたPodにラベルをつける
kubectl label pod <key>=<value> -l <key>=<value>
- 全てのpodにラベルをつける
kubectl label pods --all <key>=<value>
- Deploymentのラベルを上書きする
kubectl label deployment <deployment> --overwrite <key>=<value>
- 特定のラベルをノードにつけてそのノード上にpodを起動する
kubectl label node <node> <key>=<value>
- podのYAMLでnodeSelectorかnodeAffinityでラベルを指定する。
- Podをラベル付きで一覧表示する
kubectl get pods --show-labels
- 特定のラベルを持ったpodを一覧表示する(複数ラベルでAND検索)
kubectl get pods -l <key1>=<value1>,<key2>=<value2>
- 特定のラベルを持ったpodを一覧表示する(複数ラベルでOR検索)
kubectl get pods -l <key1>=<value1> -l <key2>=<value2>
- 特定のラベルが貼られたpodを一覧表示する
kubectl get pods -L <key>
- podにラベルをつけて起動する
kubectl run <name> --image <image> -l <key>=<value>
- 特定ラベルのpodを削除する
kubectl delete pods -l <key>=<value>
- podにdescriptionアノテーションをつける
kubectl annotate pod <pod> <key>=<value>
- podのdescriptionアノテーションを削除する
kubectl annotate pod <pod> <key>-
- 特定のラベルが付いたPodにアノテーションをつける
kubectl annotate pod <key>=<value> -l <key>=<value>
- 全てのpodにアノテーションを付与する
kubectl annotate pods --all <key>=<value>
Job
- spec.completions
- Jobを何回成功するまで実行するか
- spec.parallelism
- Jobを何並列にするか
- spec.backoffLimit
- Job失敗時に何回までリトライするか
- spec.suspend
- trueでJobを一時停止する
- spec.template.spec.restartPolicy
- Job失敗時にAlways(Podが停止すると常に再起動)かOnFailure(同じPodで再起動)かNever(新しくPodを作り直す)
- spec.template.spec.activeDeadlineSeconds
- 起動して何秒後に削除するか
- CronjobからJobを手動実行
kubectl create job <job name> --from=cronjob/<cronjob>
- 明示的に削除しないと削除されない
Cronjob
- Cronに関するものを設定する。Cronでない設定はJobの方。
- spec.startingDeadLineSeconds
- Cronが何秒遅れて実行されても許すか
- spec.concurrencyPolicy
- Cronで前のJobが完了していない場合に、Allow(同時実行許可)かForbid(同時実行不可)かReplace(前のJobを止めて新しいJobを開始)のどれか。
- spec.successfulJobsHistoryLimit
- Cronで成功したjobをいくつ保持するか
- spec.failedJobsHistoryLimit
- Cronで失敗したjobをいくつ保持するか
- spec.suspend
- trueでCronを一時停止する
- spec.jobTemplate.specにJobの設定をする。
- spec.jobTemplate.spec.activeDeadlineSecondsなど。
- 毎分特定コマンドを実行するCronjobを作成する
kubectl create cronjob <name> --image=<image> --schedule="*/1 * * * *" -- /bin/sh -c 'echo Hello World'
-
no matches for kind "CronJob" in version "batch/v1"
エラーになったらbatch/v1beta1
にする。
▼Network
Service
- CKADでは主にClusterIP(クラスタ内通信)かNodePort(クラスタ外通信)を使用する。
- NodePort -> ClusterIP -> Podの順でトラフィックが流れる。
- nodePortは全てのKubernetesノードで受けるポート、portはClusterIPのポート、targetPortはコンテナのポートを設定する。
- ClusterIPのServiceを作成する
kubectl create service clusterip <name> --tcp=<port>:<targetPort>
- NodePortのServiceを作成する
kubectl create service nodeport <name> --tcp=<port>:<targetPort> --node-port=<nodePort>
- spec.selectorで指定したlabelが付いたPodへ転送する。
- PodにはServiceの転送用目印となるlabelを付与しておく必要あり。
- 意外だがYAMLでDeployment名を指定して紐づけるといったようなことはしないし、Deploymentのlabelではダメ。
- Deploymentを公開する(Serviceを作成する)
kubectl expose deployment <deployment> --name <service name> --type <type> --port <port> --target-port <target port>
- nodePortオプションはkubectlでは設定不可
- exposeはselectorの設定が自動なので楽。
- endpoint(転送先PodのIPとポート)を確認する
kubectl get endpoints <service>
- sessionAffinity: ClientIPにより、送信元IPアドレスを使ってセッションアフィニティ(同じPod宛てにトラフィックを転送し続けること)ができる。
- NodePortのexternalTrafficPolicyはLocal(Nodeでトラフィックを受けたあとに別Nodeへのホップを無効にする。トラフィックの処理が偏る可能性がある。)とCluster(Nodeでトラフィックを受けたあとに別Nodeへのホップを有効にする。別のNodeへホップを許可することでトラフィック処理を分散できる。)がある。デフォルトはCluster。
- ServiceのIPレンジの確認
cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep service-cluster-ip-range
- 適当なPodを起動してClusterIP経由でPodへの疎通確認
k run tmp --image nginx:alpine -n <namespace> --rm -it -- curl -m 5 <service name>:<port>
- NodePort経由でPodへの疎通確認
curl -m 5 <node ip>:<nodePort>
Ingress
- L7ロードバランサとしてクラスタ外からServiceへのアクセスを管理するリソース。
- パスベースルーティング機能
- spec.rules[].http.paths[]にpathとbackend(Serviceのnameとport)を設定する。このportはServiceのport(ClusterIPのportかNodePortのport)と一致させる。
- pathTypeはPrefixかExact。
- spec.rules[].hostを設定しない場合は*扱い。
- SSL終端機能
- spec.tls[]にhosts(TLS証明書を適用するドメイン名)とsecretName(TLS証明証を格納しているSecretの名前)を設定する。
- spec.defaultBackendにrulesにマッチングしなかったリクエスト用の404の設定をする。
- Ingressが動作するにはIngressコントローラ(NginxやIstioなど)が導入されている必要がある。
- パスベースルーティングが設定されたingressを作る。pathTypeはPrefix。
kubectl create ingress <name> --rule="<host>/<path>*=<service name>:<service port>"
CNI(Container Network Interface)
- 複数Node上のPod間の疎通性を確保するための機能。
- プラグイン形式。様々なベンダーから提供される。WeaveやFlannelなど。controlplaneのNICが追加される。
- CNIバイナリはデフォルトで
/opt/cni/bin
に配置される。 - CNIの設定ファイルディレクトリはデフォルトで
/etc/cni/net.d
kube-proxy
- Service(ClusterIPやNodePort)宛のトラフィックをPodへ転送する機能。
- Node上でDaemonsetで起動している。
- userspaceモード
- カーネル空間でなくユーザ空間でトラフィックを転送する。遅い。
- iptablesモード
- カーネル空間でトラフィックを転送する。userspaceよりも速く、枯れているが、そもそもロードバランシング用途で開発されたものではない。
- ipvsモード
- 速く、ロードバランシングのアルゴリズムに複数の選択肢が用意されている。ただし、枯れていない。
CoreDNS
- CoreDNSのService/Deployment/Pod/Configmapはkube-systemネームスペース上に作成される。
- 設定はCorefileで行う。
- DeploymentのArgsでCorefileのパスを指定する。
- CorefileはConfigMapで管理することも可能。
- クラスターのドメイン名を設定する。
- 例えば
kubernetes svc.cluster.local
- 例えば
- Serviceの名前解決は
<service name>.<namespace>.<domain>
で行う。- ドメイン名は省略可能。
- 同じnamespaceであればnamespaceも省略可能。つまり、Service名のみで解決可能。
- Service名は名前解決されるがPod名は名前解決されない。
- Pod生成時に
/etc/resolv.conf
に自動で設定される。search default.svc.cluster.local svc.cluster.local cluster.local
-
nameserver 10.96.0.10
- CoreDNSのServiceのIP
▼ストレージ
ConfigMap
- ConfigMapを作る(literal)
kubectl create configmap --from-literal=<key1>=<value1> --from-literal=<key2>=<value2>
- ConfigMapを作る(file)
kubectl create configmap --from-file=<key1>=<file1> --from-file=<key2>=<file2>
- ConfigMapを作る(env-file)
kubectl create configmap --from-env-file=<file>
- 環境変数としてPod(Container)に渡す
- spec.containers[].env.valueFrom.configMapKeyRefでConfigMapとkeyを指定する。
- spec.containers[].envFrom.configMapRef.nameでConfigMapを指定する。
- VolumeとしてPod(Container)に渡す
- spec.volumes.configMapで指定して、spec.containers[].volumeMountsでマウントする。
- 動的更新される
Secret
-
Secret(Opaque)を作成する。(literal)
kubectl create secret generic --from-literal=<key1>=<value1> --from-literal=<key2>=<value2>
-
Secret(Opaque)を作成する。(file)
kubectl create secret generic --from-file=<key1>=<file1> --from-file=<key2>=<file2>
-
Secret(Opaque)を作成する。(env-file)
kubectl create secret generic --from-env-file <file>
-
環境変数としてPod(Container)に渡す
- spec.containers[].env.valueFrom.secretKeyRefでSecretとkeyを指定する。
- spec.containers[].envFrom.secretRef.nameでSecretを指定する。
-
VolumeとしてPod(Container)に渡す
- spec.volumes.secretで指定して、spec.containers[].volumeMountsでマウントする。
- 動的更新される
-
secretに登録されている値をbase64デコードして取得する
-
kubectl get secret <secret> -o yaml
してecho <encoded value> | base64 -d
kubectl get secret <secret> -o jsonpath="{.data.<target>}" | base64 -d
- describeでも確認できる場合がある
-
Volume
- あらかじめ用意された利用可能なボリューム(Node、nfs、iscsiなど)を使用するだけ。Kubernetesが管理するものではない。
- Podのspec.volumesで指定して、spec.containers[].volumeMountsでマウントする。
- emptyDirはホスト(Node)上の一時的な領域をPodに確保する。
- 同一Pod内のコンテナ間では共有可能だが、Pod間での共有は不可。
- Podが削除されると消える。
- emptyDirに関する設定を何もしない場合はemptyDir :{}
- emptyDir.medium: Memoryとすると高速なtmpfsのメモリ領域を利用できる。
- hostPathはホスト(Node)上の任意の領域をマウントする。
- pathでホストのパスを指定する
- 同一Node内の他Podとの共有は可能。
- Podが削除されても消えないがNodeが停止すると消える。
- typeはDirectoryOrCreate/Directory/FileOrCreate/Fileなどがある。
PersistentVolume(PV)
- 外部の永続ボリュームサービス(AWSのEBSなど)と連携したり、Nodeのリソースを使って、Kubernetes管理のボリュームを提供するリソース。
- 手動かStorageClassのDynamic Provisioningにより作成される。
- PodからPVを直接利用できず、必ずPVC経由で利用する。
- spec.capacity.storageで容量を設定する。
- spec.volumeModeはFilesystem(デフォルト)/Blockのいずれか。
- spec.accessModesはReadWriteOnce(単一NodeでReadWrite可能)/ReadOnlyMany(複数NodeでReadOnly可能)/ReadWriteMany(複数NodeでReadWrite可能)のいずれか。
- spec.persistentVolumeReclaimPolicyでPVCが削除される際にPVをDeleteするかRetainするかを指定する。ただし、Retainしても再度マウントすることはできず、Releasedというステータスになる。
- spec.storageClassNameを設定する。
- hostPathの場合は、spec.hostPath.pathを設定する。
PersistentVolumeClaim(PVC)
- PVをPodにアサインするリソース。
- PodやDeploymentのspec.volumes[].persistentVolumeClaim.claimNameを設定して、spec.containers[].volumeMountsでマウントする。
- spec.storageClassNameを設定する。
- spec.accessModesを設定する。
- spec.volumeModeを設定する。
- Blockの場合は、Podにはspec.containers[].volumeDevicesでマウントする。
- spec.resources.requests.storageを設定する。Dynamic Provisioningで生成されたPVでない場合は、実際にはこれよりも大きな容量のPVが割り当てられる可能性がある。
- PVとPVCの設定が一致し、PVCのspec.resources.requests.storageを満たしたPVがbindされる。
- selector.matchLabelsやselector.matchExpressionsにより、PVに付与されたlabelを使ってbindするPVを指定することも可能。
- Podから使われ続ける限りPVCは削除できない。
- PVはnamespaceスコープでないが、PVCはnamespaceスコープ。
StorageClass
- ストレージの種類。例えば、低スループット・標準:高スループットなどの分類。Dynamic Provisioningも行う。
- 手動でPVを作る場合、「PVとPVCのstorageClassName」と「StorageClassのname」が一致することで紐づく。
- provisionerでAWSのEBSやOpenStackのCinderなどを指定する。
- reclaimPolicyを設定する。PVとPVCとStorageClassのreclaimPolicyは一致する必要がある。
- volumeBindingModeでDynamic ProvisioningによるPVの作成タイミングを設定する
- Immediate(デフォルト)はPVCを作成すると即座にPVを作成する。
- WaitForFirstConsumerはPodにアタッチされる直前のタイミングでPVを作成する。節約できる。
- provisioner: kubernetes.io/no-provisionerによりDynamic ProvisioningをOFFにする。
- allowVolumeExpansion: trueにすることで使用中のPVのサイズを拡張可能にする。サイズをあげる場合はPVCのYAMLでrequestsの値を増やす。
▼セキュリティ
Admission Control
- KubernetesのAPI ServerへのAPIリクエストに対して、認証と認可を行った後のフェーズで、別途そのリクエストを受け入れるか制御する機能。
- kube-apiserverコマンドはkube-systemネームスペースのkube-apiserver-controlplaneポッドで実行する
kubectl exec -it kube-apiserver-controlplane -n kube-system -- kube-apiserver -h
- admission controlのenableになっているプラグインを取得する
kube-apiserver -h | grep 'enable-admission-plugins'
- kube-apiserverコマンドの
--enable-admission-plugins
と--disable-admission-plugins
でカンマ区切りに有効無効にする認証方法を指定する。 - admission controlのYAML上でのプラグインの設定状況を調べる(デフォルト設定までは確認できない)
cat /etc/kubernetes/manifests/kube-apiserver.yaml |grep admission
- /etc/kubernetes/manifests配下にkube-apiserverとkube-controller-managerとkube-schedulerのPodのYAMLがある。これらのYAMLはviなどで編集すると自動で再起動する。
- プラグインはMutating(リクエストの内容を検証)かValidating(リクエストの内容を検証)のどちらかあるいは両方に分類される。
- 代表的なプラグイン
- AlwaysAdmitは全てのリクエストを許可する。
- AlwaysPullImagesはPodのimagePullPolicyをAlwaysに強制的に変更する。ノードにpull済みのprivateイメージが他のPodに使用されないようにするため。
- AlwaysDenyは全てのリクエストを禁止する。テスト用。
- ServiceAccountはServiceAccountが明示的に指定されていないPodに対して、デフォルトのもの紐付ける。また、トークンをPodに自動的にマウントする。
- SecurityContextDenyはSecurityContextの設定のうち、SELinuxOptions、RunAsUserなどの設定をしているものを禁止する。
- ResourceQuotaはリクエストがnamespace内のリソース制限を超えていないかを検証する。
- LimitRangerはNamespaceに設定されるLimitRangeに対して、リクエストが適切かどうかを検証する。もしResourceが未設定の場合はデフォルト値を設定するときにも使われる。
- NamespaceAutoProvisionは、存在しないnamespaceを指定してリソースを作ってもエラーにならず、自動でnamespaceを作成する。現在はdeprecated。
- NamespaceLifecycleは、存在しないnamespaceや削除中のnamespaceへの指定を禁止する。
- MutatingAdmissionWebhookは独自リソースに関するリクエストを必要に応じて改変する。ValidatingAdmissionWebhookは独自リソースに関するリクエストを検証する。Mutatingの後にValidatingが実行される。
証明書
- /etc/kubernetes/manifests/kube-apiserver.yaml のkube-apiserverコマンドでapi-server関連の証明書を指定している。
- /etc/kubernetes/manifests/etcd.yaml のectdコマンドでetcd関連の証明書を指定している。
- 証明書に記載されたCommon Name、Issuer、Alternative Nameなどを確認する
openssl x509 -in <cert file> -text
UserAccount
- UserAccountは人間用アカウント。AWSのIAMなどにも連携できる。
- UserAccountの追加
- 新規UserAccountのClusterアクセス用サーバ証明書の申請
- 秘密鍵の作成
openssl genrsa -out <key file> 2048
- 秘密鍵からCSRファイル(公開鍵にCNなどを付与したもの)の作成
openssl req -new -key <key file> -out <csr file>
- CertificateSigningRequest(CSR)の作成
- CSRは証明書発行要求。CSRファイルをCAに渡し、署名済みのサーバ証明書を発行して貰う。
- spec.groupsには"system:authenticated"を設定する。
- spec.requestにはCSRファイルをbase64エンコードした値を設定する。
- spec.signerNameには"kubernetes.io/kube-apiserver-client"を設定する。
- spec.usagesにはTLSクライアントの場合は"digitalsignature", "key encipherment", "client auth"を設定する。
- CSRリソースの確認
kubectl get csr
- 秘密鍵の作成
- 承認の場合
- CAに承認される
kubectl certificate approve <csr>
- 承認されるとCSRリソースのstatus.certificateにCRT(サーバ証明書)が出力されるため、それをファイルに出力する。
kubectl get csr <csr> -o jsonpath='{.status.certificate}' | base64 -d > <crt file>
- CRTファイルを指定してUserAccountの認証情報を追加
kubectl config set-credentials <user name> --client-certificate=<crt file>
- cluster, context, role, rolebindingを設定してリソース操作が可能になる。
- CAに承認される
- 否認の場合
- CAに否認される
kubectl certificate deny <csr>
- CSRリソースの削除
kubectl delete csr <csr>
- CAに否認される
- 新規UserAccountのClusterアクセス用サーバ証明書の申請
kubeconfig
- UserAccount(認証情報)とclusterとcontext(userとclusterの組み合わせ)を管理する。
- UserAccount(認証情報)の定義を追加
kubectl config set-credentials <user name> --client-certificate=<crt file>
- clusterの定義を追加
kubectl config set-cluster <cluster name> --server=<url>
- contextの定義を追加
kubectl config set-context <context name> --cluster=<cluster name> --user=<user name> --namespace=<namespace>
- 現在のcontextを表示
kubectl config current-context
- contextの変更
kubectl config use-context <context name>
- 使用するkubeconfigを変える
-
--kubeconfig
オプションで別のconfigを指定する - 環境変数KUBECONFIGで別のconfigを指定する
-
~/.kube/config
の中身を編集する
-
- userを指定してリソース操作をする
kubectl get pods --as <user>
ServiceAccount
- ServiceAccountはPod用アカウント。
- ServiceAccountの作成
kubectl create serviceaccount <name>
- v1.24以降はトークンは自動生成されなくなった
- ServiceAccount用のトークンを作成する
kubectl create token <serviceaccount>
- PodとServiceAccountを紐づける
- Podのspec.serviceAccountNameを設定する。
- ServiceAccountをPodに紐づけることで、Podは
/var/run/secrets/kubernetes.io/serviceaccount
にマウントされたServiceAccountのトークンを使ってKubernetesリソースの操作ができるようになる。
RBAC(Role Based Access Control)
- Role(Podの操作権限)を作成する
kubectl create role <name> --verb=list,create,delete --resource=pods
- RoleBindingを作成してroleとuserを紐づける
kubectl create rolebinding <name> --role=<role> --user=<user>
- ClusterRoleを作成する
kubectl create clusterrole <name> --verb=<verb> --resource=<resource>
- ClusterRoleBindingを作成してClusterRoleとServiceAccountを紐づける
kubectl create clusterrolebinding <name> --clusterrole=<cluster role> --serviceaccount=<serviceaccount>
- Role一覧を取得する
kubectl get roles
- RoleBinding一覧を取得する
kubectl get rolebindings
- RoleBindingが紐づくSubjects (User、Group、ServiceAccount)を確認する
kubectl describe rolebinding <RoleBinding>
- 1つのRoleに複数のSubjectを設定可能
- YAMLでrole/clusterroleを作成する場合はapiGroupsを自分で設定する必要がある。resourceごとに設定すべき値は、
kubectl api-resources
のAPIVERSIONで確認できる。例えば、storage.k8s.io/v1であればstorage.k8s.ioをapiGroupsに指定すればよい。 - クラスタの認証モードを確認する
-
kubectl describe pod kube-apiserver-controlplane -n kube-system
を実行して、authorization-modeにRBACが含まれていればRBACが使える状態。
-
Private Registry Image
- private registryのイメージを指定する
- Podのspec.containers[].imageで
<repository>/<image>
と指定する
- Podのspec.containers[].imageで
- docker-registryのSecretを作成する
kubectl create secret docker-registry <secret name> --docker-username=<user> --docker-password=<password> --docker-email=<email> --docker-server=<server>
- Secretを使う
- Podのspec.imagePullSecretsでnameを指定する
SecurityContext
Podとコンテナ共通
- runAsUser/runAsGroup/runAsNonRoot/seLinuxOptionsはPodとコンテナの両方のSecurityContextで設定可能。重複する場合はコンテナのSecurityContextの設定が優先される。
- runAsUser でrootユーザを指定する場合はIDを0にする。
- podの実行ユーザを調べる
kubectl exec <pod> -- whoami
- 既存のpodの設定は変更できないため、変更する場合は一度podをdeleteする。
Podに関するSecurityContext
- spec.securityContextに設定する。
- spec.securityContext.fsGroupでマウントするvolumeのグループを変更する。
- Podにマウントしたvolumeはowner:group=root:rootのため、runAsUserで実行ユーザを変更すると権限エラーになってしまう。
コンテナに関するSecurityContext
- spec.containers[].securityContextに設定する。
- capabilitiesでコンテナの特定の権限(SYS_ADMINなど)のadd/dropをする。
- privileged: trueにより、特権コンテナとして起動させる。コンテナにホストのrootと同等の権限を与える。
- allowPrivilegeEscalation: trueにより、権限昇格(コンテナにホストのroot以上の権限を与えること)させる。
- readOnlyRootFilesystem: trueにより、/etc配下などのKernel関連ファイルをreadOnlyにする。
Network Policy
- クラスタ内のPod同士のトラフィックルール。
- デフォルト(NetworkPolicyがPodに適用されていない)では、Podは分離されていない状態となるため、すべてのトラフィックを許可する。
- NetworkPolicyがPodに適用されると、そのPodは分離されるようになる。ホワイトリスト形式で許可するものだけを設定する。
- 複数のNetworkPolicyがPodに適用される場合は、OR条件で制限される。
- podSelector
- spec.podSelectorでどのPodにこのNetwork Policyを有効にするかを指定する。ネットワーク系だけど意外とServiceと紐づけることはない。
-
podSelector: {}
で全てのPodを対象にする。
-
- spec.ingress.from.podSelector.matchLabelsで特定のラベルがついたPodからの通信を許可する
- spec.egress.to.podSelector.matchLabelsで特定のラベルがついたPodへの通信を許可する。
- spec.podSelectorでどのPodにこのNetwork Policyを有効にするかを指定する。ネットワーク系だけど意外とServiceと紐づけることはない。
- nameSpaceSelector
- spec.ingress.from.nameSpaceSelector.matchLabelsで特定のラベルが付いたnamespace上のpodからの通信を許可する
- spec.egress.to.nameSpaceSelector.matchLabelsで特定のラベルが付いたnamespace上のpodへの通信を許可する。
- ipBlock
- spec.ingress.from.ipBlockでクラスタ外ネットワークの特定ipからの通信を許可する
- spec.egress.to.ipBlockでクラスタ外ネットワークの特定ipへの通信を許可する。
- fromやtoにnamespaceSelectorとpodSelectorとipBlockを設定する場合、
-
が合わせて1つならばAND条件。それぞれに-
があればOR条件。つまり、-
ごとにルールがまとまる。 - ports
- spec.ingress.portsで許可する送信元ポートを設定する。
- spec.eggres.portsで許可する宛先ポートを設定する。
- portsの設定がない場合は全てのポートを許可。
-
-
付き(- ports:
)であれば、fromやtoの設定にOR条件。 -
-
なし(ports:
)であれば、fromやtoの設定にAND条件。
- 全てのトラフィックを許可する場合は、ingress/egressに
{}
を設定する。 - 全てのトラフィックを遮断する場合は、policyTypesだけ設定して、ingress/egressの設定を書かない。
- fromあるいはtoをyamlに複数設定する場合は
to:
やfrom:
を複数書く。それぞれがOR条件になる。 - kubectlではingressは作成できるがegressは作成できない。どちらにせよYAMLで書いたほうがわかりやすい。
- Network Policy一覧を取得
kubectl get networkpolicy
- 短縮名はnetpol
▼リソース制限
- LimitRangeで特定namespaceのContainer/Pod/PersistentVolumeClaimに関するリソース(CPU、memory、容量)のmin/max/defaultなどの設定をする。
- LimitRangeの設定を確認する
kubectl describe limitrange <limitrange>
- ResourceQuotaで特定namespace全体での「リソース数」と「リソース使用量」の制限をする。
- spec.hard.services
- spec.hard.requests.memory
- ResourceQuotaの設定を確認する
kubectl describe quota <quota>
▼Helm
- repositoryのchartを使ってreleaseをデプロイすることで、簡単にKubernetes上にリソース一式(DeploymentやServiceなど)を用意するためのパッケージマネージャ。
- プログラミング的に言うと、chartはクラスでreleaseはインスタンス。
- Helm関連の環境変数表示
helm env
- リポジトリの登録
helm repo add <repository name> <repository url>
- リポジトリの一覧表示
helm repo list
- リポジトリの更新
helm repo update
- Artifact Hubからchartを探す
helm search hub <chart>
- リポジトリから検索(versionなどを出力する)
helm search repo <repository>
- chartで設定可能なvaluesを表示する
helm show values <repo/chart>
- chartをインストールしてreleaseを生成(バージョン指定、パラメータを個別指定)
helm install <release> <chart> --version <version> --set <key=value>
- chartをインストールしてreleaseを生成(バージョン指定、パラメータをvaluesファイルで読み込み)
helm install <release> <chart> --version <version> --values <file>
- chartをアンインストールしてreleaseを削除
helm uninstall <release>
- releaseの一覧
helm list
- statusがdeployedでないreleaseも含めた一覧
helm list -a
- releaseの詳細情報を表示
helm get all <release>
- releaseをアップグレードする
helm upgrade <release> <repo/chart> --version <version> --set <key=value>
- releaseの履歴を確認する
helm history <releasee>
- releaseをロールバックする
helm rollback <release> <revision>
- 独自chart用の雛形を作成する
helm create <chart>
- 独自chartのインストール
helm install <release> <chart path>
- 独自chartをパッケージ(tgz)化
helm package <chart path>
- リポジトリからchartをDLして解凍する(インストールはしない)
helm pull <url or repo/chart> --untar
- テンプレートとvaluesファイルからマニフェストを生成する。(releaseは作成しない。)
helm template <manifest name> <template> --version <version> --values <file>
▼CRD
- CustomResourceDefinitionのYAMLで独自のCustomResourceの仕様を定義する。CustomResourceのYAMLでCustomResourceを設定する。CRDのYAMLをapplyしてもCRを生成するわけではない。(クラスやインスタンスのような関係ではない)
- metadata.nameは
<plural name>.<group>
の形式にする。 - spec.groupとspec.versions.nameを結合したものがそのリソースのApiVersionとして扱われる。
- spec.versions[].servedでそのバージョンの有効無効を設定する。
- spec.versions[].storageでetcdに保存するバージョンを設定する。storage: trueにできるのは一つのバージョンだけ。代表的なバージョン?みたいな理解。
- spec.versions[].schema.openAPIV3SchemaでCustomResourceのプロパティを設定する。
- spec.scopeはNamespacedかCluster。
- spec.namesでplural/singular/kind/shortNamesを設定する。
- CRD一覧を取得する
kubectl get crd
- CRの一覧を取得する
kubectl get <cr>
▼API Version
/etc/kubernetes/manifests/kube-apiserver.yaml
に --runtime-config=rbac.authorization.k8s.io/v1alpha1
を設定する。
- deprecatedなAPI VersionのYAMLを更新してリソースを作成する
kubectl convert -f <yaml> |kubectl create -f -
▼Scheduling
Affinity
- AffinityはNodeに付与されているビルトインノードラベルや自分で付与した独自ラベルを使って、ラベルベースに条件を最も満たすnodeにPodをSchedulingをする方式。
- Podのspec.affinityに設定する。
- spec.nodeSelectorは単純に、ラベルのkey/valueが一致するNodeにPodをSchedulingする。
- spec.affinity.nodeAffinityはrequiredDuringSchedulingIgnoredDuringExecutionを満たすかつ、preferredDuringSchedulingIgnoredDuringExecutionをなるべく満たすNodeにPodをSchedulingする。
- podAffinityはrequiredDuringSchedulingIgnoredDuringExecutionを満たすかつ、preferredDuringSchedulingIgnoredDuringExecutionをなるべく満たすPodが存在するドメイン(ノードかAZ)にPodをSchedulingする。topologyKeyでドメイン(ノードかAZ)を指定する。
- podAntiAffinityはrequiredDuringSchedulingIgnoredDuringExecutionを満たすかつ、preferredDuringSchedulingIgnoredDuringExecutionをなるべく満たすPodが存在しないドメイン(ノード、AZなど)にPodをSchedulingする。
- matchExpressionsのoperatorはIn/NotIn/Exists/DoesNotExist/Gt/Ltのいずれか。
Taints&Toleration
- ノードにtaintsをつけておき、それをtolerationsできるPodのみをSchedulingする方式。
- taintsを付与する
kubectl taint node <node> <key>=<value>:<effect>
- taintsを削除する
kubectl taint node <node> <key>=<value>:<effect>-
- taintsを確認する
kubectl describe node <node>
- tolerationsはPodのYAMLに設定する。tolerationsはkubectlでは作成不可。
- effectはPreferNoSchedule(なるべくスケジュールしない)/NoSchedule(スケジュールしない)/NoExecute(スケジュールしないし、既にスケジュールされているPodは停止する。)のどれか。
- NoScheduleとNoExecuteの場合は、「taintsのkey/value/effect」と「tolerationsのkey/value/effect」が一致する場合のみ、そのNodeにPodをSchedulingする。
- PreferNoScheduleの場合は一致しなくても優先度は下がるが、Scheduling自体はする。
PriorityClass
- SchedulingにおけるPodの優先度。kind: PriorityClassで作成する。
- valueが高いほど優先度は高い。
- 既にリソースの限界までSchedulingされている状態でpriorityの高いPodを作成しようとすると、priorityの低いPodは退避される。また、複数のPodがScheduling待ちの状態ではpritoriy順にソートされる。
- PodのYAMLのpriorityClassNameで紐づける。
cordon/uncordon/drain
- ノードのSchedulingステータスを確認する
kubectl get nodes
- ノードにSchedulingされないようにする
kubectl cordon <node>
- ノードにSchedulingされるように戻す
kubectl uncordon <node>
- ノードにSchedulingされないようにするかつ、起動中のpodは別のノードに退避させる。
kubectl drain <node> --force --ignore-daemonsets --delete-local-data
- 対象ノード上でReplicaSet経由でないPodが起動しているとエラーになるため
--force
をつける。 そのPodは削除される。 - 対象ノード上でDaemonSet経由で作られたPodが起動しているとエラーになるため
--ignore-daemonsets
をつける。
- PodDisruptionBudgetでdrain時に全てのpodが停止しないようにminAvailable(podの最小起動数)を設定する。
- 退避されずに残ったpodは、他のpodの退避が完了したら退避される。
- selector.matchLabelsでラベルベースにPodDisruptionBudgetの対象のpodを指定する。
- cordonするとノードにtaintsが付く仕組み。ただし単なるtaintsではない。したがって、cordonしてもpodのtolerationsをうまく設定すればSchedulingされてしまうのではないかという心配はしなくてよい。
リソースに関連するスケジューリング
- requests基準でCluster Autoscaleのスケジューリング判断を行う。
- requestsが高すぎると実際の負荷がそうでもないのにCluster Autoscaleされてしまう可能性がある。
- requestsがlimitsに対して低すぎると実際の負荷がかなり高いのにCluster Autoscaleしてくれない可能性がある。
- requestsは高すぎず、limitsと大きく離れた値にしないこと。実際の設定値は負荷試験で見極めていく。
- Guranteed > Burstable > BestEffortの順で優先度が高い。
- Guranteed
- requests/limitsが同じでCPUとmemoryの両方が設定されている
- Burstable
- Guaranteedではないが1つ以上のrequests/limitsが設定されている
- BestEffort
- requests/limitsがどちらも未設定
- Guranteed
- HPAはレプリカ数をCPU負荷などに応じて水平スケジューリングする機能。
- 各podのCPU使用率の平均値がtargetAverageUtilization(閾値)より高ければスケールアウトし、低ければスケールインする。
- スケジューリング判断のチェックは30秒に1回だが、スケーリング時のノイズを除去するために実際のスケールアウトは最大3分に1回、スケールインは最大5分に1回。
- いくつにスケーリングするかは、各podのCPU使用率の合計値をtargetAverageUtilizationで割った結果になる。(小数点切り上げ)
スケジューラその他
Podのspec.schedulerNameでschedulerを指定可能。
▼Monitoring&Observability
- 各Nodeのリソース使用状況を確認する
kubectl top nodes
- 各Podのリソース使用状況を確認する
kubectl top pods
▼kubeadmによるオンプレKubernetes環境の構築
kubeadmのインストール
以下を全てのNode(control planeおよびdata plane)で実施する。
// k8s.confの設定
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
> br_netfilter
> EOF
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
> net.bridge.bridge-nf-call-ip6tables = 1
> net.bridge.bridge-nf-call-iptables = 1
> EOF
sudo sysctl --system
// aptのupdate
sudo apt-get update
// 必要パッケージのインストール
sudo apt-get install -y apt-transport-https ca-certificates curl
// Google Cloudの公開鍵をダウンロード
sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
// Kubernetesのaptリポジトリを追加
echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
// aptのupdate
sudo apt-get update
// kubelet, kubeadm, kubectlのインストール
sudo apt-get install -y kubelet=<version> kubeadm=<version> kubectl=<version>
// パッケージが更新されないようにする
sudo apt-mark hold kubelet kubeadm kubectl
control planeのセットアップ
controle planeのNodeで以下を実行する。Flannelを使用する為、--pod-network-cidr=10.244.0.0/16を指定する。
kubeadm init --apiserver-cert-extra-sans=controlplane --apiserver-advertise-address <ip eth0> --pod-network-cidr=10.244.0.0/16
data planeのセットアップ
kubeadm join tokenの作成とjoinコマンドの出力
controle planceのNodeで以下を実行する。
kubeadm token create --print-join-command
joinコマンドの実行(data planeのノードに入って実行)
data planeのNodeで以下を実行する。
kubeadm join 10.33.92.10:6443 --token d3qmbz.wbotnx9alm0gbi4s --discovery-token-ca-cert-hash sha256:ffaddad5d14644d9ec0d421b729a17a17a80726d78b301521efb48fd9af719eb
flannel CNIのインストール
data planeのNodeで以下を実行する。
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/v0.20.2/Documentation/kube-flannel.yml
構築作業に失敗した場合
kubeadm initやkubeadm joinを実行する前の状態に戻す。
controle planceのNodeで以下を実行する。
sudo kubeadm reset
▼Clusterのバージョンアップ
現在のClusterのバージョンを確認する
kubectl get nodes
アップグレート可否とアップグレード可能なバージョンを確認する
kubeadm upgrade plan
起動中のPodを別のNodeに退避させる
kubectl drain <node> --force --ignore-daemonsets --delete-local-data
アップグレードする
Nodeを1つずつアップグレードする。
control planeのアップグレード
control planceのNodeで以下を実行する。
# kubeadmによるアップグレード
apt-get update
apt-get install kubeadm=<version>
kubeadm upgrade apply <version>
# kubeletのアップグレード
apt-get install kubelet=<version>
systemctl daemon-reload
systemctl restart kubelet
data planeのアップグレード
data planeのNodeで以下を実行する。
# kubeadmによるアップグレード
apt-get update
apt-get install kubeadm=<version>
kubeadm upgrade node
# kubeletのアップグレード
apt-get install kubelet=<version>
systemctl daemon-reload
systemctl restart kubelet
▼etcd
HA topology
Stacked etcd topology
概要
コントロールプレーンノードの内部にetcdを配置する構成。
セットアップやレプリケーションの管理がシンプルというメリットがある。
コントロールプレーンノードが故障するとetcdも故障するというデメリットがある。
見分け方
kubectl get pods -n kube-system
でetcdのミラーPodが存在すればStacked etcd topology。
バックアップ
作業はコントロールプレーンノード上で行う。
バックアップファイルは耐障害性の観点から別のストレージに移動した方がよい。
etcdを起動した際のオプションを確認する
kubectl describe pod <etcd> -n kube-system
スナップショットを取得する
ETCDCTL_API=3 etcdctl snapshot save <backup path> --endpoints=https://127.0.0.1:2379 --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key
スナップショットを確認する
ETCDCTL_API=3 etcdctl snapshot status <backup path> --write-out=table --endpoints=https://127.0.0.1:2379 --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key
リストア
作業はコントロールプレーンノード上で行う。
バックアップファイルがコントロールプレーンノード以外の場所にある場合は、事前にscpなどでコントロールプレーンノードに持ってくる。
ETCDCTL_API=3 etcdctl snapshot restore <backup path> --data-dir <data path>
/etc/kubernetes/manifests/etcd.yamlのvolumesのetcd-dataのpathを--data-dirで指定したデータベース保存先パスに置き換える。自動でrebootされる。
External etcd topology
概要
クラスターの外部にetcdを配置する構成。
コントロールプレーンノードそれぞれに対してetcdのホストが必要になるためインフラコストは増加する。
ETCDCTL_API=3 etcdctl member list --endpoints=https://127.0.0.1:2379 --cacert=/etc/etcd/pki/ca.pem --cert=/etc/etcd/pki/etcd.pem --key=/etc/etcd/pki/etcd-key.pem
でetcdノードの数を確認する
見分け方
kube-apiserverコマンドの--etcd-serversオプションで外部のサーバが指定されている場合はExternal etcd topology。
バックアップ
作業はetcdノード上で行う。
バックアップファイルは耐障害性の観点から別のストレージに移動した方がよい。
etcdを起動した際のオプションを確認する
ps -ef |grep etcd
スナップショットを取得する
ETCDCTL_API=3 etcdctl snapshot save <backup path> --endpoints=https://127.0.0.1:2379 --cacert=/etc/etcd/pki/ca.pem --cert=/etc/etcd/pki/etcd.pem --key=/etc/etcd/pki/etcd-key.pem
スナップショットを確認する
ETCDCTL_API=3 etcdctl snapshot status <backup path> --write-out=table --endpoints=https://127.0.0.1:2379 --cacert=/etc/etcd/pki/ca.pem --cert=/etc/etcd/pki/etcd.pem --key=/etc/etcd/pki/etcd-key.pem
リストア
作業はetcdノード上で行う。
バックアップファイルがetcdノード以外の場所にある場合は、事前にscpなどでetcdノードに持ってくる。
ETCDCTL_API=3 etcdctl snapshot restore <backup path> --data-dir <data path>
/etc/systemd/system/etcd.serviceのvolumesのetcd-dataのpathを--data-dirで指定したデータベース保存先パスに置き換える。
systemctl daemon-reload
systemctl restart etcd
▼Static Pod
- Static Podはkube-apiserverを介さずにkubeletが直接管理するPodのこと。例えば、control planeで動いているkube-api-server/scheduler/controller-manager/corednsなど。
- kubeletは各Static Podに対応するmirror podを自動的にkube-apiserver上に作成するため、kubectl(kube-apiserver)で確認できる。
-
/etc/kubernetes/manifests
配下にStatic PodのYAMLを配置する。このパスは、kubeletコマンドのconfigオプションで指定したconfigファイル内のstaticPodPathで変更可能。- このパスにPodのYAMLを配置すればStatic Podとして扱われる。つまり、自作のStatic Podを作成できる。当然ながらapplyは不要。
- Static Podを削除する場合はこのYAMLファイルを削除する。単にpodを削除しても自動で復活してしまう。
▼その他
テストハック系
- hostPathのPVのYAML例は公式ドキュメントで「PV hostpath」と検索するとでてくる。
- YAMLの設定項目を確認する
kubectl explain <resource> --recursive | less
- 公式ドキュメントのYAMLの例が見当たらない場合や、YAMLを参考にしたのになぜかエラーになる場合はこれで確認する。
- 実際にはリソース作成せずにYAMLだけ作る
kubectl run <pod name> --image <image> --dry-run=client -o yaml > <yaml>
- editしても変更不可だった場合は/tmp配下にYAMLが自動生成される。そのファイルを--forceでapplyすれば変更できる。
- editよりも
k get <resource> -o yaml > <yaml>
してそのyamlを編集してreplaceする方が速い。
- editよりも
- podのyamlを編集してapply(replace)したところ、変更不可だった場合は--forceする。
- ネットワーク繋がらない系問題の解き方
- NetworkPolicyの問題
- NetworkPolicyのspec.podSelectorで適切なPodのラベルが設定されているか
- ルールが適切か
- Ingressの問題
- backendのnameとportは適切か
- Serviceの問題
- Serviceのspec.selectorで適切なPodのラベルを設定できているか(endpointsがserviceに設定されていない場合は特に怪しい)
- Podの問題
- Podの状態やログを確認する。imagePullBackOffやHealthCheckで落ちていないかなど。
- NetworkPolicyの問題
kubectl系
- 全てのnamespace
kubectl get all -A
- イベントを取得する
kubectl get event -n <namespace>
- リソース数を取得する
kubectl get <resource> --no-headers | wc -l
- 大雑把に全リソースを取得する
kubectl get all
- 全リソースを取得する
kubectl api-resources
- 略称もこれで確認できる
- PersistentVolume関連はkubectlでは作成不可。
kubectl結果からの抽出
- Node名の一覧を抽出
kubectl get nodes -o jsonpath="{.items[*].metadata.name}"
- PersistentVolumeを容量順にソート
kubectl get pv --sort-by=.spec.capacity.storage
- PersistentVolumeを容量順にソートして、カラムを絞った上でカラム名をつける。
kubectl get pv --sort-by=.spec.capacity.storage -o=custom-columns=NAME:.metadata.name,CAPACITY:.spec.capacity.storage
- 特定kubeconfigの特定ユーザのコンテキスト名を取得する
kubectl config view --kubeconfig my-kube-config -o jsonpath="{.contexts[?(@.context.user=='aws-user')].name}"
Linuxコマンド系
- OSを確認する
cat /etc/os-release
- grepで後10行も見たい
| grep -A10
- grepで前10行も見たい
| grep -B10
ネットワーク系コマンド
- NIC確認
ip a
- ルーティング設定を確認
ip route
- defaultがデフォルトゲートウェイ。
- 各プロセスのIPやポートなどを確認
netstat -nplt
- nで名前解決しないでIPで表示。
- pでプログラムやプロセス名を表示。
- lでLISTENのものを抽出。
- tでTCPのものを抽出。
頻出バグ原因
Image名が不適切、ポート番号が不適切、ラベルが不適切、ファイル名が不適切、コマンドが不適切、Podの権限不足(RoleやRoleBindingの不備、ServiceAccountNameが設定されていない)、通信が通らない