[Docker01] The Docker Road

2023-05-01,,

The Docker Road

Docker是什么?

Docker是docker容器为资源分隔和调度的基本单位,封装整个软件运行时环境,为开发者和系统管理员设计的,用于构建,发布和运行分布式应用的平台。

centos6的docker源

[dockerrepo]
name=Docker Repository
baseurl=https://yum.dockerproject.org/repo/main/centos/6/
enabled=1
gpgcheck=1
gpgkey=https://yum.dockerproject.org/gpg

centos7的docker源

[dockerrepo]
name=Docker Repository
baseurl=https://yum.dockerproject.org/repo/main/centos/7/
enabled=1
gpgcheck=1
gpgkey=https://yum.dockerproject.org/gpg

1、docker的安装

yum install docker.io -y
apt-cache show docker.io
apt-get install docker.io -y

2、认识docker

docker不会与内核直接进行交互,而是通过一个底层的工具libercontainer与内核交互的,libercontainer才是真正意义上的容器引擎,他是通过克隆系统调用system call直接创建容器,通过pivot_root系统调用进入容器,且通过直接操作cgroupfs文件实现对文件的管控,docker本身侧重于处理更上层的业务《自己动手写docker》

概念一、NameSpace资源限制

内核级别六种环境隔离

PID NameSpace:Linux 2.6.24,PID隔离
Network NameSpace:Linux 2.6.29,网络设备、网络栈、端口等网络资源隔离
User NameSpace:Linux 3.8,用户和用户组资源隔离
IPC NameSpace:Linux 2.6.19,信号量、消息队列和共享内存的隔离
UTS NameSpace:Linux 2.6.19,主机名和域名的隔离;
Mount NameSpace:Linux 2.4.19,挂载点(文件系统)隔离;

概念二、API(application pragrem interface)

使用API常用的几个函数

clone():在创建新进程的同时创建新的namespace
setns():加入一个已经存在的namespace
unshare():在原先的进程上进行namespace的隔离

概念三、CGroup资源隔离

Linux Control Group即linux控制组, Linux 2.6.24

内核级别,限制、控制与一个进程组群的资源;

   资源:CPU,内存,IO

功能

Resource limitation:资源限制;
prioritization:优先级控制;
Accounting:审计和统计,主要为计费;

* Control:挂起进程,恢复进程;

CGroups的子系统(subsystem)

blkio:设定块设备的IO限制;

* cpu:设定CPU的限制;

* cpuacct:报告cgroup中所使用的CPU资源;

* cpuset:为cgroup中的任务分配CPU和内存资源;

* memory:设定内存的使用限制;

* devices:控制cgroup中的任务对设备的访问;

* freezer:挂起或恢复cgroup中的任务;

* net_cls:(classid),使用等级级别标识符来标记网络数据包,以实现基于tc完成对不同的cgroup中产生的流量的控制;

* perf_event:使用后使cgroup中的任务可以进行统一的性能测试;
hugetlb:对HugeTLB系统进行限制;

CGroups中的术语:

task(任务):进程或线程;
cgroup:一个独立的资源控制单位,可以包含一个或多个子系统;

* subsystem:子系统

* hierarchy:层级

Docker高级部分

Docker 容器概念

AUFS:UnionFS

UnionFS:称之为联合文件系统,之后又称为Another UFS,alternative ufs, Adanced UFS把不同的物理位置的目录合并到同一个目录中。

unionfs有以下特点

AUFS 是一种联合文件系统,它把若干目录按照顺序和权限 mount 为一个目录并呈现出来
默认情况下,只有第一层(第一个目录)是可写的,其余层是只读的。
增加文件:默认情况下,新增的文件都会被放在最上面的可写层中
删除文件:因为底下各层都是只读的,当需要删除这些层中的文件时,AUFS 使用 whiteout 机制,它的实现是通过在上层的可写的目录下建立对应的whiteout隐藏文件来实现的。
修改文件:AUFS 利用其 CoW (copy-on-write)特性来修改只读层中的文件。AUFS 工作在文件层面,因此,只要有对只读层中的文件做修改,不管修改数据的量的多少,在第一次修改时,文件都会被拷贝到可写层然后再被修改。
节省空间:AUFS 的 CoW 特性能够允许在多个容器之间共享分层,从而减少物理空间占用。
查找文件:AUFS 的查找性能在层数非常多时会出现下降,层数越多,查找性能越低,因此,在制作 Docker 镜像时要注意层数不要太多。
性能:AUFS 的 CoW 特性在写入大型文件时第一次会出现延迟

Device mapper

Linux 2.6内核引入的最重要的技术之一,用于在内核中支持逻辑卷管理的通用设备映射机制;

Mapped Device
Mapping Table
Target Device

Docker的架构

Docker:参考链接

docker的发展历史

2013, GO, Apache 2.0, dotCloud--> 出售给cloudControl平台服务提供商

docker架构

docker是一种container,docker daemon是docker的后台主进程,在创建容器的过程中主要通过execdriver和networkdriver两个驱动依赖libcontainer完成请求创建任务,libcontainer通过namespace和cgroup完成对容器的创建任务,容器的images是通过AUFS机制依赖grapgdriver驱动存储数据库中

graph:负责维护已下载的镜像他们之间彼此的关系,graph通过镜像层面的关系以及每层的元数据来记录镜像之间的信息,因此用户对镜像以及容器的操作都会转换为graph对这些镜像和容器的操作;
graphdriver:就是用于实现与graph进行交互的接口
graphdb:记录并管理存储的容器之间的链接关系(图示关系进行链接)

docker客户端模式

Docker Client: 发起docker相关的请求;
Docker Server: 容器运行的节点;
Docker Daemon:Docker daemon是Docker最核心的后台进程,它负责响应来自Docker client的请求,然后将这些请求翻译成系统调用完成容器管理操作。该进程会在后台启动一个API Server,负责接收由Docker client发送的请求;接收到的请求将通过Docker daemon内部的一个路由分发调度,再由具体的函数来执行请求,实际上是驱动整个docker功能的核心

docker核心组件

docker client:docker的客户端工具,是用户使用docker的主要接口,docker client与docker daemon通信并将结果返回给用户;实际上docker的客户端与docker的服务器端是统一在一个二进制文件中;
docker deamon:运行于宿主机上,Docker守护进程,用户可通过docker client与其交互;
image:镜像文件是“只读”的;用来创建container,一个镜像可以运行多个container;镜像文件可以通过Dockerfile文件创建,也可以从docker hub/registry下载;
docker link
docker volume
repository

    * 公共仓库:Docker hub/registry

    * 私有仓库:docker registry
docker container:docker的运行实例,容器是一个隔离环境;
registry:保存docker镜像及镜像层次结构和元数据;
repository:由具有某个功能的镜像的所有相关版本构成的集合;
index:管理用户的账号、访问权限、镜像及镜像标签等等相关的;可以想象成registry的索引;
graph:从registry中下载的Docker镜像需要保存在本地,此功能即由graph完成;

/var/lib/docker/graph,主要是元数据,也有可能是镜像本身;

Docker应用

镜像:包含了启动Docker容器所需要的文件系统层级及其内容;基于UnionFS采用分层结构实现;

bootfs:此层次基本上很少涉及,其上面的
rootfs:根文件系统

Docker特性

隔离应用;
维护镜像;
创建易于分发的应用
快速扩展

Docker基础命令

子命令分类 子命令
Docker环境信息 info,version
容器生命周期管理 create,exec,kill,pause,restart,rm,run,start,stop,unpause
环境信息相关 info,version
系统维护相关 images,inspect,build,commit,pause/unpause,ps,rm,rmi,run,start/stop/restart,top,kill,...
日志信息相关 events,history,logs
Docker hub服务相关 login,logout
与镜像相关的命令 images,search,pull,push,login,logout,commit,build,rmi(127)
与容器相关的命令 run, kill, stop, start, restart, logs, export, import

容器的启动方法:

run:通过镜像创建一个新的容器
start:启动一个处于停止状态的容器

注意:容器的作用是为了跑一个应用,如果应用结束了,容器自然就终止了;

Docker容器

容器创建的步骤:

检查本地是否存在指定的镜像,不存在则从registry下载;
利用镜像启动容器
分配一个文件系统,并且在只读的镜像层之外挂载一个可读写层;
从宿主机配置的网桥接口桥接一个虚拟接口给此容器;
从地址池中分配一个地址给容器;
执行用户指定的应用程序;
程序执行完成后,容器即终止;

docker安装相关目录

编号 路径名 意义
1 /var/lib/docker/devicemapper/devicemapper/data 用来存储相关的存储池数据
2 /var/lib/docker/devicemapper/devicemapper/metadata 用来存储相关的元数据
3 /var/lib/docker/devicemapper/metadata/ 用来存储 device_id、大小、以及传输_id、初始化信息
4 /var/lib/docker/devicemapper/mnt 用来存储挂载信息
5 /var/lib/docker/container/ 用来存储容器信息
6 /var/lib/docker/graph/ 用来存储镜像中间件及镜像的元数据信息 、以及依赖信息
7 /var/lib/docker/repositores-devicemapper 用来存储镜像基本信息
8 /var/lib/docker/tmp docker临时目录
9 /var/lib/docker/trust docker信任目录
10 /var/lib/docker/volumes docker卷目录

Docker Hub:

registry

docker hub

称之为public registry
private registry:

    * 安装docker-registry程序包;yum install docker-registry -y

    * 启动服务:systemctl  start  docker-registry.service

    * 建议使用nginx反代:使用ssl,基于basic做用户认证;

docker扩展

实现nginx反代

-yum install nginx	安装nginx
-vim /etc/sysconfig/iptables 配置iptables过滤规则
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-vim /etc/nginx/conf.d/www.***.com
serevr {
    listen 80;
    server_name www.***.com;     charset utf8;
    access_log /var/log/nginx/www.***.com.log main;
    location / {
        proxy_pass       http://192.168.1.20:80;
        proxy_set_header Host      $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

实现https

-vim /etc/sysconfig/iptables 配置iptables规则
-A INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT
-yum install openssl openssl-devel
-mkdir /usr/local/nginx/conf/ssl 证书存放位置
-cd /usr/local/nginx/conf/ssl
-openssl genrsa -des3 -out server.key 1024 创建服务器私钥(根据提示完成)
-openssl req -new -key serevr.key -out serevr.csr 创建签名请求证书(csr)
依次填入:国家-省份-城市-公司-部门-主机名称-邮箱
#证书请求密钥,CA读取证书的时候需要输入密码
#公司名称,CA读取证书的时候需要输入密码
-openssl rsa -in server.key -out server_nopassword.key #对key进行解密
-openssl x509 -req -days 365 -in server.csr -signkey server_nopassword.key -out server.crt#标记证书使用上述私钥和CSR
nginx使用ssl
-vim /usr/local/nginx/conf/nginx.conf
    listen 80;
    listen 443;
    ssl on;
    ssl_certificate /usr/local/nginx/conf/ssl/server.crt;
    ssl_certificate_key /usr/local/nginx/conf/ssl/server_nopassword.key;
    fastcgi_param HTTPS $https if_not_empty;
-service nginx restart

nginx基于basic认证

server{
    server_name  www.ttlsa.com ttlsa.com;
    index index.html index.php;
    root /data/site/www.ttlsa.com;
    location /
    {
        auth_basic "nginx basic http test for ttlsa.com";
        auth_basic_user_file conf/htpasswd;
       autoindex on;
    }
}
使用htpassswd或者openssl生成密码
# printf "ttlsa:$(openssl passwd -crypt 123456)\n" >>conf/htpasswd
# cat conf/htpasswd
ttlsa:xyJkVhXGAZ8tM
nginx -s reload

docker私有仓库

配置文件 /etc/sysconfig/docker

ADD_REGISTRY='--add-registry 172.16.100.68:5000'
INSECURE_REGISTRY='--insecure-registry 172.16.100.68:5000'    #此项显示哪一个地址不使用https协议访问registry

push镜像

    * tag命令:给要push到私有仓库的镜像打标签;

docker tag  IMAGE_ID  REGISRY_HOST:PORT/NAME[:TAG]

* push命令:

docker  push  REGISRY_HOST:PORT/NAME[:TAG]

* pull镜像

docker  pull  REGISRY_HOST:PORT/NAME[:TAG]

有些时候docker-registry不支持使用因此:

yum install docker-distribution
systemctl start docker-distribution.service
ss -tnlp |grep 5000

推送docker镜像到docker hub

export $DOCKER_ID_USER=bluerdocker
docker login
docker help tag
docker tag centos $DOCKER_ID_USER/centos    #此处的centos为你自己所有的images名称
docker push $DOCKER_ID_USER/centos

Docker的数据卷

Data Volume,数据卷是供一个或多个容器使用的文件或目录;

Docker数据卷的多样性

可以共享于多个容器之间;
对数据卷的修改会立即生效;
对数据卷的更新与镜像无关;
数据卷会一直存在;

数据卷的使用方式

-v  /MOUNT_POINT(此目录指的是运行的docker镜像里面的目录)

默认映射的宿主机路径:/var/lib/docker/volumes/

docker run -it --name imagesname -v /data busybox:latest

-v  /HOST/DIR:/CONTAINER/DIR

/HOST/DIR: 宿主机路径

/CONTAINER/DIR :容器上的路径

docker run -d -P --name web -v /src/webapp:/webapp training/webapp python app.py
docker inspect web #找到web在宿主机终的位置

注意:如果删除了此容器,重新运行一个容器那么其会在/var/lib/docker/volumes/下自动的创建一个新的路径,如果希望继续使用之前的路径下的文件,在启动的时候要指定上一个容器的挂载路径(可以通过docker inspect CONTAINERID | grep Source获取);

(3) 在Dockerfile中使用VOLUME指令定义;

容器之间共享卷:

者--volumes-from=[]               从一个镜像中获取挂载卷;

删除卷:

docker  rm  -v  CONTAINER_NAME 删除容器的同时删除其卷;

docker  run  --rm 选项,表示容器关闭会被自动删除,同时删除其卷(此容器为最后一个使用此卷的容器时);

备份和恢复:

备份:

docker  run  --rm  --volumes-from  vol_container  -v  $(pwd):/backup  busybox:latest  tar  cvf  /backup/data.tar  /data

Docker Network:容器的网络模型:

 封闭式容器(closed container)

1、仅有一个接口:loopback

不参与网络通信,仅适用于无须网络通信的应用场景,例如备份、程序调试等;

--net  none:不使用网络模式

#docker run -it --name test --rm --net none busybox:latest /bin/sh
#ifconfig

2、bridged container:桥接式容器

此类容器都有两个接口:

loopback

以太网接口:桥接至docker daemon设定使用的桥,默认为docker0;

选项:

    --net  bridge 
    -h, --hostname  HOSTNAME
    --dns  DNS_SERVER_IP
docker run -it --rm --name test -h myhost.linuxedu.top --dns 8.8.8.8 busybox:latest /bin/bash
docker run --name web --net bridge busybox:latest httpd -f #使用docker来运行一些守护进程时一定要将其运行在前台
docker run -d --name web --net bridge -p 80:80 busybox:latest htttpd -f #把docker进程运行在后台来运行守护进程,然后通过共享卷把程序运行起来
    --add-host  "HOSTNAME:IP" 
docker run -it --rm --name test -h myhost.linuxedu.top --dns 8.8.8.8 --add-host "docker.com:172.16.100.1" busybox:latest /bin/bash

3、docker0 NAT桥模型上的容器发布给外部网络访问:

-p  仅给出了容器端口,表示将指定的容器端口映射至主机上的某随机端口;

docker run -it --rm -p 80 --net bridge --name web busybox:latest /bin/sh
docker port docker_HOSTNAME    #列出容器映射的端口
​```
-p  <hostPort>:<containerPort>  将主机的<hostPort>映射为容器的<containerPort>
-p  <hostIP>::<containerPort>    将主机的<hostIP>上的某随机端口映射为容器的<containerPort>
-p <hostIP>:<hostPort>:<containerPort>   //限制iP 将主机的<hostIP>上的端口<hostPort>映射为容器的<containerPort>
-P, --publish-all (大写P) 发布所有的端口,跟--expose选项一起指明要暴露出外部的端口;在docker上映射的端口都是随机生成的
docker run -it --rm -P --expose 80 --expose 8080 --expose 443 --net bridge --name web busybox:latest /bin/sh
如果不想启动容器时使用默认的docker0桥接口,需要在运行docker daemon命令时使用-b选项:指明要使用桥;
详细的使用方法:docker help daemon
联盟式容器 启动一个容器时,让其使用某个已经存在的容器的网络名称空间;
--net container:CONTAINER_NAME
docker run --rm --name joined_web --net container:web busybox:latest ifconfig -a
开放式容器 容器使用Host的网络名称空间;(如果物理机可以联机网络,那么该container就可以使用命令安装一些程序包)
--net  host
docker run -it --rm --net host --name web busybox:latest ifconfig -a //显示的将是物理主机上的所有网卡信息;
容器间的依赖关系: 链接机制:linking,选项为:--link
链接的容器可以向被链接的容器传递变量,已初始化被链接的环境;一般借用任务编排工具
docker的一些常见的任务编排工具
编号|提供方|组件
---|---|---
1|docker offical|swarm,machine,compose
2|apache基金会|mesos(底层的任务框架),Marathon
3|Google|K8S
容器的资源限制:
    run命令的选项:(docker help run)
-m
--cpuset-cpus 
--shm-size ...
docker的监控命令:查看端口的映射信息
    ps命令:-a
    images命令:查看当前主机的镜像信息; 
    stats命令:  容器状态统计信息,实时监控容器的运行状态;
    inspect命令:查看镜像或容器的底层详细信息;通常是以Json的格式显示出信息;
-f, --format  {{.key1.key2....}}
docker inspect -f {{.State.Pid}} CONTAINER_NAME
    top命令:用于查看正在运行的容器中的进程的运行状态;
docker top CONTAINER_NAME
    port命令:查看端口映射; 监控工具:google/cadvisor镜像
    docker search google
    docker.io/google/cadvisor-canary 分析容器内部资源以及性能
    提供一个web页面,展示当前主机上所有容器的资源使用状态
    暴露出一个端口,根据此端口进行访问web页面 扩展-轻量级部署多主机之间的docker网络模型以及docker之间的依赖关系(参考以下)
实现容器集群的组件(服务的安装配置及使用)
docker深入研究推荐书籍(由浅入深)
《Docker in Action》
《Using Docker》
《Docker Cookbook》
Dockerfile的学习
docker并不是容器的创建者,而是二次封装了容器,docker通过以下两个组件实现
1、Docker daemon:接收请求
2、Docker Images实现方式
            docker commit //针对于变化的文件提交
            Dockerfile:文本文件,镜像文件构建脚本;
Dockerfile:由一系列用于根据[基础镜像]构建新的镜像文件的专用指令序列组成;
指令:
选定基础镜像
安装必要的程序
复制配置文件和数据文件
自动运行的服务
暴露的端口 基于dockerfile创建的镜像的命令:docker build;docker build --help
【语法格式】
        指令行、注释行和空白行;
        指令行:由指令及指令参数构成;
                指令:其字符不区分大小写;约定俗成,要使用全大写字符;
        注释行:#开头的行,必须单独位于一行当中;
        空白行:会被忽略; FROM指令:必须是第一个非注释行,用于指定所用到的基础镜像;
【语法格式】
    FROM  <image>[:<tag>] 或FROM  <image>@<digest>(digest:表示校验码)
例如:
FROM busybox:latest
FROM centos:6.9
注意:尽量不要在一个dockerfile文件中使用多个FROM指令,避免镜像重名;
MAINTANIER指令:(owner)用于提供信息的指令,用于让作者提供本人的信息;不限制其出现的位置,但建议紧跟在FROM之后;
【语法格式】
MAINTANIER  <author's detail>
例如:
MAINTANIER Linux Operation and Maintance Institute <email>
COPY指令:用于从docker主机复制文件至正在创建的映像文件中;
【语法格式】
    COPY  <src> ...  <dest>     //注意分隔符是空格
    COPY  ["<src>",...  "<dest>"]  (文件名中有空白字符时使用此种格式),注意分割符是逗号
        <src>:要复制的源文件或目录,支持使用通配符;
        <dest>:目标路径,正在创建的镜像文件的文件系统路径;建议使用绝对路径,否则,则相对于WORKDIR而言;
            注意:所有新复制生成的目录文件的UID和GID均为0;
例如:
COPY server.xml /etc/tomcat/server.xml
COPY *.conf   /etc/httpd/conf.d/
注意:
    <src>必须是build上下文中的路径,因此,不能使用类似“../some_dir/some_file”类的路径;
    <src>如果是目录,递归复制会自动行;如果有多个<src>,包括在<src>上使用了通配符这种情形,此时<dest>必须是目录,而且必须得以/结尾;
    <dest>如果事先不存在,它将被自动创建,包括其父目录; ADD指令:类似于COPY指令,额外还支持复制TAR文件,以及URL路径;
【语法格式】
    ADD  <src> ...  <dest>
    ADD  ["<src>",...  "<dest>"]
示例:
ADD haproxy.cfg /etc/haproxy/haproxy.cfg
ADD logstash_*.cnf   /etc/logstash/
ADD   http://www.magedu.com/download/nginx/conf/nginx.conf   /etc/nginx/
注意:以URL格式指定的源文件,下载完成后其目标文件的权限为600;属主属组仍然是为0
<src>必须是build上下文中的路径,因此,不能使用类似“../some_dir/some_file”类的路径;
如果<src>是URL,且<dest>不以/结尾,则<src>指定的文件将被下载并直接被创建为<dest>;如果<dest>以/结尾,则URL指定的文件将被下载至<dest>中,并保留原名;
如果<src>是一个host本地的文件系统上的tar格式的文件,它将被展开为一个目录,其行为类似于tar  -x命令;但是,如果通过URL下载到的文件是tar格式的,是不会自动进行展开操作的;
<src>如果是目录,递归复制会自动行;如果有多个<src>,包括在<src>上使用了通配符这种情形,此时<dest>必须是目录,而且必须得以/结尾;
<dest>如果事先不存在,它将被自动创建,包括其父目录;
ENV指令:定义环境变量,此些变量可被当前dockerfile文件中的其它指令所调用,调用格式为$variable_name或${variable_name};
【语法格式】
    ENV  <key>  <value> //一次定义一个变量
    ENV  <key>=<value> ... //一次可定义多个变量,如果<value>中有空白字符,要使用\字符进行转义或加引号;
例如:
ENV  myName="Obama Clark"   myDog=Hello\ Dog \ myCat=Garfield
等同于:
ENV myName Obama Clark
ENV myDog Hello Dog
ENV myCat Garfield
ENV定义的环境变量在镜像运行的整个过程中一直存在,因此,可以使用inspect命令查看,甚至也可以在docker run启动此镜像时,使用--env选项来修改指定变量的值;
USER指令:指定运行镜像时,或运行Dockerfile文件中的任何RUN/CMD/ENTRYPOINT指令指定的程序时的用户名或UID;
【语法格式】
    USER  <UID>|<Username> 
注意:<UID>应该使用/etc/passwd文件存在的用户的UID,否则,docker run可能会出错;
WORKDIR指令:用于为Dockerfile中所有的RUN/CMD/ENTRYPOINT/COPY/ADD指令指定工作目录;
【语法格式】
    WORKDIR  <dirpath>
            注意:WORDIR可出现多次,也可使用相对路径,此时表示相对于前一个WORKDIR指令指定的路径;WORKDIR还可以调用由ENV定义的环境变量的值;
例如:
```Shell
ENV STATPATH /usr/bin
WORKDIR  /var/log
WORKDIR  $STATEPATH

VOLUME指令:用于目标镜像文件中创建一个挂载点目录,用于挂载主机上的卷或其它容器的卷;

【语法格式】

    VOLUME  

    VOLUME  ["", ...]

注意:如果mountpoint路径下事先有文件存在,docker run命令会在卷挂载完成后将此前的文件复制到新挂载的卷中;

RUN指令:用于指定docker build过程中要运行的命令,而不是docker run此dockerfile构建成的镜像时运行;

【语法格式】

    RUN   或

    RUN  ["", "", "", ...] //无法通配.?*等建议使用下面一种

    RUN ["/bin/bash", "-c", "", "", "", ...]

例如:

RUN yum install iproute nginx && yum clean all

CMD指令:类似于RUN指令,用于运行程序;但二者运行的时间点不同;CMD在docker run时运行,而非docker build;

    CMD指令的首要目的在于为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束;不过,CMD指令指定的程序可被docker run命令行参数中指定要运行的程序所覆盖。

【语法格式】

    CMD    这种与shell解释器有关,或

    CMD  ["", "", "", ...]  这种与shell解释器无关,或

    CMD [ "", "", ...] 这种为ENTRYPOINT指令提供指定的程序提供默认参数;

注意:如果dockerfile中存在多个CMD指令,仅最后一个生效;

CMD ["/usr/sbin/httpd", "-c","/etc/httpd/conf/httpd.conf"]

ENTRYPOINT指令:类似于CMD指令,但其不会被docker run的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给ENTRYPOINT指令指定的程序;但是,如果运行docker  run时使用了--entrypoint选项,此选项的参数可当作要运行的程序覆盖ENTRYPOINT指令指定的程序;

语法格式:

    ENTRYPOINT   或

    ENTRYPOINT   ["", "", "", ...]

例如:

CMD ["-c"]

ENTRYPOINT ["top", "-b"]

EXPOSE指令:用于为容器指定要暴露的端口;

语法格式:

    EXPOSE   [/]  [[/]] ...

        为tcp或udp二者之一,默认为tcp;

例如:

EXPOSE  11211/tcp  11211/udp

ONBUILD指令:定义触发器;

当前dockerfile构建出的镜像被用作基础镜像去构建其它镜像时,ONBUILD指令指定的操作才会被执行;

语法格式:

    ONBUILD  

例如:

ONBUILD ADD my.cnf   /etc/mysql/my.cnf

注意:ONBUILD不能自我嵌套,且不会触发FROM和MAINTAINER指令;

示例1:

FROM busybox:latest
MAINTAINER MageEdu <mage@magedu.com>
COPY index.html  /web/html/index.html
EXPOSE 80/tcp
CMD ["httpd","-f","-h","/web/html"]
WORKDIR: /tmp/busybox-web
index.html
busybox-web.df
~]# docker build  -f  /tmp/busybox-web/busybox-web.cf  -t  busybox:web   /tmp/busybox
~]# docker images

练习:

(1)构建一个基于centos的httpd镜像,要求,其主目录路径为/web/htdocs,且主页存在,并以apache用户的身份运行,暴露80端口;

        (2)进一步地,其页面文件为主机上的卷;

(3)进一步地,httpd支持解析php页面;

(4)构建一个基于centos的maridb镜像,让容器间可互相通信;

(5)在httpd上部署wordpress;

容器导入和导出:

docker  export 

docker  import 

镜像的保存及装载:

docker  save  -o  /PATH/TO/SOMEFILE.TAR  NAME[:TAG]
docker  load  -i  /PATH/FROM/SOMEFILE.TAR 

Dockerfile(2)

示例2:httpd

FROM centos:latest
MAINTAINER MageEdu "<mage@magedu.com>"
RUN sed -i -e 's@^mirrorlist.*repo=os.*$@baseurl=http://172.16.0.1/cobbler/ks_mirror/$releasever/@g' -e '/^mirrorlist.*repo=updates/a enabled=0' -e '/^mirrorlist.*repo=extras/a enabled=0' /etc/yum.repos.d/CentOS-Base.repo && \
yum -y install httpd php php-mysql php-mbstring && \
yum clean all && \
echo -e '<?php\n\tphpinfo();\n?>' > /var/www/html/info.php
EXPOSE 80/tcp
CMD ["/usr/sbin/httpd","-f","/etc/httpd/conf/httpd.conf","-DFOREGROUND"]
docker run --rm --name httpd -P httpd:2.4
docker run -d --name httpd -p 80:80 httpd

[Docker01] The Docker Road的相关教程结束。

《[Docker01] The Docker Road.doc》

下载本文的Word格式文档,以方便收藏与打印。