Google Cloud Armor の構成

このページでは、BackendConfig カスタム リソースを使用して Google Kubernetes Engine で Google Cloud Armor を構成する方法について説明します。

概要

GKE クラスタで、受信トラフィックは Cloud Load Balancing のコンポーネントである HTTP(S) 負荷分散によって処理されます。 一般に、HTTP(S) ロードバランサは GKE Ingress コントローラによって構成され、このコントローラは構成情報を Kubernetes Ingress オブジェクトから取得します。Ingress は、1 つ以上のService オブジェクトに関連付けられています。Service オブジェクトは、受信リクエストを特定のポッドとポートに転送するために使用するルーティング情報を保持します。

Kubernetes バージョン 1.10.5-gke.3 以降では、Service ポートを BackendConfig という名前のカスタム リソースに関連付けることで、ロードバランサの追加の構成を指定できます。

GKE Ingress コントローラは、BackendConfig から構成情報を読み取り、それに従ってロードバランサを設定します。BackendConfig には、Cloud Load Balancing に固有の構成情報が格納されています。 Kubernetes Ingress および Service のリソースには、Google Cloud Armor などのプロバイダ固有の機能を構成する方法がありませんが、BackendConfig にはその構成を行う方法があります。

ここでは、この演習で BackendConfig を設定する方法の概要を示します。

  1. BackendConfig を作成します。
  2. サービスを作成し、そのポートの 1 つを BackendConfig に関連付けます。
  3. Ingress を作成して、Ingress を(Service、ポート)ペアに関連付けます。

始める前に

このタスクの準備として、次の手順を行います。

  • Google Kubernetes Engine API が有効になっていることを確認します。
  • Enable Google Kubernetes Engine API を有効にする
  • Cloud SDK がインストール済みであることを確認します。
  • デフォルトのプロジェクト ID を設定します。
    gcloud config set project [PROJECT_ID]
  • ゾーンクラスタを使用する場合は、デフォルトのコンピューティング ゾーンを設定します。
    gcloud config set compute/zone [COMPUTE_ZONE]
  • リージョン クラスタを使用する場合は、デフォルトのコンピューティング リージョンを設定します。
    gcloud config set compute/region [COMPUTE_REGION]
  • gcloud を最新バージョンに更新します。
    gcloud components update

名前空間を作成する

このガイドのオブジェクトのための Kubernetes 名前空間を作成します。

kubectl create namespace cloud-armor-how-to

Deployment を作成する

この Deployment マニフェストでは、hello-app ウェブ アプリケーションの 2 つのレプリカの実行を宣言します。

apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: cloud-armor-how-to
  name: my-deployment
spec:
  selector:
    matchLabels:
      app: hello-app
  replicas: 2
  template:
    metadata:
      labels:
        app: hello-app
    spec:
      containers:
      - name: hello-app-container
        image: gcr.io/google-samples/hello-app:1.0
        ports:
        - containerPort: 8080

このマニフェストを my-deployment.yaml という名前のファイルにコピーし、次のようにして Deployment を作成します。

kubectl apply -f my-deployment.yaml

Google Cloud Armor セキュリティ ポリシーとルールの作成

Google Cloud Armor セキュリティ ポリシーを作成します。

gcloud beta compute security-policies create ca-how-to-security-policy \
    --description "policy for Google Cloud Armor how-to topic"

セキュリティ ポリシーのルールを作成します。

gcloud beta compute security-policies rules create 1000 \
    --security-policy ca-how-to-security-policy \
    --description "Deny traffic from 192.0.2.0/24." \
    --src-ip-ranges "192.0.2.0/24" \
    --action "deny-404"

セキュリティ ポリシーを表示します。

gcloud beta compute security-policies describe ca-how-to-security-policy

出力:

...
kind: compute#securityPolicy
name: ca-how-to-security-policy
rules:
- action: deny(404)
  description: Deny traffic from 192.0.2.0/24.
  kind: compute#securityPolicyRule
  match:
    config:
      srcIpRanges:
      - 192.0.2.0/24
    versionedExpr: SRC_IPS_V1
  preview: false
  priority: 1000
  ...

BackendConfig の作成

BackendConfig のマニフェストを次に示します。このマニフェストでは、セキュリティ ポリシーを指定しています。

apiVersion: cloud.google.com/v1beta1
kind: BackendConfig
metadata:
  namespace: cloud-armor-how-to
  name: my-backend-config
spec:
  securityPolicy:
    name: "ca-how-to-security-policy"

このマニフェストを my-backend-config.yaml という名前のファイルにコピーし、次のようにして BackendConfig を作成します。

kubectl apply -f my-backend-config.yaml

BackendConfig を表示します。

kubectl get backendconfig my-backend-config --namespace cloud-armor-how-to --output yaml

出力には、指定されたセキュリティ ポリシーが表示されます。

apiVersion: cloud.google.com/v1beta1
kind: BackendConfig
metadata:
  name: my-backend-config
  namespace: cloud-armor-how-to
  ...
spec:
  securityPolicy:
    name: ca-how-to-security-policy

サービスの作成

Service のマニフェストを次に示します。

apiVersion: v1
kind: Service
metadata:
  namespace: cloud-armor-how-to
  name: my-service
  labels:
    app: hello-app
  annotations:
    beta.cloud.google.com/backend-config: '{"ports": {"80":"my-backend-config"}}'
spec:
  type: NodePort
  selector:
    app: hello-app
  ports:
  - port: 80
    protocol: TCP
    targetPort: 8080

マニフェストを my-service.yaml という名前のファイルに保存し、Service を作成します。

kubectl apply -f my-service.yaml

Service を表示します。

kubectl get service my-service --namespace cloud-armor-how-to --output yaml

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

apiVersion: v1
kind: Service
metadata:
  annotations:
    beta.cloud.google.com/backend-config: '{"ports": {"80":"my-backend-config"}}'
  labels:
    app: hello-app
  name: my-service
  namespace: cloud-armor-how-to
  ...
spec:
  clusterIP: 10.19.249.137
  externalTrafficPolicy: Cluster
  ports:
  - nodePort: 32629
    port: 80
    protocol: TCP
    targetPort: 8080
  selector:
    app: hello-app
  sessionAffinity: None
  type: NodePort
status:
  loadBalancer: {}

この演習では、Service について次の項目を把握することが重要です。

  • Service のポート 80 が my-backend-config という名前の BackendConfig に関連付けられています。これは、beta.cloud.google.com/backend-config アノテーションで指定されています。

  • Service のタイプは NodePort です。これは Service の必須タイプであり、Ingress に関連付けられます。

  • app: hello-app というラベルを持つすべてのポッドが Service のメンバーになります。これは、selector フィールドで指定されています。

  • TCP ポート 80 のサービスへのトラフィックは、メンバーのうちいずれかのポッドの TCP ポート 8080 にルーティングされます。これは、porttargetPort フィールドで指定されています。

静的外部 IP アドレスの予約

静的外部 IP アドレスを予約します。

gcloud compute addresses create cloud-armor-how-to-address --global

静的外部 IP アドレスを表示します。

gcloud compute addresses list --filter "name=cloud-armor-how-to-address"

出力:

NAME                        REGION  ADDRESS        STATUS
cloud-armor-how-to-address          203.0.113.2    RESERVED

Ingress の作成

Ingress のマニフェストを次に示します。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  namespace: cloud-armor-how-to
  name: my-ingress
  annotations:
    kubernetes.io/ingress.global-static-ip-name: "cloud-armor-how-to-address"
spec:
  backend:
    serviceName: my-service
    servicePort: 80

このマニフェストを my-ingress.yaml という名前のファイルにコピーし、次のようにして Ingress を作成します。

kubectl create -f my-ingress.yaml

Kubernetes Ingress コントローラによる Cloud ロードバランサの構成が完了するまで数分程度待機し、その後 Ingress を表示します。

kubectl get ingress my-ingress --output yaml --namespace cloud-armor-how-to

出力:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-ingress
  namespace: cloud-armor-how-to
  ...
spec:
  backend:
    serviceName: my-service
    servicePort: 80
status:
  loadBalancer:
    ingress:
    - ip: 203.0.113.2

この演習では、Ingress について次の項目を把握することが重要です。

  • 受信トラフィックの IP アドレスは loadBalancer:ingress: の下に表示されます。

  • Ingress には、あらゆるホストから受信する HTTP リクエストに適用される 1 つのルールがあります。これは、ルールに host フィールドがないためです。そのため、デフォルトでは、ルールはすべてのホストに適用されます。

  • URL パスにかかわらず、すべての受信リクエストが同じように処理されます。これは、path の値の /* で指定されます。

  • 受信リクエストは、my-service のメンバーのポッドにルーティングされます。この演習では、メンバーのポッドには app: hello-app というラベルが付与されています。

  • リクエストは、my-service で指定されたターゲット ポートのポッドにルーティングされます。この演習では、ポッドのターゲット ポートは 8080 です。

ウェブアプリの表示

数分間お待ちください。それから、ブラウザで、静的外部 IP アドレスを入力します。

このページには、Deployment のポッドのいずれかで実行されている hello-app ウェブ アプリケーションからのレスポンスが表示されます。

Hello, world!
Version: 1.0.0
Hostname: my-deployment-574ddbdf88-f9fbj

curl を使用してウェブアプリを表示します。

curl -v [STATIC_ADDRESS]

[STATIC_ADDRESS] は、静的外部 IP アドレスです。

hello-app からのレスポンスが出力されます。

Hello, world!
Version: 1.0.0
Hostname: my-deployment-574ddbdf88-zpb94

セキュリティ ポリシーの切り離し

セキュリティ ポリシーを Ingress から切り離すには、BackendConfig でセキュリティ ポリシー名を空に設定します。以下に、セキュリティ ポリシーの切り離しの例を示します。

apiVersion: cloud.google.com/v1beta1
kind: BackendConfig
metadata:
  namespace: cloud-armor-how-to
  name: my-backend-config
spec:
  securityPolicy:
    name: ""

制限事項

割り当て上限

ベータ版の Google Cloud Armor ルールの数には厳格な制限があります。この制限は、同機能が一般提供される際に解除されます。

IP のホワイトリストとブラックリストのみ

Google Cloud Armor は、IP ホワイトリストと IP ブラックリストのみをサポートします。

トラブルシューティング

BackendConfig が見つかりません

このエラーは、Service のアノテーションで Service ポートの BackendConfig が指定されているにもかかわらず BackendConfig リソースが見つからなかった場合に発生します。 これが発生するのは、BackendConfig リソースがまったく作成されていない場合、誤った名前空間に作成された場合、または Service アノテーションの参照にスペルミスがあった場合です。

kubectl get event
KIND    ... SOURCE
Ingress ... loadbalancer-controller

MESSAGE
Error during sync: error getting BackendConfig for port 80 on service "default/my-service":
no BackendConfig for service port exists

セキュリティ ポリシーが見つかりません

Ingress オブジェクトが作成された後で、セキュリティ ポリシーがロードバランサ サービスと適切に関連付けられていない場合は、Kubernetes イベントを検査して構成ミスがないか調べてください。具体的には、BackendConfig が存在しないポリシーを指定している場合、警告イベントが定期的に発生します。 この問題を修正するには、BackendConfig で正しいセキュリティ ポリシーを、名前で指定してください。

kubectl get event
KIND    ... SOURCE
Ingress ... loadbalancer-controller

MESSAGE
Error during sync: The given security policy "my-policy" does not exist.

クリーンアップ

このページの演習を完了したら、アカウントで不要な請求が発生しないように、以下の手順でリソースを削除します。

この演習で作成した Kubernetes オブジェクトを削除します。

kubectl delete ingress my-ingress --namespace cloud-armor-how-to
kubectl delete service my-service --namespace cloud-armor-how-to
kubectl delete backendconfig my-backend-config --namespace cloud-armor-how-to
kubectl delete deployment my-deployment --namespace cloud-armor-how-to
kubectl delete namespace cloud-armor-how-to

静的外部 IP アドレスを削除します。

gcloud compute addresses delete cloud-armor-how-to-address --global

セキュリティ ポリシーを削除します。

gcloud beta compute security-policies delete ca-how-to-security-policy

次のステップ

このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...

Kubernetes Engine のドキュメント