Py学习  »  docker

利用FastDFS搭建文件服务Docker一键启动集成版 - 在巨人肩膀上奔跑系列

一起吃火锅 • 4 年前 • 146 次点击  
阅读 21

利用FastDFS搭建文件服务Docker一键启动集成版 - 在巨人肩膀上奔跑系列

一、什么是FastDFS

最近公司业务需求,需要搭建文件服务器,经过各种咨询和搜索,决定使用FastDFS。那FastDFS有什么优点呢?

FastDFS是用c语言编写的一款开源的分布式文件系统。FastDFS为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,使用FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。

更详细的大家可以参考:来自ityouknow的文章: 点击查看

二、如何使用docker镜像

为了更方便地集成到现有服务里,我们需要一个可以一键运行的docker镜像,但是网络上找了很多,有的把libfastcommon分离了,有的配置繁琐,都没有很好整合或者不满足业务需求。因此,接下来我们一步一步来写这个dockerfile来实现一键运行。

如果你比较懒,直接run下面的镜像就可以:

docker run -d annoak/fastdfs:latest \
    -p 8888:8888 \
    -p 22122:22122 \
    -e TZ=Asia/Shanghai \
    -v /data/fdfs:/var/local/fdfs
    --restart=always
复制代码

如果需要自定义端口

docker run -d annoak/fastdfs:latest \
    -p 8888:8888 \
    -p 22122:22122 \
    -e TZ=Asia/Shanghai \
    -e NGINX_PORT=8888 \
    -e FDFS_PORT=22122 \
    -v /data/fdfs:/var/local/fdfs
    --restart=always
复制代码

如果需要自定义HOST

  • 第一种:[传入网络名,自动获取IP]
docker run -d annoak/fastdfs:latest \
    -p 8888:8888 \
    -p 22122:22122 \
    -e TZ=Asia/Shanghai \
    -e NET_VAR=eth0 \
    -v /data/fdfs:/var/local/fdfs
    --restart=always
复制代码
  • 第二种:[直接传入IP]
docker run -d annoak/fastdfs:latest \
    -p 8888:8888 \
    -p 22122:22122 \
    -e TZ=Asia/Shanghai \
    -e HOST_IP=xxx.xxx.xxx.xxx \
    -v /data/fdfs:/var/local/fdfs
    --restart=always
复制代码

如果不想映射端口直接使用宿主机网络:

docker run -d annoak/fastdfs:latest \
    --net=host \
    -e TZ=Asia/Shanghai \
    -v /data/fdfs:/var/local/fdfs
    --restart=always
复制代码

如果需要自定义nginx版本

docker run -d annoak/fastdfs:latest \
    --net=host \
    -e TZ=Asia/Shanghai \
    -e NGINX_VERSION=1.17.0 \
    -v /data/fdfs:/var/local/fdfs
    --restart=always
复制代码

如果你使用的是docker-compose

services:
    fastdfs:
        image: annoak/fastdfs:latest
        container_name: my-fastdfs
        environment:
            - TZ=Asia/Shanghai
            - NGINX_PORT=8888
            - FDFS_PORT=22122
            - HOST_IP=192.168.198.107
            - NET_VAR=eth0
        volumes:
            - /data/fdfs:/var/local/fdfs
        #ports:# 如果用host网络,无需映射
        #    - "8888:8888"
        #    - "22122:22122"
        # 把root权限带进去
        privileged: true
        network_mode: "host"
        restart: always
复制代码

如果你想知道它是怎么来的,请继续往下看:

三、如何编写dockerfile

  • 第1步,当然是创建一个dockerfile文件,然后去看看我们需要用的软件版本。

    依赖版本:libfastcommon和fastdfs的版本为master分支,nginx默认1.17.0,你懂的。

    具体版本查看:

    libfastcommon: 点击跳转

    fastdfs: 点击跳转

    nginx: 点击跳转

  • 第2步,我们需要选择一个环境,嗯,我们选择最小的Linux -> alpine,现在dockerfile是这样的:

FROM alpine:3.7
复制代码
  • 第3步,定义几个全局变量吧
# 工作目录
ENV HOME=/root/fastdfs \
    # nginx版本
    NGINX_VERSION=1.17.0 \
    # nginx端口默认值
    NGINX_PORT=8888 \
    # IP所在网络默认值
    NET_VAR=eth0 \
    # fastdfs端口默认值
    FDFS_PORT=22122
复制代码
  • 第4步,我们需要安装一些编译期间的依赖软件,顺便更新下系统软件
# 创建目录
RUN mkdir -p ${HOME}

# 升级软件包
RUN apk update

# 安装必要的软件,加上--virtual .mybuilds,
RUN apk add --no-cache --virtual .mybuilds \
    bash \
    gcc \
    make \
    linux-headers \
    curl \
    gnupg \
    gd-dev \
    pcre-dev \
    zlib-dev \
    libc-dev \
    libxslt-dev \
    openssl-dev \
    geoip-dev
复制代码

为什么要加--virtual .mybuilds,它是什么? 当您安装软件包时,这些软件包不会添加到全局软件包中。而且可以很容易地恢复。比如我需要gcc来编译程序,但是一旦程序被编译,我就不再需要gcc了。

  • 第5步,我们需要检查一下目录,然后下载fastdfs的依赖libfastcommon并且编译安装
# 下载、安装libfastcommon
RUN cd ${HOME}/ \
    && curl -fSL  https://github.com/happyfish100/libfastcommon/archive/master.tar.gz -o fastcommon.tar.gz \
    && tar zxf fastcommon.tar.gz \
    && cd ${HOME}/libfastcommon-master/ \
    && ./make.sh \
    && ./make.sh install
复制代码
  • 第6步,下载、编译、安装fastdfs
# 下载、安装fastdfs
RUN cd ${HOME}/ \
    && curl -fSL  https://github.com/happyfish100/fastdfs/archive/master.tar.gz -o fastfs.tar.gz \
    && tar zxf fastfs.tar.gz \
    && cd ${HOME}/fastdfs-master/ \
    && ./make.sh \
    && ./make.sh install
复制代码
  • 第7步,配置一下fastdfs, 替换一下里面的路径/home/yuqing/fastdfs
# 配置fastdfs
RUN cd /etc/fdfs/ \
    && cp storage.conf.sample storage.conf \
    && sed -i "s|/home/yuqing/fastdfs|/var/local/fdfs/storage|g"


    
 /etc/fdfs/storage.conf \
    && cp tracker.conf.sample tracker.conf \
    && sed -i "s|/home/yuqing/fastdfs|/var/local/fdfs/tracker|g" /etc/fdfs/tracker.conf \
    && cp client.conf.sample client.conf \
    && sed -i "s|/home/yuqing/fastdfs|/var/local/fdfs/storage|g" /etc/fdfs/client.conf 
复制代码
  • 第8步,好了,接下来我们安装一下nginx和nginx插件
# 下载nginx插件
RUN cd ${HOME}/ \
    && curl -fSL  https://github.com/happyfish100/fastdfs-nginx-module/archive/master.tar.gz -o nginx-module.tar.gz \
    && tar zxf nginx-module.tar.gz

# 下载nginx
RUN cd ${HOME}/ \
    && curl -fSL http://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz -o nginx-${NGINX_VERSION}.tar.gz \
    && tar zxf nginx-${NGINX_VERSION}.tar.gz
复制代码
  • 第9步,我们把nginx两兄弟一起编译安装下
# 将nginx和fastdfs的nginx插件编译
RUN cd ${HOME} \
    && chmod u+x ${HOME}/fastdfs-nginx-module-master/src/config \
    && cd nginx-${NGINX_VERSION} \
    && ./configure --add-module=${HOME}/fastdfs-nginx-module-master/src \
    && make && make install
复制代码

这时候,你大概会报错:No such file or directory #include "common_define.h" 这很致命,怎么解决呢?

我们需要改一下源码里的fastdfs-nginx-module-master/src/config文件 在dockerfile同目录下,新建一个文件:config,写入如下配置:

ngx_addon_name=ngx_http_fastdfs_module
if test -n "${ngx_module_link}"; then
    ngx_module_type=HTTP
    ngx_module_name=$ngx_addon_name
    ngx_module_incs="/usr/local/include"
    ngx_module_libs="-lfastcommon -lfdfsclient"
    ngx_module_srcs="$ngx_addon_dir/ngx_http_fastdfs_module.c"
    ngx_module_deps=
    CFLAGS="$CFLAGS -D_FILE_OFFSET_BITS=64 -DFDFS_OUTPUT_CHUNK_SIZE='256*1024' -DFDFS_MOD_CONF_FILENAME='\"/etc/fdfs/mod_fastdfs.conf\"'"
    . auto/module
else
    HTTP_MODULES="$HTTP_MODULES ngx_http_fastdfs_module"
    NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_fastdfs_module.c"
    CORE_INCS="$CORE_INCS /usr/local/include"
    CORE_LIBS="$CORE_LIBS -lfastcommon -lfdfsclient"
    CFLAGS="$CFLAGS -D_FILE_OFFSET_BITS=64 -DFDFS_OUTPUT_CHUNK_SIZE='256*1024' -DFDFS_MOD_CONF_FILENAME='\"/etc/fdfs/mod_fastdfs.conf\"'"
fi
复制代码

然后在dockerfile中编译那段之前,添加

# 修复编译找不到 #include "common_define.h"的致命问题
ADD ./config ${HOME}/fastdfs-nginx-module-master/src
复制代码
  • 第10步,配置nginx和fastdfs环境,配置一下nginx
# 配置nginx和fastdfs环境,配置nginx
RUN cp ${HOME}/fastdfs-nginx-module-master/src/mod_fastdfs.conf /etc/fdfs/ \
    && sed -i "s|^store_path0.*$|store_path0=/var/local/fdfs/storage|g" /etc/fdfs/mod_fastdfs.conf \
    && sed -i "s|^url_have_group_name=.*$|url_have_group_name=true|g" /etc/fdfs/mod_fastdfs.conf \
    && cd ${HOME}/fastdfs-master/conf/ \
    && cp http.conf mime.types anti-steal.jpg /etc/fdfs/ \
    && echo -e "events {\n\
    worker_connections  1024;\n\
}\n\
http {\n\
    include       mime.types;\n\
    default_type  application/octet-stream;\n\
    server {\n\
        listen \$NGINX_PORT;\n\
        server_name localhost;\n\
        location ~ /group[0-9]/M00 {\n\
            ngx_fastdfs_module;\n\
        }\n\
    }\n\
}">/usr/local/nginx/conf/nginx.conf
复制代码

第11步,我们很接近成功了,先清理下我们不会再用到的文件和软件

# 清理临时软件和文件
RUN rm -rf ${HOME}/*
RUN apk del .mybuilds
RUN apk add bash pcre-dev zlib-dev
复制代码

第12步,我们好像就差一个启动脚本了,接下来,写个启动脚本;这里需要注意NET_VAR变量,我在这里踩了个坑,默认是eth0,适合Linux,如果是mac,需要给它赋值en0,或者直接自定义:HOST_IP

# 创建启动脚本
RUN     echo -e "mkdir -p /var/local/fdfs/storage/data /var/local/fdfs/tracker; \n\
ln -s /var/local/fdfs/storage/data/ /var/local/fdfs/storage/data/M00; \n\n\
sed -i \"s/listen\ .*$/listen\ \$NGINX_PORT;/g\" /usr/local/nginx/conf/nginx.conf; \n\
sed -i \"s/http.server_port=.*$/http.server_port=\$NGINX_PORT/g\" /etc/fdfs/storage.conf; \n\
if [ \"\$HOST_IP\" = \"\" ]; then \n\
    HOST_IP=\$(ifconfig \$NET_VAR | grep \"inet\" | grep -v \"inet6\" | awk '{print \$2}' | awk -F: '{print \$2}')\n\
fi \n\
sed -i \"s/^tracker_server=.*$/tracker_server=\$HOST_IP:\$FDFS_PORT/g\" /etc/fdfs/storage.conf; \n\
sed -i \"s/^tracker_server=.*$/tracker_server=\$HOST_IP:\$FDFS_PORT/g\" /etc/fdfs/client.conf; \n\
sed -i \"s/^tracker_server=.*$/tracker_server=\$HOST_IP:\$FDFS_PORT/g\" /etc/fdfs/mod_fastdfs.conf; \n\
/etc/init.d/fdfs_trackerd start; \n\
/etc/init.d/fdfs_storaged start; \n\
/usr/local/nginx/sbin/nginx; \n\
tail -f /usr/local/nginx/logs/access.log \
">/start.sh \
&& chmod u+x /start.sh
复制代码

第13步,好了,暴露端口,配置启动脚本,收工

# 暴露端口
EXPOSE ${NGINX_PORT} ${FDFS_PORT}
ENTRYPOINT ["/bin/bash","/start.sh"]
复制代码
  • 总结:完整的dockerfile
FROM alpine:3.7

MAINTAINER oak <ritj@163.com>

    # 定义变量
ENV HOME=/root/fastdfs \
    # nginx版本
    NGINX_VERSION=1.17.0 \
    # nginx端口默认值
    NGINX_PORT=8888 \
    # IP所在网络
    NET_VAR=eth0 \
    # fastdfs端口默认值
    FDFS_PORT=22122

# 创建目录
RUN mkdir -p ${HOME}

# 升级软件包
RUN apk update

# 安装必要的软件
RUN apk add --no-cache --virtual .mybuilds \
    bash \
    gcc \
    make \
    linux-headers \
    curl \
    gnupg \
    gd-dev \
    pcre-dev \
    zlib-dev \
    libc-dev \
    libxslt-dev \
    openssl-dev \
    geoip-dev

# 下载、安装libfastcommon
RUN cd ${HOME}/ \
    && curl -fSL  https://github.com/happyfish100/libfastcommon/archive/master.tar.gz -o fastcommon.tar.gz \
    && tar zxf fastcommon.tar.gz \
    && cd ${HOME}/libfastcommon-master/ \
    && ./make.sh \
    && ./make.sh install

# 下载、安装fastdfs
RUN cd ${HOME}/ \
    && curl -fSL  https://github.com/happyfish100/fastdfs/archive/master.tar.gz -o fastfs.tar.gz \
    && tar zxf fastfs.tar.gz \
    && cd ${HOME}/fastdfs-master/ \
    && ./make.sh \
    && ./make.sh install

# 配置fastdfs
RUN cd /etc/fdfs/ \
    && cp storage.conf.sample storage.conf \
    && sed -i "s|/home/yuqing/fastdfs|/var/local/fdfs/storage|g"


    
 /etc/fdfs/storage.conf \
    && cp tracker.conf.sample tracker.conf \
    && sed -i "s|/home/yuqing/fastdfs|/var/local/fdfs/tracker|g" /etc/fdfs/tracker.conf \
    && cp client.conf.sample client.conf \
    && sed -i "s|/home/yuqing/fastdfs|/var/local/fdfs/storage|g" /etc/fdfs/client.conf 

# 下载nginx插件
RUN cd ${HOME}/ \
    && curl -fSL  https://github.com/happyfish100/fastdfs-nginx-module/archive/master.tar.gz -o nginx-module.tar.gz \
    && tar zxf nginx-module.tar.gz

# 下载nginx
RUN cd ${HOME}/ \
    && curl -fSL http://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz -o nginx-${NGINX_VERSION}.tar.gz \
    && tar zxf nginx-${NGINX_VERSION}.tar.gz

# 修复编译找不到 #include "common_define.h"的致命问题
ADD ./config ${HOME}/fastdfs-nginx-module-master/src

# 将nginx和fastdfs的nginx插件编译
RUN cd ${HOME} \
    && chmod u+x ${HOME}/fastdfs-nginx-module-master/src/config \
    && cd nginx-${NGINX_VERSION} \
    && ./configure --add-module=${HOME}/fastdfs-nginx-module-master/src \
    && make && make install

# 配置nginx和fastdfs环境,配置nginx
RUN cp ${HOME}/fastdfs-nginx-module-master/src/mod_fastdfs.conf /etc/fdfs/ \
    && sed -i "s|^store_path0.*$|store_path0=/var/local/fdfs/storage|g" /etc/fdfs/mod_fastdfs.conf \
    && sed -i "s|^url_have_group_name=.*$|url_have_group_name=true|g" /etc/fdfs/mod_fastdfs.conf \
    && cd ${HOME}/fastdfs-master/conf/ \
    && cp http.conf mime.types anti-steal.jpg /etc/fdfs/ \
    && echo -e "events {\n\
    worker_connections  1024;\n\
}\n\
http {\n\
    include       mime.types;\n\
    default_type  application/octet-stream;\n\
    server {\n\
        listen \$NGINX_PORT;\n\
        server_name localhost;\n\
        location ~ /group[0-9]/M00 {\n\
            ngx_fastdfs_module;\n\
        }\n\
    }\n\
}">/usr/local/nginx/conf/nginx.conf

# 清理临时软件和文件
RUN rm -rf ${HOME}/*
RUN apk del .mybuilds
RUN apk add bash pcre-dev zlib-dev

# 创建启动脚本
RUN     echo -e "mkdir -p /var/local/fdfs/storage/data /var/local/fdfs/tracker; \n\
ln -s /var/local/fdfs/storage/data/ /var/local/fdfs/storage/data/M00; \n\n\
sed -i \"s/listen\ .*$/listen\ \$NGINX_PORT;/g\" /usr/local/nginx/conf/nginx.conf; \n\
sed -i \"s/http.server_port=.*$/http.server_port=\$NGINX_PORT/g\" /etc/fdfs/storage.conf; \n\
if [ \"\$HOST_IP\" = \"\" ]; then \n\
    HOST_IP=\$(ifconfig \$NET_VAR | grep \"inet\" | grep -v \"inet6\" | awk '{print \$2}' | awk -F: '{print \$2}')\n\
fi \n\
sed -i \"s/^tracker_server=.*$/tracker_server=\$HOST_IP:\$FDFS_PORT/g\" /etc/fdfs/storage.conf; \n\
sed -i \"s/^tracker_server=.*$/tracker_server=\$HOST_IP:\$FDFS_PORT/g\" /etc/fdfs/client.conf; \n\
sed -i \"s/^tracker_server=.*$/tracker_server=\$HOST_IP:\$FDFS_PORT/g\" /etc/fdfs/mod_fastdfs.conf; \n\
/etc/init.d/fdfs_trackerd start; \n\
/etc/init.d/fdfs_storaged start; \n\
/usr/local/nginx/sbin/nginx; \n\
tail -f /usr/local/nginx/logs/access.log \
">/start.sh \
&& chmod u+x /start.sh

# 暴露端口
EXPOSE ${NGINX_PORT} ${FDFS_PORT}

ENTRYPOINT ["/bin/bash","/start.sh"]
复制代码

文件结构:

四、如何查看日志

脚本一个:

#!/bin/bash
STORAGE=/var/local/fdfs/storage/logs/storaged.log
TRACKER=/var/local/fdfs/tracker/logs/trackerd.log
NGINX=/usr/local/nginx/logs/access.log

ID=$(docker ps|grep fastdfs|awk '{print $1}')
USER_PRINT=$1
LOG=""
if [[ "${USER_PRINT}" = "tracker" ]];then
    LOG=${TRACKER}
elif [[ "${USER_PRINT}" = "storage" ]]; then
    LOG=${STORAGE}
else 
    LOG=${NGINX}
fi

docker exec -it $ID /usr/bin/tail -f ${LOG}
复制代码

使用方法(记得给脚本赋执行权): ./log.sh tracker 或 storage 或 nginx

没有公众号,也没有二维码,也没有广告,仅此。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/34231
 
146 次点击