码迷,mamicode.com
首页 > 其他好文 > 详细

[08] Docker_2

时间:2020-11-20 11:34:06      阅读:6      评论:0      收藏:0      [点我收藏+]

标签:成功   不能   unionfs   base   volume   备份   命令   vim   根目录   

Docker 镜像

镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。

UnionFS 联合文件系统

Union 文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union 文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。

技术图片

特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。

Docker 镜像加载原理

Docker 的镜像实际上由一层一层的文件系统组成,这种层级的文件系统就是 UnionFS。

bootfs(boot file system) 主要包含 bootLoader 和 Kernel,bootLoader 主要是引导加载 Kernel。Linux 刚启动时会加载 bootfs 文件系统,在 Docker 镜像的最底层是 bootfs。这一层与我们典型的 Linux/Unix 系统是一样的,包含 boot 加载器和内核。当 boot 加载完成之后整个内核就都在内存中了,此时内存的使用权已由 bootfs 转交给内核,此时系统也会卸载 bootfs。

技术图片

rootfs(root file system) 在 bootfs 之上,包含的就是典型 Linux 系统中的 /dev、/proc、/bin、/etc 等标准目录和文件。rootfs 就是各种不同的操作系统发行版,比如 Ubuntu,CentOS 等等。

Q1:平时我们安装进虚拟机的 CentOS 都是好几个 G,为什么 Docker 这里才 215M?

对于一个精简的 OS,rootfs 可以很小,只需要包括最基本的命令、工具和程序库就可以了,因为底层直接用 Host 的 Kernel,自己只需要提供 rootfs 就行了。由此可见对于不同的 Linux 发行版,bootfs 基本是一致的,只是 rootfs 会有差别,因此不同的发行版可以共用 bootfs。

技术图片

Q2:为什么 tomcat 这么大?→ “分层”的镜像

技术图片

在下载的过程中我们可以看到 Docker 的镜像好像是在一层一层的下载 ...

Q3:为什么 Docker 镜像要采用这种分层结构呢?

最大的一个好处就是共享资源。比如:有多个镜像都从相同的 base 镜像构建而来,那么宿主机只需在磁盘上保存一份 base 镜像,同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了,而且镜像的每一层都可以被共享!

镜像的特点

Docker 镜像都是只读的。当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。

commit 操作

访问 tomcat 报 404

Docker 方式启动 tomcat,访问首页出现 404 错误。

docker run -it -p 8888:8080 tomcat  # 分别代表 <docker容器>:<tomcat端口>
docker run -it -P tomcat            # 随机分配docker容器端口,但是tomcat依旧会是默认的8080

技术图片

通过 netstat -anp | more 查看端口占用情况,docker 的确在监听 8888 端口。

技术图片

进入正在运行的容器,一探究竟:

技术图片

这时候再访问,成了!

技术图片

但这么做,只在当前有效。容器停止后,下一次再使用镜像生成新的容器时,这个错误还是存在,即实际上问题的根源是在生成容器的镜像上,只有将镜像修改了,再生成的容器才不会再出现这个问题。

容器 → 镜像

由镜像可以生成容器实例,也可以根据当前正在运行的容器实例的实际状况又生成新的镜像(有点像反射)。通过 docker commit 提交容器副本使之成为一个新的镜像,命令格式如下:

docker commit -m="提交的描述信息" -a="作者" 容器ID 要创建的目标镜像名:[标签名]

上一小节修改过 webapps 的 tomcat 运行实例算是一个标准的 tomcat 容器了,故以它为模板 commit 一个新的 tomcat 镜像 nuist/mytomcat。这样一来,以后再创建 tomcat 容器时,使用我们自己生成的镜像即可(它跟阿里云拉下来的没什么差别,只是保存了我们之前对容器做的修改)。

docker commit -a="ljq" -m="tomcat update the folder-webapps" c9e9af3087aa  nuist/mytomcat:1.1

技术图片

测试:

技术图片

顺便 review 下“守护方式”启动容器:

技术图片

Docker 容器数据卷

概述

Q1:是什么?

先来看看 Docker 的理念:

  • 将运用与运行的环境打包形成容器运行 ,运行可以伴随着容器,但是我们对数据的要求希望是持久化的。
  • 容器之间希望有可能共享数据

Docker 容器产生的数据,如果不通过 docker commit 生成新的镜像,使得数据做为镜像的一部分保存下来,那么当容器删除后,数据自然也就没有了。

为了能保存数据,在 Docker 中我们使用“容器数据卷”// 有点类似我们 Redis 里面的 rdb 和 aof 文件!


Q2:作用

① 容器的持久化;② 容器间继承+共享数据;③ 容器和宿主机共享数据

“卷”就是目录或文件,存在于一个或多个容器中,由 Docker 挂载到容器,但不属于联合文件系统,因此能够绕过 Union File System 提供一些用于持续存储或共享数据的特性:

  • 数据卷可在容器之间共享或重用数据
  • 卷中的更改可以直接生效
  • 数据卷中的更改不会包含在镜像的更新中
  • 数据卷的生命周期一直持续到没有容器使用它为止

“卷”的设计目的就是数据的持久化,完全独立于容器的生存周期,因此 Docker 不会在容器删除时删除其挂载的数据卷。

容器内添加数据卷

直接命令添加

命令格式(-v 即 volume):

docker run -it -v </宿主机绝对路径目录:/容器内目录>[:ro] <镜像名>

# ro即readonly,一旦添加这个选项,容器只能读宿主机往目录里添的内容,自己不能做增删改操作。

Dockers 自动创建对应的文件夹:

技术图片

查看数据卷是否挂载成功:

技术图片

容器和宿主机之间共享数据:

技术图片

容器停止退出后,主机修改后数据是否同步?同步!

DockFile 添加

[Java] Hello.java → Hello.class
[Docker] Images → DockFile

  1. 根目录下新建 mydocker 文件夹并进入
  2. 可在 dockerFile 中使用 VOLUME 指令来给镜像添加一个或多个数据卷(出于可移植和分享的考虑,用 -v 主机目录:容器目录 这种方法不能够直接在 dockerFile 中实现。由于宿主机目录是依赖于特定宿主机的,并不能够保证在所有的宿主机上都存在这样的特定目录)。
  3. 构建 dockerFile
    # volume test
    FROM centos
    VOLUME ["/dataVolumeContainer1","/dataVolumeContainer2"]
    CMD echo "finished, success!"
    CMD /bin/bash
    
  4. build 后生成镜像,通过该镜像 run 容器
    docker build -f /mydocker/dockerFile -t mycentos .
    docker run -it mycentos
    

技术图片

通过上述步骤,容器内的卷目录地址已经知道,那么对应的主机目录地址在哪呢?→ 通过 docker inspect <容器ID> 查看:

技术图片

补充

Docker 挂载主机目录,访问时出现 cannot open directory .: Permission denied

解决办法:在挂载目录后多加一个 --privileged=true 参数即可~

数据卷容器

命名的容器挂载数据卷,其它容器通过挂载这个(父容器)实现数据共享,则这个挂载数据卷的容器,就称之为“数据卷容器”。

测试容器间传递共享(--volumes-from):

技术图片

DockFile

概述

Dockerfile 是用来构建 Docker 镜像的构建文件,是由一系列命令和参数构成的脚本。

构建三步骤:dockerfile(编写) → docker build(构建) → docker run(运行)

技术图片

构建过程解析

Dockerfile 内容基础知识:

  1. 每条保留字指令都必须为大写字母且后面要跟随至少一个参数
  2. 指令按照从上到下,顺序执行
  3. # 表示注释
  4. 每条指令都会创建一个新的镜像层,并对镜像进行提交

Docker 执行 Dockerfile 的大致流程:

  1. Docker 从基础镜像(scratch) 运行一个容器
  2. 执行一条指令并对容器作出修改
  3. 执行类似 docker commit 的操作提交一个新的镜像层
  4. Docker 再基于刚提交的镜像运行一个新容器
  5. 执行 Dockerfile 中的下一条指令直到所有指令都执行完成

Docker Hub 中 99% 的镜像都是通过在 base 镜像(scratch) 中安装和配置需要的软件构建出来的。


小结:

从应用软件的角度来看,Dockerfile、Docker 镜像与 Docker 容器分别代表软件的 3 个不同阶段:

  • Dockerfile 是软件的原材料
  • Docker 镜像是软件的交付品
  • Docker 容器则可以认为是软件的运行态

Dockerfile 面向开发,Docker 镜像成为交付标准,Docker 容器则涉及部署与运维,三者缺一不可,合力充当 Docker 体系的基石。

技术图片

  1. Dockerfile,需要定义一个 Dockerfile,Dockerfile 定义了进程需要的一切东西。Dockerfile 涉及的内容包括执行代码或者是文件、环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、服务进程和内核进程(当应用进程需要和系统服务和内核进程打交道,这时需要考虑如何设计 namespace 的权限控制)等。
  2. Docker 镜像,在用 Dockerfile 定义一个文件之后,docker build 时会产生一个 Docker 镜像,当运行 Docker 镜像时,会真正开始提供服务。
  3. Docker 容器,容器是直接提供服务的。

体系结构

技术图片

案例

自定义 centos

技术图片

自定义 mycentos 使我们自己的镜像具备如下:

  • 登陆后的落脚点为 /usr/local/
  • vim 编辑器
  • 查看网络配置 ifconfig 支持

1. 编写 Dockfile 文件:dockFile2

技术图片

2. 构建命令:docker build -f /mydocker/dockFile2 -t mycentos:1.2 .

技术图片

3. 运行:docker run -it mycentos:1.2

技术图片

4. 列出镜像的变更历史:docker history mycentos:1.2

技术图片

CMD/ENTRYPOINT

CMD、ENTRYPOINT 都是指定一个容器启动时要运行的命令。不同点是,一个会被 run 后的参数覆盖,另一个被追加组合。

1. Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效,CMD 会被 docker run 之后的参数替换。

技术图片

2. docker run 之后的参数会被当做参数传递给 ENTRYPOINT,之后形成新的命令组合。

【crul 命令解释】curl 命令可以用来执行下载、发送各种 HTTP 请求,指定 HTTP 头部等操作。如果系统没有 curl 可以使用 yum install curl 安装,也可以下载安装。curl 是将下载文件输出到 stdout。使用命令:curl http://www.baidu.com,执行后,www.baidu.com 的 html 就会显示在屏幕上了。如果我们希望显示 HTTP 头信息,就需要加上 -i 参数。

技术图片

我们可以看到 myip 报可执行文件找不到的报错(executable file not found)。之前我们说过,跟在镜像名后面的是 command,运行时会替换 CMD 的默认值。因此这里的 -i 替换了原来的 CMD 后面的命令,而不是添加在原来的 curl -s http://ip.cn 后面。而 -i 根本不是命令,所以自然找不到。

那么如果我们希望加入 -i 这参数,我们就必须重新完整的输入这个命令:docker run myip curl -s http://ip.cn -i。但这也太麻烦了,故当遇到这种组合命令,就该用 ENTRYPOINT 来指定一个容器启动时要运行的命令。

ONBUILD

当构建一个被继承的 Dockerfile 时运行命令,父镜像在被子继承后父镜像的 onbuild 被触发。

技术图片

自定义镜像 tomcat9

1. mkdir -p /zzyyuse/mydockerfile/tomcat9

2. 在上述目录下touch c.txt

3. 将 jdk 和 tomcat 安装的压缩包拷贝进上一步目录

4. 在 /zzyyuse/mydockerfile/tomcat9 目录下新建 Dockerfile 文件

FROM          centos
MAINTAINER    zzyy<zzyybs@126.com>
# 把宿主机当前上下文的 c.txt 拷贝到容器 /usr/local/ 路径下
COPY c.txt /usr/local/cincontainer.txt
# 把 jdk 与 tomcat 添加到容器中(ADD是带解压功能的COPY)
ADD jdk-8u171-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.8.tar.gz /usr/local/
# 安装 vim 编辑器
RUN yum -y install vim
# 设置工作访问时候的 WORKDIR 路径,登录落脚点
ENV MYPATH /usr/local
WORKDIR $MYPATH
# 配置 jdk 与 tomcat 环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_171
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.8
ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.8
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
# 容器运行时监听的端口
EXPOSE    8080
# 启动时运行 tomcat
# ENTRYPOINT ["/usr/local/apache-tomcat-9.0.8/bin/startup.sh" ]
# CMD ["/usr/local/apache-tomcat-9.0.8/bin/catalina.sh","run"]
CMD /usr/local/apache-tomcat-9.0.8/bin/startup.sh (不要换行,我这里是为了赏心悦目)
        && tail -F /usr/local/apache-tomcat-9.0.8/bin/logs/catalina.out

5. 构建 docker build -t zzyytomcat9 .

技术图片

6. run

docker run -d -p 9080:8080 --name myt9 (没有换行,我这里纯粹是为了赏心悦目)
-v /zzyyuse/mydockerfile/tomcat9/test:/usr/local/apache-tomcat-9.0.8/webapps/test
-v /zzyyuse/mydockerfile/tomcat9/tomcat9logs/:/usr/local/apache-tomcat-9.0.8/logs
--privileged=true zzyytomcat9

7. 验证

技术图片

![](_v_images/20201113212250547_14690.png =600x)

8. 结合前述的容器卷将测试的web服务test发布

技术图片

小结

技术图片

Docker 常用安装

技术图片

安装 MySQL

从 Docker Hub上(阿里云加速器) 拉取 MySQL 镜像(标签为 5.7) 到本地:

技术图片

docker run -p 12345:3306 --name mysql
-v /mydocker/mysql/conf:/etc/mysql/conf.d
-v /mydocker/mysql/logs:/logs
-v /mydocker/mysql/data:/var/lib/mysql
-e MYSQL_ROOT_PASSWORD=123456
-d mysql:5.7

技术图片

外部 Win10 也来连接运行在 Dokcer 上的 MySQL 服务:

技术图片

数据备份小测试:

docker exec mysql容器ID sh -c ‘ exec mysqldump --all-databases -uroot -p"123456" ‘ > /dbs.sql

安装 Redis

从 Docker Hub上(阿里云加速器)拉取 Redis 镜像(标签为 3.2) 到本地:

技术图片

docker run -p 6379:6379
-v /mydocker/myredis/data:/data
-v /mydocker/myredis/conf/redis.conf:/usr/local/etc/redis/redis.conf
-d redis:3.2 redis-server /usr/local/etc/redis/redis.conf
--appendonly yes

技术图片

本地镜像发布到阿里云

本地镜像发布到阿里云流程:

技术图片

1. 创建仓库镜像:命名空间、仓库名称

2. 将镜像推送到 Registry,其中 [ImageId]、[镜像版本号] 根据自己的镜像信息进行填写 ↓

技术图片

技术图片

3. 将阿里云上的镜像下载到本地

技术图片

[08] Docker_2

标签:成功   不能   unionfs   base   volume   备份   命令   vim   根目录   

原文地址:https://www.cnblogs.com/liujiaqi1101/p/13976368.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!