【實戰】Docker Machine + Compose + Swarm

cm54 9年前發布 | 140K 次閱讀 Docker

本文的案例結合了Docker的三大編排工具Docker Machine、Compose與Swarm,值得讀者們參閱。

Docker現在已經推出了一些新的命令行工具,這些工具可以簡單的編排(orchestration )Docker實例、集群以及容器管理。它們是:

  • Docker Machine - 讓你輕松部署Docker實例到很多不同的平臺。
  • Docker Compose - Fig工具的替代品。
  • Docker Swarm - Docker眾實例的原生集群。
  • </ul>
    這三種技術中,Swarm目前不適合在生產中使用,因此在這篇文章中我不會講關于它的太多細節。

    Docker Machine

    對于直接下載預編譯的二進制文件來說,我決定使用 Homebrew(OS X的管理包工具)

    # 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</pre>
    這樣就安裝了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 env testing
    export DOCKER_TLS_VERIFY=yes
    export DOCKER_CERT_PATH=/Users/russ/.docker/machine/machines/testing
    export DOCKER_HOST=tcp://192.168.99.100:2376
    $  docker-machine config testing
    --tls --tlscacert=/Users/russ/.docker/machine/machines/testing/ca.pem --tlscert=/Users/russ/.docker/machine/machines/testing/cert.pem --tlskey=/Users/russ/.docker/machine/machines/testing/key.pem -H="tcp://192.168.99.100:2376

    我現在啟用了一個虛擬機并準備使用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</pre>
    最后,你可以使用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就是和以下公有和私有的云服務提供商(以后會添加更多)一起使用的。

    • Amazon EC2
    • Microsoft Azure
    • Digital Ocean
    • Google Compute Engine
    • Rackspace
    • SoftLayer
    • OpenStack
    • VMWare vCloud Air
    • VMWare vSphere
    • </ul>
      讓我們使用docker-machine來啟用一個Digital Ocean的實例。你需要生成一個Personal Access Token。一旦用token啟用機子就會像下面所示一樣:

      $  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并且啟用了以下配置的實例:

      • OS = Ubuntu 14.04 x64
      • RAM = 512MB
      • HDD = 20GB SSD
      • Region = NYC3
      • </ul>
        這些默認的配置可以通過提供更多的選項被修改,運行docker-machine create --help獲取幫助查看所有帶例子的選項。

        一旦實例開啟,docker-machine通過SSH連接到安裝、配置以及開啟的最新的Docker上。

        所以,我們現在有兩臺Machines,一個在本地,一個在Digital Ocean上。

        $  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</pre>
        并且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 $  </pre>
        最終,你可以使用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命令就可以操控他們。

        Docker Compose

        Docker開始充滿生機是因為有了Fig, 這是我曾在以前的文章中寫到過,當前版本并沒有添加太多的新功能,但它開始奠定了與docker-swarm工作的基礎,單擊 這里查看詳細日志。

        像docker-machine一樣,我使用Homebrew公式安裝docker-compose。

        $  brew install docker-compose
        ==> Downloading https://homebrew.bintray.com/bottles/fig-1.1.0.yosemite.bottle.1.tar.gz

        ############################################################ 100.0%</h6>
        

        ==> 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 $  </pre>
        然后,使用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客戶端那些剛剛啟動的服務器實例的詳細信息。

        $  $(docker-machine env compose)

        此命令注入所需Docker客戶端的環境變量來連接到服務實例,要看到他們,你只需運行docker-machine env machine-name。

        $  docker-machine env compose
        export DOCKER_TLS_VERIFY=yes
        export DOCKER_CERT_PATH=/Users/russ/.docker/machine/machines/compose
        export DOCKER_HOST=tcp://192.168.99.100:2376

        往后它就像Fig一樣,除了fig.yml文件現在應該改為docker-compose.yml,在我以前的博文里有一個fig.yml文件描述:

        web:  
        image: russmckendrick/nginx-php
        volumes:
        - ./web:/var/www/html/
        ports:
        - 80:80
        environment:
        PHP_POOL: mywebsite
        links:
        - db:db
        db:  
        image: russmckendrick/mariadb
        ports:
        - 3306
        privileged: true
        environment:
        MYSQL_ROOT_PASSWORD: wibble
        MYSQL_DATABASE: wibble
        MYSQL_USER: wibble
        MYSQL_PASSWORD: wibble

        它啟用兩個容器并且把它們連接到一起,還有在Nginx容器內的/var/www/html被掛載到host的./web文件夾下。我準備運行docker-compose命令的文件夾的結構是這樣的:

        $  tree -a
        .
        ├── [russ      356]  docker-compose.yml
        └── [russ      102]  web
        └── [russ       67]  index.php

        1 directory, 2 files</pre>
        開始我要拉取需要啟用的鏡像,你可以忽略此部分。

        $  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   </pre>
        你也可以打開瀏覽器:

        open http://$(docker-machine ip)

        在我的例子中我看到PHPinfo()頁面,如下:

        【實戰】Docker Machine + Compose + Swarm

        一旦容器開啟,你可以使用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 Swarm

        在進一步討論之前,先看下官方文檔的警告:

        警告:Swarm當前是beta版本,因此后期可能會有變化。我們還不推薦在生產環境中使用。
        現在讓我們使用Homebrew來安裝docker-swarm:

        $  brew install docker-swarm
        ==> Downloading https://homebrew.bintray.com/bottles/docker-swarm-0.1.0.yosemite.bottle.tar.gz

        ############################################################ 100.0%</h6>
        

        ==> Pouring docker-swarm-0.1.0.yosemite.bottle.tar.gz /usr/local/Cellar/docker-swarm/0.1.0: 4 files, 8.7M</pre>
        因為我們已經安裝了docker-machine,我將要使用它在本地創建一個集群。首先,我們需要啟動一個實例并運行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 $  </pre>
        正如你所見,當容器啟動時,我得到了一個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 env --swarm swarm-master)

        現在讓我們添加另一個節點:

        $  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 info
        Containers: 3
        Nodes: 2
        swarm-master: 192.168.99.101:2376
        └ Containers: 2
        └ Reserved CPUs: 0 / 4
        └ Reserved Memory: 0 B / 999.9 MiB
        swarm-node-00: 192.168.99.102:2376
        └ Containers: 1
        └ Reserved CPUs: 0 / 4
        └ Reserved Memory: 0 B / 999.9 MiB

        太棒了,但這意味著什么?

        讓我們拉取一些鏡像:

        $  docker -H 192.168.99.101:2376 pull redis
        $  docker -H 192.168.99.102:2376 pull mysql

        注意到我是如何在“swarm-master”上拉取redis鏡像以及在swarm-node-00上拉取mysql的,現在我可以保證容器只在有鏡像的那個節點上啟用:

        $  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 -H 192.168.99.101:2376 pull russmckendrick/nginx-php
        $  docker -H 192.168.99.102:2376 pull russmckendrick/nginx-php

        現在,讓我們啟用一個容器并綁定到80端口。

        $  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 

        所有這一切都沒有提示或特殊的命令行,它的幫助僅僅是用它來做到這些。

        正如你所看到的,docker-swarm仍然有非常大的發展潛力,但也有一些不如意的地方,如容器不能夠跨節點通訊。然而,伴隨著 socketplane.io(他們使用Open vSwitch開發了一個基于軟件定義網絡解決方案的容器)的加入,我想用不了多長時間這個問題就能得到解決。

        最后,讓我們刪除在運行的實例:

        $  docker-machine rm local swarm-master swarm-node-00

        就這樣吧,期待在未來的幾個月這些工具的更新,我也會進一步跟進。

        原文:Docker Machine, Compose & Swarm (翻譯:田浩浩 校對:李穎杰)

        來自:http://dockerone.com/article/275

 本文由用戶 cm54 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!