Ambient Mesh 入门

Ambient 目前处于 Alpha 状态

请勿在生产环境中使用 Ambient 模式, 务必先行斟酌特性阶段定义再行使用 Ambient。 具体而言,alpha 版本意味着存在已知的性能、稳定性和安全性问题, 还存在一些计划中的破坏性变更,其中某些变更可能会令升级失败。 这些是进阶至 beta 之前需要解决的问题。

本指南有助于您快速评估 Istio ambient service mesh。 以下操作步骤需要您有一个 cluster 运行了 Kubernetes (1.25, 1.26, 1.27, 1.28) 的支持版本。 您可以使用所有受支持的平台,例如 Minikube特定平台搭建指南中所述的其他平台。

参照以下步骤开始使用 Ambient:

  1. 下载和安装
  2. 部署相同的应用
  3. 添加应用到 Ambient
  4. 确保应用访问安全
  5. 控制流量
  6. 卸载

下载和安装

  1. 下载对 Ambient Mesh 提供 alpha 支持的最新 Istio 版本

  2. 如果您没有 Kubernetes 集群,可以参照以下命令使用 kind 在本地部署一个集群:

    1. $ kind create cluster --config=- <<EOF
    2. kind: Cluster
    3. apiVersion: kind.x-k8s.io/v1alpha4
    4. name: ambient
    5. nodes:
    6. - role: control-plane
    7. - role: worker
    8. - role: worker
    9. EOF
  3. 安装大多数 Kubernetes 集群上默认并未安装的 Kubernetes Gateway CRD:

    1. $ kubectl get crd gateways.gateway.networking.k8s.io &> /dev/null || \
    2. { kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd/experimental?ref=v0.8.0" | kubectl apply -f -; }

    Istio 包括了对 Kubernetes Gateway API 的 Beta 支持, 打算未来使其成为流量管理的默认 API。 以下说明指导您在网格中配置流量管理时如何选择使用 Gateway API 或 Istio 配置 API。 请按照您的首选项遵循 Gateway APIIstio APIs 页签中的指示说明。

  4. ambient 配置文件设计用于帮助您开始使用 Ambient Mesh。 使用刚下载的 istioctl 命令,在您的 Kubernetes 集群上安装附带 ambient 配置文件的 Istio:

  1. $ istioctl install --set profile=ambient --set components.ingressGateways[0].enabled=true --set components.ingressGateways[0].name=istio-ingressgateway --skip-confirmation

运行上一条命令后,您将看到以下输出, 表明(包括 Ztunnel 在内的)五个组件已被成功安装!

  1. Istio core installed
  2. Istiod installed
  3. CNI installed
  4. Ingress gateways installed
  5. Ztunnel installed
  6. Installation complete
  1. $ istioctl install --set profile=ambient --skip-confirmation

运行上一条命令后,您将看到以下输出, 表明(包括 Ztunnel 在内的)五个组件已被成功安装!

  1. Istio core installed
  2. Istiod installed
  3. CNI installed
  4. Ztunnel installed
  5. Installation complete
  1. 使用以下命令确认已安装的组件:
  1. $ kubectl get pods -n istio-system
  2. NAME READY STATUS RESTARTS AGE
  3. istio-cni-node-n9tcd 1/1 Running 0 57s
  4. istio-ingressgateway-5b79b5bb88-897lp 1/1 Running 0 57s
  5. istiod-69d4d646cd-26cth 1/1 Running 0 67s
  6. ztunnel-lr7lz 1/1 Running 0 69s
  1. $ kubectl get daemonset -n istio-system
  2. NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
  3. istio-cni-node 1 1 1 1 1 kubernetes.io/os=linux 70s
  4. ztunnel 1 1 1 1 1 kubernetes.io/os=linux 82s
  1. $ kubectl get pods -n istio-system
  2. NAME READY STATUS RESTARTS AGE
  3. istio-cni-node-n9tcd 1/1 Running 0 57s
  4. istiod-69d4d646cd-26cth 1/1 Running 0 67s
  5. ztunnel-lr7lz 1/1 Running 0 69s
  1. $ kubectl get daemonset -n istio-system
  2. NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
  3. istio-cni-node 1 1 1 1 1 kubernetes.io/os=linux 70s
  4. ztunnel 1 1 1 1 1 kubernetes.io/os=linux 82s

部署样例应用

您将使用样例 bookinfo 应用,这是刚下载的 Istio 发行版默认包含的应用。 在 Ambient 模式中,您将这些应用部署到 Kubernetes 集群的方式与没有 Istio 时的部署方式完全相同。 这意味着您可以先让这些应用在集群中运行,再启用 Ambient Mesh, 最后将这些应用接入到网格,无需重启,也无需重新配置这些应用。

确保 default 命名空间未包括标签 istio-injection=enabled, 因为使用 Ambient 时,您不会想要 Istio 将 Sidecar 注入到应用 Pod 中。

Zip

  1. $ kubectl apply -f @samples/bookinfo/platform/kube/bookinfo.yaml@

ZipZip

  1. $ kubectl apply -f @samples/sleep/sleep.yaml@
  2. $ kubectl apply -f @samples/sleep/notsleep.yaml@

注:sleepnotsleep 是可以用作 curl 客户端的两个简单应用。

创建 Istio GatewayVirtualService, 这样您可以通过 Istio Ingress Gateway 访问 bookinfo 应用。

Zip

  1. $ kubectl apply -f @samples/bookinfo/networking/bookinfo-gateway.yaml@

为 Istio Ingress Gateway 设置环境变量:

  1. $ export GATEWAY_HOST=istio-ingressgateway.istio-system
  2. $ export GATEWAY_SERVICE_ACCOUNT=ns/istio-system/sa/istio-ingressgateway-service-account

创建 Kubernetes GatewayHTTPRoute, 这样您可以从集群外访问 bookinfo 应用:

Zip

  1. $ sed -e 's/from: Same/from: All/'\
  2. -e '/^ name: bookinfo-gateway/a\
  3. namespace: istio-system\
  4. ' -e '/^ - name: bookinfo-gateway/a\
  5. namespace: istio-system\
  6. ' @samples/bookinfo/gateway-api/bookinfo-gateway.yaml@ | kubectl apply -f -

为 Kubernetes Gateway 设置环境变量:

  1. $ kubectl wait --for=condition=programmed gtw/bookinfo-gateway -n istio-system
  2. $ export GATEWAY_HOST=bookinfo-gateway-istio.istio-system
  3. $ export GATEWAY_SERVICE_ACCOUNT=ns/istio-system/sa/bookinfo-gateway-istio

测试您的 bookinfo 应用,无论是否有网关都应该能够正常工作。

  1. $ kubectl exec deploy/sleep -- curl -s "http://$GATEWAY_HOST/productpage" | grep -o "<title>.*</title>"
  2. <title>Simple Bookstore App</title>
  1. $ kubectl exec deploy/sleep -- curl -s http://productpage:9080/ | grep -o "<title>.*</title>"
  2. <title>Simple Bookstore App</title>
  1. $ kubectl exec deploy/notsleep -- curl -s http://productpage:9080/ | grep -o "<title>.*</title>"
  2. <title>Simple Bookstore App</title>

添加应用到 Ambient

您只需给命名空间打标签,就可以作为 Ambient Mesh 的一部分,在给定的命名空间启用所有 Pod:

  1. $ kubectl label namespace default istio.io/dataplane-mode=ambient

恭喜!您已成功将 default 命名空间中的所有 Pod 添加到 Ambient Mesh。 体验最佳的地方在于无需重启,也无需重新部署任何组件!

发送一些测试流量:

  1. $ kubectl exec deploy/sleep -- curl -s "http://$GATEWAY_HOST/productpage" | grep -o "<title>.*</title>"
  2. <title>Simple Bookstore App</title>
  1. $ kubectl exec deploy/sleep -- curl -s http://productpage:9080/ | grep -o "<title>.*</title>"
  2. <title>Simple Bookstore App</title>
  1. $ kubectl exec deploy/notsleep -- curl -s http://productpage:9080/ | grep -o "<title>.*</title>"
  2. <title>Simple Bookstore App</title>

您将在 Ambient Mesh 的应用之间立即达成 mTLS 通信和 L4 遥测。 如果按照指示说明安装 PrometheusKiali, 您将能够在 Kiali 的应用中直观地查看自己的应用:

Kiali dashboard

Kiali dashboard

确保应用访问安全

将您的应用添加到 Ambient Mesh 之后,可以使用 L4 鉴权策略确保应用访问的安全。 这允许您基于客户端负载身份来控制到服务的访问或源于服务的访问, 但类似 GETPOST 的这些 HTTP 方法并不在 L7 级别。

L4 鉴权策略

显式允许 sleep 服务账号和 istio-ingressgateway 服务账号调用 productpage 服务:

  1. $ kubectl apply -f - <<EOF
  2. apiVersion: security.istio.io/v1beta1
  3. kind: AuthorizationPolicy
  4. metadata:
  5. name: productpage-viewer
  6. namespace: default
  7. spec:
  8. selector:
  9. matchLabels:
  10. app: productpage
  11. action: ALLOW
  12. rules:
  13. - from:
  14. - source:
  15. principals:
  16. - cluster.local/ns/default/sa/sleep
  17. - cluster.local/$GATEWAY_SERVICE_ACCOUNT
  18. EOF

确认上述鉴权策略正在工作:

  1. $ # this should succeed
  2. $ kubectl exec deploy/sleep -- curl -s "http://$GATEWAY_HOST/productpage" | grep -o "<title>.*</title>"
  3. <title>Simple Bookstore App</title>
  1. $ # this should succeed
  2. $ kubectl exec deploy/sleep -- curl -s http://productpage:9080/ | grep -o "<title>.*</title>"
  3. <title>Simple Bookstore App</title>
  1. $ # this should fail with a connection reset error code 56
  2. $ kubectl exec deploy/notsleep -- curl -s http://productpage:9080/ | grep -o "<title>.*</title>"
  3. command terminated with exit code 56

L7 鉴权策略

使用 Kubernetes Gateway API,您可以为使用 bookinfo-productpage 服务账号的 productpage 服务来部署 waypoint proxy。 转到 productpage 服务的所有流量都将通过 L7 代理被协调、执行和观测。

productpage 服务部署 waypoint proxy:

  1. $ istioctl x waypoint apply --service-account bookinfo-productpage
  2. waypoint default/bookinfo-productpage applied

查看 productpage waypoint proxy 状态;您应看到处于 Programmed 状态的网关资源详情:

  1. $ kubectl get gtw bookinfo-productpage -o yaml
  2. ...
  3. status:
  4. conditions:
  5. - lastTransitionTime: "2023-02-24T03:22:43Z"
  6. message: Resource programmed, assigned to service(s) bookinfo-productpage-istio-waypoint.default.svc.cluster.local:15008
  7. observedGeneration: 1
  8. reason: Programmed
  9. status: "True"
  10. type: Programmed

更新 AuthorizationPolicy 以显式允许 sleep 和 Gateway 服务账号以 GET productpage 服务,但不执行其他操作:

  1. $ kubectl apply -f - <<EOF
  2. apiVersion: security.istio.io/v1beta1
  3. kind: AuthorizationPolicy
  4. metadata:
  5. name: productpage-viewer
  6. namespace: default
  7. spec:
  8. selector:
  9. matchLabels:
  10. istio.io/gateway-name: bookinfo-productpage
  11. action: ALLOW
  12. rules:
  13. - from:
  14. - source:
  15. principals:
  16. - cluster.local/ns/default/sa/sleep
  17. - cluster.local/$GATEWAY_SERVICE_ACCOUNT
  18. to:
  19. - operation:
  20. methods: ["GET"]
  21. EOF
  1. $ # this should fail with an RBAC error because it is not a GET operation
  2. $ kubectl exec deploy/sleep -- curl -s "http://$GATEWAY_HOST/productpage" -X DELETE
  3. RBAC: access denied
  1. $ # this should fail with an RBAC error because the identity is not allowed
  2. $ kubectl exec deploy/notsleep -- curl -s http://productpage:9080/
  3. RBAC: access denied
  1. $ # this should continue to work
  2. $ kubectl exec deploy/sleep -- curl -s http://productpage:9080/ | grep -o "<title>.*</title>"
  3. <title>Simple Bookstore App</title>

控制流量

使用 bookinfo-review 服务账号为评审服务部署一个 waypoint proxy, 因此转到评审服务的所有流量都将通过 waypoint proxy 进行协调。

  1. $ istioctl x waypoint apply --service-account bookinfo-reviews
  2. waypoint default/bookinfo-reviews applied

应用评审虚拟服务以控制 90% 流量到 reviews-v1,控制 10% 流量到 reviews-v2。

ZipZip

  1. $ kubectl apply -f @samples/bookinfo/networking/virtual-service-reviews-90-10.yaml@
  2. $ kubectl apply -f @samples/bookinfo/networking/destination-rule-reviews.yaml@

ZipZip

  1. $ kubectl apply -f @samples/bookinfo/networking/virtual-service-reviews-90-10.yaml@
  2. $ kubectl apply -f @samples/bookinfo/networking/destination-rule-reviews.yaml@

创建 bookinfo 服务的子集,以控制到 reviews v1 和 v2 的流量:

Zip

  1. $ kubectl apply -f @samples/bookinfo/platform/kube/bookinfo-versions.yaml@

创建 HTTPRoute 以控制 90% 流量到 reviews v1 而 10% 流量到 reviews v2。

Zip

  1. $ kubectl apply -f @samples/bookinfo/gateway-api/route-reviews-90-10.yaml@

确认 100 个请求中大约有 10% 流量转到 reviews-v2:

  1. $ kubectl exec deploy/sleep -- sh -c "for i in \$(seq 1 100); do curl -s http://$GATEWAY_HOST/productpage | grep reviews-v.-; done"

卸载

若要移除 productpage-viewer 鉴权策略、waypoint proxy 并卸载 Istio:

  1. $ kubectl delete authorizationpolicy productpage-viewer
  2. $ istioctl x waypoint delete --service-account bookinfo-reviews
  3. $ istioctl x waypoint delete --service-account bookinfo-productpage
  4. $ istioctl uninstall -y --purge
  5. $ kubectl delete namespace istio-system

指示 Istio 自动在 default 命名空间中包括应用程序的标签默认不会被移除。 如果不再需要此标签,请使用以下命令来移除:

  1. $ kubectl label namespace default istio.io/dataplane-mode-

若要删除 Bookinfo 样例应用及其配置,请参阅 Bookinfo 清理

移除 sleepnotsleep 应用:

ZipZip

  1. $ kubectl delete -f @samples/sleep/sleep.yaml@
  2. $ kubectl delete -f @samples/sleep/notsleep.yaml@

如果您安装了 Gateway API CRD,执行以下命令移除:

  1. $ kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd/experimental?ref=v0.8.0" | kubectl delete -f -