13.4 TCP路由

上一章

13.6 mTLS迁移

下一章

更多图书

13.5 TLS路由

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