当前位置:   article > 正文

Docker学习笔记-进阶_docker tun cmd

docker tun cmd


笔记来源:kuangstudy视频学习
学习链接

Docker进阶

1. 容器数据卷

什么是数据卷

docker的理念回顾:

将我们的应用和运行环境打包成镜像发布,之后启动以容器运行。

数据怎么保存呢?如果数据存储在容器中,容器删除的时候,数据就会丢失。这肯定是不合理的。

需求:数据持久化

容器之间应该有一个数据共享的技术。docker容器中产生的数据,可以同步到本地!

这就是卷技术!

——目录的挂载:将我们容器内的目录,挂载到Linux上面!

总结一句话:

  • 容器的持久化和同步操作!
  • 容器间也是可以数据共享的

使用数据卷

方式一:使用命令挂载

docker run -it -v 主机目录:容器内目录	# 可以类比 -p 端口的映射

# 测试
docker run -it -v /home/ceshi:/home centos /bin/bash
  • 1
  • 2
  • 3
  • 4

挂载之后,容器内的/home目录和Linux的/home/ceshi目录就共享了!

容器内/home目录资源的变化,Linux目录可以共享;

容器外Linux目录资源的变化,容器内目录可以共享!


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

实战测试

思考:MySQL的数据持久化问题!

# 下载mysql
docker pull mysql:5.7

# 启动容器+数据挂载!	# 安装启动mysql,需要密码
docker run -d -p 3306:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql --name mysql01 -e MYSQL_ROOT_PASSWORD=root mysql:5.7
# 解释
-d 		# 后台运行
-p		# 端口映射
-v		# 卷挂载
-e		# 环境配置
--name	# 容器命名

# 启动成功,本地通过workbench测试连接
# workbench---> 连接到服务器的 3306 映射到容器的3306

# 在本地创建一个数据库 test,查看是否同步成功

# 将mysql容器删除,发现挂载到本地的数据为丢失,这就实现了容器数据的持久化
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

具名和匿名挂载

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

# 查看所有的	volume
local     1ee598ebd27a034a9724b33fdf94f912b77983055aeca17902440db67a5edbe9
local     e87a415937e57a9c0ee21c08e3407d705487d8b0ffd1c3d4a347b2112012f16d
local     ee5e212634a4da79f10b3f607c4e9455cf231e7d2ae72e6a6abbffcb4381c1ce
# 这里发现,这种就是匿名挂载,我们在 -v 只写了容器内路径,没有写容器外路径 

# 具名挂载
-v 卷名:容器内路径
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx

# 查看一下所有的 volume
DRIVER    VOLUME NAME
local     1ee598ebd27a034a9724b33fdf94f912b77983055aeca17902440db67a5edbe9
local     e87a415937e57a9c0ee21c08e3407d705487d8b0ffd1c3d4a347b2112012f16d
local     ee5e212634a4da79f10b3f607c4e9455cf231e7d2ae72e6a6abbffcb4381c1ce
local     juming-nginx
发现多了一个juming-nginx
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

所有的docker容器内的卷,没有指定目录的情况下都是在 /var/lib/docker/volumes/xxxx/_data。

我们通过具名挂载,可以方便的找到一个卷,大多数情况下似乎该种方式,不适用匿名挂载。

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

拓展:

# 通过 -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 只要看到ro就说明这个路径只能通过宿主机来操作,容器内部是无法操作的
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

初识DockerFile

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

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

# dockerfile	指令(大写)	参数 每一步就是一层
FROM centos

VOLUME ["volume01", "volume02"]

CMD echo "----end----"
CMD /bin/bash
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

# 启动一下自己生成的容器
  • 1

volume01,volume02是我们生成镜像的时候自动挂载的,数据卷目录。

这个卷和外部一定有一个同步的目录!

发现主机确实有被同步挂载的目录,匿名挂载方式。

在volume01新建了一个container.txt文件,看是否被同步。

这种方式我们使用很多,因为通常情况下我们会构建自己的镜像。

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

数据卷容器

容器间同步数据。

test


通过 --volumes-from docker01 将docker02挂载docker01

在docker02的volume01内创建一个文件docker01,发现在docker02容器内可见

说明数据同步成功

注意

一旦各容器之间互相挂载,只要有一个容器被使用,那么他们之间的数据共享关系就还在,哪怕父容器被删除,其他容器的共享关系也依然存在。

好处:mysql,redis数据共享。

比如两个数据库的数据共享

# 启动父容器 mysql01,匿名挂载目录
docker run -d -p 3301:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT-PASSWORD=root --name mysql01 mysql:5.7
# 启动子容器 mysql02,同步挂载mysql01
docker run -d -p 3302:3306 -e MYSQL_ROOT_PASSWORD=root --name mysql02 --volumes-from mysql01 mysql:5.7
  • 1
  • 2
  • 3
  • 4

结论

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

2. DockerFile

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

构建步骤:

  1. 编写一个dockerfile文件
  2. docker build构建成为一个镜像
  3. docker run 运行镜像
  4. docker push 发布镜像(DockerHub,阿里云镜像仓库)

DockerFile构建过程

基础知识

  1. 每个保留关键字(指令)都必须是大写字母
  2. 执行从上到下顺序执行
  3. #号表示注释
  4. 每一个指令都会创建提交一个新的镜像层,并提交

dockerfile是面向开发的,发布项目,做镜像,就需要编写dockerfile文件!

DockerFile:构建文件,定义了一切的步骤,好比源代码。

DockerImages:通过DockerFile构建生成的镜像,这就是最终要发布运行的产品。

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

DockerFile的指令

From		# 基础镜像,镜像从这里开始构建,最底层  centos
MAINTAINER	# 镜像是谁写的,姓名+邮箱
RUN		# 镜像构建的时候需要运行的命令
ADD		# 步骤:tomcat镜像,tomcat压缩包,添加内容
WORKDIR		# 镜像的工作目录
VOLUME		# 挂载的目录位置
EXPOSE		# 保留端口暴露的配置
CMD		# 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT	# 指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD		# 当构建一个被继承的DockerFile 这个时候会运行ONBUILD的指令。触发指令。
COPY		# 类似ADD,将我们的文件拷贝到镜像中
ENV		# 构建的时候设置环境变量
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

实战测试:构建自己的centos

Docker Hub中 大多数的镜像都是从这个基础镜像构建的:FROM scratch,然后配置需要的软件和配置来进行的构建。

创建一个自己的centos:包含centos,增加vim,ifconfig命令

# 1. 编写自己的dockerfile文件
# 基于centos镜像编写
FROM centos
# 作者
MAINTAINER zhangtong<mail@163.com>
# 环境变量:工作路径
ENV MYPATH /usr/local
WORKDIR $MYPATH

# 下载基础命令vim,net-tools
RUN yum -y install vim
RUN yum -y install net-tools

# 暴露80端口
EXPOSE 80

# 执行一些打印的命令
CMD echo $MYPATH
CMD echo -----end-----
# 使用/bin/bash解析
CMD /bin/bash

# 2.通过这个文件构建镜像
# docker build -f dockerfile文件路径 -t 镜像名[:tag] .
# 注意末尾有小数点
Successfully built 4a911b3865b1
Successfully tagged mycentos:1.0

# 3.测试运行
docker run -it mycentos:1.0
# 会发现几点:
# 1. 跳转到了工作目录 /usr/local
# 2. 新下载的命令vim,ifconfig可以使用了
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

我们可以列出本地镜像变更的历史:

docker history 镜像名[:tag]/镜像id

我们可以通过这个命令去查看镜像的变更记录,可以查到具体镜像层的变更和命令的执行。

CMD和ENTRYPOINT的区别

测试cmd:

# 编写dockerfile-cmd-test
FROM centos
CMD ["ls", "-a"]

# 构建镜像
docker build -f dockerfile-cmd-test -t cmdtest .

# 运行镜像容器
docker run cmdtest
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
# 发现 ls -a执行成功的

# 想追加一个命令 -l  想执行 ls -al
docker tun cmdtest -l
docker: Error response from daemon: OCI runtime create failed: container_linux.go:370: starting container process caused: exec: "-l": executable file not found in $PATH: unknown.
# cmd的前提下,-l替换了CMD ["ls","-a"]命令,执行-l 不是命令,所以报错
# 必须使用完整的命令
docker run cmdtest ls -al
# 因为他把docker的cmd给覆盖掉了
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

测试entrypoint:

# 编写dockerfile-entrypoint-test
FROM centos
ENTRYPOINT ["ls","-a"]

# 构建之后执行测试
docker run entrypoint-test -l
total 56
drwxr-xr-x   1 root root 4096 Mar  8 16:19 .
drwxr-xr-x   1 root root 4096 Mar  8 16:19 ..
-rwxr-xr-x   1 root root    0 Mar  8 16:19 .dockerenv
lrwxrwxrwx   1 root root    7 Nov  3 15:22 bin -> usr/bin
drwxr-xr-x   5 root root  340 Mar  8 16:19 dev
drwxr-xr-x   1 root root 4096 Mar  8 16:19 etc
drwxr-xr-x   2 root root 4096 Nov  3 15:22 home
lrwxrwxrwx   1 root root    7 Nov  3 15:22 lib -> usr/lib
lrwxrwxrwx   1 root root    9 Nov  3 15:22 lib64 -> usr/lib64
drwx------   2 root root 4096 Dec  4 17:37 lost+found
drwxr-xr-x   2 root root 4096 Nov  3 15:22 media
drwxr-xr-x   2 root root 4096 Nov  3 15:22 mnt
drwxr-xr-x   2 root root 4096 Nov  3 15:22 opt
dr-xr-xr-x 105 root root    0 Mar  8 16:19 proc
dr-xr-x---   2 root root 4096 Dec  4 17:37 root
drwxr-xr-x  11 root root 4096 Dec  4 17:37 run
lrwxrwxrwx   1 root root    8 Nov  3 15:22 sbin -> usr/sbin
drwxr-xr-x   2 root root 4096 Nov  3 15:22 srv
dr-xr-xr-x  13 root root    0 Mar  8 16:19 sys
drwxrwxrwt   7 root root 4096 Dec  4 17:37 tmp
drwxr-xr-x  12 root root 4096 Dec  4 17:37 usr
drwxr-xr-x  20 root root 4096 Dec  4 17:37 var
# 发现 -l追加成功了
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

总结

cmd永远你只执行最后一条命令,新来的cmd会覆盖掉之前的cmd

entrypoint其实如果在同一个dockerfile中出现的话,他也是只执行最后一条命令的。但是entrypoint在运行容器的时候,可以增加参数。使用cmd,参数会把命> 令给覆盖掉

且entrypoint优先级高于cmd,如果同时存在的话,cmd无法覆盖entrypoint,但是entrypoint会覆盖cmd。

实战测试:tomcat镜像

  1. 准备镜像文件 tomcat压缩包,jdk的压缩包

  2. 编写dockerfile文件:Dockerfile

FROM centos
MAINTAINER zhangtong<mail@163.com>
COPY README.md /usr/local/README.md

ADD jdk-8u281-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.43.tar.gc /usr/local/

RUN yum -y install vim
ENV MYPATH /usr/local
WORKDIR $MYPATH

ENV JAVA_HOME /usr/local/jdk1.8.0_281
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.43
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.43
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin

EXPOSE 8080

CMD /usr/local/apache-tomcat-9.0.43/bin/startup.sh && tail -F /url/local/apache-tomcat-9.0.43/bin/logs/catalina.out
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  1. 构建镜像
# 由于文件名是官方推荐 Dockerfile,因此不再需要指定文件,会默认找寻目录下该文件
docker build -t mytomcat .
  • 1
  • 2
  1. 启动镜像
# 后台启动mytomcat镜像容器
# 服务器端口开放8080,映射容器端口8080
# 容器命名mytomcat
# 挂载两个目录,test和logs
# 可以在容器外部test目录编写项目即可同步到容器内了
docker run -d -p 8080:8080 --name mytomcat -v /home/zhangtong/build/tomcat/test:/url/local/apache-tomcat-9.0.43/webapps/test -v /home/zhangtong/build/tomcat/tomcatlogs:/url/local/apache-tomcat-9.0.43/logs mytomcat
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  1. 访问测试
curl localhost:8080
# 得到html回显
  • 1
  • 2

浏览器访问 ip:8080,得到tomcat页面回显。

  1. 发布项目(由于做了卷挂载,可以直接在linux本地编写项目)
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/73499
推荐阅读
相关标签
  

闽ICP备14008679号