Ingress ゲートウェイで TLS 終端を設定する
概要
このページでは、Cloud Service Mesh の Ingress ゲートウェイで TLS 終端を設定して、サービスへの外部 HTTPS トラフィックを管理する方法について説明します。ゲートウェイの設定方法のより基本的な説明については、ゲートウェイ ガイドをご覧ください。TLS を使用して安全な通信を行うようにゲートウェイを構成し、アプリケーションへの暗号化されたアクセスを有効にする方法についても学習します。このプロセスでは、Cloud Service Mesh の機能を活用してサービスを安全に公開します。
始める前に
このドキュメントの手順を完了するには、次のリソースが必要です。
- Cloud Service Mesh がインストールされている Kubernetes クラスタ。Cloud Service Mesh のインストール方法については、インストール ガイドをご覧ください。
環境を設定する
使用するクラスタにアクセスできるワークステーションから次のコマンドを実行します。クラスタに固有のクラスタ コンテキストを使用するように、kubectl
ツールが構成されていることを確認します。
環境変数を設定します。
export CSM_INGRESSGATEWAY_NAMESPACE=CSM_INGRESSGATEWAY_NAMESPACE export CSM_INGRESSGATEWAY_DEPLOYMENT_NAME=CSM_INGRESSGATEWAY_DEPLOYMENT_NAME export CSM_INGRESSGATEWAY_SERVICE_NAME=CSM_INGRESSGATEWAY_SERVICE_NAME
foo
アプリケーションをクラスタにデプロイします。次の yaml を使用してインストールします。apiVersion: v1 kind: Service metadata: name: foo namespace: foo spec: selector: app: test-backend ports: - port: 8080 targetPort: 8080 --- apiVersion: apps/v1 kind: Deployment metadata: name: foo namespace: foo spec: replicas: 2 selector: matchLabels: app: test-backend template: metadata: labels: app: test-backend spec: containers: - name: whereami image: gcr.io/google-samples/whereami:v1.2.23 ports: - containerPort: 8080 EOF
証明書と鍵を生成します。
Ingress ゲートウェイを保護するには、TLS 証明書と鍵が必要です。任意の証明書生成ツールを使用することも、次の手順で openssl を使用して必要な認証情報を作成することもできます。
- ルート CA 証明書と鍵を作成する
mkdir example_certs openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=Example Corp/CN=example.com' \ -keyout example.com.key -out example.com.crt
- Ingress の証明書と鍵を生成する
openssl req -out foo.example.com.csr -newkey rsa:2048 -nodes \ -keyout foo.example.com.key -subj "/CN=foo.example.com/O=Foo Org" openssl x509 -req -sha256 -days 365 -CA example.com.crt \ -CAkey example.com.key -set_serial 0 \ -in foo.example.com.csr -out foo.example.com.crt
TLS 証明書を保存する
TLS 証明書を Secret
として保存します。
Namespace を作成します。この Namespace は、Ingress ゲートウェイのデプロイに使用されます。
kubectl create namespace ${CSM_INGRESSGATEWAY_NAMESPACE}
デフォルトのインジェクション ラベルを Namespace に適用します。
kubectl label namespace ${CSM_INGRESSGATEWAY_NAMESPACE} \ istio.io/rev- istio-injection=enabled --overwrite
TLS 認証情報を Kubernetes Secret に保存します。
kubectl create -n ${CSM_INGRESSGATEWAY_NAMESPACE} secret tls foo-credential \ --key=example_certs/foo.example.com.key \ --cert=example_certs/foo.example.com.crt
TLS 証明書をゲートウェイに適用する
新しく作成した TLS 証明書をゲートウェイで使用する方法は 2 つあります。
マウントされた認証情報ありでデプロイする(推奨)
デフォルトの Ingress ゲートウェイ マニフェストをローカル ファイルにコピーします。
curl https://raw.githubusercontent.com/GoogleCloudPlatform/anthos-service-mesh-samples/main/docs/ingress-gateway-external-lb/ingress-gateway.yaml > ingress-gateway.yaml
ingress-gateway.yaml
のデプロイ仕様を変更して、TLS シークレット認証情報をマウントします。apiVersion: apps/v1 kind: Deployment ... spec: ... spec: ... volumeMounts: - name: foo-credential # Add new volume mount specifying mount path. mountPath: /etc/secrets/foo-credential readOnly: true volumes: - name: foo-credential # Point volume mount to the Kubernetes secret holding the TLS certificate and keys. secret: secretName: foo-credential
次に、Ingress ゲートウェイに関連するリソースを作成します。
kubectl --namespace ${CSM_INGRESSGATEWAY_NAMESPACE} apply --filename ingress-gateway.yaml
Ingress ゲートウェイを定義する
マウントされたシークレットを参照するポート 443 の HTTPS トラフィックを処理するゲートウェイ リソースを作成します。
cat <<EOF | kubectl apply -f - apiVersion: networking.istio.io/v1 kind: Gateway metadata: name: secure-gateway namespace: ${CSM_INGRESSGATEWAY_NAMESPACE} spec: selector: app: asm-ingressgateway istio: ingressgateway servers: - port: number: 443 name: https protocol: HTTPS tls: mode: SIMPLE serverCertificate: /etc/secrets/foo-credential/foo.example.com.crt privateKey: /etc/secrets/foo-credential/foo.example.com.key hosts: - "foo.example.com" EOF
マウントされた認証情報なしでデプロイする
Ingress ゲートウェイ マニフェスト ファイルを適用します。
kubectl --namespace ${CSM_INGRESSGATEWAY_NAMESPACE} apply --filename https://raw.githubusercontent.com/GoogleCloudPlatform/anthos-service-mesh-samples/main/docs/ingress-gateway-external-lb/ingress-gateway.yaml
予想される出力:
serviceaccount/asm-ingressgateway created role.rbac.authorization.k8s.io/asm-ingressgateway created rolebinding.rbac.authorization.k8s.io/asm-ingressgateway created deployment.apps/asm-ingressgateway created service/asm-ingressgateway created poddisruptionbudget.policy/asm-ingressgateway created horizontalpodautoscaler.autoscaling/asm-ingressgateway created
Ingress ゲートウェイを定義する
ポート 443 の HTTPS トラフィックを処理するゲートウェイ リソースを作成します。
cat <<EOF | kubectl apply -f - apiVersion: networking.istio.io/v1 kind: Gateway metadata: name: secure-gateway namespace: ${CSM_INGRESSGATEWAY_NAMESPACE} spec: selector: app: asm-ingressgateway istio: ingressgateway servers: - port: number: 443 name: https protocol: HTTPS tls: mode: SIMPLE credentialName: foo-credential hosts: - "foo.example.com" EOF
デプロイの最適化
認証情報がマウントされていないデプロイを使用する場合、Ingress ゲートウェイ Pod は認証情報が更新されているかどうかを定期的にチェックします。デフォルトでは、最大 60 分かかります。ポーリング頻度を変更するには、Ingress ゲートウェイ Pod のデプロイに CSM_MIN_K8S_SECRET_REFRESH_INTERVAL
環境変数と CSM_MAX_K8S_SECRET_REFRESH_INTERVAL
環境変数を設定します。
apiVersion: apps/v1
kind: Deployment
metadata:
name: asm-ingressgateway
...
spec:
...
template:
...
spec:
containers:
- name: istio-proxy
image: auto
env:
- name: CSM_MIN_K8S_SECRET_REFRESH_INTERVAL
value: "15m" # Half of the default minimum interval
- name: CSM_MAX_K8S_SECRET_REFRESH_INTERVAL
value: "30m" # Half of the default maximum interval
...
トラフィックをテストする
トラフィックを foo サービスにルーティングします。
トラフィックを foo デプロイに転送する VirtualService を定義します。
cat <<EOF | kubectl apply -f - apiVersion: networking.istio.io/v1 kind: VirtualService metadata: name: foo-routing namespace: ${CSM_INGRESSGATEWAY_NAMESPACE} spec: hosts: - "foo.example.com" gateways: - secure-gateway http: - match: - uri: prefix: /status - uri: prefix: /delay route: - destination: host: foo port: number: 8080 EOF
クラスタから Ingress ゲートウェイに接続するように外部ロードバランサを設定します。
安全な接続をテストします。
次の curl コマンドを使用して設定を確認します。
export EXTERNAL_LB_IP_ADDRESS=EXTERNAL_LB_IP_ADDRESS curl -v -H "Host: foo.example.com" --resolve "foo.example.com:443:$EXTERNAL_LB_IP_ADDRESS" \ --cacert example_certs/example.com.crt "https://foo.example.com:443/ping"
EXTERNAL_LB_IP_ADDRESS
は、外部ロードバランサの IP に置き換えます。出力は次のようになります。
{ "cluster_name": "gke-us", "host_header": "34.120.175.141", "pod_name": "whereami-deployment-954cbf78-mtlpf", "pod_name_emoji": "😎", "project_id": "my-project", "timestamp": "2021-11-29T17:01:59", "zone": "us-central1-b" }
次のステップ
- ゲートウェイのインストールとアップグレードの詳細を確認する