暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

搭建高可用K8S集群(1.20.5版)

梧桐的风雪 2021-09-02
692

########################环境介绍#######################

基于CentOS7.6版本搭建一套高可用K8S集群,由3个master节点和3个work节点构成。由于内网环境无法直接上网,需要设置代理。

如果可以直接连接互联网,请直接忽略相关部分。

硬件配置和相关规划信息如下:

功能IP主机名CPU内存(GB)系统
master192.168.12.191master148CentOS7.6
master192.168.12.192master248CentOS7.6
master192.168.12.193master348CentOS7.6
worker192.168.12.194node148CentOS7.6
worker192.168.12.195node248CentOS7.6
worker192.168.12.196node348CentOS7.6


#####################系统基础配置#####################

安装基础软件包

yum -y install vim git lrzsz wget net-tools bash-completion

------------------------------------------------------------------------------

设置域名解析,配置上网代理,这里使用ansible配置

hosts文件内容:

cat > hosts << EOF

[master]

192.168.12.191 hostname=master1

192.168.12.192 hostname=master2

192.168.12.193 hostname=master3

[node]

192.168.12.194 hostname=node1

192.168.12.195 hostname=node2

192.168.12.196 hostname=node3

[all:vars]

ansible_ssh_user=monitor

ansible_become=true

EOF

------------------------------------------------------------------------------

ansible playbook文件,为了方便配置内网代理,此方法方便以后做配置,为了快速搭建,后续还是先用shell命令完成,后续再完善这一块内容:

cat > set_etc_hosts.yml << EOF

---

- hosts: all

gather_facts: true

tasks:

- name: modify hostname

raw: "echo {{hostname | quote}} > /etc/hostname"

- name: shell

shell: hostname {{hostname|quote}}

- name: register hosts

set_fact:

hosts: "{{ groups.master + groups.node| unique | list }}"

- debug:

msg: "{{ hosts }}"

- name: set /etc/hosts all ip and hostname

lineinfile:

dest: /etc/hosts

#regexp: '^{{ hostvars[item].hosts }}'  #删除已有的记录,对应的state为absent

state: present

line: |

{{ item }} {{ hostvars[item].hostname }}

with_items:

- "{{ hosts }}"

- name: set http and https proxy

lineinfile:

dest: /etc/profile

regexp: '^export http_proxy=192.168.13.x:xxxxx'

state: present

line: |

export http_proxy=192.168.13.x:xxxxx

- name: set http and https proxy

lineinfile:

dest: /etc/profile

regexp: '^export https_proxy=192.168.13.x:xxxxx'

state: present

line: |

export https_proxy=192.168.13.x:xxxxx

- name: set http and https proxy to bashrc

lineinfile:

dest: /etc/bashrc

regexp: '^export http_proxy=192.168.13.x:xxxxx'

state: present

line: |

export http_proxy=192.168.13.x:xxxxx

- name: set http and https proxy to bashrc

lineinfile:

dest: /etc/bashrc

regexp: '^export https_proxy=192.168.13.x:xxxxx'

state: present

line: |

export https_proxy=192.168.13.x:xxxxx

EOF

------------------------------------------------------------------------------

执行命令:

ansible-playbook -i host1 set_etc_hosts.yml

------------------------------------------------------------------------------

设置防火墙、selinux:

systemctl stop firewalld systemctl disable firewalld setenforce 0 sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config

------------------------------------------------------------------------------

设置网桥:

CNI插件需要在L2层进行数据包的转发,需要用到iptables的Forward转发规则,所以需要做如下配置:

cat > /etc/sysctl.d/k8s.conf << EOF

net.bridge.bridge-nf-call-ip6tables = 1

net.bridge.bridge-nf-call-iptables = 1

net.ipv4.ip_forward = 1

EOF

使其生效:

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

------------------------------------------------------------------------------

虽然新版的K8S已经支持了swap,但是我们一般用不到,所以关掉:

swapoff -a yes | cp /etc/fstab /etc/fstab_bak cat /etc/fstab_bak | grep -v swap > /etc/fstab rm -rf /etc/fstab_bak

echo vm.swappiness = 0 >> /etc/sysctl.d/k8s.conf sysctl -p /etc/sysctl.d/k8s.conf

------------------------------------------------------------------------------

设置IPVS:

安装软件:

yum -y install ipvsadm ipset

配置脚本:

cat > /etc/sysconfig/modules/ipvs.modules << EOF

#!/bin/bash

modprobe -- ip_vs

modprobe -- ip_vs_rr

modprobe -- ip_vs_wrr

modprobe -- ip_vs_sh

modprobe -- nf_conntrack_ipv4

EOF

执行:

bash /etc/sysconfig/modules/ipvs.modules

#####################负载均衡配置######################

在master节点上安装haproxy和keepalived

yum -y install haproxy keepalived

------------------------------------------------------------------------------

修改haproxy配置文件

cat > /etc/haproxy/haproxy.cfg << EOF

global

log         127.0.0.1 local2

chroot      /var/lib/haproxy

pidfile     /var/run/haproxy.pid

maxconn     4000

user        haproxy

group       haproxy

daemon

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

maxconn                 3000

frontend  k8s_https *:8443

mode      tcp

maxconn      2000

default_backend     https_sri

backend https_sri

balance      roundrobin

server master1-api 192.168.12.191:6443  check inter 10000 fall 2 rise 2 weight 1

server master2-api 192.168.12.192:6443  check inter 10000 fall 2 rise 2 weight 1

server master3-api 192.168.12.193:6443  check inter 10000 fall 2 rise 2 weight 1

EOF

------------------------------------------------------------------------------

在master1上创建keepalived配置文件:

cat > /etc/keepalived/keepalived.conf << EOF

global_defs {

router_id LVS_DEVEL

}

vrrp_script check_haproxy {

script "/etc/keepalived/check_haproxy.sh"

interval 3000

}

vrrp_instance VI_1 {

state Master

interface ens160

virtual_router_id 80

priority 100

advert_int 1

authentication {

auth_type PASS

auth_pass 111111

}

virtual_ipaddress {

192.168.12.181/24

}

track_script {

}

}

EOF

------------------------------------------------------------------------------

在master2上创建keepalived配置文件:

cat > /etc/keepalived/keepalived.conf << EOF

global_defs {

  router_id LVS_DEVEL

}

vrrp_script check_haproxy {

   script "/etc/keepalived/check_haproxy.sh"

   interval 3000

}

vrrp_instance VI_1 {

   state Slave

   interface ens160

   virtual_router_id 80

   priority 50

   advert_int 1

   authentication {

       auth_type PASS

       auth_pass 111111

   }

   virtual_ipaddress {

       192.168.12.181/24

   }

   track_script {

   }

}

EOF

------------------------------------------------------------------------------

在master3上创建keepalived配置文件:

cat > /etc/keepalived/keepalived.conf << EOF

global_defs {

  router_id LVS_DEVEL

}

vrrp_script check_haproxy {

   script "/etc/keepalived/check_haproxy.sh"

   interval 3000

}

vrrp_instance VI_1 {

   state Slave

   interface ens160

   virtual_router_id 80

   priority 20

   advert_int 1

   authentication {

       auth_type PASS

       auth_pass 111111

   }

   virtual_ipaddress {

       192.168.12.181/24

   }

   track_script {

   }

}

EOF

------------------------------------------------------------------------------

在所有Master节点上创建haproxy检测脚本:

cat > /etc/keepalived/check_haproxy.sh << EOF

#!/bin/bash

if [ `ps -C haproxy --no-header | wc -l` == 0 ]; then

systemctl start haproxy

sleep 3

if [ `ps -C haproxy --no-header | wc -l` == 0 ]; then

systemctl stop keepalived

fi

fi

EOF

------------------------------------------------------------------------------

修改为可执行权限:

chmod +x /etc/keepalived/check_haproxy.sh

------------------------------------------------------------------------------

在所有master节点上启动haproxy和keepalived,并设置为开机自启动:

systemctl start haproxy keepalived systemctl enable haproxy keepalived systemctl status haproxy keepalived

######################K8S集群配置######################

所有节点上安装docker

安装所需软件包:

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

配置repo库:

yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

安装docker CE:

yum -y install docker-ce

设置开机自启动:

systemctl start docker systemctl enable docker systemctl status docker

------------------------------------------------------------------------------

设置docker镜像源和Cgroup驱动

修改docker cgroup 驱动为systemd:

cat > /etc/docker/daemon.json << EOF

{

 "registry-mirrors": ["https://7y88q662.mirror.aliyuncs.com"],

 "exec-opts": ["native.cgroupdriver=systemd"],

 "log-driver": "json-file",

 "log-opts": {

   "max-size": "100m"

 },

 "storage-driver": "overlay2"

}

EOF

重启docker,验证修改结果:

systemctl restart docker docker info | grep Cgroup

------------------------------------------------------------------------------

安装kubelet、kubeadm和kubectl

添加K8S镜像库:

cat > /etc/yum.repos.d/kubernetes.repo << EOF

[kubernetes]

name=Kubernetes

baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64

enabled=1

gpgcheck=1

repo_gpgcheck=0

gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg

EOF

master节点安装:

yum -y install kubelet-1.20.5-0 kubeadm-1.20.5-0 kubectl-1.20.5-0

work节点安装:

yum -y install kubelet-1.20.5-0 kubeadm-1.20.5-0

所有节点运行:

启动并设置开机自启动:

systemctl start kubelet systemctl enable kubelet

------------------------------------------------------------------------------

下载K8S相关镜像

由于某些不好描述的原因,无法直接访问默认的Google上的镜像库,可手动设置为从阿里云进行下载

在master节点上,查看所需镜像列表:

kubeadm config images list --kubernetes-version 1.20.5

生成镜像拉取脚本:

kubeadm config images list --kubernetes-version 1.20.5 | sed -e 's/^/docker pull /g' -e 's#k8s.gcr.io#registry.aliyuncs.com/google_containers#g' | sh -x

如果无法解析,需要检查DNS配置

因环境而异,可能需要设置docker代理,可以如下设置解决:

mkdir -p /etc/systemd/system/docker.service.d/

cat > /etc/systemd/system/docker.service.d/http-proxy.conf <<EOF

[Service]

Environment="HTTP_PROXY=http://192.168.13.x:xxxxx/"

Environment="HTTPS_PROXY=http://192.168.13.x:xxxxx/"

Environment="NO_PROXY=localhost,127.0.0.1"

EOF

------------------------------------------------------------------------------

修改镜像标签:

docker images | grep registry.aliyuncs.com/google_containers | awk '{print "docker tag ",$1":"$2,$1":"$2}' | sed -e 's#registry.aliyuncs.com/google_containers#k8s.gcr.io#2' | sh -x

删除无用镜像:

docker images | grep registry.aliyuncs.com/google_containers | awk '{print "docker rmi ", $1":"$2}' | sh -x

------------------------------------------------------------------------------

初始化集群:

在master1上生成秘钥,以便免密登录master2和master3:

ssh-keygen -t rsa -b 8096

在master1上执行,复制秘钥到master2,master3上:

for host in master2 master3; do ssh-copy-id -i ~/.ssh/id_rsa.pub $host; done

如果未开启root密码登录可以暂时关闭,复制后再关闭:

sed -i 's/^#PermitRootLogin yes/PermitRootLogin yes/g' /etc/ssh/sshd_config

systemcl restart sshd

sed -i 's/^PermitRootLogin yes/#PermitRootLogin prohibit-password/g' /etc/ssh/sshd_config

systemctl restart sshd

------------------------------------------------------------------------------

在master1上创建集群配置文件:

cat > /etc/kubernetes/kubeadm-config.yaml << EOF

apiVersion: kubeadm.k8s.io/v1beta2

kind: ClusterConfiguration

kubernetesVersion: v1.20.5

controlPlaneEndpoint: "192.168.12.181:6443"

apiServer:

 certSANs:

 - 192.168.12.191

 - 192.168.12.192

 - 192.168.12.193

 - 192.168.12.181

networking:

 podSubnet: 10.200.0.0/16

EOF

------------------------------------------------------------------------------

在master1上初始化集群:

kubeadm init --config /etc/kubernetes/kubeadm-config.yaml

上面红框内命令,后续要用到。

如果未初始化成功,则重置后,处理相关问题后,再初始化:

kubeadm reset

本人遇到的问题,报以下错误,且kubelet服务提示未同步:

[kubelet-check] The HTTP call equal to 'curl -sSL http://localhost:10248/healthz' failed with error: Get "http://localhost:10248/healthz": dial tcp [::1]:10248: connect: connection refused.

解决方法,去掉代理,删除下面红色字体部分:

/usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf

# Note: This dropin only works with kubeadm and kubelet v1.11+

[Service]

Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf"

Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml"

# This is a file that "kubeadm init" and "kubeadm join" generates at runtime, populating the KUBELET_KUBEADM_ARGS variable dynamically

EnvironmentFile=-/var/lib/kubelet/kubeadm-flags.env

# This is a file that the user can use for overrides of the kubelet args as a last resort. Preferably, the user should use

# the .NodeRegistration.KubeletExtraArgs object in the configuration files instead. KUBELET_EXTRA_ARGS should be sourced from this file.

EnvironmentFile=-/etc/sysconfig/kubelet

ExecStart=

ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS

------------------------------------------------------------------------------

从master1上拷贝证书到master2和master3上:

for host in master2 master3; do

ssh $host "mkdir -p /etc/kubernetes/pki/etcd; mkdir -p ~/.kube/"

scp /etc/kubernetes/pki/ca.crt $host:/etc/kubernetes/pki/ca.crt

scp /etc/kubernetes/pki/ca.key $host:/etc/kubernetes/pki/ca.key

scp /etc/kubernetes/pki/sa.key $host:/etc/kubernetes/pki/sa.key

scp /etc/kubernetes/pki/sa.pub $host:/etc/kubernetes/pki/sa.pub

scp /etc/kubernetes/pki/front-proxy-ca.crt $host:/etc/kubernetes/pki/front-proxy-ca.crt

scp /etc/kubernetes/pki/front-proxy-ca.key $host:/etc/kubernetes/pki/front-proxy-ca.key

scp /etc/kubernetes/pki/etcd/ca.crt $host:/etc/kubernetes/pki/etcd/ca.crt

scp /etc/kubernetes/pki/etcd/ca.key $host:/etc/kubernetes/pki/etcd/ca.key

scp /etc/kubernetes/admin.conf $host:/etc/kubernetes/admin.conf

scp /etc/kubernetes/admin.conf $host:~/.kube/config

done

------------------------------------------------------------------------------

添加master集群节点和work节点:

添加master2和master3到集群中,即上图中的红框1命令:

kubeadm join 192.168.12.181:6443 --token 7u0l9e.fs2lwxh1l1bv3e19 \

--discovery-token-ca-cert-hash sha256:a5c23d3cbe4681b43e267d98cb3456805ad7a4f2e7223dbf4a9077338c95548c \

--control-plane

在node1、node2、node3上执行以下命令,添加工作节点到集群中,即上图中红框2命令:

kubeadm join 192.168.12.181:6443 --token 7u0l9e.fs2lwxh1l1bv3e19 \

--discovery-token-ca-cert-hash sha256:a5c23d3cbe4681b43e267d98cb3456805ad7a4f2e7223dbf4a9077338c95548c

------------------------------------------------------------------------------

在所有master节点上,删除/etc/kubernetes/manifests/kube-scheduler.yaml和/etc/kubernetes/manifests/kube-controller-manager.yaml配置文件中的--port=0参数:

sed -i 's/- --port=0/#- --port=0/g' /etc/kubernetes/manifests/kube-scheduler.yaml

sed -i 's/- --port=0/#- --port=0/g' /etc/kubernetes/manifests/kube-controller-manager.yaml

在master上配置kubectl:

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

------------------------------------------------------------------------------

在任意master节点安装网络组件calico

下载calico配置文件:

https://docs.projectcalico.org/manifests/calico.yaml

修改文件,增加如下内容:

- name: CALICO_IPV4POOL_CIDR  value: "10.200.0.0/16" - name: IP_AUTODETECTION_METHOD  value: "interface=eth.*|en.*"

部署组件:

kubectl apply -f calico.yml

------------------------------------------------------------------------------

开启kube-proxy的ipvs

在任意节点上修改ConfigMap kube-proxy中的mode为ipvs

kubectl edit configmap kube-proxy -n kube-system

在master上通过删除pod实现所有节点的kube-proxy pod重启:

kubectl get pod -n kube-system | grep kube-proxy | awk '{system("kubectl delete pod "$1" -n kube-system")}'

验证:

kubectl logs kube-proxy-qtnsr -n kube-system | grep ipvs

########################功能验证#######################

查看集群node信息:

kubectl get nodes

kubectl get pods -o wide -n  kube-system

至此,一个高可用K8S集群搭建完毕,下一篇开始将介绍相关组件的使用。


文章转载自梧桐的风雪,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论