本文最后更新于:July 18, 2019 am
                
              
            
            
              在VMware虚拟机中的CentOS7集群部署高可用的k8s集群环境(v1.15)。
这里有两篇基础知识的补充和单master节点集群的搭建过程,有需要的同学可以看一下。
k8s重要概念及各组件简介 
在CentOS7上部署k8s集群(v1.15) 
 
1、前期工作 1.1 什么是高可用集群? 简单来说就是master节点不止一个的集群,我们知道k8s的node节点中,非master节点都需要听从master节点来进行任务的调度分配和负载均衡等操作,这样的好处就是我们只需要操作master节点就可以调度所有的node节点,坏处就是如果master节点崩了,那么整个集群也就崩掉了。所以这里的解决方案就是配置多个master节点,如果一个崩掉了还有别的备用备用节点顶上,不至于出现崩溃的情况。
1.2 集群机器 这里必须要说一下,k8s对每个节点的机器配置的最低要求是2C2G,即两核心的CPU,2G的内存,低于这个配置也不是不能用,只是在初始化的时候会警告而已。这里小七采用的是虚拟机的方法(穷学生没有真机集群),具体的配置如下表。
名称 
配置 
IP 
 
 
VIP 
不需要虚拟机,留一个IP即可 
192.168.100.10 
 
master20 
8C4G,CentOS7.6 
192.168.100.20 
 
master21 
8C4G,CentOS7.6 
192.168.100.21 
 
master22 
8C4G,CentOS7.6 
192.168.100.22 
 
node30 
8C8G,CentOS7.6 
192.168.100.30 
 
node31 
8C8G,CentOS7.6 
192.168.100.31 
 
node32 
8C8G,CentOS7.6 
192.168.100.32 
 
真机用的是一块渣渣i7-8700和64G的内存,勉强能撑一下。
1.3 集群间免密登录 之前专门写过一篇文章,这里不再赘述。多主机间实现SSH免密登录 
需要注意的是,在hosts文件中,我们还需要为192.168.100.10添加一下解析。
echo  "192.168.100.10  kubernetes.haproxy.com"  >> /etc/hosts
 
这里的kubernetes.haproxy.com可以改成别的名字,但是注意后面要用到,建议改成有意义的名字。
1.4 时间同步(所有机器) 这里我们使用ntpdate来进行时间同步
 yum install ntpdate -y ntpdate ntp1.aliyun.com hwclock
 
我们也可以在/etc/cron.hourly/下面直接新建一个文件,将ntpdate ntp1.aliyun.com这条命令写进去,这样cron就会每小时执行一次这个同步时间操作。关于cron可以点击这里了解。 
cat  >>/etc/cron.hourly/synctime <<EOF ntpdate ntp1.aliyun.com EOF 
 
 
1.5 升级内核(所有机器) 建议直接升级centos官方的内核,这样兼容性最好。
uname  -r yum update -y yum install -y kernel
 
此外我们还需要设置一下内核的namespace
grubby --args="user_namespace.enable=1"  --update-kernel="$(grubby --default-kernel) "  reboot
 
1.6 关闭防火墙(所有机器) 因为k8s涉及的端口非常多,我们先把防火墙关了,如果安装了iptable也先关掉。 
 systemctl disable  firewalld.service  systemctl stop firewalld.service 
 
1.7 设置selinux(所有机器) 来自官网的说明,必须把selinux改为permissive(直接生效无需重启)或者disabled(需要重启生效) 
通过命令 setenforce 0 和 sed ... 可以将 SELinux 设置为 permissive 模式(将其禁用)。 只有执行这一操作之后,容器才能访问宿主的文件系统,进而能够正常使用 Pod 网络。您必须这么做,直到 kubelet 做出升级支持 SELinux 为止。
 
setenforce 0 sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/'  /etc/selinux/config
 
关于SELinux的简单介绍,可以点击这里查看之前的博客。 
 
1.8 关闭swap(所有机器) k8s官方不推荐我们使用swap分区,所以这里我们也关闭掉。
swapoff -a vim /etc/fstab reboot
 
2、配置ipvs(所有机器)  yum install ipvsadm ipset -y
 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20  modprobe -- ip_vs modprobe -- ip_vs_rr modprobe -- ip_vs_wrr modprobe -- ip_vs_sh modprobe -- nf_conntrack_ipv4 lsmod | grep ip_vscat  <<EOF >> /etc/rc.local modprobe -- ip_vs modprobe -- ip_vs_rr modprobe -- ip_vs_wrr modprobe -- ip_vs_sh modprobe -- nf_conntrack_ipv4 EOF chmod  +x /etc/rc.d/rc.local
 
3、配置k8s相关网络参数(所有机器) 接着我们需要编辑一个k8s的配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 cat  <<EOF > /etc/sysctl.d/k8s.conf net.ipv4.tcp_keepalive_time = 600 net.ipv4.tcp_keepalive_intvl = 30 net.ipv4.tcp_keepalive_probes = 10 net.ipv4.neigh.default.gc_stale_time = 120 net.ipv4.conf.all.rp_filter = 0 net.ipv4.conf.default.rp_filter = 0 net.ipv4.conf.default.arp_announce = 2 net.ipv4.conf.lo.arp_announce = 2 net.ipv4.conf.all.arp_announce = 2 net.ipv4.ip_forward = 1 net.ipv4.tcp_max_tw_buckets = 5000 net.ipv4.tcp_syncookies = 1 net.ipv4.tcp_max_syn_backlog = 1024 net.ipv4.tcp_synack_retries = 2 net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 net.netfilter.nf_conntrack_max = 2310720 fs.inotify.max_user_watches=89100 fs.may_detach_mounts = 1 fs.file-max = 52706963 fs.nr_open = 52706963 net.bridge.bridge-nf-call-arptables = 1 vm.swappiness = 0 vm.overcommit_memory=1 vm.panic_on_oom=0 EOF 
 
4、配置iptables(所有机器) 保险起见,我们还需要配置iptables
cat  >> /etc/sysctl.conf <<EOF net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 EOF  yum install -y bridge-utils.x86_64 modprobe bridge modprobe br_netfilter sysctl -p reboot
 
5、检查配置(所有机器)  curl https://raw.githubusercontent.com/docker/docker/master/contrib/check-config.sh > check-config.sh bash ./check-config.sh
 
这里只需要保证必要项通过就可以了。
6、安装docker(所有机器) 6.1 安装docker centos版本的decker-ce官方安装指导:
https://docs.docker.com/install/linux/docker-ce/centos/ 
这里我们主要是通过yum的方式来安装,如果出现无法连接docker官网的情况,建议检查一下网络,或者使用rpm的方式进行安装。
 sudo yum install -y yum-utils device-mapper-persistent-data lvm2 sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo yum install -y docker-ce docker-ce-cli containerd.io sudo systemctl start docker sudo docker run hello-world sudo systemctl enable  docker
 
6.2 配置cgroup k8s推荐docker的cgroup驱动使用systemd,说是会更稳定,所以这里我们还需要修改一下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 mkdir  /etc/dockercat  > /etc/docker/daemon.json <<EOF {   "exec-opts": ["native.cgroupdriver=systemd"],   "log-driver": "json-file",   "log-opts": {     "max-size": "100m"   },   "storage-driver": "overlay2",   "storage-opts": [     "overlay2.override_kernel_check=true"   ] } EOF mkdir  -p /etc/systemd/system/docker.service.d systemctl daemon-reload systemctl restart docker
 
6.3 配置普通用户 默认情况下,普通用户需要使用sudo才能操作docker,我们这里需要进行一些修改。
 su 普通用户名 sudo groupadd docker sudo gpasswd -a ${USER}  docker sudo systemctl daemon-reload sudo systemctl restart docker
 
7、安装配置keepalived、haproxy(所有master节点) 7.1 安装  yum install socat keepalived haproxy -y systemctl enable  haproxy systemctl enable  keepalivedmv  /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bakmv  /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak
 
7.2 编辑haproxy配置文件 首先我们开启系统的日志功能
vim /etc/rsyslog.conf     #为其添加日志功能 # Provides UDP syslog reception$ModLoad  imudp$UDPServerRun  514                   ------>启动udp,启动端口后将作为服务器工作   # Provides TCP syslog reception$ModLoad  imtcp$InputTCPServerRun  514            ------>启动tcp监听端口 local2.*                                                /var/log /haproxy.log 
 
注意配置文件里面的IP要根据自己的master节点实际情况进行修改。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 cat  >> /etc/haproxy/haproxy.cfg <<EOF global     log	127.0.0.1	local2     chroot      /var/lib/haproxy     pidfile     /var/run/haproxy.pid     maxconn     1024     user        haproxy     group       haproxy     daemon     nbproc      1     stats socket /var/lib/haproxy/stats defaults     mode                    tcp     log                     global     option                  tcplog     option                  dontlognull     option                  redispatch     retries                 3     timeout queue           1m     timeout connect         10s     timeout client          1m     timeout server          1m     timeout check           10s listen stats     mode   	http     bind	0.0.0.0:12345     stats   enable 	log		127.0.0.1	local2 	stats	realm  Haproxy\ Statistics     stats   uri     /stats     stats   auth    admin:admin     stats   admin   if TRUE frontend  k8s 	bind	0.0.0.0:8443     mode      tcp     maxconn      200     default_backend     k8s-https backend k8s-https     balance      roundrobin 	mode	tcp     server master220 192.168.100.20:6443  check inter 10000 fall 2 rise 2 weight 1     server master221 192.168.100.21:6443  check inter 10000 fall 2 rise 2 weight 1     server master222 192.168.100.22:6443  check inter 10000 fall 2 rise 2 weight 1 EOF 
 
7.3 编辑keepalived配置文件 注意,三个节点keepalived配置文件存在区别: 
router_id分别为master20、master21、master22 
state分别为MASTER、BACKUP、BACKUP 
priority分别为100、90、80 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 cat  >> /etc/keepalived/keepalived.conf <<EOF global_defs {    router_id master20    script_user root    enable_script_security } vrrp_script check_haproxy {     script /etc/keepalived/check_haproxy.sh     interval 3 } vrrp_instance VI_1 {     state MASTER     interface ens32     virtual_router_id 80     priority 100     advert_int 1     authentication {         auth_type PASS         auth_pass 1111     }     virtual_ipaddress {         192.168.100.10/24     }     track_script {            check_haproxy     } } EOF 
 
此外我们还需要编辑一个检查的脚本来确保正常
cat  >> /etc/keepalived/check_haproxy.sh <<EOF #!/bin/bash NUM=`ps -C haproxy --no-header |wc -l` if [ $NUM -eq 0 ];then     systemctl stop keepalived fi EOF 
 
8、安装k8s(所有机器) k8s官网提供的yum源并不太好用,我们这里使用阿里云的yum镜像源。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 cat  >> /etc/yum.repos.d/kubernetes.repo <<EOF [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 exclude=kube* EOF  yum clean all yum repolist yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes systemctl enable  kubelet && systemctl start kubelet
 
关于SELinux的简单介绍,可以点击这里查看之前的博客。
9.1 获取默认配置文件  kubeadm config print  init-defaults > kubeadm.conf kubeadm config images list --config kubeadm.conf
 
 不知道为啥这里显示的居然是1.14版本的,小七安装的明明是1.15版本,我们把kubeadm.conf里面的版本号改成1.15再查看
9.2 编辑自定义配置文件 注意下面的ip地址和版本号需要根据实际情况来进行改动。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48  apiVersion: kubeadm.k8s.io/v1beta2 kind: InitConfiguration localAPIEndpoint:   advertiseAddress: 192.168.100.20   bindPort: 6443 --- apiVersion: kubeadm.k8s.io/v1beta2 kind: ClusterConfiguration kubernetesVersion: v1.15.0 controlPlaneEndpoint: "kubernetes.haproxy.com:8443"  imageRepository: registry.aliyuncs.com/google_containers apiServer:   certSANs:   - "master20"    - "master21"    - "master22"    - 192.168.100.10   - 192.168.100.20   - 192.168.100.21   - 192.168.100.22 networking:   podSubnet: "10.244.0.0/16"  certificatesDir: /etc/kubernetes/pki clusterName: kubernetes etcd:   local :     extraArgs:       listen-client-urls: "https://127.0.0.1:2379,https://192.168.100.20:2379"        advertise-client-urls: "https://192.168.100.20:2379"        listen-peer-urls: "https://192.168.100.20:2380"        initial-advertise-peer-urls: "https://192.168.100.20:2380"        initial-cluster: "master20=https://192.168.100.20:2380"        initial-cluster-state: new     serverCertSANs:       - master20       - 192.168.100.20     peerCertSANs:       - master20       - 192.168.100.20 --- apiVersion: kubeproxy.config.k8s.io/v1alpha1 kind: KubeProxyConfiguration mode: ipvs
 
9.3 初始化  kubeadm config images pull --config kubuadm_master20.conf kubeadm init --config kubuadm_master20.conf
 
这里的token需要记下来。然后我们需要切换到非root用户来进行配置。
mkdir  -p $HOME /.kube sudo cp  -i /etc/kubernetes/admin.conf $HOME /.kube/config sudo chown  $(id  -u):$(id  -g)  $HOME /.kube/configecho  "source <(kubectl completion bash)"  >> ~/.bashrc
 
10、安装flannel网络(master20) wget https:// raw.githubusercontent.com/coreos/ flannel/master/ Documentation/kube-flannel.yml
 
我们先下载一下配置文件,为了保险起见,我们手动指定网卡
然后我们执行初始化安装操作。
kubectl apply  -f kube-flannel.yml
 
这时候我们再查看节点就会发现,coredns已经正常工作了。
 
11、分发证书(master20) 我们在master20节点上编写一个脚本进行证书的分发,只需要分发到其他的master节点即可。注意里面的ip地址和用户名需要根据实际情况进行修改。 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 cat  >> districert <<EOF #!/bin/bash for index in 21 22; do   ip=192.168.100.${index}   ssh $ip "mkdir -p /etc/kubernetes/pki/etcd/; mkdir -p /home/tinychen/.kube/"   scp /etc/kubernetes/pki/ca.crt $ip:/etc/kubernetes/pki/ca.crt   scp /etc/kubernetes/pki/ca.key $ip:/etc/kubernetes/pki/ca.key   scp /etc/kubernetes/pki/sa.key $ip:/etc/kubernetes/pki/sa.key   scp /etc/kubernetes/pki/sa.pub $ip:/etc/kubernetes/pki/sa.pub   scp /etc/kubernetes/pki/front-proxy-ca.crt $ip:/etc/kubernetes/pki/front-proxy-ca.crt   scp /etc/kubernetes/pki/front-proxy-ca.key $ip:/etc/kubernetes/pki/front-proxy-ca.key   scp /etc/kubernetes/pki/etcd/ca.crt $ip:/etc/kubernetes/pki/etcd/ca.crt   scp /etc/kubernetes/pki/etcd/ca.key $ip:/etc/kubernetes/pki/etcd/ca.key   scp /etc/kubernetes/admin.conf $ip:/etc/kubernetes/admin.conf   scp /etc/kubernetes/admin.conf $ip:/home/tinychen/.kube/config done EOF 
 
12、配置master21 12.1 编辑自定义配置文件 注意下面的ip地址和版本号需要根据实际情况来进行改动。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46  apiVersion: kubeadm.k8s.io/v1beta2 kind: InitConfiguration localAPIEndpoint:   advertiseAddress: 192.168.100.21   bindPort: 6443 --- apiVersion: kubeadm.k8s.io/v1beta2 kind: ClusterConfiguration kubernetesVersion: v1.15.0 controlPlaneEndpoint: "kubernetes.haproxy.com:8443"  imageRepository: registry.aliyuncs.com/google_containers apiServer:   certSANs:   - "master20"    - "master21"    - "master22"    - 192.168.100.10   - 192.168.100.20   - 192.168.100.21   - 192.168.100.22 networking:   podSubnet: "10.244.0.0/16"  certificatesDir: /etc/kubernetes/pki clusterName: kubernetes etcd:   local :     extraArgs:       listen-client-urls: "https://127.0.0.1:2379,https://192.168.100.21:2379"        advertise-client-urls: "https://192.168.100.21:2379"        listen-peer-urls: "https://192.168.100.21:2380"        initial-advertise-peer-urls: "https://192.168.100.21:2380"        initial-cluster: "master20=https://192.168.100.20:2380,master21=https://192.168.100.21:2380"        initial-cluster-state: existing     serverCertSANs:       - master21       - 192.168.100.21     peerCertSANs:       - master21       - 192.168.100.21 --- apiVersion: kubeproxy.config.k8s.io/v1alpha1 kind: KubeProxyConfiguration mode: ipvs
 
12.2 配置非root用户 前面我们在脚本那里已经创建好了文件夹,我们这里只需要修改权限和添加自动补全就好了。
sudo chown  $(id  -u):$(id  -g)  $HOME /.kube/configecho  "source <(kubectl completion bash)"  >> ~/.bashrc
 
12.3 初始化 注意这里的文件名和IP地址要根据实际情况进行修改。
 kubeadm init phase certs all --config kubeadm_master21.conf kubeadm init phase etcd local  --config kubeadm_master21.conf kubeadm init phase kubeconfig kubelet --config kubeadm_master21.conf kubeadm init phase kubelet-start --config kubeadm_master21.conf
 
然后这一步要切换到非root用户 
 kubectl exec  -n kube-system etcd-master20 -- etcdctl --ca-file /etc/kubernetes/pki/etcd/ca.crt --cert-file /etc/kubernetes/pki/etcd/peer.crt --key-file /etc/kubernetes/pki/etcd/peer.key --endpoints=https://192.168.100.20:2379 member add master21 https://192.168.100.21:2380
 
 kubeadm init phase kubeconfig all --config kubeadm_master21.conf kubeadm init phase control-plane all --config kubeadm_master21.conf kubeadm init phase mark-control-plane --config kubeadm_master21.conf
 
13、配置master22 13.1 编辑自定义配置文件 注意下面的ip地址和版本号需要根据实际情况来进行改动。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47  apiVersion: kubeadm.k8s.io/v1beta2 kind: InitConfiguration localAPIEndpoint:   advertiseAddress: 192.168.100.22   bindPort: 6443 --- apiVersion: kubeadm.k8s.io/v1beta2 kind: ClusterConfiguration kubernetesVersion: v1.15.0 controlPlaneEndpoint: "kubernetes.haproxy.com:8443"  imageRepository: registry.aliyuncs.com/google_containers apiServer:   certSANs:   - "master20"    - "master21"    - "master22"    - 192.168.100.10   - 192.168.100.20   - 192.168.100.21   - 192.168.100.22 networking:   podSubnet: "10.244.0.0/16"  certificatesDir: /etc/kubernetes/pki clusterName: kubernetes etcd:   local :     extraArgs:       listen-client-urls: "https://127.0.0.1:2379,https://192.168.100.22:2379"        advertise-client-urls: "https://192.168.100.22:2379"        listen-peer-urls: "https://192.168.100.22:2380"        initial-advertise-peer-urls: "https://192.168.100.22:2380"        initial-cluster: "master20=https://192.168.100.20:2380,master21=https://192.168.100.21:2380,master22=https://192.168.100.22:2380"        initial-cluster-state: existing     serverCertSANs:       - master22       - 192.168.100.22     peerCertSANs:       - master22       - 192.168.100.22 --- apiVersion: kubeproxy.config.k8s.io/v1alpha1 kind: KubeProxyConfiguration mode: ipvs
 
13.2 配置非root用户 前面我们在脚本那里已经创建好了文件夹,我们这里只需要修改权限和添加自动补全就好了。
sudo chown  $(id  -u):$(id  -g)  $HOME /.kube/configecho  "source <(kubectl completion bash)"  >> ~/.bashrc
 
13.3 初始化 注意这里的文件名和IP地址要根据实际情况进行修改。
 kubeadm init phase certs all --config kubeadm_master22.conf kubeadm init phase etcd local  --config kubeadm_master22.conf kubeadm init phase kubeconfig kubelet --config kubeadm_master22.conf kubeadm init phase kubelet-start --config kubeadm_master22.conf
 
然后这一步要切换到非root用户 
 kubectl exec  -n kube-system etcd-master20 -- etcdctl --ca-file /etc/kubernetes/pki/etcd/ca.crt --cert-file /etc/kubernetes/pki/etcd/peer.crt --key-file /etc/kubernetes/pki/etcd/peer.key --endpoints=https://192.168.100.20:2379 member add master22 https://192.168.100.22:2380
 
 kubeadm init phase kubeconfig all --config kubeadm_master22.conf kubeadm init phase control-plane all --config kubeadm_master22.conf kubeadm init phase mark-control-plane --config kubeadm_master22.conf
 
14、添加node节点 node节点的添加我们只需要切换到root用户执行之前master20初始化成功提示的指令即可。
kubeadm join  kubernetes.haproxy.com:8443 --token m42q2v.y8sffomwkgjlhx8h \     --discovery-token-ca-cert-hash sha256:1829cbaf37e968b43f91e6f0b65e2f2b7985a2d3d17ec66f3af70e0d15db01de 
 
15、查看最终效果 查看节点 
查看pods 
查看集群 kubectl exec  -n kube-system etcd-master20 \  -- etcdctl --ca-file /etc/kubernetes/pki/etcd/ca.crt \  --cert-file /etc/kubernetes/pki/etcd/peer.crt \  --key-file /etc/kubernetes/pki/etcd/peer.key \  --endpoints=https://192.168.100.20:2379 member list
 
查看ipvs情况