本文最后更新于: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情况