Cloud Armor の構成

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

概要

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

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

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

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

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

始める前に

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

  • Google Kubernetes Engine API が有効になっていることを確認します。
  • 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

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

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

gcloud beta compute security-policies create ca-how-to-security-policy \
    --description "policy for 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

サービスの作成

サービスのマニフェストを次に示します。

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 という名前のファイルに保存して、サービスを作成します。

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: {}

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

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

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

  • app: hello-app のラベルが付いたポッドは、サービスのメンバーです。これは selector フィールドで指定されています。

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

静的外部 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: ""

制限事項

割り当て上限

この機能がベータ版である間は、書き込める Cloud Armor ルールの数にハードリミットがあります。この制限は、同機能が一般提供される際に解除されます。

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

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

トラブルシューティング

BackendConfig が見つかりません

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

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 のドキュメント