需求介绍

某SaaS类项目对私有容器平台提出了如下需求:

  • 主机数量小于10台物理机

  • 支持跨主机的容器编排

  • 支持服务类应用容器服务集群的负载均衡、横向扩展

  • 支持数据持久化和跨主机使用

容器管理平台

针对上述需求,以及实际的运维资源等人力资源状况的了解,在衡量Mesos、Kubernetes的复杂度、人力资源以及技能需求之后,最终选择了docker swarm作为容器管理及编排平台。

Docker swarm mode的好处是:

  • 易部署,Docker原生支持,无需复杂的部署步骤

  • 易维护,支持多manager节点,无需依赖其他外部组件,因此无需复杂的技能储备

  • 适用于小规模的容器环境,既可以提供类似kubernetes擅长的服务类应用,也可以提供mesos擅长的非服务型计算类应用。

Docker Swarm与ceph集成测试_java

容器平台的网络

在选定采用docker swarm之后,根据Docker官方的v2 plugin列表支持的插件来看,基本上还算是惨不忍睹的状态。仅有近半年不活跃的Kuryr、Contiv和Weave三个网络插件。

  • Kuryr依赖于OpenStack Keystone、 Neutron、 Kuryr以及OpenvSwitch,实际上比较重量级。

  • Contiv需要至少2个网卡,但是Docker plugin已经近半年没有更新了。

  • Weave轻量化,容易部署,因此初步选定先对Weave进行必要的测试。

然而,经过对比Weave 和Docker原生的Overlay网络的测试之后,发现Weave果然以性能差著称,性能仅为Overlay的大约1/5 。

由于该环境主要是为单一SaaS类服务提供基础平台支撑,并不是建立基础的容器私有云平台,因此综合考虑整个容器平台的运维、人员技能等因素,最终选定采用Docker原生Overlay网络。

容器平台的存储

由于项目需求中对持久化存储的需求,结合Docker官方volume plugin列表中的实际情况,虽然Volume的插件相对还是很丰富的,但是实际上多数插件都是各厂商对自家商用存储产品的支持。

同样考虑到运维成本、人员技能、以及底层分布式存储的开放程度、社区活跃程度、产品成熟度以及Docker插件本身的活跃度等方面,最终决定采用的组合是ceph和dell的rexray/rbd插件。

容器平台的UI

由于该项目实际需求以及开发资源等方面的因素,以及在对开源的shipyard和portainer做了对比测试之后,决定选择portainer作为该平台的管理UI。

Docker Swarm与ceph集成测试_java_02

测试环境的部署准备

本文以下部分为针对上述选型的测试环境搭建,不包含具体的功能和性能测试。

准备

  • 三台物理机/虚拟机,文中实际为三台虚拟机。

    • 单网卡即可

    • 有一个额外的硬盘可以用做ceph的osd,文中为/dev/vdb

  • 安装好CentOS7.3,文中主机名如下

    • ceph-0

    • ceph-1

    • ceph-2

  • 安装必要的基础软件包,如:bash yum -y install vim wget curl yum-utils bash-completion bash-completion-extras epel-release

  • 为方便操作,建议设置好三台机器的ssh keypair登陆,是其中一台作为主节点的机器可以免密码登陆其他机器,本文中ceph-0为主节点

  • 测试环境建议禁用selinux,并且将firewall设置为开放所有端口bash firewall-cmd --permanent --zone=public --set-target=ACCEPT

注意,

 以下所有操作以root执行。

安装Docker

在所有三台机器上执行如下步骤。

  1. 配置docker官方的yum源

    basn yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo

  2. 安装docker-ce

    bash yum -y -q makecache fast yum -y -q install docker-ce

  3. 配置docker-ce

    ```bash systemctl enable docker systemctl start docker && systemctl stop docker

    cat > /etc/docker/daemon.json << __EOF { "registry-mirrors": ["https://registry.docker-cn.com"], "storage-driver": "overlay", "log-driver": "json-file", "log-opts": { "max-size": "3m", "max-file": "3" } } __EOF

    systemctl start docker ```

Ceph及Ceph插件部署

安装ceph-mon

  1. 在所有三台机器上,获取ceph的docker镜像

    bash docker pull ceph/daemon:tag-build-master-kraken-centos-7

  2. 在第一台机器ceph-0上,部署ceph-mon-0

    ```bash getlocalip() { localip=$(ip -4 route get 8.8.8.8 | awk -v FS="src " '/src/ {print $2}') printf ${localip} }

    export ceph_image="ceph/daemon:tag-build-master-kraken-centos-7"

    三台机器上的cephnodename分别为ceph-mon-0, ceph-mon-1, ceph-mon-2

    export cephnodename="ceph-mon-0" export cephnodeip=$(getlocalip) export cephpubnet=$(echo ${cephnodeip} | awk -F '.' '{print $1"."$2"."$3".0/24"}')

    docker run \ --detach \ --restart always \ --name ${cephnodename} \ --net=host \ --volume /etc/ceph:/etc/ceph \ --volume /var/lib/ceph/:/var/lib/ceph/ \ --env MONIP=${cephnodeip} \ --env CEPHPUBLICNETWORK=${cephpubnet} \ --label node.type=ceph \ --label node.role=mon \ ${cephimage} \ mon ```

  3. 将第一台机器上ceph-mon-0的配置文件复制到其他两台机器

    ```bash iplist=( <ipofceph-1> <ipofceph-2> ) for ip in ${iplist[@]}; do echo "... cleanning up $ip ..." ssh $ip "rm -rf /etc/ceph/; rm -rf /var/lib/ceph/" echo "... copy /etc/ceph to $ip ..." scp -r /etc/ceph/ $ip:/etc/ #ssh $ip "mkdir -p /etc/ceph/" #scp -r /etc/ceph/ceph* $ip:/etc/ceph/ #ssh $ip "mv -f /etc/ceph/ceph.conf /etc/ceph/ceph.conf.bak"

    echo "... copy /var/lib/ceph/bootstrap* to $ip ..."
    ssh $ip "mkdir -p /var/lib/ceph/"
    scp -r /var/lib/ceph/bootstrap* $ip:/var/lib/ceph/

    done ```

  4. 在其他两台机器上部署ceph-mon, 重复步骤2中的命令,注意修改容器名为ceph-mon-1, ceph-mon-2

安装ceph-osd

  1. 在全部三台机器上执行,如下命令,安装ceph-osd,注意修改ceph_node_name

    注意, 千万不要使用OSD_FORCE_ZAP=1,否则每次重启容器,磁盘都会被清空,会成为一个全新的osd节点。

    ```bash

    !/bin/bash

    export ceph_image="ceph/daemon:tag-build-master-kraken-centos-7"

    注意修改cephnodename分别为ceph-osd-0, ceph-osd-1, ceph-osd-2

    export cephnodename="ceph-osd-0" export cephosddev="/dev/vdb"

    docker run \ --rm \ --privileged=true \ --name zapping \ --volume /dev/:/dev/ \ --env OSDDEVICE=${cephosd_dev} \ ${cephimage} \ zapdevice 2>&1 > /dev/null

    docker run \ --detach \ --restart always \ --name ${cephnodename} \ --net=host \ --pid=host \ --privileged=true \ --volume /etc/ceph:/etc/ceph \ --volume /var/lib/ceph/:/var/lib/ceph/ \ --volume /dev/:/dev/ \ --env OSDDEVICE=${cephosddev} \ --env OSDTYPE=disk \ --label node.type=ceph \ --label node.role=osd \ ${ceph_image} \ osd

    ```

安装ceph-mds

在第一个服务器ceph-0上安装ceph-mds。该服务按需安装,不是必须。测试环境中,该服务为单点。

注意,

由于docker swarm只会采用ceph-rbd来提供volume服务,因此,实际在本测试环境中并不需要ceph-mds。


```bash

!/bin/bash

export cephimage="ceph/daemon:tag-build-master-kraken-centos-7" export cephnode_name="ceph-mds-0"

docker run \ --detach \ --restart always \ --name ${cephnodename} \ --net=host \ --volume /etc/ceph:/etc/ceph \ --volume /var/lib/ceph/:/var/lib/ceph/ \ --env CEPHFSCREATE=1 \ --label node.type=ceph \ --label node.role=mds \ ${cephimage} \ mds ```

安装ceph-rgw

在第一个服务器ceph-0上安装ceph-rgw,该服务按需安装,不是必须。测试环境中,该服务为单点。

注意,

由于docker swarm只会采用ceph-rbd来提供volume服务,因此,实际在本测试环境中并不需要ceph-rgw。

```bash

!/bin/bash

export cephimage="ceph/daemon:tag-build-master-kraken-centos-7" export cephnode_name="ceph-rgw-0"

docker run \ --detach \ --restart always \ --name ${cephnodename} \ --net host \ --volume /etc/ceph:/etc/ceph \ --volume /var/lib/ceph/:/var/lib/ceph/ \ --label node.type=ceph \ --label node.role=rgw \ ${ceph_image} \ rgw ```

安装rexray/rbd插件

  1. 在所有三台服务器上执行如下命令安装插件

    bash docker plugin install rexray/rbd \ RBD_DEFAULTPOOL=rbd

  2. 可以通过docker volume来测试ceph插件是否正常工作, 如

    ```bash

    通过docker plugin ls来查看插件工作状态,确保处于enable状态

    docker plugin ls

    通过docker volume create来创建volume

    docker volume create --driver rexray/rbd:latest cephvol1 docker volum ls ```

  3. 在所有三台服务器上安装rbd内核模块

    ```bash rpm --import 'https://download.ceph.com/keys/release.asc'

    cat > /etc/yum.repos.d/ceph.repo << __EOF [ceph] name=Ceph packages for \$basearch baseurl=https://download.ceph.com/rpm-kraken/el7/\$basearch enabled=1 priority=2 gpgcheck=1 gpgkey=https://download.ceph.com/keys/release.asc

    [ceph-noarch] name=Ceph noarch packages baseurl=https://download.ceph.com/rpm-kraken/el7/noarch enabled=1 priority=2 gpgcheck=1 gpgkey=https://download.ceph.com/keys/release.asc

    [ceph-source] name=Ceph source packages baseurl=https://download.ceph.com/rpm-kraken/el7/SRPMS enabled=0 priority=2 gpgcheck=1 gpgkey=https://download.ceph.com/keys/release.asc

    __EOF

    yum makecache fast yum -y install rbd-nbd

    modprobe rbd

    echo "rbd" > /etc/modules-load.d/rbd.conf ```

  4. 通过docker run命令来测试容器挂载volume,如

    bash CON_NAME=${CON_NAME:="demo-1"} VOL_NAME=${VOL_NAME:="demo-vol-1"} docker run -itd \ --name ${CON_NAME} \ --volume-driver rexray/rbd \ --volume ${VOL_NAME}:/data/ \ alpine:3.6 \ /bin/sh

    Docker Swarm与ceph集成测试_java_03

启用docker swarm

  1. 在第一台服务器ceph-0上执行docker swarm init初始化swarm集群

  2. 在其他两台服务器上执行docker swarm join加入swarm集群

  3. 可以在第一台服务器ceph-1上通过docker node ls确认集群状态

安装portainer

  1. 在第一台机器上执行如下命令将portainer以swarm servic的形式部署在管理节点上。

    ```bash

    !/bin/bash

    containername="portainer" containerimage="portainer/portainer:latest"

    docker service create \ --name ${containername} \ --publish 9000:9000 \ --constraint 'node.role == manager' \ --mount type=bind,src=//var/run/docker.sock,dst=/var/run/docker.sock \ --mount type=volume,src=portainer-data,dst=/data,volume-driver=rexray/rbd:latest \ ${containerimage} \ -H unix:///var/run/docker.sock ```

  2. 在其他两台机器上,部署docker-proxy来暴露docker api

    ```bash

    !/bin/bash

    containerimage="shipyard/docker-proxy:latest" containername="portainer-proxy"

    docker run \ -ti \ --detach \ --publish 2375:2375 \ --hostname=${HOSTNAME} \ --restart=always \ --name ${containername} \ --volume /var/run/docker.sock:/var/run/docker.sock \ --env PORT=2375 \ ${containerimage} ```

  3. 登陆portainer的webui,添加其他两台机器的endpoint就可以通过portainer管理所有的容器资源了,包含docker swarm的service资源。

注意,

 portainer目前的版本1.13.6不能正常通过rexray/rbd:latest插件来创建volume,但是可以正使用由该插件创建出来的volume。portainer的作者已经在开发新的版本修正这个问题,等待合并到下一个release版本。

Docker Swarm与ceph集成测试_java_04