使用ip-masq-agent灵活的控制容器服务Kubernetes集群的SNAT规则

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器镜像服务 ACR,镜像仓库100个 不限时长
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
简介: 在容器服务的集群中,默认情况下的flannel会对POD访问到非POD的网段做SNAT,以确保POD到集群外部的资源访问,但在某些情况下,比如在容器服务的VPC集群中,POD到集群外部的资源是直接可以访问的,这时我们就可以自己定义节点上的SNAT规则,而达到直接用容器IP访问VPC内其他服务。

使用ip-masq-agent灵活的控制容器服务Kubernetes集群的SNAT规则

在容器服务的集群中,默认情况下的flannel会对POD访问到非POD的网段做SNAT,以确保POD到集群外部的资源访问,但在某些情况下,比如在容器服务的VPC集群中,POD到集群外部的资源是直接可以访问的,这时我们就可以自己定义节点上的SNAT规则,而达到直接用容器IP访问VPC内其他服务。

安装配置ip-masq-agent组件

我们使用kubernetes 官方项目中的 ip-masq-agent 组件来实现对某些网段不做SNAT的需求,部署方式如下:

curl -L -O http://acs-public.oss-cn-hangzhou.aliyuncs.com/kubernetes/network/ip-masq-agent.yaml # 下载ip-masq-agent的配置文件
vim ip-masq-agent.yaml # 修改其中的nonMasqueradeCIDRs的配置增加或者删除不需要做SNAT的网段,并保存
kubectl apply -f ip-masq-agent.yaml # 使配置生效

然后我们使用如下命令判断ip-masq-agent都已正常运行:

# kubectl get pod -n kube-system -o wide | grep ip-masq-agent
ip-masq-agent-557qt                                          1/1       Running   0          30m
ip-masq-agent-dtzds                                          1/1       Running   0          30m
ip-masq-agent-f6kb6                                          1/1       Running   0          30m
ip-masq-agent-qmkgl                                          1/1       Running   0          30m
ip-masq-agent-rtkv8                                          1/1       Running   0          30m

关闭掉既有的SNAT规则

在配置好ip-masq-agent组件后,还是没有起到作用的,因为默认情况下容器服务使用flannel的网络插件,我们下面也将说明如何配置关闭掉flannelSNAT的功能:

  1. 1. 修改CNI的配置:

    kubectl edit configmap kube-flannel-cfg -n kube-system

    打开修改编辑器后,修改其中的cni-config.json的内容,在其中添加两处"ipMasq: false"的配置,修改如下:

      cni-conf.json: |
        {
          "name": "cb0",
          "type": "flannel",
          "ipMasq": false,
          "delegate": {
            "ipMasq": false,
            "isDefaultGateway": true
          }
        }

    然后保存修改退出编辑器。

  2. 2. 修改flannel daemonset的配置:

    # kubectl edit ds kube-flannel-ds -n kube-system

    打开修改编辑器后,修改flannel daemonset中kube-flannel容器的配置中的command,删除掉其中的--ip-masq,然后保存,修改后如下:

          containers:
          - command:
            - /opt/bin/flanneld
            - --kube-subnet-mgr  

    然后保存修改退出编辑器。

  3. 3. 使修改生效:

    因为kubernetes的daemonset配置后不会自动重新创建,需要手动重新创建flannel的pod,通过kubectl手动删除掉每个节点上的flannel-ds的pod使其重新创建:

    # kubectl get pod -o wide -n kube-system | grep kube-flannel-ds
    kube-flannel-ds-5tbjt                                        2/2       Running   4          6d        192.168.193.159   cn-hangzhou.i-bp1e5terjg0bgppqy6j3
    kube-flannel-ds-6mgjm                                        2/2       Running   13         6d        192.168.193.156   cn-hangzhou.i-bp1im9citpwp20zebrcr
    kube-flannel-ds-df9l9                                        2/2       Running   9          6d        192.168.193.155   cn-hangzhou.i-bp1j1j7011icxiaz0miu
    kube-flannel-ds-qdjhz                                        2/2       Running   6          6d        192.168.193.158   cn-hangzhou.i-bp1e5terjg0bgppqy6j4
    kube-flannel-ds-xdkpv                                        2/2       Running   20         6d        192.168.193.157   cn-hangzhou.i-bp1d7nsqol0apr1thvb7
    # kubectl get pod -o wide -n kube-system | grep kube-flannel-ds  | awk '{print $1}'  |xargs kubectl delete -n kube-system pod
    pod "kube-flannel-ds-5tbjt" deleted
    pod "kube-flannel-ds-6mgjm" deleted
    pod "kube-flannel-ds-df9l9" deleted
    pod "kube-flannel-ds-qdjhz" deleted
    pod "kube-flannel-ds-xdkpv" deleted
    # kubectl get pod -o wide -n kube-system | grep kube-flannel-ds # 等待kube-flannel-ds重建完成
    kubectl get pod -o wide -n kube-system | grep kube-flannel-ds
    kube-flannel-ds-c2pvx                                        2/2       Running   0          40s       192.168.193.156   cn-hangzhou.i-bp1im9citpwp20zebrcr
    kube-flannel-ds-htkmt                                        2/2       Running   0          30s       192.168.193.157   cn-hangzhou.i-bp1d7nsqol0apr1thvb7
    kube-flannel-ds-k6pfq                                        2/2       Running   0          20s       192.168.193.155   cn-hangzhou.i-bp1j1j7011icxiaz0miu
    kube-flannel-ds-p6tzx                                        2/2       Running   0          36s       192.168.193.158   cn-hangzhou.i-bp1e5terjg0bgppqy6j4
    kube-flannel-ds-sz5zg                                        2/2       Running   0          8s        192.168.193.159   cn-hangzhou.i-bp1e5terjg0bgppqy6j3

    这样flannel就被配置为了不会创建SNAT的规则了。

  4. 4. 到每个节点上清理之前flannel创建的SNAT的规则:

    # iptables -t nat --line-numbers -vnL POSTROUTING # 查看flannel创建的SNAT规则
    Chain POSTROUTING (policy ACCEPT 4 packets, 240 bytes)
    num   pkts bytes target     prot opt in     out     source               destination
    1      14M  814M KUBE-POSTROUTING  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* kubernetes postrouting rules */
    2        0     0 MASQUERADE  all  --  *      !docker0  172.17.0.0/16        0.0.0.0/0
    3    5468K  328M RETURN     all  --  *      *       172.16.0.0/16        172.16.0.0/16
    4      209 12540 MASQUERADE  all  --  *      *       172.16.0.0/16       !224.0.0.0/4
    5        0     0 RETURN     all  --  *      *      !172.16.0.0/16        172.16.2.0/24
    6    4364K  262M MASQUERADE  all  --  *      *      !172.16.0.0/16        172.16.0.0/16
    7      481 29926 IP-MASQ-AGENT  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* ip-masq-agent: ensure nat POSTROUTING directs all non-LOCAL destination traffic to our custom IP-MASQ-AGENT chain */ ADDRTYPE match dst-type !LOCAL

    在上面这个命令中可以看到我们部署的ip-masq-agent的规则已经加到最后了,然后我们需要移除掉flannel添加的集群网段的4条规则,我们这个集群中的集群POD网段是172.16.0.0/16,这个需要根据您的集群选择的网段进行判断,所以我们这个集群中的flannel添加的规则是序号3~6这4条。

    在机器重启时会重新生成iptables,我们可以重启下需要生效的节点,就会清理掉之前的iptables了,如果不希望影响运行中的服务,也可以通过iptables命令手动删除掉这4条多余的iptables规则:

    # iptables -t nat -D POSTROUTING 6
    # iptables -t nat -D POSTROUTING 5
    # iptables -t nat -D POSTROUTING 4
    # iptables -t nat -D POSTROUTING 3

大工告成,验证配置

通过kubectl run启动一个测试容器,并指定我们修改好的一个节点:

# kubectl run -it --rm --image registry.aliyuncs.com/wangbs/netdia --overrides='{ "apiVersion": "extensions/v1beta1", "spec": { "nodeName": "cn-hangzhou.i-bp1e5terjg0bgppqy6j4"}}' test
/ # ping 192.168.200.253
    

然后通过抓包查看POD ping的包就不会再做SNAT了:

# tcpdump -i eth0 -nn -vv host 192.168.200.253
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
18:54:54.430700 IP (tos 0x0, ttl 63, id 33571, offset 0, flags [DF], proto ICMP (1), length 84)
    172.16.4.11 > 192.168.200.253: ICMP echo request, id 4096, seq 10, length 64
18:54:55.430828 IP (tos 0x0, ttl 63, id 33740, offset 0, flags [DF], proto ICMP (1), length 84)
    172.16.4.11 > 192.168.200.253: ICMP echo request, id 4096, seq 11, length 64
18:54:56.430947 IP (tos 0x0, ttl 63, id 33890, offset 0, flags [DF], proto ICMP (1), length 84)
    172.16.4.11 > 192.168.200.253: ICMP echo request, id 4096, seq 12, length 64
相关实践学习
巧用云服务器ECS制作节日贺卡
本场景带您体验如何在一台CentOS 7操作系统的ECS实例上,通过搭建web服务器,上传源码到web容器,制作节日贺卡网页。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
6天前
|
Kubernetes Cloud Native Docker
云原生时代的容器化实践:Docker和Kubernetes入门
【10月更文挑战第37天】在数字化转型的浪潮中,云原生技术成为企业提升敏捷性和效率的关键。本篇文章将引导读者了解如何利用Docker进行容器化打包及部署,以及Kubernetes集群管理的基础操作,帮助初学者快速入门云原生的世界。通过实际案例分析,我们将深入探讨这些技术在现代IT架构中的应用与影响。
28 2
|
16天前
|
Kubernetes 监控 开发者
掌握容器化:Docker与Kubernetes的最佳实践
【10月更文挑战第26天】本文深入探讨了Docker和Kubernetes的最佳实践,涵盖Dockerfile优化、数据卷管理、网络配置、Pod设计、服务发现与负载均衡、声明式更新等内容。同时介绍了容器化现有应用、自动化部署、监控与日志等开发技巧,以及Docker Compose和Helm等实用工具。旨在帮助开发者提高开发效率和系统稳定性,构建现代、高效、可扩展的应用。
|
8天前
|
存储 Kubernetes Docker
【赵渝强老师】Kubernetes中Pod的基础容器
Pod 是 Kubernetes 中的基本单位,代表集群上运行的一个进程。它由一个或多个容器组成,包括业务容器、基础容器、初始化容器和临时容器。基础容器负责维护 Pod 的网络空间,对用户透明。文中附有图片和视频讲解,详细介绍了 Pod 的组成结构及其在网络配置中的作用。
【赵渝强老师】Kubernetes中Pod的基础容器
|
6天前
|
存储 Kubernetes 网络协议
k8s的无头服务
Headless Service 是一种特殊的 Kubernetes 服务,其 `spec:clusterIP` 设置为 `None`,不会分配 ClusterIP,通过 DNS 解析提供服务发现。与普通服务不同,Headless Service 不提供负载均衡功能,每个 Pod 都有唯一的 DNS 记录,直接映射到其 IP 地址,适用于有状态应用的场景,如与 StatefulSet 一起部署数据库。示例中通过创建 Nginx 的 StatefulSet 和 Headless Service,展示了如何直接访问单个 Pod 并进行内容修改。
17 3
|
8天前
|
运维 Kubernetes Shell
【赵渝强老师】K8s中Pod的临时容器
Pod 是 Kubernetes 中的基本调度单位,由一个或多个容器组成,包括业务容器、基础容器、初始化容器和临时容器。临时容器用于故障排查和性能诊断,不适用于构建应用程序。当 Pod 中的容器异常退出或容器镜像不包含调试工具时,临时容器非常有用。文中通过示例展示了如何使用 `kubectl debug` 命令创建临时容器进行调试。
|
8天前
|
Kubernetes 调度 容器
【赵渝强老师】K8s中Pod中的业务容器
Pod 是 Kubernetes 中的基本调度单元,由一个或多个容器组成。除了业务容器,Pod 还包括基础容器、初始化容器和临时容器。本文通过示例介绍如何创建包含业务容器的 Pod,并提供了一个视频讲解。示例中创建了一个名为 "busybox-container" 的业务容器,并使用 `kubectl create -f firstpod.yaml` 命令部署 Pod。
|
8天前
|
Kubernetes 容器 Perl
【赵渝强老师】K8s中Pod中的初始化容器
Kubernetes的Pod包含业务容器、基础容器、初始化容器和临时容器。初始化容器在业务容器前运行,用于执行必要的初始化任务。本文介绍了初始化容器的作用、配置方法及优势,并提供了一个示例。
|
17天前
|
Kubernetes 负载均衡 Cloud Native
云原生应用:Kubernetes在容器编排中的实践与挑战
【10月更文挑战第27天】Kubernetes(简称K8s)是云原生应用的核心容器编排平台,提供自动化、扩展和管理容器化应用的能力。本文介绍Kubernetes的基本概念、安装配置、核心组件(如Pod和Deployment)、服务发现与负载均衡、网络配置及安全性挑战,帮助读者理解和实践Kubernetes在容器编排中的应用。
47 4
|
18天前
|
Kubernetes 监控 Cloud Native
云原生应用:Kubernetes在容器编排中的实践与挑战
【10月更文挑战第26天】随着云计算技术的发展,容器化成为现代应用部署的核心趋势。Kubernetes(K8s)作为容器编排领域的佼佼者,以其强大的可扩展性和自动化能力,为开发者提供了高效管理和部署容器化应用的平台。本文将详细介绍Kubernetes的基本概念、核心组件、实践过程及面临的挑战,帮助读者更好地理解和应用这一技术。
51 3
|
19天前
|
存储 运维 Kubernetes
云端迁移:备份中心助力企业跨云迁移K8s容器服务平台
本文将简要介绍阿里云容器服务ACK的备份中心,并以某科技公司在其实际的迁移过程中遇到具体挑战为例,阐述如何有效地利用备份中心来助力企业的容器服务平台迁移项目。

相关产品

  • 容器计算服务
  • 容器服务Kubernetes版