本文为您介绍容器网络中的常见问题。

Terway相关

Flannel相关

kube-proxy相关

IPv6相关

如何解决IPv6双栈的部分常见问题?

其他

Terway网络模式下增加了虚拟交换机后,集群无法访问公网怎么办?

问题现象:在Terway网络下,因Pod没有IP资源而手动增加虚拟交换机,在增加虚拟交换机后,发现集群不能正常访问公网。

问题原因:Pod IP所属的虚拟交换机不具备公网访问的能力。

解决方法:您可以通过NAT网关的SNAT功能,为Pod IP所属的虚拟交换机配置公网SNAT规则。更多信息,请参见为已有集群开启SNAT公网访问能力

手动升级了Flannel镜像版本后,如何解决无法兼容1.16以上版本集群的问题?

问题现象:

集群版本升级到1.16之后,集群节点变成NotReady。

问题原因:

手动升级了Flannel版本,而并没有升级Flannel的配置,导致Kubelet无法识别。

解决方法:

  1. 执行以下命令,编辑Flannel,增加cniVersion字段。
    kubectl edit cm kube-flannel-cfg -n kube-system 

    返回结果中增加cniVersion字段。

    "name": "cb0",      
    "cniVersion":"0.3.0",
    "type": "flannel",
  2. 执行以下命令,重启Flannel。
    kubectl delete pod -n kube-system -l app=flannel

如何解决Pod启动后存在时延的问题?

问题现象:

Pod启动后网络需要延迟一会才能通信。

问题原因:

配置Network Policy会有一定的时延,关闭Network Policy后,就能解决该问题。

解决方法:

  1. 执行以下命令,修改Terway的ConfigMap,增加禁用NetworkPolicy的配置。
    kubectl edit cm -n kube-system eni-config 

    在返回结果中增加以下字段。

    disable_network_policy: "true"
  2. 可选:如果Terway版本不是最新的,请在控制台升级Terway版本。
    1. 登录容器服务管理控制台
    2. 在控制台左侧导航栏中,单击集群
    3. 集群列表页面中,单击目标集群名称或者目标集群右侧操作列下的详情
    4. 在集群管理页面选择运维管理 > 组件管理
    5. 组件管理页面单击网络页签,单击目标Terway组件区域的升级
    6. 提示对话框中单击确认
  3. 执行以下命令,重启所有Terway的Pod。
     kubectl delete pod -n kube-system -l app=terway-eniip

如何让Pod访问自己暴露的服务?

问题现象:

Pod无法访问自己暴露的服务,存在时好时坏或者调度到自己就出问题的现象。

问题原因:

Flannel集群可能未开启回环访问。
说明
  • 低于v0.15.1.4-e02c8f12-aliyun版本的Flannel不允许回环访问。升级版本后,仍默认不允许回环访问,但可以手动开启。
  • 只有全新部署的v0.15.1.4-e02c8f12-aliyun及以上版本的Flannel,才默认开启回环访问。

解决方法:

  • 使用Headless Service暴露服务和访问,具体操作,请参见Headless Services
    说明 推荐使用此方法。
  • 重建集群使用Terway的网络插件,具体操作,请参见使用Terway网络插件
  • 修改Flannel的配置,然后重建Flannel和Pod。
    说明 不推荐此方法,可能会被后续升级覆盖。
    1. 执行以下命令编辑cni-config.json
      kubectl edit cm kube-flannel-cfg -n kube-system
    2. 在返回结果的delegate中增加hairpinMode: true
      示例如下:
      cni-conf.json: |
          {
            "name": "cb0",
            "cniVersion":"0.3.1",
            "type": "flannel",
            "delegate": {
              "isDefaultGateway": true,
              "hairpinMode": true
            }
          }
    3. 执行以下命令,重启Flannel。
      kubectl delete pod -n kube-system -l app=flannel   
    4. 删除并重新创建Pod。

如何选择Kubernetes集群Terway和Flannel网络插件?

下面为您详细介绍在ACK创建集群时使用的两种网络插件:Terway和Flannel。

在创建Kubernetes集群时,阿里云容器服务提供以下两种网络插件:
  • Flannel:使用的是简单稳定的社区的Flannel CNI插件,配合阿里云的VPC的高速网络,能给集群高性能和稳定的容器网络体验,但功能偏简单,支持的特性少,例如:不支持基于Kubernetes标准的Network Policy。
  • Terway:是阿里云容器服务自研的网络插件,功能上完全兼容Flannel,支持将阿里云的弹性网卡分配给容器,支持基于Kubernetes标准的NetworkPolicy来定义容器间的访问策略,支持对单个容器做带宽的限流。对于不需要使用Network Policy的用户,可以选择Flannel,其他情况建议选择Terway。了解更多Terway网络插件的相关内容,请参见使用Terway网络插件

如何规划集群网络?

在创建ACK集群时,需要指定专有网络VPC、虚拟交换机、 Pod网络CIDR(地址段)和Service CIDR(地址段)。建议您提前规划ECS地址、Kubernetes Pod地址和Service地址。详情请参见Kubernetes集群网络规划

ACK是否支持hostPort的端口映射?

  • 只有Flannel插件支持hostPort,其他插件暂不支持hostPort。
  • 容器服务ACK的Pod地址是可以直接被VPC中其他资源访问的,不需要额外的端口映射。
  • 如果需要把服务暴露到外部,可以使用NodePort或者LoadBalancer类型的Service。

如何查看集群的网络类型及对应的虚拟交换机?

ACK支持两种容器网络类型,分别是Flannel网络类型和Terway网络类型。

通过以下步骤查看您创建集群时所选择的网络类型

  1. 登录容器服务管理控制台
  2. 在控制台左侧导航栏中,单击集群
  3. 在集群列表页面中,单击目标集群名称或者目标集群右侧操作列下的详情
  4. 单击基本信息页签,在集群信息区域查看集群的容器网络类型,即网络插件右侧的值。
    • 如果网络插件右侧显示terway-eniip ,则容器的网络类型为Terway网络。
    • 如果网络插件右侧显示Flannel,则容器的网络类型为Flannel网络。

通过以下步骤查看对应网络类型使用的节点虚拟交换机

  1. 登录容器服务管理控制台
  2. 在控制台左侧导航栏中,单击集群
  3. 集群列表页面中,单击目标集群名称或者目标集群右侧操作列下的详情
  4. 在集群管理页左侧导航栏中,选择节点管理 > 节点池
  5. 在目标节点池右侧操作列单击详情

    节点配置区域查看节点虚拟交换机ID。

通过以下步骤查询Terway网络类型使用的Pod虚拟交换机ID

说明 只有Terway网络类型使用Pod虚拟交换机,Flannel网络类型无需使用Pod虚拟交换机。
  1. 登录容器服务管理控制台
  2. 在左侧导航栏,单击集群,然后在集群列表中单击目标集群名称或目标集群右侧操作列下的详情
  3. 在集群信息页面,单击集群资源页签,然后查看Pod虚拟交换机ID。

如何查看集群中使用的云资源?

通过以下步骤查看集群中使用的云资源信息,包括虚拟机、虚拟专有网络VPC、Worker RAM角色等。
  1. 登录容器服务管理控制台
  2. 在控制台左侧导航栏中,单击集群
  3. 在集群列表页面中,单击目标集群名称或者目标集群右侧操作列下的详情
  4. 单击集群资源页签,查看集群中使用的云资源信息。

如何修改kube-proxy配置?

ACK托管版默认部署kube-proxy-worker DaemonSet作为负载均衡,可通过其同名配置项kube-proxy-worker ConfigMap控制其参数。如果您使用的是ACK专有版,您集群中会额外部署kube-proxy-master DaemonSet和同名配置项,其会运行于Master节点上。

kube-proxy配置项均兼容社区KubeProxyConfiguration标准,您可以参考社区KubeProxyConfiguration标准进行自定义配置,更多信息,请参见kube-proxy Configuration。kube-proxy配置文件对格式要求严格,请勿漏填冒号和空格。修改kube-proxy配置操作如下:

  • 如果您使用的是托管版集群,您需要修改kube-proxy-worker的配置。
    1. 登录容器服务管理控制台
    2. 在控制台左侧导航栏中,单击集群
    3. 集群列表页面中,单击目标集群名称或者目标集群右侧操作列下的详情
    4. 在集群管理页左侧导航栏中,选择配置管理 > 配置项
    5. 在顶部选择kube-system命名空间,然后单击配置项kube-proxy-worker右侧的YAML编辑
    6. 查看YAML面板修改参数,然后单击确定
    7. 重建所有名为kube-proxy-worker的容器,使配置生效。
      注意 kube-proxy的重启不会导致已有运行业务中断,如果有并发业务发布,新启动的业务在kube-proxy的生效时间会略有延迟,请尽量于业务低峰期操作。
      1. 在集群管理页左侧导航栏中,选择工作负载 > 守护进程集
      2. 在守护进程集列表中,找到并单击kube-proxy-worker
      3. kube-proxy-worker页面中的容器组页签下对应容器组右侧,选择更多 > 删除,然后单击确定

        重复操作删除所有容器组。删除容器组后,系统会自动重建所有容器。

  • 如果您使用的是专有版集群,您需要修改kube-proxy-worker和kube-proxy-master的配置,然后删除kube-proxy-worker和kube-proxy-master Pod,该Pod自动重新创建后会使配置生效。具体操作,请参见上文。

如何提升Linux连接跟踪Conntrack数量限制?

内核日志(dmesg)中出现conntrack full的报错日志,说明Conntrack数量已经达到conntrack_max数量限制。您需要提升Linux连接跟踪Conntrack数量限制。
  1. 执行conntrack -L命令,确认目前Conntrack中的各协议占用情况。
    • 如果出现大量TCP协议的占用,您需要确认具体业务,如果是短连接型应用可以考虑整改成长连接型。
    • 如果出现大量DNS的占用,您需要在ACK集群中使用NodeLocal DNSCache,提高DNS的性能,具体操作,请参见使用NodeLocal DNSCache
  2. 如果Conntrack实际占用情况合理,或者您不希望对业务进行整改,您可以通过配置kube-proxy增加maxPerCore参数,调整连接跟踪数量限制。
    • 如果您使用的是托管版集群,您需要在kube-proxy-worker中增加maxPerCore参数,并设置其值为65536或更高的数值,然后删除kube-proxy-worker Pod,该Pod自动重新创建后会使配置生效。关于如何修改并删除kube-proxy-worker,请参见如何修改kube-proxy配置?
      apiVersion: v1
      kind: ConfigMap
      metadata:
        name: kube-proxy-worker
        namespace: kube-system
      data:
        config.conf: |
          apiVersion: kubeproxy.config.k8s.io/v1alpha1
          kind: KubeProxyConfiguration
          featureGates:
            IPv6DualStack: true
          clusterCIDR: 172.20.0.0/16
          clientConnection:
            kubeconfig: /var/lib/kube-proxy/kubeconfig.conf
          conntrack:
            maxPerCore: 65536 // 需设置maxPerCore至合理值,此处65536为默认设置。
          mode: ipvs
      # 其它略
    • 如果您使用的是专有版集群,您需要在kube-proxy-worker和kube-proxy-master中增加maxPerCore参数,并设置其值为65536或更高的数值,然后删除kube-proxy-worker和kube-proxy-master Pod,该Pod自动重新创建后会使配置生效。关于如何修改并删除kube-proxy-worker和kube-proxy-master,请参见如何修改kube-proxy配置?

如何修改kube-proxy中IPVS负载均衡模式?

您可以通过修改kube-proxy中IPVS负载均衡模式来解决大量长连接的负载不均问题,具体操作如下:
  1. 选择合适的调度算法。关于如何选择合适的调度算法,请参见K8s官方文档parameter-changes
  2. 早于2022年10月创建的集群节点可能未默认启用所有IPVS调度算法,您需要手动在所有集群节点上启用IPVS调度算法内核模块(以最小连接数调度算法lc为例,如果选用其它算法,请替换lc关键字),逐台登录每个节点,并运行lsmod | grep ip_vs_lc查看是否有输出。
    • 如果命令输出ip_vs_lc,说明调度算法内核模块已经加载,则可以跳过本步骤。
    • 如果没有加载,运行modprobe ip_vs_lc使节点立即生效,并运行echo "ip_vs_lc" >> /etc/modules-load.d/ack-ipvs-modules.conf使机器重启后生效。
  3. 设置kube-proxy中的ipvs scheduler参数值为合理的调度算法。
    • 如果您使用的是托管版集群,您需要修改kube-proxy-worker的ipvs scheduler参数值为合理的调度算法,然后删除kube-proxy-worker Pod,该Pod自动重新创建后会使配置生效。关于如何修改并删除kube-proxy-worker,请参见如何修改kube-proxy配置?
      apiVersion: v1
      kind: ConfigMap
      metadata:
        name: kube-proxy-worker
        namespace: kube-system
      data:
        config.conf: |
          apiVersion: kubeproxy.config.k8s.io/v1alpha1
          kind: KubeProxyConfiguration
          featureGates:
            IPv6DualStack: true
          clusterCIDR: 172.20.0.0/16
          clientConnection:
            kubeconfig: /var/lib/kube-proxy/kubeconfig.conf
          conntrack:
            maxPerCore: 65536
          mode: ipvs
          ipvs:
            scheduler: lc // 需设置scheduler成合理的调度算法。
      # 其它略
    • 如果您使用的是专有版集群,您需要修改kube-proxy-worker和kube-proxy-master中的ipvs scheduler参数值为合理的调度算法,然后删除kube-proxy-worker和kube-proxy-master Pod,该Pod自动重新创建后会使配置生效。关于如何修改并删除kube-proxy-worker和kube-proxy-master,请参见如何修改kube-proxy配置?
  4. 查看kube-proxy运行日志。
    • 通过kubectl get pods命令查看kube-system命名空间下新建的kube-proxy-worker容器(如果您使用专有版集群,还需查看kube-proxy-master)是否为Running状态。
    • 通过kubectl logs命令查看新建容器的日志。
      • 如果出现Can't use the IPVS proxier: IPVS proxier will not be used because the following required kernel modules are not loaded: [ip_vs_lc]则说明IPVS调度算法内核模块未成功加载,您需要检查上述步骤是否已经正确执行,并尝试重试。
      • 如果出现Using iptables Proxier.说明kube-proxy无法启用IPVS模块,开始自动回退使用iptables模式,此时建议先回滚kube-proxy配置,再对机器进行重启操作。
      • 如果未出现上述日志,并显示Using ipvs Proxier.说明IPVS模块成功启用。
    • 如果上述检查均返回正常,说明变更成功。

如何修改kube-proxy中IPVS UDP会话保持的超时时间?

如果您的ACK集群使用了kube-proxy IPVS模式,IPVS的默认会话保持策略会使UDP协议后端在摘除后五分钟内出现概率性丢包的问题。如果您业务依赖于CoreDNS,当CoreDNS组件升级或所在节点重启时,您可能会在五分钟内遇到业务接口延迟、请求超时等现象。

若您在ACK集群中的业务没有使用UDP协议,您可以通过降低IPVS UDP协议的会话保持的超时时间来减少解析延迟或失败的影响时间。具体操作如下:
说明 若您的自有业务使用了UDP协议,请提交工单咨询。
  • K8s 1.18及以上版本集群
    • 如果您使用的是托管版集群,您需要在kube-proxy-worker中修改udpTimeout参数值。然后删除kube-proxy-worker Pod,该Pod自动重新创建后会使配置生效。关于如何修改并删除kube-proxy-worker,请参见如何修改kube-proxy配置?
      apiVersion: v1
      kind: ConfigMap
      metadata:
        name: kube-proxy-worker
        namespace: kube-system
      data:
        config.conf: |
          apiVersion: kubeproxy.config.k8s.io/v1alpha1
          kind: KubeProxyConfiguration
          // 其它不相关字段已省略。
          mode: ipvs
          // 如果ipvs键不存在,需要添加此键。
          ipvs:
            udpTimeout: 10s // 此处默认为300秒,调整成10秒可以将IPVS UDP类型后端摘除后丢包问题的影响时间缩短到10秒。
    • 如果您使用的是专有版集群,您需要在kube-proxy-worker和kube-proxy-master中修改udpTimeout参数值。然后删除kube-proxy-worker和kube-proxy-master Pod,该Pod自动重新创建后会使配置生效。关于如何修改并删除kube-proxy-worker,请参见如何修改kube-proxy配置?
  • K8s 1.16及以下版本集群
    此类版本集群的kube-proxy不支持udpTimeout参数,推荐使用运维编排服务OOS(Operation Orchestration Service)批量在所有集群机器上执行ipvsadm命令以调整UDP超时时间配置。命令如下:
    yum install -y ipvsadm
    ipvsadm -L --timeout > /tmp/ipvsadm_timeout_old
    ipvsadm --set 900 120 10
    ipvsadm -L --timeout > /tmp/ipvsadm_timeout_new
    diff /tmp/ipvsadm_timeout_old /tmp/ipvsadm_timeout_new

    关于OOS的批量操作实例介绍,请参见批量操作实例

如何解决IPv6双栈的部分常见问题?

  • 问题现象:在kubectl中显示的Pod IP还是IPv4地址。

    解决方法:执行以下命令,展示Pod IPs字段,预期输出IPv6地址。

    kubectl get pods -A -o jsonpath='{range .items[*]}{@.metadata.namespace} {@.metadata.name} {@.status.podIPs[*].ip} {"\n"}{end}'
  • 问题现象:在kubectl中显示的Cluster IP还是IPv4地址。
    解决方法:
    1. 请确认spec.ipFamilyPolicy配置的不是SingleStack。
    2. 执行以下命令,展示Cluster IPs字段,预期输出IPv6地址。
      kubectl get svc -A -o jsonpath='{range .items[*]}{@.metadata.namespace} {@.metadata.name} {@.spec.ipFamilyPolicy} {@.spec.clusterIPs[*]} {"\n"}{end}'
  • 问题现象:无法通过IPv6地址访问Pod。

    问题原因:部分应用默认不监听IPv6地址,例如Nginx容器。

    解决方法:执行netstat -anp命令,确认Pod已监听IPv6地址。

    预期输出:

    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
    tcp        0      0 127.0.XX.XX:10248         0.0.0.0:*               LISTEN      8196/kubelet
    tcp        0      0 127.0.XX.XX:41935         0.0.0.0:*               LISTEN      8196/kubelet
    tcp        0      0 0.0.XX.XX:111             0.0.0.0:*               LISTEN      598/rpcbind
    tcp        0      0 0.0.XX.XX:22              0.0.0.0:*               LISTEN      3577/sshd
    tcp6       0      0 :::30500                :::*                    LISTEN      1916680/kube-proxy
    tcp6       0      0 :::10250                :::*                    LISTEN      8196/kubelet
    tcp6       0      0 :::31183                :::*                    LISTEN      1916680/kube-proxy
    tcp6       0      0 :::10255                :::*                    LISTEN      8196/kubelet
    tcp6       0      0 :::111                  :::*                    LISTEN      598/rpcbind
    tcp6       0      0 :::10256                :::*                    LISTEN      1916680/kube-proxy
    tcp6       0      0 :::31641                :::*                    LISTEN      1916680/kube-proxy
    udp        0      0 0.0.0.0:68              0.0.0.0:*                           4892/dhclient
    udp        0      0 0.0.0.0:111             0.0.0.0:*                           598/rpcbind
    udp        0      0 47.100.XX.XX:323           0.0.0.0:*                           6750/chronyd
    udp        0      0 0.0.0.0:720             0.0.0.0:*                           598/rpcbind
    udp6       0      0 :::111                  :::*                                598/rpcbind
    udp6       0      0 ::1:323                 :::*                                6750/chronyd
    udp6       0      0 fe80::216:XXXX:fe03:546 :::*                                6673/dhclient
    udp6       0      0 :::720                  :::*                                598/rpcbind

    Proto显示为tcp即监听IPv4地址,显示为tcp6即监听IPv6地址。

  • 问题现象:通过IPv6地址可以在集群内访问Pod,但无法从公网访问。

    问题原因:该IPv6地址可能未配置公网带宽。

    解决方法:配置该IPv6地址的公网带宽。具体操作,请参见开通和管理IPv6公网带宽

  • 问题现象:无法通过IPv6 Cluster IP访问Pod。
    解决方法:
    1. 请确认spec.ipFamilyPolicy配置的不是SingleStack。
    2. 执行netstat -anp命令,确认Pod已监听IPv6地址。

      预期输出:

      Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
      tcp        0      0 127.0.XX.XX:10248         0.0.0.0:*               LISTEN      8196/kubelet
      tcp        0      0 127.0.XX.XX:41935         0.0.0.0:*               LISTEN      8196/kubelet
      tcp        0      0 0.0.XX.XX:111             0.0.0.0:*               LISTEN      598/rpcbind
      tcp        0      0 0.0.XX.XX:22              0.0.0.0:*               LISTEN      3577/sshd
      tcp6       0      0 :::30500                :::*                    LISTEN      1916680/kube-proxy
      tcp6       0      0 :::10250                :::*                    LISTEN      8196/kubelet
      tcp6       0      0 :::31183                :::*                    LISTEN      1916680/kube-proxy
      tcp6       0      0 :::10255                :::*                    LISTEN      8196/kubelet
      tcp6       0      0 :::111                  :::*                    LISTEN      598/rpcbind
      tcp6       0      0 :::10256                :::*                    LISTEN      1916680/kube-proxy
      tcp6       0      0 :::31641                :::*                    LISTEN      1916680/kube-proxy
      udp        0      0 0.0.0.0:68              0.0.0.0:*                           4892/dhclient
      udp        0      0 0.0.0.0:111             0.0.0.0:*                           598/rpcbind
      udp        0      0 47.100.XX.XX:323           0.0.0.0:*                           6750/chronyd
      udp        0      0 0.0.0.0:720             0.0.0.0:*                           598/rpcbind
      udp6       0      0 :::111                  :::*                                598/rpcbind
      udp6       0      0 ::1:323                 :::*                                6750/chronyd
      udp6       0      0 fe80::216:XXXX:fe03:546 :::*                                6673/dhclient
      udp6       0      0 :::720                  :::*                                598/rpcbind

      Proto显示为tcp即监听IPv4地址,显示为tcp6即监听IPv6地址。

    3. 问题现象:Pod无法通过IPv6访问公网。

      解决方法:对IPv6使用公网,需要开通IPv6网关,并对IPv6地址配置公网带宽。详细信息,请参见创建和管理IPv6网关开通和管理IPv6公网带宽

Terway网络模式下,Pod分配的IP不在虚拟交换机网段中怎么办?

问题现象:

在Terway网络下,创建的Pod IP不在配置的虚拟交换机网段内。

问题原因:

Pod IP来源于VPC地址,并且通过ENI分配给容器使用。只有在新建ENI时,才可以配置虚拟交换机。如果ENI已经创建,则Pod IP将继续从该ENI对应的虚拟交换机中分配。

通常以下两个使用场景会遇到该问题:

  • 纳管一个节点到集群内,但这个节点之前在其他集群使用,且删除节点时没有排空节点Pod。这种情况下节点上可能残留之前集群使用的ENI资源。
  • 手动增加、修改Terway使用的虚拟交换机配置,由于节点上可能还存在原有配置的ENI,则新建的Pod将可能继续使用原有ENI上的IP。

解决方法:

您可以通过新建节点、轮转老节点的方式来确保配置文件在新节点上生效。

Terway网络模式扩容vSwitch后,依然无法分配Pod IP怎么办?

问题现象:

在Terway网络下,Terway网络模式扩容vSwitch后依然无法分配Pod IP。

问题原因:

Pod IP来源于VPC地址,并且通过ENI分配给容器使用。只有在新建ENI时,才可以配置虚拟交换机。如果ENI已经创建,则Pod IP将继续从该ENI对应的虚拟交换机中分配。由于节点上ENI配额已经用完,无法新建ENI ,也就无法让新配置生效。关于ENI配额的具体信息,请参见使用限制

解决方法:

您可以通过新建节点、轮转老节点的方式来确保配置文件在新节点上生效。

如何为Terway IPvlan集群开启集群内负载均衡?

问题现象:

在IPvlan模式下,v1.2.0及以上版本的Terway,新建的集群默认开启集群内负载均衡功能。在集群内访问ExternalIP,LoadBalancer流量将被负载到Service网络。如何为已创建的Terway IPvlan集群开启集群内负载均衡?

问题原因:

Kube-Proxy会短路集群内访问ExternalIP、LoadBalancer的流量,即集群内访问这些外部地址,实际流量不会到外部,而会被转为对应后端的Endpoint直接访问。在Terway IPvlan模式下,Pod访问这些地址流量由Cilium而不是kube-proxy进行处理, 在Terway v1.2.0之前版本并不支持这种链路的短路。在Terway v1.2.0版本发布后,新建集群将默认开启该功能,已创建的集群不会开启。

解决方法:

说明
  • Terway需要v1.2.0及以上版本,且使用IPvlan模式。
  • 如果集群未启用IPvlan模式,则该配置无效,无需配置。
  • 新建集群此功能默认开启,无需配置。
  1. 执行以下命令,修改Terway的配置ConfigMap。
    kubectl edit cm eni-config -n kube-system
  2. eni_conf中增加以下内容。
    in_cluster_loadbalance: "true"
    说明 请保持in_cluster_loadbalanceeni_conf在同级别。
  3. 执行以下命令,重建Terway Pod,使集群内负载均衡配置生效。
    kubectl delete pod -n kube-system -l app=terway-eniip
    验证配置
    执行以下命令,检查terway-ennippolicy日志,如果显示enable-in-cluster-loadbalance=true则配置生效。
    kubectl logs -n kube-system <terway pod name> policy | grep enable-in-cluster-loadbalance

如何在ACK中对Terway网络下的Pod指定网段加白?

问题现象:

您通常需要在一些类似数据库之类的服务设置白名单,以此来给服务提供更安全的访问控制能力。在容器网络下同样有此需求,需要在容器中给动态变化的Pod IP设置白名单。

问题原因:

ACK的容器网络主要有Flannel和Terway两种:
  • 在Flannel网络下,因为Pod是通过节点访问其他服务,所以在Flannel网络下的数据库设置白名单时,首先可以将客户端Pod通过节点绑定的方式调度到固定的少数节点上去,然后在数据库侧直接对节点的IP地址做加白操作即可。
  • 在Terway网络下,Pod IP是通过ENI提供。Pod通过ENI访问外部服务,外部服务得到的客户端IP是ENI提供的IP地址,即使把Pod和节点设置了亲和性绑定,Pod访问外部服务的客户端IP仍然是ENI提供的IP而不是节点的IP。Pod IP还是会从Terway指定的vSwitch中随机分配IP地址,而且客户端Pod通常都会有自动伸缩之类的配置,那即使能固定Pod IP也很难满足弹性伸缩的场景,建议直接给客户端指定一个网段来分配IP,然后在数据库侧对这个网段来做加白操作。

解决方法:

通过给指定节点添加标签来指定Pod使用的vSwitch,从而当Pod调度到有固定标签的节点上时,该Pod就可以通过自定义的vSwitch去创建Pod IP。

  1. 在kube-system命名空间下单独创建一个名称为eni-config-fixed的ConfigMap ,其中需要指定专门的vSwitch。

    本示例以vsw-2zem796p76viir02c****,10.2.1.0/24为例。

    apiVersion: v1
    data:
      eni_conf: |
        {
           "vswitches": {"cn-beijing-h":["vsw-2zem796p76viir02c****"]},
           "security_group": "sg-bp19k3sj8dk3dcd7****",
           "security_groups": ["sg-bp1b39sjf3v49c33****","sg-bp1bpdfg35tg****"]
        }
    kind: ConfigMap
    metadata:
      name: eni-config-fixed
      namespace: kube-system
    
                            
  2. 创建节点池,为节点打上标签terway-config:eni-config-fixed。关于创建节点池的具体操作,请参见创建节点池
    为了保证该节点池内的节点上不会出现其他Pod,可以给该节点池同时配置上污点,例如fixed=true:NoSchedule节点标签.png
  3. 扩容该节点池。具体操作,请参见扩容ACK集群的节点
    通过该节点池扩容出来的节点默认会带有上一步设置的节点标签和污点。
  4. 创建Pod,调度到已有terway-config:eni-config-fixed标签的节点上,需要添加容忍。
    apiVersion: apps/v1 #1.8.0以前的版本请使用apps/v1beta1。
    kind: Deployment
    metadata:
      name: nginx-fixed
      labels:
        app: nginx-fixed
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: nginx-fixed
      template:
        metadata:
          labels:
            app: nginx-fixed
        spec:
          tolerations:        #添加容忍。
          - key: "fixed"
            operator: "Equal"
            value: "true"
            effect: "NoSchedule"
          nodeSelector:
            terway-config: eni-config-fixed
          containers:
          - name: nginx
            image: nginx:1.9.0 #替换成您实际的镜像<image_name:tags>。
            ports:
            - containerPort: 80
    结果验证
    1. 执行以下命令,查看Pod IP。
      kubectl get po -o wide | grep fixed
      预期输出:
      nginx-fixed-57d4c9bd97-l****                   1/1     Running             0          39s    10.2.1.124    bj-tw.062149.aliyun.com   <none>           <none>
      nginx-fixed-57d4c9bd97-t****                   1/1     Running             0          39s    10.2.1.125    bj-tw.062148.aliyun.com   <none>           <none>
      可以看到Pod IP已经从指定的vSwitch分配。
    2. 执行以下命令,将Pod扩容到30个。
      kubectl scale deployment nginx-fixed --replicas=30
      预期输出:
      nginx-fixed-57d4c9bd97-2****                   1/1     Running     0          60s     10.2.1.132    bj-tw.062148.aliyun.com   <none>           <none>
      nginx-fixed-57d4c9bd97-4****                   1/1     Running     0          60s     10.2.1.144    bj-tw.062149.aliyun.com   <none>           <none>
      nginx-fixed-57d4c9bd97-5****                   1/1     Running     0          60s     10.2.1.143    bj-tw.062148.aliyun.com   <none>           <none>
      ...
      可以看到生成的Pod IP全部在指定的vSwitch下,然后在数据库侧直接对此vSwitch做加白操作,从而实现给动态Pod IP做访问控制。
说明
  • 建议您使用新创建的节点,如果使用已有节点,需要在节点添加进集群之前先将ENI和ECS实例解绑,再添加进集群。添加方式要选用自动添加已有节点(替换系统盘)。具体操作,请参见解绑弹性网卡自动添加节点
  • 注意给特定的节点池打上标签和污点,尽可能保证不需要加白的业务不会调度到这部分节点上。
  • 这个设置白名单的方法其实是配置覆盖,ACK会用现在指定的ConfigMap里配置来覆盖之前的eni-config的配置,关于配置参数的具体信息,请参见Terway节点动态配置
  • 指定vSwitch的IP个数建议为预计Pod个数的2倍(或更多),一方面可以给将来的扩容多一些余量,另外也可以避免当发生故障导致Pod IP无法及时回收时,出现没有IP可分配的情况。

为什么Pod无法ping通部分ECS节点?

问题现象:

Flannel网络模式下,检查VPN路由正常,进入Pod,发现部分ECS节点无法ping通。

问题原因:

Pod无法ping通部分ECS节点的原因分为两种。
  • 原因一:Pod访问的ECS和集群在同一个VPC下,但不在同一个安全组。
  • 原因二:Pod访问的ECS和集群不在同一个VPC下。

解决方法:

根据不同的原因,提供不同的解决方法。
  • 针对原因一,需要将ECS加入到集群的安全组中。具体操作,请参见配置安全组
  • 针对原因二,需要通过ECS的公网入口访问,需要在ECS的安全组中加入集群的公网出口IP地址。具体操作,请参见ECS通过EIP对公网提供服务

为什么集群节点有NodeNetworkUnavailable污点?

问题现象:

Flannel网络模式下,新增的集群节点上面有NodeNetworkUnavailable污点,导致Pod无法调度。

问题原因:

Cloud Controller Manager没有及时删除该节点污点,可能原因是路由表满、VPC存在多路由表等情况。

解决方法:

使用kubectl describe node命令查看节点的Event事件信息,根据实际输出的报错进行处理。