istio-ingress无 TLS 终止的 Ingress Gateway

生成客户端和服务端的证书和密钥

对于此任务,您可以使用自己喜欢的工具来生成证书和密钥。以下命令使用 openssl

1、创建根证书和私钥来为您的服务签名证书:

openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout example.com.key -out example.com.crt

2、为 nginx.example.com 创建证书和私钥:

openssl req -out nginx.example.com.csr -newkey rsa:2048 -nodes -keyout nginx.example.com.key -subj "/CN=nginx.example.com/O=some organization"
openssl x509 -req -sha256 -days 365 -CA example.com.crt -CAkey example.com.key -set_serial 0 -in nginx.example.com.csr -out nginx.example.com.crt

部署一个 NGINX 服务

1、创建一个 Kubernetes 的 Secret 资源来保存服务的证书:

kubectl create secret tls nginx-server-certs --key nginx.example.com.key --cert nginx.example.com.crt

2、为 NGINX 服务创建一个配置文件:

cat <<\EOF > ./nginx.conf
events {
}

http {
  log_format main '$remote_addr - $remote_user [$time_local]  $status '
  '"$request" $body_bytes_sent "$http_referer" '
  '"$http_user_agent" "$http_x_forwarded_for"';
  access_log /var/log/nginx/access.log main;
  error_log  /var/log/nginx/error.log;

  server {
    listen 443 ssl;

    root /usr/share/nginx/html;
    index index.html;

    server_name nginx.example.com;
    ssl_certificate /etc/nginx-server-certs/tls.crt;
    ssl_certificate_key /etc/nginx-server-certs/tls.key;
  }
}
EOF

3、创建一个 Kubernetes 的 ConfigMap 资源来保存 NGINX 服务的配置:

kubectl create configmap nginx-configmap --from-file=nginx.conf=./nginx.conf

4、部署 NGINX 服务

cat <<EOF | istioctl kube-inject -f - | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
  name: my-nginx
  labels:
    run: my-nginx
spec:
  ports:
  - port: 443
    protocol: TCP
  selector:
    run: my-nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-nginx
spec:
  selector:
    matchLabels:
      run: my-nginx
  replicas: 1
  template:
    metadata:
      labels:
        run: my-nginx
    spec:
      containers:
      - name: my-nginx
        image: nginx
        ports:
        - containerPort: 443
        volumeMounts:
        - name: nginx-config
          mountPath: /etc/nginx
          readOnly: true
        - name: nginx-server-certs
          mountPath: /etc/nginx-server-certs
          readOnly: true
      volumes:
      - name: nginx-config
        configMap:
          name: nginx-configmap
      - name: nginx-server-certs
        secret:
          secretName: nginx-server-certs
EOF

5、要测试 NGINX 服务是否已成功部署,需要从其 Sidecar 代理发送请求,并忽略检查服务端的证书(使用 curl-k 选项)。确保正确打印服务端的证书,即 common name (CN) 等于 nginx.example.com

kubectl exec "$(kubectl get pod  -l run=my-nginx -o jsonpath={.items..metadata.name})" -c istio-proxy -- curl -sS -v -k --resolve nginx.example.com:443:127.0.0.1 https://nginx.example.com
...
SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
ALPN, server accepted to use http/1.1
Server certificate:
  subject: CN=nginx.example.com; O=some organization
  start date: May 27 14:18:47 2020 GMT
  expire date: May 27 14:18:47 2021 GMT
  issuer: O=example Inc.; CN=example.com
  SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.

> GET / HTTP/1.1
> User-Agent: curl/7.58.0
> Host: nginx.example.com
...
< HTTP/1.1 200 OK

< Server: nginx/1.17.10
...
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...

配置 Ingress Gateway

1、定义一个 server 部分的端口为 443 的 Gateway。注意,PASSTHROUGH tls TLS 模式,该模式指示 Gateway 以 AS IS 方式传递入口流量,而不终止 TLS。

kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: mygateway
spec:
  selector:
    istio: ingressgateway # use istio default ingress gateway
  servers:
  - port:
      number: 443
      name: https
      protocol: HTTPS
    tls:
      mode: PASSTHROUGH
    hosts:
    - nginx.example.com
EOF

2、为通过 Gateway 进入的流量配置路由:

kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: nginx
spec:
  hosts:
  - nginx.example.com
  gateways:
  - mygateway
  tls:
  - match:
    - port: 443
      sniHosts:
      - nginx.example.com
    route:
    - destination:
        host: my-nginx
        port:
          number: 443
EOF

3、根据确定 Ingress IP 和端口中的指令来定义环境变量 SECURE_INGRESS_PORTINGRESS_HOST

4、从集群外访问 NGINX 服务。注意,服务端返回了正确的证书,并且该证书已成功验证(输出了 _SSL certificate verify ok_)。

curl -v --resolve "nginx.example.com:$SECURE_INGRESS_PORT:$INGRESS_HOST" --cacert example.com.crt "https://nginx.example.com:$SECURE_INGRESS_PORT"
Server certificate:
  subject: CN=nginx.example.com; O=some organization
  start date: Wed, 15 Aug 2018 07:29:07 GMT
  expire date: Sun, 25 Aug 2019 07:29:07 GMT
  issuer: O=example Inc.; CN=example.com
  SSL certificate verify ok.

  < HTTP/1.1 200 OK
  < Server: nginx/1.15.2
  ...
  <html>
  <head>
  <title>Welcome to nginx!</title>

参考:

https://preliminary.istio.io/latest/zh/docs/tasks/traffic-management/ingress/ingress-sni-passthrough/

posted @ 2021-08-31 16:58  fat_girl_spring  阅读(133)  评论(0编辑  收藏  举报