本文將透過範例,說明如何使用閘道 API 中的下列資源建立應用程式。 其中提供下列作業的步驟:
- 使用一個 HTTPS 接聽程式建立閘道資源。
- 建立參考後端服務的 HTTPRoute 資源。
- 建立具有 CA 憑證的 FrontendTLSPolicy 資源。
背景
相互傳輸層安全性 (MTLS) 是依賴憑證來加密通訊並識別服務用戶端的流程。 這可讓適用於容器的應用程式閘道只信任來自已驗證裝置的連線,進一步提升其安全性態勢。
請參閱下圖:
有效的用戶端憑證流程會顯示向適用於容器的應用程式閘道前端出示憑證的用戶端。 適用於容器的應用程式閘道會判斷憑證有效,並將要求 Proxy 傳送至後端目標。 回應最終會傳回至用戶端。
已撤銷的用戶端憑證流程會顯示向適用於容器的應用程式閘道前端出示撤銷憑證的用戶端。 適用於容器的應用程式閘道會判斷憑證無效,並防止要求被 Proxy 傳送至用戶端。 用戶端會收到 HTTP 400 不正確的要求和對應的原因。
必要條件
如果遵循 BYO 部署策略,請確定您已設定適用於容器的應用程式閘道資源和 ALB 控制器。
如果遵循 ALB 受管理的部署策略,請確定您已透過 ApplicationLoadBalancer 自訂資源佈建 ALB 控制器 以及適用於容器的應用程式閘道資源。
部署範例 HTTP 應用程式:
在您的叢集上套用下列 deployment.yaml 檔案,以建立範例 Web 應用程式,並部署範例祕密來示範前端相互驗證 (mTLS)。
kubectl apply -f https://raw.githubusercontent.com/MicrosoftDocs/azure-docs/refs/heads/main/articles/application-gateway/for-containers/examples/https-scenario/ssl-termination/deployment.yaml此指令會在您的叢集上建立下列物件:
- 名為
test-infra的命名空間 -
echo命名空間中名為test-infra的一個服務 -
echo命名空間中名為test-infra的一個部署 -
listener-tls-secret命名空間中名為test-infra的一個祕密
- 名為
產生憑證
針對此範例,我們將建立根憑證,並從根憑證發出用戶端憑證。 如果您已經有根憑證和用戶端憑證,則可以跳過這些步驟。
產生根憑證的私密金鑰
openssl genrsa -out root.key 2048
產生根憑證
openssl req -x509 -new -nodes -key root.key -sha256 -days 1024 -out root.crt -subj "/C=US/ST=North Dakota/L=Fargo/O=Contoso/CN=contoso-root"
產生用戶端憑證的私密金鑰
openssl genrsa -out client.key 2048
建立用戶端憑證的憑證簽署要求
openssl req -new -key client.key -out client.csr -subj "/C=US/ST=North Dakota/L=Fargo/O=Contoso/CN=contoso-client"
產生由根憑證簽署的用戶端憑證
openssl x509 -req -in client.csr -CA root.crt -CAkey root.key -CAcreateserial -out client.crt -days 1024 -sha256
部署必要的閘道 API 資源
建立閘道
kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: gateway-01
namespace: test-infra
annotations:
alb.networking.azure.io/alb-namespace: alb-test-infra
alb.networking.azure.io/alb-name: alb-test
spec:
gatewayClassName: azure-alb-external
listeners:
- name: mtls-listener
port: 443
protocol: HTTPS
allowedRoutes:
namespaces:
from: Same
tls:
mode: Terminate
certificateRefs:
- kind : Secret
group: ""
name: listener-tls-secret
EOF
注意
當 ALB 控制器在 Azure Resource Manager 中建立容器資源的應用程式閘道時,它會針對前端資源使用下列命名慣例: fe-<eight randomly generated characters>。
如果您想要變更在 Azure 中建立的前端資源名稱,請考慮遵循 自備部署策略。
建立閘道資源之後,請確定狀態有效,接聽程式的狀態為 [已程式化],並且已經將位址指派給閘道。
kubectl get gateway gateway-01 -n test-infra -o yaml
成功建立閘道後的範例輸出:
status:
addresses:
- type: IPAddress
value: xxxx.yyyy.alb.azure.com
conditions:
- lastTransitionTime: "2023-06-19T21:04:55Z"
message: Valid Gateway
observedGeneration: 1
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: "2023-06-19T21:04:55Z"
message: Application Gateway For Containers resource has been successfully updated.
observedGeneration: 1
reason: Programmed
status: "True"
type: Programmed
listeners:
- attachedRoutes: 0
conditions:
- lastTransitionTime: "2023-06-19T21:04:55Z"
message: ""
observedGeneration: 1
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
- lastTransitionTime: "2023-06-19T21:04:55Z"
message: Listener is accepted
observedGeneration: 1
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: "2023-06-19T21:04:55Z"
message: Application Gateway For Containers resource has been successfully updated.
observedGeneration: 1
reason: Programmed
status: "True"
type: Programmed
name: https-listener
supportedKinds:
- group: gateway.networking.k8s.io
kind: HTTPRoute
建立閘道之後,請建立 HTTPRoute 資源。
kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: https-route
namespace: test-infra
spec:
parentRefs:
- name: gateway-01
rules:
- backendRefs:
- name: echo
port: 80
EOF
建立 HTTPRoute 資源之後,請確定路由的狀態為「已接受」,且適用於容器的應用程式閘道資源的狀態為「已程式化」。
kubectl get httproute https-route -n test-infra -o yaml
確認已成功更新適用於容器的應用程式閘道資源的狀態。
status:
parents:
- conditions:
- lastTransitionTime: "2023-06-19T22:18:23Z"
message: ""
observedGeneration: 1
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
- lastTransitionTime: "2023-06-19T22:18:23Z"
message: Route is Accepted
observedGeneration: 1
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: "2023-06-19T22:18:23Z"
message: Application Gateway For Containers resource has been successfully updated.
observedGeneration: 1
reason: Programmed
status: "True"
type: Programmed
controllerName: alb.networking.azure.io/alb-controller
parentRef:
group: gateway.networking.k8s.io
kind: Gateway
name: gateway-01
namespace: test-infra
使用 kubectl 建立 Kubernetes 祕密,其中包含用戶端憑證的憑證鏈結。
kubectl create secret generic ca.bundle -n test-infra --from-file=ca.crt=root.crt
建立 FrontendTLSPolicy
kubectl apply -f - <<EOF
apiVersion: alb.networking.azure.io/v1
kind: FrontendTLSPolicy
metadata:
name: mtls-policy
namespace: test-infra
spec:
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
name: gateway-01
namespace: test-infra
sectionNames:
- mtls-listener
default:
verify:
caCertificateRef:
name: ca.bundle
group: ""
kind: Secret
namespace: test-infra
EOF
建立 FrontendTLSPolicy 物件之後,請檢查物件上的狀態,以確保原則有效:
kubectl get frontendtlspolicy mtls-policy -n test-infra -o yaml
有效 FrontendTLSPolicy 物件建立的範例輸出:
status:
conditions:
- lastTransitionTime: "2023-06-29T16:54:42Z"
message: Valid FrontendTLSPolicy
observedGeneration: 1
reason: Accepted
status: "True"
type: Accepted
測試應用程式的存取權
現在我們已準備好將一些流量透過指派給前端的 FQDN 傳送至範例應用程式。 使用下列命令來取得 FQDN:
fqdn=$(kubectl get gateway gateway-01 -n test-infra -o jsonpath='{.status.addresses[0].value}')
在沒有用戶端憑證的情況下,將前端的 FQDN 捲曲。
curl --insecure https://$fqdn/
請注意,需要憑證的回應警示。
curl: (56) OpenSSL SSL_read: OpenSSL/1.1.1k: error:1409445C:SSL routines:ssl3_read_bytes:tlsv13 alert certificate required, errno 0
對所產生呈現用戶端憑證的 FQDN 執行 Curl。
curl --cert client.crt --key client.key --insecure https://$fqdn/
請注意,回應來自適用於容器的應用程式閘道後方的後端服務。
恭喜您,您已安裝 ALB 控制器、部署後端應用程式、透過用戶端憑證進行驗證,以及透過適用於容器的應用程式閘道從後端服務傳回流量。