一、Docker镜像介绍
1、是应用分布的标准格式;
2、可支撑一个 Docker 容器的运行;
二、Docker镜像分层
1、Dockerfile 中的每个指令都会创建一个新的镜像层;
2、镜像层将会被缓存和复用;
3、当 Dockerfile 的指令修改了,复制的文件变化了,或者构建镜像时指定的变量不同了,对应的镜像层缓存就会失效;
4、某一层的镜像缓存失效之后,它之后的镜像层缓存都会失效;
5、镜像层是不变的,如果在某一层中添加一个文件,然后在下一层中删除它,则镜像中依然包含该文件。
容器(可读,可写层)
服务本身镜像层(只读层,模板)
依赖环境镜像层(只读层,模板)
基础镜像镜像层(为以上的系统服务提供支持)
底层内核层
三、Docker镜像的构建方式
1、dockerfile :基于源镜像修改配置,似乎用dockerfile生成所需的镜像,用于新业务
2、基于已有镜像容器进行操作,经常用于业务升级、迁移、镜像打包
3、基于本地模板进行构建(使用较少)
3.1 基于Dockerfile创建
Dockerfile是一个Docker镜像的描述文件,其内部包含了一条条的指令,每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。
Dockerfile 文件结构
Dockerfile文件时以组指令组成,文件结构分为四部分
① 基础镜像信息
② 维护者信息
③ 镜像操作指令
④ 容器启动时执行指令
Dockerfile 操作指令
指令 | 含义 |
---|---|
FROM 镜像 | 指定新镜像所基于的镜像,第一条指令必须为FROM指令,每创建一个镜像就需要一条FROM指令。 |
MAINTAINER 名字 | 说明新镜像的维护人信息 |
RUN命令 | 在所基于的镜像上执行命令,并提交到新的镜像中 |
CMD [“要运行的程序”,“参数1”,“参数2”] | 指令启动容器时要运行的命令或者脚本,Dockerfile只能有一条CMD命令,如果指定多条则只能最后一条被执行 |
EXPOSE 端口号 | 指定新镜像加载到Docker时要开启的端口(EXPOSE暴露的是容器内部端口,需要再映射到一个外部端口上) |
ENV 环境变量 变量值 | 设置一个环境变量的值,会被后面的RUN使用 |
ADD 源文件/目录 目标文件/目录 | 将源文件复制到目标文件(最好的用途是将本地tar文件解压到镜像中) |
COPY 源文件/目录 目标文件/目录 | 将本地主机上的文件/目录复制到目标地点,源文件/目录要与Dockerfile在相同的目录中 |
VOLUME [“目录”] | 在容器中创建一个挂载点(VOLUME是宿主机中的某一个目录挂载到容器中) |
USER 用户名/UID | 指定运行容器时的用户 |
WORKDIR 路径 | 为后续的RUN、CMD、ENTRYPOINT指定工作目录(WORKDIR类似于cd,但是只切换目录一次,后续的RUN命令就可以写相对路径了) |
ONBUILD 命令 | 指定所生成的镜像作为一个基础镜像时所要运行的命令 |
HEALTHCHECK | 健康检查 |
Dockerfile 操作实例
使用Dockerfile安装apache
1.创建一个apache目录并在里面创建一个Dockerfile文件
[root@localhost ~]# mkdir apache && cd apache
[root@localhost apache]# vim Dockerfile
FROM centos #基于的基础镜像
MAINTAINER xhc #维护镜像的用户信息
RUN yum -y update #更新yum源
RUN yum -y install httpd #安装Apache服务
EXPOSE 80 #开启80端口
ADD index.html /var/www/html/index.html #复制网站首页文件
ADD run.sh /run.sh #将执行脚本复制到镜像中
RUN chmod 755 /run.sh #赋予执行权限
CMD ["/run.sh"] #启动容器时执行脚本
2.在apache目录创建一个执行脚本
vim run.sh #和Dockerfile文件位于相同目录下
#!/bin/bash
rm -rf /run/httpd/ * #清除httpd缓存
exec /usr/sbin/apachectl -D FOREGROUND #启动apache
3.在apache目录创建一个网页文件
echo "<h1>HELLO 世界</h1>" > index.html
4、生成镜像并测试
docker build -t httpd:centos . ##生成镜像(注意“ .”)
docker run -d -p 8080:80 httpd:centos ##新镜像运行容器
-p:映射到宿主机指定端口
-P:映射到宿主机随机端口(随机端口从32768开始)
5.查看新建的镜像
[root@docker ~]# docker images
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
364e9199baea httpd:centos "/run.sh" 11 seconds ago Up 11 seconds 0.0.0.0:8080->80/tcp priceless_bhaskara
#每加载一步会生成一个临时的容器,加载完后会删除
访问容器开放的端口
3.2 基于已有镜像容器创建镜像
将原有容器及其环境打包生成新的镜像
格式:docker commit [选项] 容器ID/名称 仓库名称:[标签]
-m :说明信息
-a :作者信息
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
httpd centos 992afbf6e1bd 8 minutes ago 338MB
centos latest 300e315adb2f 3 months ago 209MB
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
364e9199baea httpd:centos "/run.sh" 8 minutes ago Up 8 minutes 0.0.0.0:8080->80/tcp priceless_bhaskara
[root@docker ~]# docker commit -m "test" -a "test" 364e9199baea test:xxx
sha256:2e018562c581a51fe3d4953115445f32556b81db4a1a06ac7cc1f0f813327f1d
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test xxx 2e018562c581 3 seconds ago 338MB
httpd centos 992afbf6e1bd 9 minutes ago 338MB
centos latest 300e315adb2f 3 months ago 209MB
3.3 基于本地模板创建镜像
使用本地的软件包,直接创建镜像
[root@docker ~]# cat httpd-2.4.29.tar.bz2 | docker import - httpd:new
sha256:94529bc28dd89bc03bc48bf1210451119e6bb12d93fd00e9a7c6d7822b628cc3
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
httpd new 94529bc28dd8 4 seconds ago 37.8MB
四、搭建registry私有仓库
registry 和 harbor 的区别
registry:字符界面
harbor: 自己的web页面
4.1 搭建registry私有仓库并上传镜像
1、下载registry镜像
[root@docker ~]# docker pull registry
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry latest 678dfa38fcfa 2 months ago 26.2MB #此为新增的registry镜像
2、创建文件作为私有仓库
[root@docker ~]# vim /etc/docker/daemon.json
{
"insecure-registries": ["192.168.40.11:5000"], #指定本地ip为私有仓库地址
"registry-mirrors": ["https://g8f3gdle.mirror.aliyuncs.com"] #镜像加速
}
[root@docker ~]# systemctl restart docker ##重启docker
docker create -it registry /bin/bash
6b26ebbdb695683e40361e6e1bfb0634ae113e3e586ea6daed05d74ce2ec1437
3、创建容器,开放5000端口,
宿主机的/registry自动创建挂载容器中的 /data/registry
[root@docker ~]# docker run -d -p 5000:5000 -v /registry:/data/registry registry
aa4d61919f8d4f879c95e1843aa828ea3db77de7fd18fb428bba0a8b7f0ad420
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
aa4d61919f8d registry "/entrypoint.sh /etc…" 2 minutes ago Up 2 minutes 0.0.0.0:5000->5000/tcp focused_carver
364e9199baea httpd:centos "/run.sh" 2 hours ago Exited (137) 22 minutes ago priceless_bhaskara
#-p 端口 5000:5000 前者为对外提供的端口,后者为内部端口
#-v 指数据卷的挂载
4、给要上传的镜像打标记
[root@docker ~]# docker tag centos 192.168.40.11:5000/centos
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry latest 678dfa38fcfa 2 months ago 26.2MB
192.168.40.11:5000/centos latest 300e315adb2f 3 months ago 209MB #此为打上新标签的centos镜像
5、上传镜像
[root@docker ~]# docker push 192.168.40.11:5000/centos
Using default tag: latest
The push refers to repository [192.168.40.11:5000/centos]
2653d992f4ef: Pushed
latest: digest: sha256:dbbacecc49b088458781c16f3775f2a2ec7521079034a7ba499c8b0bb7f86875 size: 529
4.2 查看registry私有仓库并下载
1.获取私有仓库列表查看是否上传成功
[root@docker ~]# curl -XGET http://192.168.40.11:5000/v2/_catalog
{"repositories":["centos"]} #[ ]里已有上传的centos镜像了
2.测试私有仓库下载镜像
先删除原有的nginx镜像(删除相关镜像步骤省略)
[root@docker ~]# docker pull 192.168.40.11:5000/centos #下载刚刚上传的镜像
Using default tag: latest
latest: Pulling from centos
Digest: sha256:dbbacecc49b088458781c16f3775f2a2ec7521079034a7ba499c8b0bb7f86875
Status: Downloaded newer image for 192.168.40.11:5000/centos:latest
192.168.40.11:5000/centos:latest
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry latest 678dfa38fcfa 2 months ago 26.2MB
192.168.40.11:5000/centos latest 300e315adb2f 3 months ago 209MB
五、Docker数据卷管理
5.1 为什么要进行数据管理操作
●方便查看容器内产生的数据
●多容器间实现数据共享
例如:需要给多个容器中的网站站点上传网页内容时,可以高效的部署网页
5.2 两种管理方式
- 数据卷
数据卷是容器和宿主之间的数据共享
- 数据卷容器
数据卷容器是容器和容器之间的数据共享
数据卷操作实例
数据卷:数据卷就是在宿主中可以在容器之间进行共享和重用的一系列和文件和文件夹,通过docker run -v命令可以将数据卷挂载到对应的容器目录空间,进行文件读取,容器卷特性如下:
1、数据卷可以在容器之间共享和重用;
2、数据卷修改会立马生效;
3、对数据卷的更新,不会影响镜像;
4、数据卷会一直存在,知道没有容器使用
操作实例:
1、将宿主机目录中的/data1挂载到容器中的/data2中(如果目录不存在都会自动创建)
[root@docker ~]# docker run -v /data1:/data2 --name web1 -it centos:7 /bin/bash
2、在容器中/data2目录下创建文件进行测试
[root@c42371f23c61 /]# cd /data2/
[root@c42371f23c61 data2]# touch 111.txt
3、回到宿主机/data1查看
[root@server1 ~]# ls /data1/
111.txt
数据卷容器操作实例
数据卷容器:接数据卷,已经存在一个挂载了数据卷的容器;由于数据卷在容器之前是可以共享的,所以此时如果存在其他容器通过==docker run --volumes-from [容器别名]==命令挂载到该容器上,则该容器可以被称之为数据卷容器,其主要功能是提供数据卷供其他容器挂载。当数据卷容器宕机后,并不会造成数据卷的回收卸载,数据卷会继续挂载在其他容器中。当全部挂载该数据卷的容器全部宕机后,该数据卷才会卸载。
操作实例:
1.创建数据卷容器web10
[root@docker ~]# docker run --name web10 -v /data1 -v /data2 -it centos:7 /bin/bash
2.新容器web100挂载数据卷容器web10
docker run -it --volumes-from web10 --name web100 centos:7 /bin/bash
(web100容器会自动关联web10容器中的数据卷)
3、在新容器web100的/data1和/data2中创建文件进行测试
[root@da9bdaa71a4a /]# cd /data1
[root@da9bdaa71a4a data1]# touch 123.txt
[root@da9bdaa71a4a data1]# cd ../data2
[root@da9bdaa71a4a data2]# touch 456.txt
4、在web10中/data1和/data2中查看
[root@docker ~]# docker exec -it c265d3a5add3 /bin/bash
[root@8efa8033b0b2 /]# ls /data1
123.txt
[root@8efa8033b0b2 /]# ls /data2
456.txt
六、Docker网络通信
docker 提供了映射容器端口到宿主机和容器互联机制来为容器提供网络服务。
6.1 端口映射
Docker 提供端口映射机制来将容器内的服务提供给外部网络访问,实质上就是将宿主机的端口映射到容器中,使得外部网络访问宿主机的端口便可访问容器内的服务。
[root@docker ~]# docker run -d -P test:xxx
05c7ab72df8c6ab41c666c01bfd4e015a844be1813bfce7a1352a11a83cec1c1
#-P 随机生成端口号
[root@docker ~]# docker run -d -p 8888:80 test:xxx
aa52d1b8ed7876fe6a168174a2524f688a674071d9b1010e0aa34cbee183aadb
#-p 指定端口号 (宿主机端口:容器端口)
[root@docker ~]# docker ps -a #可看到新生成的两个容器端口, 一个是随机一个是指定的8888
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
aa52d1b8ed78 test:xxx "/run.sh" 8 seconds ago Up 7 seconds 0.0.0.0:8888->80/tcp reverent_allen
05c7ab72df8c test:xxx "/run.sh" 27 seconds ago Up 26 seconds 0.0.0.0:49153->80/tcp friendly_mahavira
6.2 容器互联(使用centos镜像)
1、创建并运行web1容器,端口号自动映射
[root@docker ~]# docker run -itd --name web1 centos:7 /bin/bash
2、创建并运行web2容器,链接到web1和其通信。
[root@docker ~]# docker run -itd --name web2 --link web1:web1 centos:7 /bin/bash
9edc0911b65cb617fed3ddd99bee9324b0745ef81edc000032b9cc59c6fba36b
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9edc0911b65c centos:7 "/bin/bash" 10 seconds ago Up 9 seconds web2
6b3ae5b4fc9c centos:7 "/bin/bash" 14 seconds ago Up 13 seconds web1
3、进入web2容器 ping web1
[root@docker ~]# docker exec -it 9edc0911b65c /bin/bash
[root@9edc0911b65c /]# ping web1
PING web1 (172.17.0.2) 56(84) bytes of data.
64 bytes from web1 (172.17.0.2): icmp_seq=1 ttl=64 time=0.200 ms
64 bytes from web1 (172.17.0.2): icmp_seq=2 ttl=64 time=0.073 ms
64 bytes from web1 (172.17.0.2): icmp_seq=3 ttl=64 time=0.082 ms
64 bytes from web1 (172.17.0.2): icmp_seq=4 ttl=64 time=0.078 ms
^C
--- web1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3007ms
rtt min/avg/max/mdev = 0.073/0.108/0.200/0.053 ms