docker学习笔记 3

桌桌 2022-8-30 146 8/30

容器数据卷

docker是将应用和环境打包成一个镜像,但是我们的数据和是存放在容器中的,如果我们的容器删除了,数据就会丢失,因此出现了数据可以持久化的需求

例如mysql,如果容器删除了,就相当于删库跑路,需求:MySQL数据可以存储在本地

容器之间可以有一个数据共享的技术,docker容器中产生的数据可以被同步在本地

就是卷技术,目录的挂载,将我们的容器内的目录挂载到linux主机上面。

docker学习笔记 3

也就是实现容器持久化和同步操作,容器之间也是可以数据共享的

使用数据卷

  • 方式一:直接使用命令来挂载 -v

    docker run -it -v  主机目录:容器内目录
    
    # 测试
    [root@VM-4-12-centos home]# ls
    lighthouse  wyz.java
    [root@VM-4-12-centos home]# docker run -it -v /home/ceshi:/home centos /bin/bash
    [root@VM-4-12-centos home]# ls
    ceshi  lighthouse  wyz.java
    
    
    # 启动起来之后可以通过docker inspect 容器id 来查看容器相关信息
    [root@VM-4-12-centos home]# docker inspect 2639b549b814

    如下所示

    docker学习笔记 3

    测试文件同步的具体效果,在容器内创建一个test.java,在服务器内对应的路径会进行同步。

    docker学习笔记 3

    继续测试,先停止容器,在容器关闭时在宿主机上对应路径的test.java中写入hello, linux updata,再启动容器查看是否做好了同步

    docker学习笔记 3

    可以看出,在服务器中的对应目录修改文件也会被同步到容器内。

    好处:以后我们修改只需要在本地进行修改,容器内会自动同步

实战:安装mysql

数据持久化的问题

# 获取镜像
[root@VM-4-12-centos home]# docker pull mysql

# 运行容器,需要做数据挂载
# 安装启动MySQL,需要配置密码

# 官方测试
docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag

# -d 后台运行
# -p 端口映射
# -v 卷挂载
# -e 环境配置
# --name 容器名字
[root@VM-4-12-centos home]# docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:latest

容器启动后,使用navicat连接数据库进行测试(记得开放服务器防火墙的3310端口)

docker学习笔记 3

在本地测试创建一个数据库,查看一下我们映射的路径是否ok

docker学习笔记 3

如果是配置文件,挂载后修改宿主机的配置文件就可以配置好容器中的配置文件。

如果删除了容器,宿主机挂载目录中的文件并不会删除,删除的只是容器中的那一份,如下图所示

docker学习笔记 3

强制删除mysql01容器之后,挂载目录中仍存在之前的数据库的数据,数据不会丢失,实现了容器数据持久化的功能。

具名和匿名挂载

# 匿名挂载
-v 容器内路径
docker run -d -p --name nginx01 -v /etc/nginx nginx

# 查看所有的volume的情况
[root@VM-4-12-centos data]# docker volume ls
DRIVER    VOLUME NAME
local     69a85dadf5555d4f185a7192c702ecefa34e4c07ee1de67bdf8e53aeba81853b
local     3947a1227af6adb672f90e06f2f265de85aaeb1c6cc2b3560927d55117b50156
local     fa75812a2b8b8cf01db942589dc862881a3a08f06644bfe0a418413091c4b7ab
# 这种就是匿名挂载,我们在-v中只写了容器内的路径,没有写容器外的路径

# 具名挂载
[root@VM-4-12-centos data]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
46da9966e8ee164cfcb8c753304ee34c66042bef182159717b8b3be672debe2d
[root@VM-4-12-centos data]# docker volume ls
DRIVER    VOLUME NAME
local     69a85dadf5555d4f185a7192c702ecefa34e4c07ee1de67bdf8e53aeba81853b
local     3947a1227af6adb672f90e06f2f265de85aaeb1c6cc2b3560927d55117b50156
local     fa75812a2b8b8cf01db942589dc862881a3a08f06644bfe0a418413091c4b7ab
local     juming-nginx
# 查看一下这个卷
[root@VM-4-12-centos data]# docker volume inspect juming-nginx
[
    {
        "CreatedAt": "2022-08-23T17:37:24+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",
        "Name": "juming-nginx",
        "Options": null,
        "Scope": "local"
    }
]

所有的docker容器内的卷,没有指定目录的情况下都在"/var/lib/docker/volumes/xxxx",所有的数据都是在此目录下的data目录下

docker学习笔记 3

我们通过具名挂载可以方便的找到我们的一个卷,大多数情况使用的都是具名挂载

# 如何确定是具名挂载还是匿名挂载,还是指定路径挂载?
-v 容器内路径            # 匿名挂载
-v 卷名:容器内路径         # 具名挂载
-v /宿主机路径::容器内路径    # 指定路径挂载

容器的权限

# 通过 -v 容器内路径:ro,rw 改变读写权限
# 这个权限是对于容器来说的
ro readonly      # 只读
rw readwrite     # 可读可写

# 一旦设置了容器权限,容器对我们挂载出来的内容就有限定了
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx

# 如果使用ro,就说明这个路径就只能通过宿主机来操作,容器内部是无法操作的
# 如果不指定则默认是rw

初识dockerfile

dockerfile就是用来构建docker镜像的构建文件!命令脚本

通过这个脚本生成一个镜像,镜像是一层一层的,所以这个脚本是一个一个的命令,每个命令都是一层!

# 创建一个dockerfile文件,名字可以随机,但是最好还是使用dockerfile
# 文件中的内容 指令(大写) 参数
FROM centos

VOLUME ["volume01","volume02"]      # 此处是匿名挂载

CMD echo "-----end-----"

CMD /bin/bash
# 文件中的每个命令,就是镜像的一层

docker学习笔记 3

启动自己生成的容器

docker学习笔记 3

使用docker inspect 容器id 查看一下挂载路径信息

docker学习笔记 3

这个卷和外部有一个同步的目录,我们使用的是匿名挂载,在容器外肯定也有一个目录与之对应,我们使用touch命令创建一个containter.txt文件

到该目录下查看是否同步了文件

docker学习笔记 3

这种方式会使用的很多,我们通常会构建自己的镜像

假设构建镜像的时候还没有挂载卷,要手动镜像挂载 -v 卷名:容器内路径

数据卷容器

多个MySQL同步数据

docker学习笔记 3

# 使用我创建的zhuozhuo/centos创建三个容器

docker学习笔记 3

同理创建容器docker02,同时使用--volume-from进行同步

docker学习笔记 3

然后我们在容器docker01的volume01中创建一个docker01文件,看docker02中是否会对应有相同的文件

docker学习笔记 3

也可以多次挂载,从挂载中被挂载的容器叫做数据卷容器

此时尝试一下是否可以递归的挂载,即2挂载在1上,3再挂载2

docker学习笔记 3

通过使用--volumes-from,就可以实现容器间的数据共享。

如果我们将容器docker01删除,其它容器的数据还会存在,docker02和docker03仍然可以访问这个文件,是一种备份的机制而不是共享的机制

多个mysql实现数据共享

[root@e173e22e38be volume01]# docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 -v /etc/mysql/conf.d -v /var/lib.mysql mysql

[root@e173e22e38be volume01]# docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volume-from mysql01 mysql

# 这个时候就可以实现两个容器数据的同步

结论:

容器之间的配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止。

一旦持久化到了本地,这个时候,本地的数据是不回删除的,重要的数据应该挂载到我们的文件系统内。

其中3->2, 2->1,2断了,仍然可以进行同步。

Dockerfile

dockerfile是用来构建docker的镜像文件,是命令参数脚本

构建步骤:

  1. 编写一个dockerfile 文件

  2. docker build 成为一个镜像

  3. docker run 运行镜像

  4. docker push 发布镜像(dockerHub、阿里云镜像仓库)

很多官方的镜像只有最基础的命令,很多功能没有,我们通常会搭建自己的镜像

我们很多时候希望是centos+jdk+tomcat+mysql+redis等

dockerfile构建过程

基础知识:

1、每个保留关键字(指令)都必须是大写字母

2、执行从上到下执行

3、#表示注释

4、每一个指令都会创建并提交一个镜像层,并提交

docker学习笔记 3

dockerfile是面向开发的,我们如果需要发布项目,做项目,就需要编写dockerfile文件

docker逐渐成为企业交付的标准,十分重要

步骤:开发,部署,运维...缺一不可

Dockerfile:构建文件,定义了一切的步骤,源代码

DockerImages:通过DockerFile构建生成的镜像,最终发布和运行的产品

Docker容器:容器就是镜像运行起来提供服务

dockerFile的指令
FROM		# 基础镜像,一切从这里开始构建
MAINTAINER 	# 镜像是谁写的,姓名+邮箱
RUN			# 镜像构建的时候需要运行的命令
ADD			# 步骤:比如我们加入tomcat的镜像,这个tomcat的压缩包,添加内容
WORKDIR		# 镜像的工作目录	/bin/bash
VOLUME		# 设置挂载的目录
EXPOSE		# 暴露指定的端口配置
RUN			# 指定容器启动之后要做的事情	
CMD			# 指定容器启动的时候要运行的命令,只有最后一个会生效,可以被替代
ENTRYPOINT	# 指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD		# 当构建一个被继承的DockerFile的时候,就会运行ONBIUILD指令。触发指令
COPY		# 十分类似于ADD,将我们的文件拷贝到镜像中
ENV			# 构建的时候设置环境变量

docker学习笔记 3

实战测试

DockerHub中99%的镜像都是从这个基础镜像过来的FROM scratch,然后配置需要的软件和配置来进行的构建

docker学习笔记 3

创建一个自己的DockrFile

在home/dockerfile中创建了mydockerfile-centos,使用vim编辑,

# 编写的dockerfile的文件
FROM centos:7

MAINTAINER zhuozhuo<787934074@qq.com>

ENV MYPATH /usr/local
WORKDIR $MYPATH

RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 80
CMD echo $MYPATH
CMD echo "----end----"
CMD /bin/bash

# 通过这个文件构建镜像
# 命令 docker build -f dockerfile的文件路径 -t 镜像名:[tag] .
[root@VM-4-12-centos dockerfile]# docker build -f mydockerfile-centos -t mycentos:0.1 .
...
Successfully built 69023696ff11
Successfully tagged mycentos:0.1
...

此处出现了一个错误

docker学习笔记 3

如图所示,出现的原因是Centos8于2021年年底停止了服务,再使用yum源会报错,按照网上的解决方案,就替换一下源就可以,但是按照以下操作之后并没有解决问题

1、进入yum的repos目录
cd /etc/yum.repos.d/

2、修改所有的CentOS文件内容
sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*

sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*

3、更新yum源为阿里镜像
wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-vault-8.5.2111.repo

yum clean all

yum makecache

4、yum安装测试是否可以yum安装
yum install wget –y

于是只好把centos的版本指定成了centos:7


结果如下:

docker学习笔记 3

测试以下我们新增的东西

docker学习笔记 3

我们可以列出本地进行变更的历史

[root@VM-4-12-centos ~]# docker history 69023696ff11
IMAGE          CREATED         CREATED BY                                      SIZE      COMMENT
69023696ff11   6 minutes ago   /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "/bin…   0B        
7c4d5bde729e   6 minutes ago   /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "echo…   0B        
11e7aef3a194   6 minutes ago   /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "echo…   0B        
2f96971c5bbe   6 minutes ago   /bin/sh -c #(nop)  EXPOSE 80                    0B        
ab7b57bccdb4   6 minutes ago   /bin/sh -c yum -y install net-tools             182MB     
cb0c5c665688   6 minutes ago   /bin/sh -c yum -y install vim                   237MB     
de7062cce233   8 minutes ago   /bin/sh -c #(nop) WORKDIR /usr/local            0B        
5f36115309aa   8 minutes ago   /bin/sh -c #(nop)  ENV MYPATH=/usr/local        0B        
c0adddcebaee   8 minutes ago   /bin/sh -c #(nop)  MAINTAINER zhuozhuo<78793…   0B        
eeb6ee3f44bd   11 months ago   /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B        
<missing>      11 months ago   /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B        
<missing>      11 months ago   /bin/sh -c #(nop) ADD file:b3ebbe8bd304723d4…   204MB

CMD和ENTRYPOINT的区别

CMD			# 指定容器启动的时候要运行的命令,只有最后一个会生效,可以被替代
ENTRYPOINT	# 指定这个容器启动的时候要运行的命令,可以追加命令

测试CMD指令

# 通过vim命令构建,然后用cat命令查看一下,如下所示
[root@VM-4-12-centos dockerfile]# cat docker-cmd-test 
FROM centos:7

CMD ["ls","-a"]

# 构建镜像
[root@VM-4-12-centos dockerfile]# docker build -f docker-cmd-test -t cmdtest .
...
Successfully built d1c3067b7c62
Successfully tagged cmdtest:latest

# 通过run运行
[root@VM-4-12-centos dockerfile]# docker run -it d1c3067b7c62
.   .dockerenv	       bin  etc   lib	 media	opt   root  sbin  sys  usr
..  anaconda-post.log  dev  home  lib64  mnt	proc  run   srv   tmp  var

# 想追加一个-l
[root@VM-4-12-centos dockerfile]# docker run -it d1c3067b7c62 -l
docker: Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "-l": executable file not found in $PATH: unknown.
ERRO[0000] error waiting for container: context canceled 
# cmd只会执行最后一个,追加的效果是-l替换掉了CMD ["ls","-a"]命令,此时只有-l,-l不是命令,所以报错

测试ENTRYPOINT

# 创建等操作与测试CMD时相同
FROM centos:7
CMD ["ls","-a"]
# 我们的追加命令是直接拼接到我们的ENTRYPOINT命令的后面
# 仅仅启动时,表现与CMD相同,但是追加命令-l时如下
[root@VM-4-12-centos dockerfile]# docker run 12bb0fbe3547 -l
total 64
drwxr-xr-x   1 root root  4096 Aug 29 08:35 .
drwxr-xr-x   1 root root  4096 Aug 29 08:35 ..
-rwxr-xr-x   1 root root     0 Aug 29 08:35 .dockerenv
...
# 追加到-a 变成 -al了

Dockerfile中很多的命令都十分的相似。

- THE END -

桌桌

8月30日09:49

最后修改:2022年8月30日
0

非特殊说明,本博所有文章均为博主原创。