😀
Kubernetes完全ガイド 雑多メモ
3. リソース
- Kubernetes Master と Kubernetes Node の2種類
- $ kubectl だけでなく、APIを呼び出すことでも操作可
- リソース
Workloads: コンテナ実行
8種類
Discovery&LB: 外部公開するようなエンドポイントを提供
7種類のServiceとIngress
Config&Strage: 設定・機密情報・永続化ボリューム
3種類
Cluster: セキュリティやクォータ
10種類
Metadata: クラスタ内の他リソースを操作する
4種類
4. APIリソースとkubectl
- Namespaceの利用により、1つのKubernetesクラスタを複数チームで運用したり、プロダクション環境・ステージング環境・開発環境に分けたりする。
例) kube-system, kube-public, default namespace - "--grace-period 0", "--force" でリソースを即座に強制的に削除する
- "kubectl apply" では、前回のマニフェスト・登録されているリソース・今回のマニフェストから差分が算出される → "kubectl create"よりもおすすめ
↓マージの挙動
https://kubernetes.io/docs/tasks/manage-kubernetes-objects/declarative-config/ - マニフェストの設定指針
- 全てのマイクロサービスのマニフェストを1つのディレクトリにまとめる(規模が小さいとき)
- 特定のサブシステムに分割する(まあまあ大きくなった時)
- マイクロサービスごとにディレクトリを切る(大規模システム)
- アノテーションとラベルの違い[どちらもメタデータ]
アノテーション→システムコンポーネントが利用する
ラベル→リソース管理に利用する
"-l" でフィルタリングする
"-l label1" であれば、存在するか
"-l label1=val1" であれば、ラベルが一致するか - "--prune" で削除されたリソースを検知して、自動的に削除する
-
set でリソースの一部情報を更新する[マニフェストと一致しなくなるため、乱用しないこと]
env, image, resources, selector, serviceaccount, subject が対象 -
get でJSON or YAMLで出力した時、より詳細な情報を確認できる
エイリアスでcustom-columnsを登録すると、ほしい情報だけ獲得できる - cp でローカルマシン-コンテナ間でファイルコピーする
- ログレベルを変更することで、デバッグを行う
HTTPリクエスト・レスポンスの概要→"-v=6"
HTTPリクエスト・レスポンスボディまで確認→"-v=8"
5. Workloadsリソース
- デザインパターン
サイドカーパターン:メインコンテナに機能を追加
アンバサダパターン:外部システムとのやりとりを代理で行う
アダプタパターン:外部からのアクセスのインタフェースとなる - Podはネットワークの名前空間を共有→Pod内でコンテナが同一ポートを指定すると起動できない
- spec.containers[].command と spec.containers[].args でコンテナイメージのENTRYPOINTとCMDを上書きする
- dnsPolicyでクラスタ内DNSではなく、外部DNSを指定する
- spec.hostAliasで/etc/hosts内のファイルを書き換える
- レプリカ数が不足している時は、templateからPodを作成する
- scale でPodをスケールする
- spec.templateの構造体ハッシュ値でDeploymentのアップデートとロールバックを行う
- DeamonSetはReplicaSetの特殊形で、各ノードに1つづつ配置するリソース
- StatefulSetもReplicaSetの特殊形で、ステートフルなワークロードに対応するためのリソース
スケールアウト 0→1→2の順、スケールイン 2→1→0の順
故に、0番目のPodをマスターノードとするような冗長化構成を持つアプリに最適 - Jobでバッチ処理を行い、spec.completionを指定しない場合に、ワークキューとして動作する
- spec.startingDeadlineSecondsで実行開始期限を制御する
- spec.successfulJobsHistoryLimit, spec.failedJobsHistoryLimitで保存する履歴の数を指定する
6. Discovery & LBリソース
- Serviceはサービスディスカバリの機能を提供する
- spec.ports.portにはサービスのポート番号、spec.ports.targetPortにはコンテナのポート番号
- ClusterIPでExternalIPサービスを使えば、指定ノードからはアクセスできる
↑ NodePortサービスを使えば、全てのノードからアクセスできる - spec.externalTrafficPolicyでClusterIPロードバランスを行うか指定できる(未検証)
- Headlessサービスは個々のIPアドレスが直接返ってくる
↑ 通常は、Cluster IPが返ってくる
7. Config & Storageリソース
- コンテナのデフォルトタイムゾーンはUTCである
→ spec.containers.envでTZ=Asia/Tokyo を環境変数として設定しておくといい - Pod情報はfieldRefで取得できる
コンテナ情報はresourceFieldRefで取得できる - GenericタイプのSecret作成方法は4通り
--from-file, --from-env-file, --from-literal, -f - Secretのデータはetcdに保存されており、Secretを利用するPodがあるときのみ、Nodeにデータを送る(データはtmpfs領域に保持される)
- Volumeはマニフェストで直接指定することで、利用可能なリソースであり、Persistent Volumeは永続化領域として確保されるリソースのこと
- VolumeはToDo
8. Cluster & Metadataリソース
- status.capacityはノードが所有しているCPUやメモリの量、status.allocatableはKubernetesが実際にPodに割り当て可能なリソースの量を指す
9. リソース管理とオートスケーリング
- requestsでリソースの下限、Limitsでリソースの上限を指定する
- Pending状態のPodができたタイミングでCluster Autoscalerが発動する
→ requestsとlimitsを適切に設定していないといけない - LimitRangeによって、PodやContainerに対して、リソースを制限する
- QoS Classの値によって、Podの優先度をつける
↑ requestsとlimitsの設定によって決まる - ResourceQuotaでNamespaceごとにリソース制限をする
- Cluster Autoscalerはクラスタノードをスケールさせる
- HorizontalPodAutoscaler(HPA)とは負荷に応じて、レプリカ数をスケールさせる(未検証)
- VerticalPodAutoscaler(VPA)とはコンテナに割り当てるリソースをスケールさせる(未検証)
10. ヘルスチェックとコンテナライフサイクル
- Liveness ProveはPodが正常動作するかチェックする
失敗時→Podを再起動する - Readiness ProveはPodがサービスインする準備ができているかチェックする
失敗時→トラフィックを流さない - ヘルスチェック方法は3つ
exec, httpGet, tcpSocket - ヘルスチェックの間隔は適切に指定する
- restartPolicyはAlways, OnFailure, Neverの3つ
- spec.InitContainersでメインコンテナを起動する前に、別コンテナで処理を行うことができる
- spec.containers.lifecycleでコンテナ起動後と停止直前に任意のコマンドを実行できる
- "preStop+SIGTERM"と"Serviceからの除外"は非同期で行われるため、"Serviceから除外"が終わるまでの数秒を待機すると安全に終了できる
11. メンテナンスとノードの停止
- $ kubectl cordon でノードのステータスを変更できる
-
$ kubectl drain で全てのPodを退避させる
処理としては、ノードをSchedulingDisabledにし、各Podに対してSIGTERMシグナルを送信する→Deploymentのセルフヒーリング機能により、別ノードでPodが作られる
12. 高度なスケジューリング
- スケジューリングの指定方法は5通り
nodeSelector, Node Affinity, Node Anti-Affinity, Inter-Pod Affinity, Inter-Pod Anti-Affinity -
spec.nodeSelector でラベルをもとにノードを指定してPodを動かせる
↑ ノードを直接指定することもできるが、これは望ましくないため、ラベルなどをもとに間接的にスケジューリングを行う - spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecutionで必須のスケジューリングポリシー
- spec.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecutionで優先するスケジューリングポリシー
- Inter-Pod Affinityは、特定のPodが実行されているノードやゾーンを指定してPodをスケジューリングする → Pod間通信のレイテンシを下げる
- Taints/Tolerationsでは、指定しない限りNodeでPodを動かさない
- Taintsの条件を全て満たすTolerationsがなければ、そのノードへはスケジューリングされない
13. セキュリティ
- ServiceAccountはNamespaceに紐づいており、これをもとに認証・認可を行う。
- SecurityContextで、コンテナに対するセキュリティ設定を行う。
privileged, capabilities, readOnlyRootFilesystem - PodSecurityContextで、Podに対するセキュリティ設定を行う。
- PodSecurityPolicyで、クラスタに対してポリシーによる制限を行う。
「PocSecurityAdmissionを使え」となっている。 - クラスタ内で通信制御を行うならpodSelectorかnamespaceSelector、クラスタ外の制御を行うならipBlockを利用する。
- AdmissionControlで、Kubernetes APIサーバへのリクエスト制御を行う。
PodPresetを使うことで、設定をInjectionできる。
14. マニフェストの汎用化
-
Helmとは、Kubernetesのパッケージマネージャである。
→ RedisやWordpressのクラスタ環境を1コマンドで作成する。
15. モニタリング
- DatadogやPrometheusを利用する。
16. ログの集約
- 基本的にログは標準出力・標準エラー出力に書き込む。
↑ アプリケーション側でファイル書き込みや外部への転送しないこと - Fluentdで/var/log/containers/の出力を読み出して、ログを転送する。
17. Kubernetes環境でのCI/CD
- CDツールとして、Spinnaker, Skaffold, Jenkins Xがある。
↑ 今なら、GitOpsでArgo CD使うのが多い? - 実運用では、kubectlでKubernetes環境を操作しないようにする。
18. マイクロサービスアーキテクチャとサービスメッシュ
- マイクロサービスではシステム全体(依存関係やトラフィックのレイテンシ)のモニタリングが難しい → Pod間の通信経路にプロキシを挟み、トラフィックのモニタリング・コントロールを行う(サービスメッシュ)
- できること
Circuit Breaker:転送先のマイクロサービスに問題がある場合に、アクセスを即座に遮断する
Fault Injection:意図的にリクエストを遅延させたり、失敗させたりする
レート制限
リクエスト失敗時のリトライ処理
19. Kubernetesのアーキテクチャ
- kubectlはkube-apiserverにリクエストを送り、DeploymentやServiceの作成・削除を行う。
-
$ kubectl apply -f sample.yaml → kube-apiserverにリクエスト
→etcdにspec.nodeName:""を登録→kube-schedularがkube-apiserverに書き換えリクエスト→kubeletがkube-apiserverにリクエストを送り、データを取得
20. Kubernetesとこれから
- OCI(Open Container Initiative): コンテナの標準仕様を策定する団体
- CRI(Container Runtime Interface): kubeletとコンテナランタイムをつなぐインタフェース
- CSI(Container Storage Interface): コンテナオーケストレーションエンジンとストレージをつなくためのインタフェース
- CNI(Container Network Interface): コンテナオーケストレーションエンジンとネットワークをつなぐためのインタフェース
Discussion