农行信创之容器云适配踩过的大坑 - 努力呀 - twt企业IT交流平台

标签: | 发表时间:2021-12-10 21:56 | 作者:
出处:https://www.talkwithtrend.com

作者:

农行研发中心 郑宇光 周思远


当前国内的信息技术的核心和标准大多数都由国外公司掌握和制定,因此存在诸多的安全风险。随着我国加快推进信息网络等新型基础设施建设、网络主权概念的逐步明确,信息技术应用创新产业已经成为当前信息化部署的关键词。我国正在大力推动政府、国防、金融、交通等关键领域的信息化产品尽快实现国产化替代,并发布了多个重要政策来保障国产化的实施,加速实现信息核心技术的自主可控。

中国农业银行作为国有银行,是中国金融体系重要的组成部分,也是信创国产化布局的关键领域,在 IT 建设方面发展十分迅速,其中引入云计算平台基础设施来承载新建应用系统已经作为行内的一条刚性原则。信创国产化云的建设也是当下的重要任务,在云计算平台软件与国芯物理服务器、国产操作系统的适配方面也遇到不少的问题与挑战,下面就这个话题举几个典型的案例和大家分享一下。

农行信创云是采用容器及容器调度为核心技术栈的 PaaS 平台。容器引擎 docker 、容器编排调度组件 kubernetes 和容器网络插件等整体运行于银河麒麟或者 CentOS8 操作系统之上。服务器方面采用基于海光 x86 和鲲鹏 arm 处理器的国产服务器。

案例 1基于国芯海光 x86 服务器安装 Centos8 操作系统,部署并运行 Kubernetes 网络插件 flannel 时出现跨服务器容器网络不通的现象。

现象:当我们完成基于海光服务器和 CentOS8 操作系统的 kubernetes 集群搭建时意外发现从集群外无法访问发布到集群的应用程序,使用同样的发布方式将应用程序发布到非国产化 kubernetes 集群上可以从集群外进行访问。环境信息如下:

操作系统: CentOS Linux 8

内核版本: 4.18.0-147.el8.x86_64

kubernetes 版本: 1.17.4

flannel 版本: 0.11.0 ( vxlan 模式)

分析:我们从集群外访问到应用程序的流量路径上逐步进行排查,最后发现跨服务器节点访问应用容器 IP 和服务端口不可达。集群采用 flannel 的 vxlan 模式提供容器网络服务, flannel 会在每个集群节点上分配一个私有子网来分配该节点的容器 IP ,当跨节点容器互访时,源容器的数据包会通过 vxlan 隧道封装技术进行封装后再通过节点 UDP4789 端口发送到目标节点,完成解封装后送至目标容器。使用 tcpdump 对 flannel 的 UDP4789 端口抓包发现,每个 UDP 数据包都会出现下图所示的 bad udp cksum 并且该数据包被丢弃。

措施:查阅网上相关技术资料发现这个现象是由服务器网卡 Checksum offloading 引起的。这项功能旨在如果内核想通过物理网卡向外发送数据包时可以让硬件网卡代替 CPU 来完成 checksum 计算,以节省 CPU 资源。如果网卡支持,可以设置对发送 Tx 或接收 Rx 有效,或者两者都有效。临时的解决方案是关闭 flannel 网络接口的 Tx checksum 功能,通过 sudo ethtool -K flannel.1 tx-checksum-ip-generic off 命令关闭。可以通过 sudo ethtool -k flannel.1 查询当前 checksum 是否有效,如下图所示,可以看到 tx-checksumming 状态是 off 。

当然这并没有根本解决问题,从 kubernetes 社区上反馈的情况来看是由于 kernel packet checksum 的 bug 以及 kubernetes 的 kube-proxy 组件设置 Iptables 策略时引发的内核 double-NAT 进而设置了错误的 checksum 值的问题碰到一起就会出现 vxlan 跨节点网络丢包的现象,两者解决一个都可以解决此问题,详细内容可以具体参考以下链接:

Ø https://github.com/coreos/flannel/issues/1279

Ø https://github.com/kubernetes/kubernetes/pull/92035

一方面对于 kernel 的 bug 尚未查到明确的 fixed 版本,对于海光芯片的服务器来说我们是通过升级网卡驱动程序来解决的,服务器网卡为网讯的 Ethernet Controller RP2000 ,升级驱动程序及版本为 kmod-ngbe-1.0.4-1.el8.x86_64 和 kmod-txgbe-1.1.12-1.el8.x86_64 ,这个解决方法只针对网讯的这款网卡,另一方面在 kubernetes(v1.16.13 、 v1.17.9 、 v1.18.6) 版本中对进行了修复。请参考以下链接中针对 PR#92035 修复的说明:

Ø https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.18.md#changelog-since-v1185


案例 2基于国芯海光 x86 和鲲鹏 arm 服务器安装银河麒麟 V10 操作系统,部署并运行 Kubernetes 网络插件 flannel 时出现跨服务器容器网络不通的现象。

现象:当我们完成基于海光、鲲鹏服务器和银河麒麟 V10 操作系统的 kubernetes 集群搭建时,跨节点容器网络测试不通。环境信息如下:

操作系统: Kylin Linux Advanced Server V10 (Tercel)

内核版本: 4.19.90-17.ky10.x86_64

kubernetes 版本: 1.17.4

flannel 版本: 0.11.0 ( vxlan 模式)

分析:参考案例 1 中的经验使用 tcpdump 对 flannel 的 UDP4789 端口抓包发现每个 UDP 数据包并没有出现 bad udp cksum 并且该数据包没有被丢弃,目标节点可以收到 UDP 包,但是只能接收到 TCP 连接第一次握手包,没有返回 ACK ,抓包信息如下:

UDP 包进入目标节点后会通过路由表路由至 cni0 的网桥上,进而进入目标容器,对 cni0 设备抓包没有发现数据包流入,查询主机路由表,其中存在至 cni0 的路由条目,查询 iptables 表、 ipvs 表和非麒麟操作系统相比也未发现异常。排查方向转向 flannel, 开启 flannel debug 级别日志,启动过程中发现 flannel 会创建一个 flannel.1 的网卡,同时会将该卡的 MAC 地址以注释方式写入 k8s 节点信息中和主机 FDB 中,排查要点如下:

  1. flannel 将生成的 flannel.1 的 MAC 地址注释在节点信息中。
  2. 其他节点的 flannel 将此 MAC 地址写入本机的 FDB 中。
  3. 在操作系统层查询 flannel.1 的 MAC 地址。

复盘整个 flannel 启动过程发现银河麒麟节点信息中的 MAC 地址与 FDB 中的 MAC 地址一致,和服务器上观察 flannel.1 的网卡 MAC 不一致,这样就可以解释为什么无法正常建立跨节点的 TCP 链接。通过 ip monitor 观察 flannel.1 网卡的启动过程发现该网卡被赋了两次 MAC 地址,第一次为 flannel 进程赋值,第二次是操作系统赋值。复现方法可以手动删除 flannel.1 网卡后重新启动 flannel 容器,同时用 ip monitor 捕捉事件:

相应的 flannel 组件写入节点注释信息和 FDB 的 MAC 地址:


操作系统层观察到的 flannel 网卡 MAC 地址:

措施:解决方法为创建 /usr/lib/systemd/network/10-flannel.link 文件,在文件内设置 flannel* 网卡的 MACAddressPolicy=none ,也就是对 flannel.1 设置例外不进行 MAC 生成并赋值,这样在 flannel 启动时保证 flannel.1 网卡、 FDB 、节点信息中的 MAC 地址的一致,通过测试容器网络跨节点通信恢复正常。以下为 10-flannel.link 文件内容:

相关 [农行 容器 大坑] 推荐:

农行信创之容器云适配踩过的大坑 - 努力呀 - twt企业IT交流平台

- -
农行研发中心 郑宇光 周思远. 当前国内的信息技术的核心和标准大多数都由国外公司掌握和制定,因此存在诸多的安全风险. 随着我国加快推进信息网络等新型基础设施建设、网络主权概念的逐步明确,信息技术应用创新产业已经成为当前信息化部署的关键词. 我国正在大力推动政府、国防、金融、交通等关键领域的信息化产品尽快实现国产化替代,并发布了多个重要政策来保障国产化的实施,加速实现信息核心技术的自主可控.

Android线程大坑

- - 移动开发 - ITeye博客
     android界面的更新实在主线程进行的,通常把主线程也叫UI线程,UI线程里进行事件的分发和交互. 在UI线程中进行耗时操作,比如网络请求,IO操作等会阻塞UI线程,界面会卡住,并且超过大概5秒钟程序会ANR(Application Not Responding),也就是死掉. 其实这种GUI单线程的思想在我上一篇博客(http://zyqwst.iteye.com/blog/2262011)都有阐述,道理一模一样,只是android实现的方式上略有不同,所以我建议把上一篇Swing线程的博客能够阅读一遍,Android线程的问题豁然开朗,始终晋级GUI开发的原则:在UI线程中进行界面的更新操作,在单独线程中进行耗时操作.

请警惕 ES 的三大坑

- - InfoQ推荐
搜索引擎现在是用得越来越多了,比如 日志系统用到的 ELK 中的 E 就是 搜索引擎 Elasticsearch(简称 ES). 那对于搜索这种技术来说,最看重的是搜索的结果的准确性和搜索的响应时间. ES 的准确性可以通过 倒排索引算法来保证,那响应时间就需要磁盘或缓存来支持了,那么磁盘和缓存会带来哪些坑呢.

Java中的CopyOnWrite容器

- - 酷 壳 - CoolShell.cn
感谢  清英 同学的投稿. Copy-On-Write简称COW,是一种用于程序设计中的优化策略. 其基本思路是,从一开始大家都在共享同一个内容,当某个人想要修改这个内容的时候,才会真正把内容Copy出去形成一个新的内容然后再改,这是一种延时懒惰策略. 从JDK1.5开始Java并发包里提供了两个使用CopyOnWrite机制实现的并发容器,它们是CopyOnWriteArrayList和CopyOnWriteArraySet.

有赞容器化实践

- - SegmentFault 最新的文章
容器化已经成为一种趋势,它可以解决很多运维中的痛点,比如效率、成本、稳定性等问题,而接入容器的过程中往往也会碰到很多问题和不便. 在有赞最开始做容器化是为了快速交付开发测试环境,在容器化的过程中,我们碰到过容器技术、运维体系适配、用户使用习惯改变等各种问题,本文主要介绍有赞容器化过程中碰到的问题以及采取的方案.

容器网络并不难

- - DockOne.io
【编者的话】本文通过实验方法一步步揭秘容器网络是如何实现容器间的互通,以及容器和外部网络是如何连通的. 使用容器总是感觉像使用魔法一样. 对于那些理解底层原理的人来说容器很好用,但是对于不理解的人来说就是个噩梦. 很幸运的是,我们已经研究容器技术很久了,甚至成功揭秘 容器只是隔离并受限的Linux进程, 运行容器并不需要镜像,以及另一个方面, 构建镜像需要运行一些容器.

美团容器平台架构及容器技术实践

- - 美团点评技术团队
本文根据美团基础架构部/容器研发中心技术总监欧阳坚在2018 QCon(全球软件开发大会)上的演讲内容整理而成. 美团的容器集群管理平台叫做HULK. 漫威动画里的HULK在发怒时会变成“绿巨人”,它的这个特性和容器的“弹性伸缩”很像,所以我们给这个平台起名为HULK. 貌似有一些公司的容器平台也叫这个名字,纯属巧合.

Web容器线程池机制小议

- - ITeye博客
从刚开始学习java,我们就被告知Java是一种支持多线程的语言,每条程序指令都会在一个线程中执行,而启动主线程的入口,是可执行类中的main方法. 我们可以在main方法或其调用的方法中创建新的线程以实现多线程、并发处理的效果. Java入门资料上介绍线程时往往会说明一点,创建线程不是免费的,是有成本的--对内存的消耗、对CPU切换调度的消耗都是成本,所以像数据库连接池这类“创建昂贵型”资源一样,创建好的线程优先被复用而不是每次都创建新的,这就是线程池出现的原因.

虚拟化 VS 容器化 哪家强?

- - ITeye资讯频道
【编者的话】以 Docker 为代表的容器技术一度被认为是虚拟化技术的替代品,然而这两种技术之间并不是不可调和的. 作者分别列举了容器技术以及虚拟化技术的优缺点,并提出将两者结合取长补短的解决方案. 容器为应用程序提供了隔离的运行空间:每个容器内都包含一个独享的完整用户环境空间,并且一个容器内的变动不会影响其他容器的运行环境.

在生产环境运行容器

- - IT瘾-tuicool
【编者的话】Vivek Juneja是一名工作首尔的云服务工程师. 他从2008年就开始接触云服务,是最早的AWS和Eucalyptus的使用者. 本文中总结了在生产环境中使用容器的几个方面,特别是对虚拟机与容器的混合部署的观点很值得推荐给大家. 如果只是把容器限制在开发测试环境中,那么您并没有享受到面向容器研发和发布工作的全部红利.