通过 SDS 提供身份服务
该任务展示了启用 SDS (secret discovery service) 来为 Istio 提供身份服务的过程。
Istio 1.1 之前,Istio 为工作负载提供的密钥和证书是由 Citadel 生成并使用加载 Secret 卷的方式分发给 Sidecar 的,这种方式有几大缺陷:
证书轮换造成的性能损失:证书发生轮换时,Envoy 会进行热重启以加载新的证书和密钥,会造成性能下降。
潜在的安全漏洞:工作负载的私钥使用 Kubernetes Secret 的方式进行分发,存在一定风险。
在 Istio 1.1 之中,上述问题可以使用 SDS 来解决。下面描述了它的工作流程:
工作负载的 Sidecar 从 Citadel 代理中请求密钥和证书:Citadel 代理是一个 SDS 服务器,这一代理以
DaemonSet
的形式在每个节点上运行,在这一请求中,Envoy 把 Kubernetes service account 的 JWT 传递给 Citadel 代理。Citadel 代理生成密钥对,并向 Citadel 发送 CSR 请求:Citadel 校验 JWT,并给 Citadel 代理签发证书。
Citadel 代理把密钥和证书返回给工作负载的 Sidecar。
这种方法有如下好处:
私钥不会离开节点:私钥仅存在于 Citadel 代理和 Envoy Sidecar 的内存中。
不再需要加载 Secret 卷:去掉对 Kubernetes Secret 的依赖。
Sidecar 能够利用 SDS API 动态的刷新密钥和证书:证书轮换过程不再需要重启 Envoy。
开始之前
- 使用 Helm 安装 Istio,并启用 SDS 和全局的双向 TLS:
$ cat install/kubernetes/namespace.yaml > istio-auth-sds.yaml
$ cat install/kubernetes/helm/istio-init/files/crd-* >> istio-auth-sds.yaml
$ helm dep update --skip-refresh install/kubernetes/helm/istio
$ helm template install/kubernetes/helm/istio --name istio --namespace istio-system --values @install/kubernetes/helm/istio/values-istio-sds-auth.yaml@ >> istio-auth-sds.yaml
$ kubectl create -f istio-auth-sds.yaml
通过 SDS 提供的密钥和证书支持服务间的双向 TLS
参考认证策略任务中的内容,部署测试服务。
$ kubectl create ns foo
$ kubectl apply -f <(istioctl kube-inject -f @samples/httpbin/httpbin.yaml@) -n foo
$ kubectl apply -f <(istioctl kube-inject -f @samples/sleep/sleep.yaml@) -n foo
$ kubectl create ns bar
$ kubectl apply -f <(istioctl kube-inject -f @samples/httpbin/httpbin.yaml@) -n bar
$ kubectl apply -f <(istioctl kube-inject -f @samples/sleep/sleep.yaml@) -n bar
验证双向 TLS 请求是否成功:
$ for from in "foo" "bar"; do for to in "foo" "bar"; do kubectl exec $(kubectl get pod -l app=sleep -n ${from} -o jsonpath={.items..metadata.name}) -c sleep -n ${from} -- curl "http://httpbin.${to}:8000/ip" -s -o /dev/null -w "sleep.${from} to httpbin.${to}: %{http_code}\n"; done; done
sleep.foo to httpbin.foo: 200
sleep.foo to httpbin.bar: 200
sleep.bar to httpbin.foo: 200
sleep.bar to httpbin.bar: 200
验证:没有通过加载 Secret 卷的方式生成的文件
要验证是否有通过加载 Secret 卷的方式生成的文件,可以访问工作负载的 Sidecar 容器:
$ kubectl exec -it $(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name}) -c istio-proxy -n foo -- /bin/bash
这里会看到,在 /etc/certs
文件夹中没有加载 Secret 卷生成的文件。
清理
清理测试服务以及 Istio 控制面:
$ kubectl delete ns foo
$ kubectl delete ns bar
$ kubectl delete -f istio-auth-sds.yaml
注意事项
目前 SDS 的身份服务有几点需要注意的地方:
要启用控制面加密,还需要加载 Secret 卷。控制面的 SDS 支持还在开发之中。
从 Secret 卷到 SDS 的平滑迁移过程,也还在开发之中。