基於Docker部署FastDFS+Nginx,實現分佈式文件存儲和文件訪問的負載均衡

1、準備工作

1.1、準備基礎環境

先準備三個虛擬機來模擬集羣,它們的ip分別是192.168.36.132、192.168.36.133、192.168.36.134,宿主系統都是centos7,並且都安裝了帶有阿里雲鏡像加速的Docker。

1.2、準備FDFS+NGINX部署文件

FDFS並沒有在docker hub上維護官方鏡像,所以需要自行構建。用於創建鏡像的部署文件可以通過以下鏈接獲取

鏈接:https://pan.baidu.com/s/1LXSELSMvBb_QDruQBs44ow 
提取碼:pcb5

文件結構應如下圖所示

或者使用以下命令直接拉取已經創建好的鏡像如下:

docker pull registry.cn-shenzhen.aliyuncs.com/sgeoc/distribute_storage:v1.0

使用該方法的可跳過構建FDFS鏡像的小節。

創建鏡像的部署文件列表(src文件下的文件)如下:

名稱 說明
fdfs fdfs源文件
libfastcommon fdfs的公用函數包
fastdfs-nginx-module nginx與fdfs的關聯模塊,編譯nginx時使用
nginx 對外提供文件訪問能力

 

1.3、準備NGINX鏡像

此NGINX(稱爲:nginx_master)鏡像與1.2的NGINX(稱爲:nginx_worker)不同。nginx_worker用於對外提供單節點的文件訪問能力,而nginx_master用於對多個nginx_worker作負載均衡。NGINX官方鏡像可用以下命令獲取

docker pull nginx

1.4 、架構設計

由上圖可以看出,每個節點都有Tracker,Storage,和nginx_worker。Tracker是FDFS中的進程,負責獲取文件系統的狀態,是監控者,一個節點只有一個Tracker進程。Storage也是FDFS的進程,在集羣中是真正用於存儲和管理文件的角色,理論上一個節點可以有多個Storage進程,這要視乎group的設置和分佈情況(每個節點有多少個group,就有多少個Storage進程)。爲了縮減文章篇幅,上圖中Tracker只會部署單節點,部署多節點Tracker時只需要在tracker.conf中部署多個tracker_server便可。文件存儲路徑也只會使用/home/dfs,並且只有一個group,名稱是group1,所以每個節點只有一個Storage進程。最終相關文件的節點,和分配如下表所示:

名稱 IP地址 服務和文件 端口
Centos 1 192.168.32.132 tracker 22122
  192.168.32.132 storage-group1 23000
  192.168.32.132 libfastcommon -
  192.168.32.132 nginx_worker 8888
  192.168.32.132 fastdfs-nginx-module -
  192.168.32.132 nginx_master 8081
Centos 2 192.168.32.133 storage-group1 23000
  192.168.32.133 libfastcommon -
  192.168.32.133 nginx_worker 8888
  192.168.32.133 fastdfs-nginx-module -
Centos 3 192.168.32.134 storage-group1 23000
  192.168.32.134 libfastcommon -
  192.168.32.134 nginx_worker 8888
  192.168.32.134 fastdfs-nginx-module -

2、構建FDFS

部署FDFS時需要關注的配置文件在<path to file>/FDFS/src/fastdfs/docker/dockerfile_network/conf目錄下,講述它們的作用不是本文的內容,所以這裏不予以贅述。需要說明的一個文件是容器的啓動腳本<path to file>FDFS/src/fastdfs/docker/dockerfile_network/fastdfs.sh,裏面的代碼如下:

#!/bin/bash

new_val=$FASTDFS_IPADDR
old="com.ikingtech.ch116221"

sed -i "s/$old/$new_val/g" /etc/fdfs/client.conf
sed -i "s/$old/$new_val/g" /etc/fdfs/storage.conf
sed -i "s/$old/$new_val/g" /etc/fdfs/mod_fastdfs.conf

cat  /etc/fdfs/client.conf > /etc/fdfs/client.txt
cat  /etc/fdfs/storage.conf >  /etc/fdfs/storage.txt
cat  /etc/fdfs/mod_fastdfs.conf > /etc/fdfs/mod_fastdfs.txt

mv /usr/local/nginx/conf/nginx.conf /usr/local/nginx/conf/nginx.conf.t
cp /etc/fdfs/nginx.conf /usr/local/nginx/conf

echo "start trackerd"
/etc/init.d/fdfs_trackerd start

echo "start storage"
/etc/init.d/fdfs_storaged start

echo "start nginx"
/usr/local/nginx/sbin/nginx 

tail -f  /dev/null

這些代碼負責修改單個節點下的配置文件裏的配置,再啓動tracker,storage,和nginx_worker。此外還有nginx的配置文件nginx.conf,其代碼有一關鍵部分如下:

server {
        listen       8888;
        server_name  localhost;
        location ~/group[0-9]/ {
            ngx_fastdfs_module;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
        root   html;
        }
    }

這部分代碼使得nginx_worker和fdfs結合在了一起,使得fdfs中的文件能夠對外訪問。

2.1、使用Dockerfile構建鏡像

下載的文件中應該有兩個Dockerfile文件(Dockerfile_git和Dockerfile_src),Dockerfile_git使用git上的部署文件部署,而Dockerfile_src使用src裏面的文件部署,理論上兩個都可以。使用docker build命令即可完成鏡像構建,Dockerfile_src中的代碼如下:

FROM alpine:3.10

LABEL "maintainer"="sword" \
      "email"="[email protected]"

RUN mkdir -p /usr/local/src

COPY src /usr/local/src

RUN set -x \
  && chmod -R 777 /usr/local/src \
  && echo "http://mirrors.aliyun.com/alpine/latest-stable/main/" > /etc/apk/repositories \
  && echo "http://mirrors.aliyun.com/alpine/latest-stable/community/" >> /etc/apk/repositories \
  && apk update \
  && apk add --no-cache --virtual .build-deps gcc libc-dev make perl-dev openssl-dev pcre-dev zlib-dev \
  && cd /usr/local/src \
  && tar -xf nginx-1.15.4.tar.gz \
  && cd /usr/local/src/libfastcommon \
  && ./make.sh \
  && ./make.sh install \
  && cd /usr/local/src/fastdfs/ \
  && ./make.sh \
  && ./make.sh install \
  && cd /usr/local/src/nginx-1.15.4/ \
  && ./configure --add-module=/usr/local/src/fastdfs-nginx-module/src/ \
  && make && make install \
  && apk del .build-deps \
  && apk add --no-cache pcre-dev bash \
  && mkdir -p /home/dfs \
  && mv /usr/local/src/fastdfs/docker/dockerfile_network/fastdfs.sh /home \
  && mv /usr/local/src/fastdfs/docker/dockerfile_network/conf/* /etc/fdfs \
  && chmod +x /home/fastdfs.sh \
  && rm -rf /usr/local/src*

VOLUME /home/dfs
EXPOSE 22122 23000 8888 8080 80
CMD ["/home/fastdfs.sh"]

Dockerfile_git中的代碼如下:

FROM alpine:3.10

RUN set -x \
    && echo "http://mirrors.aliyun.com/alpine/latest-stable/main/" > /etc/apk/repositories \
    && echo "http://mirrors.aliyun.com/alpine/latest-stable/community/" >> /etc/apk/repositories \
    && apk update \
    && apk add --no-cache --virtual .build-deps gcc libc-dev make perl-dev openssl-dev pcre-dev zlib-dev git \
    && mkdir -p /usr/local/src \
    && cd /usr/local/src \
    && git clone https://github.com/happyfish100/libfastcommon.git --depth 1 \
    && git clone https://github.com/happyfish100/fastdfs.git --depth 1    \
    && git clone https://github.com/happyfish100/fastdfs-nginx-module.git --depth 1  \
    && wget http://nginx.org/download/nginx-1.15.4.tar.gz \
    && tar -xf nginx-1.15.4.tar.gz \
    && cd /usr/local/src/libfastcommon \
    && ./make.sh \
    && ./make.sh install \
    && cd /usr/local/src/fastdfs/ \
    && ./make.sh \
    && ./make.sh install \
    && cd /usr/local/src/nginx-1.15.4/ \
    && ./configure --add-module=/usr/local/src/fastdfs-nginx-module/src/ \
    && make && make install \
    && apk del .build-deps \
    && apk add --no-cache pcre-dev bash \
    && mkdir -p /home/dfs  \
    && mv /usr/local/src/fastdfs/docker/dockerfile_network/fastdfs.sh /home \
    && mv /usr/local/src/fastdfs/docker/dockerfile_network/conf/* /etc/fdfs \
    && chmod +x /home/fastdfs.sh \
    && rm -rf /usr/local/src*
VOLUME /home/dfs
EXPOSE 22122 23000 8888 8080
CMD ["/home/fastdfs.sh"]

3、Docker集羣部署FDFS+nginx_worker和nginx_master

3.1 部署FDFS+nginx_worker

部署分佈式存儲集羣和高可用負載均衡訪問需要兩個docker-compose文件,首先是基於FDFS+nginx_worker的鏡像部署的docker-compose.yml,在Centos 1,Centos 2,Centos 3上運行docker-compose up -d命令。文件代碼如下。

version: "3.1"
services:
  sgeocfdfs_1:
    image: sgeocfdfs:v1.0
    container_name: sgeocfdfs_1
    ports:
      - "22122:22122"
      - "23000:23000"
      - "8888:8888"
      - "8080:8080"
      - "80:80"

    environment:
      FASTDFS_IPADDR: 192.168.36.132

    volumes:
      - "/home/sword/Desktop/DS/fdfs_data:/home/dfs"

    network_mode: "host"

需要注意的是,FDFS的網絡一定要使用host,或者nat,與宿主系統共享ip和端口,使用bridge的storage進程的ip會轉爲docker的虛擬ip。另外FASTDFS_IPADDR配置的tracker的ip。

3.2 部署nginx_master

nginx_master是數據訪問的入口,所以它只需要在一臺機器上部署便可,使用以下docker-compose.yml代碼部署。

version: "3.1"
services:
  sgeoc_fdfs_nginx:
    image: nginx
    container_name: sgeoc_fdfs_nginx
    ports:
     - 8081:80
    volumes:
     - "/home/sword/Desktop/DS/nginx_data:/usr/share/nginx/html"
     - "/home/sword/Desktop/DS/NGINX/conf/nginx.conf:/etc/nginx/nginx.conf"

並且nginx.conf的配置如下

user  nginx;
worker_processes  10;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    add_header 'Access-Control-Allow-Origin' '*';
    add_header 'Access-Control-Allow-Credentials' 'true';
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;

    keepalive_timeout  65;

    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;
        #access_log  /var/log/nginx/host.access.log  main;

        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
             root   /usr/share/nginx/html;
        }


        location ^~ /group1/{
            add_header 'Access-Control-Allow-Origin' '*';
            add_header 'Access-Control-Allow-Credentials' 'true';
            proxy_pass http://fdfs_group1;

        }

    }

    upstream fdfs_group1 {
        server 192.168.36.132:8888 max_fails=0;
        server 192.168.36.133:8888 max_fails=0;
        server 192.168.36.134:8888 max_fails=0;
        keepalive 10240;

    }
}

需要說明的是,upstream部分對應3臺機器的nginx_worker,對nginx_master進行訪問的鏈接只要符合^~ /group1/表達式的都會轉發到fdfs_group1中做負載

3、Python代碼示例

from fdfs_client.client import Fdfs_client, get_tracker_conf
tracker_path = get_tracker_conf('E:/PycharmProject/sgeoc_fdfs_client/client.conf')
client = Fdfs_client(tracker_path)
ret = client.upload_by_filename('E:/PycharmProject/sgeoc_fdfs_client/1.png')

其中client.conf文件對應FDFS中的/etc/fdfs/client.conf文件

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章