当您需要对外提供加密的HTTPS访问时,可以通过ASM网关启用HTTPS安全服务。ASM网关支持证书的动态加载,您可以实时动态地配置私钥、服务器证书和根证书,无需重启网关或依赖Secret卷挂载,降低操作复杂性并消除因重启造成的服务中断风险。ASM网关能够监控并管理多个证书和私钥对,为不同的主机提供灵活且安全的通信能力,加强数据传输的安全性。
前提条件
背景信息
Istio支持动态加载证书。TLS(Transport Layer Security)所需的私钥、服务器证书以及根证书,都可以在网关不重启的条件下动态配置。ASM网关会监视所在命名空间中的Secret,通过Gateway CR实现动态加载。ASM网关的HTTPS协议支持有以下优势:
入口网关可以在不需要重启的情况下,动态添加、删除或更新所需要的证书、私钥或者对应的根证书。
不需要Secret卷挂载。创建Kubernetes Secret后,ASM网关会捕获该Secret,并将其包含的证书、私钥或根证书发送到入口网关。
ASM网关可以监视多个证书、私钥对,只需要为多个主机创建Secret并更新网关规则。
步骤一:为多个主机准备服务器证书和私钥
使用域名时需要备案才能正常访问。本示例中使用aliyun.com生成证书和私钥,并保存为Secret。
如果您已经拥有针对aliyun.com可用的证书和私钥,需要将密钥命名为aliyun.com.key,证书命名为aliyun.com.crt。如果没有,可以通过openssl,执行以下步骤来生成证书和密钥。
执行以下命令,创建根证书和私钥。
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=myexample Inc./CN=aliyun.com' -keyout aliyun.root.key -out aliyun.root.crt
执行以下命令,为aliyun.com服务器生成证书和私钥。
openssl req -out aliyun.com.csr -newkey rsa:2048 -nodes -keyout aliyun.com.key -subj "/CN=aliyun.com/O=myexample organization" openssl x509 -req -days 365 -CA aliyun.root.crt -CAkey aliyun.root.key -set_serial 0 -in aliyun.com.csr -out aliyun.com.crt
按照ASM实例版本,创建Secret或证书。
ASM实例为1.17以下
在入口网关Pod所在的集群对应的KubeConfig环境下,执行以下命令,在istio-system命名空间中创建包含证书和私钥的Secret。
kubectl create -n istio-system secret tls myexample-credential --key=aliyun.com.key --cert=aliyun.com.crt
重要Secret名称不能以istio或prometheus开头,且不能包含token字段。
ASM实例为1.17及以上
步骤二:为a.aliyun.com定义内部服务
示例中的内部服务是基于Nginx实现的,首先为Nginx服务器创建配置文件。以域名a.aliyun.com的内部服务为例,定义请求根路径直接返回字样Welcome to a.aliyun.com!
及状态码200
。myexample-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 80;
location /hello {
return 200 'Welcome to a.aliyun.com!';
add_header Content-Type text/plain;
}
}
}
在入口网关Pod所在的集群对应的KubeConfig环境下,执行以下命令,创建Kubernetes ConfigMap(存储Nginx服务器的配置)。
kubectl create configmap myexample-nginx-configmap --from-file=nginx.conf=./myexample-nginx.conf
为default命名空间启用Sidecar网格代理自动注入。具体操作,请参见启用自动注入。
创建并拷贝以下内容到myexampleapp.yaml文件,执行
kubectl apply -f myexampleapp.yaml
命令,创建域名a.aliyun.com的内部服务。
步骤三:为b.aliyun.com定义内部服务
本示例中的内部服务基于httpbin实现。
使用以下内容,创建httpbin.example.yaml文件。
在入口网关Pod所在的集群对应的KubeConfig环境下,执行以下命令,创建域名为b.aliyun.com的内部服务。
kubectl apply -f httpbin.example.yaml
步骤四:创建网关规则
登录ASM控制台,在左侧导航栏,选择 。
在网格管理页面,单击目标实例名称,然后在左侧导航栏,选择 ,然后单击使用YAML创建。
在创建页面,选择目标命名空间(本文以default为例)和任意场景模版,配置如下YAML,然后单击创建。
创建完成后,您可以在网关规则页面,看到新建的网关。
步骤五:创建虚拟服务
登录ASM控制台,在左侧导航栏,选择 。
在网格管理页面,单击目标实例名称,然后在左侧导航栏,选择 ,然后单击使用YAML创建。
在创建页面,选择目标命名空间和任意场景模版,配置以下YAML,然后单击创建。
重复此步骤,为b.aliyun.com定义相应的虚拟服务。
创建完成后,在虚拟服务页面,可以看到新建的虚拟服务。
执行结果
获取入口网关服务的地址
方式一:通过ASM控制台查看。登录ASM控制台,选中对应的服务网格实例,在左侧导航栏选择 。在入口网关页面中查看对应的信息。
方式二:通过容器服务管理控制台查看。具体操作,请参见查看入口网关的服务信息。
通过命令行访问入口网关服务
执行以下命令,通过HTTPS协议访问a.aliyun.com服务。
curl -k -H Host:a.aliyun.com --resolve a.aliyun.com:443:{替换成真实的入口网关IP地址} https://a.aliyun.com/hello
预期输出:
Welcome to aliyun.com!
执行以下命令,通过HTTPS协议访问b.aliyun.com服务。
curl -k -H Host:b.aliyun.com --resolve b.aliyun.com:443:{替换成真实的入口网关IP地址} https://b.aliyun.com/status/418
预期输出:
-=[ teapot ]=- _...._ .' _ _ `. | ."` ^ `". _, \_;`"---"`|// | ;/ \_ _/ `"""`
相关操作
更新网关证书
如果您要更新网关挂载的证书,需要在数据面新建一个Secret,然后修改Gateway资源的credentialName字段值为Secret的名称,网关将自动挂载新的Secret。本文以为example.com服务器创建名为new-istio-ingressgateway-certs的Secret为例。
创建颁发者为myexample的证书。
在OpenSSL工具中执行以下命令,创建根证书和私钥。
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=myexample Inc./CN=example.com' -keyout example.root.key -out example.root.crt
执行以下命令,为example.com服务器生成证书和私钥。
openssl req -out example.com.csr -newkey rsa:2048 -nodes -keyout example.com.key -subj "/CN=example.com/O=myexample organization" openssl x509 -req -days 365 -CA example.root.crt -CAkey example.root.key -set_serial 0 -in example.com.csr -out example.com.crt
执行以下命令,创建名为new-istio-ingressgateway-certs的Secret。
kubectl create -n istio-system secret tls new-istio-ingressgateway-certs --key example.com.key --cert example.com.crt
在集群中执行以下命令,删除旧的证书Secret。
kubectl delete secret istio-ingressgateway-certs -n istio-system
更新网关规则。
登录ASM控制台,在左侧导航栏,选择 。
在网格管理页面,单击目标实例名称,然后在左侧导航栏,选择 。
在网关规则页面,单击目标规则右侧操作列下的查看YAML。
在编辑对话框,修改credentialName参数值为新的证书Secret名称new-istio-ingressgateway-certs,然后单击确定。
验证更新网关证书是否成功。
执行以下命令,在集群中查看当前证书信息。
kubectl exec istio-ingressgateway-xxxx -n istio-system -- curl localhost:15000/config_dump > ingressgateway_dump.yaml
执行以下命令,打印并搜索new-istio-ingressgateway-certs证书。
cat ingressgateway_dump.yaml | grep new-istio-ingressgateway-certs -A 3
预期输出:
复制以上inline_bytes参数后的内容,获取Base64编码后的证书。
在本地命令行工具中执行以下命令,将证书进行Base64解码。
echo <Base64编码后的证书内容> | base64 --decode
将Base64解码内容保存为test.com.crt文件。
在OpenSSL工具中执行以下命令,查看证书的组织。
openssl x509 -in test.com.crt -text -noout
预期输出:
可以看到组织成功更换为
myexample
,说明网关证书更新成功。