[Docker01] The Docker Road
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
CMD ["
CMD [ "
注意:如果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
例如:
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