容器:是一种基础工具,


docker的优缺点

优势:

模块化,层与镜像版本控制,支持回滚,快速部署

缺点:

隔离性差,安全性较差

容器镜像网站

https://hub.docker.com/

docker 是一个C/S架构应用程序,无论是客户端还是服务器端,都有docker一个程序提供,这个程序有很多子程序,或者叫子命令,叫docker daemon,我们就表示运行为守护进程,所以我们运行docker daemon就把这台主机变成为所谓的守护进程服务器,它可以监听在某个套接字之上,这个套接字为了安全,默认只提供 本机的Unix socket 套接字,

因为docket也是C/S架构的,所有服务器应该监听在套接字上,这个套接字支持三种套接字

1. iPv4加端口

2.ipv6加端口

3.Unix套接字 同一主机上不同进程之间通信时使用

docker host 真正运行容器的主机

containers 容器和images镜像是docker主机上非常重要的组成部分,镜像来自于docker的镜像仓库,默认是去dockhub上下载本地,所有镜像都是只读的,启动容器就是基于镜像启动的,在镜像的基础之上,为一个容器创建一个专用的可写仓,从而启动一个容器

registry docker存放镜像的仓库,默认本地是没有的

images镜像也要在docker的本地存储,但是images镜像有几万条,都放在本地占的内存非常的大,所有放在了一个公共的仓库里面,需要的时候在去下载,但是我们要用必须先加载到本地,这儿用的到的协议是http或https,默认是https,为了安全,只有确认不要安全的,而且明确定义为不安全才可以使用http协议

客户端client和docker host之间也是用http或者https协议

clip_image002

仓库

docker镜像是分层构建的

在一个dock registry上它拥有两重功能

1.

1.提供镜像存储的仓库

2.他还提供用户来获取镜像时的认证第功能

3.同时还提供了当前服务器所有可用镜像的索引,搜索索引

2.在一个docker registry上仓库会有很多,但是一个docker镜像仓库,有仓库的名称,一个仓库叫repository简称repo,镜像有应用到不同程序的上的版本,为了使镜像和应用程序的版本有一定意义的关联,在docker上一个仓库通常只来放一个应用程序的镜像,这个仓库名就是应用程序名。例如这个仓库是放nginx的,那么这个仓库名就叫nginx,nginx有很多版本,1.10一个镜像,后来nginx发展又有了一个镜像1.12 ,1.13, 1,14 ,我们要标记每个镜像,它通过额外给每个镜像添加一个组件叫标签,来标识每个镜像,例如:第一个镜像就叫1.10版的nginx,我们就把镜像叫nginx:1.10,这叫镜像名,用仓库名加标签,才能用来标识一个镜像,一个镜像可以有多个标签,如果要使用最新的稳定版叫 nginx:1.14 nginx :stable

我们还有独立镜像,里面没有应用程序,例如centos 7

镜像是静态的不会运行

容器是动态的,是有生命周期的

安装docker

64为CPU

内核 3.10版本以上

centos7

下载docker 镜像yum仓库

wget https://mirrors4.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo

在原来的镜像是非常的慢的,我们要把镜像指向清华大学的镜像

vim /etc/yum.repos.d/docker-ce.repo

clip_image004

:%s@https://download.docker.com/@https://mirrors4.tuna.tsinghua.edu.cn/docker-ce/@

clip_image006

[es]

name=es

baseurl=http://vault.centos.org/7.4.1708/extras/x86_64/

gpgcheck=0

安装docker

yum install docker-ce -y

第一次启动之前配置文件,默认没有,得自己创建

vim /etc/docker/daemon.json

我们定义这个文件是为了下载镜像快一点,定义一个镜像加速器

docker镜像加速,方法

1.可以使用docker cn

2.可以使用阿里云加速器

3.中国科技大学

编辑vim /etc/docker/daemon.json文件,加一段话

{

"registry-mirrors": ["https://registry.docker-cn.com"]

}

clip_image008

启动服务

systemctl start docker.service

docker version 查看客户端和服务器端的版本信息

clip_image010

docker详细的环境信息

docker version

运行docker

docker search 根据我们指定的条件,搜索镜像】

docker pull 下载到本地 或者docker image pull

docker images 列出本地使所有镜像

例如搜索一个nginx

docker search nginx

nginx要安装的时候可以被centos ,也可以被一些小发行版安装

alpine:是一个构建非常小的镜像文件的一个微型发行版,能给程序提供基础运行但体积非常小。缺点是缺少将来调试的工具,测试使用

下载nginx alpine1.14版

docker image pull nginx:1.14-alpine

clip_image012

查看

clip_image014

查看详细信息

clip_image016

我们也可以这样下载

docker pull busybox

clip_image018

删除镜像

docker image rm 新方法

docker rmi 删除镜像,老方法

创建容器

docker container

create 创建容器

rm 删除容器

start 启动容器

pause 暂停容器

unpause 取消暂停

run 创建完直接启用

ls 查看容器

top 查看容器的资源消耗

docker container ls 查看容器

创建容器

docker run --name b1 -it busybox:latest

--name b1 名字

-it 进入交互式界面

busybox:latest 镜像

例如创建一个网页页面

/ # mkdir /data/html -p 创建目录

/ # vi /data/html/index.html 编辑页面

/ # httpd -f -h /data/html/ -f 执行在前台,-h指定家目录

clip_image020

查看b1的ip地址

docker inspect b1

测试

curl 172.17.0.2

停止容器

clip_image022

查看容器,默认不显示停止的容器

clip_image024

查看停止的容器

docker container ls -a

启用停止的容器

docker container start -ai b1

clip_image026

强制中止。注意不是有特殊情况,不要强制中止,可能会丢失数据

docker kill b1

删除容器

docker rm b1

创建容器

docker run --name web1 -d nginx:1.14-alpine

-d 后台运行

nginx:1.14-alpine 镜像

注意:在容器中,任何程序或服务都不能运行在后台,运行在后台一启动服务就停止

创建容器的时候,如果镜像没有会自动下载

docker run --name kvstor1 -d redis:4-alpine

docker container exec -it kvstor1 /bin/sh

docker 镜像含有容器所需要的文件系统及其内容,因此,其用于创建并启动docker容器

docker镜像采用分层构建机制,大体分为两种

bootfs:最底层的为bootfs引导系统

aufs和btrfs这样的文件系统,来确保引导来启动一个用户空间,bootfs仅仅被用来引导系统,当系统启动完成以后会被卸载,节约空间

rootfs:真正让用户构建用户空间并运行容器的,我们叫rootfs

rootfs位于bootfs只上,表现为docker容器的根文件系统

在传统的模式中,系统启动时,内核挂载rootfs时会首先将其挂载为只读模式,完成自检后将其重新挂载为读写模式

在docker中,整个rootfs是挂载为只读模式的,不会重新挂载为读写模式,而是通过联合挂载机制,在额外挂载一个可写层

启动容器时,docker daemon会试图从本地获取相关的镜像;本

地镜像不存在时,其将从Registry中下载该镜像并保存到本地

docker registry 分类

sponsor registry

mirror registry

vendor registry

private registry 自键registry

一个registry由两部分组成

repository 各种各样的仓库

每一个仓库通常是由特定的镜像,不同的版本所组成的

一个registry 中可以存在多个repository

repository可以分为顶级仓库,和用户仓库

其中顶层仓库直接有仓库名,而用户仓库的格式是用户名/仓库名

一个镜像仓库里面的标识可以用tag,一个仓库上可以有多个tag标签

一个镜像可以有多个tag标签,一个tag只能有一个镜像

index 索引

用于维护用户账号,镜像的校验以及公命名空间的信息

提供一个检索接口

制作镜像

1.dockerfile

2.基于容器制作

3.docker hub automated builds

基于容器制作镜像

基于busybox基础系统上添加一个html页面

docker run --name b1 -it busybox

编辑一个html页面

clip_image028

基于容器制作镜像,不能关闭容器,在其他终端制作镜像

-p 是暂停,防止制作镜像的时候,那边还在不断的生成新的内容,制作镜像只有一半的内容

clip_image030

查看

仓库为空,标签为空,只有ID,id是制作镜像的时候生成的

clip_image032

加入标签

docker tag ad5c89e30e39 magedu/httpd:v0.1-1

docker tag 标签管理命令

如果镜像一个标签也没有就只能用id了ad5c89e30e39

magedu/httpd:v0.1-1 docker hub有一个账号叫magedu。期望上传到magedu这个账号目录下叫做httpd:v0.1-1

查看

clip_image034

我们还可以打标签

docker tag magedu/httpd:v0.1-1 magedu/httpd:latest

给magedu/httpd:v0.1-1 打一个新标签叫 magedu/httpd:latest

查看

clip_image036

删除标签

docker image rm magedu/httpd:latest

并没有真正的删除镜像,只是删除了一个标签

查看新建的内容是否存在

clip_image038

上传镜像

docker login -u docker hub的账户

docker push magedu/httpd 推送仓库

共享镜像

打包压缩镜像

docker save -o myimages.gz magedu/httpd:v0.1-1

magedu/httpd:v0.1-1 镜像

-o myimages.gz 指定压缩的名字格式

下载共享的镜像

clip_image040

六种名称空间:

UTS主机名

User 用户名

Mount 挂载的

IPC 名称间通信的

pid 进程ID的

Net 网络名称空间

docker 自动提供了三种网络

docker network ls

clip_image042

yum install bridge-utils -y

docker 有四种网络模型

closed container 封闭式容器,只有loopabck interface 接口

创建一个容器,使用名称空间,网络名称也包含,但是不设置任何网络设备,不创建虚拟的网络设备,只有lo接口,叫封闭式容器

bridged container 桥接式接口,有一个虚拟网卡,net网络也就是桥接式网络

创建一个容器,这个容器创建一个虚拟的设备,一半在容器上,一半在docker 桥上

joined container 联盟式网络,两个容器间共享

创建一个容器,加入另外一个容器,例如:先有一个容器A,有一个网络名称,然后在创建一个容器B,容器B共享容器A的网络名称空间,UTS空间以及,IPC空间,但是UTS,MOUNT,PID这三个是隔离的,这种我们叫联盟式容器,所以容器A和容器B可以本地式通信,使用lo就可以实现

open container 开放式容器 ,共享物理空间

把一个容器创建完成以后,名称空间共享的是速读机,也是名称共享,当不是共享的容器,

创建容器时,选定使用的网络

查看docker对象的详细信息

docker network inspect bridge

bridged container模型 桥接式接口,有一个虚拟网卡,net网络也就是桥接式网络

docker run --name t1 -it --rm busybox:latest

--rm 关闭容器就自动删除容器

clip_image044

查看有3个网络

clip_image046

加入到bridge,指定bridge,和不指定的效果是一样的-

docker run --name t1 -it --network bridge --rm busybox:latest

clip_image048

加入到none,不创建网络设备

closed container 封闭式容器,只有loopabck interface 接口

docker run --name t1 -it --network none --rm busybox:latest

clip_image050

主机名,就是ID号

clip_image052

clip_image054

创建容器时指定,主机名

docker run --name t1 -it --network bridge -h t1.magedu.com --rm busybox:latest

-h t1.magedu.com -h指定主机名为t1.magedu.com

这个容器通过主机名访问其他容器,我们要解析主机名

自动指向本机

clip_image056

我们不使用默认的DNS服务器,我们指定一个DNS 服务器

docker run --name t1 -it --network bridge -h t1.magedu.com --dns 114.114.114.114 --rm busybox:latest

--dns 114.114.114.114 指定dns

clip_image058

自己定义search

docker run --name t1 -it --network bridge -h t1.magedu.com --dns 114.114.114.114 --dns-search ilinux.io --rm busybox:latest

--dns-search ilinux.io 指定search

clip_image060

在hosts文件中自动解析例如 www.magedu.com 域名

docker run --name t1 -it --network bridge -h t1.magedu.com --dns 114.114.114.114 --dns-search ilinux.io --add-host www.magedu.com:1.1.1.1  --rm busybox:latest

--add-host www.magedu.com:1.1.1.1 解析域名

clip_image062

例如我们的一个容器的ip是17.0.2,在其他主机是无法ping通的,我们是没有路由的,除非你地址

容器主机的物理地址,当是网络中的速读机太多,我们不可能一条一条的指定,所以我们要暴露到对外通信的网络中

暴露的方式有四种

创建容器的时候加-p选项,实现暴露

-p 要暴露的端口

加入这个容器运行nginx,默认监听端口是80 ,容器监听哪个,就暴露哪个,我们将80 暴露出去,暴露在这个容器所在的物理机的物理网卡的ip地址之上的某个端口上,这个端口是动态端口,也就是随机端口,是30000到32767 之间的随机端口,好处是在,假如在一个主机上运行了多个nginx,每个都暴露80 ,每个都使用随机的,就不会导致冲突,

暴露80 端口

docker run --name webp -it --rm -p 80 zhouyafi/httpd:0.1

clip_image064

查看暴露的端口

iptables -t nat -vnL

这条规则是自动生成的,如果删除容器,这条规则也会自动删除

clip_image066

浏览器查看

clip_image068

clip_image070

查看端口映射

docker port webp

clip_image072

我们想固定一个IP地址,不是物理卷机的所有地址

-p 主机地址::容器要暴露的端口

-p 172.20.127.169::80

docker run --name webp -it --rm -p 172.20.127.169::80 zhouyafi/httpd:0.1

查看端口映射

docker port webp

clip_image074

浏览器查看

clip_image076

指定映射的端口为80

指定主机端口,容器要暴露的端口

-p 80:80

docker run --name webp -it --rm -p 80:80 zhouyafi/httpd:0.1

没有指定ip,代表所有ip可用

docker port webp

clip_image078

clip_image080

即指定端口,又指定ip

将容器要暴露的80端口,映射成8080,并指定ip

-p 172.20.127.169:8080:80

docker run --name webp -it --rm -p 172.20.127.169:8080:80 zhouyafi/httpd:0.1

查看端口映射

docker port webp

clip_image082

浏览器测试

clip_image084

如果要暴露容器的多个端口,可以使用多次-p ,但是容器必须监听这个端口,不然没用

-P 大写P 暴露使用端口

所谓暴露所有端口是指,如果你在镜像中已经指定了要暴露的端口,基于镜像启动容器时默认是不会暴露的,除非你使用 -P

联盟式容器,是指让两个容器使用一个名称空间

open container 开放式容器 ,共享物理网络

我们启动两个容器

docker run --name b1 -it --rm busybox

clip_image086

docker run --name b2 -it --rm busybox

clip_image088

正常启动容器,ip是不一样的

我们加入一个选项 --network ,并指明容器

docker run --name b2 --network container:b1 -it --rm busybox

--network container:b1 指明共享b1容器的网络

clip_image090

ip变成了b1 的ip,但是文件系统还是隔离的

在b2上面创建一个页面,并查看监听端口

clip_image092

在b1 查看

clip_image094

在容器内共享主机的网络

docker run --name b2 --network host -it --rm busybox

clip_image096

创建一个网页,并查看监听的端口

clip_image098

浏览器查看

clip_image100

更改docker0的网络ip

编辑daemon.json 文件

vim /etc/docker/daemon.json

{

"registry-mirrors": ["https://registry.docker-cn.com","https://bw5qslxa.mirror.aliyuncs.com"], # 加速器

"bip": "10.0.0.1/16" #容器的ip地址改为10.0. 网段 ,会自动配置dhcp配置地址

}

clip_image102

启动服务

systemctl restart docker

查看

clip_image104

远程控制别的主机的docker,默认是不可以的,默认指定的是/var/run/docker.sock

如果我们想远程控制docker,我们可以更改它的监控ip的端口

vim /etc/docker/daemon.json

监听本机的2375端口,还有本机的所有可用ip

{

"registry-mirrors": ["https://registry.docker-cn.com","https://bw5qslxa.mirror.aliyuncs.com"],

"bip": "10.0.0.1/16",

"hosts": ["tcp://0.0.0.0:2375","unix:///var/run/docker.sock"]

}

clip_image106

启动服务

systemctl start docker

查看端口

clip_image108

在远程主机查看docker

查看有没有容器

docker -H 172.20.127.169:2375 ps

查看镜像

docker -H 172.20.127.169:2375 image ls

怎么创建docker自定义的桥接,或仅主机桥

查看已有的网络

clip_image110

自定义桥接

docker network create -d bridge --subnet "172.98.0.0/16" --gateway "172.98.0.1" mybr0

-d bridge 指定桥接模式

--subnet "172.98.0.0/16" 指定ipv4地址

--gateway "172.98.0.1" 指定网关地址

mybr0 指定桥接的名字

clip_image112

查看

clip_image114

clip_image116

更改网卡名字

ip link set dev br-33a422bb9306 name docker1

创建容器时加入新建的网络mybr0

docker run --name t1 -it --net mybr0 busybox:latest

--net mybr0 指定网络

clip_image118

在创建一个容器连接的网络是bridge

docker run --name t2 -it --net bridge busybox:latest

clip_image120

bridge是否能和mybr0通信?

主机上打开核心转换

cat /proc/sys/net/ipv4/ip_forward

clip_image122

docker存储卷

170839571

容器应用是所有持久存储数据的,是可能有状态的

应用分为

有状态

有状态是当前支持连接请求的处理,一定于此前的处理有关联的

无状态

无状态前后是没有关联关系的

大多数有状态连接,都是要持久存储数据的,例如:mysql reids都是要持久存储数据的

nginx就属于纯粹的无状态应用,当时tomcat一定关系上是有状态应用,但是tomcat可能不是要永久存储数据

任何有状态的应用都要永久存储数据的,可以这么理解

有状态且需要持久存储,例如:mysql

有状态当时无需持久存储 例如:tomcat

无状态也无需存储数据 例如:lvs 各种反向代理服务器

无状态,要持久存储数据、;这种应用极少

可写层是随容器的生命周期而存在的

对应有状态应用,对于储卷要持久存储数据

为什么要用数据卷

关闭并重启容器,其数据不受影响,但删除docker容器,则其更改会丢失

容器存在的问题

存储于联合文件系统中,不易于宿主机访问

容器间数据共享不便

删除容器其数据会丢失

解决方法:卷

卷是容器上的一个或多个目录,此类目录可绕过联合文件系统,与宿主机上的某个目录绑定

例如容器的/var/www和宿主机的vfs/dir<UID> 这个uid是存储卷的ID号

我们要用到存储卷的话,我们不用手动创建也可以,当我们要用到存储卷的时候,在启动或创建docker的时候,在容器初始化的时候,自动创建,启动容器后自动建立所谓的绑定,或关联关系

存储卷的初衷是独立于容器的生命周期实现数据持久化,因此默认情况下删除容器时,不会删除卷

docker有两种类型的存储卷

1.绑定挂载卷 bind mount volume

在宿主机上的路径,需要人工指定一个特定路径,在容器的路径也需要指定一个特定路径,人二者已知路径,建立关联关系

2.docker管理的卷 docker -managed volume

所谓的docker管理卷是只要在容器内指定容器的挂载点是什么,而被绑定的宿主机下的哪个目录我们不需要管,由容器引擎docker的dm自行创建一个目录,或者使用一个以存在目录,以你的存储卷目录建立关联关系

作为临时存储,新初始化一个容器,提供一个空间能用的时候非常有效,但是我们删除容器的时候下次重建容器时,我们必须使用绑定挂载方式,不然的话他会给你重新初始化一个临时的另外一个卷

在容器中使用volumes容器卷

1.docker管理的卷 docker -managed volume

docker run --name b2 -it -v /data busybox

run 创建完容器就启用

--name b2 指定容器的名字为b2

-it 进入交互式界面

-v /data 指定挂载目录为data

busybox 镜像

自动生成一个data目录

clip_image124

查看data关联的目录

docker inspect b2

clip_image126

在关联的目录下创建一个文件

clip_image128

在容器内查看,可以看见在关联目录创建的文件

clip_image130

实现可以在容器和宿主机之间共享数据,这个目录是docker自动生成的

2.绑定挂载卷 bind mount volume

docker run --name b2 -it --rm -v /data/volumes/b2:/data busybox

run 创建完容器就切断容器

--name b2 指定容器名字

-it 进入交互式界面

--rm 退出就删除容器

-v /data/volumes/b2:/data 指定宿主机的目录/data/volumes给b2容器使用并挂载到data目录下

busybox

docker inspect b2 查看详细信息

clip_image132

默认如果在宿主机上没有创建目录,也会自动创建,但必须明确指定一个路径

在宿主机创建一个目录

clip_image134

在容器查看

clip_image136

如果删除容器宿主机上的容器还是存在的

我们重新创建容器,指定宿主机的位置还是那个目录/data/volumes/b2,更改容器 的挂载目录/data/web/html

docker run --name b2 -it --rm -v /data/volumes/b2:/data/web/html busybox

可以看见以前的内容还在

clip_image138

有了脱离容器生命周期的持久功能

我们可以使用模板过滤容器的消息

docker inspect -f {{.Mounts}} b2

查看b2容器的.Mounts的信息

clip_image140

获取容器的ip地址

docker inspect -f {{.NetworkSettings.IPAddress}} b2

clip_image142

让两个容器使用同一个宿主机的卷,实现两个容器的信息共享

b2容器

clip_image144

b3容器

clip_image146

在b3容器加入一条信息,在b2容器查看

clip_image148

b2容器查看

clip_image150

当有多个容器有使用同一个卷的时候,我们可以创建一个支撑的容器,在新的容器初始化的时候复制已经指定卷的容器的操作,

互联网有这种专门制作基础架构的镜像,不用启动,只要创建出来就行

创建基础支撑的容器

docker run --name ifrancon -it -v /data/infracon/volume/:/data/web/html busybox

-v /data/infracon/volume/ 指定存储卷

:/data/web/html 共享目录

busybox 镜像

--name ifrancon 容器的名字

run 创建完容器就启动

基于支撑容器创建的容器

docker run --name nginx --network container:ifrancon --volumes-from ifrancon --rm -it busybox

--network container:ifrancon 使用:ifrancon容器的网络

--volumes-from ifrancon 使用 ifrancon的卷

创建镜像

1.基于容器制作

下载镜像下来,然后进入基于镜像制作容器,然后进入交互式界面,更改配置然后基于这个容器在制作镜像,但是不方便变更配置

2.基于dockerfile制作

基于dockerfile制作镜像

from指令是最重要的且必须为dockerfile文件开篇的第一个非注释行,用于为目标镜像文件构建过程指定基准镜像,后续的指令运行环境,都是基于此镜像所提供的环境来实现。

实践中,基准镜像也就是from指定的镜像可以是任何可用镜像文件,默认情况下,docker build 会在docker当前主机上查找指定的镜像文件,在其不存在时,则会自动从docker hub registry 上拉取所需的镜像文件

mkdir img 创建工作目录

vim Dockerfile 创建dockerfile文件

FROM 指定镜像文件

LABLE 标签 ,镜像的作者

COPY 把宿主机的文件,打包到目标镜像中去,

源文件路径是相对路径,支持通配符。

目标文件路径是绝对路径

复制基本准则

原文件必须是build上下文中的路径,不能是父目录中的文件

如果原文件是目录,则自动的其内部文件或子目录会被递归复制,但是原文件自身不会被复制,意思是把原文件里面的文件复制过去了

如果指定了多个原文件,或者在原文件中使用了通配符,则目标文件必须是一个目录,且必须以/结尾

如果目标文件事先不存在,它会被自动创建,这包括父目录

ADD 把宿主机上的文件或目录,打包进目标镜像文件中

ADD支持url路径,意思是如果宿主机在执行docker build过程中能访问到网络上的某服务器,它可以自动基于url,把这个文件引用下载到本地并打包进镜像文件中

当我们使用ADD指令时,如果后面跟的是要复制的源是一个tar.gz 或者其他tar打包压缩的其他文件,它会自动把这个压缩文件展开为目录

如果ADD所引用的tar文件,不是本地的,是通过url获取到的tar文件是不会自动展开的

WORKDIR 指定工作目录

VOLUME 指定卷目录,但是只能指定容器的挂载目录,而不能指定宿主机上的卷目录

EXPOST 为容器打开指定要监听的端口以实现与外部通信,就是暴露一个端口

我们不能绑定宿主机的ip端口,只能暴露容器要暴露的端口,动态绑定到宿主机上的动态端口,因为我们不知道,我们将来要在那台宿主机上运行镜像容器,不知道那个ip或端口有没有被占用

注意:我们卸载Dockerfile文件中暴露的端口,并不会自动暴露,我们只是说可以暴露,但不会直接暴露,我们在依赖这个镜像创建容器的时候,只要-P就可以暴露端口,它会自动扫描镜像,查看可以暴露的端口

ENV 用于为镜像定义所需要的环境变量,这个环境变量可被dockerfile文件中位于其后的其他指令 如:ENV ADD COPY 等所调用

ENV DOC_ROOT /data/web/html/ DOC_ROOT为变量 /data/web/html/ 变量的值

可以设置多个变量

ENV DOC_ROOT=/data/web/html/ \

WEB_SERVER_PACKGE="nginx-1.15.2"

RUN 当基于dockerfile 构建镜像时要运行的命令,将在docker build中运行

CMD 定义把镜像启动为容器时,如果没有指定运行时候的命令,而默认要运行的命令

注意:我们可以定义多个CMD,但是只有最后一个生效

ENTR YPOINT 类似CMD指令的功能,用于为容器指定默认运行程序,从而使容器像一个单独的可执行程序

与CMD不同的是,由ENTRYPOINT 启动的程序不会被docker run命令指定的参数所覆盖,而且,这些命令行参数会被当做参数传递给ENTRPOINT指定的程序

USER 当我们运行dockerfile中的RUN,CMD ,ENV的时候要用普通用户的身份来运行,不是管理员的身份

USER <UID>|<UserName> 要确定容器中有这个用户

HEALTHCHECK 指令让我们定义一个CMD,这个CMD 是一个固定的关键词,在CMD后指定一个命令,这个命令用于检测主进程工作状态健康与否

HEALTHCHECK NONE 拒绝任何的健康状态检测

HEALTHCHECK 是持续性性的进程

--interval 检查 间隔默认是30s秒

--timeout 超时时长默认30秒

--start-period 等待主进程启动的时间,默认是不等待,我们要设置一个等待时间

--retries 如果发现一个进程失败,默认要检测3次,才确定是失败

当我们指定了健康状态检测,当指令发出时响应值有3种

0 成功

1 不健康

2 余留的,可以自己定义

SHELL 指令用来定义运行程序默认要执行的shell程序

STOPSIGNAL 进程号为ID为1的是能够接受,docker stop命令从而能停止主进程的,主进程停止,容器就停止,stop命令相对于发了一个信号 -15的信号,如果想改变信号,我们可以用STOPSIGNAL定义

ARG 这个参数和前面的ENV相像,ARG是一个变量,ARG只在build-time 过程中使用,而且能够为build命令执行时使用--build-arg传过来,只在build中使用

ONBUILD 在build过程中,在dockerfile中定义一个触发器,这个触发器不是在自己build中执行,而是制作成一个镜像后,被别人在用做基础镜像时在别build时,在后续的build才会执行

*********************************************************************************************************

clip_image152

copy 复制index.html文件到/data/web/html下

echo "<h1>Busybox httpd server. </h1>" > img1/index.html

在img1工作目录下创建index.html 文件

创建镜像

docker build -t tinyhttpd:v0.1-1 ./

-t 指定标签

tinyhttpd 仓库名字

v0.1-1 标签

./ 当前目录是 img1工作目录

clip_image154

查看

clip_image156

测试,

复制文件

docker run --name tinyweb1 --rm tinyhttpd:v0.1-1 cat /data/web/html/index.html

创建一个容器--name tinyweb1使用镜像 tinyhttpd:v0.1-1 查看/data/web/html/index.html,完成以后退出删除容器 --rm

clip_image158

测试复制目录

clip_image160

复制宿主机的ima1工作目录下的yum.repos.d 目录目标到容器目录的/etc/下,因为复制宿主机目录的话只能复制宿主机目录下的文件,所以我们要在容器的/etc目录下写上要复制的目录,这个命令会自动创建

clip_image162

测试

创建镜像

docker build -t tinyhttpd:v0.1-2 /root/img1/

clip_image164

查看目录

docker run --name tinyweb1 --rm tinyhttpd:v0.1-2 ls /etc/yum.repos.d/

clip_image166

********************************************************************************************************************8

用ADD指令,写入一个基于url的tar压缩文件,到目标镜像的/usr/local/src/目录下

注意: 这个压缩文件不会被自动展开

clip_image168

制作镜像

docker build -t tinyhttpd:v0.1-3 /root/img1/

创建容器并查看目录,完成并删除容器

docker run --name tinyweb1 --rm tinyhttpd:v0.1-3 ls /usr/local/src/

clip_image170

测试在本地的tar压缩文件,复制到镜像文件,可以被展开

clip_image172

clip_image174

制作镜像

docker build -t tinyhttpd:v0.1-4 /root/img1/

clip_image176

查看文件被展开

docker run --name tinyweb1 --rm tinyhttpd:v0.1-4 ls /usr/local/src/nginx-1.15.2

clip_image178

*****************************************************************************************************************

WORKDIR 指定工作目录

clip_image180

ADD后面的./当前目录就是WORKDIR指定的工作目录

********************************************************************************************************888

VOLUME 设置存储卷,将/data/mysql目录个宿主机做关联关系

clip_image182

创建镜像

docker build -t tinyhttpd:v0.1-5 /root/img1/

clip_image184

测试

docker run --name tinyweb1 --rm tinyhttpd:v0.1-5 mount

可以看见/data/mysql目录

clip_image186

**********************************************************************************************************88

EXPOSE 指定暴露的端口

暴露tcp的80端口

clip_image188

制作镜像

docker build -t tinyhttpd:v0.1-6 /root/img1/

clip_image190

clip_image192

docker run --name tinyweb1 --rm tinyhttpd:v0.1-6 /bin/httpd -f -h /data/web/html

/bin/httpd 运行httpd服务

-f 前台运行

-h /data/web/html 指定httpd服务的家目录

clip_image194

查看容器的详细信息,并查看容器的ip

docker inspect tinyweb1

clip_image196

测试

clip_image198

查看并没有暴露端口

clip_image200

创建容器的时候加-P

docker run --name tinyweb1 --rm -P tinyhttpd:v0.1-6 /bin/httpd -f -h /data/web/html

查看暴露的端口

docker port tinyweb1

clip_image202

在浏览器访问

clip_image204

ENV设置变量,并赋值

clip_image206

创建镜像

docker build -t tinyhttpd:v0-1.7 /root/img1/

clip_image208

查看

docker run --name tinyweb1 --rm -P tinyhttpd:v0-1.7 ls /usr/local/src/

clip_image210

docker run --name tinyweb1 --rm -P tinyhttpd:v0-1.7 ls /data/web/html

clip_image212

*************************************************************************************************************8

docker run --name tinyweb1 --rm -P tinyhttpd:v0-1.7 printenv

printenv 输出变量信息

clip_image214

重新给变量赋值

docker run --name tinyweb1 --rm -P -e WEB_SERVER_PACKGE="nginx-1.15.1" tinyhttpd:v0-1.7 printenv

-e WEB_SERVER_PACKGE="nginx-1.15.1" -e指定WEB_SERVER_PACKGE变量的值是nginx-1.15.1

clip_image216

查看值

clip_image218

当是我们更改的变量已经在build制作镜像的过程中已经就执行了,这时候更改变量的值,只是更改了变一个名字,值没变

************************************************************************************************************888

RUN 当基于dockerfile 构建镜像时要运行的命令,将在docker build中运行

如果我们要编译安装一个url下载的tar包,我们可以用RUN解压tar包,前提是基础镜像一定要有tar命令

clip_image220

cd进目录

解压tar包

制作镜像

docker build -t tinyhttpd:v0-1.8 /root/img1/

clip_image222

测试

clip_image224

****************************************************************************************************************************

CMD 定义把镜像启动为容器时,如果没有指定运行时候的命令,而默认要运行的命令

clip_image226

CMD运行的程序是httpd程序,不是shell进程,是shell的子进程

当我们创建容器的时候,是无法进入交互式界面的,因为运行的不是shell进程,而是shell下的子进程httpd

我们可以用exec进入交互式界面

docker exec -it tinyweb2 /bin/sh

我们可以用后面添加的命令,覆盖前面镜像指定的命令

clip_image228

注意:我们可以定义多个CMD,但是只有最后一个生效

************************************************************************************************************************88

ENTR YPOINT 类似CMD指令的功能,用于为容器指定默认运行程序,从而使容器像一个单独的可执行程序

与CMD不同的是,由ENTRYPOINT 启动的程序不会被docker run命令指定的参数所覆盖,而且,这些命令行参数会被当做参数传递给ENTRPOINT指定的程序

clip_image230

制作镜像

docker build -t tinyhttpd:v0.2-5 /root/img2/

clip_image232

创建容器测试,成功

docker run --name tinyweb2 -it --rm -P tinyhttpd:v0.2-5

clip_image234

再次测试,发现后加的命令不允许覆盖,而是当做命令参数,追加到后面,只是我们执行的httpd进程,没有交互式界面,所以不执行后面的命令

clip_image236

我们也以指定命令进行覆盖

docker run --name tinyweb2 -it --rm -P --entrypoint "ls /data/web/html" tinyhttpd:v0.2-5

--entrypoint 指定命令

***********************************************************************************************************************8

制作一个nginx镜像,能灵活的上传参数

clip_image238

[root@contes7 ~]# vim img3/Dockerfile

FROM nginx:1.14-alpine

LABEL maintainer="Zhouyafei <1123@ddd.com>"

ENV NGC_DOC_ROOT="/data/web/html/"

ADD index.html ${NGC_DOC_ROOT} 拷贝宿主机上的index.html 到容器的/data/web/html/ 目录下

ADD entrypoint.sh /bin/ 复制本地的entrypoint.sh 脚本到容器的 /bin/目录下

CMD ["/usr/sbin/nginx","-g","daemon off;"] 2.初始化完配置文件,运行CMD,如果CMD的nginx进程启动,ENTRYPOINT进程就退出,成为主进程

/usr/sbin/nginx 执行nginx进程,这个nginx进程是容器的进程

-g 全局参数

daemon off 不要运行为守护进程,我们要把nginx运行为前提

ENTRYPOINT ["/bin/entrypoint.sh"] 1.调用这个脚本初始化出来一个配置文件,这个脚本会运行一个shell进程,在里面初始化配置文件

先运行脚本通过读取环境变量生成配置文件,CMD是当做参数传给ENTRYPOINT的,脚本要调用 ['/usr/sbin/nginx','-g','daemon off;']可以把脚本当做当做参数,在脚本里面加入exec "$@"

clip_image240

[root@contes7 ~]# vim img3/entrypoint.sh

#!/bin/sh

cat > /etc/nginx/conf.d/www.conf << EOF

server{

server_name $HOSTNAME;

listen ${IP:-0.0.0.0}:${PORT:-80}; 如果没有ip变量,默认的ip是0.0.0.0,端口是80

root ${NGX_DOC_ROOT:-/usr/share/nginx/html};

}

EOF

exec "$@" #$@脚本的所有参数 ,exec替换当前进程

加入执行权限

chmod +x img3/entrypoint.sh

在宿主机制作index.html文件

clip_image242

制作镜像

docker build -t myweb:v0.3-6 /root/img3/

clip_image244

创建容器测试

docker run --name myweb1 --rm -P myweb:v0.3-6

clip_image246

查看容器里面的网页配置文件是否存在

clip_image248

查看监听端口

clip_image250

测试访问,访问的nginx的默认网站

clip_image252

测试访问我们监听的主机名

clip_image254

clip_image256

我们可以在创建容器的时候,追加一个监听端口8080

docker run --name myweb1 --rm -P -e "PORT=8080" myweb:v0.3-5

clip_image258

验证

clip_image260

**************************************************************************************************8

EXPOSE 80/tcp 暴露的端口是80

*******************************************************************************************************

HEALTHCHECK 健康检测

clip_image262

HEALTHCHECK --start-period=3s CMD wget -O - -q htt://${IP:-0.0.0.0}:${PORT:-80}/

--start-period=3s 等待检测的时间为3秒

CMD wget -O - -q htt://${IP:-0.0.0.0}:${PORT:-80}/ 检测的命令是 wget -O - -q htt://${IP:-0.0.0.0}:${PORT:-80}/

制作镜像

docker build -t myweb:v0.3-7 /root/img3/

clip_image264

创建容器

测试发现,检测成功

docker run --name myweb1 --rm -P -e "PORT=8080" myweb:v0.3-7

clip_image266

****************************************************************************************************************************

ARG 这个参数和前面的ENV相像,ARG是一个变量,ARG只在build-time 过程中使用,而且能够为build命令执行时使用--build-arg传过来,只在build中使用

clip_image268

ARG author="Zhouyafei <1123@ddd.com>" ARG设置默认值

LABEL maintainer="#{author}"

创建镜像,更改标记为author="pony <qq@ww.com>"

docker build --build-arg author="pony <qq@ww.com>" -t myweb:v0.3-8 /root/img3/

查看

docker image inspect myweb:v0.3-8

clip_image270

****************************************************************************************************************888

ONBUILD 在build过程中,在dockerfile中定义一个触发器,这个触发器不是在自己build中执行,而是制作成一个镜像后,被别人在用做基础镜像时在别build时,在后续的build才会执行

clip_image272

ONBUILD ADD https://nginx.org/download/nginx-1.15.2.tar.gz /usr/local/src/

当有人使用=我的镜像的时候就下载https://nginx.org/download/nginx-1.15.2.tar.gz到/usr/local/src/下

创建镜像

docker build -t myweb:v0.3-11 /root/img3/

测试基于新创建的镜像在制作一个镜像

clip_image274

创建镜像

clip_image276

测试

可以看见下载的文件

clip_image278

#########################################################################