Securing Gateways with HTTPS 任务描述了如何去配置HTTPS ingress访问一个HTTP服务;此案例描述了如何配置HTTPS ingress访问一个HTTPS服务。 例如,配置于个ingress gateway去执行SNI穿透,而不是在进入的请求那里执行TLS终结。

在这里的案例只是使用简单的NGINX 服务器。 所以先在kubernetes集群中部署一个NGINX服务。 然后你配置gateway,通过host 的nginx.example.com访问服务 。

1. 产生客户端和服务器的证书及key

  1. 创建一个根证书和私有Key,去给服务签署证书
  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
  1. 针对nginx.example.com创建证书和私有key
  1. $ openssl req -out nginx.example.com.csr -newkey rsa:2048 -nodes -keyout nginx.example.com.key -subj "/CN=nginx.example.com/O=some organization"
  2. $ openssl x509 -req -days 365 -CA example.com.crt -CAkey example.com.key -set_serial 0 -in nginx.example.com.csr -out nginx.example.com.crt

2. 部署NGINX 服务器

  1. 创建一个kubernetes Secret,该Secret拥有服务器证书
  1. $ kubectl create secret tls nginx-server-certs --key nginx.example.com.key --cert nginx.example.com.crt
  1. 创建针对NGINX服务器的配置文件
  1. $ cat <<EOF > ./nginx.conf
  2. events {
  3. }
  4. http {
  5. log_format main '$remote_addr - $remote_user [$time_local] $status '
  6. '"$request" $body_bytes_sent "$http_referer" '
  7. '"$http_user_agent" "$http_x_forwarded_for"';
  8. access_log /var/log/nginx/access.log main;
  9. error_log /var/log/nginx/error.log;
  10. server {
  11. listen 443 ssl;
  12. root /usr/share/nginx/html;
  13. index index.html;
  14. server_name nginx.example.com;
  15. ssl_certificate /etc/nginx-server-certs/tls.crt;
  16. ssl_certificate_key /etc/nginx-server-certs/tls.key;
  17. }
  18. }
  19. EOF
  1. 创建一个针对拥有NGINX 服务器配置的ConfigMap
  1. $ kubectl create configmap nginx-configmap --from-file=nginx.conf=./nginx.conf
  1. 部署NGINX server.
  1. $ cat <<EOF | istioctl kube-inject -f - | kubectl apply -f -
  2. apiVersion: v1
  3. kind: Service
  4. metadata:
  5. name: my-nginx
  6. labels:
  7. run: my-nginx
  8. spec:
  9. ports:
  10. - port: 443
  11. protocol: TCP
  12. selector:
  13. run: my-nginx
  14. ---
  15. apiVersion: apps/v1
  16. kind: Deployment
  17. metadata:
  18. name: my-nginx
  19. spec:
  20. selector:
  21. matchLabels:
  22. run: my-nginx
  23. replicas: 1
  24. template:
  25. metadata:
  26. labels:
  27. run: my-nginx
  28. spec:
  29. containers:
  30. - name: my-nginx
  31. image: nginx
  32. ports:
  33. - containerPort: 443
  34. volumeMounts:
  35. - name: nginx-config
  36. mountPath: /etc/nginx
  37. readOnly: true
  38. - name: nginx-server-certs
  39. mountPath: /etc/nginx-server-certs
  40. readOnly: true
  41. volumes:
  42. - name: nginx-config
  43. configMap:
  44. name: nginx-configmap
  45. - name: nginx-server-certs
  46. secret:
  47. secretName: nginx-server-certs
  48. EOF
  1. 在不检查服务器证书的请况下,从它的sidecar proxy发送一个请求到服务,来测试nginx服务器是否部署成功。确保服务器的证书成功打印,比如common namenginx.example.com
  1. $ kubectl exec -it $(kubectl get pod -l run=my-nginx -o jsonpath={.items..metadata.name}) -c istio-proxy -- curl -v -k --resolve nginx.example.com:443:127.0.0.1 https://nginx.example.com

3. 配置ingress gateway

  1. 定义针对端口443的Gateway。 注意那个PASSTHROUGH TLS模式告诉gateway去传输Ingress的流量,而不需要终止TLS.
  1. $ kubectl apply -f - <<EOF
  2. apiVersion: networking.istio.io/v1alpha3
  3. kind: Gateway
  4. metadata:
  5. name: mygateway
  6. spec:
  7. selector:
  8. istio: ingressgateway # use istio default ingress gateway
  9. servers:
  10. - port:
  11. number: 443
  12. name: https
  13. protocol: HTTPS
  14. tls:
  15. mode: PASSTHROUGH
  16. hosts:
  17. - nginx.example.com
  18. EOF
  1. 针对经过Gateway进入的流量配置路由
  1. $ kubectl apply -f - <<EOF
  2. apiVersion: networking.istio.io/v1alpha3
  3. kind: VirtualService
  4. metadata:
  5. name: nginx
  6. spec:
  7. hosts:
  8. - nginx.example.com
  9. gateways:
  10. - mygateway
  11. tls:
  12. - match:
  13. - port: 443
  14. sniHosts:
  15. - nginx.example.com
  16. route:
  17. - destination:
  18. host: my-nginx
  19. port:
  20. number: 443
  21. EOF
  1. 确定Ingress的IP和端口号
  1. $ export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
  2. $ export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].port}')
  3. $ export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].port}')
  4. $ export TCP_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="tcp")].port}')
  1. 从集群外部访问NGINX服务,注意返回回来的正确证书
  1. $

4. 清除本次实验

  1. 移除创建的kubernetes资源
  1. $ kubectl delete secret nginx-server-certs
  2. $ kubectl delete configmap nginx-configmap
  3. $ kubectl delete service my-nginx
  4. $ kubectl delete deployment my-nginx
  5. $ kubectl delete gateway mygateway
  6. $ kubectl delete virtualservice nginx
  1. 删除证书和key
  1. $ rm example.com.crt example.com.key nginx.example.com.crt nginx.example.com.key nginx.example.com.csr
  1. 删除产生的配置文件
  1. $ rm ./nginx.conf