分类目录归档:Docker

使用docker部署3节点etcd集群

在每个节点输入以下变量,根据实际情况修改主机名和IP
为了将etcd API暴露给docker主机外的客户端,必须使用docker inspect命令获得容器的IP来配置,这里使用了–net=host主机网络的方式来简化这一步骤。

ETCD_VERSION=latest
TOKEN=my-etcd-token
CLUSTER_STATE=new
NAME_1=etcd-node1
NAME_2=etcd-node2
NAME_3=etcd-node3
HOST_1=192.168.1.101
HOST_2=192.168.1.102
HOST_3=192.168.1.103
CLUSTER=${NAME_1}=http://${HOST_1}:2380,${NAME_2}=http://${HOST_2}:2380,${NAME_3}=http://${HOST_3}:2380
DATA_DIR=/var/lib/etcd

在节点1输入以下命令

THIS_NAME=${NAME_1}
THIS_IP=${HOST_1}
docker run -d \
  --net=host \
  --volume=${DATA_DIR}:/etcd-data \
  --name etcd quay.io/coreos/etcd:${ETCD_VERSION} \
  /usr/local/bin/etcd \
  --data-dir=/etcd-data --name ${THIS_NAME} \
  --initial-advertise-peer-urls http://${THIS_IP}:2380 --listen-peer-urls http://${THIS_IP}:2380 \
  --advertise-client-urls http://${THIS_IP}:2379 --listen-client-urls http://${THIS_IP}:2379 \
  --initial-cluster ${CLUSTER} \
  --initial-cluster-state ${CLUSTER_STATE} --initial-cluster-token ${TOKEN}

在节点2输入以下命令

THIS_NAME=${NAME_2}
THIS_IP=${HOST_2}
docker run -d \
  --net=host \
  --volume=${DATA_DIR}:/etcd-data \
  --name etcd quay.io/coreos/etcd:${ETCD_VERSION} \
  /usr/local/bin/etcd \
  --data-dir=/etcd-data --name ${THIS_NAME} \
  --initial-advertise-peer-urls http://${THIS_IP}:2380 --listen-peer-urls http://${THIS_IP}:2380 \
  --advertise-client-urls http://${THIS_IP}:2379 --listen-client-urls http://${THIS_IP}:2379 \
  --initial-cluster ${CLUSTER} \
  --initial-cluster-state ${CLUSTER_STATE} --initial-cluster-token ${TOKEN}

在节点3输入以下命令

THIS_NAME=${NAME_3}
THIS_IP=${HOST_3}
docker run -d \
  --net=host \
  --volume=${DATA_DIR}:/etcd-data \
  --name etcd quay.io/coreos/etcd:${ETCD_VERSION} \
  /usr/local/bin/etcd \
  --data-dir=/etcd-data --name ${THIS_NAME} \
  --initial-advertise-peer-urls http://${THIS_IP}:2380 --listen-peer-urls http://${THIS_IP}:2380 \
  --advertise-client-urls http://${THIS_IP}:2379 --listen-client-urls http://${THIS_IP}:2379 \
  --initial-cluster ${CLUSTER} \
  --initial-cluster-state ${CLUSTER_STATE} --initial-cluster-token ${TOKEN}

全部执行完后使用以下命令查看集群节点信息

docker exec etcd /usr/local/bin/etcdctl --endpoints=http://${HOST_1}:2379 member list
20c4dbd9ca01c9fc: etcd-node-2 peerURLs=http://192.168.1.103:2380 clientURLs=http://192.168.1.103:2379 isLeader=false
52b6c5eaedead574: etcd-node-1 peerURLs=http://192.168.1.102:2380 clientURLs=http://192.168.1.102:2379 isLeader=false
7623946005cf410f: etcd-node-0 peerURLs=http://192.168.1.101:2380 clientURLs=http://192.168.1.101:2379 isLeader=true

更改Docker的lvm挂载方式从loop-vm至direct-lvm

Docker安装后默认在/var/lib/docker/devicemapper/devicemapper目录下生成data和metadata两个文件用于存放docker的数据,然而这种默认的loop-lvm挂载方式不适合生产环境使用,并且你也会收到docker的如下提示,生产环境应改为direct-lvm方式。
WARNING: devicemapper: usage of loopback devices is strongly discouraged for production use.
Use `--storage-opt dm.thinpooldev` to specify a custom block storage device.

以下是更改docker device mapper的方法

方法一: 允许Docker配置direct-lvm模式
编辑/etc/docker/daemon.json文件(如果该文件不存在则进行创建),参数表如下
dm.directlvm_device:块设备路径(必须)
dm.thinp_percent:块设备使用比率,默认95
dm.thinp_metapercent:元数据使用比率,默认1
dm.thinp_autoextend_threshold:自动扩容阈值,默认80
dm.thinp_autoextend_percent:自动扩容比率,20
dm.directlvm_device_force:强制格式化设备,默认false
以下为示例

{
  "storage-driver": "devicemapper",
  "storage-opts": [
    "dm.directlvm_device=/dev/xdf",
    "dm.thinp_percent=95",
    "dm.thinp_metapercent=1",
    "dm.thinp_autoextend_threshold=80",
    "dm.thinp_autoextend_percent=20",
    "dm.directlvm_device_force=false"
  ]
}

重启docker以生效

sudo systemctl restart docker

方法二: 手工配置direct-lvm模式
停止docker服务

sudo systemctl stop docker

安装必要的软件包

sudo yum install -y device-mapper-persistent-data lvm2

创建pv,示例中/dev/sdb需改为对应物理卷

sudo pvcreate /dev/sdb

创建用于docker的vg

sudo vgcreate vgdocker /dev/sdb

创建两个lv,用于data和metadata,最后两个参数指定了该thin pool允许自动扩容能到达的VG百分比

sudo lvcreate --wipesignatures y -n thinpool vgdocker -l 95%VG
sudo lvcreate --wipesignatures y -n thinpoolmeta vgdocker -l 1%VG

将lv转换为thin pool

sudo lvconvert -y --zero n -c 512K \
--thinpool vgdocker/thinpool \
--poolmetadata vgdocker/thinpoolmeta

修改自动扩容配置,其中thin_pool_autoextend_threshold为自动扩容阈值,thin_pool_autoextend_percent为每次扩容的比率

sudo cat <<EOF > /etc/lvm/profile/vgdocker-thinpool.profile
activation {
  thin_pool_autoextend_threshold=80
  thin_pool_autoextend_percent=20
}
EOF

应用LVM profile

sudo lvchange --metadataprofile vgdocker-thinpool vgdocker/thinpool

启动lv监控来实现自动扩容

sudo lvs -o+seg_monitor

移动旧docker数据以便恢复

mkdir /var/lib/docker.bak
mv /var/lib/docker/* /var/lib/docker.bak

修改/etc/docker/daemon.json(如果该文件不存在则进行创建)

{
    "storage-driver": "devicemapper",
    "storage-opts": [
    "dm.thinpooldev=/dev/mapper/vgdocker-thinpool",
    "dm.use_deferred_removal=true",
    "dm.use_deferred_deletion=true"
    ]
}

启动docker服务

sudo systemctl start docker

确认已使用pool

docker info | grep Pool

确认无问题后删除旧docker数据

rm -rf /var/lib/docker.bak

逻辑卷的扩容
扩展vg,/dev/sdc为新加的物理卷

sudo vgextend docker /dev/sdc

扩展lv,并通过docker info命令确认扩容情况

sudo lvextend -l+100%FREE -n vgdocker/thinpool
docker info

重启后的激活
若系统重启后发现docker无法启动,能需要使用以下命令重新激活lv

sudo lvchange -ay vgdocker/thinpool

使用Docker部署单节点etcd

为了能使Docker外的系统访问到etcd服务,需要通过docker inspect获得容器的IP。或者也可以通过参数–net=host使容器使用主机的网络。

export NODE1=192.168.1.21
docker run \
  -p 2379:2379 \
  -p 2380:2380 \
  --volume=${DATA_DIR}:/etcd-data \
  --name etcd quay.io/coreos/etcd:latest \
  /usr/local/bin/etcd \
  --data-dir=/etcd-data --name node1 \
  --initial-advertise-peer-urls http://${NODE1}:2380 --listen-peer-urls http://${NODE1}:2380 \
  --advertise-client-urls http://${NODE1}:2379 --listen-client-urls http://${NODE1}:2379 \
  --initial-cluster node1=http://${NODE1}:2380
etcdctl --endpoints=http://${NODE1}:2379 member list

将容器作为systemd服务来运行

编写/etc/systemd/system/myapp.service内容如下

[Unit]
Description=MyApp
After=docker.service
Requires=docker.service

[Service]
TimeoutStartSec=0
ExecStartPre=-/usr/bin/docker kill busybox1
ExecStartPre=-/usr/bin/docker rm busybox1
ExecStartPre=/usr/bin/docker pull busybox
ExecStart=/usr/bin/docker run --name busybox1 busybox /bin/sh -c "trap 'exit 0' INT TERM; while true; do echo Hello World; sleep 1; done"

[Install]
WantedBy=multi-user.target

配置作为服务自动启动
sudo systemctl enable myapp.service
sudo systemctl start myapp.service
检查服务运行状态
journalctl -f -u hello.service

Docker Compose安装

两进制安装:

sudo curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-$(uname -s)-$(uname -m) \
-o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
$ docker-compose --version
docker-compose version 1.21.2, build a133471

pip安装:

pip install docker-compose

在CentOS 7上安装Docker CE

安装所需的包:

yum install -y yum-utils device-mapper-persistent-data lvm2

安装docker的repo:

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

安装docker ce:

yum install docker-ce

启动docker:

systemctl start docker

验证docker:

docker run hello-world

配置docker国内镜像:
编辑/etc/docker/daemon.json,添加以下一行

{
  "registry-mirrors": ["https://registry.docker-cn.com"]
}

重新启动docker:

systemctl restart docker

如要安装指定的旧版本则需要使用rpm安装,比如安装17.03.2.ce版本

yum remove -y docker-ce container-selinux
rm -rf /var/lib/docker
curl -O https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/stable/Packages/docker-ce-17.03.2.ce-1.el7.centos.x86_64.rpm
curl -O https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/stable/Packages/docker-ce-selinux-17.03.2.ce-1.el7.centos.noarch.rpm
rpm -Uvh docker-ce*17.03.2.ce*.rpm