安装说明
- OS是CentOS Linux release 7.7.1908 (Core)
- docker-ce最新版本
- kubernetes16.2
卸载原来的Docker版本
如果之前没有安装过可以略过。
# yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine
docker默认将镜像、容器、存储卷和网络等存在 /var/lib/docker下,在卸载老版本的docker时,该目录下的内容是不被删除的.
安装Docker
该教程采用docker的线上仓库来安装,也可以通过手动下载指定版本的rpm包来安装。
安装docker的在线仓库
- 安装所需的依赖包
# yum install -y yum-utils device-mapper-persistent-data lvm2
- 安装在线的稳定仓库
# yum-config-manage --add-repo https://download.docker.com/linux/centos/docker-ce.repo
安装docker引擎社区版本
- 安装最新的docker-engine,docker-cli,containerd
# yum install -y docker-ce docker-ce-cli containerd.io
- 安装指定版本的docker-engine,docker-ce-cli,containerd.io
首先通过 yum list docker-ce --showduplicates | sort -r 列出可以安装的稳定版本,然后从中选出指定版本安装。
# yum list docker-ce --showduplicates | sort -r
# yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io
- 启动容器
# systemctl start docker
安装k8s master节点
使用kubeadm安装,安装过程中有些镜像无法下载需要单独处理。
master节点的环境配置及依赖
- 在所有需要运⾏kubelet的节点上关闭swap
# swapoff -a
Kubernetes官⽅安装⽂档给出的理由是You MUST disable swap in order for the kubelet to work properly. ⽽在实际执⾏过程中发现如果不执 ⾏,则kubeadm直接报错并停⽌执⾏,错误信息说明⽐如禁⽤swap。每次重启都要执⾏swapoffff。TODO 要想办法⾃动化执⾏。
- 关闭防火墙
# systemctl disable firewalld && systemctl stop firwalld
- 关闭SELinux
#setenforce 0
在master上安装kubeadm, kubelet, kubectl
kubeadm能够辅助⾃动化安装kubernetes,但是kubeadm不会⾃动安装kubectl和kubelet。这两者需要⼿动安装。
- 把server binary⾥的kubeadm, kubelet, kubectl三个binary复制到 /usr/bin 下
server binary是Kubernetes github上release的编译好的Kubernetes版本,包括各组件的⼆进制和镜像。进⼊Kubernetes release⻚⾯,点 击某个release的changelog,如: CHANGELOG-1.10.8.md ),下载其中的server binary压缩包
-
下载kubelet的systemd unit定义⽂件,其中的RELEASE变量需要提前export出来,如 v1.16.2
#export RELEASE=v1.16.2
#curl -sSL "raw.githubusercontent.com/kubernetes/…" > /etc/systemd/system/kubelet.service
-
下载kubeadm配置文件
#mkdir -p /etc/systemd/system/kubelet.service.d`
#curl -sSL "raw.githubusercontent.com/kubernetes/…" > /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
-
设置kubelet开机自启动
#systemctl enable kubelet
Kubernetes控制⾯的其他组件都通过kubelet启动,所以只要配置了kubelet的开机⾃启动,kubelet就会去读/etc/kubernetes/manifests⽬录下 的static pod配置,实现etcd、kube-apiserver、kube-controller-manager、kube-scheduler4个组件不⽤单独启动 kubeadm官⽅安装⽂档在⼿动安装的guide⾥(也就是clear linux环境下的guide),推荐安装CNI plugins和ctrctl。但是我没安装并没发现错 误。
配置docker的cgroup driver为kubernetes推荐的systemd
下⾯步骤 kubeadmin init 的时候会提⽰docker使⽤的cgroup driver是cgroupfs,但是The recommended driver is "systemd",可以参考这篇⽂章把 docker配置成⽤systemd作为driver:
cat > /etc/docker/daemon.json <<EOF { "exec-opts": ["native.cgroupdriver=systemd"], "log-driver": "json-file", "log-opts": { "max-size": "100m" }, "storage-driver": "overlay2" } EOF
Restart docker.
#systemctl daemon-reload && systemctl restart docker
以上步骤完成之后kubelet会不停重启,是正常现象,不⽤紧张,接下来开始安装Kubernetes控制平⾯。
官⽅⽂档关于kubelet重启的解释是:The kubelet is now restarting every few seconds, as it waits in a crashloop for kubeadm to tell it what to do.
以上步骤中kubelet等来⾃changlog⾥的server binary,采⽤⼿动安装的⽅式。更加⽅便的是采⽤对应linux distro下的安装包。当前不清楚每个 Kubernetes release对应的kubelet等三个⽂件的版本是什么,只看到changlog⾥的server binary⾥包含了kubelet,也没有从k8s官⽹找到官⽅下载 地址
安装master节点上组件
- 提前load控制平⾯镜像
根据官⽅⽂档中Running kubeadm without an internet connection⼩节内容,kubeadm在init过程中需要启动控制平⾯,因此需要在此之前将控制平⾯ 的对应版本的镜像准备好。
1. 准备apiserver, controller manager, scheduler和kubeproxy组件镜像。将server binary中包含的镜像压缩包load进master节点即可。⽐如:
# docker load -i kube-scheduler.tar
kubernetes 1.16.2版本的时候,load进⼊的镜像名字已经直接可⽤ 但是kubernetes 1.10.8版的时候load完成之后还需要修改镜像名,因为server binary中提供的镜像load进去之后镜像名字不满⾜kubelet的 要求。以kube-proxy为例,load进去之后名字是 k8s.gcr.io/kube-proxy:v1.10.8 ,并不是static pod中需要的 k8s.gcr.io/kubeproxy-amd64:v1.10.8 ,因此需要重新tag。执⾏的命令如下: 在这个repo⾥,我写了⼀个shell脚本ldrnk8simgs.sh来加载和重命名这些 镜像
kube-proxy⽤daemonset启动,并⾮static pod,但是可以⽤相同的命名规则。
2. 准备etcd镜像
执⾏ kubeadm init --kubernetes-version=v1.16.2 --pod-network-cidr10.244.0.0/16 ,在kubernetes 1.16.2版本中,kubeadm并不会在
下载镜像之前把static pod的manifest写到 /etc/kubernetes/manifest/ 下,因此需要等待前⾯的 kubeadm init 下载镜像执⾏错误,才能得到正 确的etcd镜像名称: failed to load k8s.gcr.io/etcd:3.3.10 。 翻墙下载docker镜像的⽅法: 找到 docker.service ⽂件所在(18.09版默认在 /lib/systemd/system/docker.service ),在所在⽬录创建⽬录 mkdir /lib/systemd/system/docker.service.d ,在其中创建 http-proxy.conf ⽂件,内容为:
[Service]
Environment="HTTP_PROXY=http://127.0.0.1:1080/"
注意: 镜像下载完之后把上⾯的配置⽂件删了。
3. 准备pause镜像
和前⾯的情况⼀样, kubeadm init 执⾏错误之后会给出正确的pause镜像名称: failed to pull image k8s.gcr.io/pause:3.1
4. 准备coredns镜像
和前⾯的情况⼀样, kubeadm init 执⾏错误之后会给出正确的pause镜像名称: failed to pull image k8s.gcr.io/coredns:1.3.1
- master节点安装(kubeadm init)
kubeadm init --kubernetes-version=v1.16.2 --pod-network-cidr=10.244.0.0/16
其中:
1. --kubernetes-version告诉kubeadm具体需要安装什么版本的Kubernetes
2. --pod-network-cidr=192.168.0.0/16 flflag的值跟具体⽹络⽅案有关,这个值对应后⾯的calico⽹络⽅案,⽽如果安装的是flflannel,则根据官⽅⽂档则
应该是--pod-network-cidr=10.244.0.0/16
如果所有镜像就绪,则kubeadm init步骤执⾏时间只有不到⼀分钟。如果安装过程遇到错误需要重试,则重试之前运⾏ kubeadm reset 。
- 配置kubectl
下⾯安装pod⽹络的使⽤了kubectl,需要在此之前执⾏如下配置:
- 如果后续流程使⽤root账⼾执⾏,则执⾏
#export KUBECONFIG=/etc/kubernetes/admin.conf
为了以后⽅便可以写到<home>/.profifile下
- 如果后续流程使⽤⾮root账⼾执⾏,则执⾏:
# mkdir -p $HOME/.kube
# cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
# chown $(id -u):$(id -g) $HOME/.kube/config
- 安装pod⽹络
这⾥选择calico,按照Kubernetes官⽅安装⽂档操作即可:
#kubectl apply -f https://docs.projectcalico.org/v3.7/manifests/calico.yaml
- 允许pod调度到master节点上,否则master节点的状态会是not ready(可选,如果⽤来做单节点集群则执⾏此步)
默认会在kubeadm init过程中taint master节点,可以通过执⾏以下命令使pod能够被调度到master节点上:
#kubectl taint nodes --all node-role.kubernetes.io/master-
-
执⾏到这步,我们已经有⼀个单节点Kubernetes集群,可以运⾏pod。如果需要更多node加⼊,则下⾯可以开始把别的节点join到集群⾥
-
如果需要从⾮master节点上远程⽤kubectl操作Kubernetes集群,则是需要把kubectl和admin.conf在远程机器上准备好,执⾏如下指令: scp root@:/etc/kubernetes/admin.conf . 为了验证kubectl是否可以连接到apiserver,执⾏: kubectl --kubeconfig ./admin.conf get nodes ,注意⾥⾯的kubeconfifig flflag。
安装 Node节点上的组件
-
swapoffff -a
-
安装docker
-
安装kubeadm, kubelet, kubectl
- 把前⾯下载的server binary⾥包含的kubeadm, kubelet, kubectl三个binary复制到 /usr/bin 下
changelog⻚⾯的node binary⾥的kube-proxy是⼆进制,并⾮docker镜像,还是把server binary复制到node节点上
- 下载kubelet的systemd service定义⽂件,其中的RELEASE变量为版本号,如 v1.10.8
#export RELEASE=v1.16.2
#curl -sSL "raw.githubusercontent.com/kubernetes/…" > /etc/systemd/system/kubelet.service
#kubeadm join的时候会通过这个systemd unit⽂件启动kubelet
- 下载kubeadm配置⽂件
经过测试这个是必须的,否则kubeadm join显⽰成功,但是在kubectl get nodes始终⽆法得到刚刚join的node。似乎是kubelet找不到 bootstrap-kubelet.conf,⽽在10-kubeadm.conf会指定这个⽂件的⽬录)
mkdir -p /etc/systemd/system/kubelet.service.d
curl -sSL "raw.githubusercontent.com/kubernetes/…" > /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
- 设置kubelet开机启动⾃动,并启动kubelet:
systemctl enable kubelet && systemctl start kubelet
-
准备镜像
未来可能调度到node上的镜像都要准备好:
1. kube-proxy会通过daemonset调度到node
2. calico也会通过daemonset调度到node
3. pause
controller-manager, scheduler,apiserver,etcd通过static pod在master上启动,肯定不会调度到node上
- kubeadm join
在node上执行:
kubeadm join --token : --discovery-token-ca-cert-hash sha256:
这条命令在master上kubeadm init的结束时会在console上显⽰
其中:
1. <token>在master上⽣成,可以在master上执⾏如下命令得到当前所有有效/失效的token
kubeadm token list`
token有效期为24⼩时,如果全都失效了,可以执⾏如下命令⽣成新的token:
kubeadm token create
2. <master-ip>:<master-port>为master的ip端⼝,端⼝默认6443(Kubernetes的secure port)
3. <hash>可以在master上执⾏如下命令查看
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | \
openssl dgst -sha256 -hex | sed 's/^.* //'
hash形如:
8cb2de97839780a412b93877f8507ad6c94f73add17d5d7058e91741c9d5ec78
执⾏到这⾥join已经完成,可以在⼏秒钟后在master上执⾏kubectl get nodes查看当前集群内的node。
新加⼊的node role为none,似乎不影响⼯作
不需要在node上安装cni,join时显⽰的preflflight check中提⽰缺少ebtables也可以不要