Securing Gateways with HTTPS 任务描述了如何去配置HTTPS ingress访问一个HTTP服务;此案例描述了如何配置HTTPS ingress访问一个HTTPS服务。 例如,配置于个ingress gateway去执行SNI穿透,而不是在进入的请求那里执行TLS终结。
在这里的案例只是使用简单的NGINX 服务器。 所以先在kubernetes集群中部署一个NGINX服务。 然后你配置gateway,通过host 的nginx.example.com访问服务 。
1. 产生客户端和服务器的证书及key
- 创建一个根证书和私有Key,去给服务签署证书
$ 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
- 针对nginx.example.com创建证书和私有key
$ 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 -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 服务器
- 创建一个kubernetes Secret,该Secret拥有服务器证书
$ kubectl create secret tls nginx-server-certs --key nginx.example.com.key --cert nginx.example.com.crt
- 创建针对NGINX服务器的配置文件
$ cat <<EOF > ./nginx.confevents {}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
- 创建一个针对拥有NGINX 服务器配置的
ConfigMap
$ kubectl create configmap nginx-configmap --from-file=nginx.conf=./nginx.conf
- 部署NGINX server.
$ cat <<EOF | istioctl kube-inject -f - | kubectl apply -f -apiVersion: v1kind: Servicemetadata:name: my-nginxlabels:run: my-nginxspec:ports:- port: 443protocol: TCPselector:run: my-nginx---apiVersion: apps/v1kind: Deploymentmetadata:name: my-nginxspec:selector:matchLabels:run: my-nginxreplicas: 1template:metadata:labels:run: my-nginxspec:containers:- name: my-nginximage: nginxports:- containerPort: 443volumeMounts:- name: nginx-configmountPath: /etc/nginxreadOnly: true- name: nginx-server-certsmountPath: /etc/nginx-server-certsreadOnly: truevolumes:- name: nginx-configconfigMap:name: nginx-configmap- name: nginx-server-certssecret:secretName: nginx-server-certsEOF
- 在不检查服务器证书的请况下,从它的sidecar proxy发送一个请求到服务,来测试nginx服务器是否部署成功。确保服务器的证书成功打印,比如
common name是nginx.example.com
$ 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
- 定义针对端口443的Gateway。 注意那个
PASSTHROUGHTLS模式告诉gateway去传输Ingress的流量,而不需要终止TLS.
$ kubectl apply -f - <<EOFapiVersion: networking.istio.io/v1alpha3kind: Gatewaymetadata:name: mygatewayspec:selector:istio: ingressgateway # use istio default ingress gatewayservers:- port:number: 443name: httpsprotocol: HTTPStls:mode: PASSTHROUGHhosts:- nginx.example.comEOF
- 针对经过Gateway进入的流量配置路由
$ kubectl apply -f - <<EOFapiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata:name: nginxspec:hosts:- nginx.example.comgateways:- mygatewaytls:- match:- port: 443sniHosts:- nginx.example.comroute:- destination:host: my-nginxport:number: 443EOF
- 确定Ingress的IP和端口号
$ export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')$ export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].port}')$ export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].port}')$ export TCP_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="tcp")].port}')
- 从集群外部访问NGINX服务,注意返回回来的正确证书
$
4. 清除本次实验
- 移除创建的kubernetes资源
$ kubectl delete secret nginx-server-certs$ kubectl delete configmap nginx-configmap$ kubectl delete service my-nginx$ kubectl delete deployment my-nginx$ kubectl delete gateway mygateway$ kubectl delete virtualservice nginx
- 删除证书和key
$ rm example.com.crt example.com.key nginx.example.com.crt nginx.example.com.key nginx.example.com.csr
- 删除产生的配置文件
$ rm ./nginx.conf
