双栈 Kubernetes 集群支持

对双栈 Kubernetes 集群的实验性支持。

2023年3月10日 | 作者:Steve Zhang - 英特尔,Alex Xu - 英特尔,Iris Ding - 英特尔,Jacob Delgado - F5,Ying-chun Cai - 前 F5 员工

在过去的一年里,英特尔和 F5 合作努力将对 Kubernetes 双栈网络 的支持引入 Istio。

背景

这段旅程比我们预期的要长,我们还有很多工作要做。团队最初基于 F5 的参考实现设计了一个方案。该设计导致了一个 RFC,促使我们重新审视我们的方法。值得注意的是,社区担心内存和性能问题,希望在实施之前解决这些问题。最初的设计必须为监听器、集群、路由和端点复制 Envoy 配置。鉴于许多人已经遇到 Envoy 内存和 CPU 消耗问题,早期反馈希望我们彻底重新评估这种方法。许多代理透明地处理出站双栈流量,无论流量的来源如何。最早的许多反馈都是要求在 Istio 和 Envoy 中实现相同的行为。

重新定义双栈支持

社区对最初 RFC 提供的许多反馈意见都是更新 Envoy 以更好地在内部支持双栈用例,而不是在 Istio 中支持它。这导致我们采用了 新的设计,其中我们吸取了经验教训以及反馈意见,并将其应用于简化的设计。

Istio 1.17 中对双栈的支持

我们与 Envoy 社区合作解决了众多问题,这也是双栈启用花费了我们一段时间来实现的原因。我们实现了 出站监听器的匹配 IP 族每个监听器支持多个地址。Alex Xu 也一直在努力解决长期未解决的问题,使 Envoy 能够 更智能地为双栈选择端点。Envoy 的一些改进,例如能够 在多个地址上启用套接字选项,已在 Istio 1.17 版本中发布(例如 入站集群上的额外源地址)。

团队在 Envoy API 上进行的更改可以在其网站上找到,网址为 监听器地址绑定配置。确保我们可以在 Envoy 的下游和上游连接处都提供适当的支持对于实现双栈支持至关重要。

总的来说,团队已向 Envoy 提交了十多个 PR,并且正在努力提交至少六个 PR,以使 Istio 更轻松地采用双栈。

同时,在 Istio 端,您可以跟踪 问题 #40394 中的进度。由于我们继续与 Envoy 合作解决各种问题,因此最近进度有所放缓,但是,我们很高兴地宣布 Istio 1.17 中对双栈的实验性支持!

使用双栈的快速实验

  1. 使用以下命令在 Istio 1.17.0+ 上启用双栈实验性支持

    $ istioctl install -y -f - <<EOF
    apiVersion: install.istio.io/v1alpha1
    kind: IstioOperator
    spec:
      meshConfig:
        defaultConfig:
          proxyMetadata:
            ISTIO_DUAL_STACK: "true"
      values:
        pilot:
          env:
            ISTIO_DUAL_STACK: "true"
    EOF
    
  2. 创建三个命名空间

    • dual-stacktcp-echo 将在 IPv4 和 IPv6 地址上侦听。
    • ipv4tcp-echo 将只在 IPv4 地址上侦听。
    • ipv6tcp-echo 将只在 IPv6 地址上侦听。
    $ kubectl create namespace dual-stack
    $ kubectl create namespace ipv4
    $ kubectl create namespace ipv6
    
  3. 在所有这些命名空间以及默认命名空间上启用 sidecar 注入

    $ kubectl label --overwrite namespace default istio-injection=enabled
    $ kubectl label --overwrite namespace dual-stack istio-injection=enabled
    $ kubectl label --overwrite namespace ipv4 istio-injection=enabled
    $ kubectl label --overwrite namespace ipv6 istio-injection=enabled
    
  4. 在命名空间中创建 tcp-echo 部署

    $ kubectl apply --namespace dual-stack -f https://raw.githubusercontent.com/istio/istio/release-1.24/samples/tcp-echo/tcp-echo-dual-stack.yaml
    $ kubectl apply --namespace ipv4 -f https://raw.githubusercontent.com/istio/istio/release-1.24/samples/tcp-echo/tcp-echo-ipv4.yaml
    $ kubectl apply --namespace ipv6 -f https://raw.githubusercontent.com/istio/istio/release-1.24/samples/tcp-echo/tcp-echo-ipv6.yaml
    
  5. 在默认命名空间中创建 sleep 部署

    $ kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.24/samples/sleep/sleep.yaml
    
  6. 验证流量

    $ kubectl exec -it "$(kubectl get pod -l app=sleep -o jsonpath='{.items[0].metadata.name}')" -- sh -c "echo dualstack | nc tcp-echo.dual-stack 9000"
    hello dualstack
    $ kubectl exec -it "$(kubectl get pod -l app=sleep -o jsonpath='{.items[0].metadata.name}')" -- sh -c "echo ipv4 | nc tcp-echo.ipv4 9000"
    hello ipv4
    $ kubectl exec -it "$(kubectl get pod -l app=sleep -o jsonpath='{.items[0].metadata.name}')" -- sh -c "echo ipv6 | nc tcp-echo.ipv6 9000"
    hello ipv6
    

现在,您可以在您的环境中试验双栈服务!

对监听器和端点的重大更改

对于上述实验,您会注意到对监听器和路由进行了更改

$ istioctl proxy-config listeners "$(kubectl get pod -n dual-stack -l app=tcp-echo -o jsonpath='{.items[0].metadata.name}')" -n dual-stack --port 9000

您将看到监听器现在绑定到多个地址,但仅限于双栈服务。其他服务将只在一个 IP 地址上侦听。

"name": "fd00:10:96::f9fc_9000",
"address": {
    "socketAddress": {
        "address": "fd00:10:96::f9fc",
        "portValue": 9000
    }
},
"additionalAddresses": [
    {
        "address": {
            "socketAddress": {
                "address": "10.96.106.11",
                "portValue": 9000
            }
        }
    }
],

虚拟入站地址现在也配置为在 0.0.0.0[::] 上侦听。

"name": "virtualInbound",
"address": {
    "socketAddress": {
        "address": "0.0.0.0",
        "portValue": 15006
    }
},
"additionalAddresses": [
    {
        "address": {
            "socketAddress": {
                "address": "::",
                "portValue": 15006
            }
        }
    }
],

Envoy 的端点现在配置为路由到 IPv4 和 IPv6

$ istioctl proxy-config endpoints "$(kubectl get pod -l app=sleep -o jsonpath='{.items[0].metadata.name}')" --port 9000
ENDPOINT                 STATUS      OUTLIER CHECK     CLUSTER
10.244.0.19:9000         HEALTHY     OK                outbound|9000||tcp-echo.ipv4.svc.cluster.local
10.244.0.26:9000         HEALTHY     OK                outbound|9000||tcp-echo.dual-stack.svc.cluster.local
fd00:10:244::1a:9000     HEALTHY     OK                outbound|9000||tcp-echo.dual-stack.svc.cluster.local
fd00:10:244::18:9000     HEALTHY     OK                outbound|9000||tcp-echo.ipv6.svc.cluster.local

参与进来

仍有大量工作要做,欢迎您帮助我们完成双栈支持达到 Alpha 阶段所需的剩余任务 此处

例如,Iris Ding(英特尔)和 Li Chun(英特尔)已与社区合作,以实现环境流量的重定向,我们希望在 Istio 1.18 的即将发布的 Alpha 版本中为环境提供双栈支持。

我们非常乐意收到您的反馈,如果您渴望与我们合作,请访问我们的 Slack 频道 #dual-stack,该频道位于 Istio Slack 中。

感谢参与 Istio 双栈工作的团队!

分享此文章