这里所有的操作命令需要在kubernetes集群内所有的主机上执行,是安装kubernetes集群环境所需要的基本设置。
安装相关依赖包
yum install -y epel-release conntrack ipvsadm \
ipset jq sysstat curl libseccomp ntpdate ntp wget telnet rsync nfs-utils
KubeKey 安装 Kubernetes 时安装一下依赖
yum install -y socat conntrack ebtables ipset nfs-utils
备注:这里的依赖包主要是为worker节点上kubelet,kube-proxy,docker,以及网络插件组件安装依赖的安装包,其他包为基本网络测试包,建议在集群内所以机器上执行,因为flanneld插件需要这些依赖包
关闭防火墙
在每台机器上关闭防火墙,清理防火墙规则,设置默认转发策略:
systemctl stop firewalld >>/dev/null 2>&1
systemctl disable firewalld >>/dev/null 2>&1
iptables -F && iptables -X && iptables -F -t nat && iptables -X -t nat
iptables -P FORWARD ACCEPT
关闭 swap 分区
如果开启了 swap 分区,则worker节点上的kubelet 组件会启动失败(可以通过将参数 --fail-swap-on 设置为 false 来忽略 swap on),故需要在每台机器上关闭 swap 分区。同时注释 /etc/fstab 中相应的条目,防止开机自动挂载 swap 分区:
swapoff -a >>/dev/null 2>&1
sed -i 's/.*swap.*/#&/' /etc/fstab
关闭 SELinux
关闭 SELinux,否则后续 K8S 挂载目录时可能报错 Permission denied:
setenforce 0 >>/dev/null 2>&1
sed -i "s/^SELINUX=enforcing/SELINUX=disabled/g" /etc/sysconfig/selinux >>/dev/null 2>&1
sed -i "s/^SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config >>/dev/null 2>&1
sed -i "s/^SELINUX=permissive/SELINUX=disabled/g" /etc/sysconfig/selinux >>/dev/null 2>&1
sed -i "s/^SELINUX=permissive/SELINUX=disabled/g" /etc/selinux/config >>/dev/null 2>&1
关闭 dnsmasq(可选)
linux 系统开启了 dnsmasq 后(如 GUI 环境),将系统 DNS Server 设置为 127.0.0.1,这会导致 docker 容器无法解析域名,需要关闭它:
systemctl stop dnsmasq
systemctl disable dnsmasq
网络和 DNS 要求
必须确保 /etc/resolv.conf
中的 DNS 配置可用,否则集群中的 DNS 可能会有问题。
加载内核模块
主要是kube-proxy组件需要使用到ip_vs内核模块转发pods应用,实现endpoints路由;
sudo modprobe br_netfilter
sudo modprobe ip_vs
sudo modprobe ip_conntrack
修改文件句柄限制
echo "* soft nofile 65536" >> /etc/security/limits.conf
echo "* hard nofile 65536" >> /etc/security/limits.conf
echo "* soft nproc 65536" >> /etc/security/limits.conf
echo "* hard nproc 65536" >> /etc/security/limits.conf
echo "* soft memlock unlimited" >> /etc/security/limits.conf
echo "* hard memlock unlimited" >> /etc/security/limits.conf
优化内核参数
sudo sed -i '/net.ipv4.ip_forward/d' /etc/sysctl.conf
sudo sed -i '/net.bridge.bridge-nf-call-iptables/d' /etc/sysctl.conf
sudo sed -i '/net.bridge.bridge-nf-call-ip6tables/d' /etc/sysctl.conf
sudo sed -i '/net.ipv4.ip_forward/d' /etc/sysctl.conf
sudo sed -i '/net.ipv4.tcp_tw_recycle/d' /etc/sysctl.conf
sudo sed -i '/vm.swappiness/d' /etc/sysctl.conf
sudo sed -i '/vm.overcommit_memory/d' /etc/sysctl.conf
sudo sed -i '/vm.panic_on_oom/d' /etc/sysctl.conf
sudo sed -i '/fs.inotify.max_user_watches/d' /etc/sysctl.conf
sudo sed -i '/fs.file-max/d' /etc/sysctl.conf
sudo sed -i '/fs.nr_open/d' /etc/sysctl.conf
sudo sed -i '/net.ipv6.conf.all.disable_ipv6/d' /etc/sysctl.conf
sudo sed -i '/net.netfilter.nf_conntrack_max/d' /etc/sysctl.conf
cat >/etc/sysctl.d/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
vm.overcommit_memory=1
vm.panic_on_oom=0
fs.inotify.max_user_watches=89100
fs.file-max=52706963
fs.nr_open=52706963
net.ipv6.conf.all.disable_ipv6=1
net.netfilter.nf_conntrack_max=2310720
EOF
sysctl -p /etc/sysctl.d/kubernetes.conf >>/dev/null 2>&1
sed操作主要是为了防止sysctl.conf配置与新增的内核参数冲突;
必须关闭 tcp_tw_recycle,否则和 NAT 冲突,会导致服务不通;
关闭 IPV6,防止触发 docker BUG;
设置系统时区
# 调整系统 TimeZone
timedatectl set-timezone Asia/Shanghai
# 将当前的 UTC 时间写入硬件时钟
timedatectl set-local-rtc 0
hwclock -w
# 更新服务时间
ntpdate ntp1.aliyun.com
# 重启依赖于系统时间的服务
systemctl restart rsyslog
systemctl restart crond
关闭无关的服务
systemctl stop postfix && systemctl disable postfix
设置 rsyslogd 和 systemd journald(可选)
systemd 的 journald 是 Centos 7 缺省的日志记录工具,它记录了所有系统、内核、Service Unit 的日志。相比 systemd,journald 记录的日志有如下优势:
可以记录到内存或文件系统;(默认记录到内存,对应的位置为 /run/log/jounal);
可以限制占用的磁盘空间、保证磁盘剩余空间;
可以限制日志文件大小、保存的时间;
journald 默认将日志转发给 rsyslog,这会导致日志写了多份,/var/log/messages 中包含了太多无关日志,不方便后续查看,同时也影响系统性能。
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
systemctl restart systemd-journald
升级内核
CentOS 7.x 系统自带的 3.10.x 内核存在一些 Bugs,导致运行的 Docker、Kubernetes 不稳定,例如:
高版本的 docker(1.13 以后) 启用了 3.10 kernel 实验支持的 kernel memory account 功能(无法关闭),当节点压力大如频繁启动和停止容器时会导致 cgroup memory leak;
网络设备引用计数泄漏,会导致类似于报错:“kernel:unregister_netdevice: waiting for eth0 to become free. Usage count = 1”;
解决方案如下:
升级内核到 4.4.X 以上;
手动编译内核,disable CONFIG_MEMCG_KMEM 特性;
安装修复了该问题的 Docker 18.09.1 及以上的版本。但由于 kubelet 也会设置 kmem(它 vendor 了 runc),所以需要重新编译 kubelet 并指定 GOFLAGS=“-tags=nokmem”;
CentOS7.X 系统内核升级 :https://jwangkun.github.io/JqFGb7It7/
关闭 NUMA
sudo sed -i "s:numa=off::" /etc/sysconfig/grub
sudo sed -i "s:centos/swap rhgb:& numa=off:" /etc/sysconfig/grub
sudo grub2-mkconfig -o /boot/grub2/grub.cfg >>/dev/null 2>&1
控制机上安装ansible工具
由于所有操作都在devops机器上操作,为对所有机器进行命令操作,所有需要使用到ansible工具,将上述所有的命令根据服务器角色进行批量命令操作。
yum install ansible -y
安装Docker
wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
yum -y install docker-ce-20.10.10
systemctl enable docker && systemctl start docker
docker --version
添加阿里云YUM软件源
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
EOF
导入gpgkey文件
wget https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
rpm --import yum-key.gpg
wget https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
rpm --import rpm-package-key.gpg
修改docker 默认路径
默认情况下Docker的存放位置为:/var/lib/docker
可以通过下面命令查看具体位置:
docker info | grep "Docker Root Dir"
首先停掉Docker服务:
systemctl stop docker
然后根据上面查到的路径,移动整个/var/lib/docker目录到数据盘的目的路径:
mv /var/lib/docker /home/docker
必须使用mv命令,cp会丢失权限信息,可能会导致意想不到的bug。
加入软连接
ln -s /home/docker /var/lib/docker
先看下/home/docker下的目录,确定挂载成功在启动docker,即使挂载有问题,无碍,也可停止停止docker后重新操作
启动docker
systemctl start docker
systemctl enable docker