02. Kubernetes - 集群初始化
集群准备
生产中理想的集群规划:
但是由于资源有限,只有 6 台 CentOS 7.9 的虚拟机,所以将 K8S Master,Nginx + Keepalived,CoreDNS 三个集群进行了整合,CoreDNS 会在后面的章节单独进行安装。
具体规划如下:
主机 | IP | 系统 | 配置 | 初始化安装服务 |
---|---|---|---|---|
master-01 | 192.168.200.101 | CentOS 7.9 | 4C/4G/20G | docker,containerd,nginx,keepalived |
master-02 | 192.168.200.102 | CentOS 7.9 | 4C/4G/20G | docker,containerd,nginx,keepalived |
master-03 | 192.168.200.103 | CentOS 7.9 | 4C/4G/20G | docker,containerd,nginx,keepalived |
worker-01 | 192.168.200.104 | CentOS 7.9 | 4C/4G/20G | docker,containerd |
worker-02 | 192.168.200.105 | CentOS 7.9 | 4C/4G/20G | docker,containerd |
worker-03 | 192.168.200.106 | CentOS 7.9 | 4C/4G/20G | docker,containerd |
SLB VIP | 192.168.200.100 | / | / | keepalived 提供 |
安装容器运行时所需安装包信息:
安装包 | 版本号 | 说明 | 下载地址 |
---|---|---|---|
docker-ce | 20.10.18 | docker 引擎 | 点击下载 |
docker-ce-cli | 20.10.18 | docker 引擎的命令行 | 点击下载 |
docker-ce-rootless-extras | 20.10.18 | docker-ce 需要的依赖 | 点击下载 |
docker-scan-plugin | 0.17.0 | docker-ce-cli 需要的依赖 | 点击下载 |
containerd.io | 1.6.8 | 守护进程,独立于 docker 工作,管理容器的生命周期 | 点击下载 |
内核升级所需安装包信息:
安装包 | 版本号 | 说明 | 下载地址 |
---|---|---|---|
kernel-ml | 5.11.16 | Linux 内核 | 点击下载 |
kernel-ml-devel | 5.11.16 | Linux 内核 | 点击下载 |
Nginx + Keepalive 配置负载均衡高可用所需安装包信息:
安装包 | 版本号 | 说明 | 下载地址 |
---|---|---|---|
nginx | 1.23.0 | 负载均衡,反向代理,TCP 代理 | 点击下载 |
openssl | 1.1.1q | 依赖 | 点击下载 |
pcre | 8.45 | 依赖 | 点击下载 |
zlib | 1.2.12 | 依赖 | 点击下载 |
echo-nginx-module | master | 调试模块 | 点击下载 |
ngx-fancyindex | master | 下载美化模块 | 点击下载 |
ngx_healthcheck_module | master | 健康检查模块 | 点击下载 |
ngx_http_proxy_connect_module | master | 代理模块 | 点击下载 |
ngx_http_status_code_counter | master | 状态统计模块 | 点击下载 |
keepalived | 2.27 | 提供 VIP | 点击下载 |
关闭防火墙 / Selinux / Swap
为了避免额外的干扰,需要关闭防火墙,对于公有云,内网端口一般全开放,外网端口通过安全组控制:
# 关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
# 关闭 Selinux
sed -i "s#^SELINUX=.*#SELINUX=disabled#g" /etc/selinux/config
setenforce 0
# 关闭 swap 分区,Swap 会影响性能
swapoff -a && sysctl -w vm.swappiness=0
sed -ri '/^[^#]*swap/s@^@#@' /etc/fstab
# 主机名解析
echo "127.0.0.1 $(hostname)" >> /etc/hosts
YUM 源配置(云服务器不需要)
本地或者自建服务器都需要配置 YUM 源,如果是云服务器由于本身就有对应云的 YUM 源,不需要配置:
# 备份旧的 yum 源
cd /etc/yum.repos.d/
mkdir backup-$(date +%F)
mv *repo backup-$(date +%F)
# 添加阿里云 yum 源
curl http://mirrors.aliyun.com/repo/Centos-7.repo -o ali.repo
基础依赖安装
由于服务器最小化安装,需要安装一些常用的依赖和工具,否则后面安装可能会报错:
# 安装 epel 源
yum -y install epel-release
yum clean all
yum makecache
# 安装常用依赖
yum -y install gcc glibc gcc-c++ make cmake net-tools screen vim lrzsz tree dos2unix lsof \
tcpdump bash-completion wget ntp setuptool openssl openssl-devel bind-utils traceroute \
bash-completion bash-completion-extras glib2 glib2-devel unzip bzip2 bzip2-devel libevent libevent-devel \
ntp expect pcre pcre-devel zlib zlib-devel jq psmisc tcping yum-utils device-mapper-persistent-data \
lvm2 git device-mapper-persistent-data bridge-utils container-selinux binutils-devel \
ncurses ncurses-devel elfutils-libelf-devel ack
# 升级服务器
yum -y update
配置时间同步(云服务器不需要)
本地或者自建服务器都需要配置时间同步,如果是云服务器由于本身就有对应云的时间同步机制,不需要配置
echo "# 互联网时间同步" >> /var/spool/cron/root
echo "*/5 * * * * /usr/sbin/ntpdate time2.aliyun.com >/dev/null 2>&1" >> /var/spool/cron/root
系统优化
对系统打开文件数进行修改,提升性能:
cat >> /etc/security/limits.conf << EOF
# 打开文件优化配置
* soft nofile 655360
* hard nofile 655350
* soft nproc 655350
* hard nproc 655350
* soft memlock unlimited
* hard memlock unlimited
EOF
Master 节点互相免密
在三台 Master 节点执行以下操作:
ssh-keygen -t rsa
然后执行:
cd ~
# 定义 master 列表
MASTER_LIST=(
192.168.200.101
192.168.200.102
192.168.200.103
)
# 配置免密登录
for i in ${MASTER_LIST[@]};do
ssh-copy-id -i .ssh/id_rsa.pub root@$i
done
内核升级
在 Kubernetes 的 Github 仓库中:
https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.25.md
有提到关于内核版本的问题:
Faster mount detection for linux kernel 5.10+ using openat2 speeding up pod churn rates. On Kernel versions less 5.10, it will fallback to using the original way of detecting mount points i.e by parsing /proc/mounts.
这意味着内核 5.10 版本以后会使用 openat2 进行更快的挂载检测,所有可以将内核升级到 5.10 以后,但没必要最新。
这里使用的是 5.11.16
版本,更新于 2021 年 4 月。如果想安装其它版本可以去下面网站下载:
- 创建用于存放安装包的目录:
mkdir -p /ezops/packages
-
将下载好的内核安装包上传到所有机器的
/ezops/packages
目录:
- 执行安装:
cd /ezops/packages
yum localinstall -y kernel-ml*
# 设置内核启动顺序
grub2-set-default 0 && grub2-mkconfig -o /etc/grub2.cfg
# 查看默认内核
grubby --default-kernel
安装 ipvsadm
节点通信需要用到 LVS,所有需要安装 ipvsadm。
- 安装 ipvsadm:
yum -y install ipvsadm ipset sysstat conntrack libseccomp
- 配置 ipvs 模块(内核 4.19 版本以前使用
nf_conntrack_ipv4
,以后使用nf_conntrack
):
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack
cat > /etc/modules-load.d/ipvs.conf << EOF
ip_vs
ip_vs_lc
ip_vs_wlc
ip_vs_rr
ip_vs_wrr
ip_vs_lblc
ip_vs_lblcr
ip_vs_dh
ip_vs_sh
ip_vs_fo
ip_vs_nq
ip_vs_sed
ip_vs_ftp
ip_vs_sh
nf_conntrack
ip_tables
ip_set
xt_set
ipt_set
ipt_rpfilter
ipt_REJECT
ipip
EOF
systemctl enable --now systemd-modules-load
内核调优
添加内核调优参数,某些参数对 Kubernetes 集群很重要:
cat >> /etc/sysctl.d/user.conf << EOF
# 内核调优
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
fs.may_detach_mounts = 1
vm.overcommit_memory=1
vm.panic_on_oom=0
fs.inotify.max_user_watches=89100
fs.file-max=52706963
fs.nr_open=52706963
net.netfilter.nf_conntrack_max=2310720
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_intvl =15
net.ipv4.tcp_max_tw_buckets = 36000
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_max_orphans = 327680
net.ipv4.tcp_orphan_retries = 3
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.ip_conntrack_max = 65536
net.ipv4.tcp_timestamps = 0
net.core.somaxconn = 16384
EOF
完成后就可以重启服务器:
reboot
重启完成查看 ipvs 的配置效果:
lsmod | grep --color=auto -e ip_vs -e nf_conntrack
容器运行时安装
由于 Kubernetes 1.24 版本之后移除了 dockershim,所有无法直接使用 docker 作为容器运行时。但还是需要安装 docker,使用 containerd 作为容器运行时。
-
将下载好的 docker 相关安装包上传到
/ezops/packages
目录:
- 执行安装操作:
cd /ezops/packages
yum -y localinstall docker* containerd*
- 配置 containerd 模块:
# 配置模块
cat > /etc/modules-load.d/containerd.conf << EOF
overlay
br_netfilter
EOF
# 加载模块
modprobe -- overlay
modprobe -- br_netfilter
- 配置 containerd 配置文件:
# 生成默认配置
mkdir -p /etc/containerd
containerd config default | tee /etc/containerd/config.toml
# 将 Cgroup 改为 Systemd
sed -i "s#SystemdCgroup = false#SystemdCgroup = true#g" /etc/containerd/config.toml
# 检查配置
grep "SystemdCgroup" /etc/containerd/config.toml
低版本可能没有 SystemdCgroup 配置,可以 vim 搜索 containerd.runtimes.runc.options
关键字,然后在下面添加一项:
SystemdCgroup = true
- 修改
sandbox_image
的Pause
镜像地址,原因是国内没法访问到:
sed -i "s#k8s.gcr.io/pause:3.6#registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.6#g" /etc/containerd/config.toml
- 添加开机启动 containerd:
systemctl daemon-reload
systemctl enable --now containerd
- 配置 crictl 客户端连接的运行时位置:
cat > /etc/crictl.yaml << EOF
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false
EOF
Nginx 集群安装
由于集群需要实现高可用功能,所以需要一个统一的 IP 作为入口。
对于本地环境,推荐的方案就是 Nginx + Keepalived
的方式提供 VIP
实现负载均衡反向代理高可用。网上有部分文章提到使用 Haproxy,个人不是很推荐,出问题排查没有 Nginx 容易。
但是对于云服务器而言,大部分是不支持 Keepalived 的,此时就需要用到公有云自带的负载均衡 SLB,如阿里云的 SLB,CLB,ALB,腾讯云的 ELB 等等。这些服务都有较强的稳定性。
但如果选择阿里云,则需要注意以下问题:
-
阿里云不能使用 VIP,要用 VIP 只能走 SLB。同时 SLB 内外网都需要收费。
-
阿里云 SLB 不支持手动指定 IP 地址,在生成相关证书时需要注意。
-
反代 HTTPS 的 API Server 只能用 SLB 的四层反代。
-
SLB 四层 TCP 反代不能直接反代到服务提供者上 API Server 上。因为 API Server 也会有请求访问 SLB,这样最终请求可能转发到本机,这在阿里云是不被允许的,会导致请求超时或者报错。只能先代理到另一个 ECS 上通过类似 Nginx 之类的再代理到 API Server。即 SLB(TCP)--> Nginx(TCP)--> API Server(HTTPS),注意 Nginx 和 API Server 不能是同一个机器。
在生产环境资源充足的情况下,建议按照理想集群的规划部署到单独的服务器上。
- 将下载的 Nginx 相关安装包上传到
/ezops/packages
目录:
- 依赖安装:
yum -y install zip unzip gcc gcc-c++ automake autoconf libtool make glibc gd-devel pcre-devel libmcrypt-devel mhash-devel libxslt-devel libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel libxml2 libxml2-devel zlib zlib-devel glibc glibc-devel glib2 glib2-devel bzip2 bzip2-devel ncurses ncurses-devel curl curl-devel e2fsprogs e2fsprogs-devel krb5 krb5-devel libidn libidn-devel openssl openssl-devel libevent libevent-devel GeoIP GeoIP-devel GeoIP-data httpd-tools patch
- 安装包解压:
cd /ezops/packages
tar -zxf nginx-1.23.0.tar.gz
tar -zxf openssl-1.1.1q.tar.gz
tar -zxf pcre-8.45.tar.gz
tar -zxf zlib-1.2.12.tar.gz
unzip echo-nginx-module-master.zip
unzip ngx_healthcheck_module-master.zip
unzip ngx-fancyindex-master.zip
unzip ngx_http_proxy_connect_module-master.zip
unzip ngx_http_status_code_counter-master.zip
- 优化和打补丁:
cd nginx-1.23.0/
# 打补丁
patch -p1 < ../ngx_healthcheck_module-master/nginx_healthcheck_for_nginx_1.19+.patch
patch -p1 < ../ngx_http_proxy_connect_module-master/patch/proxy_connect_rewrite_102101.patch
# 安全优化,隐藏版本号
sed -i 's#"1.23.0"#"2.2"#g' src/core/nginx.h
sed -i 's#"nginx/"#"apache/"#g' src/core/nginx.h
sed -i 's#"NGINX"#"APACHE"#g' src/core/nginx.h
sed -i 's#"Server: nginx"#"Server: apache"#g' src/http/ngx_http_header_filter_module.c
sed -i '/"<hr><center>" NGINX_VER "<\/center>" CRLF/d' src/http/ngx_http_special_response.c
sed -i '/"<hr><center>" NGINX_VER_BUILD "<\/center>" CRLF/d' src/http/ngx_http_special_response.c
sed -i '/"<hr><center>nginx<\/center>" CRLF/d' src/http/ngx_http_special_response.c
- 编译安装:
# 编译
./configure --prefix=/ezops/service/nginx \
--user=root \
--group=root \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--with-http_secure_link_module \
--with-http_flv_module \
--with-http_ssl_module \
--with-http_mp4_module \
--with-stream \
--with-http_realip_module \
--with-http_geoip_module \
--with-http_v2_module \
--with-http_sub_module \
--with-http_image_filter_module \
--with-pcre=/ezops/packages/pcre-8.45 \
--with-openssl=/ezops/packages/openssl-1.1.1q \
--with-zlib=/ezops/packages/zlib-1.2.12 \
--add-module=/ezops/packages/echo-nginx-module-master \
--add-module=/ezops/packages/ngx_healthcheck_module-master \
--add-module=/ezops/packages/ngx_http_proxy_connect_module-master \
--add-module=/ezops/packages/ngx_http_status_code_counter-master \
--add-module=/ezops/packages/ngx-fancyindex-master
# 安装
make && make install
- 配置主配置文件:
cat > /ezops/service/nginx/conf/nginx.conf << EOF
# Worker运行用户
user root;
# Worker线程数量,一般等于CPU数
worker_processes auto;
# 默认错误日志文件
error_log logs/error.log;
# 默认PID文件位置
pid logs/nginx.pid;
# Worker打开文件数,影响并发,系统 limit 也会影响
worker_rlimit_nofile 65535;
# 最大并发数:worker_processes * worker_connections,反向代理除以 4
events {
use epoll;
worker_connections 65535;
}
# HTTP服务配置字段
http {
# 允许的文件类型和默认的打开方式
include mime.types;
default_type application/octet-stream;
# 默认的 access 日志输出格式
log_format main '\$remote_addr \$remote_user [\$time_local] "\$request" '
'\$status \$body_bytes_sent "\$http_referer" '
'\$http_user_agent \$http_x_forwarded_for \$request_time \$upstream_response_time \$upstream_addr \$upstream_status';
# 默认access日志输出位置
access_log logs/access.log main;
# 配置多个域名的时候需要增大该值
server_names_hash_bucket_size 128;
variables_hash_max_size 4096;
variables_hash_bucket_size 2048;
# 这两个值限制header buffer 大小,超出大小报错414(处理request_line)/400(处理request_header)
client_header_buffer_size 32k;
large_client_header_buffers 4 32k;
# 上传文件大小限制
client_max_body_size 30m;
# Fastcgi优化配置
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
fastcgi_param HTTP_PROXY "";
# 隐藏后端服务器的相关参数
proxy_hide_header X-Powered-By;
proxy_hide_header X-Forwarded-For;
proxy_hide_header X-AspNet-Version;
proxy_hide_header X-AspNetMvc-Version;
proxy_hide_header Via;
proxy_hide_header X-Varnish;
proxy_hide_header Server;
# 后端服务器连接的超时时间
proxy_connect_timeout 30s;
# 连接成功后,等候后端服务器响应时间
proxy_read_timeout 30s;
# 后端服务器数据回传时间
proxy_send_timeout 30s;
# 开启压缩
gzip on;
# 静态资源压缩
gzip_static on;
# 客户端IE不压缩
gzip_disable "MSIE [1-6] .";
# 响应头部标识
gzip_vary on;
# 最小压缩文件大小
gzip_min_length 1k;
# 缓冲区个数和大小
gzip_buffers 4 16k;
# 压缩等级,越高压缩比越高,但是越吃CPU
gzip_comp_level 5;
# 压缩的文件类型
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png application/vnd.ms-fontobject font/ttf font/opentype font/x-woff image/svg+xml;
# 针对压缩的协议版本
gzip_http_version 1.1;
# 虚拟主机配置目录
include vhosts/*.conf;
# 防止恶意解析
server {
listen 80 default_server;
server_name _;
access_log off;
return 444;
}
}
# TCP/UDP代理配置段
stream {
# TCP/UDP虚拟主机配置目录
include tcp/*.conf;
}
EOF
- 创建目录:
mkdir /ezops/service/nginx/conf/{tcp,vhosts,certs,template}
- 配置 API Server 的 TCP 代理(现在只是测试配置):
cat > /ezops/service/nginx/conf/tcp/k8s-apiserver.conf << EOF
# Kubernetes API Server TCP/UDP 代理
upstream K8S-APISERVER {
hash \$remote_addr consistent;
server 192.168.200.101:6443;
server 192.168.200.102:6443;
server 192.168.200.103:6443;
check interval=5000 rise=2 fall=3 timeout=5000 default_down=true type=tcp;
}
server {
listen 16443;
proxy_connect_timeout 30s;
proxy_timeout 300s;
proxy_pass K8S-APISERVER;
}
EOF
- 配置状态页面:
cat > /ezops/service/nginx/conf/vhosts/status.conf << EOF
server {
listen 2333;
server_name localhost;
access_log off;
# 请求状态统计
location = /nginx/status {
stub_status on;
}
# 状态码统计
location = /nginx/status/count {
show_status_code_count on;
}
# 负载均衡状态
location /nginx/upstream/status {
healthcheck_status;
}
location / {
return 403;
}
}
EOF
- 启动服务:
# 启动服务
/ezops/service/nginx/sbin/nginx -t
/ezops/service/nginx/sbin/nginx
# 添加开机启动
cat >> /etc/rc.local << EOF
# Nginx 开机启动
/ezops/service/nginx/sbin/nginx &
EOF
# 修改权限
chmod 755 /etc/rc.local
请求状态页面:
状态码统计页面:
Upstream 状态页面:
Keepalived 集群安装
Nginx 和 Keepalived 是配套使用的,如果有其他负载均衡器就不需要再安装这两个服务。
- 将下载的 Keeplived 相关安装包上传到
/ezops/packages
目录:
- 执行安装:
# 安装依赖
yum install -y ipvsadm popt popt-devel libnl libnl-devel libnl3-devel libnfnetlink libnfnetlink-devel net-snmp-devel openssl openssl-devel
# 下载安装包
cd /ezops/packages
tar -zxf keepalived-2.2.7.tar.gz
# 编译安装
cd keepalived-2.2.7/
./configure --prefix=/ezops/service/keepalived
make && make install
- master-01 配置 Keepalived(MASTER 节点):
cat > /ezops/service/keepalived/etc/keepalived/keepalived.conf << EOF
! Configuration File for keepalived
#全局配置
global_defs {
# 负载均衡标识,在局域网内应该是唯一的。一般为主机名。
router_id $(hostname)
script_user root
enable_script_security
}
vrrp_script check_nginx {
# 检测心跳执行的脚本
script "/ezops/service/keepalived/etc/keepalived/nginx_process_check.sh"
# 检测脚本执行间隔,单位:秒
interval 5
weight 2
}
#定义实例
vrrp_instance VI_1 {
# 指定keepalived的角色,MASTER为主,BACKUP为备
state MASTER
# 当前进行vrrp通讯的网络接口卡(当前centos的网卡)
interface ens33
# 指定VRRP实例ID(虚拟路由编号),范围是0-255,主从要一致
virtual_router_id 100
# 优先级,数值越大,获取处理请求的优先级越高, 优先级高的将成为MASTER。
priority 101
# 指定发送VRRP通告的间隔,默认为1s(vrrp组播周期秒数)
advert_int 1
# 设置验证类型和密码,MASTER和BACKUP必须使用相同的密码才能正常通信
authentication {
# 指定认证方式。PASS简单密码认证(推荐),AH:IPSEC认证(不推荐)。
auth_type PASS
# 指定认证所使用的密码。最多8位。
auth_pass k8spass
}
# 调用检测脚本
track_script {
check_nginx
}
# 定义虚拟ip(VIP),可多设,每行一个
virtual_ipaddress {
192.168.200.100
}
}
EOF
- master-02 / master-03 配置 Keepalived(BACKUP 节点):
cat > /ezops/service/keepalived/etc/keepalived/keepalived.conf << EOF
! Configuration File for keepalived
#全局配置
global_defs {
# 负载均衡标识,在局域网内应该是唯一的。一般为主机名。
router_id $(hostname)
script_user root
enable_script_security
}
vrrp_script check_nginx {
# 检测心跳执行的脚本
script "/ezops/service/keepalived/etc/keepalived/nginx_process_check.sh"
# 检测脚本执行间隔,单位:秒
interval 5
weight 2
}
#定义实例
vrrp_instance VI_1 {
# 指定keepalived的角色,MASTER为主,BACKUP为备
state BACKUP
# 当前进行vrrp通讯的网络接口卡(当前centos的网卡)
interface ens33
# 指定VRRP实例ID(虚拟路由编号),范围是0-255,主从要一致
virtual_router_id 100
# 优先级,数值越大,获取处理请求的优先级越高, 优先级高的将成为MASTER。
priority 100
# 指定发送VRRP通告的间隔,默认为1s(vrrp组播周期秒数)
advert_int 1
# 设置验证类型和密码,MASTER和BACKUP必须使用相同的密码才能正常通信
authentication {
# 指定认证方式。PASS简单密码认证(推荐),AH:IPSEC认证(不推荐)。
auth_type PASS
# 指定认证所使用的密码。最多8位。
auth_pass k8spass
}
# 调用检测脚本
track_script {
check_nginx
}
# 定义虚拟ip(VIP),可多设,每行一个
virtual_ipaddress {
192.168.200.100
}
}
EOF
- 添加启动文件:
cat > /etc/systemd/system/keepalived.service << EOF
[Unit]
Description=LVS and VRRP High Availability Monitor
After=network-online.target syslog.target
Wants=network-online.target
Documentation=man:keepalived(8)
Documentation=man:keepalived.conf(5)
Documentation=man:genhash(1)
Documentation=https://keepalived.org
[Service]
Type=forking
PIDFile=/run/keepalived.pid
KillMode=process
EnvironmentFile=-/ezops/service/keepalived/etc/sysconfig/keepalived
ExecStart=/ezops/service/keepalived/sbin/keepalived -f /ezops/service/keepalived/etc/keepalived/keepalived.conf \$KEEPALIVED_OPTIONS
ExecReload=/bin/kill -HUP \$MAINPID
[Install]
WantedBy=multi-user.target
EOF
- 配置检测脚本:
cat > /ezops/service/keepalived/etc/keepalived/nginx_process_check.sh << EOF
#!/bin/bash
# Nginx 进程检测脚本
echo "\$(date) 开始检测 Nginx 状态..." >> /tmp/keepalived.log
err=0
# 三次进程检测
for k in \$(seq 1 3);do
process_count=\$(ps -ef | grep "nginx: master process" | grep -v "grep" | wc -l)
if [[ \$process_count == 0 ]]; then
err=\$(expr \$err + 1)
sleep 1
continue
else
err=0
break
fi
done
# 判断检测结果
if [[ \$err != "0" ]];then
echo "\$(date) Nginx 进程检测异常,开始停止 Keepalived ..." >> /tmp/keepalived.log
/usr/bin/systemctl stop keepalived
exit 1
else
exit 0
fi
EOF
# 修改权限
chmod +x /ezops/service/keepalived/etc/keepalived/nginx_process_check.sh
有两个地方需要特别注意:
- 脚本中判断进程是否存活的关键字一定要跟脚本名称区分开,否则可能造成手动执行脚本没问题,但是 keepalived 一直不停止。
- keepalived 对该脚本的权限控制非常严格,权限不对会在日志中提示以下问题,并且不执行脚本:
Keepalived_vrrp[11241]: Unsafe permissions found for script 'xxx'.
Keepalived_vrrp[11241]: Disabling track script xxx due to insecure
详细信息可以查看官方 Github 仓库的说明:
- 启动服务:
systemctl daemon-reload
systemctl enable --now keepalived
此时在 master-01(MASTER 节点) 上面就会有 192.168.200.100
这个 VIP,可以通过停止该节点 nginx 看 IP 是否会转移。
到此,系统初始化和基础服务已经配置完成,如果是本地虚拟机的就可以做个快照保存现在的状态了,因为后面会使用不同方式安装 Kubernetes。