5.2.5 为多个主机配置TLS入口网关

执行前面相同的步骤,为nginx.example.com生成客户端和服务器证书和密钥,将证书移动到nginx.example.com目录。

创建一个新Secret来保存nginx.example.com的证书:


kubectl create -n istio-system secret tls istio-ingressgateway-nginx-certs --key 
nginx.example.com/3_application/private/nginx.example.com.key.pem --cert nginx.example.
com/3_application/certs/nginx.example.com.cert.pem

通过使用新Secret的volume生成部署istio-ingressgateway的deployment。切换到Istio软件包目录,然后执行如下命令:


helm template install/kubernetes/helm/istio/ --name istio-ingressgateway --namespace 
istio-system -x charts/gateways/templates/deployment.yaml --set gateways.istio-egressgateway.enabled=false \
--set gateways.istio-ingressgateway.secretVolumes[0].name=ingressgateway-certs \
--set gateways.istio-ingressgateway.secretVolumes[0].secretName=istio-ingress-gateway-certs \
--set gateways.istio-ingressgateway.secretVolumes[0].mountPath=/etc/istio/ingress-
gateway-certs \
--set gateways.istio-ingressgateway.secretVolumes[1].name=ingressgateway-ca-certs \
--set gateways.istio-ingressgateway.secretVolumes[1].secretName=istio-ingressgateway-ca-certs \
--set gateways.istio-ingressgateway.secretVolumes[1].mountPath=/etc/istio/ingress-
gateway-ca-certs \
--set gateways.istio-ingressgateway.secretVolumes[2].name=ingressgateway-nginx-
certs \
--set gateways.istio-ingressgateway.secretVolumes[2].secretName=istio-ingress-gateway-nginx-certs \
--set gateways.istio-ingressgateway.secretVolumes[2].mountPath=/etc/istio/ingress-
gateway-nginx-certs > \
istio-ingressgateway.yaml

重新部署istio-ingressgateway:


kubectl apply -f istio-ingressgateway.yaml

验证密钥和证书是否已成功加载到istio-ingressgateway pod中:


kubectl exec -it -n istio-system $(kubectl -n istio-system get pods -l istio=ingress-
gateway -o jsonpath='{.items[0].metadata.name}') -- ls -alR /etc/istio
/etc/istio:
total 12
drwxr-xr-x 1 root root 4096 Jan 10 06:01 .
drwxr-xr-x 1 root root 4096 Jan 10 06:01 ..
drwxrwxrwt 3 root root   80 Jan 10 06:01 ingressgateway-ca-certs
drwxrwxrwt 3 root root  120 Jan 10 06:01 ingressgateway-certs
drwxrwxrwt 3 root root  120 Jan 10 06:01 ingressgateway-nginx-certs
drwxr-xr-x 1 root root 4096 Jan 10 06:01 proxy

/etc/istio/ingressgateway-ca-certs:
total 4
drwxrwxrwt 3 root root   80 Jan 10 06:01 .
drwxr-xr-x 1 root root 4096 Jan 10 06:01 ..
drwxr-xr-x 2 root root   40 Jan 10 06:01 ..2019_01_10_06_01_05.702280334
lrwxrwxrwx 1 root root   31 Jan 10 06:01 ..data -> ..2019_01_10_06_01_05.702280334

/etc/istio/ingressgateway-certs:
total 4
drwxrwxrwt 3 root root  120 Jan 10 06:01 .
drwxr-xr-x 1 root root 4096 Jan 10 06:01 ..
drwxr-xr-x 2 root root   80 Jan 10 06:01 ..2019_01_10_06_01_05.947231531
lrwxrwxrwx 1 root root   31 Jan 10 06:01 ..data -> ..2019_01_10_06_01_05.947231531
lrwxrwxrwx 1 root root   14 Jan 10 06:01 tls.crt -> ..data/tls.crt
lrwxrwxrwx 1 root root   14 Jan 10 06:01 tls.key -> ..data/tls.key

/etc/istio/ingressgateway-nginx-certs:
total 4
drwxrwxrwt 3 root root  120 Jan 10 06:01 .
drwxr-xr-x 1 root root 4096 Jan 10 06:01 ..
drwxr-xr-x 2 root root   80 Jan 10 06:01 ..2019_01_10_06_01_05.025849340
lrwxrwxrwx 1 root root   31 Jan 10 06:01 ..data -> ..2019_01_10_06_01_05.025849340
lrwxrwxrwx 1 root root   14 Jan 10 06:01 tls.crt -> ..data/tls.crt
lrwxrwxrwx 1 root root   14 Jan 10 06:01 tls.key -> ..data/tls.key

创建Nginx服务,具体代码可参见目录mtls-go-example/https下的文件mynginx.yaml:


kubectl apply -f - <<EOF
apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - name: http
    port: 80
  selector:
    app: nginx
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx
        version: v1
    spec:
      containers:
      - image: nginx
        imagePullPolicy: IfNotPresent
        name: nginx
        ports:
        - containerPort: 80
EOF

为上述服务定义Istio虚拟服务,为通过入口网关进入的流量进行路由配置,具体代码可以参见目录mtls-go-example/https下的文件mynginx-vs.yaml:


kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: nginx
spec:
  hosts:
  - "nginx.example.com"
  gateways:
  - mygateway
  http:
  - match:
    - uri:
        prefix: /
    route:
    - destination:
        port:
          number: 80
        host: nginx
EOF

重新部署Gateway,具体代码可以参见目录mtls-go-example/https下的文件mynginx-gateway.yaml:


kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: mygateway
spec:
  selector:
    istio: ingressgateway # 使用 Istio 默认的 Gateway
  servers:
  - port:
      number: 443
      name: https-httpbin
      protocol: HTTPS
    tls:
      mode: SIMPLE
      serverCertificate: /etc/istio/ingressgateway-certs/tls.crt
      privateKey: /etc/istio/ingressgateway-certs/tls.key
    hosts:
    - "httpbin.example.com"
  - port:
      number: 443
      name: https-nginx
      protocol: HTTPS
    tls:
      mode: SIMPLE
      serverCertificate: /etc/istio/ingressgateway-nginx-certs/tls.crt
      privateKey: /etc/istio/ingressgateway-nginx-certs/tls.key
    hosts:
    - "nginx.example.com"
EOF

通过HTTPS协议访问Nginx服务时可以访问到首页面,如下所示:


$ INGRESS_HOST={服务istio-ingressgateway的实际IP地址}
$ SECURE_INGRESS_PORT=443

$ curl -v -HHost:nginx.example.com --resolve nginx.example.com:$SECURE_INGRESS_
PORT:$INGRESS_HOST --cacert nginx.example.com/2_intermediate/certs/ca-chain.cert.pem https://nginx.example.com:$SECURE_INGRESS_PORT/index.html

* Added nginx.example.com:443:112.126.68.15 to DNS cache
* Hostname nginx.example.com was found in DNS cache
*   Trying 112.126.68.15...
* TCP_NODELAY set
* Connected to nginx.example.com (112.126.68.15) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: nginx.example.com/2_intermediate/certs/ca-chain.cert.pem
  CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305
* ALPN, server accepted to use h2
* Server certificate:
*  subject: C=US; ST=Denial; L=Springfield; O=Dis; CN=nginx.example.com
*  start date: Jan 10 02:33:53 2019 GMT
*  expire date: Jan 20 02:33:53 2020 GMT
*  common name: nginx.example.com (matched)
*  issuer: C=US; ST=Denial; O=Dis; CN=nginx.example.com
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x7f8c63805600)
> GET /index.html HTTP/2
> Host:nginx.example.com
> User-Agent: curl/7.54.0
> Accept: */*
>
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
< HTTP/2 200
< server: istio-envoy
< date: Tue, 19 Nov 2019 03:06:58 GMT
< content-type: text/html
< content-length: 612
< last-modified: Tue, 22 Oct 2019 14:30:00 GMT
< etag: "5daf1268-264"
< accept-ranges: bytes
< x-envoy-upstream-service-time: 0
<
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
* Connection #0 to host nginx.example.com left intact

再一次通过HTTPS协议访问httpbin服务,则会得到前面访问时相同的结果。