G-gen の佐々木です。当記事では Google Cloud ( 旧称 GCP ) の Google Kubernetes Engine ( GKE ) で作成した Ingress に対して、Cloud Armor セキュリティポリシー を構成することで、ワークロードに対するアクセス元 IP アドレス制限を実装します。
- 前提知識
- GKE クラスタの準備
- GKE クラスタにサンプルアプリケーションをデプロイする
- Ingress を作成してアプリケーションを公開する
- Cloud Armor のセキュリティポリシーを作成する
- BackendConfig を作成する
- Service を更新して BackendConfig に紐づける
- 許可していない IP アドレスからアクセスしてみる

前提知識
Google Kubernetes Engine とは
Google Kubernetes Engine (以下、GKE ) は、Google Cloud のインフラストラクチャ上に構築された マネージドな Kubernetes クラスタ を利用することができるサービスです。
サービスの詳細は以下の記事で解説しています。
Ingress とは
Ingress は Kubernetes の API リソースの 1 つで、Kubernetes クラスタ内のワークロードに対する L7 ロードバランシングを提供します。
Ingress は Service に関連付けることで、その背後にある Pod にデプロイされたアプリケーションを外部に公開することができます。
GKE では、組み込みのコントローラである GKE Ingress Controller によって、Kubernetes によって管理される HTTP(S) ロードバランサを GKE クラスタ外に作成することができます。

当記事では省略しますが、Ingress によって作成される HTTP(S) ロードバランサで HTTPS を使用する場合、Ingress と SSL 証明書を紐づける設定をする必要があります。
詳細な手順については以下の記事をご一読ください。
Cloud Armor とは
Cloud Armor は Google 製のクラウド型 WAF であり、Cloud Armor の セキュリティポリシー を HTTP(S) ロードバランサのバックエンドに紐づけることで、バックエンドに対するアクセス元の制限をかけることができます。
Cloud Armor の詳細については、以下の記事で解説しています。
GKE クラスタの準備
当記事では Autopilot モードの限定公開クラスタを使用していきます。
クラスタの作成方法については 公式ドキュメント、または Terraform を使用した以下の記事を参照してください。
GKE クラスタにサンプルアプリケーションをデプロイする
Google Cloud が提供するサンプルのコンテナイメージを使用し、アプリケーションを GKE クラスタに登録します。
マニフェストファイルは以下のようになります。
# deployment.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: hellonamespace: defaultspec:replicas: 3selector:matchLabels:app: hellotemplate:metadata:labels:app: hellospec:containers:- name: helloimage: us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0ports:- containerPort: 8080protocol: TCP
続いて、アプリケーションを公開するための Service を GKE クラスタに登録します。
Service のマニフェストファイルは後に編集するため、当記事ではファイル名を service.yaml
と定めます。
# service.yamlapiVersion: v1kind: Servicemetadata:name: hellonamespace: defaultannotations:cloud.google.com/neg: '{"ingress": true}'spec:ports:- port: 8080protocol: TCPtargetPort: 8080selector:app: hellotype: NodePort
それぞれのプロビジョニングが完了するまで待ちます。
$ kubectl get deployments helloNAME READY UP-TO-DATE AVAILABLE AGEhello 3/3 3 3 15m$ kubectl get services helloNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEhello NodePort 172.31.236.34 <none> 8080:32678/TCP 10m
Ingress を作成してアプリケーションを公開する
まずは Cloud Armor のセキュリティポリシーを構成せずに Ingress を作成してみます。
この Ingress によって作成される HTTP(S) ロードバランサはアクセス元の制限がされておらず、ロードバランサの IP アドレスを知っていれば誰でもアプリケーションにアクセスすることができてしまいます。
# ingress.yamlapiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: hello-ingressnamespace: defaultannotations:kubernetes.io/ingress.class: "gce" # 外部 HTTP(S) ロードバランサを指定spec:defaultBackend:service:name: helloport:number: 8080
Ingress によって作成された HTTP(S) ロードバランサの外部 IP アドレスを確認し、ブラウザからアクセスしてみます。
$ kubectl get ingresses hello-ingressNAME CLASS HOSTS ADDRESS PORTS AGEhello-ingress <none> * 34.117.255.169 80 19m

Cloud Armor のセキュリティポリシーを作成する
アプリケーションに対するアクセス元 IP アドレスを制限するセキュリティポリシーを作成します。
ここで設定したセキュリティポリシーの名前は後で使用します。
セキュリティポリシーは Cloud Armor の機能ですが、gcloud compute
コマンドグループを使用して作成、編集を行うことができます。
当記事では hello-sec-policy
という名前のセキュリティポリシーを作成します。
# セキュリティポリシーの作成$ gcloud compute security-policies create hello-sec-policy
ポリシーのデフォルトルール(優先度 2,147,483,647 )を更新し、すべてのアクセス元を拒否します。
# デフォルトルールの更新$ gcloud compute security-policies rules update 2147483647 \--security-policy hello-sec-policy \--action "deny-403"
特定の IP アドレス範囲からのアクセスを許可するルールを追加します。
ルールの優先度はデフォルトのルールより高ければよいので、ここでは優先度 1000 で設定します。
# 許可ルールの追加$ gcloud compute security-policies rules create 1000 \--security-policy hello-sec-policy \--src-ip-ranges "<許可する IP アドレス範囲>" \--action "allow"
BackendConfig を作成する
Ingress に対して Cloud Armor セキュリティポリシーを紐づけるため、GKE のカスタムリソースである BackendConfig リソースをクラスタに登録します。
BackendConfig リソースを使用することで、セキュリティポリシーだけではなく、Cloud CDN や Identity-Aware Proxy など、HTTP(S) ロードバランサで利用できる様々な機能を Kubernetes から有効化することができます。
BackendConfig のマニフェストファイルでは、先ほど作成したセキュリティポリシーの名前を使用します。
# backendconfig.yamlapiVersion: cloud.google.com/v1kind: BackendConfigmetadata:name: hello-backend-configspec:securityPolicy:name: hello-sec-policy # 作成したセキュリティポリシーの名前
Service を更新して BackendConfig に紐づける
BackendConfig は、Ingress に対してではなく、HTTP(S) ロードバランサのバックエンドとなる Service に対して紐づけます。
バックエンドが使用するポートと BackendConfig を組み合わせた cloud.google.com/backend-config
アノテーションを service.yaml
に追記します。
annotations のキー | 値 |
---|---|
cloud.google.com/backend-config | '{"ports": {"8080":"hello-backend-config"}}' |
# service.yamlapiVersion: v1kind: Servicemetadata:name: hellonamespace: defaultannotations:cloud.google.com/backend-config: '{"ports": {"8080":"hello-backend-config"}}' # 追記cloud.google.com/neg: '{"ingress": true}'spec:ports:- port: 8080protocol: TCPtargetPort: 8080selector:app: hellotype: NodePort
許可していない IP アドレスからアクセスしてみる
Ingress によって作成された HTTP(S) ロードバランサに Cloud Armor セキュリティポリシーが構成されたので、ポリシーで許可していない IP アドレス範囲からのアクセスが拒否されることを確認します。
ブラウザで、HTTP(S) ロードバランサの外部 IP アドレスに再度アクセスしてみます。

最後に、ポリシーで許可された IP アドレスからアクセスし、サンプルアプリケーションの画面が表示されることを確認します。

佐々木 駿太 (記事一覧)
G-gen最北端、北海道在住のクラウドソリューション部エンジニア
2022年6月にG-genにジョイン。Google Cloud Partner Top Engineer 2025 Fellowに選出。好きなGoogle CloudプロダクトはCloud Run。
趣味はコーヒー、小説(SF、ミステリ)、カラオケなど。
Follow @sasashun0805