GKE で Ingress を使用して Google マネージド SSL 証明書を使用した外部 HTTP(S) ロードバランサを作成する

記事タイトルとURLをコピーする

G-gen の佐々木です。当記事では Google Cloud ( 旧称 GCP ) の Google Kubernetes Engine ( GKE ) で Ingress を使用し、Google マネージド SSL 証明書が構成された HTTPS ロードバランサ を Kubernetes のリソースとして作成していきます。

前提知識

Google Kubernetes Engine とは

Google Kubernetes Engine (以下、GKE ) は、Google Cloud のインフラストラクチャ上に構築された マネージドな Kubernetes クラスタ を利用することができるサービスです。
サービスの詳細は以下の記事で解説しています。

blog.g-gen.co.jp

Ingress とは

Ingress は Kubernetes の API リソースの 1 つで、Kubernetes クラスタ内のワークロードに対する L7 ロードバランシングを提供します。
Ingress は Service に関連付けることで、その背後にある Pod にデプロイされたアプリケーションを外部に公開することができます。

GKE では、組み込みのコントローラである GKE Ingress Controller によって、Kubernetes によって管理される HTTP(S) ロードバランサを GKE クラスタ外に作成することができます。

Ingressを用いたL7ロードバランサによるワークロードの外部公開

GKE クラスタの準備

当記事では Autopilot モードの限定公開クラスタを使用していきます。
クラスタの作成方法については 公式ドキュメント、または Terraform を使用した以下の記事を参照してください。

blog.g-gen.co.jp

GKE クラスタにサンプルアプリケーションをデプロイする

gcloud container clusters get-credentials コマンドを使用して GKE クラスタに接続した後、アプリケーションを GKE クラスタにデプロイします。
ここでは、Google Cloud が提供するサンプルのコンテナイメージを使用します。
また、Ingress に紐づける Service も同時にデプロイしていきます。

マニフェストファイルは以下のようになります。

# workload.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello
  template:
    metadata:
      labels:
        app: hello
    spec:
      containers:
      - name: hello
        image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0
        ports:
        - containerPort: 8080
          protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
  name: hello
  namespace: default
  annotations:
    cloud.google.com/neg: '{"ingress": true}'
spec:
  ports:
  - port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    app: hello
  type: NodePort

このマニフェストファイルにより、3 つの Pod を含む Deployment と、それらを公開するための Service ( NodePort ) が作成されます。

# デプロイ後
$ kubectl get deployments hello
NAME    READY   UP-TO-DATE   AVAILABLE   AGE
hello   3/3     3            3           3m45s  
  
$ kubectl get services hello
NAME    TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
hello   NodePort   172.31.113.220   <none>        8080:30989/TCP   4m24s

証明書を使用せずに Ingress を作成する

まずは、最小限のマニフェストを使用して Ingress リソースを作成してみます。
ここで作成されるロードバランサは SSL 証明書が構成されておらず、HTTP トラフィック(ポート 80)を GKE クラスタ内のワークロードにルーティングします。

当記事では、Ingress リソースを作成するマニフェストファイルの名前を ingress.yaml とします。

# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: hello-ingress
  namespace: default
  annotations:
    kubernetes.io/ingress.class: "gce"  # 外部 HTTP(S) ロードバランサを指定
spec:
  defaultBackend:
    service:
      name: hello
      port:
        number: 8080
# デプロイ後
$ kubectl get ingresses hello-ingress
NAME            CLASS    HOSTS   ADDRESS          PORTS   AGE
hello-ingress   <none>   *       34.117.255.169   80      4m55s

Ingress のデプロイが完了すると、Google Cloud コンソールで HTTP(S) ロードバランサが作成されていることを確認できます。
ここで作成されたロードバランサが使用できるプロトコルは HTTP のみ となっています。

Ingress から作成された HTTP(S) ロードバランサ

ブラウザでロードバランサの IP アドレスにアクセスすると、サンプルアプリケーションのページが表示されます。

サンプルアプリケーションのページ

Google マネージド SSL 証明書を使用して Ingress を作成する

静的外部 IP アドレスを払い出す

当記事では、hello-app-address という名前で IP アドレスを払い出します。
この IP アドレスは、HTTP(S) ロードバランサに紐づけ、証明書に使用するドメインで解決できるようにします。

# 静的外部 IP アドレスの払い出し
$ gcloud compute addresses create hello-app-address --global

払い出した IP アドレスは次の手順で使用するため、値を確認しておきます。

# 払い出した IP アドレスを確認する
$ gcloud compute addresses describe hello-app-address --global 
address: 34.160.155.24

A レコードを登録する

SSL 証明書に使用するドメインで、先ほど作成した IP アドレスを解決できるように DNS を構成します。
当記事では Cloud DNS に作成された DNS ゾーンに A レコードを作成していきます。
ここでは仮の値として、DNS ゾーンをhogehoge-zone、ドメインをhogehoge.com とします。

# トランザクションの開始
$ gcloud dns record-sets transaction start --zone=hogehoge-zone
Transaction started [transaction.yaml].
  
# Aレコードの登録
$ gcloud dns record-sets transaction add 34.160.155.24 \
   --name=hogehoge.com \
   --ttl=300 \
   --type=A \
   --zone=hogehoge-zone
Record addition appended to transaction at [transaction.yaml].
  
# トランザクションの終了
$ gcloud dns record-sets transaction execute --zone=hogehoge-zone
Executed transaction [transaction.yaml] for managed-zone [hogehoge-zone].
Created [https://dns.googleapis.com/dns/v1/projects/myproject/managedZones/hogehoge-zone/changes/32].
ID  START_TIME                STATUS
32  2023-02-21T14:38:43.813Z  pending

ManagedCertificate リソースを作成する

ManagedCertificate カスタムリソースを使用して、Google マネージド SSL 証明書を Kubernetes リソースとして作成します。
マニフェストファイルには、先ほど DNS に登録したドメインを記述します。

# cert.yaml
apiVersion: networking.gke.io/v1
kind: ManagedCertificate
metadata:
  name: hello-managed-cert
spec:
  domains:
  - hogehoge.com
# デプロイ後
$ kubectl get managedcertificate.networking.gke.io hello-managed-cert
NAME                 AGE     STATUS
hello-managed-cert   6m21s   Provisioning

証明書を使用するように Ingress を更新する

作成した Google マネージド SSL 証明書を使用するように Ingress を更新します。
始めに作成した ingress.yamlannotations に以下の 2 つを追記して GKE クラスタに再適用します。

annotations のキー
kubernetes.io/ingress.global-static-ip-name ロードバランサ用に払い出した静的外部 IP アドレスの名前
networking.gke.io/managed-certificates ManagedCertificate の名前
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: hello-ingress
  namespace: default
  annotations:
    kubernetes.io/ingress.global-static-ip-name: hello-app-address  # 追記
    networking.gke.io/managed-certificates: hello-managed-cert      # 追記
    kubernetes.io/ingress.class: "gce"
spec:
  defaultBackend:
    service:
      name: hello
      port:
        number: 8080

Ingress を更新すると、Ingress が使用する(ロードバランサで使用する) IP アドレスが、払い出した静的外部 IP アドレスに変更されます。

$ kubectl get ingresses hello-ingress
NAME            CLASS    HOSTS   ADDRESS         PORTS   AGE
hello-ingress   <none>   *       34.160.155.24   80      19m

Google Cloud コンソールから、HTTP(S) ロードバランサが HTTPS プロトコルを使用するように構成され直したことが確認できます。

HTTP(S) ロードバランサに HTTPS プロトコルが追加されている

Google マネージド SSL 証明書のステータスを確認する

Google マネージド SSL 証明書のステータスが Active になるまで待ちます。
※ 証明書のステータス反映は Google Cloud コンソールのほうが早いようです。

# 証明書のステータス確認
$ kubectl get managedcertificate.networking.gke.io hello-managed-cert --watch
NAME                 AGE   STATUS
hello-managed-cert   31m   Active

証明書のステータスが ACTIVE になっていることを確認

サンプルアプリケーションに HTTPS でアクセスできることを確認する

証明書を構成したあと、DNS に設定したドメインに接続すると、サンプルアプリケーションに HTTPS でアクセスすることができます。

サンプルアプリケーションに HTTPS でアクセスできることを確認

佐々木 駿太 (記事一覧)

G-gen最北端、北海道在住のクラウドソリューション部エンジニア

2022年6月にG-genにジョイン。Google Cloud Partner Top Engineer 2024に選出。好きなGoogle CloudプロダクトはCloud Run。

趣味はコーヒー、小説(SF、ミステリ)、カラオケなど。