通过ASM网关启用TLS透传
本文介绍如何通过ASM网关启用TLS透传,以实现对集群内HTTPS服务的安全入口访问。
前提条件
已创建ASM实例。具体操作,请参见创建ASM实例。
已创建Kubernetes托管版集群。具体操作,请参见创建Kubernetes托管版集群。
已添加集群到ASM实例。具体操作,请参见添加集群到ASM实例。
已部署入口网关。具体操作,请参见创建入口网关。
已部署应用到ASM实例。具体操作,请参见部署应用到ASM实例。
使用域名时需要备案才能正常访问,本示例中使用aliyun.com。
步骤一:生成服务器证书和私钥
如果您已经拥有针对sample.aliyun.com
可用的证书和私钥,需要将密钥命名为sample.aliyun.com.key
,证书命名为sample.aliyun.com.crt
。如果没有,可以通过openssl执行以下操作来生成证书和密钥。
执行以下命令,创建根证书和私钥。
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=mynginx Inc./CN=aliyun.com' -keyout aliyun.root.key -out aliyun.root.crt
执行以下命令,为
sample.aliyun.com
服务器生成证书和私钥。openssl req -out sample.aliyun.com.csr -newkey rsa:2048 -nodes -keyout sample.aliyun.com.key -subj "/CN=sample.aliyun.com/O=mynginx sample organization" openssl x509 -req -days 365 -CA aliyun.root.crt -CAkey aliyun.root.key -set_serial 0 -in sample.aliyun.com.csr -out sample.aliyun.com.crt
步骤二:定义内部服务
示例中的内部服务是基于Nginx实现的,首先为Nginx服务器创建配置文件。以域名aliyun.com的内部服务为例,定义请求根路径直接返回字样Welcome to aliyun.com without TLS Termination!
及状态码200。mynginx.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;
location / {
return 200 'Welcome to aliyun.com without TLS Termination!';
add_header Content-Type text/plain;
}
server_name www.aliyun.com;
ssl_certificate /etc/nginx-server-certs/tls.crt;
ssl_certificate_key /etc/nginx-server-certs/tls.key;
}
}
在入口网关Pod所在的集群对应的kubeconfig环境下,执行以下命令,创建Kubernetes ConfigMap存储Nginx服务器的配置。
kubectl create configmap mynginx-configmap --from-file=nginx.conf=./mynginx.conf
在入口网关Pod所在的集群对应的kubeconfig环境下,执行以下命令,将在default命名空间中创建包含证书和私钥的Secret。
kubectl create secret tls nginx-server-certs --key sample.aliyun.com.key --cert sample.aliyun.com.crt
在入口网关Pod所在的集群对应的kubeconfig环境下,执行以下命令,设置命名空间default,启用Sidecar网格代理自动注入。
kubectl label namespace default istio-injection=enabled
创建并拷贝以下内容到mynginxapp.yaml文件中,并执行
kubectl apply -f mynginxapp.yaml
命令,创建域名aliyun.com的内部服务。apiVersion: v1 kind: Service metadata: name: mynginxapp labels: app: mynginxapp spec: ports: - port: 443 protocol: TCP selector: app: mynginxapp --- apiVersion: apps/v1 kind: Deployment metadata: name: mynginxapp spec: selector: matchLabels: app: mynginxapp replicas: 1 template: metadata: labels: app: mynginxapp spec: containers: - name: nginx image: nginx:1.15 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: mynginx-configmap - name: nginx-server-certs secret: secretName: nginx-server-certs
确认Nginx服务器已成功部署,执行以下命令从其sidecar代理向服务器发送请求。
kubectl exec -it $(kubectl get pod -l app=mynginxapp -o jsonpath={.items..metadata.name}) -c istio-proxy -- curl -v -k --resolve sample.aliyun.com:443:127.0.0.1 https://sample.aliyun.com
步骤三:创建自定义网关配置对象
登录ASM控制台。
在左侧导航栏,选择 。
在网格管理页面,找到待配置的实例,单击实例的名称或在操作列中单击管理。
在网格详情页面左侧导航栏,选择 ,然后在右侧页面,单击使用YAML创建。
按以下步骤定义网关规则,然后单击创建。
选择相应的命名空间。本文以选择default命名空间为例。
在弹出窗口的文本框中,定义服务网关。可参考以下YAML定义。
apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: istio-mynginx-customingressgateway spec: selector: istio: ingressgateway servers: - hosts: - 'sample.aliyun.com' port: name: https number: 443 protocol: HTTPS tls: mode: PASSTHROUGH
在网关规则(Gateway)页面可以看到新建的网关。
步骤四:创建虚拟服务
登录ASM控制台。
在左侧导航栏,选择 。
在网格管理页面,找到待配置的实例,单击实例的名称或在操作列中单击管理。
在网格详情页面左侧导航栏,选择 ,然后在右侧页面,单击使用YAML创建。
按以下步骤定义虚拟服务,然后单击创建。
选择相应的命名空间。本文以选择default命名空间为例。
在文本框中,定义Istio虚拟服务。可参考以下YAML定义。
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: istio-mynginx-customvirtualservice spec: hosts: - "sample.aliyun.com" gateways: - istio-mynginx-customingressgateway tls: - match: - port: 443 sniHosts: - sample.aliyun.com route: - destination: host: mynginxapp.default.svc.cluster.local port: number: 443
在虚拟服务(VirtualService)页面可以看到新建的虚拟服务。
执行结果
可以通过以下任意一种方法获取入口网关服务的地址:
通过控制台查看,请参见查看入口网关的服务信息。
执行以下命令(注意是在入口网关Pod所在的集群对应的kubeconfig环境下),获取入口网关服务的地址。
kubectl get svc -n istio-system -l istio=ingressgateway
执行以下命令,通过HTTPS协议访问aliyun.com服务。
curl -v --cacert aliyun.root.crt --resolve sample.aliyun.com:443:xx.xx.xx.xx https://sample.aliyun.com
Welcome to aliyun.com without TLS Termination!%