分布式 MinIO s3 云存储实践

MinIO 是一款优秀的开源云存储服务,兼容亚马逊 S3 云存储。它最适合存储非结构化数据,如照片,视频,日志文件,备份和容器/ VM映像。 对象的大小可以从几KB到最大5TB。

MinIO 是一个轻量级服务器,可以与应用程序堆栈捆绑在一起,类似于 NodeJS,Redis 和 MySQL。

通过 docker 运行

docker pull minio/minio
docker run -p 9000:9000 minio/minio server /data

分布式运行实践

minio

要通过分布式方式运行 minio, 需要配置不少于4个的偶数 minio 运行实例。

我们首先编写一个 DockerFile 文件,用于快速配置及运行 minio 实例,再通过 docker-compose.yml 传入执行参数 MINIO_VOLUMES 并运行 docker 实例。

每一个实例对应不同的 MINIO_VOLUMES 参数,例如 hk 实例使用参数:

MINIO_VOLUMES: "https://minio:9199/data/1 https://s3-jp.xdty.org:443/data/2 https://s3-sh.xdty.org:443/data/3 https://s3-tx.xdty.org:443/data/4"

而 jp 实例使用参数:

MINIO_VOLUMES: "https://minio:9199/data/2 https://s3-hk.xdty.org:443/data/1 https://s3-sh.xdty.org:443/data/3 https://s3-tx.xdty.org:443/data/4"

其他节点依次类推,注意这里的节点可以运行在同一个服务器上,例如每个节点实例运行在同一个服务器的不同存储目录下;也可以运行在不同的服务器上。

其中 9199 端口是当前实例 docker 运行监听的端口,由于 minio 分布式实例不能同时使用 HTTP 和 HTTPS ,为了能和其他实例通信,docker 内的实例也启用了 TLS。

最后通过 nginx 作为前端代理,将 minio 服务转到 443 端口。

当所有节点实例运行起来后,会和其他节点实例通信并建立连接。这时当用户上传新文件到某一个节点时,其他节点也会同步数据;在某一个节点增加用户也会同步到其他节点。

更多关于分布式服务的细节请参考官方文档 https://docs.min.io/docs/distributed-minio-quickstart-guide.html

示例代码

如下代码仅供参考,已经包含了所有运行分布式 minio 实例配置文件。

Dockerfile

FROM alpine
MAINTAINER [email protected]

ENV GID=33 UID=33

ADD https://dl.min.io/server/minio/release/linux-amd64/minio /usr/bin/minio

RUN apk \
    --update \
    --no-cache \
    add su-exec \
    ca-certificates \
    openssl \
    tini && \
    chmod +x /usr/bin/minio

COPY run.sh /run.sh

ENV MINIO_VOLUMES "/data"
ENV MINIO_OPTS "server --address 0.0.0.0:9199"
ENV MINIO_ACCESS_KEY "73mPXCPJzhpPLIiFnf"
ENV MINIO_SECRET_KEY "M56OsPqKxBFxNqnmSOBVtfbIziKHMCD8iugu"

VOLUME "/data"
EXPOSE 9199

CMD ["sh", "run.sh"]

run.sh

#!/bin/sh

set -e

mkdir -p /data

if [ ! -d "/certs" ]; then
    mkdir -p /certs
    cd /certs
    openssl genrsa 1024 > private.key
    chmod 400 private.key
    openssl req -new -key private.key -out private.csr -subj "/C=UK/ST=Warwickshire/L=Leamington/O=OrgName/OU=IT Department/CN=minio"
    openssl x509 -req -days 36500 -in private.csr -signkey private.key -out public.crt
    cd -
fi

chown -R $UID:$GID /data /certs

echo "Starting minio..."
exec su-exec $UID:$GID /sbin/tini -- /usr/bin/minio $MINIO_OPTS $MINIO_VOLUMES

docker-compose.yml

version: '3'

services:

  nginx:
    image: xdtianyu/hub:nginx
    restart: always
    container_name: nginx
    volumes:
      - /etc/nginx/conf.d:/etc/nginx/conf.d
      - /etc/nginx/le:/etc/nginx/le
      - /var/www:/var/www

  minio:
    image: xdtianyu/hub:minio
    restart: always
    container_name: minio
    ports:
      - "127.0.0.1:9199:9199"
    volumes:
      - /home/minio/xdty/data:/data
    environment:
      MINIO_ACCESS_KEY: xxxxxxxx
      MINIO_SECRET_KEY: xxxxxxxxxxxxxxxx
      MINIO_OPTS: "-S /certs server --address minio:9199"
      MINIO_VOLUMES: "https://minio:9199/data/1 https://s3-jp.xdty.org:443/data/2 https://s3-sh.xdty.org:443/data/3 https://s3-tx.xdty.org:443/data/4"

nginx 配置文件 s3-xdty.conf

server {
    include listen.conf;

    server_name  s3-jp.xdty.org s3-hk.xdty.org s3-tx.xdty.org s3-sh.xdty.org;

    charset utf-8;

    access_log  /var/log/nginx/$host.access.log;

    client_max_body_size 24M;

    root   /var/www/;

    if ($scheme = http) {
        return 301 https://$http_host$request_uri;
    }

    location / {
        proxy_pass https://minio:9199;
        include proxy_params;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
    }
}

参考

https://github.com/minio/minio

https://docs.min.io/docs/distributed-minio-quickstart-guide.html