Implementasi referensi load balancing Lapisan 7 HAProxy

Google Distributed Cloud (GDC) dengan air gap menyediakan load balancer Lapisan 4 (L4) terkelola bawaan, tetapi banyak aplikasi perusahaan memerlukan kemampuan Lapisan 7 (L7) lanjutan, seperti pemilihan rute berbasis host, pengelolaan TLS terpusat, dan pemisahan traffic yang kompleks. Secara historis, hal ini dilakukan menggunakan Ingress API, yang kini dianggap sebagai fitur yang dibekukan dalam komunitas Kubernetes.

Arsitektur referensi ini menyediakan solusi load balancing Lapisan 7 yang dikelola sendiri. Dengan men-deploy pengontrol open source HAProxy yang populer di cluster standar GDC, pelanggan dapat merutekan traffic L7 dengan lancar ke lingkungan hybrid. Arsitektur ini menggunakan TLS Termination (HTTPRoute) untuk merutekan traffic berdasarkan Server Name Indication (SNI) ke pod dalam container bawaan dan aplikasi yang dihosting di Virtual Machine eksternal.

Arsitektur

Diagram arsitektur untuk load balancing Lapisan 7 HAProxy di GDC dengan air gap.

Komponen utama solusi ini meliputi:

  • Klien: Entity yang memulai permintaan HTTPS untuk berinteraksi dengan aplikasi.
  • Cluster standar GDC: GDC menyediakan cara bawaan untuk membuat Cluster Vanilla Kubernetes. Dalam solusi ini, cluster akan menghosting LB L7 dan pengontrolnya, beserta workload dan layanan headless untuk VM eksternal
  • Load Balancer L4 GDC: Load balancer L4 bawaan yang berfungsi sebagai titik entri, mendistribusikan traffic TCP/443 langsung ke Pod Kubernetes yang menjalankan pengontrol.
  • Ingress Controller: Operator HAProxy yang berjalan di cluster standar. Mereka memantau resource Ingress dan memperbarui proxy yang mendasarinya secara dinamis. HAProxy Ingress Controller akan digunakan dalam implementasi berikut
  • Ingress: Resource Kubernetes standar yang menentukan port pemantauan fisik (443) dan aturan pemilihan rute host berbasis SNI dengan Penghentian TLS.
  • Workload dalam Container (Pod): Deployment Kubernetes standar yang diekspos secara internal dengan Service Kubernetes reguler.
  • Workload Berbasis VM (Eksternal): Workload yang dihosting di VM eksternal di jaringan project, yang diekspos ke proxy menggunakan Service Kubernetes headless dan endpoint kustom yang berisi IP langsung VM.
  • Harbor Registry: Container Registry pribadi yang digunakan untuk menyimpan dan menyajikan image proxy dan aplikasi di lingkungan air-gapped.

Di cluster standar, Anda membuat tiga namespace:

  • Namespace load-balancer menghosting HAProxy Ingress Controller dan workload load balancer HAProxy:

    Resource namespace load balancer.

  • Namespace hello-app menghosting Deployment, Service, dan Ingress untuk workload container demo:

    Resource namespace hello-app.

  • Namespace vm-app menghosting layanan headless yang mengekspos IP VM eksternal, EndpointSlice yang mengarah ke IP eksternal, dan Ingress:

    Resource namespace vm-app.

Sebelum memulai

Sebelum men-deploy solusi ini, pastikan Anda telah memenuhi prasyarat berikut:

  • Software yang diperlukan: helm, docker, kubectl
  • Login CLI dan penyiapan lokal: Download gdcloud CLI dari konsol GDC dan siapkan lingkungan Anda secara lokal:

    export USER_NAME="USER_NAME"
    export PROJECT_ID="PROJECT_ID"
    export ZONE="ZONE"
    export ORG_NAME="ORG_NAME"
    export GDC_URL="GDC_URL"
    
    gdcloud components install gdcloud-k8s-auth-plugin
    
    gdcloud config set core/organization_console_url \
      https://console.$ORG_NAME.$ZONE.$GDC_URL
    gdcloud config set core/zone $ZONE
    gdcloud config set core/project ${PROJECT_ID}
    
    gdcloud auth login # use --login-config-cert option in case of TLS error
    
  • Penyiapan Project: Buat project di lingkungan GDC dengan air gap Anda untuk menyimpan resource:

    gdcloud projects create $PROJECT_ID
    
  • Peran IAM: Berikan peran Cluster Admin dan Standard Cluster Admin kepada pengguna Anda untuk mengelola resource Kubernetes, dan peran Harbor Instance Admin untuk mengirim image:

    # Grant standard cluster and cluster admin roles
    gdcloud projects add-iam-policy-binding ${PROJECT_ID} \
      --member="user:${USER_NAME}" \
      --role=cluster-admin
    
    gdcloud projects add-iam-policy-binding ${PROJECT_ID} \
      --member="user:${USER_NAME}" \
      --role=standard-cluster-admin
    
    # Grant Harbor instance admin role
    gdcloud projects add-iam-policy-binding ${PROJECT_ID} \
      --member="user:${USER_NAME}" \
      --role=harbor-instance-admin
    

Membuat cluster standar

Bagian ini memandu Anda dalam proses menyiapkan cluster Kubernetes standar dalam lingkungan GDC dengan air gap. Cluster standar menyediakan fondasi yang fleksibel dan andal untuk men-deploy berbagai workload, termasuk Pengontrol Ingress HAProxy, dan aplikasi kustom Anda. Langkah-langkah berikut akan memastikan cluster Anda dikonfigurasi dengan benar dan dapat diakses untuk deployment berikutnya.

  1. Identifikasi jenis image virtual machine yang tersedia dengan menjalankan:

    gdcloud compute machine-types list
    
  2. Pilih jenis mesin yang sesuai untuk worker node cluster Anda. Untuk tutorial ini, sebaiknya gunakan jenis mesin dengan minimal 4 vCPU.

    export MACHINE_TYPE="MACHINE_TYPE"
    
  3. Dapatkan kubeconfig server API pengelolaan dan tetapkan alias:

    export CLUSTER_NAME="CLUSTER_NAME"
    
    KUBECONFIG=kubeconfig-admin.yaml gdcloud clusters \
      get-credentials ${ORG_NAME}-admin
    
    alias km="kubectl --kubeconfig kubeconfig-admin.yaml"
    
  4. Buat cluster standar dengan dua worker node:

    km create -f - <<EOF
    apiVersion: cluster.gdc.goog/v1
    kind: Cluster
    metadata:
      name: ${CLUSTER_NAME}
      namespace: ${PROJECT_ID}
    spec:
      nodePools:
      - machineTypeName: ${MACHINE_TYPE}
        nodeCount: 2
        name: ${CLUSTER_NAME}-node-pool
    EOF
    

    Untuk mengetahui detail selengkapnya tentang opsi yang tersedia, lihat dokumentasi.

    Pembuatan cluster Standard dapat memerlukan waktu hingga 60 menit. Untuk memeriksa status, gunakan perintah berikut:

    km get clusters/${CLUSTER_NAME} \
      -n ${PROJECT_ID} \
      --watch
    

    Setelah cluster siap, output akan menampilkan status Running, seperti ini:

    NAME         STATE     K8S VERSION
    my-cluster   Running   1.30.12-gke.300
    
  5. Setelah cluster siap, ambil kredensialnya:

    KUBECONFIG=kubeconfig-${CLUSTER_NAME}.yaml gdcloud clusters \
      get-credentials ${CLUSTER_NAME} \
      --standard \
      --project ${PROJECT_ID} \
      --zone ${ZONE}
    
  6. Buat alias agar perintah kubectl lebih ringkas di bagian selanjutnya dalam panduan ini. Alias ini akan digunakan untuk berinteraksi dengan cluster standar:

    alias kk="kubectl --kubeconfig kubeconfig-${CLUSTER_NAME}.yaml"
    
  7. Buat namespace untuk pengontrol, aplikasi dalam container demo "hello-app", dan aplikasi demo berbasis VM:

    kk create namespace load-balancer
    kk create namespace hello-app
    kk create namespace vm-app
    

Membuat dan mengintegrasikan Harbor Registry

Harbor adalah registry image container dengan dukungan bawaan di GDC dengan air gap. Bagian ini memandu Anda melakukan langkah-langkah untuk mengintegrasikan Harbor Registry dengan cluster standar, termasuk mengonfigurasi kredensial dan secret untuk mengaktifkan pengambilan dan pengiriman image yang aman.

  1. Buat instance Harbor di project Anda.
  2. Buat project Harbor di instance Harbor Anda.
  3. Menetapkan variabel lingkungan:

    export HARBOR_INSTANCE_NAME="HARBOR_INSTANCE_NAME"
    export HARBOR_INSTANCE_URL="HARBOR_INSTANCE_URL"
    export HARBOR_PROJECT="HARBOR_PROJECT"
    export IMAGE_PULL_SECRET_NAME="harbor-secret"
    
  4. Login ke instance Harbor menggunakan akun robot:

    docker --config=./docker login ${HARBOR_INSTANCE_URL}
    
  5. Buat secret di cluster standar:

    kk create secret docker-registry ${IMAGE_PULL_SECRET_NAME} \
      --from-file=.dockerconfigjson=./docker/config.json \
      -n load-balancer
    
    kk create secret docker-registry ${IMAGE_PULL_SECRET_NAME} \
      --from-file=.dockerconfigjson=./docker/config.json \
      -n hello-app
    

Men-deploy aplikasi demo dalam container

Bagian ini menjelaskan deployment aplikasi dalam container demo (hello-app) dalam cluster Kubernetes GDC dengan air gap Anda. Anda akan membuat resource Deployment dan Service Kubernetes yang diperlukan untuk menjalankan hello-app dan mengeksposnya secara internal dalam cluster, sehingga menyiapkannya untuk akses menggunakan load balancer L7.

  1. Upload contoh image untuk aplikasi dalam container demo ke Harbor:

    docker pull gcr.io/google-samples/hello-app:1.0 \
      --platform linux/amd64
    docker tag gcr.io/google-samples/hello-app:1.0 \
      ${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/hello-app:1.0
    docker --config=./docker push \
      ${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/hello-app:1.0
    
  2. Deploy manifes berikut di cluster standar:

    cat << EOF > hello-app.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: hello-app
      namespace: hello-app
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: hello-app
      template:
        metadata:
          labels:
            app: hello-app
        spec:
          containers:
          - name: hello-server
            image: ${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/hello-app:1.0
            ports:
            - containerPort: 8080
          imagePullSecrets:
          - name: ${IMAGE_PULL_SECRET_NAME}
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: hello-app
      namespace: hello-app
    spec:
      type: ClusterIP
      selector:
        app: hello-app
      ports:
        - protocol: TCP
          port: 80
          targetPort: 8080
    EOF
    
    kk apply -f hello-app.yaml
    

Kemudian, pastikan deployment dan layanan ada di sana

kk get svc,deploy -n hello-app

Men-deploy aplikasi demo di VM

Bagian ini menjelaskan deployment aplikasi demo dalam virtual machine (VM) di luar cluster Kubernetes Anda. Dengan menyiapkan server HTTP di VM, Anda akan menyimulasikan aplikasi eksternal yang dapat diekspos oleh load balancer, yang menunjukkan kemampuannya untuk mengelola traffic ke resource di dalam dan di luar cluster.

Pertama, buat VM untuk aplikasi demo:

  1. Buka konsol GDC di browser web Anda.
  2. Pilih project yang sama dengan tempat Anda membuat cluster Kubernetes standar.
  3. Buka menu, lalu klik Virtual machines.
  4. Klik Create Instance.
  5. Beri nama VM vm-workload. Image 2 vCPU sudah cukup untuk contoh ini.
  6. Untuk boot disk image, pilih distribusi Ubuntu 22.04, yang dilengkapi dengan Python yang telah diinstal sebelumnya.
  7. Klik Create.
  8. Tunggu beberapa menit hingga VM siap.
  9. Buat koneksi SSH ke VM:
    1. Di konsol GDC, klik VM.
    2. Klik Connect with SSH.

Setelah Anda terhubung ke konsol SSH, jalankan perintah berikut:

mkdir ~/simple-server
cd ~/simple-server
echo 'Welcome to my VM!' > index.html
python3 -m http.server --bind 0.0.0.0 8080 &

Untuk merutekan traffic ke VM, buat Service headless (tanpa pemilih). Alamat ini akan dipetakan secara manual ke alamat IP internal VM menggunakan resource EndpointSlice.

kk apply -f - <<EOF
apiVersion: v1
kind: Service
metadata:
  name: vm-app-svc
  namespace: vm-app
spec:
  ports:
  - protocol: TCP
    port: 443
    targetPort: 443
EOF

Dapatkan alamat IP VM vm-workload dengan menjalankan

gdcloud compute instances list --project ${PROJECT_ID} \
  | grep workload-vm | awk '{print $3}'

Output-nya adalah alamat IP VM yang akan diperlukan untuk menyiapkan resource EndpointSlice.

Buat resource EndpointSlice yang akan terhubung ke Service tanpa pemilih VM-app dan alamatkan IP VM yang akan menjadi tujuan perutean traffic.

apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
  name: vm-app-endpoints
  namespace: vm-app
  labels:
    kubernetes.io/service-name: vm-app-svc
addressType: IPv4
ports:
  - port: 8080
endpoints:
  - addresses:
    - "VM_IP"
    conditions:
      ready: true

Membuat sertifikat yang ditandatangani sendiri

Bagian ini memandu Anda melalui proses pembuatan sertifikat TLS dan secret Kubernetes untuk mengamankan komunikasi bagi aplikasi berbasis container dan berbasis VM Anda. Panduan ini menggunakan sertifikat yang ditandatangani sendiri untuk memudahkan, tetapi di lingkungan produksi, Anda harus menggunakan sertifikat tingkat produksi, seperti yang dijelaskan dalam Opsional: Menggunakan sertifikat siap produksi. Pilih nama domain sampel arbitrer untuk aplikasi ini. Dengan membuat koneksi yang aman, Anda memastikan integritas dan kerahasiaan data bagi klien yang mengakses aplikasi Anda melalui HAProxy Ingress Controller.

Untuk aplikasi dalam container, kita membuat sertifikat yang ditandatangani sendiri dan menyimpannya sebagai secret di namespace load balancer. Ini akan digunakan untuk TLS saat meminta k8s-app.example.com

openssl req -x509 -newkey rsa:2048 -nodes \
  -keyout tls-containerized.key \
  -out tls-containerized.crt \
  -subj "/CN=k8s-app.example.com" \
  -days 365

kk create secret tls tls-containerized \
  --namespace load-balancer \
  --key tls-containerized.key \
  --cert tls-containerized.crt

kk create secret tls tls-containerized \
  --namespace hello-app \
  --key tls-containerized.key \
  --cert tls-containerized.crt

Untuk aplikasi VM, sertifikat yang ditandatangani sendiri yang serupa akan diterbitkan dan disimpan. Sertifikat ini akan digunakan untuk TLS saat meminta vm-app.example.com

openssl req -x509 -newkey rsa:2048 -nodes \
  -keyout tls-vm.key \
  -out tls-vm.crt \
  -subj "/CN=vm-app.example.com" \
  -days 365

kk create secret tls tls-vm \
  --namespace load-balancer \
  --key tls-vm.key \
  --cert tls-vm.crt

kk create secret tls tls-vm \
  --namespace vm-app \
  --key tls-vm.key \
  --cert tls-vm.crt

Men-deploy HAProxy

Menginstal pengontrol Ingress HAProxy dan LB L4

export HAPROXY_VERSION=3.1.14

# pull the HAProxy Ingress Controller image and push it to Harbor
docker pull haproxytech/kubernetes-ingress:${HAPROXY_VERSION} \
  --platform linux/amd64
docker tag haproxytech/kubernetes-ingress:${HAPROXY_VERSION} \
  ${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/haproxy-ingress:${HAPROXY_VERSION}
docker --config=./docker push \
  ${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/haproxy-ingress:${HAPROXY_VERSION}

# Get Helm repo
helm repo add haproxytech https://haproxytech.github.io/helm-charts
helm repo update

# Install the Ingress Controller with helm
helm upgrade --install haproxy-kubernetes-ingress \
  haproxytech/kubernetes-ingress \
  --kubeconfig kubeconfig-${CLUSTER_NAME}.yaml \
  --namespace load-balancer \
  --set controller.image.repository=${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/haproxy-ingress \
  --set controller.image.tag=${HAPROXY_VERSION} \
  --set controller.existingImagePullSecret=${IMAGE_PULL_SECRET_NAME} \
  --set controller.service.type=LoadBalancer \
  --set-json \
  controller.service.annotations='{"networking.gke.io/load-balancer-type": "internal"}'

Pengontrol Ingress HAProxy mendapatkan alamat IP virtual unik untuk akses klien menggunakan layanan jenis LoadBalancer. Layanan ini menyiapkan load balancer Lapisan 4 yang terkelola sepenuhnya. Untuk memudahkan panduan ini, load balancer internal dibuat dengan menetapkan anotasi load-balancer-type ke internal. Menghilangkan anotasi ini akan menghasilkan load balancer eksternal. Deployment Kubernetes menarik image dengan aman dari Harbor menggunakan secret yang disediakan (${IMAGE_PULL_SECRET_NAME}), yang berisi kredensial akun robot Harbor.

Memvalidasi penginstalan pengontrol Ingress HAProxy

Pastikan pod HAProxy Ingress Controller berjalan dan siap:

kk get pods -n load-balancer

Outputnya akan terlihat seperti berikut ini:

NAME                                          READY   STATUS      RESTARTS   AGE
haproxy-kubernetes-ingress-78dc9c8676-f8fcb   1/1     Running     0          35s
haproxy-kubernetes-ingress-78dc9c8676-lfnr2   1/1     Running     0          65s
haproxy-kubernetes-ingress-crdjob-3-tgj2h     0/1     Completed   0          65s

Pastikan layanan HAProxy Ingress Controller telah dibuat dan dikonfigurasi:

kk get services -n load-balancer

Outputnya akan terlihat mirip seperti berikut:

NAME                         TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)                                                                  AGE
haproxy-kubernetes-ingress   LoadBalancer   10.252.27.46   10.252.4.17   80:32023/TCP,443:31103/TCP,443:31103/UDP,1024:30146/TCP,6060:30718/TCP   10m

Menentukan resource Ingress untuk aplikasi demo

Buat resource Ingress yang akan menghubungkan HAProxy ke Service aplikasi dalam container

cat << EOF > hello-app-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: hello-app-ingress
  namespace: hello-app
  annotations:
    haproxy.org/ssl-redirect: "true"
    haproxy.org/ssl-redirect-port: "443"
    haproxy.org/ssl-redirect-code: "308"
spec:
  ingressClassName: haproxy
  tls:
  - hosts:
    - "k8s-app.example.com"
    secretName: tls-containerized
  rules:
  - host: "k8s-app.example.com"
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: hello-app
            port:
              number: 80
EOF

kk apply -f hello-app-ingress.yaml

Buat resource Ingress yang akan terhubung ke Service tanpa pemilih VM-app dan alamatkan IP VM yang akan menerima traffic.

cat << EOF > vm-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: vm-app-ingress
  namespace: vm-app
  annotations:
    haproxy.org/ssl-redirect: "true"
    haproxy.org/ssl-redirect-port: "443"
    haproxy.org/ssl-redirect-code: "308"
spec:
  ingressClassName: haproxy
  tls:
  - hosts:
    - "vm-app.example.com"
    secretName: tls-vm
  rules:
  - host: "vm-app.example.com"
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: vm-app-svc
            port:
              number: 443
EOF

kk apply -f vm-ingress.yaml

Mengambil alamat IP load balancer

Jalankan perintah untuk mendapatkan alamat IP load balancer.

kk get services/haproxy-kubernetes-ingress \
  -n load-balancer \
  -o jsonpath='{.status.loadBalancer.ingress[0].ip}'

Hal ini akan diperlukan saat memverifikasi akses ke aplikasi. Ini akan disebut sebagai LOAD_BALANCER_IP.

Membuat VM klien

Ikuti langkah-langkah untuk membuat VM klien:

  1. Buka konsol GDC di browser web Anda.
  2. Buka menu, lalu klik Virtual machines.
  3. Klik Create Instance.
  4. Buat VM bernama client, pilih jenis mesin kecil, dan pilih Rocky Linux atau Ubuntu, yang dilengkapi dengan curl yang telah diinstal sebelumnya.
  5. Klik Create.
  6. Tunggu beberapa menit hingga VM siap.
  7. Setelah VM siap, buat koneksi SSH dengan VM:
    1. Di konsol GDC, klik VM.
    2. Klik Connect with SSH.

Memverifikasi akses dan perutean

Untuk menguji pemilihan rute, jalankan perintah curl dari VM klien Anda. Anda dapat terhubung ke kedua aplikasi menggunakan nama host yang ditentukan dengan alamat IP load balancer.

Dengan meneruskan flag --resolve di curl, Anda dapat memaksa nama domain untuk me-resolve ke IP Load Balancer L4 GDC dengan air gap. Perhatikan bahwa kita meneruskan flag -k untuk memercayai sertifikat yang ditandatangani sendiri.

Uji aplikasi dalam container Kubernetes:

curl -k --resolve k8s-app.example.com:443:$LOAD_BALANCER_IP https://k8s-app.example.com -v

Uji aplikasi VM eksternal:

curl -k --resolve vm-app.example.com:443:$LOAD_BALANCER_IP https://vm-app.example.com -v

Jika dikonfigurasi dengan benar, pengontrol Ingress akan berfungsi dengan lancar sebagai TLS terminator dan meneruskan traffic ke tujuan.

Opsional: Menggunakan sertifikat siap produksi

Bagian ini membahas cara memanfaatkan CA Service GDC dengan air gap untuk membuat Root Certificate Authority (CA) pribadi, menerbitkan sertifikat yang ditandatangani untuk workload Anda, serta mengamankan update cluster standar dan VM klien GDC dengan air gap Anda.

Bagian ini menguraikan cara menggunakan CA Service GDC dengan air gap untuk membuat Root Certificate Authority (CA) pribadi dan menerbitkan sertifikat yang valid untuk aplikasi Anda. Dengan menginstal Root CA ini di VM klien, Anda dapat memverifikasi bahwa TLS termination berfungsi lancar dengan sertifikat tepercaya, tanpa perlu mengabaikan peringatan SSL (misalnya, menggunakan curl -k).

Memberikan izin yang diperlukan dan mendapatkan kredensial

Untuk mengelola CA Service dan menerbitkan sertifikat, pengguna Anda memerlukan peran IAM yang sesuai dalam project.

  1. Berikan peran certificate-authority-service-admin dan certificate-requester:

    gdcloud projects add-iam-policy-binding ${PROJECT_ID} \
      --member=user:${USER_NAME} \
      --role=certificate-authority-service-admin
    
    gdcloud projects add-iam-policy-binding ${PROJECT_ID} \
      --member=user:${USER_NAME} \
      --role=certificate-requester
    
  2. Dapatkan kredensial server API pengelolaan:

    gdcloud clusters get-credentials ${ORG_NAME}-admin
    

Membuat root CA

Anda akan membuat Certificate Authority di server API pengelolaan dalam namespace project Anda.

  1. Terapkan resource CertificateAuthority:

    km apply -f - <<EOF
    apiVersion: pki.security.gdc.goog/v1
    kind: CertificateAuthority
    metadata:
      name: my-root-ca
      namespace: ${PROJECT_ID}
    spec:
      caProfile:
        commonName: "My Root CA"
        duration: 87600h # 10 years
        keyAlgorithm: RSA_2048
        maxChainLength: 1
      caType: ROOT
      keyLocation: HSM
      rotationPolicy:
        cronTime: 0 0 1 1 *
    EOF
    
    km -n ${PROJECT_ID} get \
    certificateauthority.pki.security.gdc.goog/my-root-ca -ojson \
    | jq -r '
    .status.conditions[] | select( .type as $id | "Ready" | index($id)) .status'
    

Menerbitkan dan men-deploy sertifikat

Setelah CA siap, Anda akan meminta sertifikat untuk aplikasi dalam container dan aplikasi berbasis VM. Permintaan ini terjadi di server API pengelolaan, dan kunci yang dihasilkan harus dipindahkan ke cluster standar Anda.

Buat permintaan untuk kedua domain:

km apply -f - <<EOF
apiVersion: pki.security.gdc.goog/v1
kind: CertificateRequest
metadata:
  name: tls-containerized-req
  namespace: ${PROJECT_ID}
spec:
  certificateAuthorityRef:
    name: my-root-ca
    namespace: ${PROJECT_ID}
  certificateConfig:
    subjectConfig:
      commonName: "k8s-app.example.com"
      dnsNames:
      - "k8s-app.example.com"
  signedCertificateSecret: tls-containerized-signed
---
apiVersion: pki.security.gdc.goog/v1
kind: CertificateRequest
metadata:
  name: tls-vm-req
  namespace: ${PROJECT_ID}
spec:
  certificateAuthorityRef:
    name: my-root-ca
    namespace: ${PROJECT_ID}
  certificateConfig:
    subjectConfig:
      commonName: "vm-app.example.com"
      dnsNames:
      - "vm-app.example.com"
  signedCertificateSecret: tls-vm-signed
EOF

Tunggu beberapa saat hingga sertifikat diterbitkan. Anda dapat memverifikasi bahwa cluster tersebut siap saat kondisi Ready bernilai True:

km get certificaterequests -n ${PROJECT_ID}

Mengupdate cluster standar

Jika Anda mengikuti bagian sebelumnya dari panduan ini, Anda memiliki secret yang ditandatangani sendiri di cluster standar. Anda harus menghapusnya sebelum membuat versi baru yang ditandatangani:

kk delete secret tls-containerized -n load-balancer
kk delete secret tls-vm -n load-balancer

kk delete secret tls-containerized -n hello-app
kk delete secret tls-vm -n vm-app

Sekarang, ekstrak sertifikat yang ditandatangani dari server API pengelolaan dan buat secret baru di cluster standar.

km get secret -n ${PROJECT_ID} tls-containerized-signed \
  -o jsonpath='{.data.tls\.crt}' \
  | base64 -d > tls-containerized.crt

km get secret -n ${PROJECT_ID} tls-containerized-signed \
  -o jsonpath='{.data.tls\.key}' \
  | base64 -d > tls-containerized.key

kk create secret tls tls-containerized \
  --namespace load-balancer \
  --key tls-containerized.key \
  --cert tls-containerized.crt

kk create secret tls tls-containerized \
  --namespace hello-app \
  --key tls-containerized.key \
  --cert tls-containerized.crt

km get secret -n ${PROJECT_ID} tls-vm-signed \
  -o jsonpath='{.data.tls\.crt}' \
  | base64 -d > tls-vm.crt

km get secret -n ${PROJECT_ID} tls-vm-signed \
  -o jsonpath='{.data.tls\.key}' \
  | base64 -d > tls-vm.key

kk create secret tls tls-vm \
  --namespace load-balancer \
  --key tls-vm.key \
  --cert tls-vm.crt

kk create secret tls tls-vm \
  --namespace vm-app \
  --key tls-vm.key \
  --cert tls-vm.crt

Secret baru akan diperoleh secara otomatis dan dimuat ulang oleh load balancer.

Mengonfigurasi kepercayaan klien

Untuk memverifikasi penyiapan, Anda harus memberi tahu VM klien untuk memercayai root CA baru Anda.

Ekstrak sertifikat CA root ke file:

km get secret -n ${PROJECT_ID} my-root-ca-secret \
  -o jsonpath='{.data.tls\.crt}' \
  | base64 -d > my-root-ca.crt

Transfer sertifikat ke VM klien Anda. (Anda dapat menyalin konten my-root-ca.crt dan menempelkannya ke file di VM klien).

Di VM klien, update trust store.

Jika VM client adalah Ubuntu:

sudo cp my-root-ca.crt /usr/local/share/ca-certificates/
sudo chmod 644 /usr/local/share/ca-certificates/my-root-ca.crt
sudo update-ca-certificates

Jika VM client adalah Rocky Linux:

sudo cp my-root-ca.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust

Memverifikasi akses

Anda kini dapat mengakses aplikasi menggunakan curl tanpa flag -k. Koneksi akan sepenuhnya dipercaya.

Menguji Aplikasi dalam container k8s:

curl -v --resolve k8s-app.example.com:443:LOAD_BALANDER_IP https://k8s-app.example.com

Menguji Aplikasi VM:

curl -v --resolve vm.example.com:443:LOAD_BALANDER_IP https://vm-app.example.com

Jika berhasil, Anda akan langsung melihat output aplikasi tanpa peringatan sertifikat SSL.