TLS路由(TLSRoute)用于配置未终止的TLS/HTTPS流量。一般情况下配合Gateway或者ServiceEntry来使用。
Nginx服务器的TLS路由示例如下:
1 apiVersion: networking.istio.io/v1alpha3 2 kind: Gateway 3 metadata: 4 name: https-gateway 5 spec: 6 selector: 7 istio: ingressgateway # use Istio default gateway implementation 8 servers: 9 - port: 10 number: 443 11 name: https 12 protocol: HTTPS 13 tls: 14 mode: PASSTHROUGH 15 hosts: 16 - "*" 17 --- 18 apiVersion: networking.istio.io/v1alpha3 19 kind: VirtualService 20 metadata: 21 name: my-nginx 22 spec: 23 hosts: 24 - "*" 25 gateways: 26 - https-gateway 27 tls: 28 - match: 29 - port: 443 30 sniHosts: 31 - "foo.my-nginx.com" 32 route: 33 - destination: 34 host: my-nginx.foo.svc.cluster.local 35 port: 36 number: 443 37 - match: 38 - port: 443 39 sniHosts: 40 - "bar.my-nginx.com" 41 route: 42 - destination: 43 host: my-nginx.bar.svc.cluster.local 44 port: 45 number: 443
第1~16行定义了名为https-gateway的网关,监听443端口,使用HTTPS协议,TLS模式选择PASSTHROUGH,表示不终止TLS。
第18~45行定义了名为my-nginx的VirtualService,当sni host为foo.my-nginx.com时,路由请求到my-nginx.foo.svc.cluster.local服务的443端口,当sni host为bar.my-nginx.com时,路由请求到my-nginx.bar.svc.cluster.local服务的443端口。
【实验】
1)创建HTTPS证书:
$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /tmp/nginx.key -out /tmp/nginx.crt -subj '/CN=*.my-nginx.com/O=my-nginx' $ kubectl create ns foo $ kubectl create ns bar $ kubectl create secret tls nginxsecret -n foo --key /tmp/nginx.key --cert /tmp/nginx.crt $ kubectl create secret tls nginxsecret -n bar --key /tmp/nginx.key --cert /tmp/nginx.crt $ kubectl get secret nginxsecret -n foo NAME TYPE DATA AGE nginxsecret kubernetes.io/tls 2 20s $ kubectl get secret nginxsecret -n bar NAME TYPE DATA AGE nginxsecret kubernetes.io/tls 2 10s
2)创建Nginx的HTTPS配置:
$ kubectl create configmap nginxconfigmap -n foo --from-file=istio/miscellaneous/https-default.conf $ kubectl create configmap nginxconfigmap -n bar --from-file=istio/miscellaneous/https-default.conf $ kubectl get configmap nginxconfigmap -n foo NAME DATA AGE nginxconfigmap 1 20s $ kubectl get configmap nginxconfigmap -n bar NAME DATA AGE nginxconfigmap 1 10s
3)创建测试Pod:
$ kubectl apply -f kubernetes/dns-test.yaml
4)部署nginx服务:
$ kubectl apply -f <(istioctl kube-inject -f kubernetes/my-nginx.yaml) -n foo $ kubectl apply -f <(istioctl kube-inject -f kubernetes/my-nginx.yaml) -n bar $ kubectl get pod -n foo NAME READY STATUS RESTARTS AGE my-nginx-97744d9bd-2z8v5 2/2 Running 0 48s $ kubectl get pod -n bar NAME READY STATUS RESTARTS AGE my-nginx-97744d9bd-t4mdd 2/2 Running 0 54s
5)关闭nginx服务的mTLS:
$ kubectl apply -f istio/security/mtls-my-nginx-disable.yaml -n foo $ kubectl apply -f istio/security/mtls-my-nginx-disable.yaml -n bar
6)服务访问测试:
$ kubectl exec dns-test -c dns-test -- curl -sk https://my-nginx.foo/ Hello from nginx in foo $ kubectl exec dns-test -c dns-test -- curl -sk https://my-nginx.bar/ Hello from nginx in bar
7)创建TLS路由规则:
$ kubectl apply -f istio/miscellaneous/virtual-service-tls-route.yaml
8)服务访问测试:
$ curl -sk --resolve foo.my-nginx.com:31390:11.11.11.112 https://foo.my-nginx.com:31390/ Hello from nginx in foo $ curl -sk --resolve bar.my-nginx.com:31390:11.11.11.112 https://bar.my-nginx.com:31390/ Hello from nginx in bar
从上面的请求测试可以看出,当请求的sni host为foo.my-nginx.com,请求转发到了foo命名空间的my-nginx服务;当请求的sni host为bar.my-nginx.com,请求转发到了bar命名空间的my-nginx服务。
9)清理:
$ kubectl delete -f kubernetes/dns-test.yaml $ kubectl delete ns foo $ kubectl delete ns bar $ kubectl delete -f istio/miscellaneous/virtual-service-tls-route.yaml