banner
云野阁

云野阁

闲云野鹤,八方逍遥

Kubernetesの知識整理 - コアコンポーネント

pod#

Kubernetes において、基本的にすべてのリソースの第一属性は同じで、主に 5 つの部分から構成されています:

  1. apiVersion <string> バージョン。Kubernetes 内部で定義されており、バージョン番号は kubectl api-versions で確認可能です。
  2. kind <string> タイプ。Kubernetes 内部で定義されており、バージョン番号は kubectl api-resources で確認可能です。
  3. metadata <object> メタデータ。主にリソースの識別と説明が含まれ、一般的には name、namespace、labels などがあります。
  4. spec <object> 説明。これは設定の中で最も重要な部分で、さまざまなリソースの設定に関する詳細な説明が含まれています。
  5. status <object> ステータス情報。内部の内容は定義する必要がなく、Kubernetes によって自動生成されます。

Pod のライフサイクル#

Pod オブジェクトが作成から終了までの時間範囲を Pod のライフサイクルと呼びます。そのライフサイクルの主なプロセスは以下の通りです:

  1. pod の作成
  2. 初期化コンテナの実行
  3. 主コンテナの実行
    (1)スタートフック、終了フック
    (2)生存性探査、準備性探査
  4. pod の終了

0

ライフサイクル全体で、Pod は 5 つの状態に分かれます:

  1. 保留中 (Pending):apiserver が pod リソースオブジェクトを作成しましたが、まだスケジュールが完了していないか、イメージのダウンロード中です。
  2. 実行中 (Running):pod が特定のノードにスケジュールされ、すべてのコンテナが kubelet によって作成されています。
  3. 成功 (Succeeded):pod 内のすべてのコンテナが正常に終了し、再起動されません。
  4. 失敗 (Failed):すべてのコンテナが終了しましたが、少なくとも 1 つのコンテナが失敗し、非 0 の終了ステータスを返しました。
  5. 不明 (Unknown):apiserver が pod オブジェクトの状態情報を正常に取得できず、通常はネットワーク通信の失敗によって引き起こされます。

pod の作成プロセス#

kubectl を使用して pod の設定を apiserver に送信し、apiserver は pod 情報を変換して etcd に保存し、次に「ハンドシェイク」フィードバックを行います。scheduler は apiserver 内の pod 情報の変化を監視し、アルゴリズムを使用して pod にホストを割り当て、apiserver の情報を更新します。対応する node ノードのホストは更新された情報を監視し、コンテナを作成して情報を apiserver に更新します。apiserver は最終情報を etcd に保存し、これで pod の作成が完了します。

  1. ユーザーは kubectl または他の API クライアントを使用して、作成する必要のある pod 情報を apiServer に送信します。
  2. apiServer は pod オブジェクトの情報を生成し、情報を etcd に保存し、確認情報をクライアントに返します。
  3. apiServer は etcd 内の pod オブジェクトの変化を反映し、他のコンポーネントは watch メカニズムを使用して apiServer の変動を追跡します。
  4. scheduler は新しい pod オブジェクトを作成する必要があることを発見し、Pod にホストを割り当て、結果情報を apiServer に更新します。
  5. node ノード上の kubelet は pod がスケジュールされていることを発見し、docker を呼び出してコンテナを起動し、結果を apiServer に返します。
  6. apiServer は受信した pod の状態情報を etcd に保存します。

1

pod の終了プロセス#

ユーザーが pod 削除コマンドを送信すると、apiserver は受け入れて情報を更新し、pod の状態が terminating に変わります。kubelet は受信後、pod 終了指示を起動し、エンドポイントコントローラーは pod 終了指示を監視し、対応するサービスリソースを削除します。pod は実行を停止し、kubelet は apiServer に pod リソースの猶予期間を 0 に設定するよう要求し、削除操作を完了します。apiserver は最終情報を etcd に保存し、これで pod の削除が完了します。

  1. ユーザーは apiServer に pod オブジェクトの削除コマンドを送信します。
  2. apiServer 内の pod オブジェクト情報は時間の経過とともに更新され、猶予期間内(デフォルト 30 秒)では pod は dead と見なされます。
  3. pod を terminating 状態にマークします。
  4. kubelet は pod オブジェクトが terminating 状態に変わったことを監視し、pod 終了プロセスを起動します。
  5. エンドポイントコントローラーは pod オブジェクトの終了動作を監視し、すべての一致するエンドポイントのサービスリソースのエンドポイントリストからそれを削除します。
  6. 現在の pod オブジェクトが preStop フックハンドラーを定義している場合、terminating にマークされた後、同期的に実行を開始します。
  7. pod オブジェクト内のコンテナプロセスは停止信号を受け取ります。
  8. 猶予期間が終了した後、pod 内にまだ実行中のプロセスが存在する場合、pod オブジェクトは即時終了信号を受け取ります。
  9. kubelet は apiServer にこの pod リソースの猶予期間を 0 に設定するよう要求し、削除操作を完了します。この時点で pod はユーザーには見えなくなります。

初期化コンテナ#

初期化コンテナは Pod の主コンテナが起動する前に実行されるコンテナで、主コンテナの前処理を行います。主に 2 つの特徴があります:

  1. 初期化コンテナは終了するまで実行を完了する必要があります。もし初期化コンテナが失敗した場合、Kubernetes は成功するまで再起動する必要があります。
  2. 初期化コンテナは定義された順序で実行される必要があり、前のコンテナが成功した場合にのみ次のコンテナが実行されます。
    初期化コンテナには多くのアプリケーションシーンがあり、以下は最も一般的なものです:
  3. 主コンテナのイメージにないツールやカスタムコードを提供します。
  4. 初期化コンテナはアプリケーションコンテナの前に直列に起動し、実行を完了する必要があるため、アプリケーションコンテナの起動を遅延させるために使用できます。
    次に、以下の要求をシミュレートするケースを作成します:
    主コンテナで Nginx を実行する必要がありますが、Nginx を実行する前に MySQL と Redis があるサーバーに接続できる必要があります。
    テストを簡素化するために、MySQL と Redis の IP アドレスをそれぞれ 192.168.18.103 と 192.168.18.104 に設定します(注意:これらの IP は ping 通しません。環境にこれらの IP がないためです)。
    pod-initcontainer.yaml ファイルを作成し、内容は以下の通りです:
apiVersion: v1
kind: Pod
metadata:
  name: pod-initcontainer
  namespace: dev
  labels:
    user: xudaxian
spec:
  containers: # コンテナ設定
    - name: nginx
      image: nginx:1.17.1
      imagePullPolicy: IfNotPresent
      ports:
        - name: nginx-port
          containerPort: 80
          protocol: TCP
      resources:
        limits:
          cpu: "2"
          memory: "10Gi"
        requests:
          cpu: "1"
          memory: "10Mi"
  initContainers: # 初期化コンテナ設定
    - name: test-mysql
      image: busybox:1.30
      command: ["sh","-c","until ping 192.168.18.103 -c 1;do echo waiting for mysql ...;sleep 2;done;"]
      securityContext:
        privileged: true # 特権モードでコンテナを実行
    - name: test-redis
      image: busybox:1.30
      command: ["sh","-c","until ping 192.168.18.104 -c 1;do echo waiting for redis ...;sleep 2;done;"]

コマンドを実行すると、test-mysql は正常に作成されず、後続のコンテナも作成できません。アクセス可能な IP に変更して再度コマンドを実行すると、順番に正常に作成されます。

フック関数#

Kubernetes は主コンテナの起動後と停止前に 2 つのフック関数を提供します:

  • post start:コンテナが作成された後に実行され、失敗した場合はコンテナが再起動されます。

  • pre stop:コンテナが終了する前に実行され、実行が完了した後にコンテナは正常に終了します。完了するまでコンテナの削除操作はブロックされます。

フックハンドラーは以下の 3 つの方法でアクションを定義することをサポートしています:

  • exec コマンド:コンテナ内でコマンドを 1 回実行します。
  .......
    lifecycle:
       postStart: 
          exec:
             command:
               - cat
               - /tmp/healthy
  .......
  • tcpSocket:現在のコンテナが指定されたソケットにアクセスしようとします。
  .......
     lifecycle:
        postStart:
           tcpSocket:
              port: 8080
  .......
  • httpGet:現在のコンテナ内の特定の URL に HTTP リクエストを送信します。
  ....... 
     lifecycle:
        postStart:
           httpGet:
              path: / #URIアドレス
              port: 80 #ポート番号
              host: 192.168.109.100 #ホストアドレス  
              scheme: HTTP #サポートされるプロトコル、httpまたはhttps
  .......

コンテナ探査#

コンテナ探査は、コンテナ内のアプリケーションインスタンスが正常に動作しているかどうかを検出するために使用され、ビジネスの可用性を保証するための伝統的なメカニズムです。探査の結果、インスタンスの状態が期待通りでない場合、Kubernetes はその問題のあるインスタンスを「取り除き」、ビジネスのトラフィックを負担しません。Kubernetes は、コンテナ探査を実現するために 2 種類のプローブを提供しています:

  • liveness probes:生存性探査。アプリケーションインスタンスが現在正常に動作しているかどうかを検出します。そうでない場合、k8s はコンテナを再起動します。

  • readiness probes:準備性探査。アプリケーションインスタンスがリクエストを受け入れられるかどうかを検出します。受け入れられない場合、k8s はトラフィックを転送しません。

livenessProbe:生存性探査。コンテナを再起動するかどうかを決定します。
readinessProbe:準備性探査。リクエストをコンテナに転送するかどうかを決定します。

k8s は 1.16 バージョン以降に startupProbe プローブを追加しました。これは、コンテナ内のアプリケーションが起動したかどうかを判断するために使用されます。startupProbe プローブが設定されている場合、他のプローブは成功するまで禁止され、成功すると探査は行われなくなります。

上記の 2 種類のプローブは、現在 3 つの探査方法をサポートしています:

  • exec コマンド:コンテナ内でコマンドを 1 回実行します。コマンドの終了コードが 0 であれば、プログラムは正常と見なされ、そうでなければ異常と見なされます。
  ……
    livenessProbe:
       exec:
          command:
            -    cat
            -    /tmp/healthy
  ……
  • tcpSocket:ユーザーコンテナのポートにアクセスしようとします。接続が確立できれば、プログラムは正常と見なされ、そうでなければ異常と見なされます。
  ……
     livenessProbe:
        tcpSocket:
           port: 8080
  ……
  • httpGet:コンテナ内の Web アプリケーションの URL を呼び出します。返されたステータスコードが 200 から 399 の間であれば、プログラムは正常と見なされ、そうでなければ異常と見なされます。
……
   livenessProbe:
      httpGet:
         path: / #URIアドレス
         port: 80 #ポート番号
         host: 127.0.0.1 #ホストアドレス
         scheme: HTTP #サポートされるプロトコル、httpまたはhttps
……

再起動ポリシー#

コンテナ探査において、コンテナ探査に問題が発生した場合、Kubernetes はコンテナが存在する Pod を再起動します。これは Pod の再起動ポリシーによって決定されます。Pod の再起動ポリシーには 3 つの種類があります:

  • Always:コンテナが失敗した場合、自動的にそのコンテナを再起動します。デフォルト値です。
  • OnFailure:コンテナが終了し、終了コードが 0 でない場合に再起動します。
  • Never:状態に関係なく、そのコンテナを再起動しません。

再起動ポリシーは Pod オブジェクト内のすべてのコンテナに適用されます。最初に再起動が必要なコンテナは、必要なときに即座に再起動され、その後の再起動操作は kubelet によって遅延され、繰り返しの再起動操作の遅延時間は 10 秒、20 秒、40 秒、80 秒、160 秒、300 秒となり、300 秒が最大の遅延時間です。

Pod のスケジューリング#

デフォルトでは、Pod がどの Node ノードで実行されるかは、Scheduler コンポーネントが適切なアルゴリズムを使用して計算します。このプロセスは人工的に制御されません。しかし、実際の使用においては、特定の Pod を特定のノードに到達させたい場合が多く、そのためには Kubernetes の Pod スケジューリングルールを理解する必要があります。Kubernetes は 4 つの主要なスケジューリング方式を提供しています。

  • 自動スケジューリング:どの Node ノードで実行されるかは完全に Scheduler によって一連のアルゴリズム計算によって決定されます。
  • 指向スケジューリング:NodeName、NodeSelector。
  • 親和性スケジューリング:NodeAffinity、PodAffinity、PodAntiAffinity。
  • 汚染(耐性)スケジューリング:Taints、Toleration。

指向スケジューリング#

指向スケジューリングは、Pod に宣言されたnodeNameまたはnodeSelectorを利用して、Pod を希望する Node ノードにスケジュールすることを指します。注意すべきは、ここでのスケジューリングは強制的であり、スケジュール対象の Node が存在しなくても上記にスケジュールされますが、Pod の実行は失敗します。

nodeName#

nodeName は Pod を特定の名前の Node ノードに強制的にスケジュールするために使用されます。この方法は、Scheduler のスケジューリングロジックを直接スキップし、Pod を指定された名前のノードに直接スケジュールします。
pod-nodename.yaml ファイルを作成し、内容は以下の通りです:

apiVersion: v1
kind: Pod
metadata:
  name: pod-nodename
  namespace: dev
  labels:
    user: xudaxian
spec:
  containers: # コンテナ設定
    - name: nginx
      image: nginx:1.17.1
      imagePullPolicy: IfNotPresent
      ports:
        - name: nginx-port
          containerPort: 80
          protocol: TCP
  nodeName: k8s-node1 # k8s-node1ノードにスケジュールするよう指定
nodeSelector#

nodeSelector は Pod を特定のラベルが付けられた Node ノードにスケジュールするために使用されます。これは Kubernetes の label-selector メカニズムを通じて実現されます。言い換えれば、Pod が作成される前に、Scheduler は MatchNodeSelector スケジューリングポリシーを使用してラベルをマッチングし、ターゲットノードを見つけて Pod をターゲットノードにスケジュールします。このマッチングルールは強制的な制約です。

apiVersion: v1
kind: Pod
metadata:
  name: pod-nodeselector
  namespace: dev
spec:
  containers: # コンテナ設定
    - name: nginx
      image: nginx:1.17.1
      imagePullPolicy: IfNotPresent
      ports:
        - name: nginx-port
          containerPort: 80
          protocol: TCP
  nodeSelector:
    nodeenv: pro # nodeenv=proのNodeノードにスケジュールするよう指定

親和性スケジューリング#

指向スケジューリングの 2 つの方法は非常に便利ですが、条件を満たす Node がない場合、Pod は実行されません。たとえクラスター内に利用可能な Node のリストがあっても、これが使用シーンを制限します。
上記の問題に基づいて、Kubernetes は親和性スケジューリング(Affinity)を提供しています。これは nodeSelector の基盤の上に拡張され、条件を満たす Node を優先的に選択してスケジュールすることができ、条件を満たさないノードにもスケジュールできるため、スケジューリングがより柔軟になります。Affinity は主に 3 つのカテゴリに分かれます:

  • nodeAffinity(node 親和性):Node をターゲットにし、Pod がどの Node にスケジュールできるかを解決します。
  • podAffinity(pod 親和性):Pod をターゲットにし、Pod がどの既存の Pod と同じトポロジ領域にデプロイできるかを解決します。
  • podAntiAffinity(pod 反親和性):Pod をターゲットにし、Pod がどの既存の Pod と同じトポロジ領域にデプロイできないかを解決します。

親和性と反親和性の使用シーンに関する説明:

  • 親和性:2 つのアプリケーションが頻繁に相互作用する場合、親和性を利用して 2 つのアプリケーションをできるだけ近くに配置することが重要です。これにより、ネットワーク通信による性能損失を減らすことができます。
  • 反親和性:アプリケーションが複数のレプリカでデプロイされる場合、反親和性を利用して各アプリケーションインスタンスをさまざまな Node に分散させることが重要です。これにより、サービスの高可用性が向上します。
nodeAffinity(node 親和性)#

nodeAffinity のオプション設定を確認します:

pod.spec.affinity.nodeAffinity
  requiredDuringSchedulingIgnoredDuringExecution  Nodeノードは指定されたすべてのルールを満たす必要があり、これはハード制約に相当します。
    nodeSelectorTerms  ノード選択リスト
      matchFields   ノードフィールドに基づくノード選択器要求リスト  
      matchExpressions   ノードラベルに基づくノード選択器要求リスト(推奨)
        key    キー
        values 値
        operator 演算子(Exists, DoesNotExist, In, NotIn, Gt, Ltをサポート)
  preferredDuringSchedulingIgnoredDuringExecution 指定されたルールを満たすNodeに優先的にスケジュールされます。これはソフト制約に相当します(傾向)。
    preference   ノード選択器項目、関連する重みと関連付けられています。
      matchFields ノードフィールドに基づくノード選択器要求リスト
      matchExpressions   ノードラベルに基づくノード選択器要求リスト(推奨)
        key キー
        values 値
        operator 演算子(In, NotIn, Exists, DoesNotExist, Gt, Ltをサポート)  
    weight 傾向の重み、範囲は1-100です。

演示 requiredDuringSchedulingIgnoredDuringExecution:
pod-nodeaffinity-required.yaml ファイルを作成し、内容は以下の通りです:

apiVersion: v1
kind: Pod
metadata:
  name: pod-nodeaffinity-required
  namespace: dev
spec:
  containers: # コンテナ設定
    - name: nginx
      image: nginx:1.17.1
      imagePullPolicy: IfNotPresent
      ports:
        - name: nginx-port
          containerPort: 80
          protocol: TCP
  affinity: # 親和性設定
    nodeAffinity: # node親和性設定
      requiredDuringSchedulingIgnoredDuringExecution: # Nodeノードは指定されたすべてのルールを満たす必要があり、これはハードルールに相当します。定向スケジューリングに似ています。
        nodeSelectorTerms: # ノード選択リスト
          - matchExpressions:
              - key: nodeenv # nodeenvのラベルを持つノードをマッチングし、valueが"xxx"または"yyy"のノード
                operator: In
                values:
                  - "xxx"
                  - "yyy"

nodeAffinity の注意事項:

  • nodeSelector と nodeAffinity の両方が同時に定義されている場合、Pod は指定された Node で実行されるために両方の条件を満たす必要があります。
  • nodeAffinity が複数の nodeSelectorTerms を指定している場合、1 つのマッチが成功すれば十分です。
  • 1 つの nodeSelectorTerms 内に複数の matchExpressions がある場合、ノードはすべてを満たす必要があります。
  • Pod が実行中にその Node のラベルが変更され、Pod の nodeAffinity の要件を満たさなくなった場合、システムはこの変更を無視します。
podAffinity(pod 親和性)#

podAffinity は、実行中の Pod を参照として、新しく作成された Pod を参照の Pod と同じ領域に配置する機能を実現します。
PodAffinity のオプション設定:

pod.spec.affinity.podAffinity
  requiredDuringSchedulingIgnoredDuringExecution  ハード制約
    namespaces  参照podのnamespaceを指定
    topologyKey  スケジューリングの作用域を指定
    labelSelector  ラベル選択器
      matchExpressions  ノードラベルに基づくノード選択器要求リスト(推奨)
        key    キー
        values 値
        operator 演算子(In, NotIn, Exists, DoesNotExist)
      matchLabels    複数のmatchExpressionsのマッピング内容  
  preferredDuringSchedulingIgnoredDuringExecution ソフト制約    
    podAffinityTerm  オプション
      namespaces
      topologyKey
      labelSelector
         matchExpressions 
            key    キー  
            values 値  
            operator
         matchLabels 
    weight 傾向の重み、範囲は1-1

topologyKey はスケジューリングの作用域を指定します。例えば:

  • kubernetes.io/hostname を指定すると、Node ノードで区別されます。
  • beta.kubernetes.io/os を指定すると、Node ノードのオペレーティングシステムの種類で区別されます。

requiredDuringSchedulingIgnoredDuringExecution を演示します。
pod-podaffinity-requred.yaml ファイルを作成し、内容は以下の通りです:

apiVersion: v1
kind: Pod
metadata:
  name: pod-podaffinity-requred
  namespace: dev
spec:
  containers: # コンテナ設定
    - name: nginx
      image: nginx:1.17.1
      imagePullPolicy: IfNotPresent
      ports:
        - name: nginx-port
          containerPort: 80
          protocol: TCP
  affinity: # 親和性設定
    podAffinity: # Pod親和性
      requiredDuringSchedulingIgnoredDuringExecution: # ハード制約
        - labelSelector:
            matchExpressions: # このPodはpodenv=xxxまたはpodenv=yyyのラベルを持つPodと同じNode上でなければなりません。明らかにそのようなPodはありません。
              - key: podenv
                operator: In
                values:
                  - "xxx"
                  - "yyy"
          topologyKey: kubernetes.io/hostname
podAntiAffinity(pod 反親和性)#

podAntiAffinity は、実行中の Pod を参照として、新しく作成された Pod が参照の Pod と同じ領域に存在しない機能を実現します。
その設定方法は podAffinity と同じです。

apiVersion: v1
kind: Pod
metadata:
  name: pod-podantiaffinity-requred
  namespace: dev
spec:
  containers: # コンテナ設定
    - name: nginx
      image: nginx:1.17.1
      imagePullPolicy: IfNotPresent
      ports:
        - name: nginx-port
          containerPort: 80
          protocol: TCP
  affinity: # 親和性設定
    podAntiAffinity: # Pod反親和性
      requiredDuringSchedulingIgnoredDuringExecution: # ハード制約
        - labelSelector:
            matchExpressions:
              - key: podenv
                operator: In
                values:
                  - "pro"
          topologyKey: kubernetes.io/hostname

汚染と耐性#

汚染(Taints)#

前述のスケジューリング方式はすべて Pod の視点から見たもので、Pod が指定された Node にスケジュールされるかどうかを決定するために属性を追加します。実際には Node の視点から見て、Node に汚染属性を追加することで、Pod のスケジューリングを決定することもできます。
Node に汚染が設定されると、Pod との間に排他的な関係が生じ、Pod のスケジューリングを拒否し、すでに存在する Pod を追い出すことさえできます。
汚染の形式は:key=valueで、key と value は汚染のラベルで、effect は汚染の作用を説明します。以下の 3 つのオプションをサポートしています:

  • PreferNoSchedule:Kubernetes は、他にスケジュールできるノードがない場合を除き、汚染のある Node に Pod をスケジュールすることをできるだけ避けます。
  • NoSchedule:Kubernetes は、汚染のある Node に Pod をスケジュールしませんが、すでに存在する Pod には影響しません。
  • NoExecute:Kubernetes は、汚染のある Node に Pod をスケジュールせず、すでに存在する Pod も追い出します。

2

耐性(Toleration)#

上記で汚染の作用を説明しました。Node に汚染を追加して Pod のスケジューリングを拒否することができますが、汚染のある Node に Pod をスケジュールしたい場合は、耐性を使用する必要があります。

汚染は拒否、耐性は無視です。Node は汚染によって Pod のスケジューリングを拒否し、Pod は耐性によって拒否を無視します。

耐性の詳細な設定:

kubectl explain pod.spec.tolerations
......
FIELDS:
  key       # 容認する汚染のキーに対応し、空はすべてのキーにマッチ
  value     # 容認する汚染の値に対応
  operator  # key-valueの演算子。EqualとExists(デフォルト)をサポート
  effect    # 汚染のeffectに対応し、空はすべての影響にマッチ
  tolerationSeconds   # 耐性時間。effectがNoExecuteの場合に有効で、PodがNodeに滞在する時間を示します。

operator が Equal の場合、Node ノードに複数の Taint がある場合、Pod はすべての Taint を容認する必要があります。
operator が Exists の場合、以下の 3 つの書き方があります:

  • 指定された汚染を容認し、汚染が指定された effect を持つ場合:
  • 指定された汚染を容認し、具体的な effect は考慮しない:
  • すべての汚染を容認する(注意が必要):
  tolerations: # 耐性
    - key: "tag" # 容認する汚染のkey
      operator: Exists # 演算子
      effect: NoExecute # 容認のルールを追加。ここではマークされた汚染ルールと同じでなければなりません。
  tolerations: # 耐性
    - key: "tag" # 容認する汚染のkey
      operator: Exists # 演算子
 tolerations: # 耐性
    - operator: Exists # 演算子

Pod コントローラー#

Kubernetes では、Pod の作成方法に応じて、Pod を 2 つのカテゴリに分けることができます:

  • 自主式 Pod:Kubernetes が直接作成した Pod。この Pod は削除されると消え、再作成されません。
  • コントローラーによって作成された Pod:Pod コントローラーによって作成された Pod。この Pod は削除されると自動的に再作成されます。

Pod コントローラー:Pod コントローラーは Pod を管理する中間層で、Pod コントローラーを使用すると、必要な数の Pod を指定するだけで、条件を満たす Pod を作成し、各 Pod がユーザーの期待する状態にあることを保証します。Pod が実行中に障害が発生した場合、コントローラーは指定されたポリシーに基づいて Pod を再起動または再作成します。
Kubernetes には多くの種類の Pod コントローラーがあり、それぞれに適したシーンがあります。一般的なものは以下の通りです:

  • ReplicationController:比較的原始的な Pod コントローラーで、ReplicaSet に置き換えられました。
  • ReplicaSet:指定された数の Pod が実行されることを保証し、Pod の数の変更やイメージのバージョン変更をサポートします。
  • Deployment:ReplicaSet を制御して Pod を制御し、ローリングアップグレードやバージョンのロールバックをサポートします。
  • Horizontal Pod Autoscaler:クラスターの負荷に基づいて Pod の数を自動的に調整し、ピークを平準化します。
  • DaemonSet:クラスター内の指定された Node 上で 1 つのレプリカを実行し、一般的にはデーモンプロセスのタスクに使用されます。
  • Job:作成された Pod はタスクを完了するとすぐに終了し、一時的なタスクを実行するために使用されます。
  • CronJob:作成された Pod は定期的に実行され、定期的なタスクを実行するために使用されます。
  • StatefulSet:有状態のアプリケーションを管理します。

ReplicaSet(RS)#

ReplicaSet の主な役割は、一定数の Pod が正常に実行されることを保証することです。ReplicaSet はこれらの Pod の実行状態を継続的に監視し、Pod に障害が発生した場合は再起動または再作成します。

3

ReplicaSet のリソースマニフェストファイル:

apiVersion: apps/v1 # バージョン番号 
kind: ReplicaSet # タイプ 
metadata: # メタデータ 
  name: # rsの名前
  namespace: # 所属名前空間 
  labels: # ラベル 
    controller: rs 
spec: # 詳細説明 
  replicas: 3 # レプリカ数 
  selector: # セレクタ。どのPodをこのコントローラーが管理するかを指定します。
    matchLabels: # Labelsマッチングルール 
      app: nginx-pod 
    matchExpressions: # Expressionsマッチングルール 
      - {key: app, operator: In, values: [nginx-pod]} 
template: # テンプレート。レプリカ数が不足している場合、以下のテンプレートに基づいてPodのレプリカを作成します。
  metadata: 
    labels: 
      app: nginx-pod 
  spec: 
    containers: 
      - name: nginx 
        image: nginx:1.17.1 
        ports: 
        - containerPort: 80

ここで新たに理解する必要がある設定項目は、spec の下にあるいくつかのオプションです:

  • replicas:指定されたレプリカ数。実際には、rs が作成する Pod の数で、デフォルトは 1 です。
  • selector:セレクタ。これは Pod コントローラーと Pod の関連付けを確立する役割を果たし、Label Selector メカニズムを採用しています(Pod モジュールで Label を定義し、コントローラーでセレクタを定義することで、現在のコントローラーがどの Pod を管理できるかを示します)。
  • template:テンプレート。これは現在のコントローラーが Pod を作成するために使用するテンプレートで、実際には前に学んだ Pod の定義が含まれています。

Deployment(Deploy)#

サービス編成の問題をより良く解決するために、Kubernetes は v1.2 バージョンから Deployment コントローラーを導入しました。特筆すべきは、Deployment コントローラーは Pod を直接管理するのではなく、ReplicaSet を管理することによって Pod を間接的に管理することです。つまり、Deployment は ReplicaSet を管理し、ReplicaSet は Pod を管理します。したがって、Deployment の機能は ReplicaSet よりも強力です。

Deployment の主な機能は以下の通りです:

  • ReplicaSet のすべての機能をサポートします。
  • 公開の停止、再開をサポートします。
  • バージョンのローリングアップデートとバージョンのロールバックをサポートします。

Deployment のリソースマニフェスト:

apiVersion: apps/v1 # バージョン番号 
kind: Deployment # タイプ 
metadata: # メタデータ 
  name: # rsの名前 
  namespace: # 所属名前空間 
  labels: # ラベル 
    controller: deploy 
spec: # 詳細説明 
  replicas: 3 # レプリカ数 
  revisionHistoryLimit: 3 # 履歴バージョンを保持。デフォルトは10 
  paused: false # デプロイを一時停止。デフォルトはfalse 
  progressDeadlineSeconds: 600 # デプロイのタイムアウト時間(秒)。デフォルトは600 
  strategy: # ストラテジー 
    type: RollingUpdate # ローリングアップデート戦略 
    rollingUpdate: # ローリングアップデート 
      maxSurge: 30% # 最大追加で存在できるレプリカ数。パーセントまたは整数で指定可能。 maxUnavailable: 30% # 最大不可用状態のPodの最大値。パーセントまたは整数で指定可能。 
  selector: # セレクタ。どのPodをこのコントローラーが管理するかを指定します。 
    matchLabels: # Labelsマッチングルール 
      app: nginx-pod 
    matchExpressions: # Expressionsマッチングルール 
      - {key: app, operator: In, values: [nginx-pod]} 
  template: # テンプレート。レプリカ数が不足している場合、以下のテンプレートに基づいてPodのレプリカを作成します。 
    metadata: 
      labels: 
        app: nginx-pod 
    spec: 
      containers: 
      - name: nginx 
        image: nginx:1.17.1 
        ports: 
        - containerPort: 80

Deployment は、イメージの更新戦略として再構築更新とローリング更新(デフォルト)をサポートし、strategy オプションを通じて設定できます。

strategy: 新しいPodが古いPodを置き換える戦略を指定します。2つの属性をサポートします。
  type: 戦略タイプを指定します。2つの戦略をサポートします。
    Recreate:新しいPodを作成する前に、すべての既存のPodを削除します。
    RollingUpdate:ローリングアップデート。つまり、一部を削除し、一部を起動し、更新プロセス中に2つのバージョンのPodが存在します。
  rollingUpdate:typeがRollingUpdateの場合に有効で、rollingUpdateのパラメータを設定します。2つの属性をサポートします:
    maxUnavailable:アップグレード中に不可用のPodの最大数を指定します。デフォルトは25%です。
    maxSurge:アップグレード中に期待されるPodの最大数を超えることができる最大数を指定します。デフォルトは25%です。

Deployment は、バージョンのアップグレードプロセス中の一時停止、再開機能やバージョンのロールバックなど、多くの機能をサポートしています。以下に具体的に見てみましょう:

# バージョンアップグレード関連機能
kubetl rollout パラメータ deploy xx  # 以下の選択をサポート
# status 現在のアップグレードの状態を表示
# history アップグレードの履歴を表示
# pause アップグレードプロセスを一時停止
# resume 一時停止されたアップグレードプロセスを再開
# restart アップグレードプロセスを再起動
# undo 前のバージョンにロールバック(--to-revisionを使用して指定されたバージョンにロールバック可能)

Deployment がバージョンのロールバックを実現できるのは、履歴の ReplicaSet を記録することによって実現されます。ロールバックしたいバージョンに戻すには、現在のバージョンの Pod 数を 0 に減らし、ロールバックバージョンの Pod 数を目標数に引き上げるだけです。

カナリアリリース#

Deployment は、更新プロセス中の制御をサポートします。たとえば、更新操作を一時停止(pause)したり、更新操作を再開(resume)したりできます。
たとえば、新しい Pod リソースのバッチが作成された後、更新プロセスを直ちに一時停止することができます。この時点で、新しいバージョンのアプリケーションが一部存在し、主体部分は古いバージョンのままです。その後、少数のユーザーリクエストを新しいバージョンの Pod アプリケーションにフィルタリングし、期待通りに安定して実行できるかどうかを観察します。問題がなければ、残りの Pod リソースのローリングアップデートを続行し、問題があれば即座にロールバック操作を行います。

Horizontal Pod Autoscaler(HPA)#

手動で kubectl scale コマンドを実行することで Pod のスケールアップやスケールダウンを実現できますが、これは明らかに Kubernetes の目標である自動化とインテリジェンスには合致しません。Kubernetes は、Pod の使用状況を監視することで Pod の数を自動的に調整できることを期待しており、そのために HPA というコントローラーが生まれました。
HPA は各 Pod の利用率を取得し、HPA で定義された指標と比較し、必要なスケール値を計算し、最終的に Pod の数を調整します。実際、HPA も以前の Deployment と同様に Kubernetes リソースオブジェクトの一種であり、ターゲット Pod の負荷変動を追跡分析することで、ターゲット Pod のレプリカ数を調整する必要があるかどうかを判断します。

5

クラスター内にリソース使用状況を収集するプログラムがない場合は、metrics-server をインストールすることを選択できます。

テスト例:

apiVersion: autoscaling/v1 # バージョン番号
kind: HorizontalPodAutoscaler # タイプ
metadata: # メタデータ
  name: pc-hpa # deploymentの名前
  namespace: dev # 名前空間
spec:
  minReplicas: 1 # 最小Pod数
  maxReplicas: 10 # 最大Pod数
  targetCPUUtilizationPercentage: 3 # CPU使用率指標
  scaleTargetRef:  # 制御するNginxの情報を指定
    apiVersion: apps/v1
    kind: Deployment
    name: nginx

DaemonSet(DS)#

DaemonSet タイプのコントローラーは、クラスター内のすべての(または指定された)ノードで 1 つのレプリカが実行されることを保証します。一般的にはログ収集やノード監視などのシーンで使用されます。つまり、Pod が提供する機能がノードレベルのものである場合(各ノードで必要かつ 1 つだけ必要)、このタイプの Pod は DaemonSet タイプのコントローラーを使用して作成するのが適しています。

DaemonSet コントローラーの特徴:

  • クラスターにノードが追加されるたびに、指定された Pod のレプリカもそのノードに追加されます。
  • ノードがクラスターから削除されると、Pod もガーベジコレクションされます。

DaemonSet のリソースマニフェスト:

apiVersion: apps/v1 # バージョン番号
kind: DaemonSet # タイプ
metadata: # メタデータ
  name: # 名前
  namespace: # 名前空間
  labels: # ラベル
    controller: daemonset
spec: # 詳細説明
  revisionHistoryLimit: 3 # 履歴バージョンを保持
  updateStrategy: # 更新戦略
    type: RollingUpdate # ローリングアップデート戦略
    rollingUpdate: # ローリングアップデート
      maxUnavailable: 1 # 最大不可用状態のPodの最大値。パーセントまたは整数で指定可能。
  selector: # セレクタ。どのPodをこのコントローラーが管理するかを指定します。
    matchLabels: # Labelsマッチングルール
      app: nginx-pod
    matchExpressions: # Expressionsマッチングルール
      - key: app
        operator: In
        values:
          - nginx-pod
  template: # テンプレート。レプリカ数が不足している場合、以下のテンプレートに基づいてPodのテンプレートを作成します。
     metadata:
       labels:
         app: nginx-pod
     spec:
       containers:
         - name: nginx
           image: nginx:1.17.1
           ports:
             - containerPort: 80

Job#

Job は、バッチ処理の短期的な一時的なタスクを担当します。
Job の特徴:

  • Job が作成した Pod が成功裏に終了すると、Job は成功した Pod の数を記録します。
  • 成功した Pod の数が指定された数に達すると、Job は実行を完了します。

Job は指定された数の Pod が実行されることを保証できます。

Job のリソースマニフェスト:

apiVersion: batch/v1 # バージョン番号
kind: Job # タイプ
metadata: # メタデータ
  name:  # 名前
  namespace:  # 名前空間
  labels: # ラベル
    controller: job
spec: # 詳細説明
  completions: 1 # Jobが成功裏に実行されるPodの総数を指定。デフォルトは1
  parallelism: 1 # Jobが同時に実行するPodの数を指定。デフォルトは1
  activeDeadlineSeconds: 30 # Jobが実行できる時間制限を指定。時間を超えると、システムは終了を試みます。
  backoffLimit: 6 # Jobが失敗した後の再試行回数を指定。デフォルトは6
  manualSelector: true # セレクタを使用してPodを選択できるかどうか。デフォルトはfalse
  selector: # セレクタ。どのPodをこのコントローラーが管理するかを指定します。
    matchLabels: # Labelsマッチングルール
      app: counter-pod
    matchExpressions: # Expressionsマッチングルール
      - key: app
        operator: In
        values:
          - counter-pod
  template: # テンプレート。レプリカ数が不足している場合、以下のテンプレートに基づいてPodのテンプレートを作成します。
     metadata:
       labels:
         app: counter-pod
     spec:
       restartPolicy: Never # 再起動ポリシーはNeverまたはOnFailureに設定する必要があります。
       containers:
         - name: counter
           image: busybox:1.30
           command: ["/bin/sh","-c","for i in 9 8 7 6 5 4 3 2 1;do echo $i;sleep 20;done"]

テンプレート内の再起動ポリシーに関する説明:

  • OnFailure に設定すると、Job は Pod が故障したときにコンテナを再起動しますが、Pod を作成せず、失敗回数は変わりません。
  • Never に設定すると、Job は Pod が故障したときに新しい Pod を作成し、故障した Pod は消えず、再起動せず、失敗回数は + 1 されます。
  • Always に設定すると、常に再起動されることを意味し、Pod タスクが繰り返し実行されることを意味します。これは Job の定義と矛盾するため、Always に設定することはできません。

CronJob(CJ)#

CronJob コントローラーは Job コントローラーリソースを管理対象としており、Job コントローラーが定義した作業タスクは、そのコントローラーリソースが作成された後に即座に実行されますが、CronJob は Linux オペレーティングシステムの周期的なタスク作業計画のように、実行時間点および繰り返し実行の方法を制御できます。つまり、CronJob は特定の時間点で(繰り返し)job タスクを実行できます

CronJob のリソースマニフェストファイル:

apiVersion: batch/v1beta1 # バージョン番号
kind: CronJob # タイプ       
metadata: # メタデータ
  name: # rsの名前 
  namespace: # 所属名前空間 
  labels: # ラベル
    controller: cronjob
spec: # 詳細説明
  schedule: # cron形式の作業スケジュール実行時間点。タスクがいつ実行されるかを制御します。
  concurrencyPolicy: # 同時実行ポリシー。前回の作業が完了していない場合、次の作業をどのように実行するかを定義します。
  failedJobHistoryLimit: # 失敗したタスク実行の履歴を保持する数。デフォルトは1
  successfulJobHistoryLimit: # 成功したタスク実行の履歴を保持する数。デフォルトは3
  startingDeadlineSeconds: # 作業開始エラーのタイムアウト期間
  jobTemplate: # jobコントローラーのテンプレート。cronjobコントローラーがjobオブジェクトを生成するために使用されます。以下は実際にはjobの定義です。
    metadata:
    spec:
      completions: 1
      parallelism: 1
      activeDeadlineSeconds: 30
      backoffLimit: 6
      manualSelector: true
      selector:
        matchLabels:
          app: counter-pod
        matchExpressions: ルール
          - {key: app, operator: In, values: [counter-pod]}
      template:
        metadata:
          labels:
            app: counter-pod
        spec:
          restartPolicy: Never 
          containers:
          - name: counter
            image: busybox:1.30
            command: ["bin/sh","-c","for i in 9 8 7 6 5 4 3 2 1; do echo $i;sleep 20;done"]
重要なオプションをいくつか説明します:
schedule: cron式。タスクの実行時間を指定します。
    */1    *      *    *     *
    <分> <時間> <日> <月> <曜日>

    分:0から59までの値。
    時間:0から23までの値。
    日:1から31までの値。
    月:1から12までの値。
    曜日:0から6までの値。0は日曜日を表します。
    複数の時間はカンマで区切ることができます。範囲はハイフンで指定できます。*はワイルドカードとして使用できます。/は毎...を示します。
concurrencyPolicy:
    Allow:   Jobsの同時実行を許可(デフォルト)
    Forbid:  同時実行を禁止。前回の実行が完了していない場合、次の実行をスキップします。
    Replace: 現在実行中の作業をキャンセルし、新しい作業に置き換えます。

StatefulSet(有状態)#

無状態アプリケーション:

  • Pod はすべて同じと見なされます。
  • 順序要件はありません。
  • どの Node ノードで実行されるかを考慮する必要はありません。
  • 拡張やスケールの制限はありません。

有状態アプリケーション:

  • 順序要件があります。
  • 各 Pod は異なると見なされます。
  • どの Node ノードで実行されるかを考慮する必要があります。
  • 拡張やスケールは順序に従って行う必要があります。
  • 各 Pod は独立しており、Pod の起動順序と一意性を保持します。

StatefulSet は Kubernetes が提供する有状態アプリケーションの負荷管理コントローラーです。
StatefulSet のデプロイには HeadlessService(無頭サービス)が必要です。

なぜ HeadlessService(無頭サービス)が必要なのか?

  • Deployment を使用する場合、各 Pod の名前は順序がなく、ランダムな文字列であるため、Pod の名前は無秩序ですが、StatefulSet では順序が必要であり、各 Pod は自由に置き換えることができず、Pod が再構築されても Pod の名前は同じでなければなりません。
  • Pod の IP は変化するため、Pod の名前で識別されます。Pod の名前は Pod の一意の識別子であり、持続的で安定している必要があります。この場合、無頭サービスを使用して、各 Pod に一意の名前を付けることができます。

StatefulSet は RabbitMQ クラスター、Zookeeper クラスター、MySQL クラスター、Eureka クラスターなどのデプロイに一般的に使用されます。

演示例:

apiVersion: v1
kind: Service
metadata:
  name: service-headliness
  namespace: dev
spec:
  selector:
    app: nginx-pod
  clusterIP: None # clusterIPをNoneに設定すると、headliness Serviceが作成されます。
  type: ClusterIP
  ports:
    - port: 80 # Serviceのポート
      targetPort: 80 # Podのポート
...

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: pc-statefulset
  namespace: dev
spec:
  replicas: 3
  serviceName: service-headliness
  selector:
    matchLabels:
      app: nginx-pod
  template:
    metadata:
      labels:
        app: nginx-pod
    spec:
      containers:
        - name: nginx
          image: nginx:1.17.1
          ports:
            - containerPort: 80

サービス#

Kubernetes では、Pod はアプリケーションのコンテナであり、Pod の IP を使用してアプリケーションにアクセスできますが、Pod の IP アドレスは固定されていないため、サービスへのアクセスに直接 Pod の IP を使用するのは便利ではありません。
この問題を解決するために、Kubernetes は Service リソースを提供します。Service は同じサービスを提供する複数の Pod を集約し、統一されたエントリーアドレスを提供します。Service のエントリーアドレスにアクセスすることで、背後の Pod サービスにアクセスできます。

Service は多くの場合、概念に過ぎず、実際に機能するのは kube-proxy サービスプロセスです。各 Node ノード上で kube-proxy サービスプロセスが実行されています。Service を作成すると、API Server を介して etcd に作成された Service の情報が書き込まれ、kube-proxy はリスニングメカニズムに基づいてこの Service の変化を検出し、最新の Service 情報を対応するアクセスルールに変換します。

9

kube-proxy は現在 3 つの動作モードをサポートしています:

  • userspace モード:

    • userspace モードでは、kube-proxy は各 Service にリスニングポートを作成し、Cluster IP へのリクエストは iptables ルールによって kube-proxy のリスニングポートにリダイレクトされ、kube-proxy は LB アルゴリズム(負荷均衡アルゴリズム)に基づいてサービスを提供する Pod を選択し、接続を確立してリクエストを Pod に転送します。

    • このモードでは、kube-proxy は 4 層の負荷均衡器の役割を果たします。kube-proxy が userspace で実行されているため、転送処理中にカーネルとユーザースペース間のデータコピーが増加し、安定性は高いですが、効率は非常に低下します。

10

  • iptables モード:

    • iptables モードでは、kube-proxy は Service のバックエンドの各 Pod に対応する iptables ルールを作成し、Cluster IP へのリクエストを直接 Pod の IP にリダイレクトします。

    • このモードでは、kube-proxy は 4 層の負荷均衡器の役割を果たさず、iptables ルールを作成するだけです。このモードの利点は、userspace モードよりも効率が高いですが、柔軟な LB 戦略を提供できず、バックエンド Pod が利用できない場合は再試行できません。

11

ipvs モード:

  • ipvs モードは iptables に似ており、kube-proxy は Pod の変化を監視し、対応する ipvs ルールを作成します。ipvs は iptables よりも転送効率が高く、さらに多くの LB(負荷均衡)アルゴリズムをサポートしています。

12

サービスの種類#

Service のリソースマニフェスト:

apiVersion: v1 # バージョン
kind: Service # タイプ
metadata: # メタデータ
  name: # リソース名
  namespace: # 名前空間
spec:
  selector: # ラベルセレクタ。現在のServiceがどのPodを代理するかを決定します。
    app: nginx
  type: NodePort # Serviceのタイプ。Serviceのアクセス方法を指定します。
  clusterIP: # 仮想サービスのIPアドレス
  sessionAffinity: # セッション親和性。ClientIP、Noneの2つのオプションをサポートし、デフォルト値はNoneです。
  ports: # ポート情報
    - port: 8080 # Serviceポート
      protocol: TCP # プロトコル
      targetPort : # Podポート
      nodePort:  # ホストポート

spec.type の説明:

  • ClusterIP:デフォルト値。Kubernetes システムが自動的に割り当てる仮想 IP で、クラスター内部からのみアクセス可能です。
  • NodePort:Service を指定された Node のポートを介して外部に公開します。この方法で、クラスター外部からサービスにアクセスできます。
  • LoadBalancer:外部負荷均衡器を使用してサービスへの負荷分散を実現します。このモードは外部クラウド環境のサポートが必要です。
  • ExternalName:クラスター外部のサービスをクラスター内部に引き入れ、直接この Service を使用してアクセスします。

ClusterIP タイプの Service#

エンドポイント(実際にはあまり使用されません)

  • Endpoint は Kubernetes のリソースオブジェクトで、etcd に保存され、service に対応するすべての Pod のアクセスアドレスを記録します。これは service 設定ファイル内の selector 記述に基づいて生成されます。
  • 1 つの service は一連の Pod で構成され、これらの Pod は Endpoints を介して公開されます。言い換えれば、service と Pod の間の関連は Endpoints を介して実現されます。

13

負荷分散戦略

Service へのアクセスはバックエンドの Pod に分散されます。現在、Kubernetes は 2 つの負荷分散戦略を提供しています:

  • 定義しない場合、デフォルトで kube-proxy の戦略(ランダム、ラウンドロビンなど)を使用します。
  • クライアントアドレスに基づくセッション保持モード。つまり、同じクライアントからのすべてのリクエストは固定の Pod に転送されます。これは、従来のセッションベースの認証プロジェクトにとって非常に便利です。このモードは spec に sessionAffinity: ClusterIP オプションを追加することで実現できます。

HeadLiness タイプの Service#

特定のシーンでは、開発者は Service が提供する負荷均衡機能を使用したくない場合があり、独自の負荷均衡戦略を制御したいと考えています。このような場合、Kubernetes は HeadLiness Service を提供します。このタイプの Service は Cluster IP を割り当てず、Service にアクセスするには Service のドメイン名を介してクエリする必要があります。

NodePort タイプの Service#

以前のケースで作成した Service の IP アドレスはクラスター内部からのみアクセス可能です。Service をクラスター外部に公開したい場合は、NodePort タイプの Service を使用する必要があります。NodePort の動作原理は、Service のポートを Node のポートにマッピングし、NodeIPを介して Service にアクセスできるようにすることです。

14

LoadBalancer タイプの Service#

15

ExternalName タイプの Service#

ExternalName タイプの Service は、クラスター外部のサービスを引き入れるために使用され、externalName 属性を介してサービスのアドレスを指定し、クラスター内部からこの Service にアクセスすることで外部のサービスにアクセスできます。

16

Ingress#

Service がクラスター外部にサービスを公開する主な方法は NodePort と LoadBalancer の 2 つですが、これらの方法にはいくつかの欠点があります:

  • NodePort 方式の欠点は、クラスター内の多くのマシンのポートを占有することです。クラスターサービスが増えると、この欠点はますます顕著になります。
  • LoadBalancer の欠点は、各 Service に LB が必要で、無駄で面倒であり、Kubernetes 外のデバイスのサポートが必要です。

このような状況に基づいて、Kubernetes は Ingress リソースオブジェクトを提供しました。Ingress は、NodePort または LB の 1 つだけで複数の Service を公開するニーズを満たすことができます。動作メカニズムは以下の図のようになります:

17

実際、Ingress は 7 層の負荷均衡器に相当し、Kubernetes によるリバースプロキシの抽象化です。その動作原理は Nginx に似ており、Ingress 内に多くのマッピングルールが構築され、Ingress Controller はこれらの設定ルールの変化を監視し、Nginx のリバースプロキシ設定に変換して外部にサービスを提供します。

  • Ingress:Kubernetes 内のオブジェクトで、リクエストが Service にどのように転送されるかのルールを定義します。
  • Ingress Controller:リバースプロキシおよび負荷均衡を具体的に実装するプログラムで、Ingress が定義したルールを解析し、設定されたルールに基づいてリクエストを転送します。実装方法は多く、Nginx、Contour、Haproxy などがあります。

Ingress(Nginx を使用)の動作原理は以下の通りです:

  • ユーザーは Ingress ルールを作成し、どのドメイン名が Kubernetes クラスター内のどの Service に対応するかを説明します。
  • Ingress コントローラーは Ingress サービスルールの変化を動的に感知し、対応する Nginx のリバースプロキシ設定を生成します。
  • Ingress コントローラーは生成された Nginx 設定を実行中の Nginx サービスに書き込み、動的に更新します。
  • これで、実際に機能しているのは Nginx であり、ユーザーが定義したリクエストルールが内部に設定されています。

18

Ingress は Http プロキシと Https プロキシをサポートしています。

データストレージ#

前述のように、コンテナのライフサイクルは非常に短く、頻繁に作成および削除される可能性があります。このため、コンテナが削除されると、コンテナ内に保存されているデータも消去されます。この結果は、ユーザーにとっては望ましくない場合があります。コンテナのデータを永続的に保存するために、Kubernetes は Volume の概念を導入しました。

Volume は Pod 内で複数のコンテナがアクセスできる共有ディレクトリであり、Pod に定義され、Pod 内の複数のコンテナが具体的なファイルディレクトリにマウントされます。Kubernetes は Volume を介して同じ Pod 内の異なるコンテナ間でデータを共有し、データを永続的に保存します。Volume のライフは Pod 内の単一のコンテナのライフサイクルとは関連しておらず、コンテナが終了または再起動しても Volume 内のデータは失われません。

Kubernetes の Volume は多くのタイプをサポートしており、一般的なものは以下の通りです:

  • シンプルストレージ:EmptyDir、HostPath、NFS
  • 高度なストレージ:PV、PVC
  • 設定ストレージ:ConfigMap、Secret

基本ストレージ#

EmptyDir#

EmptyDir は最も基本的な Volume タイプで、EmptyDir はホスト上の空のディレクトリです。

EmptyDir は Pod が Node に割り当てられたときに作成され、その初期内容は空であり、ホスト上の対応するディレクトリファイルを指定する必要はありません。Kubernetes が自動的にディレクトリを割り当てます。Pod が削除されると、EmptyDir 内のデータも永久に削除されます。EmptyDir の用途は以下の通りです:

  • 一時的なスペース。たとえば、特定のアプリケーションが実行中に必要な一時ディレクトリで、永続的に保持する必要はありません。
  • 1 つのコンテナが別のコンテナからデータを取得するためのディレクトリ(複数のコンテナで共有されるディレクトリ)。

次に、コンテナ間でファイルを共有するケースを使用して EmptyDir を使用します。

Pod 内に nginx と busybox の 2 つのコンテナを準備し、

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。