美文网首页Docker 编程杂货铺
Docker Swarm 使用NFS数据共享

Docker Swarm 使用NFS数据共享

作者: 会动的木头疙瘩儿 | 来源:发表于2019-01-15 15:56 被阅读48次

    主要解决在集群中不同主机之间的容器数据共享,当前以单主机的nfs为例,你也可以搭建分布式文件系统
    docker swarm 集群的搭建请看前面的文章Docker Swarm集成搭建

    1. 搭建nfs

    • centos 7 系统

    1.1. 安装

    yum -y install nfs-utils rpcbind
    

    1.2. 配置文件

    nfs 的配置文件 /etc/expots
    共享目录赋予权限:chmod 755 /home/data

    vim /etc/exports
    /root/share 172.16.10.0/24(rw,async,insecure,anonuid=1000,anongid=1000,no_root_squash)
    

    配置生效

    exportfs -rv
    

    配置文件说明:

    /root/share 为共享目录

    * 192.168.1.0/24 可以为一个网段,一个IP,也可以是域名,域名支持通配符 如: *.com
    * rw:read-write,可读写;
    * ro:read-only,只读;
    * sync:文件同时写入硬盘和内存;
    * async:文件暂存于内存,而不是直接写入内存;
    * no_root_squash:NFS客户端连接服务端时如果使用的是root的话,那么对服务端分享的目录来说,也拥有root权限。显然开启这项是不安全的。
    * root_squash:NFS客户端连接服务端时如果使用的是root的话,那么对服务端分享的目录来说,拥有匿名用户权限,通常他将使用nobody或nfsnobody身份;
    * all_squash:不论NFS客户端连接服务端时使用什么用户,对服务端分享的目录来说都是拥有匿名用户权限;
    * anonuid:匿名用户的UID值
    * anongid:匿名用户的GID值。备注:其中anonuid=1000,anongid=1000,为此目录用户web的ID号,达到连接NFS用户权限一致。
    * defaults 使用默认的选项。默认选项为rw、suid、dev、exec、auto nouser与async。
    * atime 每次存取都更新inode的存取时间,默认设置,取消选项为noatime。
    * noatime 每次存取时不更新inode的存取时间。
    * dev 可读文件系统上的字符或块设备,取消选项为nodev。
    * nodev 不读文件系统上的字符或块设备。
    * exec 可执行二进制文件,取消选项为noexec。
    * noexec 无法执行二进制文件。
    * auto 必须在/etc/fstab文件中指定此选项。执行-a参数时,会加载设置为auto的设备,取消选取为noauto。
    * noauto 无法使用auto加载。
    * suid 启动set-user-identifier设置用户ID与set-group-identifer设置组ID设置位,取消选项为nosuid。
    * nosuid 关闭set-user-identifier设置用户ID与set-group-identifer设置组ID设置位。
    * user 普通用户可以执行加载操作。
    * nouser 普通用户无法执行加载操作,默认设置。
    * remount 重新加载设备。通常用于改变设备的设置状态。
    * rsize 读取数据缓冲大小,默认设置1024。–影响性能
    * wsize 写入数据缓冲大小,默认设置1024。
    * fg 以前台形式执行挂载操作,默认设置。在挂载失败时会影响正常操作响应。
    * bg 以后台形式执行挂载操作。
    * hard 硬式挂载,默认设置。如果与服务器通讯失败,让试图访问它的操作被阻塞,直到服务器恢复为止。
    * soft 软式挂载。服务器通讯失败,让试图访问它的操作失败,返回一条出错消息。这项功能对于避免进程挂在无关紧要的安装操作上来说非常有用。
    * retrans=n 指定在以软方式安装的文件系统上,在返回一条出错消息之前重复发出请求的次数。
    * nointr 不允许用户中断,默认设置。
    * intr 允许用户中断被阻塞的操作并且让它们返回一条出错消息。
    * timeo=n 设置请求的超时时间以十分之一秒为单位。
    * tcp 传输默认使用udp,可能出现不稳定,使用proto=tcp更改传输协议。客户端参考mountproto=netid
    

    1.3. 启动nfs服务

    systemctl enable rpcbind
    systemctl start rpcbind
    systemctl enable nfs-server
    systemctl start nfs-server
    

    确认NFS服务器启动成功

    [root@master opt]# rpcinfo -p
       program vers proto   port  service
        100024    1   udp  50813  status
        100024    1   tcp   6021  status
        100005    1   udp  20048  mountd
        100005    1   tcp  20048  mountd
        100005    2   udp  20048  mountd
        100005    2   tcp  20048  mountd
        100005    3   udp  20048  mountd
        100005    3   tcp  20048  mountd
        100003    3   tcp   2049  nfs
        100003    4   tcp   2049  nfs
        100227    3   tcp   2049  nfs_acl
        100003    3   udp   2049  nfs
        100003    4   udp   2049  nfs
        100227    3   udp   2049  nfs_acl
        100021    1   udp  35715  nlockmgr
        100021    3   udp  35715  nlockmgr
        100021    4   udp  35715  nlockmgr
        100021    1   tcp   5350  nlockmgr
        100021    3   tcp   5350  nlockmgr
        100021    4   tcp   5350  nlockmgr
    [root@master opt]# cat /var/lib/nfs/etab
    /root/share 172.16.10.0/24(rw,sync,wdelay,hide,nocrossmnt,secure,root_squash,all_squash,no_subtree_check,secure_locks,acl,no_pnfs,anonuid=1000,anongid=1000,sec=sys,rw,secure,root_squash,all_squash)
    

    2. 将nfs应用到docker swarm中

    在现有的集群中

    IP 角色
    172.16.10.172 master
    172.16.10.173 node1
    172.16.10.174 node2

    2.1. 以手动创建docker service的方式

    先手动创建docker volume volume_create/#examples

    docker volume create --driver local \
        --opt type=nfs \
        --opt o=addr=172.16.10.172,rw \
        --opt device=:/root/share \
        foo33
    

    --opt device=:/root/share 指向共享目录,也可以是共享目录下的子目录

    查看一下volume

    [root@master share]# docker volume ls
    DRIVER              VOLUME NAME
    local               4c1cbdd6e3d41d1a1d51947b2790d85ed43633de5f1b67d49c178277fa7eff08
    local               681da6e4b4207705fd8a3b8da280cbec12d284e626b548bea8af0db5522b72db
    local               682ad60281ad3e68321f3a7828c7ad2df8873a68d2f94ee602700498392fb252
    local               efb6b51422ec168075cc207e7d7e01a7cec65cda6736b4ba8d2617213a258eff
    local               elk_esdata
    local               f5ce2d5d45b11d745e85633e87a7ba38fab09afcde5cda0291bb6cfa84da010c
    local               f7c089ebff176bb98b5055d5762bc07c110f67cec74d87f4496e88cb3acaae27
    local               f6497e59073da936a28bdc1ba646390f9ef937551ee6bbeaa72db3b851114bbb
    local               faa50b0f8bfccd96362b7306af57ccb79ef2bf6fceba9720f4bd0c45bb842f4f
    local               foo2
    local               foo33
    local               myvol2
    

    看到了docker volume列表中有foo33,查看volume详细

    [root@master share]# docker volume inspect foo33
    [
        {
            "CreatedAt": "2019-01-15T11:13:45+08:00",
            "Driver": "local",
            "Labels": {},
            "Mountpoint": "/var/lib/docker/volumes/foo33/_data",
            "Name": "foo33",
            "Options": {
                "device": ":/root/share",
                "o": "addr=172.16.10.172,rw",
                "type": "nfs"
            },
            "Scope": "local"
        }
    ]
    

    可以看出nfs 的/root/share 被挂载到了当前主要的 /var/lib/docker/volumes/foo33/_data

    这里有个问题,如果不用docker compose创建服务的话,你必须在服务所在的节点上创建docker volume
    我的服务要创建3个副本,服务可能会分布到三个主机上,那么我在三个主机上都创建docker volume create foo33使用上面的代码在其它两台主机上都执行一遍

    [root@node2 ~]# docker volume ls
    DRIVER              VOLUME NAME
    省略... 
    local               foo33
    省略...
    
    [root@node1 share]# docker volume ls
    DRIVER              VOLUME NAME
    省略... 
    local               foo33
    省略...
    

    然后发布服务

    docker service create \
      --name test-nginx-nfs \
      --publish 84:80 \
      --mount type=volume,source=foo33,destination=/app/share \
      --replicas 3 \
      nginx
    

    服务名 test-nginx-nfs 把foo33安装到容器的/app/share目录中

    [root@master share]# docker service create   --name test-nginx-nfs   --publish 84:80   --mount type=volume,source=foo33,destination=/app/share   --replicas 3   nginx
    ska2oere0k3e6kbi6i5a5hnfa
    overall progress: 3 out of 3 tasks
    1/3: running   [==================================================>]
    2/3: running   [==================================================>]
    3/3: running   [==================================================>]
    verify: Service converged
    

    查看服务分布的节点:

    [root@master share]# docker service ps test-nginx-nfs
    ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE            ERROR               PORTS
    xgpgfgfk7jo4        test-nginx-nfs.1    nginx:latest        node2               Running             Running 47 seconds ago
    xy8do6go0nrn        test-nginx-nfs.2    nginx:latest        node1               Running             Running 47 seconds ago
    56zfy845yxo3        test-nginx-nfs.3    nginx:latest        master              Running             Running 46 seconds ago
    

    抽一个节点看 node1
    我在nfs服务搭建成功后在/root/share目录中放了一个文件名叫index.html的文件

    [root@master share]# pwd
    /root/share
    [root@master share]# ls
    index.html
    

    node1
    查看宿主机挂载目录

    [root@node1 /]# docker volume inspect foo33
    [
        {
            "CreatedAt": "2019-01-15T11:13:45+08:00",
            "Driver": "local",
            "Labels": {},
            "Mountpoint": "/var/lib/docker/volumes/foo33/_data",
            "Name": "foo33",
            "Options": {
                "device": ":/root/share",
                "o": "addr=172.16.10.172,rw",
                "type": "nfs"
            },
            "Scope": "local"
        }
    ]
    [root@node1 /]# cd /var/lib/docker/volumes/foo33/_data
    [root@node1 _data]# ls
    index.html
    [root@node1 _data]#
    

    查看容器目录

    [root@node1 share]# docker ps
    CONTAINER ID        IMAGE                   COMMAND                  CREATED             STATUS              PORTS                                                 NAMES
    e81de34902f4        nginx:latest            "nginx -g 'daemon of…"   10 seconds ago      Up 8 seconds        80/tcp                                                test-nginx-nfs.2.ed05o9nezwpppw8ov7jtvjagv
    bf5550586e1e        rabbitmq:3-management   "docker-entrypoint.s…"   7 weeks ago         Up 7 weeks          4369/tcp, 5671-5672/tcp, 15671-15672/tcp, 25672/tcp   rabbit_rabbit3.1.3vn2fjjux9jtaeclutiietzys
    [root@node1 share]# docker exec -it e81de34902f4 bash
    root@e81de34902f4:/# cd app/share/
    root@e81de34902f4:/app/share# ls
    index.html
    root@e81de34902f4:/app/share#
    

    2.2. 使用 编排的方式发布service

    docker compose文档

    version: '3.3'
    
    services:
    
      nginx-test5:
        image: nginx:latest
        deploy:
          mode: replicated
          replicas: 1
          restart_policy:
            condition: on-failure
        ports:
          - "88:80"
        networks:
          my-overlay-network:
            aliases:
              - nginx-test5
        volumes:
          - "foo_new:/app/share"
    
    
    volumes:
      foo_new:
        driver: local
        driver_opts:
          type: "nfs"
          o: "addr=172.16.10.172,rw"
          device: ":/root/share"
    
    networks:
      my-overlay-network:
        driver: overlay
    

    使用docker compose编排不需要分别在每一个主机上手动创建docker volume

    发布服务

    [root@master opt]# docker stack deploy -c docker-compose.yml app
    Creating network app_my-overlay-network
    Creating service app_nginx-test5
    [root@master opt]# docker stack ls
    NAME                SERVICES            ORCHESTRATOR
    app                 1                   Swarm
    rabbit              3                   Swarm
    [root@master opt]# docker stack services app
    ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
    ighafroycq0c        app_nginx-test5     replicated          3/3                 nginx:latest        *:88->80/tcp
    [root@master opt]# docker service ps app_nginx-test5
    ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE            ERROR               PORTS
    54gdcmfxh218        app_nginx-test5.1   nginx:latest        master              Running             Running 13 seconds ago
    jt2v0mlgqwup        app_nginx-test5.2   nginx:latest        node2               Running             Running 15 seconds ago
    z039pxqu4sbl        app_nginx-test5.3   nginx:latest        node1               Running             Running 14 seconds ago
    [root@master opt]#
    

    查看docker volume

    [root@master opt]# docker volume ls
    DRIVER              VOLUME NAME
    省略......
    local               app_foo_new
    local               foo33
    local               myvol2
    local               test-vol
    [root@master opt]# docker volume inspect app_foo_new
    [
        {
            "CreatedAt": "2019-01-15T11:13:45+08:00",
            "Driver": "local",
            "Labels": {
                "com.docker.stack.namespace": "app"
            },
            "Mountpoint": "/var/lib/docker/volumes/app_foo_new/_data",
            "Name": "app_foo_new",
            "Options": {
                "device": ":/root/share",
                "o": "addr=172.16.10.172,rw",
                "type": "nfs"
            },
            "Scope": "local"
        }
    ]
    [root@master opt]#
    

    抽查一个看看node2

    查看本机挂载:

    [root@node2 ~]# docker volume ls
    DRIVER              VOLUME NAME
    省略......
    local               app_foo_new
    local               foo2
    local               foo33
    local               myvol2
    local               test-vol
    [root@node2 ~]# docker volume inspect app_foo_new
    [
        {
            "CreatedAt": "2019-01-15T11:13:45+08:00",
            "Driver": "local",
            "Labels": {
                "com.docker.stack.namespace": "app"
            },
            "Mountpoint": "/var/lib/docker/volumes/app_foo_new/_data",
            "Name": "app_foo_new",
            "Options": {
                "device": ":/root/share",
                "o": "addr=172.16.10.172,rw",
                "type": "nfs"
            },
            "Scope": "local"
        }
    ]
    [root@node2 ~]# cd /var/lib/docker/volumes/app_foo_new/_data
    [root@node2 _data]# ls
    index.html
    [root@node2 ~]#
    

    查看容器:

    [root@node2 _data]# docker ps
    CONTAINER ID        IMAGE                   COMMAND                  CREATED             STATUS              PORTS                                                 NAMES
    7e333092c3cf        nginx:latest            "nginx -g 'daemon of…"   5 minutes ago       Up 5 minutes        80/tcp                                                app_nginx-test5.2.jt2v0mlgqwupvv5lag7epriwo
    91d318ee2b04        rabbitmq:3-management   "docker-entrypoint.s…"   7 weeks ago         Up 7 weeks          4369/tcp, 5671-5672/tcp, 15671-15672/tcp, 25672/tcp   rabbit_rabbit2.1.ykbawm133w4c9rzsrmlm9mkhp
    [root@node2 _data]# docker exec -it 7e333092c3cf bash
    root@7e333092c3cf:/# cd app/share/
    root@7e333092c3cf:/app/share# ls
    index.html
    root@7e333092c3cf:/app/share#
    

    总结:环境配置比较简单,难的是nfs服务的读写,随着业务和流量的增加,读写量增大,可能需要分布式的文件系统,分布式的文件系统又改如何何理的使用

    相关文章

      网友评论

        本文标题:Docker Swarm 使用NFS数据共享

        本文链接:https://www.haomeiwen.com/subject/pofydqtx.html