# Make sure everything is up-to-date
brew update
brew doctor
brew cask update
brew cask doctor
# install docker-machine
brew cask install docker-machine
这样就安装了docker-machine。
$ docker-machine -v
docker-machine version 0.1.0
$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM
$
我已经安装了VirtualBox,并且要创建一个叫“testing”的虚拟机:
$ docker-machine create --driver virtualbox testing
INFO[0000] Creating SSH key...
INFO[0000] Creating VirtualBox VM...
INFO[0006] Starting VirtualBox VM...
INFO[0006] Waiting for VM to start...
INFO[0038] "testing" has been created and is now the active machine.
INFO[0038] To point your Docker client at it, run this in your shell: $(docker-machine env testing)
docker-machine使用几个命令来帮助你连接到本地安装的Docker客户端:
$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM
testing * virtualbox Running tcp://192.168.99.100:2376
和其他新安装的一样,让我们运行一个“Hello World”:
$ docker $(docker-machine config testing) run busybox echo hello world
Unable to find image 'busybox:latest' locally
511136ea3c5a: Pull complete
df7546f9f060: Pull complete
ea13149945cb: Pull complete
4986bf8c1536: Pull complete
busybox:latest: The image you are pulling has been verified. Important: image verification is a tech preview feature and should not be relied on to provide security.
Status: Downloaded newer image for busybox:latest
hello world
最后,你可以使用docker-machie ssh machine-name命令SSH到虚拟机:
$ docker-machine ssh testing
Boot2Docker version 1.5.0, build master : a66bce5 - Tue Feb 10 23:31:27 UTC 2015
Docker version 1.5.0, build a8a31ef
docker@testing:~$ uname -a
Linux testing 3.18.5-tinycore64 #1 SMP Sun Feb 1 06:02:30 UTC 2015 x86_64 GNU/Linux
docker@testing:~$ cat /etc/*release
NAME=Boot2Docker
VERSION=1.5.0
ID=boot2docker
ID_LIKE=tcl
VERSION_ID=1.5.0
PRETTY_NAME="Boot2Docker 1.5.0 (TCL 5.4); master : a66bce5 - Tue Feb 10 23:31:27 UTC 2015"
ANSI_COLOR="1;34"
HOME_URL="http://boot2docker.io"
SUPPORT_URL="https://github.com/boot2docker/boot2docker"
BUG_REPORT_URL="https://github.com/boot2docker/boot2docker/issues"
docker@testing:$ exit
$
太棒了,我现在有一个虚拟机运行在我的电脑上,接下来呢?
$ docker-machine create \
→ --driver digitalocean \
→ --digitalocean-access-token cdb81ed0575b5a8d37cea0d06c9690daa074b1276892fc8473bdda97eb7c65ae \
→ dotesting
INFO[0000] Creating SSH key...
INFO[0000] Creating Digital Ocean droplet...
INFO[0004] Waiting for SSH...
INFO[0071] Configuring Machine...
INFO[0120] "dotesting" has been created and is now the active machine.
INFO[0120] To point your Docker client at it, run this in your shell: $(docker-machine env dotesting)
那么发生了什么呢?docker-machine访问我的Digital Ocean账户通过API并且启用了以下配置的实例:
$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM
dotesting * digitalocean Running tcp://45.55.134.248:2376
testing virtualbox Running tcp://192.168.99.100:2376
让我们再次运行“Hello World”,但是这次使用刚才启动的那个实例:
$ docker $(docker-machine config dotesting) run busybox echo hello world
Unable to find image 'busybox:latest' locally
511136ea3c5a: Pull complete
df7546f9f060: Pull complete
ea13149945cb: Pull complete
4986bf8c1536: Pull complete
busybox:latest: The image you are pulling has been verified. Important: image verification is a tech preview feature and should not be relied on to provide security.
Status: Downloaded newer image for busybox:latest
hello world
并且SSH到那个机器中:
$ docker-machine ssh dotesting
Welcome to Ubuntu 14.04.1 LTS (GNU/Linux 3.13.0-43-generic x86_64)
Documentation: https://help.ubuntu.com/
System information as of Sat Mar 21 07:24:02 EDT 2015
System load: 0.43 Processes: 72
Usage of /: 11.4% of 19.56GB Users logged in: 0
Memory usage: 12% IP address for eth0: 45.55.134.248
Swap usage: 0% IP address for docker0: 172.17.42.1
Graph this data and manage this system at:
https://landscape.canonical.com/
root@dotesting:~# docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
busybox latest 4986bf8c1536 11 weeks ago 2.433 MB
root@dotesting:~# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b8a83077d858 busybox:latest "echo hello world" 4 minutes ago Exited (0) 4 minutes ago kickass_almeida
root@dotesting:~# exit
logout
$
最终,你可以使用docker-mashie stop machine-name和docker-mashie rm machine-name来停止和移除machines。请注意当使用rm时,是不会提示你是否确定删除。
$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM
dotesting * digitalocean Running tcp://45.55.134.248:2376
testing virtualbox Running tcp://192.168.99.100:2376
$ docker-machine stop dotesting
$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM
dotesting * digitalocean Stopped tcp://45.55.134.248:2376
testing virtualbox Running tcp://192.168.99.100:2376
$ docker-machine rm dotesting
$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM
testing virtualbox Running tcp://192.168.99.100:2376
$
总结,以上就是docker-machie的总览。正如你看到的,它确实很方便在很多不同的供应商中来引导Docker服务实例,并且使用一个本地machine命令就可以操控他们。
$ brew install docker-compose
==> Downloading https://homebrew.bintray.com/bottles/fig-1.1.0.yosemite.bottle.1.tar.gz############################################################ 100.0%==> Pouring fig-1.1.0.yosemite.bottle.1.tar.gz
==> Caveats
Bash completion has been installed to:
/usr/local/etc/bash_completion.d
==> Summary
/usr/local/Cellar/fig/1.1.0: 186 files, 2.2M
$
然后,使用docker-machine创建一个Docker服务实例:
$ docker-machine create --driver virtualbox compose
INFO[0001] Creating SSH key...
INFO[0001] Creating VirtualBox VM...
INFO[0007] Starting VirtualBox VM...
INFO[0008] Waiting for VM to start...
INFO[0041] "compose" has been created and is now the active machine.
INFO[0041] To point your Docker client at it, run this in your shell: $(docker-machine env compose)
因为docker-compose不直接与docker-machine交互,我们需要告诉docker客户端那些刚刚启动的服务器实例的详细信息。
$ tree -a
.
├── \[russ 356] docker-compose.yml
└── \[russ 102] web
└── \[russ 67] index.php
1 directory, 2 files
开始我要拉取需要启用的镜像,你可以忽略此部分。
$ docker-compose pull
Pulling db (russmckendrick/mariadb:latest)...
Pulling web (russmckendrick/nginx-php:latest)...
现在镜像已经被拉取下来,是时候开启容器了:
$ docker-compose up -d
Creating example_db_1...
Creating example_web_1...
我们现在有了两个正在运行的容器:
$ docker-compose ps
Name Command State Ports
----------------------------------------------------------------
example_db_1 /usr/local/bin/run Up 0.0.0.0:49154->3306/tcp
example_web_1 /usr/local/bin/run Up 0.0.0.0:80->80/tcp
你也可以打开浏览器:
open http://$(docker-machine ip)
在我的例子中我看到PHPinfo()页面,如下:
一旦容器开启,你可以使用docker exec来连接到容器内部:
$ docker exec -it example_web_1 bash
[root@997bbe6b5c80 /]# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.2 1.5 115200 15360 ? Ss 13:59 0:01 /usr/bin/python /usr/bin/supervisord -n
root 16 0.0 3.2 382876 33624 ? S 13:59 0:00 php-fpm: master process (/etc/php-fpm.conf)
root 17 0.0 0.2 110016 2096 ? Ss 13:59 0:00 nginx: master process nginx
nginx 18 0.0 0.5 110472 5568 ? S 13:59 0:00 nginx: worker process
webserv+ 19 0.0 1.5 383132 16284 ? S 13:59 0:00 php-fpm: pool mywebsite
webserv+ 20 0.0 0.8 382876 8848 ? S 13:59 0:00 php-fpm: pool mywebsite
webserv+ 21 0.0 0.8 382876 8848 ? S 13:59 0:00 php-fpm: pool mywebsite
webserv+ 22 0.0 0.8 382876 8848 ? S 13:59 0:00 php-fpm: pool mywebsite
webserv+ 23 0.0 0.8 382876 8852 ? S 13:59 0:00 php-fpm: pool mywebsite
root 95 0.0 0.4 91540 4740 ? Ss 13:59 0:00 /usr/libexec/postfix/master -w
postfix 97 0.0 0.6 91712 6508 ? S 13:59 0:00 qmgr -l -t unix -u
postfix 200 0.0 0.6 91644 6232 ? S 14:05 0:00 pickup -l -t unix -u
root 234 2.3 0.2 11748 2968 ? S 14:07 0:00 bash
root 250 1.0 1.1 110012 11616 ? S 14:07 0:00 nginx
root 251 0.0 0.2 19756 2212 ? R+ 14:07 0:00 ps aux
[root@997bbe6b5c80 /]# exit
exit
$
最后你可以停止以及移除容器,当然还有Docker实例:
$ docker-compose stop && docker-compose rm --force
Stopping example_web_1...
Stopping example_db_1...
Going to remove example_web_1, example_db_1
Removing example_db_1...
Removing example_web_1...
$ docker-machine rm compose
$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM
$
$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM
$ docker-machine create -d virtualbox local
INFO[0001] Creating SSH key...
INFO[0001] Creating VirtualBox VM...
INFO[0006] Starting VirtualBox VM...
INFO[0006] Waiting for VM to start...
INFO[0039] "local" has been created and is now the active machine.
INFO[0039] To point your Docker client at it, run this in your shell: $(docker-machine env local)
$ $(docker-machine env local)
$ docker run swarm create
Unable to find image 'swarm:latest' locally
511136ea3c5a: Pull complete
ae115241d78a: Pull complete
f49087514537: Pull complete
fff73787bd9f: Pull complete
97c8f6e912d7: Pull complete
33f9d1e808cf: Pull complete
62860d7acc87: Pull complete
bf8b6923851d: Pull complete
swarm:latest: The image you are pulling has been verified. Important: image verification is a tech preview feature and should not be relied on to provide security.
Status: Downloaded newer image for swarm:latest
63e7a1adb607ce4db056a29b1f5d30cf
$
正如你所见,当容器启动时,我得到了一个token:63e7a1adb607ce4db056a29b1f5d30cf,我将要用它来添加更多的节点,但是首先我们需要创建一个Swarm master:
$ docker-machine create \
→ -d virtualbox \
→ --swarm \
→ --swarm-master \
→ --swarm-discovery token://63e7a1adb607ce4db056a29b1f5d30cf \
→ swarm-master
INFO[0000] Creating SSH key...
INFO[0000] Creating VirtualBox VM...
INFO[0006] Starting VirtualBox VM...
INFO[0006] Waiting for VM to start...
INFO[0038] Configuring Swarm...
INFO[0043] "swarm-master" has been created and is now the active machine.
INFO[0043] To point your Docker client at it, run this in your shell: $(docker-machine env swarm-master)
然后,我们需要连接Docker客户端到Swarm上,这就需要将--swarm添加到$(docker-machine env machine-name)命令上:
$ docker-machine create \
→ -d virtualbox \
→ --swarm \
→ --swarm-discovery token://63e7a1adb607ce4db056a29b1f5d30cf \
→ swarm-node-00
INFO[0000] Creating SSH key...
INFO[0000] Creating VirtualBox VM...
INFO[0006] Starting VirtualBox VM...
INFO[0006] Waiting for VM to start...
INFO[0039] Configuring Swarm...
INFO[0048] "swarm-node-00" has been created and is now the active machine.
我们现在有了2个节点的集群 - “swarm-master”:
$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM
local virtualbox Running tcp://192.168.99.100:2376
swarm-master virtualbox Running tcp://192.168.99.101:2376 swarm-master (master)
swarm-node-00 * virtualbox Running tcp://192.168.99.102:2376 swarm-master
使用docker info来获取更多有关集群的信息:
$ docker run -d --name redis1 -e affinity:image==redis redis
af66148bbbc8dcd799d82448dfd133b968d34eb7066a353108bf909ea3324a58
$ docker run -d --name mysql -e affinity:image==mysql -e MYSQL_ROOT_PASSWORD=mysecretpassword -d mysql
70b2d93d6f83aa99f5ad4ebe5037e228a491a4b570609840f3f4be9780c33587
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
70b2d93d6f83 mysql:latest "/entrypoint.sh mysq 3 seconds ago Up Less than a second 3306/tcp swarm-node-00/mysql
af66148bbbc8 redis:latest "/entrypoint.sh redi 2 minutes ago Up 2 minutes 6379/tcp swarm-master/redis1
另一个例子是使用节点的端口,让我们在两个节点上都拉取我的nginx-php镜像:
$ docker run -d -p 80:80 russmckendrick/nginx-php
2d066b2ccf28d2a1fa9edad8ac7b065266f29ecb49a8753b972780051ff83587
再有:
$ docker run -d -p 80:80 russmckendrick/nginx-php
40f5fee257bb2546a639a5dc5c2d30f8fa0ac169145e431c534f85d8db51357f
你会说这没什么特别的啊?正常来说,当试图启动第二个容器时,你会得到如下信息因为你不用将同一个端口绑定到两个容器上:
$ docker run -d -p 80:80 russmckendrick/nginx-php
FATA[0000] Error response from daemon: unable to find a node with port 80 available
然而,在集群的情况下,因为Docker知道集群节点运行的是什么以及哪些端口是在使用的。Docker可以简单地通过Swarm在“swarm-node-00”上启动容器并且它知道“swarm-master”已经使用了80端口:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
40f5fee257bb russmckendrick/nginx-php:latest "/usr/local/bin/run" 4 seconds ago Up Less than a second 192.168.99.101:80->80/tcp swarm-master/elated_einstein
2d066b2ccf28 russmckendrick/nginx-php:latest "/usr/local/bin/run" 8 seconds ago Up Less than a second 192.168.99.102:80->80/tcp swarm-node-00/drunk_mestorf
70b2d93d6f83 mysql:latest "/entrypoint.sh mysq 26 minutes ago Up 26 minutes 3306/tcp swarm-node-00/mysql
af66148bbbc8 redis:latest "/entrypoint.sh redi 29 minutes ago Up 29 minutes 6379/tcp swarm-master/redis1
所有这一切都没有提示或特殊的命令行,它的帮助仅仅是用它来做到这些。