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

你可能感兴趣的:(运维)