Calico网络中的ProxyARP

如果K8s使用Calico作为网络方案的话,应该都会知道Calico是个纯3层的方案,也是就说,所有的数据包,都是通过路由的形式找到对应机器和容器的,然后通过BGP协议来将所有的路由同步到所有的机器或者数据中心,来完成整个网络的互联。
简单的来说,Calico针对一个容器,在主机上创建了一堆veth pair,其中一端在主机,一端在容器的网络空间里,然后在主机和容器中分别设置几条路由,来完成网络的互联,我们可以看一个例子:

阅读全文

如何在一秒之内丢弃1000万个网络数据包?

偶然看到一篇cloudflare的博客How to drop 10 million packets per second,如何实现单核情况下一秒钟丢弃1000万个数据包,原文循序渐进,从最简单的用户态丢弃到使用非常新的技术XDP,逐步将单核丢包性能提升到10mpps,很有意思,网上也没有看到原文的中文版本,所以这里顺便翻译一下,看看cloudflare是如何处理类似的情况的。

阅读全文

删除K8s Namespace时卡在Terminating状态

想要删除K8s里的一个Namespace,结果删除了所有该Namespace资源之后使用kubectl delete namespace test发现删除不掉,一直卡在Terminating状态,使用--force参数依然无法删除,报错:
Error from server (Conflict): Operation cannot be fulfilled on namespaces "test": The system is ensuring all content is removed from this namespace. Upon completion, this namespace will automatically be purged by the system.
找了一圈,发现这个Issue,里面有条评论

kubectl get namespace annoying-namespace-to-delete -o json > tmp.json
then edit tmp.json and remove”kubernetes”

curl -k -H “Content-Type: application/json” -X PUT –data-binary @tmp.json https://kubernetes-cluster-ip/api/v1/namespaces/annoying-namespace-to-delete/finalize

and it should delete your namespace,

跟着试了一下,很管用,直接就删除了:
先运行kubectl get namespace test -o json > tmp.json,拿到当前namespace描述,然后打开tmp.json,删除其中的spec字段。因为这边的K8s集群是带认证的,所以又新开了窗口运行kubectl proxy跑一个API代理在本地的8081端口。最后运行curl -k -H "Content-Type: application/json" -X PUT --data-binary @tmp.json http://127.0.0.1:8001/api/v1/namespaces/test/finalize

搞定!

阅读全文

kubelet判断机器是否重启逻辑

如果K8s中某个Node节点重启,在Event信息中会有一条消息,大致内容如Node xxxxx has been rebooted, boot id: xxx,而如果是重启kubelet,则不会有这条消息,所以kubelet是怎么判断是自己重启了还是机器重启了呢?

阅读全文

CentOS系统Bonding+VLAN+Bridge配置

由于业务的需要,需要在我们的一台虚拟化机器上,实现如下的配置:

首先,需要将两块网卡设置Bonding并配置交换机对应端口trunk模式;在此基础上,添加宿主机的IP地址,并添加相应的VLAN,最后,还需要添加一个Bridge,用于桥接创建的虚拟机。

由于本身这台机器就是Openstack的宿主机,所以当前的状况是除了所需要的一个Bridge,其他都已经配置完成了,并且由于Openstack的原因,已经有个Bridge virbr0被绑定到bond0上了。
但是呢,这个Bridge是给ovs用的,也就是说,桥接在virbr0上的网络需要自己带上VLAN的tag才能正常工作,而我们希望的是再有一个Bridge br0,桥接在br0上不需要管理VLAN,保持和宿主机相同就可以。

阅读全文

Kubernetes Pod dnsPolicy 配置

在Kubernetes中,可以针对每个Pod设置DNS的策略,通过PodSpec下的dnsPolicy字段可以指定相应的策略,目前支持的策略如下:

  • Default“: Pod继承所在宿主机的设置,也就是直接将宿主机的/etc/resolv.conf内容挂载到容器中。
  • ClusterFirst“: 默认的配置,所有请求会优先在集群所在域查询,如果没有才会转发到上游DNS。
  • ClusterFirstWithHostNet“: 和ClusterFirst一样,不过是Pod运行在hostNetwork:true的情况下强制指定的。
  • None“: 1.9版本引入的一个新值,这个配置忽略所有配置,以Pod的dnsConfig字段为准。

阅读全文

一行Python生成随机字符串

一行Python代码生成随机字符串:

1
import random, string; print(''.join(random.choice(string.ascii_letters + string.digits) for _ in range(15)))

阅读全文

/etc/resolv.conf search和ndots配置

先说说背景,为什么会要了解一下/etc/resolv.conf配置,起因是一个跑在k8s集群的一个业务出现问题,仔细排查后,发现其中一个Pod的域名解析有问题,域名login.example.com被解析到了一个IP,而这个IP地址是另一个范域名*.ichenfu.com的解析,经过一番调查,最终发现是同事在配置一台机器上的kubelet时填错了clusterDomain的配置,将原本需要配置为c2.ichenfu.com的配置写成了c1.ichenfu.com,那么问题来了,为什么这么配置会导致DNS解析到一个错误的,而且是完全不相干的地址的呢?下面就慢慢分析一下。

首先还原一下场景,默认情况下,kubelet启动Pod的时候,会将DNS配置注入到Pod中,出问题的Pod里/etc/resove.conf内容如下:

1
2
3
nameserver 10.254.0.2
search default.svc.c1.ichenfu.com svc.c1.ichenfu.com c1.ichenfu.com localdomain
options ndots:5

阅读全文

netfilter数据流图

这两天因为内部kubernetes的网络配置问题和同事交流了一下,由于内部使用了calico网络,在内部pod出网时有两种选择,使用nat或者不使用nat,为此还经历了一番讨论,突然发现自己对netfilter包括其相关的很多概念还是比较模糊,所以查了查资料,尝试深入了解一下。

netfilter

在网上找到了一张图,发现还是能比较清楚的描述整个netfilter架构的,来源来自http://xkr47.outerspace.dyndns.org,先把图贴出来:

阅读全文

Harbor折腾升级记

Harbor是vmware中国开发的一款企业级的DockerRegistry服务器,我们内部也是有搭建了一个Harbor,但是版本是0.5,对于当前最新的release版本1.5.2而言已经太老了,确实也有一些问题,比如不支持多级的镜像名称,某些情况下会触发bug导致panic。

所以需要升级一下,既然考虑升级了,就干脆升级到最新的版本1.5.2了。首先说一下目前的Harbor,官方提供的离线安装包里,默认是本地启动一个MySQL,将Harbor需要的一些数据存储在本地的MySQL中的,这个是不能接受的,所以在之前的部署中,是使用了外部的一个MySQL,同样,registry的存储在线上也是使用了共享存储,保证可用性。

不过Harbor的1.5.2版本对于0.5版本变化还是比较大的,首先是增加了adminserver这个角色,将所有的配置都拿到adminserver中存储,ui组件通过http请求定期向adminserver请求当前最新的配置信息,其次是数据库结构,新版本和旧版本相比数据库结构发生了很大的变化。

对于升级操作,官方也提供了解决方案,可以参考migration_guide进行升级,升级工具的镜像官方也是提供了,但是这其中存在一个问题,就是升级工具依赖本地的MySQL,也就是说,这个工具只能工作在MySQL是Harbor离线安装包启动的情况下,如果使用了外部的MySQL,这个升级工具就无法直接使用了。

所以呢,最终还是需要去看一下官方的升级工具是如何实现的,看能否通过其他办法手动升级,于是就花了点时间看了一下代码,找到了最后的实现方式,具体的代码在alembic/mysql这个目录下,原理也很简单,官方使用了一个Python的工具alembic实现了数据库结构的版本管理。

手动运行数据库升级,首先需要安装alembic工具,可以通过pip安装,或者针对不同的发行版找对应的软件包。

下面开始操作:

阅读全文