k8s属于云原生的一个技术,是由多个组件组成的大杂烩,并不是一个单纯的组件。
早期的服务,比如web服务,数据库服务等,这些传统的服务可能与云计算不太匹配,云原生服务就是来协调这两者之间。
云原生包括:
**微服务:**比如电商网站里包括用户管理模块、商品管理模块、订单管理模块,传统的想法都是把这些模块放在一个模块里,成为一个整体,拆分不好拆,每个模块想要进行扩展,必须整体进行扩展,不灵活;所谓微服务,就是把这些模块切成多个微服务,每个小服务可以独立运行,甚至可以把其放在不同主机上,这样扩展的话很easy,比如订单访问量很大,那就可以把订单管理的这个主机多fen配几台,这样的话就可以解决这个问题。实现微服务必须使用相关技术,而容器技术就是实现微服务的很好方法。(将一个系统拆成多个微服务,比如说订单管理,用户信息等,而容器技术可以将每个服务以容器的方式去管理)
CNCF下著名的项目:containerd,k8s,普罗米修斯,etcd,harbor,coredns等
containerd就是docker的基础组件,docker的底层进程,即容器的运行时环境,docker包含containerd,后者是其的一部分。安装K8s不需要docker的所有部分,只需要docker里的containerd即可。有传言说K8S不支持docker , 但是K8S只需要Docker的containerd , 其他的部分不需要。
K8S是集群分布式系统,网络中需要的主机节点往往是很多的,按类型可以分为master,worker(node),即管理节点和工作节点。企业内一般master有3或者5台(必须是奇数,1的话没有容错率不选,一般为3或5,7代价太大),而node节点一般很多
为什么master必须是奇数,因为etcd数据库,可用节点必须大于n/2,n为master节点数。etcd是基于RAFT协议开发的分布式键值存储,要求集群需要数量大于(n/2)的正常主节点才能提供服务(n为主节点数) 比如一共有3个,坏了一个,剩下两个大于3/2,所以是可用的,所以会在剩下的两个里边选取出一个新master
https://www.cnblogs.com/cndotabestdota/p/15519430.html
K8S是(谷歌公司)吸收了其他组织的一些软件,API server,controller-manager,scheduler,kubelet,kube proxy是自己的,docker,flannel,etcd,coredns不是k8s公司的组件,这样也避免了谷歌公司一家独大。
由三个网段组成:物理主机(或虚拟机)间通信、pod网段(用来给容器分配地址)、service网络(由于pod每次获得的地址是动态的,结合Service网络用户就能进而使用service来访问,而不需要关注pod地址)
K8S集群组件master主机:负责数据备份管理、组成员通信或原子性提交协议制定等
API server:接口软件,业务都是通过接口进入
controller-manager:控制器管理器
scheduler:调度,将用户发的请求发送给某个节点完成,由其实现
这三个应用都是无状态的,不存数据的,存的数据到etcd里,其相当于mysql,但不是关系型而是键值对数据库。
前三个可以和etcd分开装,但是也可以四个装到一起
worker节点:
kubelet:和主节点之间沟通协商,来实现调度的效果
kube proxy:解决网络和容器之间的通讯问题
docker:k8s容器依赖其的containerd,后者提供了容器运行的基础环境
addons 附件:有些附件是必须的,核心部件,比如Flannel解决网络问题,coredns实现dns解析
为了模拟生产环境,2个haproxy来负责,处理用户请求,两个ha绑定一个虚拟ip,用户访问服务时直接访问此IP即可。访问时需要经过代理haproxy,为了实现代理的高可用,用了两个haproxy.keepalived检测ha的可用性,并在有问题时完成无缝切换。3个master节点,3个node节点,1个harbor,node节点搭建镜像时可以从 habor上下载或者上传.由etcd选择一个合适的master,由master-api-server进入,API server解析请求并处理请求,调度器分析各node节点状况,选择一个最佳的节点将请求带领至此节点。该节点上,本地容器引擎docker来启动容器,如果本地没有镜像,去harbor上pull,也可以从私有镜像上拖。
我的实验环境:centos7
(只是为了实验高可用,所以用了2个master,由于计算机性能的原因,没有使用奇数个,所以没考虑到主节点宕机后的etcd选举)
192.168.1.46 master1.lis.com 主节点和etcd master1
192.168.1.43 master2.lis.com 主节点备份 master2
192.168.1.42 node01.lis.com 工作节点1 node1
192.168.1.44 ha.lis.com haproxy
192.168.1.45 harbor.lis.com habor 同时扮演node2
lscpu 查看cpu参数,2核以上,每个主机至少2G以上内存
ssh在集群内主机建立无密码登录
hostnamectl set-hostname master1.lis.com 修改主机名和实验环境一样
cat /etc/hosts
for i in {42..45};do scp /etc/hosts 192.168.1.$i:/etc/hosts;done
配置主机名解析,并传到各个机器上
sed -i '/swap/s/^/#/' /etc/fstab;swapoff -a 默认禁用swap
每个主机除了需要有唯一的主机名,还需有唯一uuid和MAC地址,对于是由虚拟机克隆过去的主机而言,其uuid,mac,ip都和主机一样,可以通过修改/etc/sysconfig/network-scripts/ifcfg-eth0里的ip,来更改地址,通过uuidgen来随机生成一个uuid来更改配置文件内的uuid,mac地址可以通过编辑-网络配置-高级-生成mac地址,然后将生成的mac地址复制到配置文件内,这样就可保证每台主机的uuid,ip,MAC是不一样的
STEP2:安装habor,keepalivedharbor节点安装harbor 准备好docker-compose-Linux-x86_64、install_docker.sh、harbor-offline-installer-v2.3.2.tgz 这3个文件,执行.sh文件
安装后启动harbor并设置开机自启
systemctl start harbor systemctl enable harbor
安装keepalived,更改conf相关选项
yum install keepalived vim /etc/keepalived/keepalived.confSTEP3:安装haproxy
yum install haproxy vim /etc/haproxy/haproxy.conf
在cfg文件后添加下面几句:
listen stats mode http bind 0.0.0.0:8888 stats enable log global stats uri /status stats auth admin:lwj123 listen kubernetes-api-6443 bind 192.168.1.100:6443 mode tcp server master1 192.168.1.46:6443 check inter 3s fall 3 rise 3 server master2 192.168.1.43:6443 check inter 3s fall 3 rise 3
更改haproxy服务器的一些内核参数
sysctl -w net.ipv4.ip_forward=1 vim /etc/sysctl.conf net.ipv4.ip_nonlocal_bind = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 net.ipv4.ip_forward=1
sysctl -p 执行使配置文件生效
配置好后,重启keepalived服务,然后在windows/system32/etc/hosts下将192.168.1.100映射为www.lisk8s.com,这样就可以使用url/status访问了,登录用户名和密码都在刚刚的配置文件写着
可以看到,访问成功的haproxy页面是这样的,由于还没部署master节点,所以master节点是红色的。
注意keepalived配置完后启动,还要设置开启自启。方便后面使用
systemctl start keepalived systemctl enable keepalived
注意此处修改keepalived文件,keepalived是用来做haproxy的高可用,由于我这里只用了一个haproxy,没有做高可用,如果做高可用的话,按下面步骤修改cfg文件,对于ha1和ha2两个节点上的配置文件是不同的。
master和node节点安装docker,使用install_docker.sh脚本。安装完记得要将配置文件/etc/docker/daemon.json后加上 “exec-opts”: [“native.cgroupdriver=systemd”] 由于没有修改service文件,所以不用reload,直接重启docker服务就行。
在node节点:安装kubeadm,kubelet;这需要先在节点配置K8S源,方便后面下载一些集群必须的镜像。
由于官方网址的一些特殊原因,我们从国内的阿里云官网网站https://developer.aliyun.com/mirror/kubernetes,按照centos的脚本执行,如下
cat </etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/ enabled=1 gpgcheck=0 repo_gpgcheck=0 gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg EOF setenforce 0
yum install kubeadm-1.22.1-0 kubelet-1.22.1-0 -y --nogpgcheck
安装成功后查看版本
kubeadm version kubelet --version
如需要卸载某一版本
kubeadm yum remove kubeadm-1.23.0 -y
除了这两个,master节点还需要安装kubectl,worker(node)节点不用装,命令如下
yum install kubeadm-1.22.1-0 kubelet-1.22.1-0 kubectl-1.22.1-0 -y --nogpgcheckSTEP5:初始化集群
一、第一个master节点执行kubeadm init
kubeadm init --control-plane-endpoint 192.168.1.100 --kubernetes-version=v1.22.1 --pod-network-cidr 10.244.0.0/16 --service-cidr 10.96.0.0/12 --apiserver-advertise-address=192.168.1.46 --image-repository registry.cn-hangzhou.aliyuncs.com/google_containers --token-ttl=0
–control-plane-endpoint 是控制平面的访问端点,可以为IP地址也可以是DNS域名,作用是为管理员或者是集群组件的kubeconfig配置文件的API server的访问地址。 单控制平面时可以不指定此选项,这里由于我们做了ha的高可用,并将地址绑定在192.168.1.100上,因此此IP可以作为控制平面访问端点
–apiserver-advertise-address 为API server通告给其他组件的IP地址,一般为master节点用于集群内部通信的ip地址,0.0.0.0表示节点上所有可用地址。
–pod-network-cidr pod网络的地址范围,其值是CIDR式的网络地址,flannel网络插件的默认值:10.244.0.0/16,caclio的默认值是192.168.0.0/16.
–service-cidr Service网络的地址范围,其值是CIDR式的网络地址,其值默认是10.96.0.0/12,仅flanel一类的网络插件需要手动指定该地址
–token-ttl 共享令牌的过期时间,默认24h,0为永不过期
k8s三大网络部分:pod网络, service网络, 节点网络
------------------------------------------------------------此过程可能会遇到的问题:-------------------------------------------------------------
1.如果之前执行过初始化命令,可能会留下残留文件,rm -rf /etc/kubernetes 即可。如果集群出现异常情况想要重置集群设置,kubeadm reset rm -rf $HOME/.kube/config 然后再执行kubeadm init命令即可。
2.如果在集群初始化过程中出现问题。首先考虑通过以下命令来查找报错信息或日志文件
journalctl -fu kubelet -f follow -u 过滤
journalctl -xeu kubelet systemctl status kubelet tail -100 /var/log/messages
通过错误信息来看是哪里出了问题。我在此部署过程中出现的问题:
1.kubelet和docker的cgroups-driver必须为一样的,同为systemd或者同为cgroupfs。docker更改cgroupdriver为systemd在/etc/docker/daemon.json 添加"exec-opts": [“native.cgroupdriver=systemd”] ,不改的话默认是cgroupfs,kubelet更改的话
vim /usr/lib/systemd/system/kubelet.service 加入如下几句:
[Unit] Description=kubelet: The Kubernetes Node Agent Documentation=https://kubernetes.io/docs/ Wants=network-online.target After=network-online.target [Service] #ExecStart=/usr/bin/kubelet Restart=always ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS #加入此句 $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS #加入此句 StartLimitInterval=0 Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --cgroup-driver=systemd" #加入此句 Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml" #加入此句 RestartSec=10 #加入此句 [Install] WantedBy=multi-user.target
更改ymal配置文件
cat > /var/lib/kubelet/config.yaml <查看docker的 cgroups-driver
docker info | grep Cgroup查看kubelet的 cgroups-driver
systemctl show --property=Environment kubelet | grep cgroup-driver2.每个主机都有唯一的uuid,mac,K8S使用这些信息来唯一标识集群中的节点,因此非唯一的信息会导致集群部署失败。关于唯一mac地址的设置,可以通过修改/etc/sysconfig/network-scripts/ifcfg-eth0里的ip,来更改地址,通过uuidgen来随机生成一个uuid来更改配置文件内的uuid,mac地址可以通过编辑-网络配置-高级-生成mac地址,然后将生成的mac地址复制到配置文件内,这样就可保证每台主机的uuid,ip,MAC是不一样的。
---------------------------------------------------------------------问题描述OVER---------------------------------------------------------------------------
注意:第一个master节点执行初始化命令成功会得到以下重要的信息:
Your Kubernetes control-plane has initialized successfully! To start using your cluster, you need to run the following as a regular user: mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config Alternatively, if you are the root user, you can run: export KUBECONFIG=/etc/kubernetes/admin.conf You should now deploy a pod network to the cluster. Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at: https://kubernetes.io/docs/concepts/cluster-administration/addons/ You can now join any number of control-plane nodes by copying certificate authorities and service account keys on each node and then running the following as root: #这是其他master节点加入集群的命令*kubeadm join 192.168.1.100:6443 --token f9k3a3.c0358ovl103x497u --discovery-token-ca-cert-hash sha256:21eb54df16efc9e1095c8e3dc1933d44f0f038d161c2d592c8232034d59e56 --control-plane Then you can join any number of worker nodes by running the following on each as root: # 这是worker节点加入集群的命令: kubeadm join 192.168.1.100:6443 --token f9k3a3.c0358ovl103x497u --discovery-token-ca-cert-hash sha256:21eb54df16efc9e1095c8e3dc1933d44f0f038d101c2d592c8232034d59e56 #这是生成 kubectl命令的 kube-config 授权文件 mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/configmaster节点初始化后是notready,需要在第一个master节点安装网络组件flannel后再获取集群状态就是ready了
[root@master1 /etc/sysconfig]#kubectl get nodes
NAME STATUS ROLES AGE VERSION
master1 NotReady control-plane,master 8m5s v1.22.1主节点执行 kubectl apply -f kube-flannel-v0.16.3.yml便可安装flannel插件
二、将worker节点加入集群
使用第一步得到的命令
kubeadm join192.168.1.100:6443 --token f9k3a3.c0358ovl103x497u --discovery-token-ca-cert-hashsha256:21eb54df16efc9e1095c8e3dc1933d44f0f038d16101c2d592c8232034d59e56如果成功加入,会显示下列信息:
This node has joined the cluster: Certificate signing request was sent to apiserver and a response was received. The Kubelet was informed of the new secure connection details. Run 'kubectl get nodes' on the control-plane to see this node join the cluster.master1>>kubectl get nodes 多了两个节点
NAME STATUS ROLES AGE VERSION
harbor-node02 NotReady 23m v1.22.1
master1 Ready control-plane,master 41m v1.22.1
node01 Ready 30m v1.22.1三、为了实现主节点高可用:
在第一个主节点上执行 kubeadm init phase upload-certs --upload-certs来生成其他master加入集群需要的令牌
I0331 15:43:51.096536 98189 version.go:255] remote version is much newer: v1.23.5; falling back to: stable-1.22
[upload-certs] Storing the certificates in Secret “kubeadm-certs” in the “kube-system” Namespace
[upload-certs] Using certificate key:
832deebb9830ebaaf1724d4d73ec078a292e35de024a782b444dd27bbd556c3
在其他主节点上执行:注意这个命令是由初始化主节点时成功的信息 加上 刚刚生成的令牌得到的,是两个命令的组合kubeadm join 192.168.1.100:6443 --token f9k3a3.c0358ovl103x497u --discovery-token-ca-cert-hashsha256:21eb54df16efc9e1095c8e3dc1933d44f0f038d16101c2d592c8232034d59e56 --control-plane --certificate-key 832deebb9830ebaadf1724d4d73ec078a292e35de024a782b444dd27bbd556c3如果出现以下说明加入K8S集群成功:
This node has joined the cluster and a new control plane instance was created: Certificate signing request was sent to apiserver and approval was received. The Kubelet was informed of the new secure connection details. Control plane (master) label and taint were applied to the new node. The Kubernetes control plane instances scaled up. A new etcd member was added to the local/stacked etcd cluster. To start administering your cluster from this node, you need to run the following as a regular user: mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config Run 'kubectl get nodes' to see this node join the cluster.至此,主节点上kubectl get nodes发现有2个node,2个master节点
四、创建容器并测试访问
主节点master1上执行
kubectl create deployment demoapp --image=ikubernetes/demoapp:v1.0 --replicas=2 使用镜像在两个node节点创建名为demoapp的控制器(deployment)
–replicas=2表示在两个node节点上都部署demoapp这个pod
[root@master1 ~]#kubectl get pods -o wide 再加-A会显示所有pods的详细情况
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
demoapp-5f7d8f9847-clp7p 1/1 Running 0 32m 10.244.1.3 node01
demoapp-5f7d8f9847-s8g6h 1/1 Running 0 32m 10.244.5.4 harbor-node02
两个节点上都创建了这个pod,并且分配了IP地址,那么主节点就可以通过访问这两个IP来访问pod了,如下[root@master1 ~]#curl 10.244.5.4 iKubernetes demoapp v1.0 !! ClientIP: 10.244.0.0, ServerName: demoapp-5f7d8f9847-s8g6h, ServerIP: 10.244.5.4! [root@master1 ~]#curl 10.244.1.3 iKubernetes demoapp v1.0 !! ClientIP: 10.244.0.0, ServerName: demoapp-5f7d8f9847-clp7p, ServerIP: 10.244.1.3!可以看到每次输入IP访问很不方便,因此我们创建一个service 叫demoapp,关联到demoapp这个pod上,这样用户端只需要访问demoapp这个service即可
[root@master1 ~]#kubectl create service nodeport demoapp --tcp=80:80 #创建nodeport类型的服务,K8S的服务还有其他3种类型clusterip externalname loadbalancer service/demoapp created[root@master1 ~]#kubectl get svc # 查看目前都有的服务 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE demoapp NodePort 10.99.63.9680:32436/TCP 3s # 这就是我们刚创建的服务 kubernetes ClusterIP 10.96.0.1 443/TCP 41h 那么我们再次访问pod时,就可以通过访问这个节点加上port即可,如下
[root@master1 ~]#curl node01:32436 iKubernetes demoapp v1.0 !! ClientIP: 10.244.1.0, ServerName: demoapp-5f7d8f9847-s8g6h, ServerIP: 10. 244.5.4! [root@master1 ~]#curl harbor-node02:32436 iKubernetes demoapp v1.0 !! ClientIP: 10.244.5.0, ServerName: demoapp-5f7d8f9847-clp7p, ServerIP: 10. 244.1.3! [root@master1 ~]#curl harbor-node02:32436 iKubernetes demoapp v1.0 !! ClientIP: 10.244.5.0, ServerName: demoapp-5f7d8f9847-**clp7p**, ServerIP: 10. 244.1.3! [root@master1 ~]#curl harbor-node02:32436 iKubernetes demoapp v1.0 !! ClientIP: 10.244.5.1, ServerName: demoapp-5f7d8f9847-**s8g6h**, ServerIP: 10. 244.5.4!NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
demoapp-5f7d8f9847-clp7p 1/1 Running 0 32m 10.244.1.3 node01
demoapp-5f7d8f9847-s8g6h 1/1 Running 0 32m 10.244.5.4 harbor-node02
由这个可以看出,虽然3次访问的都是harbor-node02节点的demoapp服务,但是每次实际访的demoapp是不一样的,第三次访问的demoapp pod实际是node01上的,这样就做到了负载均衡。客服端不用关系用的是哪台机器上的服务,只需要访问服务即可,K8S集群会按照负载均衡的原理,进行调度,选择最适合的机器来处理这个客户端请求。根据以上的测试的实验可以看出,docker run 只能在一个机器上跑,那需要实现负载均衡,在多个机器上跑docker run 。有了k8s集群之后,有了容器后只需在主节点执行,便可以实现负载均衡。
-----------------------------------------------------------------实验中可能用到的其他命令:------------------------------------------------------------
1、查看防火墙,iptables规则是否禁用
getenforce firewalld getenforce iptables必须保证这两个都是 disabled
2、关闭selinux:
getenforce 为disable
如果没有关闭的话
vim /etc/selinux/config
将SELINUX设置为disable3、关闭swap(我安装的v1.23.0不关闭也没报错,所以我没关闭,早一些的版本是需要关闭的,这里提供关闭的方法)
swapoff -a #暂时关闭永久关闭
vim /etc/fstab #注释掉swap的设备free -m #查看Swap是否关闭4、启动ipvs内核模块
–>cd /usr/lib/modules/3.10.0-1160.el7.x86_64/kernel/net/netfilter/ipvs
–>ls
ip_vs_dh.ko.xz ip_vs_lblcr.ko.xz ip_vs_rr.ko.xz ip_vs_wrr.ko.xz
ip_vs_ftp.ko.xz ip_vs_lc.ko.xz ip_vs_sed.ko.xz
ip_vs.ko.xz ip_vs_nq.ko.xz ip_vs_sh.ko.xz
ip_vs_lblc.ko.xz ip_vs_pe_sip.ko.xz ip_vs_wlc.ko.xz6、启动docker服务
vim /usr/lib/systemd/system/docker.service在[service]里添加
Environment="NO_PROXY=127.0.0.0/8,192.168.29.0/24" ExecStartPost=/usr/sbin/iptables -P FORWARD ACCEPT #192.168.29.0/24是自己集群的网段保存后重启docker服务
systemctl daemon-reload #重加载配置文件 systemctl restart docker #重启服务 docker info #用来查看配置文件是否生效7、确保为这两个内核参数=1
sysctl -a | grep bridgenet.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
如若不为1vim /etc/sysctl.d/k8s.conf net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1wq存盘退出
sysctl -p /etc/sysctl.d/k8s.conf # 重读文件使之生效8、构建k8s仓库
cd /etc/yum.repos.d wget https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/repodata/ vim Kubernetes.repo #写入以下内容 [kubernetes] name=Kubernetes Repo baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/repodata/ gpgcheck=1 enabled=1 gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg ~ #wq存盘退出安装 kubeadm kubelet kubelet
yum repolist yum install kubeadm kubelet kubelet #未指明版本号默认都是最新版rpm -ql kubelet #查看安装生成了什么文件 rpm -ql kubeadm9、初始化master节点的kubeadm
rpm -q kubeadm #查看k8s版本,我的是v1.23.0 kubeadm init --kubernetes-version="v1.23.0" --pod-network-cidr="10.244.0.0/16" --dry-run #先干跑下测试出现以下内容就说明没什么问题了,可以进行下一步
查看初始化要下载的镜像:kubeadm config images list由于直接init,需要到网站 下载以下镜像,这样就会很慢很慢,所以我们先通过镜像网站把这些images下载下来,如果不加镜像网站,默认从gcr.io上下载,很慢。
kubeadm config images pull --image-repository=registry.aliyuncs.com/google_containers出现以下就说明没问题
docker image ls #查看镜像
可以看到下载成功了!更改下名字就可以init啦
镜像文件打包,方便以后使用
docker save -o kubeadm.gz k8s.gcr.io/kube-apiserver:v1.23.0 k8s.gcr.io/kube-controller-manager:v1.23.0 k8s.gcr.io/kube-scheduler:v1.23.0 k8s.gcr.io/kube-proxy:v1.23.0 k8s.gcr.io/pause:3.6 k8s.gcr.io/etcd:3.5.1-0 k8s.gcr.io/coredns/coredns:v1.8.6-----------------------------------------------------------------以下是问题记录及解决方法:------------------------------------------------------------
问题记录:一、从节点加入集群后状态一直是Notready
主节点 kubectl describe node harbor-node02 查看notready原因
发现是:network not ready: NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized Addresses:
在出问题节点上执行 kubelet status -l 查看原因,发现是Apr 04 15:03:06 harbor-node02 kubelet[29282]: E0404 15:03:06.567672 29282 kubelet.go:2332] “Container runtime network not ready” networkReady=“NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized”
都是与cni插件有关,解决方法参照这个连接。
https://www.cnblogs.com/cuicj/articles/14512540.html
将文件复制过去后重置后再加入即可,如下,问题解决,各节点都就位
[root@master1 ~]#kubectl get nodes
NAME STATUS ROLES AGE VERSION
harbor-node02 Ready 12s v1.22.1
master1 Ready control-plane,master 17h v1.22.1
node01 Ready 17h v1.22.1二、获取组件健康信息,发现scheduler不健康
[root@master1 ~]#kubectl get cs Warning: v1 ComponentStatus is deprecated in v1.19+ NAME STATUS MESSAGE ERROR **scheduler Unhealthy** Get "http://127.0.0.1:10251/healthz": dial tcp 127.0.0.1:10251: connect: connection refused controller-manager Healthy ok etcd-0 Healthy {"health":"true","reason":""}解决办法参考
https://www.cnblogs.com/zbhlinux/p/15130723.html三、获取名称空间信息发现coredns一直是containercreating状态
因为flannel没有安装好kubectl apply -f kube-flannel-v0.16.3.yml解决办法参考:
https://www.cnblogs.com/sxgaofeng/p/12213073.html四、主节点创建了2个pod,分别在两个从节点上,但是有一个从节点无法访问(无法ping,curl)
[root@master1 ~]#kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES demoapp-5f7d8f9847-m76gd 1/1 Running 0 61s 10.244.1.2 node01demoapp-5f7d8f9847-t65tl 1/1 Running 0 61s 10.244.5.3 harbor-node02 [root@master1 ~]#curl 10.244.1.2 iKubernetes demoapp v1.0 !! ClientIP: 10.244.0.0, ServerName: demoapp-5f7d8f9847-m76gd, ServerIP: 10. 244.1.2! [root@master1 ~]#curl 10.244.5.3 curl: (7) Failed connect to 10.244.5.3:80; **Connection timed out** 解决方法:
在出故障节点上:
ifconfig如有flannel.1网段地址
清除iptables规则 >>iptables -F
如没有flannel.1网段地址:
参考https://my.oschina.net/u/4408224/blog/4464047五、在各节点都加入集群后,更改某一节点的hosts文件,然后再重启网络失败(systemctl restart network failure)
解决方法:注意,都加入节点了还改hosts干嘛呀,纯粹是我在作死,遇到这种情况我是重启机器(reboot)解决了,但是也仅作为实验环境,生产中应该没有人这种操作吧。。六、集群重置后要删除flannel插件,这样重新建立集群时cni接口才不会出现问题
for i in {42..46};do ssh 192.168.1.$i 'echo y | kubeadm reset';done for i in {42..46};do ssh 192.168.1.$i 'rm -rf /etc/cni/net.d && rm -rf $HOME/.kube/config ';done kubectl logs -f -n kube-system kube-flannel



