Docker下打包FastDFS鏡像以及上傳遇到的問題


官方地址:https://github.com/happyfish100/fastdfs

一、先下載個包,然后解壓(自己找個目錄下載即可)

[root@localhost soft]# wget https://github.com/happyfish100/fastdfs/archive/master.zip
--2019-09-16 05:26:36--  https://github.com/happyfish100/fastdfs/archive/master.zip
Resolving github.com (github.com)... 13.250.177.223
Connecting to github.com (github.com)|13.250.177.223|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://codeload.github.com/happyfish100/fastdfs/zip/master [following]
--2019-09-16 05:26:37--  https://codeload.github.com/happyfish100/fastdfs/zip/master
Resolving codeload.github.com (codeload.github.com)... 13.229.189.0
Connecting to codeload.github.com (codeload.github.com)|13.229.189.0|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [application/zip]
Saving to: ‘master.zip’

    [    <=>                                                                                                                                                                                            ] 482,045      645KB/s   in 0.7s   

2019-09-16 05:26:38 (645 KB/s) - ‘master.zip’ saved [482045]

[root@localhost soft]# unzip master.zip 
Archive:  master.zip
14edb44071b27599a5fc8c818b643eed6fe15e11
   creating: fastdfs-master/
....

二、進入fastdfs-master/docker/dockerfile_network目錄,執行打包命令

[root@localhost soft]# cd fastdfs-master/docker/dockerfile_network
[root@localhost dockerfile_network]# 

打包(注意,你的宿主機內存至少要2G,不然會報錯如下:)我之前只分配給宿主機1G內存,明顯不夠用。

如果還不行,清理一下yum緩存

# yum clean all
Loaded plugins: fastestmirror, langpacks
Cleaning repos: base docker-ce-stable extras updates
Cleaning up everything
Maybe you want: rm -rf /var/cache/yum, to also free up space taken by orphaned data from disabled or removed repos

# rm -rf /var/cache/yum

好,執行命令打包:(注意最后有個點)

[root@localhost dockerfile_network]# docker build -t local/fastdfs:latest .
Sending build context to Docker daemon   68.1kB
Step 1/13 : FROM centos
 ---> 67fa590cfc1c
Step 2/13 : ADD conf/client.conf /etc/fdfs/
 ---> Using cache
 ---> f6d4d01d7cf4
Step 3/13 : ADD conf/http.conf /etc/fdfs/
 ---> Using cache
 ---> 09b5d6e42010
Step 4/13 : ADD conf/mime.types /etc/fdfs/
 ---> Using cache
 ---> 01ba930f4e2a
Step 5/13 : ADD conf/storage.conf /etc/fdfs/
 ---> Using cache
 ---> 628d5f17543d
Step 6/13 : ADD conf/tracker.conf /etc/fdfs/
 ---> Using cache
 ---> b62b681c8ee8
Step 7/13 : ADD fastdfs.sh /home
 ---> Using cache
 ---> 6f0ffb43c5fc
Step 8/13 : ADD conf/nginx.conf /etc/fdfs/
 ---> Using cache
 ---> 6e2dded720b5
Step 9/13 : ADD conf/mod_fastdfs.conf /etc/fdfs
 ---> Using cache
 ---> 6feff4c6bb23
Step 10/13 : RUN yum install git gcc gcc-c ++ make automake autoconf libtool pcre pcre-devel zlib zlib-devel openssl-devel wget vim -y   &&    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 -zxvf nginx-1.15.4.tar.gz      &&    mkdir /home/dfs     &&    cd /usr/local/src/    &&    cd libfastcommon/     &&    ./make.sh && ./make.sh install    &&    cd ../    &&    cd fastdfs/     &&    ./make.sh && ./make.sh install    &&    cd ../    &&    cd nginx-1.15.4/    &&    ./configure --add-module=/usr/local/src/fastdfs-nginx-module/src/     &&    make && make install    &&    chmod +x /home/fastdfs.sh
 ---> Using cache
 ---> 59424d66e1a1
Step 11/13 : VOLUME /etc/fdfs
 ---> Using cache
 ---> d72d68fd5ebf
Step 12/13 : EXPOSE 22122 23000 8888 80
 ---> Using cache
 ---> f0c2d84a954e
Step 13/13 : ENTRYPOINT ["/home/fastdfs.sh"]
 ---> Using cache
 ---> fc76c652493b
Successfully built fc76c652493b
Successfully tagged local/fastdfs:latest

(額,這是我第二次打包,我第一次打包輸出好多內容的,你們自行體會,你們應該能看見  ---> Using cache 利用了緩存)

 

另:網友打包把體積縮小到30M左右,需要修改Dockerfile成如下所示,打包過程不變如上所示(https://github.com/happyfish100/fastdfs/issues/327

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"]

測試上傳

這里面有個坑。先啟動鏡像

docker run -d -e FASTDFS_IPADDR=[宿主機地址] -p 8888:8888 -p 22122:22122 -p 23000:23000 -p 8011:80 --name test-fast local/fastdfs

然后客戶端上傳,報錯。com.github.tobato.fastdfs.exception.FdfsConnectException: 無法獲取服務端連接資源:can't create connection to/172.17.0.1:23000

 

 為什么呢,首先我們客戶端連接提供了tracker的地址,這個地址可以訪問的,已經將22122端口映射到宿主機上了,而客戶端的storage地址是通過tracker獲取的,而這個地址則是Docker的容器地址,不能直接訪問,所以連接超時。

進入容器能看到storage的地址如下:

 

你查看容器信息:

$ docker inspect 437c7bde65f8

在最后有地址信息,可見網關地址和實際地址

 

也就是說,tracker把Docker容器的網關地址當成了storage的地址

思考過程

網上有人說,利用iptables配置轉發規則即可,可是我按照它的方法沒有成功,那么根據轉發這個思路分析一下。

目前我的環境大概是這樣的

首先,Java客戶端根據獲取的storage地址(172.17.0.1:23000)去請求,到底能不能經過網段192.*的虛擬機,我們知道路由表的概念:(引用網友通俗的解釋)

路由表是機器使用網絡時要查找的一個表項,根據路由表來查找發送到特定IP的信息該發送到那個下一跳。

比如你的機子要發送一個信息到192.168.2.8,它就要查路由表到底應該怎么發,假設它查出的結果是可以直接發送,那就直接發送,否則就查出來應該發送到哪個IP,交給那個IP轉發。

那么我們看一下我本機的路由表,執行: route print -4 【-6代表IPv6,不加打印全部】

 

 我在搜索一下172的

 

 沒有,證明什么,憑借172*的地址,我哪也去不了,所以不會到達虛擬機,到達不了虛擬機,網上說的轉發是轉發什么呢?所以根本行不通吧。

我們再來看我虛擬機上的路由表

 

 沒錯,存在172的網段,但是,你要玩172,也要先進入虛擬機才行。而Java客戶端是直接去請求172地址的,那就別想了。哪也去不了。

=====================================================================================================

以下是我查閱的資料:

關於Docker網絡:https://docs.docker.com/network/

Docker網絡模式:https://www.cnblogs.com/yy-cxd/p/6553624.html

iptables的介紹:http://www.zsythink.net/archives/1199

iptables簡單增刪查改:https://www.cnblogs.com/bethal/p/5806525.html

路由表:https://www.cnblogs.com/baiduboy/p/7278715.html

路由尋址過程:https://blog.csdn.net/u011857683/article/details/83795279

 

后記:仔細想一下,如果你分開容器部署可能也會出現同樣的問題,問題就在於我們無法為storage強制配一個地址,這樣的結果在Docker環境下就成了:tracker獲取到的storage地址永遠都是容器網關地址,而不是映射外網地址。

也有個網友這樣想的,但需要修改代碼:

 

 

另外我也明白了那個iptables網友的思路:他覺得是因為在請求tracker,tracker返回storage地址的時候去修改(將返回的172.17.0.1:23000修改為宿主機地址),可是我沒有成功。

最后一種方法,就是使用host網絡模式,這樣就不存在二層網絡了,媽媽再也不用擔心地址錯誤了。

[root@localhost admin]# docker run -d -e FASTDFS_IPADDR=192.168.192.128 --name test-fast --net=host local/fastdfs-2
047250f19cad90af03ae979e8a646fff61349883f7ecdb38f72d063bd93e3f80
[root@localhost admin]# 

然后客戶端上傳文件

<dependency>
    <groupId>com.github.tobato</groupId>
    <artifactId>fastdfs-client</artifactId>
    <version>1.26.6</version>
</dependency>

application.properties

#連接時間
fdfs.connect-timeout=600
#讀取時間
fdfs.so-timeout=2000
#縮略圖
fdfs.thumb-image.width=96
fdfs.thumb-image.height=128
#tracker列表
fdfs.tracker-list=192.168.192.128:22122

# 自定義屬性,圖片訪問地址
img.host=http://192.168.192.128:8888/

工具類

import com.alibaba.fastjson.JSONObject;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.domain.fdfs.ThumbImageConfig;
import com.github.tobato.fastdfs.domain.upload.FastFile;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.InputStream;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

/**
 * 不會出現網上說的jmx重復注冊bean的問題,是FastDFS-Client 1.26.4版本以前引入方式
 */
@Component
@Slf4j
public class UploadToFastDFS {

    @Autowired
    protected FastFileStorageClient storageClient;

    @Autowired
    private ThumbImageConfig thumbImageConfig;

    @Value("${img.host}")
    private String imgHost;

    /**
     * 上傳文件並生成縮略圖
     * @param inputStream
     * @param fileSize
     * @param fileExtName
     * @return
     */
    public Map<String, String> uploadFile(InputStream inputStream, Long fileSize, String fileExtName){
        Map<String, String> map = new HashMap<>();
        log.info("##上傳文件...");
        FastFile fastFile = new FastFile.Builder()
                .withFile(inputStream, fileSize, fileExtName)
                .build();

        // 上傳文件
        StorePath storePath = storageClient.uploadImageAndCrtThumbImage(inputStream, fileSize, fileExtName, new HashSet<>());
        log.info("上傳文件結果...{}", storePath);
        // 帶分組的路徑
        String fullPath = storePath.getFullPath();
        log.info("帶分組的路徑...{}", fullPath);
        String path = storePath.getPath();
        log.info("路徑...{}", path);
        // 獲取縮略圖路徑
        String thumbImagePath = thumbImageConfig.getThumbImagePath(storePath.getPath());
        log.info("縮略圖路徑...{}", thumbImagePath);

        map.put("fullPath", imgHost + fullPath);
        map.put("thumbImagePath", imgHost + storePath.getGroup() + "/" + thumbImagePath);
        log.info("返回結果:{}" + JSONObject.toJSONString(map));
        // 返回結果:{}{"fullPath":"http://192.168.192.128:8888/group1/M00/00/00/wKjAgF2C7aqAcJNzAAFRSnsPpGY738.png","thumbImagePath":"http://192.168.192.128:8888/group1/M00/00/00/wKjAgF2C7aqAcJNzAAFRSnsPpGY738_96x128.png"}
        return map;
    }

}

測試類

    @Autowired
    private UploadToFastDFS uploadToFastDFS;

    @Test
    public void contextLoads() throws IOException {
        FileInputStream in = new FileInputStream("3d4cdbb229559df79d93a30e27f8d521.png");
        uploadToFastDFS.uploadFile(in, in.getChannel().size(), "png");
    }

 

 瀏覽器訪問

http://192.168.192.128:8888/group1/M00/00/00/wKjAgF2C4zaAEFIXAAFRSnsPpGY325.png

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM