入门

本指南有助于您快速评估 Istio 的 Ambient 模式。 这些步骤要求您有一个运行受支持版本的 Kubernetes (1.27, 1.28, 1.29, 1.30) Cluster。 您可以在任何被支持的 Kubernetes 平台上安装 Istio Ambient 模式, 但为了简单起见,本指南将假设使用 kind

请注意,Ambient 模式当前需要使用 istio-cni 来配置 Kubernetes 节点,该节点必须作为特权 Pod 运行。 Ambient 模式与之前支持 Sidecar 模式的所有主流 CNI 兼容。

请按照以下步骤开始使用 Istio 的 Ambient 模式:

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

下载和安装

  1. 安装 kind

  2. 下载对 Ambient 模式提供 Alpha 支持的最新 Istio 版本(v1.21.0 或更高)。

  3. 部署一个新的本地 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
  4. 安装大多数 Kubernetes 集群上默认并未安装的 Kubernetes Gateway API 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=v1.1.0" | kubectl apply -f -; }
  5. 使用上面下载的 istioctl 版本, 在 Kubernetes 集群上安装带有 ambient 配置文件的 Istio:

    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
  6. 使用以下命令验证已安装的组件:

    1. $ kubectl get pods,daemonset -n istio-system
    2. NAME READY STATUS RESTARTS AGE
    3. pod/istio-cni-node-btbjf 1/1 Running 0 2m18s
    4. pod/istiod-55b74b77bd-xggqf 1/1 Running 0 2m27s
    5. pod/ztunnel-5m27h 1/1 Running 0 2m10s
    6. NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
    7. daemonset.apps/istio-cni-node 1 1 1 1 1 kubernetes.io/os=linux 2m18s
    8. daemonset.apps/ztunnel 1 1 1 1 1 kubernetes.io/os=linux 2m10s

部署样例应用

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

使用 Ambient 模式时,请确保 default 命名空间不包含标签 istio-injection=enabled,因为您不需要 Istio 将 Sidecar 注入应用程序 Pod。

  1. 启动样例服务:

    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 客户端的两个简单应用。

  2. 部署一个 Ingress Gateway,这样您可以从集群外访问 bookinfo 应用:

    要在 kind 中获取服务类型为 Loadbalancer 的 IP 地址, 您可能需要安装 MetalLB 这类工具。更多细节请参阅此指南

    创建 Kubernetes GatewayHTTPRoute

    Zip

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

    设置 Kubernetes Gateway 的环境变量:

    1. $ kubectl wait --for=condition=programmed gtw/bookinfo-gateway
    2. $ export GATEWAY_HOST=bookinfo-gateway-istio.default
    3. $ export GATEWAY_SERVICE_ACCOUNT=ns/default/sa/bookinfo-gateway-istio
  3. 测试您的 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 网格

  1. 您可以通过简单地标记命名空间来使给定命名空间中的所有 Pod 成为 Ambient 网格的一部分:

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

    恭喜!您已成功将 default 命名空间中的所有 Pod 添加到网格中。 请注意,您不必重新启动或重新部署任何内容!

  2. 现在,发送一些测试流量:

    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 模式的应用之间立即达成 mTLS 通信和 L4 遥测。 如果按照指示说明安装 PrometheusKiali, 您将能够在 Kiali 的应用中直观地查看自己的应用:

Kiali 仪表盘

Kiali 仪表盘

确保应用访问安全

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

Layer 4 鉴权策略

  1. 显式允许 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
  2. 确认上述鉴权策略正在工作:

    1. $ # 这条命令应成功
    2. $ kubectl exec deploy/sleep -- curl -s "http://$GATEWAY_HOST/productpage" | grep -o "<title>.*</title>"
    3. <title>Simple Bookstore App</title>
    1. $ # 这条命令应成功
    2. $ kubectl exec deploy/sleep -- curl -s http://productpage:9080/ | grep -o "<title>.*</title>"
    3. <title>Simple Bookstore App</title>
    1. $ # 这条命令应失败且返回连接重置错误码 56
    2. $ kubectl exec deploy/notsleep -- curl -s http://productpage:9080/ | grep -o "<title>.*</title>"
    3. command terminated with exit code 56

Layer 7 鉴权策略

  1. 使用 Kubernetes Gateway API, 您可以为您的命名空间部署 waypoint 代理:

    1. $ istioctl x waypoint apply --enroll-namespace --wait
    2. waypoint default/waypoint applied
    3. namespace default labeled with "istio.io/use-waypoint: waypoint"
  2. 查看 waypoint 代理状态;您应该看到状态为 Programmed 的网关资源的详细信息:

    1. $ kubectl get gtw waypoint -o yaml
    2. ...
    3. status:
    4. conditions:
    5. - lastTransitionTime: "2024-04-18T14:25:56Z"
    6. message: Resource programmed, assigned to service(s) waypoint.default.svc.cluster.local:15008
    7. observedGeneration: 1
    8. reason: Programmed
    9. status: "True"
    10. type: Programmed
  3. 更新您的 AuthorizationPolicy 以显式允许 sleep 服务通过 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. targetRefs:
    9. - kind: Service
    10. group: ""
    11. name: productpage
    12. action: ALLOW
    13. rules:
    14. - from:
    15. - source:
    16. principals:
    17. - cluster.local/ns/default/sa/sleep
    18. to:
    19. - operation:
    20. methods: ["GET"]
    21. EOF
  4. 确认新的 waypoint 代理正在执行更新的鉴权策略:

    1. $ # this should fail with an RBAC error because it is not a GET operation
    2. $ kubectl exec deploy/sleep -- curl -s "http://productpage:9080/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>

控制流量

  1. 您可以使用相同的 waypoint 来控制 reviews 的流量。 配置流量路由以将 90% 的请求发送到 reviews v1,将 10% 发送到 reviews v2:

    ZipZip

    1. $ kubectl apply -f @samples/bookinfo/platform/kube/bookinfo-versions.yaml@
    2. $ kubectl apply -f @samples/bookinfo/gateway-api/route-reviews-90-10.yaml@
  2. 确认 100 个请求中大约有 10% 流量转到 reviews-v2:

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

卸载

  1. 默认情况下,不会删除指示 Istio 自动将 default 命名空间中的应用程序包含到 Ambient 网格中的标签。 如果不再需要,请使用以下命令将其删除:

    1. $ kubectl label namespace default istio.io/dataplane-mode-
    2. $ kubectl label namespace default istio.io/use-waypoint-
  2. 要删除 waypoint 代理、已安装的策略并卸载 Istio:

    1. $ istioctl x waypoint delete --all
    2. $ istioctl uninstall -y --purge
    3. $ kubectl delete namespace istio-system
  3. 若要删除 Bookinfo 样例应用及其配置, 请参阅 Bookinfo 清理

  4. 移除 sleepnotsleep 应用:

    ZipZip

    1. $ kubectl delete -f @samples/sleep/sleep.yaml@
    2. $ kubectl delete -f @samples/sleep/notsleep.yaml@
  5. 如果您安装了 Gateway API CRD,执行以下命令移除:

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