Docker 初见

Docker 初见

一、概念

1.1、Docker 存在的意义?

Docker 的存在是为了解决开发到部署中间存在的各种困难,例如,由于环境不一致,运维拿去还要进行很多相关环境的配置、安装,且环境装好后不一定还能进行成功的部署,工作中带来了很大的麻烦。Docker 就可以完美的解决这一问题;

Docker 可以实现,进行一次构建就可以到处运行的理念(将我们所用到的所有环境,包括各种配置、应用环境等),可以类比为 Java 的可跨平台性,可以比作一个简易版的 Linux 环境;

1.2、组成

1.2.1、Docker 架构图

image-20211213201637469

1.2.2、各个模块概念

Docker 利用容器(Container)独立的运行一个或者一组应用,容器是用来镜像创建实例运行的地方;

它可以启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台;就相当于一个简易版的 Linux 环境,包括各种配置等;

Client

Client 就是一个可以操作 Docker 的客户端,可以运行各种操作 Docker 的命令。当一个容器运行一个服务时,当我们需要的时候,我们就通过 Docker 客户端创建一个对应的运行实例,也就是容器;

Images

Images 称为镜像,我们把应用程序和配置依赖打包成一个可以交付的运行环境,这个打包好的运行环境就是 Images 镜像文件,我们可以通过该镜像文件创建 docker 容器实例;Images 可以看做是容器的模板,同一个 Images 可以同时创建多个实例;

Registry

仓储,就是存放我们镜像的地方,我们可以把镜像发布到仓储中,在需要的时候拉下来创建实例即可;

1.3、Docker 下载安装

基于 Centos 7 下安装 Docker;

安装

1.3.1、卸载旧版本 Docker

如果安装过旧版本的 Docker 需要先卸载旧版本的 Docker;

yum remove docker  docker-common docker-selinux docker-engine

1.3.2、安装所需要的依赖

yum-utils、 device-mapper-persistent-data、 lvm2

yum install yum-utils device-mapper-persistent-data lvm2

1.3.3、添加 yum 源

我们这里直接添加为阿里云的源,国外的源太慢了;

yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

1.3.4、查看版本

查看 yum 软件仓库中的所有版本的 docker 软件;

yum list docker-ce --showduplicates | sort -r

1.3.5、安装

yum install -y docker-ce

选择版本安装:

yum install docker-ce-17.12.0.ce

1.3.6、设置开机启动,并开启服务

systemctl enable docker
systemctl start docker

1.3.7、检查版本

docker version

image-20211213211305483

到这里就算是安装成功了;

1.3.8、配置阿里云镜像加速

进入到阿里云获取指定的自己的加速地址(自己去申请);

image-20211225161145667

在 Linux 相应的位置上创建配置文件(如果没有的话)

vim /etc/docker/daemon.json

写入 json 文件中对应的信息
{
"registry-mirrors": ["https://0****7a.mirror.aliyuncs.com"]
}

重启服务

systemctl daemon-reload
systemctl restart docker

1.4、Docker 的 Hello World

docker run hello-world

Docker 首先会在本地找 hello-world 的镜像,在找不到的时候,就会去 DockerHub 找,找到了就会自动下载到本地的库里,我们这里配置了阿里云的 DockerHub 的镜像加速器;

二、常用命令

我们在系统里可以尝试使用 docker --help 来查看更多的命令或者指南;

docker [OPTIONS] COMMAND

docker --help

2.1、搜索镜像

docker search xxx

image-20211216211551870

可以加上 -f [条件] 选项进行筛选

docker  search -f stars=30  tomcat

2.2、拉取下载镜像

拉取下载镜像到本地仓库

docker pull tomcat

上述命令的默认是 docker pull tomcat:latest

2.3、查询本地仓库中的镜像

查询本地仓库中的镜像的 docker 镜像

docker images

image-20211217203405842

仅仅显示镜像 id

docker images -q

image-20211217203421828

2.4、镜像删除命令

docker rmi -f [镜像名]....

组合命令

docker rmi -f $(docker images -q)

2.5、运行命令

docker run [OPTIONS] IMAGE  

这里以 Centos 为例做笔记

docker run -it centos
--name "容器新名字"为容器指定一个名字
-d 后台运行容器,并返回容器 id,也即启动守护式容器
-i 以交互模式运行容器,通常以 -t 同时使用
-t 为容器重新分配一个伪输入终端,通常与 -i 同时使用
-P(大写) 随机端口映射
-p(小写) 指定端口映射一般有以下四种形式
	ip:hostport:containerPort
	ip:containerPort
	containerPort

2.5.1、大小写 -p 的端口映射用法

在后面的笔记写!

[小写看这里](###用参数小 p 运行)

[大写看这里](###大 P 随机分配映射端口)

2.6、查看 docker 中运行的容器

docker ps -[选项]
选项
-a 列出当前所有正在运行的容器和历史运行过的
-l 列出最近创建的容器
-n 显示最近n个创建的容器
-q 静默模式,只显示容器编号
--no-trunc 不截断输出

查看所有容器的另一种办法,虽然上边的更好用,但是写都写了

docker container ps -a

image-20211218211501716

2.7、退出容器

# 直接关闭容器并退出
exit
# 退出但不关闭
ctrl + p + q

看下面 [退出但不关闭,如何重新进入?](###2.13.2、直接进入到 Centos);

2.8、强制停止容器

docker kill container-id或容器名

2.9、启动或者重启容器

docker start container-id或者names
docker restart container-id或者names

2.10、删除容器

docker rm container-id

2.11、启动守护进程

以守护进程启动,默认在自动启动之后进行”自杀“

docker run -d 容器名或者容器id

2.12、查看容器日志

docker logs [参数] 容器id或容器名
-f 跟随最新的日志打印
-t 加入时间戳
--tail 显示最后几条

2.13、重新进入系统执行命令

2.13.1、直接拿到返回结果

在 docker 中的 centos_1 的容器中的 /etc 目录下执行 ls -a 命令

docker exec -it centos_1 ls -a /etc

2.13.2、直接进入到 Centos

对应我们前面所写的,重新进入系统

docker attach centos_1

2.13.3、从docker中拷贝文件

docker cp centos_1:/tmp/hello.txt /root

三、镜像原理

我们通常在远端仓库里拉取下来的镜像都是内置了环境的,比如说我们拉下来的 Tomcat 很大,有624 M。

image-20211218201026398

其实是里面包含了很多东西包含了能支撑 Tomcat 运行起来的一切的环境配置等,所以会很大。

3.1、用小 p 指定端口映射方式运行

-p

我们这里拉取了一个版本号为 9.0.24 的Tomcat,并通过我们之前介绍的一种端口映射方式将其运行起来

docker pull tomcat:9.0.24
docker run -it --name tomcat01 -p 8989:8080 tamcat:9.0.24

image-20211218201725563

那么这样一来的意思是我们通过地址 ip:8989, 就可以对 Tomcat 进行访问了。

-p 8989:8080 的意义在于,将外部真实虚拟机的端口 8989 映射到 docker 中的端口 8080 即可。

3.2、大 P 随机分配映射端口

docker run -it -P tomcat:9.0.24

image-20211218203852418

3.3、镜像的提交/构建

将正在运行的容器,打包成镜像!

docker commit -a="atroot" -m="helloworld docker commit test" 6f9f849b2099 atroot/tomcat:1.0

-a 代表的是作者

-m 代表描述?

后面的 image-id 是修改后的 container-id,将其打成 images

以名为 atroot/tomcat:1.0 的形式发布;

image-20211218211117957

3.4、镜像导出

为什么要做导入导出?因为我们在开发过程中,我们自己打包好了的镜像肯定会交给其他的人来运行,那么这个时候,就会涉及到镜像的打包、导出、导入操作;

docker save [option] 生成文件名 被导出镜像
docker save -o my_tomcat.tar atroot/mytomcat_1:1.0

image-20211225130937626

3.5、镜像导入

docker load [option] 
docker load --input my_tomcat.tar

-input , -i 导入指定的文件

image-20211225131951979


四、DockerFile(重要)

4.1、Dockerfile 是什么?

一个 Dockerfile 文件示例

#基于centos镜像
FROM centos

#维护人的信息
MAINTAINER The CentOS Project <303323496@qq.com>

#安装httpd软件包
RUN yum -y update
RUN yum -y install httpd

#开启80端口
EXPOSE 80

#复制网站首页文件至镜像中web站点下
ADD index.html /var/www/html/index.html

#复制该脚本至镜像中,并修改其权限
ADD run.sh /run.sh
RUN chmod 775 /run.sh

#当启动容器时执行的脚本文件
CMD ["/run.sh"]

由上面的信息我们可以知道,Dockerfile 结构大致分为四个部分:

  1. 基础镜像信息
  2. 维护者信息
  3. 镜像操作指令
  4. 容器启动时执行指令

4.2、执行 Dockerfile 的大致流程

  1. docker 从基础镜像运行一个容器
  2. 执行指令并对容器做出修改
  3. 执行类似 docker commit 的操作提交一个新的镜像
  4. docker 运行上一步提交的新容器
  5. 执行 Dockerfile 中的下一条指令知道所有命令都执行完成

4.3、Dockerfile 的一些命令

FROM

基于哪个镜像进行改造;

MAINTAINER

写作者的一些信息,镜像维护着的姓名和邮箱;

RUN

写容器构建时需要运行的命令;

EXPOSE

写当前容器对外暴露出的端口;

WORKDIR

指定在容器创建后,终端默认进来的工作目录;

ENV

用来构建镜像过程中设置环境变量;

ADD

将宿主机目录下的文件拷贝进镜像,且 ADD 命令会自动处理 URL 和解压 tar 压缩包;

COPY

类似于 ADD。拷贝文件和目录到镜像中;

VOLUME

容器数据卷,用于数据保存和持久化工作;

CMD

指定一个容器启动时要运行的命令;Dockerfile 中有多个 CMD 指令,但是只会生效最后一个,CMD 会被 docker run 之后的参数替换;

ENTRYPOINT

指定一个容器启动时要运行的命令;其目的和 CMD 一样,都是在指定容器启动程序及参数;他的命令是追加不是像 CMD 那样覆盖,docker run 之后的参数会被当做参数传给 ENTRYPOINT,之后形成新的命令组合

ONBUILD

当构建一个被继承的 Dockerfile 时运行的命令时,父镜像在被子继承后父镜像的 ONBUILD 被触发(触发器触发);

4.4、测试用 Dockerfile 定义镜像

Base 镜像(search),Docker Hub 中 99% 的镜像都是通过在 base 镜像中安装和配置需要的软件构建出来的;这里我将自定义一个 Centos 镜像,使其具备以下条件:登录后的默认路径、vim 编辑器、支持查看网络配置 ifconfig;

4.1.1、添加 Dockerfile 文件

创建一个文件,并不是一定要叫 Dockerfile,但是最好叫这个!

vim Dockerfile

编辑如下内容:

# 基于centos 镜像
FROM centos:centos7.9.2009
# 作者信息
MAINTAINER atroot<atroot@126.com>
# 定义变量
ENV MYPATH /usr/local
# 定义工作空间
WORKDIR $MYPATH
# 安装所需要的软件
RUN yum install -y vim
RUN yum install -y net-tools
# 开放端口
EXPOSE 80
# 执行命令
CMD echo $MYPATH
CMD echo "success!"
CMD /bin/bash
4.1.2、开始构建

如果 Dokcerfile1 是在当前目录下的,那么 -f 参数以及文件名是不用写的;记得在结尾加一个点 . ,表示当前路径;

docker build -f /root/mydocker/Dockerfile1 -t mycentos:7.1 .

如下为构建完成结果图:
image-20211224165731394

image-20211224170219495

验证工作目录确实为我们设置的;

image-20211224170422401

查看镜像历史
docker history mycentos:7.1

从下往上看!

image-20211224171636578

五、容器数据卷

为了使数据持久化,所谓的数据卷。类比 Redis 的数据持久化。

解决了容器的持久化、容器间继承和共享数据;

5.1、特点

image-20211218213302899

可以实现容器到主机和主机到容器的数据共享;

5.2、数据卷

5.2.1、容器内添加

docker run -it -v /myDataVolume:/dataVolumeContainer centos:latest

创建并运行一个带有数据卷的容器实例,这里的 -v 就是我们这里特殊的符号,绑定挂载一个卷。前者是宿主机的内存路径,后者是容器内的卷路径,可以在其中进行数据共享等操作,重启容器不会受到影响;

5.2.2、Dokcerfile 添加容器数据卷

# volume test
FROM centos
VOLUME ["/dataVolumeContainer1","/dataVolumeContainer2"]
CMD echo "finished"
CMD /bin/bash

上面的文件内容就想当于以下命令;

docker run -it -v /host1:/dataVolumeContainer1 -v /host2:/dataVolumeContainer2 centos /bin/bash

image-20211222204054976

编辑好上述的文件之后,使用 docker build 命令进行构建一个自定义的 Centos 镜像,注意后面的一个 “ . ”代表的是当前目录 ;

docker build -f Dockerfile -t atroot/centos .

执行结果如下

image-20211222204118995

image-20211222204205874

将该创建好了的简洁的 Centos,run 起来;

docker run -it --name centos_2 atroot/centos /bin/bash

image-20211222205327561

上面的两个卷就是我们批量创建的容器卷,对应着宿主机中的如下所示位置:

宿主机上执行,查看详细内容,在其中的 Mounts 中藏着这俩个东东;

docker inspect centos_2

image-20211222205851860

/var/lib/docker/volumes/ea07fbf2ceb1f5fbd050d2441283a88eab2e1fb6d449e0ff4b4722497ed0c2d7/_data
/var/lib/docker/volumes/84b3700ab2796df11a928580bdaae8a3bed966907d7193868ed8d9761a333ea8/_data

六、容器间的传递、共享性

6.1、定义

这个东西,有点类似于把容器数据卷做了一个类似于“订阅”的功能

6.2、怎么玩

  1. 先启动一个容器,并且在其 Volume 对应的文件夹中修改文件;

  2. 启动另外的容器,并挂载到已经启动了的 centos_2 上面;

docker run -it --name centos_21 --volumes-from centos_2 atroot/centos

image-20211222212715273

可以挂载多个上去,实现容器间文件共享、传递的作用,这里不做多余示范;

6.3、特点

  • 删除被挂载的第一台机器的时候,其他机器任然可以互相传递、共享数据;
  • 容器间的配置信息的传递,数据卷的生命周期一直持续到没有容器为止

七、镜像到远程库的操作

7.1、创建阿里云账号

7.2、进入容器镜像服务

7.3、创建好容器仓库

创建好,大概就会显示以下界面了,教程!

image-20211225165454544

7.4、推送到远程库

7.4.1、登录

我这里创建的是杭州节点的仓库,所以是 hangzhou,这个要看自己的配置的。

docker login --username=zheng**** registry.cn-hangzhou.aliyuncs.com

image-20211225165858437

7.4.2、设置标签版本等信息

#  镜像版本号是定义传到远程库的版本号的,不必和本地保持一致
docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/******/****study:[镜像版本号]

设置好后,如下所示:

image-20211225171113779

7.4.3、推送

这里的版本号,要和上边改好了的保持一致!

docker push registry.cn-hangzhou.aliyuncs.com/******/******study:1.1

image-20211225171611427

7.5、拉取镜像

docker pull registry.cn-hangzhou.aliyuncs.com/****/*****_study:[镜像版本号]

image-20211225172416487

完结!