使用kubeadm部署k8s 1.15集群——基于CentOS 7

背景

之前搭建的k8s集群是基于CentOS 7自带yum源,版本老旧,是1.5.2版本,但是目前社区k8s版本已经发布1.15版本了,因此想要了解最新特性和方向还是需要使用最新版本搭建集群。

k8s 1.15版本

我们可以通过版本的release notes(https://kubernetes.io/docs/setup/release/notes/)了解一些信息,尤其是一些组件依赖,因为一般版本升级了,依赖组件也会升级,如果不匹配,有可能特性无法使用,甚至服务也不可用。

比如,k8s使用的容器引擎是docker,1.15版本支持的docker版本为:

The list of validated docker versions remains unchanged.
	The current list is 1.13.1, 17.03, 17.06, 17.09, 18.06, 18.09. (#72823, #72831)

因此如果使用的版本过旧或者过新,可能都会出现问题。

环境准备

节点名称节点IP
master192.168.0.100
node1192.168.0.101
node2192.168.0.102
registry(镜像仓库)192.168.0.200

大前提

1、所有机器关闭防火墙

systemctl stop firewalld.service
systemctl disable firewalld.service

2、所有机器关闭selinux

setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

3、所有机器配置好hostname,并确保集群内能通过hostname访问

hostnamectl set-hostname master
echo "192.168.0.100 master" >> /etc/hosts

4、所有机器关闭swap,镜像仓库机器可不关闭

swapoff -a
注释/etc/fstab中swap的分区挂载项

既然swap已经关闭,那么vm.swappiness参数也要一同设置为0,让进程尽可能使用内存,我们将该参数设置和下一步配置放一起。

5、配置各节点系统内核参数使流过网桥的流量也进入iptables/netfilter框架中

cat > /etc/sysctl.d/k8s.conf <<EOF
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward                 = 1
vm.swappiness                       = 0
EOF

然后执行以下命令,即时生效,

sysctl -p /etc/sysctl.d/k8s.conf

因为配置文件在/etc/sysctl.d/目录,所以不用担心重启后会失效,系统在启动过程中会加载这个目录的配置。

6、确认iptables的FORWARD规则

Docker不知啥时候开始会将iptables filter链的FORWARD规则默认设置为DROP,

[root@CentOS-7-2 ~]# iptables -vnL | grep FORWARD
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
[root@CentOS-7-2 ~]# systemctl start docker
[root@CentOS-7-2 ~]# iptables -vnL | grep FORWARD
Chain FORWARD (policy DROP 0 packets, 0 bytes)

经常会导致集群网络不通,因此需要设置FORWARD规则为ACCEPT

iptables -P FORWARD ACCEPT

并将该操作固化到开机流程中,而且得在docker服务启动之后,因此我们添加一个systemd开机服务,

cat > /usr/lib/systemd/system/forward-accept.service <<EOF
[Unit]
Description=set forward accept
After=docker.service
 
[Service]
ExecStart=/usr/sbin/iptables -P FORWARD ACCEPT
 
[Install]
WantedBy=multi-user.target
EOF
systemctl enable forward-accept && systemctl start forward-accept

当然,也可以直接修改docker的service文件,增加一个服务启动后执行项,效果一样。

vi /usr/lib/systemd/system/docker.service
[Service]
ExecStartPost=/usr/sbin/iptables -P FORWARD ACCEPT

7、安装ntp服务并启动

保证集群间的时间一致,否则会有各种未知问题。

yum install -y ntp
systemctl start ntpd;systemctl enable ntpd

开始搭建

1、所有节点安装docker

上面说到1.15版本支持的docker版本最低为1.13.1,CentOS 7自带repo中docker版本正是1.13.1,因此是OK的。

[root@CentOS-7-4 /home]# yum list docker
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
Available Packages
docker.x86_64                     2:1.13.1-96.gitb2f74b2.el7.centos                      extras

不过我还是想用新一点的版本,毕竟社区版本已经是19.03了。

所以呢,参考docker文档(https://docs.docker.com/install/linux/docker-ce/centos/)安装新的repo,使用高版本的docker。

大致步骤如下:

a、卸载旧版本docker

yum remove -y docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

b、更新docker依赖驱动

yum install -y yum-utils \
  device-mapper-persistent-data \
  lvm2

c、安装docker-ce.repo

yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo

d、看下有提供哪些版本的docker

[root@CentOS-7-4 /home]# yum list docker-ce --showduplicates 
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
...
Available Packages
...
docker-ce.x86_64                   18.06.0.ce-3.el7                           docker-ce-stable 
docker-ce.x86_64                   18.06.1.ce-3.el7                           docker-ce-stable 
docker-ce.x86_64                   18.06.2.ce-3.el7                           docker-ce-stable 
docker-ce.x86_64                   18.06.3.ce-3.el7                           docker-ce-stable 
docker-ce.x86_64                   3:18.09.0-3.el7                            docker-ce-stable 
...
docker-ce.x86_64                   3:18.09.7-3.el7                            docker-ce-stable 
docker-ce.x86_64                   3:18.09.8-3.el7                            docker-ce-stable 
docker-ce.x86_64                   3:19.03.0-3.el7                            docker-ce-stable 
docker-ce.x86_64                   3:19.03.1-3.el7                            docker-ce-stable 

e、安装docker-ce

为了避免过于激进,采用中庸思想,我们选择安装18.06版本的docker-ce,

yum install -y docker-ce-18.06.3.ce-3.el7

f、启动服务并设置开机启动

systemctl start docker
systemctl enable docker

2、准备镜像

由于国内无法访问k8s.gcr.io、quay.io等网站,但是使用kubeadm搭建的方式又会去这些网站拉取k8s相关镜像,这样肯定是会失败的。因此我们先从其他渠道获取镜像,放到自己本地的私有镜像,然后将k8s.gcr.io、quay.io的解析指向我们自己私有的registry就可以曲线救国了。

a、创建自己的私有镜像仓库

docker pull registry
docker run --restart=always -d -p 80:5000 --hostname=my-registry --name my-registry -v /mnt/data/registry:/var/lib/registry registry

在192.168.0.200上创建私有镜像仓库,对外端口映射到80端口,同时挂载本地存储分区到容器中,用于镜像的存储和持久化。

b、获取k8s和flannel相关镜像

k8s使用mirrorgooglecontainers库的镜像,

docker pull mirrorgooglecontainers/kube-apiserver:v1.15.1
docker pull mirrorgooglecontainers/kube-proxy:v1.15.1
docker pull mirrorgooglecontainers/kube-controller-manager:v1.15.1
docker pull mirrorgooglecontainers/kube-scheduler:v1.15.1
docker pull mirrorgooglecontainers/coredns:1.3.1
docker pull mirrorgooglecontainers/etcd:3.3.10
docker pull mirrorgooglecontainers/pause:3.1

flannel使用七牛的镜像获取,

docker pull quay-mirror.qiniu.com/coreos/flannel:v0.11.0-amd64

c、将镜像打上我们自己仓库的tag,并push到私有镜像

docker tag mirrorgooglecontainers/kube-apiserver:v1.15.1  192.168.0.200:80/kube-apiserver:v1.15.1
docker push 192.168.0.200:80/kube-apiserver:v1.15.1
...

其余的镜像也要同样操作,其中192.168.0.200是我们刚才创建私有仓库的机器。

d、修改/etc/hosts,更改域名解析

在master和两个node节点上执行以下操作,

echo "192.168.0.200 quay.io k8s.gcr.io gcr.io"  >> /etc/hosts

这样,在后续使用镜像时都会到我们自己的私有镜像上获取。

3、所有节点(除registry节点)增加insecure-registries选项和设置cgroup驱动

由于我们搭建的镜像仓库使用的是http协议,但是docker pull镜像默认使用https协议,因此需要增加insecure-registries选项配置。

同时修改docker cgroup driver的驱动默认为cgroupfs,

[root@CentOS-7-2 ~]# docker info | grep "Cgroup Driver"
Cgroup Driver: cgroupfs

但是kubelet使用的是systemd,因此也需要将docker的cgroup驱动修改。

cat << EOF > /etc/docker/daemon.json
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "insecure-registries":["192.168.0.200:80", "quay.io", "k8s.gcr.io", "gcr.io"]
}
EOF
systemctl restart docker

重启docker后通过docker info再次确认驱动修改成功。

4、所有节点(除registry节点)安装kubelet kubeadm kubectl

同样,我们使用阿里云的repo源来安装,

cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
yum install -y kubelet kubeadm kubectl
systemctl enable kubelet && systemctl start kubelet

首先获取阿里云k8s repo,然后直接yum安装,省时省力,最后设置服务开机启动并启动服务。

5、 master节点使用kubeadm init 一键式部署集群

所有准备做完后,就可以使用 kubeadm init来初始化整个集群了,

 kubeadm init --pod-network-cidr 10.244.0.0/16

切记,如果集群通信采用flannel的话,执行时一定要带 --pod-network-cidr 参数,并且网络段要和flannel yaml文件中定义的保持一致。

[root@master ~]# kubeadm init --pod-network-cidr 10.244.0.0/16
...
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

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/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 192.168.0.100:6443 --token 6p1t12.uw1tyqp0ajhkinnd \
    --discovery-token-ca-cert-hash sha256:26e28cc6199cd4dfeba4b933311ffb902ff97dc15b9940decd704cfdca9beaa2 

为了让非root用户能使用 kubelet,还是需要作如下的一些配置,

 mkdir -p $HOME/.kube
 sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
 sudo chown $(id -u):$(id -g) $HOME/.kube/config

6、将node节点加入集群中

根据上面的提示,在两个node节点中执行kubeadm join加入集群,

[root@CentOS-7-5 ~]# kubeadm join 192.168.0.100:6443 --token 6p1t12.uw1tyqp0ajhkinnd \
	 --discovery-token-ca-cert-hash sha256:26e28cc6199cd4dfeba4b933311ffb902ff97dc15b9940decd704cfdca9beaa2 
[preflight] Running pre-flight checks
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml'
[kubelet-start] Downloading configuration for the kubelet from the "kubelet-config-1.15" ConfigMap in the kube-system namespace
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Activating the kubelet service
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...

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.

这样我们在master节点就能查到这两个节点了,

[root@master ~]# kubectl get nodes
NAME     STATUS     ROLES    AGE    VERSION
node1    NotReady   <none>   14s    v1.15.1
master   NotReady   master   172m   v1.15.1
node2    NotReady   <none>   11s    v1.15.1

因为我们还没部署集群通信组件flannel,因此节点状态还都是NotReady。

7、master节点部署flannel组件

首先获取yaml文件,然后直接使用该配置文件创建flannel集群,

wget https://raw.githubusercontent.com/coreos/flannel/62e44c867a2846fefb68bd5f178daf4da3095ccb/Documentation/kube-flannel.yml
kubectl apply -f kube-flannel.yml 

部署完成后,过一会就能查看节点状态都OK了,

[root@master ~]# kubectl get nodes
NAME     STATUS   ROLES    AGE     VERSION
node1    Ready    <none>   8m53s   v1.15.1
master   Ready    master   3h1m    v1.15.1
node2    Ready    <none>   8m50s   v1.15.1

到此,整个集群就搭建好了。

异常处理

如果集群初始化过程中出现异常,可以执行reset命令回退,但是记得清理一些数据,否则再次创建集群时会出现各种未知错误。

kubeadm reset
rm -rf $HOME/.kube/
rm -rf /var/lib/cni/
rm -rf /var/lib/kubelet/*
rm -rf /etc/cni/
ip link delete cni0
ip link delete flannel.1
systemctl restart docker

常见问题

1、创建registry容器失败,

OCI runtime create failed: container_linux.go:348: starting container process caused "process_linux.go:297: copying bootstrap data to pipe caused \"write init-p: broken pipe\"": unknown

解决方案:内核版本过低,因为镜像仓库是在CentOS 7.2系统上搭建的,内核版本是3.10.0-327.el7.x86_64,升级到3.10.0-957.21.3.el7.x86_64后问题解决。

yum update kernel
reboot

2、无法从私有镜像仓库中拉取镜像

Error response from daemon: Get https://192.168.0.200:80/v2/: http: server gave HTTP response to HTTPS client

解决方案:这是因为docker默认需要使用https连接,但是我们搭建仓库时用的是http协议,因此需要在docker的启动参数里添加insecure-registries选项,将私有镜像ip地址和quay.io,k8s.gcr.io都添加进去,并且重启docker服务。

在/etc/docker/daemon.json中添加以下选项
{
    "insecure-registries":["192.168.0.200:80","quay.io", "k8s.gcr.io"]
}
systemctl restart docker

3、节点执行kubeadm join后状态一直不正常,kubelet状态不断重启,该节点的flannel pod也一直处于pending状态,

kubelet: Failed to start ContainerManager Cannot set property TasksAccounting, or unknown property

解决方案:升级systemd组件,我这个出问题的节点是CentOS 7.3, systemd版本是systemd-219-30,升级至systemd-219-62后问题解决。

4、在安装flannel网络插件后,发现pod: kube-flannel-ds 一直是CrashLoopBackOff

解决方案:执行kubeadm Init的时候,增加 --pod-network-cidr 10.244.0.0/16参数,不指定这个参数会导致节点网络和flannel yaml中的"Network": "10.244.0.0/16"不一样,使得Node间Cluster IP不通。

——————————

参考

1、https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/

2、https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值