コンテナ化されたウェブサーバー アプリをデプロイする


このチュートリアルでは、エアギャップされた Google Distributed Cloud(GDC)エアギャップ環境でコンテナ アプリケーションをアップロードし、そのアプリケーションを Kubernetes クラスタで実行する方法について説明します。コンテナ化されたワークロードは、プロジェクト Namespace 内の Kubernetes クラスタで実行されます。クラスタは、異なる障害ドメインと分離保証を提供するために、プロジェクトと論理的に分離されています。ただし、コンテナ化されたワークロードをプロジェクト内で管理できるようにするには、クラスタがプロジェクトに関連付けられていることを確認する必要があります。

コンテナアプリのデプロイにおける最大の障害の 1 つは、アプリのバイナリをエアギャップ データセンターに取得することです。インフラストラクチャ チームと管理者に協力して、アプリケーションをワークステーションに転送するか、継続的インテグレーションと継続的デリバリー(CI/CD)サーバーでこのチュートリアルを直接実装します。

このチュートリアルでは、 Google CloudArtifact Registry から入手できるサンプル ウェブサーバー アプリを使用します。

目標

  • マネージド Harbor レジストリを作成します。
  • コンテナ イメージをマネージド Harbor レジストリに push します。
  • Kubernetes クラスタを作成する。
  • サンプル コンテナアプリをクラスタにデプロイします。

料金

GDC はエアギャップ データセンターで実行するように設計されているため、課金プロセスと情報は GDC デプロイに限定され、他の Google プロダクトによって管理されません。

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。

予測費用ダッシュボードを使用して、請求書の将来の SKU 費用を予測します。

ストレージとコンピューティングの使用量を追跡するには、請求額の使用量ダッシュボードを使用します。

始める前に

  1. コンテナ化されたデプロイを管理するプロジェクトがあることを確認します。プロジェクトがない場合は、プロジェクトを作成します。

  2. プロジェクトの Namespace を環境変数として設定します。

    export NAMESPACE=PROJECT_NAMESPACE
    
  3. gdcloud CLI をダウンロードしてインストールします

  4. 組織の IAM 管理者に次のロールの付与を依頼します。

    • プロジェクトの Namespace の Namespace 管理者ロール(namepspace-admin)。このロールは、プロジェクトにコンテナ ワークロードをデプロイするために必要です。

    • プロジェクト Namespace の Harbor インスタンス管理者ロール(harbor-instance-admin)。このロールは、すべての Harbor リソースに対する読み取り / 書き込みアクセス権に必要です。Harbor インスタンスを削除する場合にも必要です。

    • プロジェクト Namespace の Harbor インスタンス閲覧者ロール(harbor-instance-viewer)。このロールは、Harbor インスタンスを表示して選択するために必要です。

    • プロジェクト Namespace の Harbor プロジェクト作成者ロール(harbor-project-creator)。このロールは、Harbor プロジェクトにアクセスして管理するために必要です。

    • ユーザー クラスタ管理者ロール(user-cluster-admin)。このロールは Kubernetes クラスタの作成に必要であり、Namespace にバインドされていません。

  5. ゾーン管理 API サーバーにログインし、ユーザー ID を使用して kubeconfig ファイルを生成します。kubeconfig パスを環境変数として設定します。

    export MANAGEMENT_API_SERVER=MANAGEMENT_API_SERVER_KUBECONFIG_PATH
    

マネージド Harbor レジストリを作成する

GDC air-gapped は、Harbor as a Service を提供します。これは、Harbor を使用してコンテナ イメージを保存および管理できるフルマネージド サービスです。

Harbor as a Service を使用するには、まず Harbor レジストリ インスタンスと Harbor プロジェクトを作成する必要があります。

Harbor レジストリ インスタンスを作成する

Harbor コンテナ レジストリ インスタンスを作成する手順は次のとおりです。

コンソール

  1. ナビゲーション メニューで、[CI/CD] セクションから [Harbor Container Registry] を選択します。

  2. Harbor インスタンスを作成するゾーンを選択します。Harbor インスタンスはゾーン リソースであり、高可用性を確保するために各ゾーンに手動で作成する必要があります。

  3. [インスタンスを作成] をクリックします。

  4. インスタンスの名前を入力し、Harbor マネージドの利用規約に同意します。

  5. [インスタンスを作成] をクリックします。

  6. 新しい Harbor インスタンスが [Harbor インスタンス] セクションに存在することを確認します。

  7. [Go to Harbor Instance] 外部リンクをクリックし、インスタンスの URL をメモします。たとえば、インスタンス URL の形式は harbor-1.org-1.zone1.google.gdc.test のようになります。インスタンス URL に https:// プレフィックスを含めることはできません。

  8. チュートリアルの後半で使用する変数としてインスタンス URL を設定します。

    export INSTANCE_URL=INSTANCE_URL
    

    INSTANCE_URL は、Harbor レジストリ インスタンスの URL に置き換えます。

    次に例を示します。

    export INSTANCE_URL=harbor-1.org-1.zone1.google.gdc.test
    

gdcloud

  1. 新しい Harbor コンテナ レジストリ インスタンスを作成します。

    gdcloud harbor instances create INSTANCE_NAME \
        --project=PROJECT \
    

    次のように置き換えます。

    • INSTANCE_NAME: Harbor インスタンスの名前。
    • PROJECT: GDC プロジェクトの名前。
  2. インスタンスの URL を一覧表示します。

    gdcloud harbor instances describe INSTANCE_NAME \
        --project=PROJECT
    

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

    # Several lines of code are omitted here.
    status:
      url: https://harbor-1.org-1.zone1.google.gdc.test
    
  3. チュートリアルの後半で使用する変数としてインスタンス URL を設定します。

    export INSTANCE_URL=INSTANCE_URL
    

    INSTANCE_URL は、Harbor レジストリ インスタンスの URL に置き換えます。インスタンス URL に https:// 接頭辞が含まれていないことを確認します。

    次に例を示します。

    export INSTANCE_URL=harbor-1.org-1.zone1.google.gdc.test
    

レジストリに Harbor プロジェクトを作成する

コンテナ イメージを管理するには、Harbor レジストリ インスタンス内に Harbor プロジェクトを作成する必要があります。

コンソール

  1. [Harbor Container Registry] ページで [Create A Harbor Project] をクリックします。

  2. プロジェクトの名前を入力します。

  3. [作成] をクリックします。

  4. このチュートリアルの後半で使用する変数として、Harbor プロジェクト名を設定します。

    export HARBOR_PROJECT=HARBOR_PROJECT
    

gdcloud

  1. 新しい Harbor プロジェクトを作成します。

    gdcloud harbor harbor-projects create HARBOR_PROJECT \
        --project=PROJECT \
        --instance=INSTANCE_NAME
    

    次のように置き換えます。

    • HARBOR_PROJECT: 作成する Harbor プロジェクトの名前。
    • PROJECT: GDC プロジェクトの名前。
    • INSTANCE_NAME: Harbor インスタンスの名前。
  2. このチュートリアルの後半で使用する変数として、Harbor プロジェクト名を設定します。

    export HARBOR_PROJECT=HARBOR_PROJECT
    

Configure Docker

Harbor レジストリで Docker を使用するには、次の手順を行います。

  1. Harbor as a Service を信頼するように Docker を構成します。詳細については、Harbor ルート CA を信頼するように Docker を構成するをご覧ください。

  2. Harbor に対する Docker 認証を構成します。詳細については、Harbor レジストリ インスタンスに対する Docker 認証を構成するをご覧ください。

Kubernetes イメージ pull シークレットを作成する

非公開の Harbor プロジェクトを使用しているため、Kubernetes イメージ pull シークレットを作成する必要があります。

  1. サービス アカウントとして機能する Harbor プロジェクト ロボット アカウントを追加します。

    1. Harbor コンソールで、Harbor プロジェクトを選択します。

    2. [ロボット アカウント] をクリックします。

    3. [New Robot Account] を選択します。

    4. 新しいロボット アカウントに名前を付け、追加の設定を定義します。

    5. [追加] をクリックします。

    6. ロボット アカウントの名前とシークレットが成功画面に表示されます。次のステップで参照するため、この画面を開いたままにしておきます。

    詳細については、Harbor のドキュメント(https://goharbor.io/docs/2.8.0/working-with-projects/project-configuration/create-robot-accounts/#add-a-robot-account)をご覧ください。

  2. 新しいターミナル ウィンドウで、Harbor プロジェクトのロボット アカウントとシークレット トークンを使用して Docker にログインします。

    docker login ${INSTANCE_URL}
    

    プロンプトが表示されたら、前の手順で Harbor コンソールの成功画面から提供されたロボット プロジェクト名を [Username] に、シークレット トークンを [Password] に挿入します。

  3. イメージ pull シークレットに任意の名前を設定します。

    export SECRET=SECRET
    
  4. イメージ pull に必要なシークレットを作成します。

    kubectl create secret docker-registry ${SECRET}  \
        --from-file=.dockerconfigjson=DOCKER_CONFIG \
        -n ${NAMESPACE}
    

    DOCKER_CONFIG は、.docker/config.json ファイルのパスに置き換えます。

  5. Secret が GDC プロジェクトの Namespace に存在することを確認します。

    kubectl get secrets -n ${NAMESPACE}
    

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

    NAME          TYPE                               DATA     AGE
    my-secret     kubernetes.io/dockerconfigjson     1        23s
    

コンテナ イメージをマネージド Harbor レジストリに push する

このチュートリアルでは、nginx ウェブサーバー イメージをダウンロードしてマネージド Harbor レジストリに push し、それを使用してサンプル nginx ウェブサーバー アプリを Kubernetes クラスタにデプロイします。nginx ウェブサーバー アプリは、一般公開されている Docker Hub リポジトリから入手できます。

  1. 外部ネットワークを使用して、Docker Hub からローカル ワークステーションに nginx イメージを pull します。

    docker pull nginx
    
  2. ローカル イメージにリポジトリ名でタグ付けします。

    docker tag nginx ${INSTANCE_URL}/${HARBOR_PROJECT}/nginx:1.25
    
  3. nginx コンテナ イメージをマネージド Harbor レジストリに push します。

    docker push ${INSTANCE_URL}/${HARBOR_PROJECT}/nginx:1.25
    

Kubernetes クラスタの作成

nginx コンテナ イメージがマネージド Harbor レジストリに保存され、アクセスできるようになったので、nginx ウェブサーバーを実行する Kubernetes クラスタを作成します。

コンソール

  1. ナビゲーション メニューで、[Kubernetes Engine] > [クラスタ] を選択します。

  2. [クラスタを作成] をクリックします。

  3. [名前] フィールドに、クラスタの名前を指定します。

  4. Kubernetes クラスタを作成するゾーンを選択します。Kubernetes クラスタはゾーン リソースであり、高可用性を確保するには、各ゾーンで手動で作成する必要があります。

  5. [プロジェクトを接続] をクリックし、クラスタに接続するプロジェクトを選択します。[保存] をクリックします。

  6. [作成] をクリックします。

  7. クラスタが作成されるまで待ちます。クラスタが使用可能になると、クラスタ名の横にステータス READY が表示されます。

API

  1. Cluster カスタム リソースを作成し、cluster.yaml などの YAML ファイルとして保存します。

    apiVersion: cluster.gdc.goog/v1
    kind: Cluster
    metadata:
      name: CLUSTER_NAME
      namespace: platform
    

    CLUSTER_NAME 値は、クラスタの名前に置き換えます。

  2. カスタム リソースを GDC インスタンスに適用します。

    kubectl create -f cluster.yaml --kubeconfig ${MANAGEMENT_API_SERVER}
    
  3. GDC コンソールを使用して、プロジェクトを Kubernetes クラスタにアタッチします。現時点では、API を使用してプロジェクトをクラスタに接続することはできません。

Kubernetes クラスタの作成の詳細については、Kubernetes クラスタを作成するをご覧ください。

サンプル コンテナアプリをデプロイする

これで、nginx コンテナ イメージを Kubernetes クラスタにデプロイする準備が整いました。

Kubernetes では、アプリケーションは Pod リソースとして表されます。これは、1 つ以上のコンテナを保持するスケーラブルな単位です。Pod は、Kubernetes でデプロイ可能な最小単位です。通常は、Pod をレプリカのセットとしてデプロイし、クラスタ全体で一緒にスケーリングと分散を行えます。レプリカのセットをデプロイする 1 つの方法は、Kubernetes Deployment を使用することです。

このセクションでは、クラスタで nginx コンテナアプリを実行する Kubernetes Deployment を作成します。この Deployment にはレプリカ(Pod)があります。1 つの Deployment Pod には、nginx コンテナ イメージという 1 つのコンテナのみが含まれます。また、クライアントが Deployment の Pod にリクエストを安定して送信できるようにする Service リソースも作成します。

nginx ウェブサーバーを Kubernetes クラスタにデプロイします。

  1. Kubernetes クラスタにログインし、ユーザー ID を使用して kubeconfig ファイルを生成します。kubeconfig パスを環境変数として設定します。

    export KUBECONFIG=CLUSTER_KUBECONFIG_PATH
    
  2. Kubernetes の Deployment カスタム リソースと Service カスタム リソースを作成してデプロイします。

    kubectl --kubeconfig ${KUBECONFIG} -n ${NAMESPACE} \
    create -f - <<EOF
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
      labels:
        app: nginx
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: ${INSTANCE_URL}/${HARBOR_PROJECT}/nginx:1.25
            ports:
            - containerPort: 80
          imagePullSecrets:
          - name: ${SECRET}
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-service
    spec:
      selector:
        app: nginx
      ports:
        - port: 80
          protocol: TCP
      type: LoadBalancer
    EOF
    
  3. デプロイによって Pod が作成されたことを確認します。

    kubectl get pods -l app=nginx -n ${NAMESPACE}
    

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

    NAME                                READY     STATUS    RESTARTS   AGE
    nginx-deployment-1882529037-6p4mt   1/1       Running   0          1h
    nginx-deployment-1882529037-p29za   1/1       Running   0          1h
    nginx-deployment-1882529037-s0cmt   1/1       Running   0          1h
    
  4. すべてのネットワーク トラフィックを Namespace に許可するネットワーク ポリシーを作成します。

    kubectl --kubeconfig ${KUBECONFIG} -n ${NAMESPACE} \
    create -f - <<EOF
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      annotations:
      name: allow-all
    spec:
      ingress:
      - from:
        - ipBlock:
            cidr: 0.0.0.0/0
      podSelector: {}
      policyTypes:
      - Ingress
    EOF
    
  5. nginx サービスの IP アドレスをエクスポートします。

      export IP=`kubectl --kubeconfig=${KUBECONFIG} get service nginx-service \
          -n ${NAMESPACE} -o jsonpath='{.status.loadBalancer.ingress[*].ip}'`
    
  6. curl を使用して nginx サーバーの IP アドレスをテストします。

      curl http://$IP
    

クリーンアップ

このチュートリアルで使用したリソースについて GDC アカウントに課金されないようにするには、作成したリソースを削除する必要があります。

コンテナ イメージを削除する

GDC のエアギャップ環境からコンテナ イメージを削除するには、イメージを含む Harbor インスタンスを削除するか、Harbor インスタンスは残して個々のコンテナ イメージを削除します。

マネージド Harbor レジストリからコンテナ イメージを削除するには、GDC コンソールを使用します。

  1. ナビゲーション メニューで、[CI/CD] セクションから [Harbor Container Registry] を選択します。

  2. [Go to Harbor Instance] 外部リンクをクリックします。

  3. Harbor UI を使用してコンテナ イメージを削除します。詳細については、Harbor レジストリ インスタンスを削除するをご覧ください。

コンテナアプリを削除する

デプロイされたコンテナアプリを削除するには、リソースを含む GDC プロジェクトを削除するか、GDC プロジェクトを維持して個々のリソースを削除します。

リソースを個別に削除する手順は次のとおりです。

  1. コンテナアプリの Service オブジェクトを削除します。

    kubectl delete service nginx-service -n ${NAMESPACE}
    
  2. コンテナアプリの Deployment オブジェクトを削除します。

    kubectl delete deployment nginx-deployment -n ${NAMESPACE}
    
  3. このチュートリアル専用にテスト Kubernetes クラスタを作成した場合は、そのクラスタを削除します。

    kubectl delete clusters.cluster.gdc.goog/USER_CLUSTER_NAME \
        -n platform --kubeconfig ${MANAGEMENT_API_SERVER}
    

    これにより、Kubernetes クラスタを構成するリソース(コンピューティング インスタンス、ディスク、ネットワーク リソースなど)が削除されます。

次のステップ