• 通过 SDS 提供身份服务
    • 开始之前
    • 通过 SDS 提供的密钥和证书支持服务间的双向 TLS
    • 验证:没有通过加载 Secret 卷的方式生成的文件
    • 清理
    • 注意事项

    通过 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:

    Zip

    1. $ cat install/kubernetes/namespace.yaml > istio-auth-sds.yaml
    2. $ cat install/kubernetes/helm/istio-init/files/crd-* >> istio-auth-sds.yaml
    3. $ helm dep update --skip-refresh install/kubernetes/helm/istio
    4. $ 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
    5. $ kubectl create -f istio-auth-sds.yaml

    通过 SDS 提供的密钥和证书支持服务间的双向 TLS

    参考认证策略任务中的内容,部署测试服务。

    ZipZipZipZip

    1. $ kubectl create ns foo
    2. $ kubectl apply -f <(istioctl kube-inject -f @samples/httpbin/httpbin.yaml@) -n foo
    3. $ kubectl apply -f <(istioctl kube-inject -f @samples/sleep/sleep.yaml@) -n foo
    4. $ kubectl create ns bar
    5. $ kubectl apply -f <(istioctl kube-inject -f @samples/httpbin/httpbin.yaml@) -n bar
    6. $ kubectl apply -f <(istioctl kube-inject -f @samples/sleep/sleep.yaml@) -n bar

    验证双向 TLS 请求是否成功:

    1. $ 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
    2. sleep.foo to httpbin.foo: 200
    3. sleep.foo to httpbin.bar: 200
    4. sleep.bar to httpbin.foo: 200
    5. sleep.bar to httpbin.bar: 200

    验证:没有通过加载 Secret 卷的方式生成的文件

    要验证是否有通过加载 Secret 卷的方式生成的文件,可以访问工作负载的 Sidecar 容器:

    1. $ 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 控制面:

    1. $ kubectl delete ns foo
    2. $ kubectl delete ns bar
    3. $ kubectl delete -f istio-auth-sds.yaml

    注意事项

    目前 SDS 的身份服务有几点需要注意的地方:

    • 要启用控制面加密,还需要加载 Secret 卷。控制面的 SDS 支持还在开发之中。

    • 从 Secret 卷到 SDS 的平滑迁移过程,也还在开发之中。