在 Kubernetes 環境下,Istio 提供了強大的流量管理和安全功能。本文首先介紹如何使用自簽憑證和 Let’s Encrypt 簽發的憑證來設定 Istio Gateway,確保服務的 SSL/TLS 加密,提升安全性。接著,文章說明如何利用 Istio 進行零停機佈署和 A/B 測試,以提升服務的可靠性和彈性。最後,文章整理了 Kubernetes 常用的指令操作,方便開發者快速查詢和使用,涵蓋了資源資訊查詢、排序、篩選、標籤與註解操作、資源的建立、編輯與刪除,以及進階的互動式操作和連線埠轉發等技巧。

在 Istio 中實踐 SSL 憑證設定

SSL 憑證在現今網路環境中是不可或缺的。它們透過加密伺服器與客戶端之間的資料傳輸,增強網站的可信度。本章節將探討多種取得 SSL 憑證的方法,並組態 Istio Gateway 使用這些憑證。

佈署範例應用程式

首先,佈署一個簡單的 Hello World 網頁應用程式,以確保所有設定正常運作。你也可以使用自己的應用程式或服務。

  1. 建立 Kubernetes 佈署:使用 learncloudnative/helloworld:0.1.0 映像檔。

    kubectl run helloworld --image=learncloudnative/helloworld:0.1.0 --port=3000
    
  2. 建立 Kubernetes 服務

    cat <<EOF | kubectl apply -f -
    apiVersion: v1
    kind: Service
    metadata:
      name: helloworld
      labels:
        run: helloworld
    spec:
      ports:
      - name: http
        port: 80
        targetPort: 3000
      selector:
        run: helloworld
    EOF
    
  3. 建立 Gateway 資源

    cat <<EOF | kubectl apply -f -
    apiVersion: networking.istio.io/v1alpha3
    kind: Gateway
    metadata:
      name: public-gateway
    spec:
      selector:
        istio: ingressgateway
      servers:
      - port:
          number: 80
          name: http
          protocol: HTTP
        hosts:
        - '*'
    EOF
    
  4. 建立 VirtualService

    cat <<EOF | kubectl apply -f -
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: helloworld
    spec:
      hosts:
      - '*'
      gateways:
      - public-gateway
      http:
      - route:
        - destination:
            host: helloworld.default.svc.cluster.local
            port:
              number: 80
    EOF
    

自簽憑證與手動設定

建立自簽憑證

  1. 選擇網域名稱:這裡使用 mysuperdomain.com 作為範例。

    export DOMAIN_NAME=mysuperdomain.com
    
  2. 建立根憑證與私鑰

    openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj "/O=$DOMAIN_NAME Inc./CN=$DOMAIN_NAME" -keyout $DOMAIN_NAME.key -out $DOMAIN_NAME.crt
    
  3. 建立私鑰與憑證簽名請求(CSR)

    openssl req -out helloworld.$DOMAIN_NAME.csr -newkey rsa:2048 -nodes -keyout helloworld.$DOMAIN_NAME.key -subj "/CN=helloworld.$DOMAIN_NAME/O=hello world from $DOMAIN_NAME"
    
  4. 簽署憑證

    openssl x509 -req -days 365 -CA $DOMAIN_NAME.crt -CAkey $DOMAIN_NAME.key -set_serial 0 -in helloworld.$DOMAIN_NAME.csr -out helloworld.$DOMAIN_NAME.crt
    

在 Istio 中組態自簽憑證

  1. 建立 Secret 資源

    kubectl create secret tls istio-ingressgateway-certs -n istio-system --key helloworld.$DOMAIN_NAME.key --cert helloworld.$DOMAIN_NAME.crt
    
  2. 更新 Gateway 資源

    cat <<EOF | kubectl apply -f -
    apiVersion: networking.istio.io/v1alpha3
    kind: Gateway
    metadata:
      name: public-gateway
    spec:
      selector:
        istio: ingressgateway
      servers:
      - port:
          number: 443
          name: https
          protocol: HTTPS
        tls:
          mode: SIMPLE
          serverCertificate: /etc/istio/ingressgateway-certs/tls.crt
          privateKey: /etc/istio/ingressgateway-certs/tls.key
        hosts:
        - helloworld.$DOMAIN_NAME
    EOF
    
  3. 更新 VirtualService

    cat <<EOF | kubectl apply -f -
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: helloworld
    spec:
      hosts:
      - helloworld.$DOMAIN_NAME
      gateways:
      - public-gateway
      http:
      - route:
        - destination:
            host: helloworld.default.svc.cluster.local
            port:
              number: 80
    EOF
    

測試組態

使用 curl 命令測試 SSL 憑證是否正確組態:

export EXTERNAL_IP=$(kubectl get svc istio-ingressgateway -n istio-system -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
curl -v --resolve helloworld.$DOMAIN_NAME:443:$EXTERNAL_IP --cacert $DOMAIN_NAME.crt https://helloworld.$DOMAIN_NAME

真實簽發的憑證與手動設定

要獲得被客戶端信任的 SSL 憑證,可以使用 Let’s Encrypt 或購買來自授權憑證機構的憑證。以下步驟以 SSL For Free 為例,使用 Let’s Encrypt 簽發憑證。

  1. 取得 SSL 憑證:前往 SSL For Free 輸入你的網域名稱,例如 mydomain.com

在 Istio 中組態真實簽發的憑證

組態步驟與自簽憑證類別似,但需要使用從授權機構取得的真實憑證。

使用 Istio 實作零停機佈署與安全網站設定

在現代化的軟體開發與佈署過程中,如何確保服務的持續可用性以及安全性是個重要的課題。本篇文章將討論如何使用 Istio 實作零停機佈署(Zero-Downtime Releases)、A/B 測試,以及如何為網站設定 SSL/TLS 加密以確保安全性。

零停機佈署與 A/B 測試

在 Kubernetes 環境中使用 Istio,可以實作服務的零停機佈署和 A/B 測試。這些功能主要透過 Istio 的流量管理能力來實作。

  1. 零停機佈署:在佈署新版本的服務時,Istio 可以逐漸將流量從舊版本切換到新版本,從而避免服務中斷。
  2. A/B 測試:Istio 可以根據特定的規則(如 cookie、header 等)將流量分配到不同的服務版本,從而實作 A/B 測試。

相關 Istio 組態範例

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: helloworld
spec:
  hosts:
  - helloworld.default.svc.cluster.local
  http:
  - route:
    - destination:
        host: helloworld.default.svc.cluster.local
        subset: v1
      weight: 50
    - destination:
        host: helloworld.default.svc.cluster.local
        subset: v2
      weight: 50
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: helloworld
spec:
  host: helloworld.default.svc.cluster.local
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2

內容解密:

此組態範例展示瞭如何使用 Istio 的 VirtualServiceDestinationRule 物件來實作流量分配。在這個例子中,50% 的流量會被路由到 v1 版本的服務,而另外 50% 會被路由到 v2 版本。這樣可以實作 A/B 測試或逐步的零停機佈署。

為網站設定 SSL/TLS 加密

為了確保網站的安全性,啟用 SSL/TLS 加密是必要的。以下是使用 Istio 為 Ingress Gateway 組態 SSL/TLS 的步驟。

  1. 取得 SSL/TLS 證書:可以使用 Let’s Encrypt 這類別的證書頒發機構來取得免費的 SSL/TLS 證書。
  2. 建立 Kubernetes Secret:將獲得的證書和私鑰儲存為 Kubernetes Secret。
  3. 組態 Istio Ingress Gateway:更新 Istio Ingress Gateway 的組態,使其使用剛才建立的 Secret。

取得 SSL/TLS 證書的步驟

  1. 前往 SSL For Free 網站並請求證書。
  2. 進行 DNS 驗證。
  3. 下載證書檔案。

下載的檔案包含三個主要檔案:ca_bundle.crtcertificate.crtprivate.key

建立和更新 Kubernetes Secret

kubectl delete secret istio-ingressgateway-certs -n istio-system
kubectl create secret tls istio-ingressgateway-certs -n istio-system --key private.key --cert certificate.crt

更新 Istio Gateway 組態

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: public-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 443
      name: https
      protocol: HTTPS
    tls:
      mode: SIMPLE
      serverCertificate: /etc/istio/ingressgateway-certs/tls.crt
      privateKey: /etc/istio/ingressgateway-certs/tls.key
    hosts:
    - mysuperdomain.com

內容解密:

此組態更新了 Istio Ingress Gateway 以使用新的 SSL/TLS 證書和私鑰。tls.crttls.key 分別對應於之前建立的 Secret 中的 certificate.crtprivate.key

Kubernetes CLI 速查

基本資源資訊操作

Kubernetes 提供強大的命令列工具 kubectl 來管理叢集資源。以下是一些基本的操作命令:

  • kubectl get pod mypod:列出目前名稱空間中名為 mypod 的 Pod。
  • kubectl get pod:列出目前名稱空間中的所有 Pod。
  • kubectl get pod -n mynamespace:列出 mynamespace 名稱空間中的所有 Pod。
  • kubectl get pod --all-namespaces:列出所有名稱空間中的 Pod。
  • kubectl get pod --all-namespaces -o wide:列出所有名稱空間中的 Pod,並顯示 IP 和節點資訊。
  • kubectl get all --all-namespaces:列出叢集中的所有資源。
  • kubectl describe pod mypod:詳細描述名為 mypod 的 Pod 資源,適合用於診斷問題。
  • kubectl get pod --show-labels:顯示所有 Pod 及其標籤。
  • kubectl explain pod:顯示 Pod 資源的檔案說明。
  • kubectl get pod mypod -o yaml:以 YAML 格式顯示名為 mypod 的 Pod 資訊。
  • kubectl get pod mypod -o json:以 JSON 格式顯示名為 mypod 的 Pod 資訊。
  • kubectl cluster-info:顯示叢集資訊。
  • kubectl get pod -w:監控 Pod 狀態變化,適合用於等待 Pod 啟動等操作。

詳細資源資訊查詢

若需要更詳細的資源資訊,可以使用以下命令:

  • kubectl get pod --selector="app=myapp":列出具有標籤 app=myapp 的所有 Pod。
  • kubectl get pod --selector="app=myapp" -o jsonpath='{.items[*].metadata.name}':取得具有標籤 app=myapp 的 Pod 名稱。
  • kubectl get pod mypod -o jsonpath='{.spec.containers[0].ports[0].containerPort}':取得 mypod 中第一個容器的第一個連線埠號碼。
  • kubectl -v 9 get pod:以最高詳細程度(9)取得 Pod 資訊。

資源排序與篩選

Kubernetes CLI 也支援對資源的排序和篩選功能。

  • kubectl get pod --sort-by=.metadata.name:按名稱排序列出 Pod。
  • kubectl get pod --sort-by=.metadata.creationTimestamp:按建立時間排序列出 Pod,最早建立的在最前面。
  • kubectl get pod -l app=myapp:顯示具有標籤 app=myapp 的 Pod。

標籤與註解操作

標籤和註解是 Kubernetes 中重要的中繼資料管理工具。

新增與刪除標籤

# 新增標籤
kubectl label pod mypod mylabel=myvalue

# 刪除標籤
kubectl label pod mypod mylabel-

新增與刪除註解

# 新增註解
kubectl annotate pod mypod name=value

# 刪除註解
kubectl annotate pod mypod name-

資源的建立、編輯與刪除

Kubernetes CLI 支援對資源的 CRUD(建立、讀取、更新、刪除)操作。

建立與刪除資源

# 從檔案建立資源
kubectl create -f ./file.yaml

# 從檔案刪除資源
kubectl delete -f ./file.yaml

# 刪除特定 Pod
kubectl delete pod mypod

# 建立 Pod(及 Deployment)
kubectl run mypod --image=myimage

# 建立並暴露連線埠
kubectl run mypod --image=myimage --port=8080

進階命令操作

以下是一些進階的 Kubernetes CLI 操作命令。

互動式操作與連線埠轉發

# 執行互動式終端機
kubectl run curl --image=radial/busyboxplus:curl -i --tty

# 連線埠轉發
kubectl port-forward mypod 8080:CONTAINER_PORT

# 暴露 Deployment 到外部流量
kubectl expose deployment mydeployment --type="NodePort" --port 8080

# 在 Pod 中執行命令
kubectl exec -it mypod -- /bin/bash

# 連結到容器輸出
kubectl attach mypod

# 複製檔案
kubectl cp mypod:/some/path/file.txt .

Kubernetes 資源名稱一覽表

Kubernetes 中有許多資源型別,以下是常見的資源及其簡寫對照表。

長名稱簡寫
podspo
servicessvc
deploymentsdeploy
replicasetsrs
statefulsetssts
configmapscm
persistentvolumespv
persistentvolumeclaimspvc

這些命令和資源名稱可以幫助你更好地管理和維護 Kubernetes 叢集。熟練使用 Kubernetes CLI 可以顯著提升你的工作效率。