这个《Docker入门系列》文档,是根据Docker官网(https://docs.docker.com)的帮助文档大致翻译而成。主要是作为个人学习记录。有错误的地方,Robin欢迎大家指正。分为如下几个部分:

1 Docker入门:简介

2 Docker入门:安装运行

3 Docker入门:容器(Containers)

4 Docker入门:服务(Services)

5 Docker入门:Swarms

6 Docker入门:Stacks

7 Docker入门:部署app

8 Docker入门:稍高级的话题

 

5.1 引言

         在上一节,我们使用上上一节里写的app,通过将它转化为一个service,来定义该app在产品中的运行方式,并在进程中scale到5个副本。

         在本节,我们将这个app部署到一个cluster上,使其在多个机器上运行。通过将多个机器加入到这个”Dockerized” cluster,我们实现了多容器、多机器环境中运行的应用程序。这个”Dockerized” cluster被称为swarm。

 

5.2 理解swarm集群

         一个swarm是一组机器,这些机器上运行着Docker,并加入到一个集群中。经过这些配置后,你仍然像之前那样运行Docker命令,但不同的是,这些命令由swarm manager在集群上执行。这些机器可以是真实的机器,也可以是虚拟机。机器加入到一个swarm后,可以称这些机器为节点(node)。

         Swarm manager可以使用多种策略来运行容器。比如策略”emptiest node”:在最少的机器上运行容器;比如策略”global”:确保每个机器之运行一个特定容器的实例。通过修改Compose文件,告诉swarm manager使用哪些策略。

         在一个swarm里,只有swarm manager能够执行Docker命令,也只有swarm manager可以批准其他机器作为worker节点加入到swarm中。Worker只提供服务能力,并没有权利干涉其他机器的工作。

         到现在为止,我们只是在本地机器上使用Docker的single-host模式。只要使能swarm的使用,Docker也可以切换到swarm模式。在某机器上使能swarm模式,可以使该机器立即成为一个swarm manager。然后,Docker不只是运行当前机器上的命令,也会运行在swarm上执行的命令。

 

5.3 构建一个swarm

         一个swarm由多个节点组成,这些节点可以是物理上的,也可以是虚拟的。要做的只是简单的两步。首先,运行docker swarm init来使能swarm模式,从而使当前的机器成为一个swarm manager;然后在其他机器上运行docker swarm join,使这些机器作为worker节点加入到swarm中。

         下面将采用虚拟机方式(VMs)来快速创建两个机器的集群(cluster),然后将集群转为一个swarm。

 

5.3.1 安装VirtualBox

  不同的平台,创建虚拟机的方式不同。如在MAC/LINUX/WINDOWS7/WINDOWS8系统上,需要使用hypersisor来创建虚拟机;在WINDOWS10平台上,使用Hyper-V来创建虚拟机(Hyper-V会默认安装在WINDOWS10上)。

  由于本人用的是CentOS系统,使用hypersisor,需要安装VirtualBox。

  进入VirtualBox的官网,选择版本及安装方式。本人使用yum源安装:

yum install VirtualBox-5.2

  不过使用该命令安装时提示没有可以的VirtualBox-5.2。

  在/etc/yum.repos.d下建立VirtualBox-5.2.repo源,源中输入内容:

[virtualbox]

name=Oracle Linux / RHEL / CentOS-$releasever / $basearch - VirtualBox

baseurl=http://download.virtualbox.org/virtualbox/rpm/el/$releasever/$basearch

enabled=1

gpgcheck=1

repo_gpgcheck=1

gpgkey=https://www.virtualbox.org/download/oracle_vbox.asc

         然后再运行命令yum install VirtualBox-5.2,安装成功。

 

5.3.2 安装Docker Machine

         创建虚拟机时使用docker machine。对于macOS和Windows系统,安装对应版本的Docker时,会自动安装Docker machine。但在Linux系统下,需要手动安装。Centos系统下,运行命令:

curl -L https://github.com/docker/machine/releases/download/v0.13.0/docker-machine-`uname -s`-`uname -m` >/tmp/docker-machine &&

chmod +x /tmp/docker-machine &&

sudo cp /tmp/docker-machine /usr/local/bin/docker-machine

         显示machine版本号来确认是否安装成功:

$ docker-machine version

docker-machine version 0.13.0, build 9371605

 

5.3.3 创建虚拟机

         使用VirtualBox驱动,创建两个VMs:

docker-machine create --driver virtualbox myvm1

docker-machine create --driver virtualbox myvm2

 

5.3.4 列出所有VMs并获取它们的IP

         上面创建了两个虚拟机:myvm1和myvm2。

         使用命令docker-machine ls列出这些虚拟机和它们的IP地址:

$ docker-machine ls

NAME    ACTIVE   DRIVER       STATE     URL           SWARM   DOCKER        ERRORS

myvm1   -        virtualbox   Running   tcp://192.168.99.100:2376           v17.06.2-ce  

myvm2   -        virtualbox   Running   tcp://192.168.99.101:2376           v17.06.2-ce 

 

5.3.5 初始化swarm并添加节点

         将第一个虚拟机作为manager节点,用以执行管理命令并准许其他worker加入到swarm中;将第二个虚拟机作为worker节点。

         通过使用命令docker-machine ssh,将命令发送到虚拟机上。命令中使用docker swarm init,使myvm1成为manager:

$ docker-machine ssh myvm1 "docker swarm init --advertise-addr <myvm1 ip>"

Swarm initialized: current node <node ID> is now a manager.

 

To add a worker to this swarm, run the following command:

 

  docker swarm join \

  --token <token> \

  <myvm ip>:<port>

 

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

 

  ◆ 关于端口2377和2376。

  2377是swarm管理端口,运行命令docker swarm init和docker swarm join时会用到该端口。运行命令时不使用端口号,会采用默认端口。

  命令docker-machine ls的返回结果包括端口2376,这是Docker daemon port。使用这个端口会导致错误。

         命令docker swarm init的执行结果中,包含已配置好的命令docker swarm join,在其他机器上运行这个,从而使该机器加入到swarm中。复制这个命令,通过docker-machine ssh将该命令发送到myvm2,使myvm2作为worker节点加入到这个新swarm中:

$ docker-machine ssh myvm2 "docker swarm join \

--token <token> \

<ip>:2377"

 

This node joined a swarm as a worker.

         恭喜,现在已经创建好了一个swarm。

         在manager节点上运行命令docker node ls来查看这个swarm中的节点:

$ docker-machine ssh myvm1 "docker node ls"

ID                            HOSTNAME      STATUS      AVAILABILITY     MANAGER STATUS

brtu9urxwfd5j0zrmkubhpkbd     myvm2         Ready       Active

rihwohkh3ph38fhillhhb84sk *   myvm1         Ready       Active           Leader

 

5.3.6 节点脱离swarm

         如果想让某一节点脱离swarm,在该节点上运行命令docker swarm leave即可。

 

5.4 在swarm集群上部署app

         我们已经完成最难的部分,下面只要重复第4部分(Docker入门:服务)中的步骤,就可以在swarm上部署app了。记住一点:只有像myvm1这样的manager节点才可以执行Docker命令,worker节点只是提供服务能力。

5.4.1 配置一个和swarm manager对话的docker-machine shell

         到目前为止,我们是通过将Docker命令包裹在docker-machine ssh中的方式,来和VMs进行对话。

  还有一种更好的办法。首先运行docker-machine env <machine>来获取一个新命令,然后通过运行这个新命令来配置当前的shell,从而使当前的shell和VM上的Docker deamon进行对话。这种方法更好,因为它允许我们使用本地的docker-compose.yml文件来“远程”部署app,从而避免拷贝这个Compose文件。

         运行命令docker-machine env myvm1会有结果输出,将结果输出的最后一行作为命令再执行,从而配置当前的shell可以和myvm1(swarm manager)对话了。

         平台不同,配置shell的命令也会不同。下面展示Linux平台下Docker machine shell环境的配置过程,其他平台查看Docker官网。

         运行命令docker-machine env myvm1

$ docker-machine env myvm1

export DOCKER_TLS_VERIFY="1"

export DOCKER_HOST="tcp://192.168.99.100:2376"

export DOCKER_CERT_PATH="/Users/sam/.docker/machine/machines/myvm1"

export DOCKER_MACHINE_NAME="myvm1"

# Run this command to configure your shell:

# eval $(docker-machine env myvm1)

         然后运行提供的命令来配置当前shell和myvm1对话:

eval $(docker-machine env myvm1)

         现在运行docker-machine ls来验证myvm1就是当前的活跃机器,会有星号标识:

$ docker-machine ls

NAME    ACTIVE   DRIVER       STATE     URL                           SWARM   DOCKER        ERRORS

myvm1   *        virtualbox   Running   tcp://192.168.99.100:2376     v17.06.2-ce  

myvm2   -        virtualbox   Running   tcp://192.168.99.101:2376     v17.06.2-ce  

 

5.4.2 在swarm manager上部署app

         现在拥有了虚拟机myvm1,并将其作为了swarm manager。就像第4部分所做的一样,通过在myvm1上使用命令docker stack deploy并利用本地文件docker-compose.yml,从而在swarm上部署app。

         经过docker-machine shell配置后,你可以连接到myvm1,但你仍然有权限来访问你本机上的文件。

         和之前一样,通过运行如下命令,在myvm1上部署app:

docker stack deploy -c docker-compose.yml getstartedlab

         OK了,app在swarm集群上部署成功。

         现在可以使用上一部分的那些命令。不同的是,service(及其关联的容器)已经分布到myvm1和myvm2两个节点上了。

$ docker stack ps getstartedlab

 

ID            NAME                  IMAGE                   NODE   DESIRED STATE

jq2g3qp8nzwx  getstartedlab_web.1   robin/get-started:part2  myvm1  Running

88wgshobzoxl  getstartedlab_web.2   robin/get-started:part2  myvm2  Running

vbb1qbkb0o2z  getstartedlab_web.3   robin/get-started:part2  myvm2  Running

ghii74p9budx  getstartedlab_web.4   robin/get-started:part2  myvm1  Running

0prmarhavs87  getstartedlab_web.5   robin/get-started:part2  myvm2  Running

 

5.4.3 访问集群

         无论使用myvm1或myvm2的IP地址,都可以访问到你的app。

         你所创建的网络在这些节点间能够共享并负载均衡。运行docker-machine ls来获取所有的虚拟机IP地址,在浏览器中访问任何一个IP地址,并刷新页面。

         

         不停刷新后,可以看到5个容器ID随机循环显示,从而展示了负载均衡。

         为什么两个IP地址都可以工作呢?这是因为两个节点都参与到了这个ingress routing mesh。因此,在你的swarm中,如果一个service部署在特定的端口,该service自己也会保留那个端口,而不管到底哪个节点上运行着容器。

         下面这张图,展示了my-web这个service的routing mesh是什么样子,其中,my-web在端口8080上发布,并运行在一个3节点swarm上。

 

         如果你遇到连接问题,请记住如下事项。为了在swarm中使用ingress network,在你使能swarm模式前,要保证如下端口在swarm的节点之间是打开的:

  • 7946:TCP/UDP,用于容器网络发现;
  • 4789:UDP,用于容器ingress network。

 

5.4.4 和VMs的连接方式

         和VMs有两种连接方式。本文展示了docker-machine sshdocker-machine env两种方式。通过docker-machine CLI,所有的平台都支持这两种方式。

(1)如果想让你的shell和另一个机器(如myvm2)对话,只要在当前shell(或另一个shell)中运行docker-machine env myvm2命令,再运行给出的命令后,就可以将shell指向myvm2。这只对当前的shell有效。如果更换到一个未配置的shell或一个新打开的shell,需要重新运行上述命令。使用docker-machine ls来列出所有的机器,观察它们的状态,获取它们的IP地址,或者查看你连的是哪个机器。

(2)同样,你可以将Docker命令封装到命令docker-machine ssh <machine> “<command>”中,这样可以直接登到虚拟机上,但没有权限访问你本机上的文件。

(3)在Mac或Linux上,可以使用命令docker-machine scp <file> <machine>:~在机器间拷贝文件;在Windows平台上,需要使用Git Bash这样的Linux终端模拟器。

 

5.5 scale你的app

         现在你就可以做任何你在第三部分和第四部分学的东西:

         通过修改docker-compose.yml文件来scale你的app。

         如果想修改app的行为,可以修改代码,然后重新构建映像,并推送这个新的映像。

         无论采用哪种修改,只是简单的再运行一下docker stack deploy就可以部署这些变化。

         通过使用命令docker swarm join(之前我们在myvm2上使用过该命令),我们可以将任何机器(物理上的或虚拟的)加入到swarm中,从而增加这个集群的服务能力。然后运行docker stack deploy,我们的app就可以使用这些新加入的资源。

        

5.6 清理和重启

5.6.1 Stack和Swarm

         使用命令docker stack rm来关闭stack,例如:

docker stack rm getstartedlab

接下来是要保留还是删除我们的swarm?

         可以通过如下步骤来删除这个swarm:在worker节点上使用命令docker-machine ssh myvm2 "docker swarm leave";在manager节点上使用命令docker-machine ssh myvm1 "docker swarm leave --force"

         后面的部分还需要使用这个swarm,暂时先别删除它。

 

5.6.2 重置docker-machine shell环境变量

         要在当前的shell中重置docker-machine环境变量,可以使用如下命令:

eval $(docker-machine env -u)

         这会断开shell和docker-machine所创建的虚拟机之间的连接,并允许你继续使用这个shell,并运行原生的docker命令。

 

5.6.3 重启Docker machines

         如果关闭了主机,Docker machine也将停止运行。可以通过命令docker-machine ls来检测这些machine的状态:

$ docker-machine ls

NAME    ACTIVE   DRIVER       STATE     URL   SWARM   DOCKER    ERRORS

myvm1   -        virtualbox   Stopped                 Unknown

myvm2   -        virtualbox   Stopped                 Unknown

         想重启这些停止的machine,运行命令:

docker-machine start <machine-name>

         例如:

$ docker-machine start myvm1

Starting "myvm1"...

(myvm1) Check network to re-create if needed...

(myvm1) Waiting for an IP...

Machine "myvm1" 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.

 

$ docker-machine start myvm2

Starting "myvm2"...

(myvm2) Check network to re-create if needed...

(myvm2) Waiting for an IP...

Machine "myvm2" 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.

 

5.7 总结

         在这一部分,我们学习了许多知识:什么是swarm;在swarm中怎样让一个节点成为manager节点或worker节点;创建一个swarm并将app部署在其上。可以看到使用的核心Docker命令和第四部分没有区别,只是命令需要运行在swarm master上。你也看到了Docker网络功能的威力,即便容器运行在不同的机器上,依然能够将请求负载均衡到这些容器上。最后,我们学习了在集群上怎样去迭代开发app以及scale你的app。

 

5.8 本节命令列表

         如果你想和你的swarm或者你的虚拟机进行交互,可以使用下面的一些命令:

docker-machine create --driver virtualbox myvm1 # Create a VM (Mac, Win7, Linux)

docker-machine create -d hyperv --hyperv-virtual-switch "myswitch" myvm1 # Win10

docker-machine env myvm1                # View basic information about your node

docker-machine ssh myvm1 "docker node ls"         # List the nodes in your swarm

docker-machine ssh myvm1 "docker node inspect <node ID>"        # Inspect a node

docker-machine ssh myvm1 "docker swarm join-token -q worker"   # View join token

docker-machine ssh myvm1   # Open an SSH session with the VM; type "exit" to end

docker node ls                # View nodes in swarm (while logged on to manager)

docker-machine ssh myvm2 "docker swarm leave"  # Make the worker leave the swarm

docker-machine ssh myvm1 "docker swarm leave -f" # Make master leave, kill swarm

docker-machine ls # list VMs, asterisk shows which VM this shell is talking to

docker-machine start myvm1            # Start a VM that is currently not running

docker-machine env myvm1      # show environment variables and command for myvm1

eval $(docker-machine env myvm1)         # Mac command to connect shell to myvm1

& "C:\Program Files\Docker\Docker\Resources\bin\docker-machine.exe" env myvm1 | Invoke-Expression   # Windows command to connect shell to myvm1

docker stack deploy -c <file> <app>  # Deploy an app; command shell must be set to talk to manager (myvm1), uses local Compose file

docker-machine scp docker-compose.yml myvm1:~ # Copy file to node's home dir (only required if you use ssh to connect to manager and deploy the app)

docker-machine ssh myvm1 "docker stack deploy -c <file> <app>"   # Deploy an app using ssh (you must have first copied the Compose file to myvm1)

eval $(docker-machine env -u)     # Disconnect shell from VMs, use native docker

docker-machine stop $(docker-machine ls -q)               # Stop all running VMs

docker-machine rm $(docker-machine ls -q) # Delete all VMs and their disk images

 

  备注:由于写这篇文章时,无法访问gitlab,所以本文的后面部分只是翻译。

posted on 2017-10-22 22:39  巴黎河畔  阅读(573)  评论(0编辑  收藏  举报