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文件