暗无天日

=============>DarkSun的个人博客

docker-machine初体验

Docker Machine是Docker官方提供的一个帮助我们在远程机器上安装Docker和在本地安装带Docker的虚拟机的工具。 我们还可以通过docker=machine命令来对远程主机的Docker进行管理。

Docker Machine自带了很多驱动,这些驱动将不同的虚拟机引擎与云服务商与Docker Machine整合在一起。 Docker Machine自带的驱动有:

amazonec2        digitalocean     generic          hyperv           rackspace        virtualbox       vmwarevcloudair
azure            exoscale         google           openstack        softlayer        vmwarefusion     vmwarevsphere

在本地创建带Docker的虚拟机

通过 docker-machine create 命令可以创建主机并安装虚拟机,比如下面命令会创建三个使用VirtualBox驱动的主机并且在每台主机上安装好Docker

docker-machine create --driver virtualbox host1
docker-machine create --driver virtualbox host2
docker-machine create --driver virtualbox host3
Running pre-create checks...
Creating machine...
(host1) Copying /home/lujun9972/.docker/machine/cache/boot2docker.iso to /home/lujun9972/.docker/machine/machines/host1/boot2docker.iso...
(host1) Creating VirtualBox VM...
(host1) Creating SSH key...
(host1) Starting the VM...
(host1) Check network to re-create if needed...
(host1) Waiting for an IP...
Waiting for machine to be running, this may take a few minutes...
Detecting operating system of created instance...
Waiting for SSH to be available...
Detecting the provisioner...
Provisioning with boot2docker...
Copying certs to the local machine directory...
Copying certs to the remote machine...
Setting Docker configuration on the remote daemon...
Checking connection to Docker...
Docker is up and running!
To see how to connect your Docker Client to the Docker Engine running on this virtual machine, run: docker-machine env host1
Running pre-create checks...
Creating machine...
(host2) Copying /home/lujun9972/.docker/machine/cache/boot2docker.iso to /home/lujun9972/.docker/machine/machines/host2/boot2docker.iso...
(host2) Creating VirtualBox VM...
(host2) Creating SSH key...
(host2) Starting the VM...
(host2) Check network to re-create if needed...
(host2) Waiting for an IP...
Waiting for machine to be running, this may take a few minutes...
Detecting operating system of created instance...
Waiting for SSH to be available...
Detecting the provisioner...
Provisioning with boot2docker...
Copying certs to the local machine directory...
Copying certs to the remote machine...
Setting Docker configuration on the remote daemon...
Checking connection to Docker...
Docker is up and running!
To see how to connect your Docker Client to the Docker Engine running on this virtual machine, run: docker-machine env host2
Running pre-create checks...
Creating machine...
(host3) Copying /home/lujun9972/.docker/machine/cache/boot2docker.iso to /home/lujun9972/.docker/machine/machines/host3/boot2docker.iso...
(host3) Creating VirtualBox VM...
(host3) Creating SSH key...
(host3) Starting the VM...
(host3) Check network to re-create if needed...
(host3) Waiting for an IP...
Waiting for machine to be running, this may take a few minutes...
Detecting operating system of created instance...
Waiting for SSH to be available...
Detecting the provisioner...
Provisioning with boot2docker...
Copying certs to the local machine directory...
Copying certs to the remote machine...
Setting Docker configuration on the remote daemon...
Checking connection to Docker...
Docker is up and running!
To see how to connect your Docker Client to the Docker Engine running on this virtual machine, run: docker-machine env host3

同时,你会发现virtualbox创建了名为host1,host2,host3的三台主机

vboxmanage list vms
"winxp_default_1529148278389_22373" {5d100a8e-a670-4f84-8ea4-eb22f3dab94d}
"win7" {dddcdefb-5002-4bcd-bef2-ee37f0ba6197}
"rhel7.5" {bbf01330-070b-4663-b8e3-52734297c112}
"redis-host" {f5576790-7d12-4ee8-884f-7352c04f4e04}
"rhel_default_1532386536492_17873" {449040f4-21ef-436d-8648-a4026a547875}
"centos_default_1532472936791_11249" {86ffd1ee-681a-4062-a233-e29ac966fc81}
"freebsd" {2924b43b-da8b-4f59-ac32-ee4420923055}
"RHEL7" {33e98062-f82e-49df-9a8a-91b0eb31e80d}
"arch_default_1532990644081_68335" {2d5206ba-c07a-4691-8c3b-63e941113f15}
"ctf-tools_default_1533510374954_98487" {edd5c5d6-95e5-47af-a462-1d66aab8e640}
"host1" {ee738687-3981-4582-b2d3-3540a1cbff1c}
"host2" {d2907cef-5018-4476-a6e8-5e7c1c321cfe}
"host3" {222d485e-26c2-46e8-bc6e-cfc490d4c34a}

在远程主机上安装Docker

若远程主机是在Docker Machine支持的云服务商的,那么可以直接通过对应的驱动来帮助安装Docker,方法跟上面很类似。

然若远程主机并不是在云服务商上,或者是Docker Machine所不支持的云服务商,那么可以通过 generic 驱动来进行安装。

在使用 generic 进行远程安装前,我们需要一些准备工作:

  1. 在目标主机创建一个无需输入密码即可sudo操作的用户

    sudo adduser ${user}
    sudo usermod -a -G sudo wheel ${user}
    echo "${user} ALL=(ALL:ALL) NOPASSWD: ALL" >>/etc/sudoers
    
  2. 在目标主机上添加密钥认证,使得登陆远程主机不同输入密码

    ssh-copy-id ${user}@${remote_host}
    

准备工作完成后,我们可以在本地主机上运行下面命令

docker-machine create -d generic \
    --generic-ip-address=xxx.xxx.xxx.xxx \
    --generic-ssh-user=${user} \
    --generic-ssh-key ~/.ssh/id_rsa \
    ${name}

其中 ${name} 就是 Docker-Machine 用来管理目标主机上Docker的一个指代名称。

管理Docker Machine

查看被管主机信息

Docker Machine可以用来列出、检查和升级被管主机,我们可以通过 ls 子命令来获得被管理的机器列表

docker-machine ls
NAME         ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER        ERRORS
host1        -        virtualbox   Running   tcp://192.168.99.100:2376           v18.06.0-ce   
host2        -        virtualbox   Running   tcp://192.168.99.101:2376           v18.06.0-ce   
host3        -        virtualbox   Running   tcp://192.168.99.102:2376           v18.06.0-ce   
redis-host   -        virtualbox   Stopped                                       Unknown       

这个命令列出了每台被管主机的名称、创建时的驱动、状态、以及Docker Daemon访问的URL。 ACTIVE这一列若带星号,则表示这台机器是活跃的,也就是任何在本地运行的docker命令连接上的都是活跃机器上的Docker Daemon。

类似于 docker, 我们也可以使用 inspect 子命令来查看某台主机的配置

docker-machine inspect --format "{{.Driver.IPAddress}}" host2
192.168.99.101

当然,如果只是想看被管主机IP,那么可以直接通过 ip 子命令来查看

docker-machine ip host2
192.168.99.101

升级被管主机

docker-machine upgrade host1
Waiting for SSH to be available...
Detecting the provisioner...
Upgrading docker...
Stopping machine to do the upgrade...
Upgrading machine "host1"...
Copying /home/lujun9972/.docker/machine/cache/boot2docker.iso to /home/lujun9972/.docker/machine/machines/host1/boot2docker.iso...
Starting machine back up...
(host1) Check network to re-create if needed...
(host1) Waiting for an IP...
Restarting docker...

停止被管主机

使用 stop 子命令来停止被管主机

docker-machine stop host2
Stopping "host2"...
Machine "host2" was stopped.

如果使用 stop 子命令迟迟无法关闭被管主机,那么也可以直接使用 kill 命令来强制关机

启动被管主机

使用 start 子命令来启动被停止的主机

docker-machine start host2
Starting "host2"...
(host2) Check network to re-create if needed...
(host2) Waiting for an IP...
Machine "host2" was started.
Waiting for SSH to be available...
Detecting the provisioner...
Started machines may have new IP addresses. You may need to re-run the `docker-machine env` command.

删除被管主机

使用 rm 子命令来删除被管主机

yes|docker-machine rm host3
About to remove host3
WARNING: This action will delete both local reference and remote instance.
Are you sure? (y/n): Successfully removed host3

再次查看一下virtualbox还剩下哪些主机

vboxmanage list vms
"winxp_default_1529148278389_22373" {5d100a8e-a670-4f84-8ea4-eb22f3dab94d}
"win7" {dddcdefb-5002-4bcd-bef2-ee37f0ba6197}
"rhel7.5" {bbf01330-070b-4663-b8e3-52734297c112}
"redis-host" {f5576790-7d12-4ee8-884f-7352c04f4e04}
"rhel_default_1532386536492_17873" {449040f4-21ef-436d-8648-a4026a547875}
"centos_default_1532472936791_11249" {86ffd1ee-681a-4062-a233-e29ac966fc81}
"freebsd" {2924b43b-da8b-4f59-ac32-ee4420923055}
"RHEL7" {33e98062-f82e-49df-9a8a-91b0eb31e80d}
"arch_default_1532990644081_68335" {2d5206ba-c07a-4691-8c3b-63e941113f15}
"ctf-tools_default_1533510374954_98487" {edd5c5d6-95e5-47af-a462-1d66aab8e640}
"host1" {ee738687-3981-4582-b2d3-3540a1cbff1c}
"host2" {d2907cef-5018-4476-a6e8-5e7c1c321cfe}

host3虚拟机被干掉了。

管理远程Docker

我们只需要更改更改环境变量就能让Docker客户端连接上远程主机上的Docker Daemon来进行操作。

Docker Machine提供了一个 env 子命令来告诉你输入哪些命令可以连接到特定的机器上。

docker-machine env host1
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.100:2376"
export DOCKER_CERT_PATH="/home/lujun9972/.docker/machine/machines/host1"
export DOCKER_MACHINE_NAME="host1"
# Run this command to configure your shell: 
# eval $(docker-machine env host1)

按照说明,只需要执行 eval $(docker-machine env host1), 之后Docker客户端的操作就都是在 host1 主机上进行的了。比如

echo "激活host1前"
echo "check docker machines"
docker-machine ls
echo "check docker images"
docker images |head -n 5

echo "激活host1后"
eval $(docker-machine env host1)
echo "check docker machines"
docker-machine ls
echo "check docker images"
docker images |head -n 5
激活host1前
check docker machines
NAME         ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER        ERRORS
host1        -        virtualbox   Running   tcp://192.168.99.100:2376           v18.06.0-ce   
host2        -        virtualbox   Running   tcp://192.168.99.101:2376           v18.06.0-ce   
redis-host   -        virtualbox   Stopped                                       Unknown       
check docker images
REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
eaf                            latest              85aaf245545d        14 hours ago        1.97GB
<none>                         <none>              071e13965b57        24 hours ago        1.97GB
<none>                         <none>              2717978972e0        24 hours ago        1.97GB
<none>                         <none>              86ac9d427d3f        24 hours ago        1.97GB
激活host1后
check docker machines
NAME         ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER        ERRORS
host1        *        virtualbox   Running   tcp://192.168.99.100:2376           v18.06.0-ce   
host2        -        virtualbox   Running   tcp://192.168.99.101:2376           v18.06.0-ce   
redis-host   -        virtualbox   Stopped                                       Unknown       
check docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

可以发现,激活host1前和激活host1主机后有两个不同点:

  1. 激活host1主机后,ACTIVE这一列,在 host1 这一行有一个 * 号标识
  2. 激活host1主机后,docker images变成空了,因为 host1 主机上并没有任何镜像。