【一点一滴,成材之基!】kubeadm初始化K8S集群

(1)Kubernetes集群介绍
Kubernetes整个集群主要两个部分组成,一个是master节点,对于主节点而言它主要是由三个组件加一个第三方的集群状态存储服务组成。第一是API Server,第二是Scheduler,第三是Controller-Manager。集群上每一个组件最终状态将保存在etcd这个存储之中,而且etcd也应该做高可用。
Kubernetes整个集群主要两个部分组成,二是node节点,可以跟上多个node节点,每个node也是由三个组件组成,一是kubelet集群代理,二是kube-proxy,三个是docker容器引擎。所有的node节点要想能够运行Pod,它们要依赖于docker registry当中所能够取得的镜像来实现。
【一点一滴,成材之基!】kubeadm初始化K8S集群
如果我们现在要去部署一个集群,整个的部署环境如下,我们的节点网络是172.20.0.0/16网段,然后Pod网络我们使用10.244.0.0/16的网段,因为这是flannel默认的,随后Service网络使用的是10.96.0.0/12的网段。
【一点一滴,成材之基!】kubeadm初始化K8S集群
K8S常见的有两种部署方案:第一种采用传统的方式来部署K8S自身,让K8S的组件统统运行为系统级的守护进程,这包括master之上的四个组件,以及每个node之上的三个组件都运行为系统级的守护进程,但是这种安装方式的每一步都需要我们自己手动解决,包括做证书等等,配置过程繁琐而复杂,当然我们也可以借助于工具来解决,在GitHub上有人将部署的每一步都写成了playbook了,你只需要告诉ansible谁是master谁是node,使用playbook执行一遍也能够把K8S部署完成,这种方式都是把相关组件部署为系统级的守护进程,这种方式的坏处在于如果Controller-Manager的进程down了,还需要手动启动,没办法确保自己自动的启动起来。
K8S常见的有两种部署方案:第二种方式我们在每一个节点之上,我们使用kubeadm的工具来进行部署,这是K8S官方提供的专门集群部署工具,每一个节点都作为K8S底层docker运行的节点,也就是说包括master之上都要安装docker,同时每一个节点包括master之上都要安装kubelet,确保docker和kubelet都启动并运行起来,接着我们把第一个节点初始化为master,余下的节点初始化为node,而初始的过程中,在第一个master节点上API Server,Scheduler,Controller-Manager以及etcd全部运行为Pod,也就意味着K8S自己的组件都直接运行为Pod,而后余下的节点上依然把kube-proxy运行为Pod,那么整个集群就运行起来了,需要注意的是这些Pod都是静态Pod。每一个节点本身,也需要以系统守护进程的方式来运行一个flannel的守护进程,以便于为运行在node之上的Pod提供网络功能,master需要flannel,而各node也需要flannel以支撑他们部署的Pod资源彼此间能够互相通信,所以flannel也是Pod化,但这个flannel的确是托管在K8S集群之上的附加组件,是动态的Pod。
(2)kubeadm组件介绍
Kubeadm有很多子组件,第一个是kubeadm init用来初始化集群,第二是kubeadm join让节点加入集群,这两个是初始化并安装集群的工具。这两者支持以下特性,比如强制支持RBAC等。利用/etc/kubernetes/manifests作为静态Pod的清单文件实现Pod部署,另外可以自动帮我们生成ca.crt、ca.key、apiserver.crt、apiserver.key、apiserver-kubelet-client.crt、apiserver-kubelet-client.key等证书文件。而kubeadm init可以帮我们完成集群的初始化,初始化的时候首先会做环境的检查,比如内核是否在3.10版本以上,安装的docker版本如果大于17.03也会有警告,因为K8S目前官方的版本只支持到17.03,检查用户是否以root管理员的身份运行等,如果能满足我们的条件就会去生成对应的证书。接着生成静态Pod的清单文件用于启动API Server,Scheduler,Controller-Manager等一系列重要的集群核心组件。接着包括etcd的相关组件,并生成init的配置文件,同时把节点标记为master,而后启动Pod就可以结束了。当然后面还需要安装kube-proxy addon附件和dns addon附件,另外各node想要加入使用kubeadm join就可以了,join的时候需要做预检查,找到主节点,发现主节点相关信息,通过域共享的令牌认证方式完成认证从而加入集群。每个kubelet也需要一个证书,它需要跟API Server靠CA来签署,所以join的时候会在本地发送一个证书签署请求并发给master,由master签证,master签完后再发给每一个node节点,然后我们的node节点就启动起来了,这就是kubeadm帮我们初始化并安装生成一个K8S集群的过程(网址来源:https://github.com/kubernetes/kubeadm/blob/master/docs/design/design_v1.10.md) 。
【一点一滴,成材之基!】kubeadm初始化K8S集群
(3)kubeadm部署K8S实战
(3.1)我们启动3台虚拟机,其中master的IP地址为172.20.0.70,node01的IP地址为172.20.0.66,node02的IP地址为172.20.0.67(注:如果DNS解析有问题可以配置成8.8.8.8)
【一点一滴,成材之基!】kubeadm初始化K8S集群

【一点一滴,成材之基!】kubeadm初始化K8S集群

【一点一滴,成材之基!】kubeadm初始化K8S集群

(3.2)同时我们在所有主机的/etc/hosts文件中加上主机IP和主机名的对应信息
【一点一滴,成材之基!】kubeadm初始化K8S集群
(3.3)我们使用kubeadm的方式进行安装,可以使用阿里云或者清华大学的镜像站点。在次我们使用阿里云的镜像站点使用kubeadm安装K8S。
网址:https://developer.aliyun.com/mirror/?spm=5176.12901015.0.i12901015.1e6a525caHjAik
【一点一滴,成材之基!】kubeadm初始化K8S集群
(3.4)然后我们在kubernetes目录下找到kubernetes-el7-x86_64目录下的repodata/目录,我们可以把安装的YUM仓库的路径指向这里。
地址:https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
【一点一滴,成材之基!】kubeadm初始化K8S集群
(3.5)如果我们想要做gpgcheck的认证,则可以按照下面的路径,设置YUM仓库的gpgcheck。同时我们还要保证每一个节点之上的iptables和firewalld服务都没有开启,因为随后K8S会大量自己去操作iptables规则的,所以这些服务都不要启动起来,并且设置开机禁用。
gpgcheck下载地址:https://mirrors.aliyun.com/kubernetes/yum/doc/
【一点一滴,成材之基!】kubeadm初始化K8S集群
(3.6)我们不但要K8S,还要安装docker,同时额外还要生成docker仓库的配置文件,它们的前后关系没有那么重要,所以我们首先在阿里云上找docker仓库进行安装(注:需要配置好镜像加速器)
网址:https://developer.aliyun.com/mirror/?spm=5176.12901015.0.i12901015.471f525cVhLwmK
【一点一滴,成材之基!】kubeadm初始化K8S集群
下载地址:https://mirrors.aliyun.com/docker-ce/linux/centos/
【一点一滴,成材之基!】kubeadm初始化K8S集群
(3.7)我们将docker-ce.repo文件下载到master主机的/etc/yum.repos.d目录下
【一点一滴,成材之基!】kubeadm初始化K8S集群
(3.8)同时编辑下载好的docker-ce.repo的文件,将其中的下载路径修改为阿里云的官方站点的地址即可。
【一点一滴,成材之基!】kubeadm初始化K8S集群
(3.9)同时我们也可以把K8S同时一并安装,我们在kubernetes.repo配置文件中配置好baseurl和gpgkey的信息。
# vim kubernetes.repo
编辑一个kubernetes.repo仓库配置文件
【一点一滴,成材之基!】kubeadm初始化K8S集群
[kubernetes]
name=Kubernetes Repo
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
【一点一滴,成材之基!】kubeadm初始化K8S集群
(3.10)此时我们便发现在YUM仓库中已经可以看到docker-ce和kubernetes的程序包了。
# yum repolist
检查yum仓库的信息是否正常
【一点一滴,成材之基!】kubeadm初始化K8S集群
(3.11)然后我们把master主机上的kubernetes和docker-ce仓库文件复制node01和node02上。
# scp kubernetes.repo docker-ce.repo node01:/etc/yum.repos.d/
将kubernetes和docker-ce的仓库文件复制给node01主机上
# scp kubernetes.repo docker-ce.repo node02:/etc/yum.repos.d/
将kubernetes和docker-ce的仓库文件复制给node02主机上
【一点一滴,成材之基!】kubeadm初始化K8S集群
(3.12)然后我们在master主机上首先将文件下载下来然后再将gpgkey导入进来。
# wget https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
在master主机上将rpm-package-key.gpg下载到/root目录下
# rpm --import rpm-package-key.gpg
将rpm-package-key.gpg的认证导入
【一点一滴,成材之基!】kubeadm初始化K8S集群
【一点一滴,成材之基!】kubeadm初始化K8S集群
(3.13.1)接着我们在master主机上安装docker-ce、kubelet、kubeadm和kubectl命令行工具。
# yum list docker-ce --showduplicates
查询docker-ce可以安装的版本
# yum install docker-ce-18.06.0.ce-3.el7 -y
其中docker安装18.06.0.ce-3.el7版本
# yum install kubectl-1.11.1-0 -y
我们也可以指定kubectl安装1.11.1的版本(略)
# yum install kubelet-1.11.1-0 -y
我们也可以指定kubelet安装1.11.1的版本(略)
# yum list kubeadm --showduplicates
查询kubeadm可以安装的版本
# yum install kubeadm-1.11.1-0 -y
我们也可以指定kubeadm安装1.11.1的版本(略)
# kubeadm version
查看安装的kubeadm的版本
# yum install -y kubelet-1.18.1-0 kubeadm-1.18.1-0 kubectl-1.18.1-0 --disableexcludes=kubernetes
docker使用最新版即可使,但是K8S组件使用这个进行安装(用这个)
【一点一滴,成材之基!】kubeadm初始化K8S集群
(3.13.2)配置好docker的镜像加速器
# mkdir /etc/docker
# vim /etc/docker/daemon.json
#阿里云的镜像加速器
{
"registry-mirrors": ["https://xxgatzv7ikxx.mirror.aliyuncs.com","https://registry.docker-cn.com"]
}
# systemctl daemon-reload
将守护进程重新加载一下
# systemctl start docker
将docker启动一下
(3.14.1)方案一(略):接下来我们去启动docker服务,然后再启动kubelet相关服务。我们docker会自动到仓库下载相关的镜像文件,但是由于某些限制,这些文件可能下载不到,建议大家把镜像文件通过其他方式加载完以后导入进来使用。
# vim /usr/lib/systemd/system/docker.service
编辑docker.service文件
【一点一滴,成材之基!】kubeadm初始化K8S集群
(3.14.2)
# systemctl daemon-reload
将daemon守护进程重新加载一下
# systemctl start docker
将docker服务启动起来
# docker info
查看docker运行的配置信息
【一点一滴,成材之基!】kubeadm初始化K8S集群
【一点一滴,成材之基!】kubeadm初始化K8S集群
(3.14.3)经验总结:因为docker随后会生成大量的iptables规则,所以iptables需要打开内生的桥接的相关功能,查看它们的状态是否是1,当为1的时候说明状态是正常的。注意:内存需要大于2G,CPU的个数需要大于2个;同时SELinux要关闭,firewalld防火墙要关闭,swap内存要关闭;/etc/hosts文件需要配置好。
# cat /proc/sys/net/bridge/bridge-nf-call-iptables
查看值的状态是否是1
# cat /proc/sys/net/bridge/bridge-nf-call-ip6tables
查看值的状态是否是1
【一点一滴,成材之基!】kubeadm初始化K8S集群
(3.14.4)此时docker已经设定完成了,接下来我们需要去设定kubelet,我们首先看一下kubelet生成了哪些文件。早期的K8S版本要求每一个节点之上一定不能打开swap设备,但是我们可以人为的设置忽略它,定义方式就是在/etc/sysconfig/kubelet定义设置即可。
# rpm -ql kubelet
查看下kubelet生成了哪些文件
# cat /etc/sysconfig/kubelet
查看设置了哪些参数,额外参数为空
文章参考:https://blog.csdn.net/ma726518972/article/details/106251380/
# swapoff -a && sed -i.bak "s/\/dev\/mapper\/centos-swap/#\/dev\/mapper\/centos-swap/g" /etc/fstab(方法1)
swapoff -a && sed -i.bak "s@\/dev\/mapper\/centos-swap@#\/dev\/mapper\/centos-swap@g" /etc/fstab(方法2)
关闭Swap交换分区
# swapon -s(方法3图1-24-2,用这个)
查询那个分区时开的
# swapoff /dev/sda5
关闭交换分区
# vim /etc/fstab
将fstab文件中的swap注释掉
【一点一滴,成材之基!】kubeadm初始化K8S集群
【一点一滴,成材之基!】kubeadm初始化K8S集群
(3.14.5)我们设置kubelet开机自启动即可,但不能设置启动它,因为我们的各种配置还没有初始化完成,初始化完成之后才可以启动。
# systemctl enable kubelet
设置kubelet开机自动启动
# systemctl enable docker
设置docker开机自动启动
【一点一滴,成材之基!】kubeadm初始化K8S集群
(3.14.6)我们要在kubelet的配置参数文件中加一个参数,表示当swap开启的时候也不会报错。(注意:由于我们没有使用代理软件,所以具体操作时会报错)
# vim /etc/sysconfig/kubelet
编辑kubelet配置文件
KUBELET_EXTRA_ARGS="--fail-swap-on=false"(可省)
【一点一滴,成材之基!】kubeadm初始化K8S集群
# kubeadm init --kubernetes-version=v1.20.2 --pod-network-cidr=10.244.0.0/16 --service-cidr=10.96.0.0/12 --ignore-preflight-errors==Swap
使用kubeadm init做初始化,其中指明自己的初始化集群的版本是v1.20.2,指定Pod的网络是10.244.0.0/16,service的cidr是10.96.0.0/12(如果出现detected "cgroupfs"问题参考:https://www.ywcsb.vip/blog/94.html )(略)
# kubeadm init --image-repository registry.aliyuncs.com/google_containers --kubernetes-version=v1.18.1 --pod-network-cidr=10.244.0.0/16
在master主机上操作集群初始化,使用阿里云的仓库(方法二用这个方法同3.15.4)
【一点一滴,成材之基!】kubeadm初始化K8S集群
(3.15.1)方案二(略):注意在3.14的方案中使用的通过代理的方式来进行镜像的拉取,而我们没有代理软件的时候则可能会出现下载镜像失败的情况,此时我们可以换个方法变通处理一下,我们使用docker pull将镜像文件先拉取到本地。(略)
# docker pull mirrorgooglecontainers/kube-apiserver:v1.11.1(略)
# docker pull mirrorgooglecontainers/kube-controller-manager:v1.11.1(略)
# docker pull mirrorgooglecontainers/kube-scheduler:v1.11.1(略)
# docker pull mirrorgooglecontainers/kube-proxy:v1.11.1 (略)
# docker pull mirrorgooglecontainers/pause:3.1(略)
# docker pull mirrorgooglecontainers/etcd:3.2.18(略)
# docker pull coredns/coredns:1.1.3(略)
【一点一滴,成材之基!】kubeadm初始化K8S集群
(3.15.2)然后我们在master主机上执行命令查看系统所需要的docker镜像的名称。
# kubeadm config images list
使用这个命令获取适合主机所需要的docker镜像名称
【一点一滴,成材之基!】kubeadm初始化K8S集群
(3.15.3)然后再重新给每个镜像打上tag标签,标签为k8s.gcr.io开头的镜像名,并且镜像要命名为我们在3.15.2中查询到的名字,最后把原先下载的那些原命名的镜像使用docker rmi删除掉,其中第5个镜像pause代表的是为一个Pod提供一个底层的基础架构的镜像。(略)
# docker tag docker.io/mirrorgooglecontainers/kube-apiserver:v1.11.1 k8s.gcr.io/kube-apiserver-amd64:v1.11.10 (略)
# docker tag docker.io/mirrorgooglecontainers/kube-controller-manager:v1.11.1 k8s.gcr.io/kube-controller-manager-amd64:v1.11.10 (略)
# docker tag docker.io/mirrorgooglecontainers/kube-scheduler:v1.11.1 k8s.gcr.io/kube-scheduler-amd64:v1.11.10 (略)
# docker tag docker.io/mirrorgooglecontainers/kube-proxy:v1.11.1 k8s.gcr.io/kube-proxy-amd64:v1.11.10 (略)
# docker tag docker.io/mirrorgooglecontainers/pause:3.1 k8s.gcr.io/pause:3.1 (略)
# docker tag docker.io/mirrorgooglecontainers/etcd:3.2.18 k8s.gcr.io/etcd-amd64:3.2.18 (略)
# docker tag docker.io/coredns/coredns:1.1.3 k8s.gcr.io/coredns:1.1.3 (略)
【一点一滴,成材之基!】kubeadm初始化K8S集群
(3.15.4)此时我们在master主机上执行kubeadm init对K8S集群进行初始化操作
# kubeadm init --pod-network-cidr=10.244.0.0/16 --service-cidr=10.96.0.0/12
在master主机上操作集群初始化(略)
# kubeadm init --image-repository registry.aliyuncs.com/google_containers --kubernetes-version=v1.18.1 --pod-network-cidr=10.244.0.0/16
我们使用阿里云的仓库,在master主机上操作集群初始化(方法二图1-29-2和图1-29-3用这个)
【一点一滴,成材之基!】kubeadm初始化K8S集群
【一点一滴,成材之基!】kubeadm初始化K8S集群
(3.15.5)我们在初始化页面的下方可以看到把各node节点加入到K8S集群的命令如下。
# kubeadm join 172.20.0.70:6443 --token ydico9.hb659ilsqr2drul6 --discovery-token-ca-cert-hash sha256:5b8e3a221966fa1a6a76a5c608d19eba098571b742a9d5e902e55b150dc0d1e2(略)
【一点一滴,成材之基!】kubeadm初始化K8S集群
# kubeadm join 172.20.0.70:6443 --token ak4pjl.5nq0f4qp2bnm0ca2 --discovery-token-ca-cert-hash sha256:b8591d6f035d908bf615dd838c6302cb7b9232e0edd0fea26e3e321272083829(用这个)
【一点一滴,成材之基!】kubeadm初始化K8S集群
# kubeadm token list
如果我们忘记了token的值,我们可以通过这个方法查询到token
# openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
如果我们也忘记了sha256的哈希值,也可以通过如上的命令查询到sha256的值
【一点一滴,成材之基!】kubeadm初始化K8S集群
(3.16)接着我们开始设置node01和node02主机,我们在两台节点主机上安装docker-ce、kubelet、kubeadm和kubectl。
# yum list docker-ce --showduplicates
查询docker-ce可以安装的版本
# yum install docker-ce-18.06.0.ce-3.el7 -y
其中docker安装18.06.0.ce-3.el7版本
# yum install kubectl-1.11.1-0 -y
我们也可以指定kubectl安装1.11.1的版本(略)
# yum install kubelet-1.11.1-0 -y
我们也可以指定kubelet安装1.11.1的版本(略)
# yum list kubeadm --showduplicates
查询kubeadm可以安装的版本
# yum install kubeadm-1.11.1-0 -y
我们也可以指定kubeadm安装1.11.1的版本(略)
# kubeadm version
查看安装的kubeadm的版本
# yum install -y kubelet-1.18.1-0 kubeadm-1.18.1-0 kubectl-1.18.1-0 --disableexcludes=kubernetes
docker使用最新版即可使,但是K8S组件使用这个进行安装(用这个)
【一点一滴,成材之基!】kubeadm初始化K8S集群
(3.17)我们在master主机上查看监听的端口信息
# ss -tnl
查询master主机上是否有监听6443端口
【一点一滴,成材之基!】kubeadm初始化K8S集群
(3.18)然后我们在master主机上第一创建一个隐藏目录,第二将admin.conf拷贝到创建的隐藏目录下,第三将这个文件的属主和属组改为当前普通用户。
# mkdir -p $HOME/.kube
创建一个隐藏目录
# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
kubeadm帮我们自动初始化好的一个被kuectl拿来可以做配置文件,指定连接至K8S的API Server并完成认证的配置文件
# sudo chown $(id -u):$(id -g) $HOME/.kube/config
进行权限设置
【一点一滴,成材之基!】kubeadm初始化K8S集群
# kubectl get componentstatus
显示当前组件状态的健康与否
# kubectl get cs
显示当前组件状态的健康与否(如果显示unknown可以用这个方式查看kubectl get cs -o yaml)
# kubectl get nodes
查询集群节点信息如下
【一点一滴,成材之基!】kubeadm初始化K8S集群
(3.19)我们看到上面的节点信息显示的是NotReady的状态,是属于未就绪的状态,之所以是未就绪状态是由于它缺少一个网络组件,没有网络,它的各Pod之间是没法通信的,所以我们在主节点上部署flannel,我们需要登录到GitHub上找到flannel项目(https://github.com/coreos/flannel) ,然后按照提示的命令操作。
# kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
【一点一滴,成材之基!】kubeadm初始化K8S集群
# wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
将kube-flannel.yml文件下载到本地来
# docker pull quay.io/coreos/flannel:v0.13.1-rc2
我们可以把kube-flannel.yml文件中定义的flannel插件拖到本地来
【一点一滴,成材之基!】kubeadm初始化K8S集群
【一点一滴,成材之基!】kubeadm初始化K8S集群
# kubectl get nodes
查看节点的状态信息
# kubectl get pod -n kube-system
查看节点的运行状态信息
【一点一滴,成材之基!】kubeadm初始化K8S集群
# journalctl -f -u kubelet
如果有报错,查看报错的日志信息
(3.20)然后我们在node01和node02节点将kubelet服务和docker服务启动并设置为开机自动启动。
# systemctl start kubelet
node01和node02节点上将kubelet启动起来
# systemctl enable kubelt
node01和node02节点上将kubelet设置为开机自动启动
# systemctl start docker.service
node01和node02节点上将docker启动起来
# systemctl enable docker.service
node01和node02节点上将docke设置为开机自动启动
(3.21)接着我们在node01和node02节点执行如下加入集群的命令即可。
# kubeadm join 172.20.0.70:6443 --token ak4pjl.5nq0f4qp2bnm0ca2 --discovery-token-ca-cert-hash sha256:b8591d6f035d908bf615dd838c6302cb7b9232e0edd0fea26e3e321272083829
【一点一滴,成材之基!】kubeadm初始化K8S集群
# docker image ls
同时我们在node01和node02节点上看到系统已经自动下载了kube-proxy、pause和flannel这三个文件了
【一点一滴,成材之基!】kubeadm初始化K8S集群
(3.22)此时我们发现所有的节点都已经是就绪状态,运行起来了,以上我们的环境搭建成功。
# kubectl get pods -n kube-system -o wide
查看节点运行的扩展信息
# kubectl get nodes
查看节点运行状态信息
【一点一滴,成材之基!】kubeadm初始化K8S集群

—————— 本文至此结束,感谢阅读 ——————

猜你喜欢

转载自blog.51cto.com/13613726/2631255