前置准备

  1. Higress 安装在 K8s 内的 higress-system 命名空间下,监听的 HTTP 端口为 80。 为了测试方便,gateway 端口映射都本地 127.0.0.1:80;
  2. 目标是为 default 命名空间下的 部署 https-httpbin 服务,服务监听的端口为 443;
  3. https-httpbin 服务具体内容请参考 github httpbin;

准备证书

  1. 生成 CA(根证书):
  1. # 生成 CA 私钥
  2. openssl genrsa -out ca.key 2048
  3. # 生成 CA 根证书
  4. openssl req -x509 -new -nodes -key ca.key -subj “/CN=MyCA -days 3650 -out ca.crt
  1. 生成服务端证书
  1. # 生成服务端私钥
  2. openssl genrsa -out server.key 2048
  3. # 生成服务端证书签名请求(CSR)
  4. openssl req -new -key server.key -subj “/CN=https-httpbin-v1.default.svc.cluster.local -out server.csr
  5. # 使用 CA 签署服务端证书
  6. openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 3650 -sha256
  1. 生成 Gateway 证书
  1. # 生成 Gateway 私钥
  2. openssl genrsa -out gateway.key 2048
  3. # 生成 Gateway 证书签名请求(CSR)
  4. openssl req -new -key gateway.key -subj “/CN=gateway.higress-system.svc.cluster.local -out gateway.csr
  5. # 使用 CA 签署 Gateway 证书
  6. openssl x509 -req -in gateway.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out gateway.crt -days 3650 -sha256
  1. 导入 CA 证书、Gateway、服务端证书到 secret 中
  1. kubectl create secret generic gateway-cert-cacert from-file=cacert=ca.crt namespace=default
  2. kubectl create secret tls gateway-cert key gateway.key cert gateway.crt namespace=default
  3. kubectl create secret tls server-cert key server.key cert server.crt namespace=default

准备后端 https-httpbin 服务

  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4. name: https-httpbin-v1
  5. namespace: default
  6. spec:
  7. selector:
  8. app: https-httpbin-v1
  9. ports:
  10. - protocol: TCP
  11. port: 443
  12. targetPort: 443
  13. —-
  14. apiVersion: apps/v1
  15. kind: Deployment
  16. metadata:
  17. name: https-httpbin-v1
  18. namespace: default
  19. labels:
  20. app: https-httpbin-v1
  21. spec:
  22. replicas: 1
  23. selector:
  24. matchLabels:
  25. app: https-httpbin-v1
  26. template:
  27. metadata:
  28. labels:
  29. app: https-httpbin-v1
  30. spec:
  31. containers:
  32. - name: https-httpbin-v1
  33. image: registry.cn-hangzhou.aliyuncs.com/2456868764/httpbin:v1.0.2
  34. imagePullPolicy: Always
  35. ports:
  36. - containerPort: 443
  37. command:
  38. - /app/httpbin
  39. - https-enable=true
  40. - https-port=443
  41. - mtls=true
  42. - cert=/etc/cert/tls.crt
  43. - key=/etc/cert/tls.key
  44. - cacert=/etc/cacert/cacert
  45. env:
  46. - name: POD_NAME
  47. valueFrom:
  48. fieldRef:
  49. fieldPath: metadata.name
  50. - name: NAMESPACE
  51. valueFrom:
  52. fieldRef:
  53. fieldPath: metadata.namespace
  54. volumeMounts:
  55. - mountPath: “/etc/cert
  56. name: server-cert
  57. readOnly: true
  58. - mountPath: “/etc/cacert
  59. name: ca-cert
  60. readOnly: true
  61. resources:
  62. requests:
  63. cpu: 10m
  64. volumes:
  65. - name: server-cert
  66. secret:
  67. secretName: server-cert
  68. - name: ca-cert
  69. secret:
  70. secretName: gateway-cert-cacert

配置路由

  1. apiVersion: networking.k8s.io/v1
  2. kind: Ingress
  3. metadata:
  4. annotations:
  5. # backend protocol
  6. nginx.ingress.kubernetes.io/backend-protocol: HTTPS
  7. # gateway to backend mtls
  8. nginx.ingress.kubernetes.io/proxy-ssl-secret: default/gateway-cert
  9. # SNI for backend check
  10. nginx.ingress.kubernetes.io/proxy-ssl-name: https-httpbin-v1.default.svc.cluster.local
  11. nginx.ingress.kubernetes.io/proxy-ssl-server-name: on
  12. name: ingress-https-httpbin
  13. namespace: default
  14. spec:
  15. ingressClassName: higress
  16. rules:
  17. - host: foo.com
  18. http:
  19. paths:
  20. - path: /
  21. pathType: Prefix
  22. backend:
  23. service:
  24. name: https-httpbin-v1
  25. port:
  26. number: 443

Ingress Annotaion 配置:

  • nginx.ingress.kubernetes.io/backend-protocol 指定后端服务使用的协议,默认为HTTP,支持HTTP、HTTP2、HTTPS、GRPC和GRPCS。
  • nginx.ingress.kubernetes.io/proxy-ssl-secret 启用 mtls 需要指定 gateway 证书,格式为 namespace/secret-name。 这里需要注意的是需要同时创建一个 CA 证书的 secret, 名称为 proxy-ssl-secret 的名称加 -cacert 后缀,比如是 gateway-cert-cacert,否则会报错。
  • nginx.ingress.kubernetes.io/proxy-ssl-name 后端校验 SNI 需要指定后端服务使用的域名。
  • nginx.ingress.kubernetes.io/proxy-ssl-server-name 启用 SNI。

测试

  1. curl -H host: foo.com http://127.0.0.1/ping
  2. pong