kube-apiserver高可用架构图:
7.3 部署Nginx负载均衡器 - 图1

  • Nginx是一个主流Web服务和反向代理服务器,这里用四层实现对apiserver实现负载均衡。
  • Keepalived是一个主流高可用软件,基于VIP绑定实现服务器双机热备,在上述拓扑中,Keepalived主要根据Nginx运行状态判断是否需要故障转移(偏移VIP),例如当Nginx主节点挂掉,VIP会自动绑定在Nginx备节点,从而保证VIP一直可用,实现Nginx高可用。

    1. 安装软件包(主/备)

    1. yum install epel-release -y
    2. yum install nginx keepalived -y

    2. Nginx配置文件(主/备一样)

    1. cat > /etc/nginx/nginx.conf << "EOF"
    2. user nginx;
    3. worker_processes auto;
    4. error_log /var/log/nginx/error.log;
    5. pid /run/nginx.pid;
    6. include /usr/share/nginx/modules/*.conf;
    7. events {
    8. worker_connections 1024;
    9. }
    10. # 四层负载均衡,为两台Master apiserver组件提供负载均衡
    11. stream {
    12. log_format main '$remote_addr $upstream_addr - [$time_local] $status $upstream_bytes_sent';
    13. access_log /var/log/nginx/k8s-access.log main;
    14. upstream k8s-apiserver {
    15. server 192.168.31.71:6443; # Master1 APISERVER IP:PORT
    16. server 192.168.31.74:6443; # Master2 APISERVER IP:PORT
    17. }
    18. server {
    19. listen 6443;
    20. proxy_pass k8s-apiserver;
    21. }
    22. }
    23. http {
    24. log_format main '$remote_addr - $remote_user [$time_local] "$request" '
    25. '$status $body_bytes_sent "$http_referer" '
    26. '"$http_user_agent" "$http_x_forwarded_for"';
    27. access_log /var/log/nginx/access.log main;
    28. sendfile on;
    29. tcp_nopush on;
    30. tcp_nodelay on;
    31. keepalive_timeout 65;
    32. types_hash_max_size 2048;
    33. include /etc/nginx/mime.types;
    34. default_type application/octet-stream;
    35. server {
    36. listen 80 default_server;
    37. server_name _;
    38. location / {
    39. }
    40. }
    41. }
    42. EOF

    3. keepalived配置文件(Nginx Master)

    cat > /etc/keepalived/keepalived.conf << EOF
    global_defs { 
     notification_email { 
       acassen@firewall.loc 
       failover@firewall.loc 
       sysadmin@firewall.loc 
     } 
     notification_email_from Alexandre.Cassen@firewall.loc  
     smtp_server 127.0.0.1 
     smtp_connect_timeout 30 
     router_id NGINX_MASTER
    } 
    vrrp_script check_nginx {
      script "/etc/keepalived/check_nginx.sh"
    }
    vrrp_instance VI_1 { 
      state MASTER 
      interface ens33
      virtual_router_id 51 # VRRP 路由 ID实例,每个实例是唯一的 
      priority 100    # 优先级,备服务器设置 90 
      advert_int 1    # 指定VRRP 心跳包通告间隔时间,默认1秒 
      authentication { 
          auth_type PASS      
          auth_pass 1111 
      }  
      # 虚拟IP
      virtual_ipaddress { 
          192.168.31.88/24
      } 
      track_script {
          check_nginx
      } 
    }
    EOF
    
  • vrrp_script:指定检查nginx工作状态脚本(根据nginx状态判断是否故障转移)

  • virtual_ipaddress:虚拟IP(VIP)

检查nginx状态脚本:

cat > /etc/keepalived/check_nginx.sh  << "EOF"
#!/bin/bash
count=$(ps -ef |grep nginx |egrep -cv "grep|$$")
if [ "$count" -eq 0 ];then
    exit 1
else
    exit 0
fi
EOF
chmod +x /etc/keepalived/check_nginx.sh

4. keepalived配置文件(Nginx Backup)

cat > /etc/keepalived/keepalived.conf << EOF
global_defs { 
   notification_email { 
     acassen@firewall.loc 
     failover@firewall.loc 
     sysadmin@firewall.loc 
   } 
   notification_email_from Alexandre.Cassen@firewall.loc  
   smtp_server 127.0.0.1 
   smtp_connect_timeout 30 
   router_id NGINX_BACKUP
} 
vrrp_script check_nginx {
    script "/etc/keepalived/check_nginx.sh"
}
vrrp_instance VI_1 { 
    state BACKUP 
    interface ens33
    virtual_router_id 51 # VRRP 路由 ID实例,每个实例是唯一的 
    priority 90
    advert_int 1
    authentication { 
        auth_type PASS      
        auth_pass 1111 
    }  
    virtual_ipaddress { 
        192.168.31.88/24
    } 
    track_script {
        check_nginx
    } 
}
EOF

上述配置文件中检查nginx运行状态脚本:

cat > /etc/keepalived/check_nginx.sh  << "EOF"
#!/bin/bash
count=$(ps -ef |grep nginx |egrep -cv "grep|$$")
if [ "$count" -eq 0 ];then
    exit 1
else
    exit 0
fi
EOF
chmod +x /etc/keepalived/check_nginx.sh

注:keepalived根据脚本返回状态码(0为工作正常,非0不正常)判断是否故障转移。

5. 启动并设置开机启动

systemctl daemon-reload
systemctl start nginx
systemctl start keepalived
systemctl enable nginx
systemctl enable keepalived

6. 查看keepalived工作状态

ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:04:f7:2c brd ff:ff:ff:ff:ff:ff
    inet 192.168.31.80/24 brd 192.168.31.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
    inet 192.168.31.88/24 scope global secondary ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe04:f72c/64 scope link 
       valid_lft forever preferred_lft forever

可以看到,在ens33网卡绑定了192.168.31.88 虚拟IP,说明工作正常。

7. Nginx+Keepalived高可用测试

关闭主节点Nginx,测试VIP是否漂移到备节点服务器。

在Nginx Master执行 pkill nginx
在Nginx Backup,ip addr命令查看已成功绑定VIP。

8. 访问负载均衡器测试

找K8s集群中任意一个节点,使用curl查看K8s版本测试,使用VIP访问:

curl -k https://192.168.31.88:6443/version
{
  "major": "1",
  "minor": "18",
  "gitVersion": "v1.18.3",
  "gitCommit": "2e7996e3e2712684bc73f0dec0200d64eec7fe40",
  "gitTreeState": "clean",
  "buildDate": "2020-05-20T12:43:34Z",
  "goVersion": "go1.13.9",
  "compiler": "gc",
  "platform": "linux/amd64"
}

可以正确获取到K8s版本信息,说明负载均衡器搭建正常。该请求数据流程:curl -> vip(nginx) -> apiserver
通过查看Nginx日志也可以看到转发apiserver IP:

tail /var/log/nginx/k8s-access.log -f
192.168.31.81 192.168.31.71:6443 - [30/May/2020:11:15:10 +0800] 200 422
192.168.31.81 192.168.31.74:6443 - [30/May/2020:11:15:26 +0800] 200 422

到此还没结束,还有下面最关键的一步。