在 Kubernetes 中建立部署作業,並啟用 TLS 加密

Spanner Omni 會使用 TLS 1.3,加密用戶端與伺服器之間,以及 Spanner Omni 伺服器之間傳輸的資料。Spanner Omni 提供 mTLS,可強化安全性,雙方在交換任何資料前,都會先驗證彼此的身分。如果使用加密,伺服器必須透過 mTLS 通訊。您可以選擇用戶端和伺服器是否也使用 mTLS。

事前準備

請確認您符合下列規定:

  • 建立 Kubernetes 叢集。這項設定支援 Google Kubernetes Engine (GKE) 和 Amazon Elastic Kubernetes Service (Amazon EKS)。您可能需要自訂設定,才能在其他環境中運作。

  • 確認 Kubernetes 叢集可以存取託管 Spanner Omni 容器的 Artifact Registry 構件。

  • 安裝及設定 kubectl 指令列工具和 Helm。

  • 如果您在 vSphere 虛擬化平台機器上設定 Kubernetes 環境,請在虛擬機器的 .vmx 設定檔中新增 monitor_control.virtual_rdtsc = FALSE,停用時間戳記計數器 (TSC) 虛擬化功能。確保 TrueTime 正常運作。

  • 確認環境符合 Spanner Omni 系統需求。

步驟 1:產生憑證

您必須建立三組憑證:

  • API 憑證:用於保護 Spanner Omni API 伺服器。

  • 伺服器憑證:有助於保護伺服器之間的通訊。

  • 用戶端憑證:使用者或應用程式會使用這些憑證,建立身分並與 Spanner Omni 伺服器建立信任關係。

這些憑證由憑證授權單位 (CA) 核發。Spanner Omni 提供工具,可建立自行簽署的 CA 和所有三種憑證。

請在其中一部機器上執行下列步驟。這些步驟假設命名空間為 spanner-ns。請將這個值變更為您要在部署作業中使用的命名空間。

您可以使用 Spanner Omni CLI,在工作站上建立這些憑證。

1. 建立憑證授權單位 (CA)

所有憑證均由憑證授權單位 (CA) 核發。貴機構可能會有中央 CA,您也可以使用公開 CA。雖然所有憑證都可以使用相同的 CA,但 API 憑證和用戶端憑證必須使用相同的 CA。

Spanner Omni 可讓您建立私人 CA。

./google/spanner/bin/spanner certificates create-ca --ca-certificate-directory=certs

create-ca 指令會在 certs 目錄中產生 CA 憑證。您可以複製這個憑證,做為 API 憑證的 CA,或建立其他 CA。建立憑證時,請務必使用正確的 CA。

cp certs/ca.crt certs/ca-api.crt

$HOME/.spanner/private-keys 目錄包含 CA 的私密金鑰。請務必備份並保護這個目錄。只要使用者能存取私密金鑰,就能簽署任何憑證,而信任自行簽署 CA 的用戶端也會信任這些憑證。您也可以視需要為 API 憑證建立額外的 CA (或使用外部信任的 CA)。本文對所有類型的憑證使用相同的 CA。

2. 產生伺服器憑證

您必須產生兩種伺服器憑證:

  • API 憑證:使用這個憑證,加密與部署項目互動的系統通訊。

  • Spanner 伺服器憑證:Spanner Omni 伺服器會使用這項憑證,加密彼此之間的通訊。

這項設定可讓您靈活管理這些憑證。例如,您可以使用憑證輪替功能。

建立 Spanner 伺服器憑證

執行下列指令,建立伺服器憑證:

# Comma-separate names of the Spanner servers; wildcards are supported.
SERVER_NAMES=*.pod.NAMESPACE
./google/spanner/bin/spanner certificates create-server --hostnames=${SERVER_NAMES} --ca-certificate-directory certs --output-directory certs

這個指令會在 certs 目錄中建立 server.crt 和 server.key。

建立 API 憑證

如要建立 API 憑證,請執行下列指令:

OMNI_ENDPOINT=spanner.NAMESPACE
./google/spanner/bin/spanner certificates create-server --filename-prefix=api --hostnames=${OMNI_ENDPOINT} --ca-certificate-directory certs --output-directory certs

這個指令會在 certs 目錄中建立 api.crt 和 api.key。如有需要,請使用外部信任的 CA 取得 API 憑證。

3. 產生用戶端憑證

您可以使用用戶端憑證驗證使用者和應用程式。用戶端憑證可在用戶端和伺服器之間啟用 mTLS。如果不打算使用 mTLS,可以略過這個步驟。

簽署 API 憑證的 CA 必須簽署用戶端憑證,且憑證中必須包含授權使用者名稱。在本範例中,請使用 admin 使用者,這是每個新資料庫的預設使用者。詳情請參閱「Spanner Omni 的驗證與授權」。

USERNAME=admin
./google/spanner/bin/spanner certificates create-client $USERNAME --output-directory clientcerts --ca-certificate-directory certs

這個指令會在 clientcerts 目錄中建立 client.crt 和 client.key。將這些檔案傳送至任何連線至部署作業的機器。

如果您打算搭配 Java 用戶端程式庫使用用戶端憑證,則必須產生 PKCS#8 格式的憑證金鑰。使用下列指令:

USERNAME=admin
./google/spanner/bin/spanner certificates create-client $USERNAME --output-directory clientcerts --ca-certificate-directory certs --generate-pkcs8-key

4. 產生包裝函式金鑰組

Spanner Omni 會使用掛接在每個伺服器 Pod /spanner/kms/wrapper_key 的金鑰加密金鑰 (KEK) 包裝函式金鑰組,加密內部金鑰,例如權杖加密和簽署金鑰。

如要使用 spanner keys create-keyset 產生新的包裝函式金鑰組檔案,請執行下列指令:

./google/spanner/bin/spanner keys create-keyset --output-file=kms/wrapper_key

根據預設,spanner keys create-keyset 會產生 AES256_GCM 金鑰。如要產生其他類型的金鑰,請使用 --key-template 旗標,並搭配下列其中一個金鑰類型值:AES256_GCM、AES128_GCM、AES256_GCM_RAW、CHACHA20_POLY1305 或 XCHACHA20_POLY1305。

步驟 2:將憑證、包裝函式金鑰組和管理員密碼推送至 Kubernetes 叢集

執行下列指令,建立命名空間,並將憑證、包裝函式金鑰集和管理員密碼推送至 Kubernetes 叢集:

  1. 建立命名空間:

    kubectl create namespace NAMESPACE
    
  2. 將 TLS 憑證推送至 Secret:

    kubectl create secret generic tls-certs \
      --from-file=ca.crt="certs/ca.crt" \
      --from-file=ca-api.crt="certs/ca-api.crt" \
      --from-file=server.crt="certs/server.crt" \
      --from-file=server.key="certs/server.key" \
      --from-file=api.crt="certs/api.crt" \
      --from-file=api.key="certs/api.key" \
      -n NAMESPACE
    
  3. 將包裝函式金鑰組推送至密鑰 (wrapper-key),該密鑰會掛接在每個伺服器 Pod 的 /spanner/kms:

    kubectl create secret generic wrapper-key \
      --from-file=wrapper_key="kms/wrapper_key" \
      -n NAMESPACE
    
  4. 建立密碼檔案,其中包含預設 admin 使用者的密碼,並設定受限制權限 (只有擁有者可讀取,權限 600):

    printf '%s' 'PASSWORD' > admin_password.txt
    chmod 600 admin_password.txt
    

    密碼必須符合下列規定:

    • 長度介於 8 到 32 個半形字元。
    • 至少一個大寫字元。
    • 至少一個小寫字元。
    • 至少一個數字。
    • 至少一個特殊字元。
  5. 建立管理員密碼的密鑰:

    kubectl create secret generic spanner-admin-password \
      --from-file=password=admin_password.txt \
      -n NAMESPACE
    

步驟 3:建立採用 TLS 加密的部署作業

請按照下列步驟,建立採用 TLS 加密機制的部署作業。

1. 準備 Helm 設定

請參閱「建立 Helm 圖表設定」,並為環境建立部署設定。

如要啟用 TLS 並設定管理員密碼,請在 Helm 圖表設定中設定下列值:

# Enables TLS
global:
  insecureMode: false

# Enables client certificate authentication (mTLS)
deployment:
  enableClientCertificateAuthentication: true
  # Name of the secret containing the administrator password
  adminPasswordSecret: spanner-admin-password

2. 建立部署作業

執行下列指令來建立 Deployment:

kubectl create ns monitoring

helm upgrade --install spanner-omni oci://us-docker.pkg.dev/spanner-omni/charts/spanner-omni \
  --version VERSION \
  --set global.platform=gke \
  --set global.insecureMode=false \
  --set deployment.enableClientCertificateAuthentication=true \
  --set deployment.adminPasswordSecret=spanner-admin-password \
  --namespace NAMESPACE \
  --set monitoring.enabled=true

這個指令會觸發啟動工作。您可以查看這項工作的記錄,追蹤進度:

kubectl logs -n NAMESPACE -l app.kubernetes.io/component=bootstrap -f

輸出內容會顯示進度。完成後,畫面會顯示「Deployment created successfully」(已成功建立部署作業) 訊息。

3. 檢查 Pod 狀態

執行下列指令,確認 Pod 狀態:

kubectl get pods --watch --namespace NAMESPACE

所有 Pod 都處於 READY 狀態。

4. 使用負載平衡器詳細資料更新憑證和部署作業

如要讓用戶端從 Kubernetes 叢集外部連線,就必須執行這個步驟。

# Get the service details
kubectl get service spanner -n NAMESPACE

# The EXTERNAL-IP:PORT is the API or deployment endpoint for your deployment.
# Update the API certificate with these details.
OMNI_ENDPOINT=EXTERNAL_IP,spanner.NAMESPACE.svc
./google/spanner/bin/spanner certificates update \
    --certificate-file=certs/api.crt \
    --certificate-key-file=certs/api.key \
    --hostnames=${OMNI_ENDPOINT} \
    --ca-certificate-directory=certs

# Update the secrets in Kubernetes
kubectl patch secret tls-certs -n NAMESPACE -p "{\"data\":{\"api.crt\":\"$(base64 -w 0 certs/api.crt)\"}}"

步驟 4:與 Spanner Omni 互動

您可以使用 Spanner Omni CLI,從任何 VM 與 Spanner Omni 部署項目互動。

如果您為用戶端啟用了 mTLS,請在每個指令中使用下列旗標:

  • --client-certificate-directory=CLIENT_CERTIFICATE_DIRECTORY

  • --ca-certificate-file=API_CA_CERT_FILE_PATH

1. 登入 Spanner Omni (選用)

登入 Spanner Omni (如果使用用戶端憑證,則可略過這個步驟):

./google/spanner/bin/spanner auth login admin \
    --ca-certificate-file=certs/ca-api.crt \
    --deployment-endpoint=DEPLOYMENT_ENDPOINT

系統提示時,請輸入在 admin_password.txt 設定的密碼。

Successfully logged in as "admin"

2. 建立資料庫

執行下列指令來建立資料庫:

./google/spanner/bin/spanner --deployment-endpoint=DEPLOYMENT_ENDPOINT databases create DATABASE_NAME --ca-certificate-file=certs/ca-api.crt --client-certificate-directory=clientcerts

3. 開啟 SQL Shell

執行下列指令,開啟殼層:

./google/spanner/bin/spanner sql --database=DATABASE_NAME --deployment-endpoint=DEPLOYMENT_ENDPOINT --ca-certificate-file=certs/ca-api.crt --client-certificate-directory=clientcerts

4. 建立資料表並新增資料

執行下列 SQL 指令:

spanner> CREATE TABLE names (nameId INT64 NOT NULL, name String(100)) PRIMARY KEY (nameId);
Query OK, 0 rows affected (4.62 sec)

spanner> INSERT names (nameId, name) VALUES (1, "Jack");
Query OK, 1 rows affected (0.18 sec)

5. 驗證 Deployment

如要列出資料庫,請執行下列指令:

./google/spanner/bin/spanner databases list --ca-certificate-file=certs/ca-api.crt --client-certificate-directory=clientcerts --deployment-endpoint=DEPLOYMENT_ENDPOINT

輸出看起來類似以下內容:

名稱 狀態 VERSION_RETENTION_PERIOD EARLIEST_VERSION_TIME ENABLE_DROP_PROTECTION
DATABASE_NAME 已就緒 1 小時 2025-02-07T12:25:30Z false

執行下列指令來查詢資料:

./google/spanner/bin/spanner sql --database=DATABASE_NAME --ca-certificate-file=certs/ca-api.crt --client-certificate-directory=clientcerts --deployment-endpoint=DEPLOYMENT_ENDPOINT

執行下列 SQL 指令:

SHOW TABLES;
SELECT * FROM names;

或者,您也可以按照「搭配使用 PGAdapter 與 Spanner Omni」中的操作說明設定 PGAdapter,並使用 psql 等工具進行互動。

步驟 5:監控部署作業

如果您使用 monitoring.enabled=true 安裝 Spanner Omni,Prometheus 會抓取指標。您可以使用 Grafana 以圖表呈現這些指標。

1. 取得服務詳細資料

執行下列指令,取得服務詳細資料:

# Prometheus service details. Default port is 9090.
kubectl get service prometheus-service -n monitoring

# Grafana service details. Default port is 3000.
kubectl get service grafana -n monitoring

後續步驟