此任务向您展示如何在不更改授权策略的情况下从一个信任域迁移到另一个信任域。

在Istio 1.4中,我们引入了一个alpha特性来支持授权策略的信任域迁移。这意味着,如果Istio mesh需要更改其信任域,则不需要手动更改授权策略。在Istio中,如果一个工作负载运行在具有服务帐户栏的名称空间foo中,并且系统的信任域是my-td,那么该工作负载的标识就是spiffe://my-td/ns/foo/sa/bar。默认情况下,Istio mesh信任域是cluster.local,除非在安装期间指定

1. 准备工作

  1. 安装Istio时启用自定义信任域和双向TLS
  1. $ istioctl manifest apply --set profile=demo --set values.global.trustDomain=old-td
  1. 在默认名称空间中部署httpbin示例,在默认和sleep-allow的名称空间中部署sleep示例
  1. $ kubectl label namespace default istio-injection=enabled
  2. $ kubectl apply -f samples/httpbin/httpbin.yaml
  3. $ kubectl apply -f samples/sleep/sleep.yaml
  4. $ kubectl create namespace sleep-allow
  5. $ kubectl label namespace sleep-allow istio-injection=enabled
  6. $ kubectl apply -f samples/sleep/sleep.yaml -n sleep-allow
  1. 应用下面的授权策略来拒绝对httpbin的所有请求,除非来自sleep-allow名称空间中的sleep
  1. $ kubectl apply -f - <<EOF
  2. apiVersion: security.istio.io/v1beta1
  3. kind: AuthorizationPolicy
  4. metadata:
  5. name: service-httpbin.default.svc.cluster.local
  6. namespace: default
  7. spec:
  8. rules:
  9. - from:
  10. - source:
  11. principals:
  12. - old-td/ns/sleep-allow/sa/sleep
  13. to:
  14. - operation:
  15. methods:
  16. - GET
  17. selector:
  18. matchLabels:
  19. app: httpbin
  20. ---
  21. EOF

注意,将授权策略传播到sidecars可能需要数十秒的时间。

  1. 校验到httpbin的请求
  • 在默认名称空间的sleep是拒绝的
  1. $ kubectl exec $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c sleep -- curl http://httpbin.default:8000/ip -s -o /dev/null -w "%{http_code}\n"
  • sleep-allow名称空间是允许的
  1. $ kubectl exec $(kubectl -n sleep-allow get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c sleep -n sleep-allow -- curl http://httpbin.default:8000/ip -s -o /dev/null -w "%{http_code}\n"

2. 迁移没有信任域别名的信任域

  1. 安装Istio到一个新的信任域
  1. $ istioctl manifest apply --set profile=demo --set values.global.trustDomain=new-td

Istio网格现在运行在一个新的信任域,new-td

  1. 重新部署httpbin和sleep应用程序,以接收来自新Istio控制平面的更改。
  1. $ kubectl delete pod --all
  2. $ kubectl delete pod --all -n sleep-allow
  1. 验证从默认名称空间中的sleep和sleep-allow名称空间中对httpbin的请求都被拒绝。
  1. $ kubectl exec $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c sleep -- curl http://httpbin.default:8000/ip -s -o /dev/null -w "%{http_code}\n"
  1. $ kubectl exec $(kubectl -n sleep-allow get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c sleep -n sleep-allow -- curl http://httpbin.default:8000/ip -s -o /dev/null -w "%{http_code}\n"

这是因为我们指定了一个授权策略,该策略拒绝对httpbin的所有请求,除了旧的td/ns/sleep-allow/sa/sleep标识之外,这是sleep应用程序在sleep-allow名称空间中的旧标识。当我们迁移到上面的一个新的信任域,即new-td,这个睡眠应用程序的身份现在是new-td/ns/sleep-allow/sa/sleep,这与旧的td/ns/sleep-allow/sa/sleep不同。因此,以前允许sleep-allow名称空间中的sleep应用程序对httpbin的请求现在被拒绝。在Istio 1.4之前,完成此工作的唯一方法是手动更改授权策略。在Istio 1.4中,我们介绍了一种简单的方法,如下所示。

3. 迁移具有信任域别名的信任域

  1. 使用新的信任域和信任域别名安装Istio。
  1. $ cat <<EOF > ./td-installation.yaml
  2. apiVersion: install.istio.io/v1alpha1
  3. kind: IstioOperator
  4. spec:
  5. values:
  6. global:
  7. trustDomain: new-td
  8. trustDomainAliases:
  9. - old-td
  10. EOF
  11. istioctl manifest apply --set profile=demo -f td-installation.yaml
  1. 在不更改授权策略的情况下,验证从httpbin发出的请求
  • 在默认名称空间下的sleep是拒绝的
  1. $ kubectl exec $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c sleep -- curl http://httpbin.default:8000/ip -s -o /dev/null -w "%{http_code}\n"
  • sleep-allow名称空间的sleep是允许的
  1. $ kubectl exec $(kubectl -n sleep-allow get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c sleep -n sleep-allow -- curl http://httpbin.default:8000/ip -s -o /dev/null -w "%{http_code}\n"

3. 最佳实践

从Istio 1.4开始,在编写授权策略时,应该考虑使用值集群。本地作为策略中的信任域部分。例如,旧的td/ns/sleep-allow/sa/sleep应该是cluster.local/ns/sleep-allow/sa/sleep,而不是old-td/ns/sleep-allow/sa/sleep。注意,在本例中,是cluster。本地不是Istio mesh信任域(信任域仍然是old-td)。但是,在授权策略中,集群。local是指向当前信任域(即old-td(以及稍后的new-td))及其别名的指针。通过使用集群。在本地授权策略中,当您迁移到新的信任域时,Istio将检测到这一点,并将新信任域视为旧信任域,而不必包含别名。

4. 清空本实验

  1. $ kubectl delete authorizationpolicy service-httpbin.default.svc.cluster.local
  2. $ kubectl delete deploy httpbin; kubectl delete service httpbin; kubectl delete serviceaccount httpbin
  3. $ kubectl delete deploy sleep; kubectl delete service sleep; kubectl delete serviceaccount sleep
  4. $ kubectl delete namespace sleep-allow
  5. $ istioctl manifest generate --set profile=demo -f td-installation.yaml | kubectl delete --ignore-not-found=true -f -