docker 與docker-compose

文章來源: https://blog.csdn.net/liudongdong19/article/details/79590241

docker 的使用過程,它分爲鏡像構建與容器啓動。

鏡像構建:即創建一個鏡像,它包含安裝運行所需的環境、程序代碼等。這個創建過程就是使用 dockerfile 來完成的。

容器啓動:容器最終運行起來是通過拉取構建好的鏡像,通過一系列運行指令(如端口映射、外部數據掛載、環境變量等)來啓動服務的。針對單個容器,這可以通過 docker run 來運行。

而如果涉及多個容器的運行(如服務編排)就可以通過 docker-compose 來實現,它可以輕鬆的將多個容器作爲 service 來運行(當然也可僅運行其中的某個),並且提供了 scale (服務擴容) 的功能。

簡單總結:

dockerfile: 構建鏡像;

docker run: 啓動容器;

docker-compose: 啓動服務;

docker-compose是編排容器的。例如,你有一個php鏡像,一個mysql鏡像,一個nginx鏡像。如果沒有docker-compose,那麼每次啓動的時候,你需要敲各個容器的啓動參數,環境變量,容器命名,指定不同容器的鏈接參數等等一系列的操作,相當繁瑣。而用了docker-composer之後,你就可以把這些命令一次性寫在docker-composer.yml文件中,以後每次啓動這一整個環境(含3個容器)的時候,你只要敲一個docker-composer up命令就ok了。
而dockerfile的作用是從無到有的構建鏡像。


docker的基本操作
  1.1 系統條件,本系統使用的linux操作系統是Centos7_x64
  1.2 啓動docker,service docker start
  1.3 演示從Docker Hub上下載最新版本的ubuntu
    命令: sudo docker pull ubuntu,會有如下的信息提示:
    [kass@localhost ~]$ sudo docker pull ubuntu
    Using default tag: latest
    Trying to pull repository docker.io/library/ubuntu ... latest: Pulling from library/ubuntu
    c2a0e656b13b: Pull complete
    a1918483ff2d: Pull complete
    19f3070b96b2: Pull complete
    0930cd7fba20: Pull complete
    8e5b7248472b: Pull complete
    Digest: sha256:46fb5d001b88ad904c5c732b086b596b92cfb4a4840a3abd0e35dbb6870585e4
    Status: Downloaded newer image for docker.io/ubuntu:latest

  1.4 使用下載的鏡像創建一個容器,在其中運行bash應用,具體執行結果如下:
    [kass@localhost ~]$ sudo docker run -t -i ubuntu /bin/bash
    [sudo] password for kass:
    Usage of loopback devices is strongly discouraged for production use. Either use `--storage-opt dm.thinpooldev` or use `--storage-opt dm.no_warn_on_loop_devices=true` to suppress this warning.

  1.5 使用docker images 命令查看本地主機上已有的鏡像,及添加一個新的ubuntu:latest鏡像標籤
    具體的操作命令及信息如下:
    [kass@localhost ~]$ sudo docker images
    REPOSITORY       TAG    IMAGE ID        CREATED VIRTUAL   SIZE
    docker.io/ubuntu    latest    8e5b7248472b    2 weeks ago      122 MB
    [kass@localhost ~]$ sudo docker tag docker.io/ubuntu:latest ubuntu:latest
    [kass@localhost ~]$ sudo docker images
    REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
    ubuntu latest 8e5b7248472b 2 weeks ago 122 MB
    docker.io/ubuntu latest 8e5b7248472b 2 weeks ago 122 MB
  1.6 查看鏡像的詳細信息
    [kass@localhost ~]$ sudo docker inspect 8e5b7248472b
    [sudo] password for kass:
    [
    {
      "Id": "8e5b7248472b1cf370e8b181c357148a5aff33c0b8da2ba133701f599de15a84",
      "RepoTags": [
        "docker.io/ubuntu:latest",
        "ubuntu:latest"
    ],
    "RepoDigests": [],
    "Parent": "0930cd7fba20b2f6a84c3abc1918b4e159b123c1a3b787c0a9bea874e4f7e40b",
    "Comment": "",
    "Created": "2016-05-27T14:15:02.359284074Z",
    "Container": "b8bd6a8e8874a87f626871ce370f4775bdf598865637082da2949ee0f4786432",
    "ContainerConfig": {
    "Hostname": "914cf42a3e15",
    "Domainname": "",
    "User": "",
    "AttachStdin": false,
    "AttachStdout": false,
    "AttachStderr": false,
    "Tty": false,
    "OpenStdin": false,
    "StdinOnce": false,
    "Env": [],
    "Cmd": [
      "/bin/sh",
      "-c",
      "#(nop) CMD [\"/bin/bash\"]"
    ],
    "Image": "b873f334fa5259acb24cf0e2cd2639d3a9fb3eb9bafbca06ed4f702c289b31c0",
    "Volumes": null,
    "WorkingDir": "",
    "Entrypoint": null,
    "OnBuild": null,
    "Labels": {}
    },
    "DockerVersion": "1.9.1",
    "Author": "",
    "Config": {
      "Hostname": "914cf42a3e15",
      "Domainname": "",
      "User": "",
      "AttachStdin": false,
      "AttachStdout": false,
      "AttachStderr": false,
      "Tty": false,
      "OpenStdin": false,
      "StdinOnce": false,
      "Env": [],
      "Cmd": [
        "/bin/bash"
    ],
    "Image": "b873f334fa5259acb24cf0e2cd2639d3a9fb3eb9bafbca06ed4f702c289b31c0",
    "Volumes": null,
    "WorkingDir": "",
    "Entrypoint": null,
    "OnBuild": null,
    "Labels": {}
    },
    "Architecture": "amd64",
    "Os": "linux",
    "Size": 0,
    "VirtualSize": 121963951,
    "GraphDriver": {
    "Name": "devicemapper",
    "Data": {
    "DeviceId": "6",
    "DeviceName": "docker-253:1-34403904-8e5b7248472b1cf370e8b181c357148a5aff33c0b8da2ba133701f599de15a84",
    "DeviceSize": "107374182400"
    }
  }
  }
  ]
  1.7 詳細搜索
    sudo docker -f {{".Architecture"}} 8e5 //8e5就是8e5b7248472b 是鏡像的ID

  1.8 搜索鏡像
    [kass@localhost ~]$ sudo docker search mysql
    INDEX NAME DESCRIPTION STARS OFFICIAL AUTOMATED
    docker.io docker.io/mysql MySQL is a widely used, open-source relati... 2493 [OK]
    docker.io docker.io/mysql/mysql-server Optimized MySQL Server Docker images. Crea... 158 [OK]
    docker.io docker.io/centurylink/mysql Image containing mysql. Optimized to be li... 45 [OK]
    docker.io docker.io/sameersbn/mysql 36 [OK]
    docker.io docker.io/appcontainers/mysql Centos/Debian/Ubuntu Based Customizable My... 7 [OK]
    docker.io docker.io/marvambass/mysql MySQL Server based on Ubuntu 14.04 6 [OK]
    docker.io docker.io/alterway/mysql Docker Mysql 2 [OK]
    docker.io docker.io/azukiapp/mysql Docker image to run MySQL by Azuki - http:... 2 [OK]
    docker.io docker.io/drupaldocker/mysql MySQL for Drupal 2 [OK]
    docker.io docker.io/yfix/mysql Yfix docker built mysql 2 [OK]
    docker.io docker.io/bahmni/mysql Mysql container for bahmni. Contains the ... 1 [OK]
    docker.io docker.io/phpmentors/mysql MySQL server image 1 [OK]
    docker.io docker.io/sin30/mysql MySQL images with my own config files. 1 [OK]
    docker.io docker.io/tetraweb/mysql 1 [OK]
    docker.io docker.io/ahmet2mir/mysql This is a Debian based image with MySQL se... 0 [OK]
    docker.io docker.io/akilli/mysql akilli/base based MySQL image 0 [OK]
    docker.io docker.io/cloudposse/mysql Improved `mysql` service with support for ... 0 [OK]
    docker.io docker.io/dockerizedrupal/mysql docker-mysql 0 [OK]
    docker.io docker.io/jeffutter/mysql-no_volumes Images based on the official mysql images ... 0 [OK]
    docker.io docker.io/kardasz/mysql Debian 8, MySQL 5.7 0 [OK]
    docker.io docker.io/lancehudson/docker-mysql MySQL is a widely used, open-source relati... 0 [OK]
    docker.io docker.io/nanobox/mysql MySQL service for nanobox.io 0 [OK]
    docker.io docker.io/projectomakase/mysql Docker image for MySQL 0 [OK]
    docker.io docker.io/tozd/mysql MySQL (MariaDB fork) Docker image. 0 [OK]
    docker.io docker.io/vukor/mysql Build for MySQL. Project available on http... 0 [OK]

  1.9 刪除鏡像
    1.9.1 通過name刪除鏡像
      [kass@localhost ~]$ sudo docker rmi docker.io/ubuntu
      Untagged: docker.io/ubuntu:latest
      [kass@localhost ~]$ sudo docker images
      REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
      ubuntu latest 8e5b7248472b 2 weeks ago 122 MB

    1.9.2 通過鏡像ID刪除文件
      這種方式,會先嚐試刪除所有指向該鏡像的標籤,然後刪除該鏡像本身
      [kass@localhost ~]$ sudo docker rmi docker.io/ubuntu

  2.0 創建鏡像
      [kass@localhost ~]$ sudo docker run -ti ubuntu /bin/bash
      Usage of loopback devices is strongly discouraged for production use. Either use `--storage-opt dm.thinpooldev` or use `--storage-opt dm.no_warn_on_loop_devices=true` to suppress this warning.
      root@bfda0c922239:/# touch test
      root@bfda0c922239:/# exit
      exit
      [kass@localhost ~]$ sudo docker commit -m "Add a new file" -a "Docker Newbee" 8e5b7248472b test
      Error response from daemon: no such id: 8e5b7248472b
      [kass@localhost ~]$ sudo docker images
      REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
      ubuntu latest 8e5b7248472b 2 weeks ago 122 MB
      [kass@localhost ~]$ sudo docker commit -m "Add a new file" -a "Docker Newbee" bfda0c922239 test
      4521126f01b2bdf6816929a82cd428bfc2da50119f4c1afc19f751fec71d510c
      [kass@localhost ~]$ sudo docker images
      REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
      test latest 4521126f01b2 6 seconds ago 122 MB
      ubuntu latest 8e5b7248472b 2 weeks ago 122 MB

    2.1 存儲鏡像、載入鏡像
      2.1.1 存儲鏡像
        [kass@localhost ~]$ sudo docker save -o test.zip test
      2.1.2 載入鏡像
        [kass@localhost ~]$ sudo docker load < test.zip
        或者
        [kass@localhost ~]$ sudo docker load --input test.zip

   note:使用sudo的時候如果提示permission denied,將當前用戶切換爲root身份,
   然後編輯/etc/sudoers 文件, 在root ALL=(ALL) ALL下面添加 kass ALL=(ALL) ALL

 

Compose命令補全
安裝命令補全

 確保bash completion已經安裝,如果當前使用非最小安裝的Linux,bash completion已經OK了,如果是在MAC上,可以使用brew install bash-completion來安裝
將completion腳本放在/etc/bash_completion.d/(在MAC上是/usr/local/etc/bash_completion.d/)

curl -L https://raw.githubusercontent.com/docker/compose/1.1.0/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose

在下次登錄時,Completion功能已經可以使用
可用的補全取決於在命令行的輸入,會補全:
* 可用的docker-compose命令
* 對於某一特別命令可用的選項
* 在一個給定的上下文條件(比如:具有運行或停止狀態的實例的服務或者基於鏡像的服務 VS 基於Dockerfile的服務)下,給出有可行的服務名稱,對於docker-compose scale,補全服務名稱時會自動有”=”附加上去
* 對於可選項的參數,比如:docker-compose kill -s會完成一些信號,比如SIGUP和SIGUSR1

擁有了這項功能以後,Compose更快更少輸入了呢!Happy working!

三、Compose使用實例

在本例中將會實現啓動nginx服務及一個數據卷容器,並將該數據卷容器作爲nginx的靜態文件
1.創建compose文件夾
sudo mkdir composetest
cd composetest
2.創建docker-compose.yml文件
touch docker-compose.yml
vim docker-compose.yml
在docker-compose.yml中輸入以下內容:

dvc:  
  image: debian:wheezy
  volumes:  
   - /www:/usr/share/nginx/html:ro
nginx:
  image: nginx:latest
  volumes_from:
   - dvc
  ports:
   - "8081:80"

3.啓動
docker-compose up -d
注:使用命令docker-compose ps查看運行狀況

四、CLI 說明(docker-compose 命令)

大多數Compose命令都是運行於一個或多個服務的,如果服務沒有指定,該命令將會應用到所有服務,如果要獲得所有可用信息,使用命令:docker-compose [COMMAND] --help,下面是命令(COMMAND)的說明:

build
創建或者再建服務
服務被創建後會標記爲project_service(比如composetest_db),如果改變了一個服務的Dockerfile或者構建目錄的內容,可以使用docker-compose build來重建它

help
顯示命令的幫助和使用信息

kill
通過發送SIGKILL的信號強制停止運行的容器,這個信號可以選擇性的通過,比如:
docker-compose kill -s SIGKINT

logs
顯示服務的日誌輸出

port
爲端口綁定輸出公共信息

ps
顯示容器

pull
拉取服務鏡像

rm
刪除停止的容器

run
在服務上運行一個一次性命令,比如:
docker-compose run web python manage.py shell

scale
設置爲一個服務啓動的容器數量,數量是以這樣的參數形式指定的:service=num,比如:
docker-compose scale web=2 worker=3

start
啓動已經存在的容器作爲一個服務

stop
停止運行的容器而不刪除它們,它們可以使用命令docker-compose start重新啓動起來

up
爲一個服務構建、創建、啓動、附加到容器
連接的服務會被啓動,除非它們已經在運行了
默認情況下,docker-compose up會集中每個容器的輸出,當存在時,所有的容器會停止,運行docker-compose up -d會在後臺啓動容器並使它們運行
默認情況下,如果服務存在容器的話,docker-compose up會停止並再創建它們(使用了volumes-from會保留已掛載的卷),如果不想使容器停止並再創建的話,使用docker-compose up --no-recreate,如果有需要的話,這會啓動任何停止的容器

選項
–verbose
顯示更多輸出

–version
顯示版本號並退出

-f,–file FILE
指定一個可選的Compose yaml文件(默認:docker-compose.yml)

-p,–project-name NAME
指定可選的項目名稱(默認:當前目錄名稱)

五、docker-compose.yml命令說明

每一個定義在docker-compose.yml中的服務必須明確指定一個image或者build選項,這與docker run命令行中輸入的是對應相同的,對於docker run,在Dockerfile文件中指定的選項(比如CMD、EXPOSE、VOLUME、ENV)是默認的,因此不必在docker-compose.yml中再指定一次

image
標明image的ID,這個image ID可以是本地也可以是遠程的,如果本地不存在,Compose會嘗試去pull下來

image: ubuntu  
image: orchardup/postgresql  
image: a4bc65fd  

build
該參數指定Dockerfile文件的路徑,該目錄也是發送到守護進程的構建環境(這句有點),Compose將會以一個已存在的名稱進行構建並標記,並隨後使用這個image

build: /path/to/build/dir  

command
重寫默認的命令

command: bundle exec thin -p 3000  

links
連接到其他服務中的容器,可以指定服務名稱和這個鏈接的別名,或者只指定服務名稱

links:  
 - db  
 - db:database  
 - redis  

此時,在容器內部,會在/etc/hosts文件中用別名創建一個條目,就像這樣:

172.17.2.186  db  
172.17.2.186  database  
172.17.2.186  redis  

環境變量也會被創建,關於環境變量的參數,會在後面講到

external_links
連接到在這個docker-compose.yml文件或者Compose外部啓動的容器,特別是對於提供共享和公共服務的容器。在指定容器名稱和別名時,external_links遵循着和links相同的語義用法

external_links:  
 - redis_1  
 - project_db_1:mysql  
 - project_db_1:postgresql  

ports
暴露端口,指定兩者的端口(主機:容器),或者只是容器的端口(主機會被隨機分配一個端口)

注:當以 主機:容器 的形式來映射端口時,如果使容器的端口小於60,那可能會出現錯誤,因爲YAML會將 xx:yy這樣格式的數據解析爲六十進制的數據,基於這個原因,時刻記得要將端口映射明確指定爲字符串

ports:  
 - "3000"  
 - "8000:8000"  
 - "49100:22"  
 - "127.0.0.1:8001:8001"  

expose
暴露端口而不必向主機發布它們,而只是會向鏈接的服務(linked service)提供,只有內部端口可以被指定

  1. expose:

  2. - "3000"

  3. - "8000"

volumes
掛載路徑最爲卷,可以選擇性的指定一個主機上的路徑(主機:容器),或是一種可使用的模式(主機:容器:ro)

  1. volumes_from:

  2. - service_name

  3. - container_name

environment
加入環境變量,可以使用數組或者字典,只有一個key的環境變量可以在運行Compose的機器上找到對應的值,這有助於加密的或者特殊主機的值

  1. environment:

  2. RACK_ENV: development

  3. SESSION_SECRET:

  4. environments:

  5. - RACK_ENV=development

  6. - SESSION_SECRET

env_file
從一個文件中加入環境變量,該文件可以是一個單獨的值或者一張列表,在environment中指定的環境變量將會重寫這些值env_file:
- .env
RACK_ENV: development

net
網絡模式,可以在docker客戶端的--net參數中指定這些值
net: "bridge"
net: "none"
net: "container:[name or id]"
net: "host"

dns
自定義DNS服務,可以是一個單獨的值或者一張列表

dns: 8.8.8.8
dns:
- 8.8.8.8
- 9.9.9.9

cap_add,cap_drop
加入或者去掉容器能力,查看man 7 capabilities 可以有一張完整的列表
cap_add:
- ALL
cap_drop:
- NET_ADMIN
- SYS_ADMIN

dns_search
自定義DNS搜索範圍,可以是單獨的值或者一張列表
dns_search: example.com
dns_search:
- dc1.example.com
- dc2.example.com

working_dir,entrypoint,user,hostname,domainname,mem_limit,privileged,restart,stdin_open,tty,cpu_shares
上述的每一個都只是一個單獨的值,和docker run中對應的參數是一樣的

cpu_shares: 73
 
working_dir: /code
entrypoint: /code/entrypoint.sh
user: postgresql
 
hostname: foo
domainname: foo.com
 
mem_limit: 1000000000
privileged: true
 
restart: always
 
stdin_open: true
tty: true

六、Compose環境變量說明

環境變量已經不再是用來連接服務的推薦方法了,相反,應該使用鏈接名稱(默認情況下是鏈接服務的名稱)作爲主機名稱來連接,這可以查看docker-compose.yml的更多細節
Compose使用Docker links來暴露服務的容器給其他的。每一個鏈接的容器都使用了一組環境變量,這每一組環境變量都是以容器名稱的大寫字母開頭的
要查看服務可用的環境變量,運行docker-compose run SERVICE env

name_PORT
完整URL,如:DB_PORT=tcp//172.17.0.5:5432

name_PORT_num_protocol
完整URL,如:DB_PORT_5432_TCP=tcp://172.17.0.5:5432

name_PORT_num_protocol_ADDR
容器的IP地址,如:DB_PORT_5432_TCP_ADDR=172.17.0.5

name_PORT_num_protocol_PORT
暴露的端口號,如:DB_PORT_5432_TCP_PORT=5432

name_PORT_num_protocol_PROTO
協議(tcp或者udp),如:DB_PORT_5432_TCP_PROTO=tcp

name_NAME
完全合格的容器名稱,如:DB_1_NAME=/myapp_web_1/myapp_db_1

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章