自动化运维之docker上——docker简介、docker的安装、docker镜像

目录

一、docker容器(Container)简介

1、什么是docker

2、传统虚拟化与docker的差别?

3、docker容器的优势

4、容器是如何工作的 

二、docker的安装

1、配置docker的软件源

2、安装docker-ce

3、启动docker

4、查看docker信息

5、docker中镜像的查询及下载

6、docker中镜像的使用

7、测试

三、docker的镜像

1、镜像的分层结构

2、镜像的构建——三部曲

(1)容器的创建(运行)与删除

(2)容器的更改

容器删除后重新启动,之前创建的文件没了。因此需要保存对容器的更改。

(3)镜像的删除

3、镜像的构建——Dockerfile文件

(1)编写Dockerfile文件

 (2)查看镜像

(3)镜像的缓存特性

4、Dockerfile详解

(1)Dockerfile官方文档:

(2)Dockerfile常用指令

(3)Dockerfile实践

5、镜像的优化

1、镜像的优化原则

2、优化实验一:减少镜像的层数,清理镜像构建的中间产物对构建的影响。

3、优化实验二:使用多阶段构建镜像

4、 优化实验三:选择最精简的基础镜像,使用多阶段构建镜像

四、docker命令的常用参数

五、本章总结



一、docker容器(Container)简介

1、什么是docker

自动化运维之docker上——docker简介、docker的安装、docker镜像_第1张图片

 Docker就好比传统的货运集装箱

自动化运维之docker上——docker简介、docker的安装、docker镜像_第2张图片

 Docker是管理容器的引擎。 Docker为应用打包、部署平台,而非单纯的虚拟化技术。

2、传统虚拟化与docker的差别?

自动化运维之docker上——docker简介、docker的安装、docker镜像_第3张图片

3、docker容器的优势

对于开发人员:Build once、Run anywhere。

对于运维人员:Configure once、Run anything。

4、容器是如何工作的 

客户端——>Docker引擎——>仓库

自动化运维之docker上——docker简介、docker的安装、docker镜像_第4张图片

二、docker的安装

1、配置docker的软件源

自动化运维之docker上——docker简介、docker的安装、docker镜像_第5张图片

curl https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -o docker-ce.repo

自动化运维之docker上——docker简介、docker的安装、docker镜像_第6张图片

修改软件docker软件源,只保留上一步中下载的第一个软件源路径,并取消校验。

自动化运维之docker上——docker简介、docker的安装、docker镜像_第7张图片

这样配置的docker软件源没有解决依赖性,因此还需要进一步配置centos源20

自动化运维之docker上——docker简介、docker的安装、docker镜像_第8张图片

wget https://mirrors.aliyun.com/repo/Centos-7.repo

自动化运维之docker上——docker简介、docker的安装、docker镜像_第9张图片

对Centos-7.repo软件源做如下更改(其余部分删除)

自动化运维之docker上——docker简介、docker的安装、docker镜像_第10张图片

软件源配置完成后,更新软件源列表,即可看到docker软件仓库和centos7的软件仓库。

2、安装docker-ce

yum install -y docker-ce

自动化运维之docker上——docker简介、docker的安装、docker镜像_第11张图片

注意:这里有个小建议。在安装时可以把从外部下载的依赖包保存在自己的软件源中,再次安装时可以从自己的软件源中调取。否则每次都从网络上下载依赖包会比较麻烦。

解决办法:更改yum配置,保存缓存,那么在安装完软件后会将软件包保存在指定目录下。

自动化运维之docker上——docker简介、docker的安装、docker镜像_第12张图片

3、启动docker

systemctl enable --now docker        #启动并设置docker开机自启动

4、查看docker信息

docker info            #查看docker信息

自动化运维之docker上——docker简介、docker的安装、docker镜像_第13张图片

5、docker中镜像的查询及下载

docker search yakexi007                #查询容器
    NAME                      DESCRIPTION   STARS     OFFICIAL   AUTOMATED
    yakexi007/game2048                      0                    
    yakexi007/mario                         0                    
    yakexi007/nginx                         0                    
    yakexi007/base-debian10                 0                    
docker pull yakexi007/game2048          #拉取容器中的镜像
docker images                           #查看本地有哪些镜像
    

自动化运维之docker上——docker简介、docker的安装、docker镜像_第14张图片

 自动化运维之docker上——docker简介、docker的安装、docker镜像_第15张图片

注意:docker的所有数据全部保存在目录中。

6、docker中镜像的使用

docker run -d --name demo -p 80:80 yakexi007/game2048        #运行镜像
     -d:打入后台; --name:项目名取为demo(加上名字后方便操作,不加时会随机创建一个名称);
     -p:端口映射(宿主机的80端口映射到docker的80端口)
docker ps                                                    #查看正在运行的镜像

自动化运维之docker上——docker简介、docker的安装、docker镜像_第16张图片

7、测试

在浏览器中访问虚拟机IP,可以访问正在运行中的docker

自动化运维之docker上——docker简介、docker的安装、docker镜像_第17张图片

三、docker的镜像

1、镜像的分层结构

自动化运维之docker上——docker简介、docker的安装、docker镜像_第18张图片

共享宿主机的kernel;base镜像提供的是最小的Linux发行版;同一docker主机支持运行多种Linux发行版;采用分层结构的最大好处是:共享资源

自动化运维之docker上——docker简介、docker的安装、docker镜像_第19张图片

Copy-on-Write 可写容器层;容器层以下所有镜像层都是只读的;docker从上往下依次查找文件;容器层保存镜像变化的部分,并不会对镜像本身进行任何修改;一个镜像最多127层。

2、镜像的构建——三部曲

Docker commit构建新镜像三部曲:

运行容器;修改容器;将容器保存为新的镜像(运行——>修改——>提交)

先拉取一个新镜像busybox

自动化运维之docker上——docker简介、docker的安装、docker镜像_第20张图片

(1)容器的创建(运行)与删除

运行busybox镜像,镜像在运行时会占用终端,并且可以在shell中交互创建文件。+会退出容器进程

docker run -it --name demo busybox        #运行容器

自动化运维之docker上——docker简介、docker的安装、docker镜像_第21张图片

重新启动容器,已经在后台运行,通过“attach”进入容器内部后,可以通过+

+将容器打入后台。

docker start demo         #启动容器
docker attach demo        #提取正在后台运行的容器

自动化运维之docker上——docker简介、docker的安装、docker镜像_第22张图片

关闭容器,将会把后台运行的容器关闭,重新查看进程,确认demo容器已经不在后台运行。

docker stop demo         #关闭容器

自动化运维之docker上——docker简介、docker的安装、docker镜像_第23张图片

(2)容器的更改

容器删除后重新启动,之前创建的文件没了。因此需要保存对容器的更改。

进入busybox容器内部,创建一个file1文件。退出后将更改提交(commit),并重新命名为“demo:v1”那么“demo:v1”就是在“busybox”的基础上新加了一层。通过docker history命令可以查看到两个容器的差别。

自动化运维之docker上——docker简介、docker的安装、docker镜像_第24张图片

删除掉现有的容器demo,进入新的容器“demo:v1”后,可以看到之前的更改了。 

自动化运维之docker上——docker简介、docker的安装、docker镜像_第25张图片

(3)镜像的删除

镜像的删除有两种方法,可以指定镜像名称,也可以指定镜像ID

docker rmi demo:v1                #指定镜像名称
docker rmi f4ac6fa47a2a            #指定镜像ID

自动化运维之docker上——docker简介、docker的安装、docker镜像_第26张图片

此方法的缺点: 效率低、可重复性弱、容易出错;使用者无法对镜像进行审计,存在安全隐患

3、镜像的构建——Dockerfile文件

原理:Dockerfile文件中命令的每一层都是逐层提交的。即将构建的操作逻辑以文件的形式表现出来。

自动化运维之docker上——docker简介、docker的安装、docker镜像_第27张图片

(1)编写Dockerfile文件

vim Dockerfile                            #编辑Dockerfile
    FROM busybox
    RUN touch file1
    Run echo westos > index.html
docker build -t demo:v1 .                 #构建Dockerfile
                    .表示构建的所有数据来自于当前目录

自动化运维之docker上——docker简介、docker的安装、docker镜像_第28张图片

 (2)查看镜像

通过Dockerfile文件生成镜像后,如果只是要进入查看后退出,可以按照如下命令。

docker run  --rm -it demo:v1            #退出时删除容器

通过“docker history”可以看到Dockerfile文件中每一步的执行细节。退出容器后删除,再次查看进程已经查不到了。

自动化运维之docker上——docker简介、docker的安装、docker镜像_第29张图片

(3)镜像的缓存特性

在上一个Dockerfile的最后再创建一个文件file2,构建时可以看到,前边几步在构建“demo:v1”时已经执行过了,所以构建“demo:v2”时不会再次执行,会使用上一次执行的缓存。 

自动化运维之docker上——docker简介、docker的安装、docker镜像_第30张图片

4、Dockerfile详解

(1)Dockerfile官方文档:

Docker Documentation | Docker DocumentationHome page for Docker's documentation自动化运维之docker上——docker简介、docker的安装、docker镜像_第31张图片https://docs.docker.com/

(2)Dockerfile常用指令

FROM 指定base镜像,如果本地不存在会从远程仓库下载。
MAINTAINER 设置镜像的作者,比如用户邮箱等。
COPY

把文件从build context复制到镜像

支持两种形式:COPY src dest 和 COPY ["src", "dest"]

src必须指定build context中的文件或目录

ADD

用法与COPY类似,不同的是src可以是归档压缩文件,文件会被自动解压到dest,也可以自动下载URL并拷贝到镜像:

ADD html.tar /var/www

ADD http://ip/html.tar /var/www

ENV

设置环境变量,变量可以被后续的指令使用:

ENV HOSTNAME sevrer1.example.com

EXPOSE

如果容器中运行应用服务,可以把服务端口暴露出去:

EXPOSE 80

VOLUME

申明数据卷,通常指定的是应用的数据挂在点:

VOLUME ["/var/www/html"]

WORKDIR 为RUN、CMD、ENTRYPOINT、ADD和COPY指令设置镜像中的当前工作目录,如果目录不存在会自动创建。
RUN

在容器中运行命令并创建新的镜像层,常用于安装软件包:

RUN yum install -y vim

CMD 与 ENTRYPOINT

这两个指令都是用于设置容器启动后执行的命令,但CMD会被docker run后面的命令行覆盖,而ENTRYPOINT不会被忽略,一定会被执行。

docker run后面的参数可以传递给ENTRYPOINT指令当作参数。

Dockerfile中只能指定一个ENTRYPOINT,如果指定了很多,只有最后一个有效。

COPY指令:

注意:COPY指令执行时,目标文件只能用相对路径,不能用绝对路径。因此要处理的文件应该和Dockerfile文件放在同一目录下。

vim Dockerfile                         #编辑Dockerfile文件
    FROM busybox
    COPY index.html /                        #COPY命令
docker build -t demo:v1 .              #构建为demo:v1
docker history demo:v1                 #查看demo:v1的构建步骤
docker run --rm -it demo:v1            #仅查看容器demo:v1的执行结果

 自动化运维之docker上——docker简介、docker的安装、docker镜像_第32张图片

ADD指令:

此例中,由于所有指令都是基于第一步“FROM busybox”的镜像,如果busybox镜像中不含有该指令,那么将无法执行。对压缩文件来说,busybox中如果没有tar或者gzip命令,将无法处理压缩文件。因此引入“ADD”指令,执行后可以将压缩文件直接解压成目录。

注意:原文件可以来自本机,也可以来自网络

cat Dockerfile 
        FROM busybox
        COPY index.html /
        ADD nginx-1.20.2.tar.gz /
docker build -t demo:v2 .
docker history demo:v2
docker run --rm -it demo:v2                    #仅执行,不构建

自动化运维之docker上——docker简介、docker的安装、docker镜像_第33张图片

ENV指令:

设置环境变量,变量可以被后续的指令使用

自动化运维之docker上——docker简介、docker的安装、docker镜像_第34张图片

EXPOSE指令:

一般在docker中封装了一些服务,EXPOSE用于将这些服务的端口设置成对外开放。 

自动化运维之docker上——docker简介、docker的安装、docker镜像_第35张图片

以超级玛丽游戏为例:

docker search yakexi007                    #查找镜像
        NAME                      DESCRIPTION   STARS     OFFICIAL   AUTOMATED
        yakexi007/game2048                      0                    
        yakexi007/mario                         0                    
        yakexi007/nginx                         0                    
        yakexi007/base-debian10                 0                    
        yakexi007/base-debian11                 0                    
docker pull yakexi007/mario                #拉取镜像
docker history yakexi007/mario:latest        #查看此镜像的详细信息
docker run -d --name demo -p 80:8080 yakexi007/mario      
                      #后台运行,并将镜像中的8080端口映射为宿主机的80端口

自动化运维之docker上——docker简介、docker的安装、docker镜像_第36张图片

后台运行后,在浏览器访问宿主机的80时,实际上访问的是容器内的8080。可以看到正在运行的镜像。

自动化运维之docker上——docker简介、docker的安装、docker镜像_第37张图片

 VOLUME指令:

申明数据卷,通常指定的是应用的数据挂载点。用于分离容器和数据的,可以是本地,也可以是远程。(相当于数据直接写入宿主机)

由于容器的文件系统是比较慢的,因此通过此方式,将容器中的文件直接挂载到宿主机中,和宿主机中的文件系统保持一致,可以加快文件读写速度。

cat Dockerfile 
        FROM busybox
        VOLUME /data            #创建卷
docker build -t demo:v3 .            #构建为demo:v3

自动化运维之docker上——docker简介、docker的安装、docker镜像_第38张图片

docker history demo:v3
docker run -it --name demo1 demo:v3        #运行容器并命名为demo1

 运行容器后,在卷目录“/data”下新建文件file1,可以查看到卷中内容已发生改变。

自动化运维之docker上——docker简介、docker的安装、docker镜像_第39张图片

docker inspect demo1        #查看demo1的详细信息

 表示宿主机中的这个目录实际上挂载的是容器中的“/data”目录下。

自动化运维之docker上——docker简介、docker的安装、docker镜像_第40张图片

进入此目录下,可以看到之前在容器内创建的文件。且映射的这两个目录是同步的。在宿主机的此目录下创建file2,重新进土容器后,也可以在该卷中看到file2. 

自动化运维之docker上——docker简介、docker的安装、docker镜像_第41张图片

VOLUME的删除:删除容器时,创建的卷不会一起删掉,因此需要单独删除

[root@server1 docker]# docker volume ls
        DRIVER    VOLUME NAME
        local     bdf969483abfb346f3f51ae50655cc4949fc521a5696a7ee043e9b59163c439a
[root@server1 docker]# docker volume rm bdf969483abfb346f3f51ae50655cc4949fc521a5696a7ee043e9b59163c439a

 WORKDIR指令:

为RUN、CMD、ENTRYPOINT、ADD和COPY指令设置镜像中的当前工作目录,如果目录不存在会自动创建。(一般用户切换路径)

RUN指令:

在容器中运行命令并创建新的镜像层,常用于安装软件包:

RUN yum install -y vim

CMD 与 ENTRYPOINT 指令:

cat Dockerfile 
        FROM busybox
        CMD echo "hello world"            #CMD指令
docker build -t demo:v4 .                #构建demo:v4
docker run --rm demo:v4                  #运行后删除(仅查看运行结果)
        hello world                        #运行结果

 CMD里可以写多个,但只有最后一个生效。

自动化运维之docker上——docker简介、docker的安装、docker镜像_第42张图片

书写格式:一般有shell和exec两种书写格式。

Shell和exec格式的区别为:

ENTRYPOINT echo "hello, $name"

Shell格式底层会调用/bin/sh -c来执行命令,可以解析变量,而下面的exec格式不会:ENTRYPOINT ["/bin/echo", "hello, $name"]

需要改写成以下形式:ENTRYPOINT ["/bin/sh", "-c", "echo hello, $name"]

# cat Dockerfile
        FROM busybox
        CMD echo "hello world"                                #shell格式
        CMD echo "hello $hostname"                            #shell格式(解析变量)
        CMD ["/bin/sh", "-c", "echo hello $hostname"]         #exec格式

CMD 与 ENTRYPOINT 区别:

一般情况下,两个命令可以相互替换。区别在于,CMD可以被覆盖而ENTRYPOINT不能被覆盖。

已CMD命令结尾时,Dockerfile默认输出为“hello world”。先构建,再运行,在运行时、传入参数“linux”,这个参数将会覆盖原文件中的CMD命令“world”,输出变为“hello linux”。

[root@server1 docker]# cat Dockerfile             
        FROM busybox
        ENTRYPOINT ["/bin/echo", "hello"]
        CMD ["world"]
[root@server1 docker]# docker build -t demo:v1 .        #构建
[root@server1 docker]# docker run --rm demo:v1            #运行
        hello world
[root@server1 docker]# docker run --rm demo:v1 linux        #运行时传参
        hello linux

自动化运维之docker上——docker简介、docker的安装、docker镜像_第43张图片

一般要进入某个容器而不运行时,可以在运行命令的最后加上“bash”,则会替换掉原本的CMD命令。

docker run --rm -it demo:v3            
docker run --rm -it demo:v3 bash

(3)Dockerfile实践

#Dockerfile文件内容
#vim Dockerfile                                               
  1 FROM centos:7
  2 ADD nginx-1.20.2.tar.gz /mnt
  3 WORKDIR "/mnt/nginx-1.20.2"
  4 RUN yum install -y gcc make pcre-devel zlib-devel
  5 RUN ./configure --prefix=/usr/local/nginx
  6 RUN make
  7 RUN make install
  8 EXPOSE 80
  9 VOLUME /usr/local/nginx/html
 10 CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
docker build -t demo:v1 .                    #构建
docker run -d --name demo demo:v1            #运行

[root@server1 docker]# docker ps                #查看是否运行
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS     NAMES
8b6a5b3e6579   demo:v1   "/usr/local/nginx/sb…"   6 seconds ago   Up 6 seconds   80/tcp    demo

[root@server1 docker]# docker inspect demo | grep IPAddress        #查看容器详细信息
            "SecondaryIPAddresses": null,
            "IPAddress": "172.17.0.2",
                    "IPAddress": "172.17.0.2",


[root@server1 docker]# curl 172.17.0.2            #测试



Welcome to nginx!