# 继上次迁移计算节点把部分节点由虚机转换为‘物理机’后,资源还是吃紧 (内存+磁盘), 毕竟vm1的kernel和rootfs都要占用宝贵的资源,所以这次准备把vm1也给禁用掉,所有原来抛在vm1 master节点上的资源都跑到hostubuntu上,也就是准备把hostubuntu作为master节点以及平时的工作节点。

这篇文章记录下操作过程已经中间碰到的问题:

重新生成kube-apiserver的server.crt/server.key 包含hostubuntu的ip地址。因为原来的server证书只包含了vm1的地址10.0.0.61,

#kube-apiserver-csr.json,
{
   "CN": "kube-apiserver",
   "hosts": [
   "vm1",
   "hostubuntu",
       "kubernetes",
       "kubernetes.default",
       "kubernetes.default.svc",
       "kubernetes.default.svc.cluster.local",
       "10.96.0.1",
       "10.0.0.61",
   	"172.16.137.128"   #新的master hostubuntu的地址
   ],
   "key": {
       "algo": "rsa",
       "size": 2048
   },
   "names": [
       {
       }
   ]
}
  1. 数据和配置文件复制 on vm1:
systemctl stop kubelet
    systemctl stop docker
    tar -czvf conf.tar.gz /etc/kubernetes /var/lib/etcd
    scp conf.tar.gz root@hostubuntu:/tmp;

on hostubuntu:tar -C / -xzvf conf.tar.gz 3. 修改新master的配置 修改/etc/kubernetes/bootstrap-kubelet.conf kubelet.conf kube-proxy.config.yaml controller-manager.conf kube-proxy.kubeconfig scheduler.conf 从server: https://10.0.0.61:6443 改为 server: https://172.16.137.128:6443 也就是指向新的master的apiserver 重起kubelet!

开始其他的都改了,忘了修改/etc/kubernetes/kubelet.conf, 仍然是https://10.0.0.61:6443, 碰到一个让我很痛苦的问题: kubelet跑起来后会启动创建/etc/kubernetes/manifests下的静态pod, 我这个集群最开始时使用kubeadm部署的,etcd,kube-apiserver, kube-controllermanager, kube-scheduler都是容器化部署,所以这几个pod很快都被kubelet拉起来了,kubectl命令也可以使用,但是奇怪的是过不了多久就会退出, kube-apiserver日志里有很多decode error的错误,kubelet很快也会报apiserver连接不上,开始误以为etcd数据不对,中间换了几种方法重新backup restore etcd数据还是同样的问题,尝试去掉了livenesscheck也是一样很快就死掉。

后来手工用docker启动etcd, kube-apiserver就没这个问题了, 应该是kubelet强行杀掉了拉起来的pod, 最后查到时这个/etc/kubernetes/kubelet.conf配置没改, 一直指向旧的10.0.0.61的apiserver, 注册超时然后又停掉了自己拉起来的pod。

  1. 修改其他计算节点的配置 on rhel7: rm -rf /etc/kubernetes/kubelet.conf

修改/etc/kubernetes/bootstrap-kubelet.conf 指向新的kube-apiserver 重起kubelet!

kube-proxy组建正常启动,但是网络组件k8s-ovs-node-6v4jc一直启动不起来,这个地方发现还漏了一步, ovs网络组件自身也自带了了etcd,它的存储以hostPath方式放在vm1的磁盘上,好吧吧这块数据也搬到hostubuntu上来。

都是按问题还在, 尝试了不同的网络插件, 比如替换ovs为flannel,报同样的错误:E0527 01:45:08.866085 1 main.go:241] Failed to create SubnetManager: error retrieving pod spec for 'kube-system/kube-flannel-ds-amd64-j2c8w': Get https://10.96.0.1:443/api/v1/namespaces/kube-system/pods/kube-flannel-ds-amd64-j2c8w: dial tcp 10.96.0.1:443: connect: connection refused

10.96.0.1是kubernetes的ClusterIP, 那应该是Kube-proxy不正常了,原因是没有修改/etc/kubernetes/kube-proxy.config.yaml kube-proxy.kubeconfig, 这会导致rhel7节点上的kube-proxy不正常, flannel通过clusterIP访问10.96.0.1也就会失败, flannel初始化失败也就会导致其它的pod创建失败。。。。。

所以总结下就是做下面的操作:

rm -rf /etc/kubernetes/kubelet.conf  kubelet-dynamic-config  kube-proxy.config.yaml  kube-proxy.kubeconfig
/var/lib/kubernetes/pki
  1. 升级master的nsenter 现在flannel或者ovs都好了,但是hostubuntu上创建的pod后有时会CrashLoopBackOff,有些pod比如kube-apiserver, kube-scheduler,kube-controller-manager, etcd又没有问题, 但是rhel7是好的,什么情况, 难道也要重新注册下?重新删创hostubuntu节点注册后,同样的错误,

后来想难道对的pod的liveness check 失败?但是我没有配啊,看了下kubelet的日志中有如下错误:

May 27 11:36:14 hostubuntu kubelet[16847]: W0527 11:36:14.689540   16847 docker_sandbox.go:384] failed to read pod IP from plugin/docker: NetworkPlugin cni failed on the status hook for pod "node-exporter-mxp27_monitor": Unexpected command output usage: nsenter [-h] --target PID [--proc PROCFS] [--ipc] [--pid] [--mnt]
May 27 11:36:14 hostubuntu kubelet[16847]:                [--uts] [--user] [--net] [--all]
May 27 11:36:14 hostubuntu kubelet[16847]:                [command [command ...]]
May 27 11:36:14 hostubuntu kubelet[16847]: nsenter: error: argument --net: ignored explicit argument '/proc/19933/ns/net'
May 27 11:36:14 hostubuntu kubelet[16847]:  with error: exit status 2
May 27 11:36:14 hostubuntu kubelet[16847]: E0527 11:36:14.690074   16847 pod_workers.go:190] Error syncing pod d2c11583-802d-11e9-a72c-000c295160ff ("node-exporter-mxp27_monitor(d2c11583-802d-11e9-a72c-000c295160ff)"), skipping: failed to "StartContainer" for "node-exporter" with CrashLoopBackOff: "Back-off 5m0s restarting failed container=node-exporter pod=node-exporter-mxp27_monitor(d2c11583-802d-11e9-a72c-000c295160ff)"

晕啊, nsenter的版本不对,我也记不清我这台机器上的nsenter什么时候安装的了,反正从rhel7拷贝一个过来就好了。

这也解释了为什么之前有些pod没问题,有些又问题, 没问题的都是些系统组建的pod, 比如ovs, kube-proxy, 这些是一‘hostNetwork’模式启动的,不要用nsenter进入网络命名空间

  1. statefulSets 不正常 但是发现mongodb statefulset还是创建失败,查看kubelet日志发现下面这条错误,
kubelet.go:1662] Failed creating a mirror pod for "kube-controller-manager-hostubuntu_kube-system(f5d347a9ba549dd4761689a4a74ccc38)": pods "kube-controller-manager-hostubuntu" is forbidden: a mirror pod may not reference secrets

响起来在折腾第一个问题时,kubelet杀掉pod后也会清理镜像,我写了这个脚本不停的pull镜像,后来想把imagePullSecrets加到/etc/kubernetes/manifests下的静态pod里是不是就会自动拉镜像,发现也不会自动拉,还给自己埋了这个坑:)

去掉这个/etc/kubernetes/manifests 下的 imagePullSecrets后这个错误没有了, 但是mongodb replicaset还是启动失败, 看了启动步骤里用刀了peerfinder,其主要原来是通过dns获取当前的statefulset里的已经在线的peer, 但到dns组件不正常?

kubectl logs -f coredns-945486bb4-hfqfp -n kube-system 
E0527 05:34:09.627393       1 reflector.go:205] github.com/coredns/coredns/plugin/kubernetes/controller.go:313: Failed to list *v1.Endpoints: Get https://10.96.0.1:443/api/v1/endpoints?limit=500&resourceVersion=0: dial tcp 10.96.0.1:443: connect: connection refused
E0527 05:34:09.627624       1 reflector.go:205] github.com/coredns/coredns/plugin/kubernetes/controller.go:318: Failed to list *v1.Namespace: Get https://10.96.0.1:443/api/v1/namespaces?limit=500&resourceVersion=0: dial tcp 10.96.0.1:443: connect: connection refused

晕倒原来通过clusterip访问还是不正常,难道kube-proxy还没好? 检查了一通都是好的,后来发现节点上还有flannel.1这个设备,可是我已经在使用ovs了,这是之前尝试不同网络插件时留下的,ip link del dev flannel.1, 还是不行, 继续清理删除了cni0, kube-ipvs0 vxlan_sys_4789 这些网络设备, 删除了一个多余的ovs bridge ubuntu_br好了。

折腾啊, 不过这样一折腾我就把原来的k8s集群成功整体从虚机迁移到物理机了!还有个体会就是切换网络组件时一定要仔细检查,包括遗留的网络设备,遗留的cni配置文件,遗留的路由表,有些重起可以清理,但是有些清理不掉,比如ovs bridge里添加的port.