Docker好好学三

Docker好好学三

大纲

1、Commit 镜像

2、容器数据卷

3、安装MySQL(持久化数据)

4、具名挂载和匿名挂载

5、初识Dockerfile

1、 Commit 镜像

docker commit 提交容器成为一个新的副本

# 命令和git原理类似
docker commit -m="描述信息" -a="作者" 容器id  目标镜像名:[TAG]

实战测试

# 启动一个默认的tomcat镜像, webapps里兵没有应用(镜像原因),  将webapps.list 下的所有文件移动至webapps文件夹下

# 将更改后的容器通过commit提交成为一个新的奖项.
[root@Oskari ~]# docker commit -a="oskari" -m="reset webapps files" 8bbdd54e1ca5 tomcat_normal:1.0
sha256:5e03b52c61624e583666cada38f58fb33e32b72ba17fe2e99b8bf1fdd6919b09
[root@Oskari ~]# docker images
REPOSITORY                      TAG                 IMAGE ID            CREATED             SIZE
tomcat_normal                   1.0                 5e03b52c6162        4 seconds ago       673 MB
docker.io/tomcat                9.0                 46cfbf1293b1        13 days ago         668 MB

如果想要保存当前容器的状态, 就可以通过 commit 来提交, 获取一个镜像. 就像VM的快照一样!

2、 容器数据卷

docker的理念

将应用和环境打包成一个镜像! 数据如果都存储在容器中, 如果容器被删除, 数据随之丢失. 故: 数据需要持久化. 通过容器之间数据共享技术, Docker容器中产生的数据同步到本地宿主机.

这就是卷技术! 目录的挂载, 将我们容器内的目录, 挂载到宿主机上!

  • 使用数据卷

方式一: 直接使用命令 -v 进行数据地址挂载

docker run -it -v 宿主机目录:容器目录 IMAGENAME

测试一:

# 测试
[root@Oskari home]# docker run -it -v /home/test:/home centos:7 /bin/bash

# 查看卷是否挂载成功

[root@Oskari home]# docker inspect 3fe744aed21c

"Mounts": [ # 挂载
            {
                "Type": "bind",
                "Source": "/home/test", # 宿主机位置
                "Destination": "/home", # 容器内的位置
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],

# 双向绑定
# 宿主机创建文件同步至容器
[root@Oskari test]# touch test.txt
[root@Oskari test]# docker attach 3fe744aed21c
[root@3fe744aed21c home]# ls
test.txt
[root@3fe744aed21c home]# 

# 容器内创建文件同步至宿主机
[root@3fe744aed21c home]# touch test_from_container.txt
# 退回至宿主机
[root@Oskari test]# ls
test_from_container.txt  test.txt

测试二:

# 在宿主机更改test.txt文件内容, 添加"This is update from Linux!"
# 在容器中查看文件内容, cat test.txt, 获取文字 "This is update from Linux!"

# 在容器冲更改test_from_container.txt 文件内容, 添加"This is update from Container!"
# 在宿主机中查看文件内容, cat test_from_container.txt, 获取文字 "This is update from Container!"

3、 安装MySQL(持久化数据)

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

以MySQL5.7为示例

启动MySQL5.7镜像, 创建容器, -p 端口映射, -v 挂载

# 启动镜像, 做配置文件以及数据挂载 
# 注意: 安装启动MySQL要配置ROOT密码!!!
# Offical: docker run --name some-mysql -e MY_ROOT_PASSWD=PASSWD -d mysql:tag
# -d                    后台运行
#-p                     端口映射
# -v                    数据卷挂载
# -e                    环境配置
# --name         容器名字
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=123123 --name mysql01 mysql:5.7

4、 具名挂载和匿名挂载

# 匿名挂载
-P 大写的P, 映射随机端口
-v 容器内路径
docker run -d -P --name nginx02 -v /etc/nginx nginx

# 查看数据卷的相关帮助命令
docker volume --help

Options:
      --help   Print usage

Commands:
  create      Create a volume
  inspect     Display detailed information on one or more volumes
  ls          List volumes
  prune       Remove all unused volumes
  rm          Remove one or more volumes

# 查看所有数据卷信息
docker volume ls

DRIVER              VOLUME NAME
local               62c9d09e0c0693635857ea94246534747a7276950e1bd75f79260d25d2e9407e
local               dc0cc8aaee37ac6d0d9d68e4d7f08b26fe6867a3df396d29a62e119af7cfd121
# VOLUME NAME 当前显示为匿名数据卷, 在 -v 挂载的时候只写了容器内的路径,没有写宿主机的路径
# 具名挂载
# 通过 -v 卷名:容器内路径
docker run -d -P --name nginx03 -v juming-nginx:/etc/nginx nginx

所有Docker容器内的数据卷, 在没有指定目录的情况下都是在 /var/lib/docker/volumes/xxxx/_data 路径下.

我们通过具名挂载可以方便地找到我们需要查询的数据卷. 大多数情况都是在使用 具名挂载

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

拓展:

# 通过 -v 容器内路径: ro rw 改变读写权限
# ro readonly           只读
# rw readwrite        读写
# 如果设置了容器权限, 容器对挂载出来的数据就有权限限定了. 
docker run -d -P --name nginx04 -v juming-nginx:/etc/nginx:ro nginx
docker run -d -P --name nginx04 -v juming-nginx:/etc/nginx:rw nginx
# ro    只要看到ro就说明这个路径只能通过宿主机来操作, 容器内部是无法操作

5、 初识Dockerfile

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

通过脚本生成镜像, 镜像是一层一层的. 脚本就是一个一个的命令, 每个命令都是一层.

创建 dockerfile1 文件

FROM centos

VOLUME ["volume01","volume02"]

CMD echo "-----VOLUME END-----"
CMD /bin/bash

执行构建镜像命令

docker build -f ./dockerfile1 -t oskari/centos:1.0 .

这两个数据卷是在dockerfile1中挂载的(匿名挂载). 所以宿主机一定有一个与之同步的目录

查看数据卷挂载路径

# 进入容器,在挂载的数据卷 volume01 中创建测试文件container.txt文件
# 宿主机中查看容器源数据, 找到挂载信息
docker inspect c0fe3ce4ec96

        "Mounts": [
            {
                "Type": "volume",
                "Name": "a77fa64e6c71513d905f7307ad44df496dfcba948288113162dbf5ab036b317e",
                "Source": "/var/lib/docker/volumes/a77fa64e6c71513d905f7307ad44df496dfcba948288113162dbf5ab036b317e/_data",
                "Destination": "volume01",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            },
            {
                "Type": "volume",
                "Name": "d0c1bb2ca01b0e4c38d0cc3b0d3e632c8440fd98ea49811243a4283a86a77f55",
                "Source": "/var/lib/docker/volumes/d0c1bb2ca01b0e4c38d0cc3b0d3e632c8440fd98ea49811243a4283a86a77f55/_data",
                "Destination": "volume02",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],

数据卷容器

多个容器间同步

# 通过我们刚刚自己生成的镜像来启动一个容器
docker run -it -d --name docker01 oskari/centos:1.0  # 作为父容器

创建 docker02

# 创建docker02
docker run -it --name docker02 --volumes-from docker01 oskari/centos:1.0

进入 docker01 创建测试同步文档

[root@4cf79574d316 /]# docker attach docker01
[root@4cf79574d316 /]# cd volume01
[root@4cf79574d316 volume01]# ls
[root@4cf79574d316 volume01]# touch docker01.txt
[root@4cf79574d316 volume01]# ls
docker01.txt

进入 docker02 查看是否同步成功

[root@6a9129945bbe /]# docker attach docker02
[root@6a9129945bbe /]# cd volume01
[root@6a9129945bbe volume01]# ls
docker01.txt

--volume-from 相当于 继承

创建 docker03 (继承) 挂载于 docker02

[root@50cc8409521f /]# docker run -it --name docker03 --volumes-from docker02 oskari/centos:1.0 /bin/bash
[root@50cc8409521f /]# cd volume01
[root@50cc8409521f volume01]# ls
docker01.txt
[root@50cc8409521f volume01]# touch docker03.txt

分别进入 docker01 docker02 查看 volume01 目录下是否同步 docker03.txt 成功, 如果 docker03.txt 分别存在于 docker01 docker02 的 volume01 目录内, 说明容器间的数据共享成功

只要通过 --volume-from 命令挂载, 那么容器间就可以做到数据共享了, 同时共享数据的容器间, 如果容器被删除, 数据依然存在于运行中的容器中.依然可以访问. 可以理解为容器之间, 数据共享等同于 容器间的双向拷贝!

多个MySQL实现数据共享(思路,代码非验证)

docker run -d -p 3310:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123123 --name mysql01 mysql:5.7
docker run -d -p 3311:3306 -e MYSQL_ROOT_PASSWORD=123123 --name mysql02 --volume-from mysql01 mysql:5.7

结论:

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

但是如果持久化到了本地, 这个时候, 本地的数据是不会删除的.

Dockerfile

Dockerfile介绍

Dockerfile 是用来构成Docker镜像文件的命令参数脚本

构建步骤:

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

Dockerfile构建过程

基础知识:

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

Dockerfile是面向开发的. 我们以后要发布的项目, 做镜像, 就需要编写dockerfile文件.

Docker 镜像逐渐成为企业交付的标准, 必须掌握!

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

Docker images 通过 Dockerfile 构建生成的镜像, 最终发布和运行的产品.

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

5.1 Dockerfile 指令

FROM                        # 基础镜像
MAINTAINER          # 镜像作者   姓名+邮箱, 例如:   Oskari < oskari@bengder.cc >
RUN                           # 镜像构建时需要运行的命令
ADD                           # 添加内容, 例如 tomcat 压缩包
WORKDIR               # 镜像的工作目录
VOLUME                  # 挂载数据卷(目录)
EXPOSE                   # 指定暴露端口
CMD                          # 指定容器启动的时候要运行的命令, 只有最后一个会生效, 可以被替代
ENTRYPOINT        # 指定容器启动的时候要运行的命令, 可以追加命令
ONBUILD                # 当构建一个被继承 Dockerfile , 这个时候就会运行 ONBUILD 指令, 触发指令
COPY                         # 类似 ADD 命令, 将文件拷贝到镜像中
ENV                            # 构建的时候设置环境变量

实战测试①

Docker Hub 中大多数镜像都是 FROM scratch 开始的. 然后配置需要的软件和配置来进行构建.

  1. 编写 Dockerfile 文件
FROM centos
MAINTAINER Oskari<oskari@bengder.cc>

ENV MYPATH /usr/local
WORKDIR $MYPATH

RUN yum -y install vim
RUN yum -y install net-tools

EXPOSE 80

CMD echo $MYPATH
CMD echo "IMAGE HAS BEEN BUILD SUCCESS!"

  1. 通过 Dockerfile 文件构建镜像

COMMAND: docker build -f dockerfile文件路径 -t 镜像名:版本号

docker build -f mydockerfile-centos -t mycentos .

运行镜像创建容器

docker run -it mycentos:1.0 /bin/bash
[root@8e1170f6d9f9 local]# ls
bin  etc  games  include  lib  lib64  libexec  sbin  share  src
[root@8e1170f6d9f9 local]# pwd
/usr/local
[root@8e1170f6d9f9 local]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.18.0.3  netmask 255.255.0.0  broadcast 0.0.0.0
        inet6 fe80::42:acff:fe12:3  prefixlen 64  scopeid 0x20<link>
        ether 02:42:ac:12:00:03  txqueuelen 0  (Ethernet)
        RX packets 8  bytes 656 (656.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 8  bytes 656 (656.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[root@8e1170f6d9f9 local]# vim test.txt
[root@8e1170f6d9f9 local]#

可以看到基于centos我们设置了进入容器后的工作目录, 安装了ifconfig vim 工具.

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

docker history mycentos:1.0 # 这里要使用 镜像名:版本号   或者 IMAGE ID
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
cca92ffcc1b0        9 minutes ago       /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "/b...   0 B                 
3d83dcb4dbd9        9 minutes ago       /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "ec...   0 B                 
5c0d7d6368f8        9 minutes ago       /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "ec...   0 B                 
f7142fb9a548        9 minutes ago       /bin/sh -c #(nop)  EXPOSE 80/tcp                0 B                 
cb37ff0fda19        9 minutes ago       /bin/sh -c yum -y install net-tools             27.9 MB             
d125a97e66e0        9 minutes ago       /bin/sh -c yum -y install vim                   65.5 MB             
d4dbfdccb802        9 minutes ago       /bin/sh -c #(nop) WORKDIR /usr/local            0 B                 
96e44cb6ccfb        9 minutes ago       /bin/sh -c #(nop)  ENV MYPATH=/usr/local        0 B                 
d193dbeebed5        9 minutes ago       /bin/sh -c #(nop)  MAINTAINER Oskari<oskar...   0 B                 
300e315adb2f        8 months ago        /bin/sh -c #(nop)  CMD ["/bin/bash"]            0 B                 
<missing>           8 months ago        /bin/sh -c #(nop)  LABEL org.label-schema....   0 B                 
<missing>           8 months ago        /bin/sh -c #(nop) ADD file:bd7a2aed6ede423...   209 MB

实现测试②

  1. 准备镜像文件 tomcat 压缩包, JDK 的压缩包
cd /home/build/tomcat       # 路径自由,随意些, 做足下面软件以及文件的准备
apache-tomcat-9.0.52-fulldocs.tar.gz  Dockerfile  jdk-16.0.2_linux-aarch64_bin.tar.gz  readme.txt
  1. 编写 Dockerfile ( 官方建议使用 Dockerfile , 在使用build 命令时, 无需添加 -f 参数)
FROM centos
MAINTAINER Oskari<oskari@bengder.cc>
COPY readme.txt /usr/local/readme.txt

# 在找包的时候请注意要与系统内核相对应
ADD jdk-8u301-linux-x64.tar.gz /usr/local
ADD apache-tomcat-9.0.52.tar.gz /usr/local

RUN yum -y install vim

ENV MYPATH /usr/local
WORKDIR $MYPATH

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

EXPOSE 8080

CMD /usr/local/apache-tomcat-9.0.52/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.52/logs/catalina.out

构建镜像

docker build -t tom .

启动镜像

# 挂载文件到宿主机并启动镜像
docker run -d -p 8090:8080 --name tomtest -v /home/build/tomcat/test:/usr/local/apache-tomcat-9.0.52/webapps/test -v /home/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.52/logs tom

查看挂载文件

访问容器

curl localhost:8090

可以看到正常返回的 html 代码. 亦可通过浏览器访问 IP:8090 查看容器状态是否正常运行

发布项目( 因为做了卷挂载, 所以在宿主机即可发布/编辑项目 )

/usr/build/tomcat/test/ 路径下创建 WEB-INF 文件夹, 创建配置文件 web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLScheme-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                            http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
        version="2.5">
</web-app>

/usr/build/tomcat/test/ 路径下创建 index.jsp 文件

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
Hello World!<br/>
<%
out.println("你的 IP 地址 " + request.getRemoteAddr());
%>
</body>
</html>

访问 IP:8090/test/ , 会正常输出 Hello World! 等信息

发布自己的镜像

发布镜像到 Dockerhub

地址 https://hub.docker.com 注册账号

登陆账号

docker login -u YOUR_DOCKERHUB_ACCOUNT
Password:   # 出现 Password 输入密码
Login Succeeded # 表示当前docker账户已登录

在服务器上进行镜像发布

docker push docker.io/zhangruoyucc/tom:1.0
end
  • 作者:旭仔(联系作者)
  • 发表时间:2024-06-09 13:58
  • 版权声明:自由转载-非商用-非衍生-保持署名
  • 转载声明:如果是转载栈主转载的文章,请附上原文链接
  • 公众号转载:请在文末添加作者公众号二维码(公众号二维码见右边,欢迎关注)
  • 评论