在ASM網關和Sideca代理之間,所有數據均通過mTLS隧道傳輸。如果應用注入了Sidecar,建議在網關處配置TLS終止,此時仍能保證全程加密。如果應用沒有注入Sidecar或者有其他特殊情況,ASM網關同樣支持TLS透傳。本文介紹如何通過ASM網關啟用TLS透傳,以實現對集群內HTTPS服務的安全入口訪問。
前提條件
已添加集群到ASM實例。具體操作,請參見添加集群到ASM實例。
已部署入口網關。具體操作,請參見創建入口網關。
已部署應用到ASM實例關聯的集群。具體操作,請參見在ASM實例關聯的集群中部署應用。
使用域名時需要備案才能正常訪問,本示例中使用aliyun.com。
步驟一:生成服務器證書和私鑰
如果您已經擁有針對sample.aliyun.com
可用的證書和私鑰,需要將密鑰命名為sample.aliyun.com.key
,證書命名為sample.aliyun.com.crt
。如果沒有,可以通過openssl執行以下操作來生成證書和密鑰。
執行以下命令,創建根證書和私鑰。
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=mynginx Inc./CN=aliyun.com' -keyout aliyun.root.key -out aliyun.root.crt
執行以下命令,為
sample.aliyun.com
服務器生成證書和私鑰。openssl req -out sample.aliyun.com.csr -newkey rsa:2048 -nodes -keyout sample.aliyun.com.key -subj "/CN=sample.aliyun.com/O=mynginx sample organization" openssl x509 -req -days 365 -CA aliyun.root.crt -CAkey aliyun.root.key -set_serial 0 -in sample.aliyun.com.csr -out sample.aliyun.com.crt
步驟二:定義內部服務
示例中的內部服務是基于Nginx實現的,首先為Nginx服務器創建配置文件。以域名aliyun.com的內部服務為例,定義請求根路徑直接返回字樣Welcome to aliyun.com without TLS Termination!
及狀態碼200。mynginx.conf的具體內容如下。
events {
}
http {
log_format main '$remote_addr - $remote_user [$time_local] $status '
'"$request" $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log;
server {
listen 443 ssl;
location / {
return 200 'Welcome to aliyun.com without TLS Termination!';
add_header Content-Type text/plain;
}
server_name www.aliyun.com;
ssl_certificate /etc/nginx-server-certs/tls.crt;
ssl_certificate_key /etc/nginx-server-certs/tls.key;
}
}
在入口網關Pod所在的集群對應的kubeconfig環境下,執行以下命令,創建Kubernetes ConfigMap存儲Nginx服務器的配置。
kubectl create configmap mynginx-configmap --from-file=nginx.conf=./mynginx.conf?
在入口網關Pod所在的集群對應的kubeconfig環境下,執行以下命令,將在default命名空間中創建包含證書和私鑰的Secret。
kubectl create secret tls nginx-server-certs --key sample.aliyun.com.key --cert sample.aliyun.com.crt?
為default命名空間啟用Sidecar網格代理自動注入。具體操作,請參見啟用自動注入。
創建并拷貝以下內容到mynginxapp.yaml文件中,并執行
kubectl apply -f mynginxapp.yaml
命令,創建域名aliyun.com的內部服務。apiVersion: v1 kind: Service metadata: name: mynginxapp labels: app: mynginxapp spec: ports: - port: 443 protocol: TCP selector: app: mynginxapp --- apiVersion: apps/v1 kind: Deployment metadata: name: mynginxapp spec: selector: matchLabels: app: mynginxapp replicas: 1 template: metadata: labels: app: mynginxapp spec: containers: - name: nginx image: nginx:1.15 ports: - containerPort: 443 volumeMounts: - name: nginx-config mountPath: /etc/nginx readOnly: true - name: nginx-server-certs mountPath: /etc/nginx-server-certs readOnly: true volumes: - name: nginx-config configMap: name: mynginx-configmap - name: nginx-server-certs secret: secretName: nginx-server-certs
確認Nginx服務器已成功部署,執行以下命令從其sidecar代理向服務器發送請求。
kubectl exec -it $(kubectl get pod -l app=mynginxapp -o jsonpath={.items..metadata.name}) -c istio-proxy -- curl -v -k --resolve sample.aliyun.com:443:127.0.0.1 https://sample.aliyun.com
步驟三:創建網關規則
登錄ASM控制臺。
在左側導航欄,選擇 。
在網格管理頁面,找到待配置的實例,單擊實例的名稱或在操作列中單擊管理。
在網格詳情頁面左側導航欄,選擇 ,然后在右側頁面,單擊使用YAML創建。
按以下步驟定義網關規則,然后單擊創建。
選擇相應的命名空間。本文以選擇default命名空間為例。
在彈出窗口的文本框中,定義服務網關。可參考以下YAML定義。
apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: istio-mynginx-customingressgateway spec: selector: istio: ingressgateway servers: - hosts: - 'sample.aliyun.com' port: name: https number: 443 protocol: HTTPS tls: mode: PASSTHROUGH
在網關規則(Gateway)頁面可以看到新建的網關。
步驟四:創建虛擬服務
登錄ASM控制臺。
在左側導航欄,選擇 。
在網格管理頁面,找到待配置的實例,單擊實例的名稱或在操作列中單擊管理。
在網格詳情頁面左側導航欄,選擇 ,然后在右側頁面,單擊使用YAML創建。
按以下步驟定義虛擬服務,然后單擊創建。
選擇相應的命名空間。本文以選擇default命名空間為例。
在文本框中,定義Istio虛擬服務。可參考以下YAML定義。
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: istio-mynginx-customvirtualservice spec: hosts: - "sample.aliyun.com" gateways: - istio-mynginx-customingressgateway tls: - match: - port: 443 sniHosts: - sample.aliyun.com route: - destination: host: mynginxapp.default.svc.cluster.local port: number: 443
在虛擬服務(VirtualService)頁面可以看到新建的虛擬服務。
執行結果
通過以下任意方式獲取入口網關的地址。
方式一:通過控制臺獲取。具體操作,請參見獲取入口網關地址。
方式二:通過kubectl命令獲取。
在入口網關Pod所在的集群對應的KubeConfig環境下,執行以下命令,獲取入口網關的地址。
kubectl get svc -n istio-system -l istio=ingressgateway
執行以下命令,通過HTTPS協議訪問aliyun.com服務。
curl -v --cacert aliyun.root.crt --resolve sample.aliyun.com:443:xx.xx.xx.xx https://sample.aliyun.com
預期輸出:
Welcome to aliyun.com without TLS Termination!%