原文發表於我的部落格,轉載請註明出處
一直聽說Nginx的強大,它不僅可以作為Web伺服器,按照排程規則實現動態、靜態頁面的分離;還可以作為反向代理伺服器,構建服務叢集,按輪詢、權重等多種方式對後端伺服器做負載均衡。以及自動剔除因故障負載均衡列表中當機的伺服器。這兩天折騰了一下Nginx的安裝、配置,並通過Docker模擬出Nginx在多伺服器提供服務的狀態下的負載均衡。
(一) 系統環境
作業系統 | Docker | Nginx |
---|---|---|
Ubuntu 16 | 1.12.1 | 1.8.0 |
(二) 準備Nginx環境
使用Docker這種容器技術,可以很方便地將所需要的環境打包和快速部署。所以我將Nginx的環境做成Docker映象,當需要多個Nginx服務時,只需要通過映象啟動多個容器。
-
映象已經PUSH到Docker Hub上,如果需要,可以直接在Docker拉取配置好nginx環境的映象
docker pull raomengnan/ubuntu:nginx-1.8.0
-
raomengnan/ubuntu:nginx-1.8.0 包含的基礎環境: nginx,zsh,vim,ssh,python
Dockerfile
# Ubuntu with Nginx
# Author raomengnan
FROM raomengnan/ubuntu-base
MAINTAINER raomengnan
# 安裝升級gcc
RUN rm -rf /var/lib/apt/lists/*
RUN apt-get update
# 新增相關的src
RUN apt-get -y install build-essential
RUN apt-get -y install supervisor
RUN mkdir -p /usr/local/temp
COPY supervisor.conf /etc/supervisor/conf.d/supervisord.conf
RUN wget http://nginx.org/download/nginx-1.8.0.tar.gz && tar -zxvf nginx-1.8.0.tar.gz -C /usr/local/temp
RUN wget http://zlib.net/zlib-1.2.8.tar.gz && tar -zxvf zlib-1.2.8.tar.gz -C /usr/local/temp
RUN wget http://www.openssl.org/source/openssl-1.0.1q.tar.gz && tar -zxvf openssl-1.0.1q.tar.gz -C /usr/local/temp
RUN wget http://downloads.sourceforge.net/project/pcre/pcre/8.37/pcre-8.37.tar.gz && tar -zxvf pcre-8.37.tar.gz -C /usr/local/temp
RUN rm *.tar.gz
# 安裝
RUN ls /usr/local/temp/nginx-1.8.0
RUN cd /usr/local/temp/nginx-1.8.0
&& ./configure --sbin-path=/usr/local/nginx-1.8.0/nginx --conf-path=/usr/local/nginx-1.8.0/nginx.conf --pid-path=/usr/local/nginx-1.8.0/nginx.pid --with-http_ssl_module --with-pcre=/usr/local/temp/pcre-8.37 --with-zlib=/usr/local/temp/zlib-1.2.8 --with-openssl=/usr/local/temp/openssl-1.0.1q
&& make
&& make install
# 設定nginx是非daemon啟動,否則nginx無法啟動
RUN echo "
daemon off;" >> /usr/local/nginx-1.8.0/nginx.conf
RUN echo `master_process off;` >> /usr/local/nginx-1.8.0/nginx.conf
RUN echo `error_log logs/error.log;` >> /usr/local/nginx-1.8.0/nginx.conf
RUN rm -rf /usr/local/temp/*
ENV NGINX_HOME /usr/local/nginx-1.8.0
# 將nginx新增到command
update-alternatives --install /usr/bin/nginx nginx /usr/local/nginx-1.8.0/nginx 300
EXPOSE 80
# 使用supervisor來管理多個程式同時啟動
# 若不想使用supervisor,可以使用:
# CMD nginx $/NGINX_HOME/nginx.conf
# 或者進入容器手動啟動nginx
CMD ["/usr/bin/supervisord"]
supervisor.conf
[supervisord]
nodaemon=true
[program:sshd]
command=/usr/sbin/sshd -D
[program:nginx]
command=/usr/local/nginx-1.8.0/nginx -c /usr/local/nginx-1.8.0/nginx.conf
(三) 啟動Nginx服務
啟動nginx時,可以提供Nginx的welcome頁面的訪問服務,可以通過這個頁面簡單地嘗試nginx提供的負載均衡。
通過映象啟動三個nginx服務
docker run --name ser1 -p 8881:80 raomengnan/ubuntu:nginx-1.8.0
docker run --name ser2 -p 8882:80 raomengnan/ubuntu:nginx-1.8.0
docker run --name ser3 -p 8883:80 raomengnan/ubuntu:nginx-1.8.0
-p引數將容器的80埠對映到宿主機的888×埠上
以ser1作為主伺服器,進入容器內修改nginx配置檔案
使用docker inspect ser1
便可以看到容器的詳細資訊,其中注意NetworkSetting下的這一段資訊就可以知道容器的閘道器和ip地址
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.3",
docker exec -it ser1 bash
進入容器內部
nginx安裝目錄在`/usr/local/nginx-1.8.0`下,vim /usr/local/nginx-1.8.0/nginx.conf
編輯配置檔案:
#user nobody;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
client_header_buffer_size 1k;
large_client_header_buffers 4 4k;
# 配置負載均衡,weight代表權重,權重越高,分配到的可能就越搭
upstream 172.17.0.2 {
server 172.17.0.2:8888 weight=5;
server 172.17.0.3:80 weight=4;
server 172.17.0.4:80 weight=3;
}
# 配置反向代理
server {
listen 80;
server_name 172.17.0.2;
location /{
# 反向代理的主機頭
proxy_pass http://172.17.0.2;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
# 偵聽本地8888埠,以便為反向代理到本地的請求提供服務
server {
listen 8888;
server_name localhost;
# 如過沒有對代理的連結形式有特殊要求,可以直接將root和index寫在server中
location / {
root /home/html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /home/html;
}
}
}
在ser1這個容器中配置反向代理,要關注server 172.17.0.2:8888 weight=5;
這一行,之所以反向代理到本機的8888埠,很好理解,因為若再次代理到80埠,永遠不能代理到本機的服務中,陷入死迴圈。
以ser×作為伺服器
#user nobody;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
client_header_buffer_size 1k;
large_client_header_buffers 4 4k;
server {
listen 80;
server_name 172.17.0.2;
# 如過沒有對代理的連結形式有特殊要求,可以直接將root和index寫在server中
location / {
root /home/html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /home/html;
}
}
}
serx和ser1的區別就在於http的設定,沒有upstream,server_name 為要負載的伺服器的ip。修改好配置檔案後,使用nginx -s reload
重新載入配置。
(四) 重新整理網頁測試
-
修改三個ser中的index.html,方便觀察
-
在瀏覽器中開啟 localhost:8881 或者 172.17.0.2,重新整理網頁
不斷重新整理,可以看到會開啟不同容器中的index頁面,說明服務被Nginx均衡地分配到不同的service上,這就是Nginx的負載均衡的作用。