在ASM网关和Sideca代理之间,所有数据均通过mTLS隧道传输。如果应用注入了Sidecar,建议在网关处配置TLS终止,此时仍能保证全程加密。如果应用没有注入Sidecar或者有其他特殊情况,ASM网关同样支持TLS透传。本文介绍如何通过ASM网关启用TLS透传,以实现对集群内HTTPS服务的安全入口访问。
前提条件
已添加集群到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
为default命名空间启用Sidecar网格代理自动注入。具体操作,请参见启用自动注入。
创建并拷贝以下内容到mynginxapp.yaml文件中,并执行
kubectl apply -f mynginxapp.yaml
命令,创建域名aliyun.com的内部服务。确认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)页面可以看到新建的虚拟服务。
执行结果
通过以下任意方式获取入口网关的地址。
方式一:通过控制台获取。具体操作,请参见获取入口网关地址。
方式二:通过kubectl命令获取。
在入口网关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!%