部署目的
目前k8s发展太快,版本迭代和更新等,导致现在有很多冲突、不适用的解决方案,故搭建一套各个软件版本都较新的集群。
物理机器和网络准备
一台5600x+32G+有外网的电脑。
VMWARE虚拟机。
centos7最新的dvd版镜像。
高可用方案选择
以前做法:多个master服务器,然后使用keepalived监控master节点的可用性和故障转移,使用haproxy对master进行均衡负载。
新的解决方案:利用K8S原生的kube-vip实现master高可用。
建议使用kube-vip解决方案,这样,不存在VIP节点的问题,其中心思想也是vip架构,但是通过公平选举诞生的。
系统和软件版本选择
centos7.9.2009 3.10.x内核 kube-vip 0.3.8 Kubernetes 1.22.3 containerd(替代docker) 1.5.7 flannel (推荐可用calico替代)
讯享网
主机和节点规划:
hostname ip
讯享网api.k8s.local 192.168.66.10 k8s-master01 192.168.66.11 k8s-master02 192.168.66.12 k8s-master03 192.168.66.13 k8s-node01 192.168.66.21 k8s-node02 192.168.66.22 k8s-node03 192.168.66.23
备注:
1.建议选择centos7,因为centos8无法安装npt和nptdate换成了wntp,8最新内核也取消了ntf-conn_ipvs的插件,8也只能支持到今年年底。
2.建议使用离线安装,不要用boot,重要不会自动获取IP,然后也不会等待软件源更新时间。采用最小安装。
3.vip的域名建议就采用默认的,一定要是那种域名形式的,否则无法解析和运行
初始化环境搭建(6台都需要)
以下步骤重复多台部署,感兴趣的可以用ansible批量部署,我这边没环境就没安排。
分别设置静态ip,然后用xshell批量部署了。
cd /etc/sysconfig/network-scripts,找到里面的网卡名称,再vim进入,在里面添加静态网络信息。
将BOOTPROTO改成static,再添加IP,子网掩码,网关(我这里是66.1),dsn
centos7重启网卡:systemctl restart network
1.centos7 添加yum源
更新国内源。
yum install -y wget
进入yum.repos.d文件夹
讯享网cd /etc/yum.repos.d/ mv CentOS-Base.repo CentOS-Base.repo.backup
下载yum源
wget http://mirrors.163.com/.help/CentOS7-Base-163.repo wget http://mirrors.aliyun.com/repo/Centos-7.repo yum clean all 清除系统yum 缓存 yum makecache 生成yum缓存
2.设置系统主机名以及host文件修改
6台主机分别设置hostname:
讯享网hostnamectl set-hostname api.k8s.local hostnamectl set-hostname k8s-master01 … hostnamectl set-hostname k8s-node03
再修改host文件,让6台机器之间可以互相访问。
vi /etc/hosts
添加6条记录:(自带的千万别删,是添加)
讯享网192.168.66.10 api.k8s.local 192.168.66.11 k8s- master01 192.168.66.12 k8s- master02 192.168.66.13 k8s-master03 192.168.66.21 k8s-node01 192.168.66.22 k8s-node02 192.168.66.23 k8s-node03
3.升级内核版本(先升级)
centos7.x系统自带的3.10.x内核存在一些bug,导致运行的docker和k8s不稳定。所以升级一下,我这边get最新的是5.4,所以就用这个好了
#导入ELRepo仓库的公共密钥
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
#安装ELRepo仓库的yum源
讯享网rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
yum --disablerepo="*" --enablerepo="elrepo-kernel" list available yum --enablerepo=elrepo-kernel install -y kernel-lt #设置开机从新内核启动 grub2-set-default 0 #表示设置最新版本的为默认启动方式 reboot
4.安装依赖包
6台都需安装如下包:
讯享网yum install -y ntpdate ntp conntrack ipvsadm ipset jq iptables curl sysstat libseccomp wget vim net-tools git
解释:ntpdate ntp是同步时间用的组件。
conntrack ipvsadm ipset jq iptables 都是为了开启相应的网络组件
libseccomp:是运行containerd和docker的必要组件。这里有个坑,后面会讲到。
5.设置防火墙为iptable并设置为默认规则
停止防火墙并关闭其自启动:
systemctl stop firewalld && systemctl disable firewalld
安装iptables-services,启动它,并且设置开机自启,清空它的规则,保存默认规则
讯享网yum -y install iptables-services && systemctl start iptables && systemctl enable iptables && iptables -F && service iptables save
6.关闭seniuxs和虚拟内存
关闭swap分区(即虚拟内存)并且将其永久关闭。(虚拟内存在k8s里怕拖累系统运行速度)
swapoff -a && sed -i '/swap/s/^\(.*\)$/#\1/g' /etc/fstab
SELinux 主要作用就是最大限度地减小系统中服务进程可访问的资源,安全用。浪费资源和权限
讯享网setenforce 0 && sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config
7.调整内核参数
cat > kubernetes.conf <<EOF net.bridge.bridge-nf-call-iptables=1 #开启网桥模式 net.bridge.bridge-nf-call-ip6tables=1 #开启网桥模式 net.ipv4.ip_forward=1 #net.ipv4.tcp_tw_recycle=0 vm.swappiness=0 #禁止使用swap空间,只有当系统OOM时才允许使用它 vm.overcommit_memory=1 #不检查物理内存是否够用 vm.panic_on_oom=0 #开启OOM fs.inotify.max_user_instances=8192 fs.inotify.max_user_watches= fs.file-max= fs.nr_open= net.ipv6.conf.all.disable_ipv6=1 #关闭ipv6的协议 net.netfilter.nf_conntrack_max= EOF
注:
net.bridge.bridge-nf-call-iptables=1 #开启网桥模式
net.bridge.bridge-nf-call-ip6tables=1 #开启网桥模式
net.ipv6.conf.all.disable_ipv6=1 #关闭ipv6的协议
以上为开启k8s必须的方案,其余仅为优化选项。
讯享网cp kubernetes.conf /etc/sysctl.d/kubernetes.conf #拷贝文件至sysctl.d目录下 sysctl -p /etc/sysctl.d/kubernetes.conf #手动刷新,并让其立即生效
报错1:显示没有 /proc/sys/net/bridge/bridge-nf-call-iptables
modprobe br_netfilter
报错2:显示没有 /proc/sys/net/ipv4/tcp_tw_recycle:
从4.10内核开始,官方修改了时间戳的生成机制,没有tcp_tw_recycle,只有tcp_tw_refuse,因此,需要删掉该行
报错3:显示没有 /proc/sys/net/netfilter/nf_conntrack:
3.0版本中是没有这个的,需要升级到4.0以后才会有这个文,或者如下指定
modprobe ip_netfilter
8.调整系统时区
时间要同步,否则k8s无法完成相应的操作
#设置系统时区为中国/上海 timedatectl set-timezone Asia/Shanghai #将当前的UTC时间写入硬件时钟 timedatectl set-local-rtc 0 #重启依赖于系统时间的服务 systemctl restart rsyslog systemctl restart crond
9.关闭不需要的服务
讯享网关闭邮箱服务,没啥用的服务。 systemctl stop postfix && systemctl disable postfix
报错没有load此服务:尝试systemctl disable postfix,若还是没有,那就是此版本中没有这个服务
10.设置rsyslogd和systemd journald
设置日志的保存方式
mkdir /var/log/journal #持久化保存日志的目录 mkdir /etc/systemd/journald.conf.d
讯享网cat > /etc/systemd/journald.conf.d/99-prophet.conf <<EOF [Journal] #持久化保存到磁盘 Storage=persistent #压缩历史日志 Compress=yes SyncIntervalSec=5m RateLimitInterval=30s RateLimitBurst=1000 #最大占用空间10G SystemMaxUse=10G #单日志文件最大200M SystemMaxFileSize=200M #日志保存时间2周 MaxRetentionSec=2week #不将日志转发到syslog ForwardToSyslog=no EOF
重启journald服务:
systemctl restart systemd-journald
推荐就是用journald来保存日志,后续也可通过此命令查找一些bug。
至此,初始化即完成了。以上步骤全部节点都需要操作。下面进行k8s的部署安装。
kubeam和kube-vip部署安装
kubeam是官方推荐的安装方式,比较简洁快速,所以我们也用这个。下面进行相关的配置。
1.Kube-proxy开启ipvs的前置条件
常用的有iptables和ipvs 2种调度方式。ipvs实现了传输层负载均衡,也就是我们常说的4层LAN交换,会增加service调度pod的效率,需要进行配置,否则就会自动变回ipables的模式。
讯享网modprobe br_netfilter #加载netfilter模块 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 #modprobe -- nf_conntrack_ipv4 EOF
上述文件会引导一些相关依赖的加载
chmod 755 /etc/sysconfig/modules/ipvs.modules #赋予这些文件755权限 /etc/sysconfig/modules/ipvs.modules #启动这些模块 lsmod | grep -e ip_vs -e nf_contrack_ipv4 #查看这些模块是否被成功引导和加载
错误1:modprobe: FATAL: Module nf_conntrack_ipv4 not found in directory /lib/modules/…
原因分析:
linux kernel 4.19版本已经将nf_conntrack_ipv4 更新为 nf_conntrack, 而 kube-proxy 1.13 以下版本,强依赖 nf_conntrack_ipv4。
解决方式:
1、降级内核到 4.18
2、升级kube-proxy到 1.13+ (推荐,无需重启机器,影响小)
我们这里新版已经ok了所以就不用加载也没事。
2.安装containerd
需要在各个节点上全部安装此组件。由于需要调用runc,所以需要先安装runc。github有多个版本,cri版本,集成了相关依赖,故用这个安装。
讯享网wget https://github.com/containerd/containerd/releases/download/v1.5.7/cri-containerd-cni-1.5.7-linux-amd64.tar.gz
将压缩包解压到系统的各个目录中:
tar -C / -xzf cri-containerd-cni-1.5.7-linux-amd64.tar.gz
然后将/usr/local/bin和/usr/local/sbin追加到~/.bashrc文件的PATH环境变量中。
讯享网export PATH=$PATH:/usr/local/bin:/usr/local/sbin
执行下面的命令使其生效:
source ~/.bashrc
containerd的默认配置文件为/etc/containerd/config.toml,我们需要生成一个默认的配置:
讯享网mkdir -p /etc/containerd containerd config default>/etc/containerd/config.toml
对于使用systemd作为init system的Linux发行版,使用systemd作为容器的cgroup driver可以确保节点在资源紧张情况下更稳定。推荐将containerd的cgroup driver配置为systemd(跟docker类似)
设置systemdCgroup为true

也可以根据需要修改mirrors地址
由于我们下载的安装包里面有一个/etc/systemd/system/containerd.service服务,所以重载并设置开机启动即可。
systemctl daemon-reload systemctl enable containerd --now
配置完成后,可以用ctr version和crictr 查看安装的版本信息。

负载均衡安装设置(kube-vip)
kube-vip通过静态pod运行在控制节点(master)上。可以选择,ARP和BGP来设置。ARP模式,会选举leader,继承VIP的虚拟ip,而在BGP模式下,所有节点都会通知vip地址。
这里使用ARP模式。(BGP更优,最新版本推出的功能,避免ARP广播拥堵和拦截,不过BGP需要上层有3层交换机,以此来实现定向广播)
获取 kube-vip 的 docker 镜像,并在 /etc/kuberentes/manifests 中设置静态 pod 的 yaml 资源清单文件,这样 Kubernetes 就会自动在每个控制平面节点上部署 kube-vip 的 pod 了。
3.设置VIP地址(仅在master01上部署先)
讯享网mkdir -p /etc/kubernetes/manifests/ export VIP=192.168.66.10 export INTERFACE=ens33 ctr image pull ghcr.io/kube-vip/kube-vip:v0.3.8 ctr run --rm --net-host ghcr.io/kube-vip/kube-vip:v0.3.8 vip \ /kube-vip manifest pod \ --interface $INTERFACE \ --vip $VIP \ --controlplane \ --services \ --arp \ --leaderElection | tee /etc/kubernetes/manifests/kube-vip.yaml
注:
VIP地址根据规划而设置,需要更后面k8s initd配置文件的一致
INTERFACE:要用虚拟机里面的网卡名字,否则很尴尬,后面vip pod就起不来。
其他master先不要部署,否则join时候会提示k8s目录存在。
报错:ctr: failed to create shim: OCI runtime create failed: unable to retrieve OCI runtime error (open /run/containerd/io.containerd.runtime.v2.task/default/…/log.json: no such file or directory): runc did not terminate successfully
解决:containerd版本比较高,而libseccomp版本太低(最新是2.5.2,yum默认安装是2.3)
wget https://github.com/seccomp/libseccomp/releases/download/v2.5.2/libseccomp-2.5.2.tar.gz tar -zxvf libseccomp-2.5.2.tar.gz cd libseccomp-2.5.2 ./configure --prefix=/usr --disable-static make && make install yum -y install libseccomp libseccomp-dev
4.安装kubeadm相关组件(6台都需要安装)
让kubeadm去引导成为k8s,添加repo源,这里使用的是阿里源
讯享网cat <<EOF >/etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64 enabled=1 gpgcheck=0 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
然后安装
yum -y install kubeadm kubectl kubelet --disableexcludes=kubernetes kubeadm version
–disableexcludes 禁掉除了kubernetes之外的别的仓库
kubelet是与容器接口进行交互,而k8s通过kubeadm安装以后都是以Pod方式存在,底层是以容器的方式运行。所以一定要开机自启,不然的话启动不了k8s集群。
这里默认的一下子变成1.22.3了,怕改动过大查看官方文档,发现还没,尴尬,生产环境中建议指定版本安装,避免因为版本不一致出现问题(很可能出现)
讯享网systemctl enable kubelet.service
5.集群初始化(仅在master01上运行即可,其余join):
生成一个默认的yaml配置文档,然后进行修改!
kubeadm config print init-defaults --component-configs KubeletConfiguration > kubeadm.yaml vim kubeadm.yaml
讯享网apiVersion: kubeadm.k8s.io/v1beta3 bootstrapTokens: - groups: - system:bootstrappers:kubeadm:default-node-token token: abcdef.0abcdef ttl: 24h0m0s usages: - signing - authentication kind: InitConfiguration localAPIEndpoint: advertiseAddress: 192.168.66.11 #当前master的ip bindPort: 6443 nodeRegistration: criSocket: /run/containerd/containerd.sock #默认是docker,改为cocntainerd imagePullPolicy: IfNotPresent name: k8s-master01 #名字改成hostname一致 taints: # 给master添加污点,master节点不能调度应用 - effect: "NoSchedule" key: "node-role.kubernetes.io/master" --- apiVersion: kubeproxy.config.k8s.io/v1alpha1 kind: KubeProxyConfiguration mode: ipvs # kube-proxy 模式指定为IPVS --- apiServer: extraArgs: authorization-mode: Node,RBAC timeoutForControlPlane: 4m0s certSANs: # 添加其他master节点的相关信息 - api.k8s.local - k8s-master01 - k8s-master02 - k8s-master03 - 192.168.66.11 - 192.168.66.12 - 192.168.66.13 apiVersion: kubeadm.k8s.io/v1beta3 certificatesDir: /etc/kubernetes/pki clusterName: kubernetes controllerManager: {
} dns: {
} etcd: local: dataDir: /var/lib/etcd imageRepository: k8s.gcr.io kind: ClusterConfiguration kubernetesVersion: 1.22.0 controlPlaneEndpoint: api.k8s.local:6443 # 设置控制平面Endpoint地址 networking: dnsDomain: cluster.local serviceSubnet: 10.96.0.0/12 podSubnet: 10.244.0.0/16 # 指定 pod 子网,因为后续是用flannel插件,若是其他的这里也需要同步修改。 scheduler: {
} --- apiVersion: kubelet.config.k8s.io/v1beta1 authentication: anonymous: enabled: false webhook: cacheTTL: 0s enabled: true x509: clientCAFile: /etc/kubernetes/pki/ca.crt authorization: mode: Webhook webhook: cacheAuthorizedTTL: 0s cacheUnauthorizedTTL: 0s cgroupDriver: systemd #已经是默认了就不用改了 clusterDNS: - 10.96.0.10 clusterDomain: cluster.local cpuManagerReconcilePeriod: 0s evictionPressureTransitionPeriod: 0s fileCheckFrequency: 0s healthzBindAddress: 127.0.0.1 healthzPort: 10248 httpCheckFrequency: 0s imageMinimumGCAge: 0s kind: KubeletConfiguration logging: {
} memorySwap: {
} nodeStatusReportFrequency: 0s nodeStatusUpdateFrequency: 0s rotateCertificates: true runtimeRequestTimeout: 0s shutdownGracePeriod: 0s shutdownGracePeriodCriticalPods: 0s staticPodPath: /etc/kubernetes/manifests streamingConnectionIdleTimeout: 0s syncFrequency: 0s volumeStatsAggPeriod: 0s
注:若版本相近,建议直接复制粘贴,否则很容易出错!!!!!!
修改完成后,拉取镜像,避免后续master节点创建和join时候很慢.
kubeadm config images pull --config kubeadm.yaml #master01开始初始化 kubeadm init --upload-certs --config kubeadm.yaml
如果成功了,就会出现很多的行,然后会出现join的命令
#根据提示创建文件及目录
#目的为保存 kubectl 与 api server 交互时的缓存,交互过程为https协议
讯享网mkdir -p $HOME/.kube cp -i /etc/kubernetes/admin.conf $HOME/.kube/config chown $(id -u):$(id -g) $HOME/.kube/config
注:所有master创建或加入后都需要执行创建这些目录的过程。因为大家其实都是一样一样的!
6.其他master和node节点加入
在master01初始化集群后,会产生2条join的指令。
上面带有control-plane的是master加入命令,如下图

master其他节点加入成功后,
mkdir -p $HOME/.kube cp -i /etc/kubernetes/admin.conf $HOME/.kube/config chown $(id -u):$(id -g) $HOME/.kube/config
然后是node节点的加入。加入完成后,在任一maste节点都能看到相关信息。
kubectl get node可以看到,master都处于notReady状态。那是其他两个master还未成功启动kube-vip的静态pod并且缺少网络插件。

PS:正常配置完成后,都是notready状态。
7.先将另外2台maser也生成kube-vip文件。
讯享网export VIP=192.168.66.10 export INTERFACE=ens33 ctr image pull ghcr.io/kube-vip/kube-vip:v0.3.8 ctr run --rm --net-host ghcr.io/kube-vip/kube-vip:v0.3.8 vip \ /kube-vip manifest pod \ --interface $INTERFACE \ --vip $VIP \ --controlplane \ --services \ --arp \ --leaderElection | tee /etc/kubernetes/manifests/kube-vip.yaml
8.再来安装网络插件
目前主流有2种可以解决,flannel和calico(新版推荐使用这个,不过由于之前我们在默认文件里面是10.244.0.0的flannel网络。故此次先用这个)。相比于flannel,calico转发效率更高,且消耗极小的cpu资源。
安装flannel(任一master节点操作即可)
Flannel是centos专门为kubenetes设计的一个网络规划服务。Flannel的设计目的就是为集群中的所有节点重新规划IP地址的使用规则,从而使得不同节点上的容器能够获得“同属一个内网”且”不重复的”IP地址,并让属于不同节点上的容器能够直接通过内网IP通信。
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml kubectl apply -f kube-flannel.yml
安装完成后,可以看到所有master和node节点都变成ready状态了。

再查看coredns,之前一直也是pending状态,现在也是running了。

至此,我们的高可用kube-vip集群就搭建完成了。
kube-vip的BGP模式,效率更优(无需全部ARP广播),calico在大型网络里面也效率更优,建议大型网络和集群用这2种插件。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/29931.html