概述
很多搭建过kubernetes集群的人都知道在搭建集群前需要做好充足的准备工作,其中就包括对pod网段和service网段的划分,还包括对每台node上的子网段大小的设置,但如果集群搭建完发现之前划分的网段有问题咋办?能改吗?
问题展示
我在实际使用中就遇到一个问题,我首次搭建集群时划分的网段是这样的:
pod网段:10.129.96.0/20
service网段:10.130.96.0/20
node子网段:9(即两个C段地址)
懂网络的朋友一计算就会明白了,pod网段和service网段划分的太小了,只能容纳8个节点,事实也证明后面添加节点的时候总是报错说"Could not find an allocated subnet for node , Waiting…"
解决方案
决定去改两个网段,改的是master节点上的config.yaml,修改后的网段如下:
pod网段:10.129.0.0/16
service网段:10.130.0.0/16
node子网段:9(即两个C段地址)
然后重启master的服务,发现还是原来的报错,咋回事?
然后在kubernetes官方文档里面搜了,说这两个网段一经部署则不能修改,TMD这不是坑人吗?
心里不甘心,想着这肯定是可以改掉的,只是暂时不知道在哪改,于是用IDE打开源码好好研究研究,下面和大家分享下源码的分析过程。
把报错信息在源码里面搜索一下,“Could not find an allocated subnet”,找到subnets.go
subnet, err = node.networkClient.Network().HostSubnets().Get(node.hostName, metav1.GetOptions{})
可以看出node在尝试获取subnet网段,我们再看看它是怎么去Get的,
func (c *hostSubnets) Get(name string, options v1.GetOptions) (result *network.HostSubnet, err error) {
result = &network.HostSubnet{}
err = c.client.Get().
Resource("hostsubnets").
Name(name).
VersionedParams(&options, scheme.ParameterCodec).
Do().
Into(result)
return
}
它原来是通过向master api server发送REST API请求来获取的,因为本人已经对代码比较了解,所以知道client发送的每个REST API请求的信息都是通过etcd来获取的,也就是说网段信息是保存在etcd里面的,那我们在看看这个信息是存在etcd的哪个位置下的,最后在storage_options.go中找到对应代码:
{Resource: "clusternetworks"}: "registry/sdnnetworks",
{Resource: "clusternetworks", Group: "network.openshift.io"}: "registry/sdnnetworks",
网段信息在etcd中的对应位置是:
registry/sdnnetworks
找到后可以有两种方式修改,
用etcdctl命令来修改
用kubectl edit clusternetwork 来修改
修改完后,用kubectl get nodes发现新增加的节点状态已经正常了。