安全网关(文件挂载)
控制 Ingress 流量任务5描述了如何配置一个 ingress 网关以将 HTTP 服务暴露给外部流量。本任务则展示了如何使用简单或双向 TLS 暴露安全 HTTPS 服务。
TLS 所必需的私钥、服务器证书和根证书使用基于文件挂载的方式进行配置。
开始之前
执行开始之前6任务和控制 Ingress 流量5任务中的确认 ingress 的 IP 和端口小节中的步骤。执行完毕后,Istio 和 httpbin7 服务都已经部署完毕。环境变量
INGRESS_HOST
和SECURE_INGRESS_PORT
也已经设置。对于 macOS 用户,确认您的 curl 使用了 LibreSSL8 库来编译:
如果以上输出打印了 LibreSSL 的版本,则 curl 应该可以按照此任务中的说明正常工作。否则,请尝试另一种 curl 版本,例如运行于 Linux 计算机的版本。
生成服务器证书和私钥
此任务您可以使用您喜欢的工具来生成证书和私钥。下列命令使用了 openssl9
创建一个根证书和私钥以为您的服务所用的证书签名:
为
httpbin.example.com
创建一个证书和私钥:
基于文件挂载的方式配置 TLS ingress 网关
本节中,您将配置一个使用 443 端口的 ingress 网关,以处理 HTTPS 流量。
首先使用证书和私钥创建一个 secret。该 secret 将被挂载为 /etc/istio/ingressgateway-certs
路径下的一个文件。
然后您可以创建一个网关定义,它将配置一个运行于端口 443 的服务。
创建一个 Kubernetes secret 以保存服务器的证书和私钥。使用
kubectl
在命名空间istio-system
下创建 secretistio-ingressgateway-certs
。Istio 网关将会自动加载该 secret。请注意,默认情况下,
istio-system
命名空间下的所有 pod 都能挂载这个 secret 并访问该私钥。您可以将 ingress 网关部署到一个单独的命名空间中,并在那创建 secret,这样就只有这个 ingress 网关 pod 才能挂载它。验证
tls.crt
和tls.key
是否都已经挂载到 ingress 网关 pod 中:为 443 端口定义
Gateway
并设置server
。配置路由以让流量从
Gateway
进入。定义与控制 Ingress 流量任务中相同的VirtualService
:使用 curl 发送一个
https
请求到SECURE_INGRESS_PORT
以通过 HTTPS 访问httpbin
服务。--resolve
标志让 curl 在通过 TLS 访问网关 IP 时支持 SNI10 值httpbin.example.com
。--cacert
选项则让 curl 使用您创建的证书来验证服务器。通过发送请求到
/status/418
URL 路径,您可以很好地看到您的httpbin
服务确实已被访问。httpbin
服务将返回 418 I’m a Teapot11 代码。在 curl 的输出中寻找 Server certificate 部分,尤其是找到与 common name 匹配的行:
common name: httpbin.example.com (matched)
。 输出中的SSL certificate verify ok
这一行表示服务端的证书验证成功。 如果一切顺利,您还应该看到返回的状态 418,以及精美的茶壶图。
配置双向 TLS ingress 网关
本节中您将您的网关的定义从上一节中扩展为支持外部客户端和网关之间的双向 TLS12。
创建一个 Kubernetes
Secret
以保存服务端将用来验证它的客户端的 CA13 证书。使用kubectl
在命名空间istio-system
中创建 secretistio-ingressgateway-ca-certs
。Istio 网关将会自动加载该 secret。重新定义之前的
Gateway
,修改 TLS 模式为MUTUAL
,并指定caCertificates
:像上一节中一样通过 HTTPS 访问
httpbin
服务:这次您将得到一个报错,因为服务端拒绝接受未认证的请求。您需要传递 curl 客户端证书和私钥以将请求签名。
为
httpbin.example.com
服务创建客户端证书。您可以使用httpbin-client.example.com
URI 来指定客户端,或使用其它 URI。重新用 curl 发送之前的请求,这次通过参数传递客户端证书(添加
--cert
选项)和您的私钥(--key
选项):这次服务器成功执行了客户端身份验证,您再次收到了漂亮的茶壶图。
为多主机配置 TLS ingress 网关
本节中您将为多个主机(httpbin.example.com
和 bookinfo.com
)配置 ingress 网关。
Ingress 网关将向客户端提供与每个请求的服务器相对应的唯一证书。
与之前的小节不同,Istio 默认 ingress 网关无法立即使用,因为它仅被预配置为支持一个安全主机。 您需要先使用另一个 secret 配置并重新部署 ingress 网关服务器,然后才能使用它来处理第二台主机。
为 bookinfo.com
创建服务器证书和私钥
使用新证书重新部署 istio-ingressgateway
创建一个新的 secret 以保存
bookinfo.com
的证书:更新
istio-ingressgateway
deployment 以挂载新创建的 secret。创建如下gateway-patch.json
文件以更新istio-ingressgateway
deployment:使用以下命令应用
istio-ingressgateway
deployment 更新:验证
istio-ingressgateway
pod 已成功加载私钥和证书:tls.crt
和tls.key
应该出现在文件夹之中。
配置 bookinfo.com
主机的流量
部署 Bookinfo 示例应用14,但不要部署网关:
为
bookinfo.com
定义网关:配置
bookinfo.com
的路由。定义类似samples/bookinfo/networking/bookinfo-gateway.yaml
16 的VirtualService
:发送到 Bookinfo
productpage
的请求:验证
httbin.example.com
像之前一样可访问。发送一个请求给它,您会再次看到您喜爱的茶壶:
问题排查
检查环境变量
INGRESS_HOST
和SECURE_INGRESS_PORT
的值。通过下列命令的输出确保它们都有有效值:验证
istio-ingressgateway
pod 已经成功加载了私钥和证书:tls.crt
和tls.key
应存在于文件夹之中。如果您已经创建了
istio-ingressgateway-certs
secret,但是私钥和证书未加载,删掉 ingress 网关 pod 以强行重启 ingress 网关 pod 并重新加载私钥和证书。验证 ingress 网关的证书的
Subject
是正确的:验证 ingress 网关的代理是否知道证书:
检查
istio-ingressgateway
的日志看是否有错误消息:
双向 TLS 问题排查
除了上一节中的步骤之外,请执行以下操作:
验证
istio-ingressgateway
pod 已经加载了 CA 证书:example.com.crt
应存在于文件夹之中。如果您已经创建了
istio-ingressgateway-ca-certs
secret,但是 CA 证书未加载,删掉 ingress 网关 pod 以强行重新加载证书:If you created the
istio-ingressgateway-ca-certs
secret, but the CA certificate is not loaded, delete the ingress gateway pod and force it to reload the certificate:验证 ingress 网关的 CA 证书的
Subject
是正确的:
清理
删除
Gateway
配置、VirtualService
和 secrets:删除证书目录和用于生成证书的存储库:
删除用于重新部署
istio-ingressgateway
的更新文件:关闭 httpbin7 服务: