Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

サーバをデプロイする

このページでは PFCP クラスタ上で Web サーバや推論サーバなどの常時稼働するサーバ型ワークロードを Deployment としてデプロイする方法を説明します。

Note

バッチジョブとの使い分け

リクエストを継続的に受け付けて処理する長時間稼働のワークロードには Deployment が適しています。 一方、一定の処理が終わったら終了するバッチ処理には Job や ParallelJob が適しています。 分散バッチジョブを作成する場合は 分散バッチジョブを作成する を参照してください。

概要

Kubernetes でサーバをホスティングする際、主に以下の 2 つのリソースを使用します。

  • Deployment — コンテナの実行数(レプリカ数)・更新戦略・ヘルスチェックなど Pod の仕様を管理します。
  • Service — Deployment が起動する Pod に対して安定した名前と IP アドレスを提供し、クラスタ内外からのアクセスを取り次ぎます。

Deployment を作成する

以下は example-server という名前の Deployment を作成する例です。 <イメージ名>:<タグ> を実際のコンテナイメージに置き換えてください。 latest タグは同名の異なるイメージを指す可能性があるため、1.2.3 のような不変のタグを使用することを推奨します。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: example-server
spec:
  # レプリカ数を 2 以上にすることで可用性が高まります。
  # ノード障害やメンテナンス時の同時停止を避けるため、後述の PodDisruptionBudget を合わせて設定します。
  replicas: 2
  selector:
    matchLabels:
      app: example-server
  template:
    metadata:
      labels:
        app: example-server
    spec:
      # 複数ノードに Pod を分散させることで、ノード障害時の影響を最小化します。
      # ノードが 1 台しかない検証・開発環境では、2 台目以降の Pod が Pending のままになります。
      # その場合は whenUnsatisfiable を ScheduleAnyway に変更するか、ノードを追加してください。
      topologySpreadConstraints:
      - maxSkew: 1
        topologyKey: kubernetes.io/hostname
        whenUnsatisfiable: DoNotSchedule
        labelSelector:
          matchLabels:
            app: example-server
      # グレースフルシャットダウンの猶予期間(秒)です。
      # SIGTERM を受け取ってからこの秒数以内に、処理中のリクエストを完了させて終了します。
      terminationGracePeriodSeconds: 60
      containers:
      - name: main
        image: <イメージ名>:<タグ>
        ports:
        - containerPort: 8080
        # requests はスケジューリング(どのノードで起動するか)の判断に使われ、limits は他の Pod への影響を防ぐ上限として機能します。
        # 計算ノードの種類と利用可能なリソースは「計算ノードの種類と比較」を参照してください。
        resources:
          requests:
            cpu: "500m"
            memory: "512Mi"
          limits:
            # CPU の limits を超えると処理が一時的に制限(待機)されますが Pod は停止しないため、設定は任意です。
            # memory limits を超えると Pod が強制終了されるため、異常時の影響範囲を限定する目的で設定を推奨します。
            memory: "2Gi"
        # livenessProbe: コンテナを再起動すべき状態かを確認します。
        # デッドロックなど回復不能な状態を検出して自動再起動します。
        # readinessProbe とエンドポイントを分け、failureThreshold も大きめにすることで、高負荷時の一時的な応答遅延が再起動ループにつながることを防ぎます。
        livenessProbe:
          httpGet:
            path: /healthz/live
            port: 8080
          initialDelaySeconds: 15
          periodSeconds: 20
          failureThreshold: 5
        # readinessProbe: トラフィックを受け付けられる状態かを確認します。
        # 起動中やウォームアップ中は READY にならず、Service 経由のトラフィックが流れません。
        readinessProbe:
          httpGet:
            path: /healthz/ready
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 10
        # グレースフルシャットダウン: SIGTERM を受け取る前に Service からの切り離し完了を待ちます。
        lifecycle:
          preStop:
            sleep:
              seconds: 5
        # securityContext: 非 root 実行や readOnlyRootFilesystem の設定を推奨します。
        # 詳しくは「Pod にセキュリティポリシを適用する」を参照してください。
        # securityContext:
        #   runAsNonRoot: true
        #   readOnlyRootFilesystem: true
        # 機密情報は Secret または SealedSecret で管理してください。
        # 詳しくは「機密データ(Secret)を扱う」を参照してください。
        # env:
        # - name: API_KEY
        #   valueFrom:
        #     secretKeyRef:
        #       name: my-secret
        #       key: api-key

Deployment を適用してステータスを確認します。

$ kubectl apply -f deployment.yaml
deployment.apps/example-server created

$ kubectl get deployment example-server
NAME             READY   UP-TO-DATE   AVAILABLE   AGE
example-server   2/2     2            2           30s

$ kubectl get pod -l app=example-server
NAME                              READY   STATUS    RESTARTS   AGE
example-server-7d4f9b6c8-abcde   1/1     Running   0          30s
example-server-7d4f9b6c8-fghij   1/1     Running   0          30s

Note

コンテナイメージの管理について

ユーザ管理のコンテナイメージや PFCP 提供イメージの使用方法については、ユーザ管理のコンテナイメージを使用する および PFCP 提供のコンテナイメージを使用する を参照してください。

Service を作成する

Service は、Pod が入れ替わっても変わらない安定したネットワークエンドポイント(IP アドレス・DNS 名)を提供する Kubernetes リソースです。selector に指定したラベルを持つ Pod へのトラフィックを自動的に振り分けます。 詳しくは Kubernetes 公式ドキュメント(Service) を参照してください。

apiVersion: v1
kind: Service
metadata:
  name: example-server-svc
spec:
  selector:
    app: example-server
  ports:
  - port: 80
    targetPort: 8080
$ kubectl apply -f service.yaml
service/example-server-svc created

$ kubectl get service example-server-svc
NAME                  TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
example-server-svc   ClusterIP   10.96.100.200   <none>        80/TCP    10s

同一 Namespace の他の Pod から http://example-server-svc/ でアクセスできます。

ローリングアップデートとスケール

Deployment の変更はマニフェストを編集して kubectl apply で適用します。 デフォルトでは既存の Pod を 1 台ずつ入れ替えながら更新し、サービスを継続します(ローリングアップデート)。

イメージを更新する

deployment.yamlspec.template.spec.containers[].image フィールドを新しいタグに変更します。

       containers:
       - name: main
-        image: <イメージ名>:<旧タグ>
+        image: <イメージ名>:<新タグ>

Tip

kubectl explain コマンドでフィールドの詳細や構造を確認できます。

$ kubectl explain deployment.spec.template.spec.containers.image

変更を適用します。

$ kubectl apply -f deployment.yaml
deployment.apps/example-server configured

レプリカ数を変更する

deployment.yamlspec.replicas フィールドを変更して kubectl apply で適用します。

   replicas: 4  # 2 から 4 に変更
$ kubectl apply -f deployment.yaml
deployment.apps/example-server configured

PodDisruptionBudget を設定する

ノードのメンテナンスなどで Pod が停止させられる際に、同時に停止できる Pod の数を制限します。 replicas: 2 の場合、minAvailable: 1 を設定することで常に 1 台以上の Pod が稼働し続けます。

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: example-server-pdb
spec:
  minAvailable: 1
  selector:
    matchLabels:
      app: example-server

ベストプラクティスのまとめ

観点推奨参照
可用性replicas: 2 以上 + topologySpreadConstraints でノード分散 + PodDisruptionBudget
ヘルスチェックreadinessProbe(受信可否)と livenessProbe(再起動要否)を個別に設定
グレースフルシャットダウンpreStop フック + terminationGracePeriodSeconds でリクエスト処理完了を待つ
リソース指定requests を必ず設定。memory limits は異常時の影響範囲を限定するために設定を推奨計算ノードの種類と比較
イメージ管理latest タグを避けて不変タグを使用。ユーザ管理のコンテナイメージを使用する
セキュリティsecurityContext で非 root 実行・readOnlyRootFilesystem を設定Pod にセキュリティポリシを適用する
設定・機密管理設定は ConfigMap、機密情報は SealedSecret で管理機密データ(Secret)を扱う

関連機能

オートスケーリング

Pod のオートスケーリングには 2 種類の方法があります。

メトリクス監視

ServiceMonitor カスタムリソースを使用すると、Pod が公開するメトリクスを Prometheus でスクレイプし、Grafana でダッシュボードやアラートを設定できます。詳しくは メトリクスモニタリングとアラーティング を参照してください。

GitOps による継続的デリバリ

Deployment・Service・PodDisruptionBudget などのマニフェストを Git リポジトリで管理し、変更を自動でクラスタに適用する GitOps の設定方法は GitOps スタイルの継続的デリバリを構成する を参照してください。

パブリッククラウドとの連携

AWS や Google Cloud のリソースへアクセスするサーバを実行する場合、クレデンシャルをコンテナへ埋め込まずに ID 連携を使用してアクセスできます。 詳しくは パブリッククラウドと ID 連携を構成する を参照してください。

リレーショナルデータベース

サーバのバックエンドとしてリレーショナルデータベースが必要な場合、PFCP が提供する MOCO を使用して MySQL クラスタを同一クラスタ内にデプロイできます。 詳しくは リレーショナルデータベースを実行する を参照してください。

次のステップ

作成した Service をインターネットに公開するには以下を参照してください。