docker-nginx-backup-server-and-loadblance
版本
Host主機作業系統: Ubuntu 20.04 LTS
Docker: Docker version 19.03.8
Container作業系統: Ubuntu 18.04.3 LTS
情景
架設一台主server和一個備用server,當主server斷線或其他原因掛掉,備用server將會接手主server的一切,並且支援load blancer的功能
使用的工具和設備的資料
利用Nginx+keepalived實作一台主server,一個備用server和load blancer
假設Host主機IP為140.0.0.1
Host Server IP: 140.0.0.1
虛擬IP: 172.18.0.15(希望改用實體IP)
主Server IP: 140.0.0.1:8880 對應container 172.18.0.2:80
備用Server IP: 140.0.0.1:8881 對應container 172.18.0.3:80
Web1 Server IP: 140.0.0.1:8882 對應container 172.18.0.4:80
Web2 Server IP: 140.0.0.1:8883 對應container 172.18.0.5:80
問題:目前遇到的問題是想要在keepalived的虛擬IP改用為140.0.0.1實體,這樣可以讓使用者連進來,目前不知道實體IP是否能取代虛擬IP?
創建VIP的keepalived架構圖
創建實體IP的keepalived架構圖(希望成為這樣的架構)
Image和網絡環境建立
創建 base image
cd base
docker build -t nginx_base .
cd ..
創建 master image
cd master
docker build -t nginx_master .
cd ..
創建 Slave image
cd slave
docker build -t nginx_slave .
cd ..
創建 Web image
cd web
docker build -t nginx_web .
cd ..
建立一個172.18.0.0/24子網絡
docker network create --subnet=172.18.0.0/24 test-network
docker network ls
NETWORK ID NAME DRIVER SCOPE
8aa82cadb992 bridge bridge local
1c6dc9a181fd host host local
6e57738d4cf8 none null local
1f3b89f652fe test-network bridge local
執行Master container
docker run -d \
-p 8880:80 -p 8022:22 \
--name nginx_master \
--privileged \
--net test-network \
nginx_master
執行Slave container
docker run -d \
-p 8881:80 -p 8023:22 \
--name nginx_slave \
--privileged \
--net test-network \
nginx_slave
執行Web1 and Web2 container
docker run -d \
-p 8882:80 -p 8024:22 \
--privileged \
--name web1 \
--net test-network \
-e "name=WEB1" \
nginx_web
docker run -d \
-p 8883:80 -p 8025:22 \
--privileged \
--name web2 \
--net test-network \
-e "name=WEB2" \
nginx_web
Container內部設定
Master設定
docker exec -it nginx_master bash # 開啟container
ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.18.0.2 netmask 255.255.255.0 broadcast 172.18.0.255
ether 02:42:ac:12:00:02 txqueuelen 0 (Ethernet)
RX packets 23 bytes 3347 (3.3 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 30 bytes 1500 (1.5 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
顯示目前的IP
ip appr
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
319: eth0@if320: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.18.0.2/24 brd 172.18.0.255 scope global eth0
valid_lft forever preferred_lft forever
inet 172.18.0.15/32 scope global eth0
valid_lft forever preferred_lft forever
Nginx upstream的設定
cat /etc/nginx/sites-enabled/default
upstream test {
server 172.18.0.4 weight=6;
server 172.18.0.5 weight=4;
}
server {
listen 80;
server_name 172.18.0.2; #container ip
location / {
proxy_pass http://test;
}
}
keepalived的設定
cat /etc/keepalived/keepalived.conf
global_defs {
router_id nginx_master
}
vrrp_script chk_http_port {
script "/opt/bin/nginx_check.sh"
interval 2
weight -20
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 55
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
track_script {
chk_http_port
}
virtual_ipaddress {
172.18.0.15 #VIP 想要換成 實體IP
}
}
重新啟動Nginx,若啟動失敗則2秒後殺掉keepalived
cat /opt/bin/nginx_check.sh
#!/bin/bash
A=`ps -C nginx --no-header |wc -l`
if [ $A -eq 0 ];then
/etc/init.d/nginx # start nginx
sleep 2
if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then
killall keepalived
fi
fi
Slave設定
docker exec -it nginx_slave bash # 開啟container
ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.18.0.3 netmask 255.255.255.0 broadcast 172.18.0.255
ether 02:42:ac:12:00:03 txqueuelen 0 (Ethernet)
RX packets 159 bytes 10977 (10.9 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 2 bytes 108 (108.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
顯示目前的IP
ip addr
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
321: eth0@if322: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:12:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.18.0.3/24 brd 172.18.0.255 scope global eth0
valid_lft forever preferred_lft forever
設定nginx upstream
cat /etc/nginx/sites-enabled/default
upstream test {
server 172.18.0.4 weight=6;
server 172.18.0.5 weight=4;
}
server {
listen 80;
server_name 172.18.0.3; #container ip
location / {
proxy_pass http://test;
}
}
設定keepalived
cat /etc/keepalived/keepalived.conf
global_defs {
router_id nginx_slave
}
vrrp_script chk_http_port {
script "/opt/bin/nginx_check.sh"
interval 2
weight -20
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 55
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
track_script {
chk_http_port
}
virtual_ipaddress {
172.18.0.15 #VIP 想要換成 實體IP
}
}
重新啟動Nginx,若啟動失敗則2秒後殺掉keepalived
cat /opt/bin/nginx_check.sh
#!/bin/bash
A=`ps -C nginx --no-header |wc -l`
if [ $A -eq 0 ];then
/etc/init.d/nginx # start nginx
sleep 2
if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then
killall keepalived
fi
fi