ubuntu系统下的docker

官网:https://www.docker.com/

相关资料:
1、Docker入门教程 http://dockone.io/article/111
2、Docker_百度百科 http://baike.baidu.com/view/11854949.htm
3、史上最全Docker资料集粹 http://special.csdncms.csdn.net/BeDocker/
4、Docker - 话题精华 - 知乎 http://www.zhihu.com/topic/19950993/top-answers
5、docker 简明教程 | 简果网 http://www.simapple.com/docker-tutorial
6、如何使用Dockerfile构建镜像 http://blog.csdn.net/qinyushuang/article/details/43342553
7、Dockerfile reference - Docker https://docs.docker.com/engine/reference/builder/

安装

Docker 要求 Ubuntu 系统的内核版本高于 3.10 ,通过 uname -r 命令查看你当前的内核版本:

  1.  
    [root@bogon ~]# uname -r
  2.  
    3.10.0-327.22.2.el7.x86_64

Docker 支持以下的 Ubuntu 版本:

  • Ubuntu Precise 12.04 (LTS)
  • Ubuntu Trusty 14.04 (LTS)
  • Ubuntu Wily 15.10
  • 其他更新的版本……

当以普通用户身份去使用docker images时,如果出现以下错误:

Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.26/images/json: dial unix /var/run/docker.sock: connect: permission denied

是因为权限问题:

  1.  
    sudo groupadd docker
  2.  
    sudo gpasswd -a ${USER} docker
  3.  
    sudo service docker restart
  4.  
    newgrp - docker

查看文档:
https://docs.docker.com/engine/installation/linux/centos/
http://docs.daocloud.io/faq/install-docker-daocloud

查看版本:

docker version

启动docker服务:

  1.  service docker start
  2. 或者systemctl start docker

为了后面的需要,这里下载个ubuntu的镜像:

  1.  docker search ubuntu# 查看所有可用镜像
  2.  docker pull ubuntu
  3.  docker images -a

这就下载了最新的ubuntu系统镜像到本地,接下来我们可以从该镜像创建多个容器。具体命令含义下面会有说明。

Docker里比较重要的概念有注册服务器、仓库、镜像、容器。

仓库: 注册服务器是存放仓库的地方,其上往往存放着多个仓库。每个仓库集中存放某一类镜像,往往包括多个镜像文件,通过不同的标签(tag)来进行区分。例如存放Ubuntu操作系统镜像的仓库,称为Ubuntu仓库,其中可能包括14.04、12.04等不同版本的镜像。

镜像: Docker镜像(Image)类似于虚拟机镜像,可以将它理解为一个面向Docker引擎的只读模板,包含了文件系统。例如:一个镜像可以只包含一个完整的Ubuntu操作系统环境,可以把它称为一个Ubuntu镜像。

容器: 容器是从镜像创建的应用运行实例,可以将其启动、开始、停止、删除,而这些容器都是相互隔离、互不可见的。可以从一个镜像创建无数个容器。平时我们主要操作的就是容器。我们也可以把容器打包成镜像以方便再次使用。镜像自身是只读的。容器从镜像启动的时候,Docker会在镜像的最上层创建一个可写层,镜像本身将保持不变。

客户端和守护进程

这部分将介绍docker的结构以及docker服务的管理。

Docker 的 C/S 模式

docker是C/S架构,使用client与Server通信。

支持三种连接方式:
unix:///var/run/docker.sock
tcp://host:port
fd://socketfd

Docker 守护进程的配置和操作

使用ps -ef | grep docker查看docker进程。

管理docker服务:

  1.  
    service docker start
  2.  
    service docker stop
  3.  
    service docker restart

docker守护进程的配置和操作模式:

docker -d [OPTIONS]    #-d 以后台方式运行容器。

下面是容器创建时的一些配置,按需添加。初学者可以简单看看,以后需要再来查找。

运行相关:

  1.  
    -D, --debug=false
  2.  
    -e,--exec-driver="native"
  3.  
    -p,--pidfile="/var/run/docker.pid"

服务器相关:

  1.  
    -G,--group="docker"
  2.  
    -H,--host=[]
  3.  
    --tls=false

RemoteAPI相关:

    --api-enable-cors=false

存储相关:

  1.  
    -S,--storage-driver=""
  2.  
    --selinux-enabled=false
  3.  
    --storage-opt=[]

网络设置相关:

  1.  
    -b,--bridge="" 设置自定义网桥
  2.  
    --bip=""
  3.  
    --dns=[]
  4.  
    --ip=0.0.0.0

启动配置文件

Ubuntu: /etc/default/docker
如果没有配置文件,可以直接编辑:

vim  /lib/systemd/system/docker.service

里面的ExecStart就是启动配置,默认是:

ExecStart=/usr/bin/docker -H fd://

我们可以加几个配置:

ExecStart=/usr/bin/docker -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock -H fd:// --label name=server_1

然后重启:

  1.  
    systemctl daemon-reload
  2.  
    systemctl restart docker.service
  3.  
     
  4.  
    # 如果出问题了,可以使用下面命令查看:
  5.  
    systemctl status docker.service

通过ps -ef | grep docker可以查看刚才添加的信息:

  1.  
    [root@localhost ~]# ps -ef | grep docker
  2.  
    root 8262 1 0 23:50 ? 00:00:00 /usr/bin/docker daemon -H tcp://0.0.0.0:4243 -H unix:///var/run/docker.sock -H fd:// --label name=server_1

 

Docker 的远程访问

我们可以从一台安装了docker的机器访问另一台安装了docker的机器。一般情况下我们使用当前机器的docker客户端访问当前机器的Server端。下面演示如何访问其他docker服务端。

第一台IP:192.168.12.3
第二台IP:192.168.12.4

使用第二台安装有docker的服务器做演示。为区分,设置label不同。

修改守护进程(Server)默认的启动配置:
默认是:-H fd://
可修改为:-H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock -H fd:// --label name=server_1

可设置多个连接方式。

第一台访问第二台机器的docker服务:

  • 通过http连接Server:

    curl http://192.168.12.4:2375/info

访问的是服务器192.168.12.4:2375的info接口,返回服务器相关信息。

  • 通过docker客户端访问Server:

    docker -H tcp://192.168.12.4:2375 info

如果是是第一台机器访问第一台机器Docker的服务端,则使用127.0.0.1:2375就行了。

和服务器端一样,客户端也支持三种连接方式,默认是 -H unix:///var/run/docker.sock:
-H unix:///path/to/sock
tcp://host:port
fd://socketfd

docker客户端使用docker info默认访问的是本地Server。可以修改环境变量DOCKER_HOST改变默认连接。命令行直接输入:

export DOCKER_HOST="tcp://127.0.0.1:2375"

127.0.0.1:237可以替换为实际的Server地址。

如果想恢复本地连接,将DOCKER_HOST置空即可:

export DOCKER_HOST=""

Docker容器

容器的基本操作

我们可以从镜像中创建容器。

Docker run IMAGE [COMMOND] [ARG...] 在新的容器中执行命令

该命令每运行一次,就创建了一个新的容器。下面演示从下载好的ubuntu镜像中创建并运行一个新的容器:

  1.  # 只运行一次命令
  2.  docker run ubuntu echo 'hello world' 运行一个新的容器,并执行命令echo 
  3.  # 创建并运行容器,然后进入容器 
  4. docker run -i -t --name test ubuntu /bin/bash 以交互式终端运行一个新的容器,镜像是ubuntu,使用bash,容器别名test

-i 交互式界面,默认是false
-t 伪终端,默认false
--name 容器别名,默认随机命名

exit 退出交互式界面,容器停止运行
Crtl+P 或者Crtl+Q 退出交互式界面,容器在后台运行。(注意是大写P和Q)

查看容器:

  1.  docker ps 查看正在运行的容器
  2.  docker ps -a 查看所有容器
  3.  docker ps -l 查看最近一次运行的容器

示例:

  1.  
    [root@localhost ~]# docker ps -a
  2.  
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  3.  
    8c52c83c1903 redis "docker-entrypoint.sh" 2 hours ago Exited (0) 2 hours ago myredis

容器操作:

  1.  docker create 容器名或者容器ID 创建容器
  2.  docker start [-i] 容器名 启动容器
  3.  docker run 容器名或者容器ID 运行容器,相当于docker create + docker start
  4.  docker attach 容器名或者容器ID 进入容器的命令行
  5.  docker stop 容器名 停止容器
  6.  docker rm 容器名 删除容器
  7.  docker top 容器名 查看WEB应用程序容器的进程
  8.  docker inspect 容器名 查看Docker的底层信息

删除容器时,容器必须是停止状态,否则会报错误。

守护式容器

我们可以使用守护式容器运行一个或者多个服务,例如运行lamp服务、redis服务、mysql服务等。

什么是守护式容器?

  • 能够长期运行
  • 没有交互式会话
  • 适合运行应用程序和服务

启动守护式容器:

docker run -d IMAGE [COMMOND] [ARG...]

-d 让容器在后台运行

后台运行任务:

  1.  docker run -d --name d1 ubuntu /bin/sh -c "while true;do echo hello world;sleep 1;done;"
  2.  输出:b89b9ce64d34bd202a642c8190428f4776f15e882f138949259722f22120201a

返回了一个守护进程的唯一ID。

查看守护进程的运行情况:

  1.  [root@localhost ~]# docker ps
  2.  CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  3.  b89b9ce64d34 ubuntu "/bin/sh -c 'while tr" 3 minutes ago Up 3 minutes d1
  4.  [root@localhost ~]# docker logs -f b89b9ce64d34
  5.  hello world
  6.  hello world
  7.  hello world
  8.  hello world
  9.  hello world
  10.  [root@localhost ~]# docker logs -f -t --tail 2 b89b9ce64d34
  11.  2016-06-26T10:13:19.786516589Z hello world
  12.  2016-06-26T10:13:20.788871572Z hello world
  13.  2016-06-26T10:13:21.791921389Z hello world
  14.  [root@localhost ~]# docker top b89b9ce64d34
  15.  UID PID PPID C STIME TTY TIME CMD
  16.  root 4156 4148 0 06:05 ? 00:00:00 /bin/sh -c while true;do echo hello world;sleep 1;done;
  17.  root 4850 4156 0 06:16 ? 00:00:00 sleep 1
docker logs [-f] [-t] [--tail] 容器名或id       查看容器内WEB应用程序日志

-f --follow=true|false,默认false,一直跟随log变化
-t --timestamps=true|false,默认false,加上时间戳
--tail="all",返回最新多少条日志

在运行的容器中启动新的进程:

docker exec [-d] [-i] [-t] 容器名 [COMMOND] [ARG...]

停止守护式进程:

  1.  
    docker stop 容器名 发送停止信号,等待关闭
  2.  
    docker kill 容器名 直接关闭容器

在容器中部署静态网站

  1.  docker run -d -p 80 -i -t ubuntu /bin/bash 主机端口随机
  2.  docker run -d -p 8080:80 -i -t ubuntu /bin/bash 主机端口自定义
  3.  docker run -d -p 0.0.0.0:80 -i -t ubuntu /bin/bash
  4.  docker run -d -p 0.0.0.0:8080:80 -i -t ubuntu /bin/bash

-P --publish-all=true|false,默认false
-p --publish=[],自定义端口,将容器内部使用的网络端口映射到我们使用的主机上。

  1.  docker run -d -P training/webapp python app.py 后台运行一个容器应用
  2.  docker run -d -p 5000:5000 training/webapp python app.py 容器内部的 5000 端口映射到我们本地主机的 5000 端口上
docker port 容器id            查看到容器的端口映射

Nginx部署示例:

  1.  # 创建映射端口为80的交互式界面:
  2.  docker run -p 80 --name web -i -t ubuntu /bin/bash
  3.  # 第一次使用更新源
  4.  apt-get update
  5. # 安装nginx
  6.  apt-get install nginx
  7.  # 安装vim
  8. apt-get install vim 
  9. whereis nginx
  10.  nginx: /usr/sbin/nginx /etc/nginx /usr/share/nginx
  11.  vim /etc/nginx/conf.d/localhost.conf

发现配置文件在/etc/nginx/conf.d下面:

conf.d/localhost.conf

  1.  server {
  2.  listen 80;
  3.  server_name localhost;
  4.  location / {root /var/www/;index index.html index.htm;}
  5.  }

新建个目录:

  1.  
    mkdir -p /var/www/
  2.  
     
  3.  
    vim /var/www/index.html

内容随便写。

  1.  
    # 启动nginx
  2.  
    nginx

使用Crtl+P(即Crtl+shift+p)退出容器,并后台运行。
查看:

  1.  
    [root@localhost ~]# docker port web
  2.  
    80/tcp -> 0.0.0.0:32769
  3.  
     
  4.  
    [root@localhost ~]# docker top web
  5.  
    UID PID PPID C STIME TTY TIME CMD
  6.  
    root 12123 12113 0 07:14 pts/2 00:00:00 /bin/bash
  7.  
    root 12159 12123 0 07:14 ? 00:00:00 nginx: master process nginx
  8.  
    33 12160 12159 0 07:14 ? 00:00:00 nginx: worker process
  9.  
     
  10.  
    [root@localhost ~]# curl http://127.0.0.1:32769

正常的话会显示网页内容。

如果exit退出了容器,想开启nginx服务,还可以:

  1.  
    docker start web
  2.  
    docker exec web nginx

链接另一个容器

我们可以使用--link使用另一个容器的服务。
创建mysql_db 容器:

docker run --name mysql_db -e MYSQL_ROOT_PASSWORD=123456 -d mysql

创建一个应用,并使用刚才创建的mysql_db容器服务:

docker run --name some-wordpress --link mysql_db:mysql -p 8001:80 -d wordpress

Docker镜像

搜索镜像

docker search [-s] IMAGE

下载镜像

  1.  
    docker pull [OPTIONS] NAME[:TAG|@DIGEST]
  2.  
     
  3.  
    [root@bogon ~]# docker pull ubuntu:16.04
  4.  
    [root@bogon ~]# docker pull daocloud.io/library/ubuntu:16.04

下载镜像名称其实由三部分组成:daocloud.io/library/ubuntu:16.04
其中其中daocloud.io是注册服务器地址,默认是registry.hub.docker.com;ubuntu是仓库名,16.04是标签名,默认是latest。

查看已下载镜像列表

  1.  
    docker images [-a]
  2.  
     
  3.  
    [root@bogon ~]# docker images
  4.  
    REPOSITORY TAG IMAGE ID CREATED SIZE
  5.  
    daocloud.io/library/ubuntu 16.04 12543ced0f6f 2 weeks ago 122.4 MB
  6.  
    ubutun latest 12543ced0f6f 2 weeks ago 122.4 MB
  7.  
    daocloud.io/daocloud/dao-2048 latest 6c1ff658e77e 3 months ago 7.598 MB
  8.  
    daocloud.io/daocloud/alpine latest e9f3e32a4303 3 months ago 11.52 MB
  9.  
    daocloud.io/library/centos 7.1.1503 fac97c5c4748 8 months ago 212.1 MB
  10.  
    daocloud.io/daocloud/dao-redis master-init 173a30377d85 13 months ago 190.4 MB

各个选项说明:

  1.  
    REPOSTITORY:表示镜像的仓库源
  2.  
    TAG:镜像的标签
  3.  
    IMAGE ID:镜像ID
  4.  
    CREATED:镜像创建时间
  5.  
    SIZE:镜像大小

同一仓库源可以有多个 TAG,代表这个仓库源的不同个版本,我们使用 REPOSTITORY:TAG 来定义不同的镜像。

给镜像添加标签

  1.  
    docker tag [OPTIONS] IMAGE[:TAG] [REGISTRYHOST/][USERNAME/]NAME[:TAG]
  2.  
     
  3.  
    [root@bogon ~]# docker tag daocloud.io/library/ubuntu:16.04 ubuntu:latest

删除镜像

  1.  
    docker rmi [OPTIONS] IMAGE [IMAGE...]
  2.  
     
  3.  
    # 按标签删除:多个标签,仅会删除当前标签,不会删除镜像
  4.  
    [root@bogon ~]# docker rmi ubuntu:latest
  5.  
    # 按ID删除:直接删除镜像
  6.  
    [root@bogon ~]# docker rmi 12543ced0f6f

选项:
-f, --force 强制删除镜像
--no-prune 不删除untagged parents

导出镜像

  1.  
    docker save [OPTIONS] IMAGE [IMAGE...]
  2.  
     
  3.  
    [root@bogon ~]# docker save -o ubuntu_latest.tar ubuntu:latest
  4.  
    [root@bogon ~]# ls -l
  5.  
    -rw-r--r--. 1 root root 128086528 Jun 28 12:39 ubuntu_latest.tar

选项:
-o, --output 写入到文件

导入镜像

  1.  
    docker load --input ubuntu_latest.tar
  2.  
    # 或者
  3.  
    docker load < ubuntu_latest.tar

选项:
-i, --input 从压缩包载入镜像

创建镜像

当我们从docker镜像仓库中下载的镜像不能满足我们的需求时,我们可以通过以下两种方式对镜像进行更改。
1.从已经创建的容器中更新镜像,并且提交这个镜像
2.使用 Dockerfile 指令来创建一个新的镜像

从容器生成镜像

假设有一容器2c74d574293f,可以使用commit命令生成镜像:

docker commit -m "create images" -a "52fhy"  2c74d574293f  52fhy/test:v1

-m 加一些改动信息,-a 指定作者相关信息,2c74d这一串为旧容器id,再后面为新镜像的名字。

上传镜像

docker push [OPTIONS] NAME[:TAG|@DIGEST]

选项:
--disable-content-trust=true 跳过镜像签名

Docker仓库

仓库是集中存放镜像的地方。官方提供的公共仓库是https://hub.docker.com。不用注册即可使用里面的众多仓库资源,包含了常用的ubuntu、centos、php、nginx、mysql等仓库。

由于国外仓库访问比较慢,可以使用国内的仓库,一般需要注册,使用docker pull的时候需要指明注册服务器地址。

示例:

docker pull registry.aliyuncs.com/acs-sample/mysql

其中registry.aliyuncs.com是注册服务器地址,acs-sample/mysql是仓库名,所有者是acs-sample,没有指定镜像标签,则默认是latest

根据所存储的镜像公开分享与否,Docker仓库可以分为公开仓库(Public)和私有仓库(Private)两种形式。

搭建私有仓库

详见:Docker私有仓库搭建

Docker数据卷及数据卷容器

在使用容器的过程中,我们可能需要共享数据:
1、共享本地主机数据到容器;
2、共享容器数据到另一个容器。

Docker里的数据卷及数据卷容器恰好满足了这个需求。

数据卷

数据卷(Data Volumes)是一个可供容器使用的特殊目录,它提供了很多有用的特性:

  • 对数据卷的修改会立马生效
  • 数据卷会一直存在,直到没有容器使用
  • 数据卷可以被多个容器使用

数据卷类似于Linux的mount。实质是在当前机器映射了一个目录到容器内部。

创建或运行容器的时候,使用-v创建一个数据卷,多次使用-v可以创建多个数据卷。

  1.  
    docker run -d -P --name test1 -v /data1 ubuntu
  2.  
     
  3.  
    # 挂载本地已有目录到容器中
  4.  
    docker run -d -P --name test2 -v /tmp/data2:/data2 ubuntu
  5.  
     
  6.  
    # 挂载本地已有目录到容器中,指定只读
  7.  
    docker run -d -P --name test3 -v /tmp/data3:/data3:ro ubuntu

挂载的数据卷默认权限是读写rw

数据卷容器

数据卷容器(Data Volume Dontainers)其实就是一个普通的容器,只是我们专门用它提供数据卷供其它容器挂载使用。

创建数据库容器很简单,创建一个普通容器就行了:

docker run --name db1  -v /data ubuntu

其他容器使用该数据卷容器:

docker run  -it --name test4  --volumes-from db1 ubuntu

使用--volumes-from指定数据卷容器。多个--volumes-from将挂载多个数据卷容器。

注意:使用--volumes-from参数所挂载的数据卷容器本身并不需要保持运行状态。如果删除了挂载的容器,数据卷并不会被自动删除,如果要删除一个数据卷,必需使用docker rm -v命令来指定同时删除管联的容器。

使用Dockerfile创建镜像

Dockerfile用来创建一个自定义的image,包含了用户指定的软件依赖等。Dockerfile文件可以用docker build命令生成一个新的镜像。

Dockerfile文件示例:

  1.  
    FROM daocloud.io/centos:7
  2.  
     
  3.  
    # Install Nginx.
  4.  
    # WORKDIR /etc/yum.repos.d/
  5.  
    RUN \
  6.  
    yum update -y && \
  7.  
    yum install -y wget && \
  8.  
    # wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo && \
  9.  
    wget -O /etc/yum.repos.d/CentOs-Base.repo http://mirrors.163.com/.help/CentOS7-Base-163.repo && \
  10.  
    yum makecache && \
  11.  
    yum update -y && \
  12.  
    yum install -y vim && \
  13.  
    yum install -y nginx && \
  14.  
    yum install -y net-tools && \
  15.  
    echo "daemon off;" >> /etc/nginx/nginx.conf && \
  16.  
    echo "master_process off;" >> /etc/nginx/nginx.conf
  17.  
    # Define mountable directories.
  18.  
    VOLUME ["/usr/share/nginx", "/etc/nginx/conf.d", "/var/log/nginx"]
  19.  
    # Define working directory.
  20.  
    WORKDIR /etc/nginx
  21.  
    # Define default command.
  22.  
    CMD ["/usr/sbin/nginx"]
  23.  
    # Expose ports.
  24.  
    EXPOSE 80
  25.  
    EXPOSE 443

运行如下命令:

docker build -t nginx:v1 .

进行镜像构建。成功后,从生成的镜像运行容器:

docker run -d -p 8090:80 nginx:v1

Dockerfile文件语法

(1)FROM(指定基础image)
构建指令,必须指定且需要在Dockerfile其他指令的前面。后续的指令都依赖于该指令指定的image。FROM指令指定的基础image可以是官方远程仓库中的,也可以位于本地仓库。镜像可以指定标签。格式:

FROM <image>:<tag> 

(2)MAINTAINER(用来指定镜像创建者信息)
构建指令,用于将image的制作者相关的信息写入到image中。当我们对该image执行docker inspect命令时,输出中有相应的字段记录该信息。
格式:

MAINTAINER <name> 

(3)RUN
构建指令,RUN可以运行任何被基础image支持的命令。如基础image选择了ubuntu,那么软件管理部分只能使用ubuntu的命令。RUN指令可以有多条,每条RUN指令将在当前镜像基础上执行指定命令,并提交为新的镜像。当命令较长时,可以用\来换行。
该指令有两种格式:

  1.  
    # 在shell终端中运行 - `/bin/sh -c`
  2.  
    RUN <command>
  3.  
     
  4.  
    # 使用exec执行
  5.  
    RUN ["executable", "param1", "param2" ... ]

(4)CMD(设置容器启动时执行的操作)
设置指令,用于容器启动时指定的操作。该操作可以是执行自定义脚本,也可以是执行系统命令。该指令只能在文件中存在一次,如果有多个,则只执行最后一条。
该指令有三种格式:

  1.  
    # 格式一:like an exec, this is the preferred form
  2.  
    CMD ["executable","param1","param2"]
  3.  
     
  4.  
    # 格式二:as a shell
  5.  
    CMD command param1 param2
  6.  
     
  7.  
    # 当Dockerfile指定了ENTRYPOINT,那么使用下面的格式:作为ENTRYPOINT的缺省参数
  8.  
    CMD ["param1","param2"]

注意:
1) CMD运行在镜像构建之后,容器启动的时候;
2) CMD只执行最后一条
3) CMD可以被用户指定的命令覆盖

(5)ENTRYPOINT(设置容器启动时执行的操作)
设置指令,指定容器启动时执行的命令,可以多次设置,但是只有最后一个有效。
两种格式:

  1.  
    # 格式一:like an exec, this is the preferred form
  2.  
    ENTRYPOINT ["executable", "param1", "param2"]
  3.  
     
  4.  
    # 格式二:as a shell
  5.  
    ENTRYPOINT command param1 param2

该指令的使用分为两种情况,一种是独自使用,另一种和CMD指令配合使用。

当独自使用时,如果你还使用了CMD命令且CMD是一个完整的可执行的命令,那么CMD指令和ENTRYPOINT会互相覆盖只有最后一个CMD或者ENTRYPOINT有效:

  1.  
    # CMD指令将不会被执行,只有ENTRYPOINT指令被执行
  2.  
    CMD echo “Hello, World!”
  3.  
    ENTRYPOINT ls -l

另一种用法和CMD指令配合使用来指定ENTRYPOINT的默认参数,这时CMD指令不是一个完整的可执行命令,仅仅是参数部分;ENTRYPOINT指令只能使用JSON方式指定执行命令,而不能指定参数:

  1.  
    FROM ubuntu
  2.  
    CMD ["-l"]
  3.  
    ENTRYPOINT ["/usr/bin/ls"]

注意:
1) 和CMD指令基本一样,但是不能被用户指定的命令所覆盖;
2) 可以和CMD组合使用,ENTRYPOINT提供不可变得命令,CMD提供缺省参数。

(6)USER(设置容器的用户)
设置指令,设置启动容器的用户,默认是root用户。

  1.  
    # 指定memcached的运行用户
  2.  
    ENTRYPOINT ["memcached"]
  3.  
    USER daemon
  4.  
     
  5.  
    # 或
  6.  
    ENTRYPOINT ["memcached", "-u", "daemon"]

(7)EXPOSE(指定容器需要映射到宿主机器的端口)
设置指令,该指令会将容器中的端口映射成宿主机器中的某个端口。格式为:

EXPOSE <port> [<port> ...]

例如:

EXPOSE 80 443 11211

告诉Docker服务端容器暴露的端口号,供互联系统使用。在启动容器时需要通过-P,Docker主机会自动分配一个端口转发到指定的端口;使用-p,则可以具体指定哪个本地端口映射过来。

(8)ENV(用于设置环境变量)
构建指令,在image中设置一个环境变量。格式:

ENV <key> <value>

设置了后,后续的RUN命令都可以使用,容器启动后,可以通过docker inspect查看这个环境变量,也可以通过在docker run --env key=value时设置或修改环境变量。

假如你安装了JAVA程序,需要设置JAVA_HOME,那么可以在Dockerfile中这样写:

ENV JAVA_HOME /path/to/java/dirent

(9)ADD(从src复制文件到容器的dest路径)
构建指令,所有拷贝到容器中的文件和文件夹权限为0755,uid和gid为0。格式为:

ADD <src> <dest> 

<src> 是相对被构建的源目录的相对路径,可以是文件或目录的路径,也可以是一个远程的文件url;<dest>是容器中的绝对路径。

该命令将复制指定的<src>到容器中的<dest>。其中<src>可以是Dockerfile所在目录的一个相对路径(文件或目录);也可以是一个URL;还可以是一个tar文件(自动解压为目录)。

如果是一个目录,那么会将该目录下的所有文件添加到容器中,不包括目录;如果文件是可识别的压缩格式,则docker会帮忙解压缩(注意压缩格式);如果<src>是文件且<dest>中不使用斜杠结束,则会将<dest>视为文件,<src>的内容会写入<dest>;如果<src>是文件且<dest>中使用斜杠结束,则会<src>文件拷贝到<dest>目录下。

(10)COPY
格式为

COPY <src> <dest>

复制本地主机的<src>(为Dockerfile所在目录的相对路径,文件或目录)为容器中的<dest>。目标路径不存在时,会自动创建。
当使用本地目录为源目录时,推荐使用COPY。

(11)VOLUME(指定挂载点))
设置指令,使容器中的一个目录具有持久化存储数据的功能,该目录可以被容器本身使用,也可以共享给其他容器使用。我们知道容器使用的是AUFS,这种文件系统不能持久化数据,当容器关闭后,所有的更改都会丢失。当容器中的应用有持久化数据的需求时可以在Dockerfile中使用该指令。格式:

VOLUME ["<mountpoint>"] 

示例:

  1.  
    FROM base
  2.  
    VOLUME ["/tmp/data"]

运行通过该Dockerfile生成image的容器,/tmp/data目录中的数据在容器关闭后,里面的数据还存在。例如另一个容器也有持久化数据的需求,且想使用上面容器共享的/tmp/data目录,那么可以运行下面的命令启动一个容器:

docker run -t -i -rm -volumes-from container1 image2 bash  

container1为第一个容器的ID,image2为第二个容器运行image的名字。

(12)WORKDIR(切换目录)
设置指令,可以多次切换(相当于cd命令),对RUN,CMD,ENTRYPOINT生效。格式:

WORKDIR /path/to/workdir  

示例:

  1.  
    # 在 /p1/p2 下执行 vim a.txt
  2.  
    WORKDIR /p1
  3.  
    WORKDIR p2
  4.  
    RUN vim a.txt

(13)ONBUILD(在子镜像中执行)

ONBUILD <Dockerfile关键字>  

ONBUILD 指定的命令在构建镜像时并不执行,而是在它的子镜像中执行。

(14)ARG(指定构建过程中使用的环境变量)

  1.  
    ARG buildno
  2.  
    ARG password
  3.  
     
  4.  
    RUN echo "Build number: $buildno"
  5.  
    RUN script-requiring-password.sh "$password"

Docker Compose

Compose是用于定义和运行复杂Docker应用的编排工具(旧版本叫Fig)。你可以在一个文件中定义一个多容器的应用,然后使用一条命令来启动你的应用,然后所有相关的操作都会被自动完成。

资料:
https://docs.docker.com/compose
https://github.com/docker/compose

安装Compose

  1.  
    # 方法一:
  2.  
    curl -L https://github.com/docker/compose/releases/download/1.8.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
  3.  
    chmod +x /usr/local/bin/docker-compose
  4.  
     
  5.  
    # 方法二:
  6.  
    yum install python-pip python-dev
  7.  
    pip install docker-compose

查看版本号:

  1.  
    $ docker-compose --version
  2.  
    docker-compose 1.8.0

Compose示例

docker-compose.yml内容

  1.  
    web:
  2.  
    image: wordpress:latest
  3.  
    links:
  4.  
    - db:mysql
  5.  
    ports:
  6.  
    - "8002:80"
  7.  
    db:
  8.  
    image: mysql
  9.  
    environment:
  10.  
    - MYSQL_ROOT_PASSWORD=123456

启动应用:

docker-compose up

docker-compose.yml常用指令

image:镜像的ID
build:直接从pwd的Dockerfile来build,而非通过image选项来pull
links:连接到那些容器。每个占一行,格式为SERVICE[:ALIAS],例如 – db[:database]
external_links:连接到该compose.yaml文件之外的容器中,比如是提供共享或者通用服务的容器服务。格式同links
command:替换默认的command命令
ports: 导出端口。格式可以是:

  1.  
    ports:
  2.  
    -"3000"
  3.  
    -"8000:8000"
  4.  
    -"127.0.0.1:8001:8001"

expose:导出端口,但不映射到宿主机的端口上。它仅对links的容器开放。格式直接指定端口号即可。
volumes:加载路径作为卷,可以指定只读模式:

  1.  
    volumes:
  2.  
    -/var/lib/mysql
  3.  
    - cache/:/tmp/cache
  4.  
    -~/configs:/etc/configs/:ro

volumes_from:加载其他容器或者服务的所有卷

  1.  
    environment:
  2.  
    - RACK_ENV=development
  3.  
    - SESSION_SECRET

env_file:从一个文件中导入环境变量,文件的格式为RACK_ENV=development
extends:扩展另一个服务,可以覆盖其中的一些选项。一个sample如下:

  1.  
    # common.yml
  2.  
    webapp:
  3.  
    build:./webapp
  4.  
    environment:
  5.  
    - DEBUG=false
  6.  
    - SEND_EMAILS=false
  7.  
     
  8.  
    # development.yml
  9.  
    web:extends:
  10.  
    file: common.yml
  11.  
    service: webapp
  12.  
    ports:
  13.  
    -"8000:8000"
  14.  
    links:
  15.  
    - db
  16.  
    environment:
  17.  
    - DEBUG=true
  18.  
    db:
  19.  
    image: postgres

net:容器的网络模式,可以为"bridge", "none", "container:[name or id]", "host"中的一个。
dns:可以设置一个或多个自定义的DNS地址。
dns_search:可以设置一个或多个DNS的扫描域。
其他的working_dir, entrypoint, user, hostname, domainname, mem_limit, privileged, restart, stdin_open, tty, cpu_shares,和docker run命令是一样的,这些命令都是单行的命令。例如:

  1.  
    cpu_shares:73
  2.  
    working_dir:/code
  3.  
    entrypoint: /code/entrypoint.sh
  4.  
    user: postgresql
  5.  
    hostname: foo
  6.  
    domainname: foo.com
  7.  
    mem_limit:1000000000
  8.  
    privileged:true
  9.  
    restart: always
  10.  
    stdin_open:true
  11.  
    tty:true

常见问题

安装出错

1、Transaction check error

  1.  
    Transaction check error:
  2.  
    file /usr/lib/systemd/system/blk-availability.service from install of device-mapper-7:1.02.107-5.el7_2.1.x86_64 conflicts with file from package lvm2-7:2.02.105-14.el7.x86_64
  3.  
    file /usr/sbin/blkdeactivate from install of device-mapper-7:1.02.107-5.el7_2.1.x86_64 conflicts with file from package lvm2-7:2.02.105-14.el7.x86_64
  4.  
    file /usr/share/man/man8/blkdeactivate.8.gz from install of device-mapper-7:1.02.107-5.el7_2.1.x86_64 conflicts with file from package lvm2-7:2.02.105-14.el7.x86_64
  5.  
     
  6.  
    Error Summary

运行命令:yum install libdevmapper* -y

2、http://blog.csdn.net/baidu_36342103/article/details/69357438

posted @ 2018-09-04 08:42  小裁缝  阅读(585)  评论(0编辑  收藏  举报