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/fastdfs: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"="980623070@qq.com"
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"
- "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文件