アプリケーションをデプロイする

このドキュメントでは、GKE on Bare Metal にアプリケーションをデプロイする方法について説明します。

始める前に

ワークロードをデプロイするには、ワークロードを実行できるユーザー、ハイブリッド、またはスタンドアロンのクラスタが必要です。

Deployment を作成する

次の手順では、クラスタに Deployment を作成します。

  1. 以下のマニフェストを my-deployment.yaml という名前のファイルにコピーします。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: my-deployment
    spec:
      selector:
        matchLabels:
          app: metrics
          department: sales
      replicas: 3
      template:
        metadata:
          labels:
            app: metrics
            department: sales
        spec:
          containers:
          - name: hello
            image: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0"
    
  2. kubectl apply を使用して、Deployment を作成します。

    kubectl apply -f my-deployment.yaml --kubeconfig CLUSTER_KUBECONFIG
    

    CLUSTER_KUBECONFIG は、クラスタの kubeconfig ファイルのパスに置き換えます。

  3. Deployment に関する基本情報を取得して Deployment が正常に作成されたことを確認します。

    kubectl get deployment my-deployment --kubeconfig CLUSTER_KUBECONFIG
    

    出力には、Deployment に利用可能な次の 3 つの Pod があることが示されます。

    NAME            READY   UP-TO-DATE   AVAILABLE   AGE
    my-deployment   3/3     3            3           27s
    
  4. Deployment 内の Pod を一覧表示します。

    kubectl get pods --kubeconfig CLUSTER_KUBECONFIG
    

    出力に Deployment に実行中の Pod が 3 つあることが表示されます。

    NAME                             READY   STATUS    RESTARTS   AGE
    my-deployment-869f65669b-5259x   1/1     Running   0          34s
    my-deployment-869f65669b-9xfrs   1/1     Running   0          34s
    my-deployment-869f65669b-wn4ft   1/1     Running   0          34s
    
  5. Deployment に関する詳細情報を取得します。

    kubectl get deployment my-deployment --output yaml --kubeconfig CLUSTER_KUBECONFIG
    

    出力には、Deployment の仕様とステータスの詳細が表示されます。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      ...
      generation: 1
      name: my-deployment
      namespace: default
      ...
    spec:
      ...
      replicas: 3
      revisionHistoryLimit: 10
      selector:
        matchLabels:
          app: metrics
          department: sales
      ...
        spec:
          containers:
          - image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0
            imagePullPolicy: IfNotPresent
            name: hello
            resources: {}
            terminationMessagePath: /dev/termination-log
            terminationMessagePolicy: File
          dnsPolicy: ClusterFirst
          restartPolicy: Always
          schedulerName: default-scheduler
          securityContext: {}
          terminationGracePeriodSeconds: 30
    status:
      availableReplicas: 3
      conditions:
      - lastTransitionTime: "2023-06-29T16:17:17Z"
        lastUpdateTime: "2023-06-29T16:17:17Z"
        message: Deployment has minimum availability.
        reason: MinimumReplicasAvailable
        status: "True"
        type: Available
      - lastTransitionTime: "2023-06-29T16:17:12Z"
        lastUpdateTime: "2023-06-29T16:17:17Z"
        message: ReplicaSet "my-deployment-869f65669b" has successfully progressed.
        reason: NewReplicaSetAvailable
        status: "True"
        type: Progressing
      observedGeneration: 1
      readyReplicas: 3
      replicas: 3
      updatedReplicas: 3
    
  6. Deployment を記述します。

    kubectl describe deployment my-deployment --kubeconfig CLUSTER_KUBECONFIG
    

    関連付けられた ReplicaSet を含む、適切にフォーマットされた Deployment の詳細が出力に表示されます。

    Name:                   my-deployment
    Namespace:              default
    CreationTimestamp:      Thu, 29 Jun 2023 16:17:12 +0000
    Labels:                 <none>
    Annotations:            deployment.kubernetes.io/revision: 1
    Selector:               app=metrics,department=sales
    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=metrics
              department=sales
      Containers:
      hello:
        Image:        us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0
        Port:         <none>
        Host Port:    <none>
        Environment:  <none>
        Mounts:       <none>
      Volumes:        <none>
    Conditions:
      Type           Status  Reason
      ----           ------  ------
      Available      True    MinimumReplicasAvailable
      Progressing    True    NewReplicaSetAvailable
    OldReplicaSets:  <none>
    NewReplicaSet:   my-deployment-869f65669b (3/3 replicas created)
    Events:
      Type    Reason             Age    From                   Message
      ----    ------             ----   ----                   -------
      Normal  ScalingReplicaSet  6m50s  deployment-controller  Scaled up replica set my-deployment-869f65669b to 3
    

LoadBalancer タイプの Service を作成する

Deployment をクラスタ外のクライアントに公開する方法の 1 つは、LoadBalancer タイプの Kubernetes Service を作成することです。

LoadBalancer タイプの Service を作成するには:

  1. 以下のマニフェストを my-service.yaml という名前のファイルにコピーします。

    apiVersion: v1
    kind: Service
    metadata:
      name: my-service
    spec:
      selector:
        app: metrics
        department: sales
      type: LoadBalancer
      ports:
      - port: 80
        targetPort: 8080
    

    ここでは、Service について次のことを理解しておくことが重要です。

    • app: metricsdepartment: sales のラベルが付いた Pod は、Service のメンバーです。 my-deployment の Pod には、これらのラベルが付けられています。

    • クライアントによってこの Service の TCP ポート 80 にリクエストが送信されると、このリクエストは TCP ポート 8080 でメンバー Pod に転送されます。

    • メンバー Pod ごとに、TCP ポート 8080 をリッスンするコンテナが必要です。

    デフォルトでは、hello-app コンテナは TCP ポート 8080 をリッスンします。このポート設定は、アプリの Dockerfile とソースコードで確認できます。

  2. kubectl apply を使用して、クラスタに Service を作成します。

    kubectl apply -f my-service.yaml --kubeconfig CLUSTER_KUBECONFIG
    

    CLUSTER_KUBECONFIG は、クラスタの kubeconfig ファイルのパスに置き換えます。

  3. Service を表示します。

    kubectl get service my-service --output yaml --kubeconfig CLUSTER_KUBECONFIG
    

    出力は次のようになります。

    apiVersion: v1
    kind: Service
    metadata:
      ...
      name: my-service
      namespace: default
      ...
    spec:
      allocateLoadBalancerNodePorts: true
      clusterIP: 10.96.2.165
      clusterIPs:
      - 10.96.2.165
      externalTrafficPolicy: Cluster
      internalTrafficPolicy: Cluster
      ipFamilies:
      - IPv4
      ipFamilyPolicy: SingleStack
      ports:
      - nodePort: 31565
        port: 80
        protocol: TCP
        targetPort: 8080
      selector:
        app: metrics
        department: sales
      sessionAffinity: None
      type: LoadBalancer
    status:
      loadBalancer:
        ingress:
        - ip: 192.168.1.13
    

    上記の出力から、Service に clusterIP と外部 IP アドレスがあることがわかります。また、nodePortporttargetPort もあります。

    clusterIP は、この演習とは関係ありません。外部 IP アドレス(status.loadBalancer.ingress.ip)は、クラスタ構成ファイルでロードバランサのアドレスプール(spec.loadBalancer.addressPools)を定義したときに指定したアドレスの範囲から取得されます。

    例として、上記の Service の出力での値は次の通りです。

    • 外部 IP アドレス: 192.168.1.13
    • port: 80
    • nodePort: 31565
    • targetPort: 8080

    クライアントは TCP ポート 80192.168.1.13 にリクエストを送信します。リクエストはロードバランサにルーティングされ、そこから TCP ポート 8080 のメンバー Pod に転送されます。

  4. Service を呼び出します。

    curl INGRESS_IP_ADDRESS
    

    INGRESS_IP_ADDRESS を、前のステップで取得した Service の status セクションにある Ingress IP アドレスに置き換えます(status.loadBalancer.ingress)。

    出力には、Hello, world! メッセージが表示されます。

    Hello, world!
    Version: 2.0.0
    Hostname: my-deployment-869f65669b-wn4ft
    

LoadBalancer のポートの制限

LoadBalancer タイプは NodePort の拡張タイプです。したがって、LoadBalancer タイプの Service は、クラスタ IP アドレスと 1 つ以上の nodePort 値を使用します。 デフォルトでは、Kubernetes はタイプ LoadBalancer の Service にノードポートを割り当てます。これらの割り当てでは、クラスタに割り当てられた 2,768 個の使用可能なノードポートを短期間で使い切る可能性があります。ノードポートを節約するには、LoadBalancer Service 仕様で allocateLoadBalancerNodePorts フィールドを false に設定して、ロードバランサ ノードポートの割り当てを無効にします。この設定により、Kubernetes はノードポートを LoadBalancer Service に割り当てなくなります。詳細については、Kubernetes ドキュメントのロードバランサの NodePort 割り当ての無効化をご覧ください。

ノードポートを使用しない Service を作成するマニフェストは次のとおりです。

apiVersion: v1
kind: Service
metadata:
  name: service-does-not-use-nodeports
spec:
  selector:
    app: my-app
  type: LoadBalancer
  ports:
  - port: 8000
  # Set allocateLoadBalancerNodePorts to false
  allocateLoadBalancerNodePorts: false

Service を削除する

Service を削除するには:

  1. kubectl delete を使用して、クラスタから Service を削除します。

    kubectl delete service my-service --kubeconfig CLUSTER_KUBECONFIG
    
  2. Service が削除されたことを確認します。

    kubectl get services --kubeconfig CLUSTER_KUBECONFIG
    

    出力に my-service が表示されなくなります。

Deployment を削除する

Deployment を削除するには:

  1. kubectl delete を使用して、クラスタから Deployment を削除します。

    kubectl delete deployment my-deployment --kubeconfig CLUSTER_KUBECONFIG
    

    Deployment が削除されたことを確認します。

    kubectl get deployments --kubeconfig CLUSTER_KUBECONFIG
    

    出力に my-deployment が表示されなくなります。

次のステップ

Service と Ingress を作成する