Menyiapkan penghentian TLS di gateway masuk

Ringkasan

Halaman ini menunjukkan cara menyiapkan penghentian TLS di gateway masuk di Cloud Service Mesh untuk mengelola traffic HTTPS eksternal ke layanan Anda. Untuk pengantar yang lebih mendasar tentang cara menyiapkan gateway, lihat panduan gateway. Anda akan mempelajari cara mengonfigurasi gateway untuk komunikasi aman menggunakan TLS, yang memungkinkan akses terenkripsi ke aplikasi Anda. Proses ini memanfaatkan kemampuan Cloud Service Mesh untuk mengekspos layanan dengan aman.

Sebelum memulai

Anda memerlukan resource berikut untuk menyelesaikan langkah-langkah dalam dokumen ini:

  • Cluster Kubernetes dengan Cloud Service Mesh terinstal. Lihat panduan penginstalan untuk mengetahui detail tentang cara menginstal Cloud Service Mesh.

Menyiapkan lingkungan Anda

Jalankan perintah berikut dari workstation yang dapat mengakses cluster yang ingin Anda gunakan. Pastikan alat kubectl dikonfigurasi untuk menggunakan konteks cluster khusus untuk cluster Anda.

  1. Tetapkan variabel lingkungan.

    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
    
  2. Deploy aplikasi foo di cluster Anda. Instal dengan yaml berikut:

    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
    
  3. Buat sertifikat dan kunci.

    Untuk mengamankan gateway masuk, Anda memerlukan kunci dan sertifikat TLS. Anda dapat menggunakan alat pembuatan sertifikat apa pun atau mengikuti langkah-langkah ini menggunakan openssl untuk membuat kredensial yang diperlukan.

    • Membuat sertifikat dan kunci CA root
    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
    
    • Membuat sertifikat dan kunci untuk 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
    

Menyiapkan gateway traffic masuk TLS

Langkah-langkah berikut menjelaskan cara menyiapkan gateway traffic masuk TLS.

Menyimpan sertifikat TLS

  1. Buat namespace. Namespace ini digunakan untuk men-deploy gateway entrance.

    kubectl create namespace ${CSM_INGRESSGATEWAY_NAMESPACE}
    
  2. Terapkan label injeksi default ke namespace:

    kubectl label namespace ${CSM_INGRESSGATEWAY_NAMESPACE} \
        istio.io/rev- istio-injection=enabled --overwrite
    
  3. Simpan kredensial TLS di secret Kubernetes:

    kubectl create -n ${CSM_INGRESSGATEWAY_NAMESPACE} secret tls foo-credential \
      --key=example_certs/foo.example.com.key \
      --cert=example_certs/foo.example.com.crt
    

Menerapkan sertifikat TLS ke gateway

Ada dua cara untuk membuat gateway menggunakan sertifikat TLS yang baru dibuat.

Deployment dengan kredensial yang dipasang (Direkomendasikan)

  1. Salin manifes gateway ingress default ke file lokal.

    curl https://raw.githubusercontent.com/GoogleCloudPlatform/anthos-service-mesh-samples/main/docs/ingress-gateway-external-lb/ingress-gateway.yaml > ingress-gateway.yaml
    
  2. Ubah spesifikasi deployment di ingress-gateway.yaml untuk memasang kredensial secret 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
    

    Kemudian, buat resource yang terkait dengan gateway masuk.

    kubectl --namespace ${CSM_INGRESSGATEWAY_NAMESPACE} apply --filename ingress-gateway.yaml 
    
  3. Tentukan gateway masuk.

    Buat resource Gateway untuk menangani traffic HTTPS di port 443 yang mereferensikan secret yang dipasang:

    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
    

Deployment tanpa kredensial yang terpasang

  1. Terapkan file manifes gateway masuk.

    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
    

    Output yang diharapkan:

    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
    
  2. Tentukan gateway masuk.

    Buat resource Gateway untuk menangani traffic HTTPS di port 443:

    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
    

Traffic Pengujian

  1. Rutekan traffic ke layanan foo.

    Tentukan VirtualService untuk mengarahkan traffic ke deployment foo:

    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
    
  2. Siapkan load balancer eksternal untuk terhubung dengan gateway traffic masuk dari cluster.

  3. Uji koneksi aman.

    Gunakan perintah curl berikut untuk memverifikasi penyiapan:

    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"
    

    Ganti EXTERNAL_LB_IP_ADDRESS dengan ip load balancer eksternal.

    Outputnya mirip dengan hal berikut ini:

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

Langkah berikutnya