赞
踩
因为项目需要,在此学习一下docker相关知识,本篇参考黑马程序员相关课程以及其他人博客总结而成。
上图基本罗列了Docker的一些相关操作,其中有三个名词:
阿里镜像源:
mkdir -p /etc/docker
vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://duvzla6d.mirror.aliyuncs.com"]
}
systemctl daemon-reload
systemctl restart docker
其他镜像源:跳转
下图为Docker常用命令示意图,可以看出基本是基本是围绕着容器、镜像、仓库、DockFile等。
更多命令 可参考:https://docs.docker.com/engine/reference/commandline/cli/
注:忘记用法的命令都可以通过最后加–help的方式查看用法。
操作 | 命令 | 说明 |
---|---|---|
查找 | docker search 关键字 | 在docker hub网站查看镜像详情 |
抽取 | docker pull 镜像名:Tag | 如果Tag不指定,默认是latest 即最新版 |
推送 | docker push NAME[:TAG] | 把指定镜像推送到远程仓库 |
镜像保存 | docker save | 保存镜像到本地压缩文件 |
镜像加载 | docker load | 从本地压缩文件加载镜像 |
列表 | docker images | 查看本地所有镜像 |
获取元信息 | docker inspect 镜像ID或镜像名:Tag | 获取有关该镜像的相关信息 |
删除 | docker rmi -f 镜像id或镜像名:Tag | 删除本地镜像,-f强制删除 |
DockerFile构建镜像 | docker build -f Dockerfile文件的路径 -t 镜像名:tag 命令执行的上下文 | 利用DockerFile自己构建镜像 |
操作 | 命令 | 说明 |
---|---|---|
运行 | docker run -name 容器名 -p 宿主机端口:容器端口 -d -v 数据卷名或者宿主文件夹路径:容器内文件夹路径 -it 镜像id或镜像名:版本号 | -name:指定容器名,如果不指定会随机命名 -i 以交互模式运行 -t 分配一个终端 通常一起使用-it -p指定端口映射 -d 表示后台运行,以服务方式运行 -v 指定挂载 |
容器列表 | docker ps -a -q | -a:查看所有容器(包括已关闭的) -q 只显示容器id |
启动容器 | docker start 容器id/容器名 | 如果该容器已停止 通过该命令可以启动 |
重新启动容器 | docker restart 容器id/容器名 | 如果该容器在运行,通过该命令能让其重启 |
关闭容器 | docker stop 容器id/容器名 | 关闭指定容器 |
删除容器 | docker rm -f 容器id/容器名 | -f 表示强制删除容器(可删除正在运行的容器) |
日志 | docker logs 容器id/容器名 | 获取容器日志 |
获取容器元信息 | docker inspect 容器id/容器名 | 获取容器元信息 |
进入容器 | docker exec -it 容器id/容器名 bash或者/bin/bash | 以交互模式进入一个正在运行的容器 |
拷贝文件 | docker cp 主机中的文件路径 容器id/容器名:容器路径 docker cp 容器id或容器名称:容器路径 主机中的文件 | 谁在前 从谁那里拷贝 |
把容器保存为镜像 | docker commit 容器 镜像:Tag | 把修改的容器保存为新的镜像 |
Docker 的分层结构是 Docker 镜像的核心概念之一,它使得 Docker 在创建和管理容器时变得高效、灵活且资源节约。
在 Docker 中,每个镜像都由一系列分层(Layers)组成,这些分层是只读的文件系统。每一层都包含了镜像的一部分文件系统内容或配置。当你创建一个新的镜像时,Docker 将会基于现有的镜像,添加一个新的分层。这种方式可以极大地节省存储空间,因为多个镜像可以共享相同的分层。
以下是 Docker 分层结构的一些关键概念:
基础镜像(Base Images):基础镜像是 Docker 镜像的起点,它包含了操作系统的基本文件系统和工具。比如,Ubuntu、Alpine Linux、CentOS 等都可以作为基础镜像。基础镜像是只读的,且通常包含操作系统的核心组件。
分层(Layers):每个镜像由一系列分层组成,每一层都包含了文件系统的一部分。这些分层是只读的,并且通过联合文件系统(Union File System)进行组合,形成一个完整的镜像。当容器运行时,这些分层被叠加在一起,为容器提供文件系统和环境。
联合文件系统(Union File System):联合文件系统是一种文件系统的组合方式,它允许将多个文件系统挂载到同一个目录下,使得这些文件系统的内容在逻辑上呈现为单个文件系统。Docker 使用联合文件系统将多个镜像的分层组合成一个容器的文件系统。
镜像的可读性和写时复制(Copy-on-Write):由于 Docker 分层的特性,当容器运行时,它们可以读取所有镜像的分层,但是只有在容器中进行的修改才会写入新的分层中。这种写时复制的机制使得容器的创建和修改变得高效,并且可以节省存储空间。
镜像标签(Image Tags):镜像标签是用于标识镜像版本的字符串,它通常包含了镜像的名称和版本号。通过使用不同的标签,可以方便地管理和区分不同版本的镜像。
总的来说,Docker 的分层结构使得容器的创建、共享和管理变得更加灵活和高效。通过共享相同的基础镜像和分层,可以大大减少存储空间的占用,并且能够快速地创建、启动和销毁容器。
由于制作镜像的过程中,需要逐层处理和打包,比较复杂,所以Docker就提供了自动打包镜像的功能。我们只需要将打包的过程,每一层要做的事情用固定的语法写下来,交给Docker去执行即可。
而这种记录镜像结构的文件就称为Dockerfile,其对应的语法可以参考官方文档:
https://docs.docker.com/engine/reference/builder/
例如,要基于Ubuntu镜像来构建一个Java应用,其Dockerfile内容如下:
# 指定基础镜像 FROM ubuntu:16.04 # 配置环境变量,JDK的安装目录、容器内时区 ENV JAVA_DIR=/usr/local ENV TZ=Asia/Shanghai # 拷贝jdk和java项目的包 COPY ./jdk8.tar.gz $JAVA_DIR/ COPY ./docker-demo.jar /tmp/app.jar # 设定时区 RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone # 安装JDK RUN cd $JAVA_DIR \ && tar -xf ./jdk8.tar.gz \ && mv ./jdk1.8.0_144 ./java8 # 配置环境变量 ENV JAVA_HOME=$JAVA_DIR/java8 ENV PATH=$PATH:$JAVA_HOME/bin # 指定项目监听的端口 EXPOSE 8080 # 入口,java项目的启动命令 ENTRYPOINT ["java", "-jar", "/app.jar"]
当然我们也可以直接把基础镜像设为JDK环境。
# 基础镜像
FROM openjdk:11.0-jre-buster
# 设定时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 拷贝jar包
COPY docker-demo.jar /app.jar
# 入口
ENTRYPOINT ["java", "-jar", "/app.jar"]
一个Java项目的容器,而Java项目往往需要访问其它各种中间件,例如MySQL、Redis等。一个Docker中的所有容器都是可以通过本地IP互联的,因为他们都在同一个虚拟网关(docker0)下.
但是,容器的网络IP其实是一个虚拟的IP,其值并不固定与某一个容器绑定,如果我们在开发时写死某个IP,而在部署时很可能MySQL容器的IP会发生变化,连接会失败。
所以,我们必须借助于docker的网络功能来解决这个问题,官方文档:
https://docs.docker.com/engine/reference/commandline/network/
常见命令有:
案例:
# 1.首先通过命令创建一个网络 docker network create hmall # 2.然后查看网络 docker network ls # 结果: NETWORK ID NAME DRIVER SCOPE 639bc44d0a87 bridge bridge local 403f16ec62a2 hmall bridge local 0dc0f72a0fbb host host local cd8d3e8df47b none null local # 其中,除了hmall以外,其它都是默认的网络 # 3.让dd和mysql都加入该网络,注意,在加入网络时可以通过--alias给容器起别名 # 这样该网络内的其它容器可以用别名互相访问! # 3.1.mysql容器,指定别名为db,另外每一个容器都有一个别名是容器名 docker network connect hmall mysql --alias db # 3.2.db容器,也就是我们的java项目 docker network connect hmall dd # 4.进入dd容器,尝试利用别名访问db # 4.1.进入容器 docker exec -it dd bash # 4.2.用db别名访问 ping db # 结果 PING db (172.18.0.2) 56(84) bytes of data. 64 bytes from mysql.hmall (172.18.0.2): icmp_seq=1 ttl=64 time=0.070 ms 64 bytes from mysql.hmall (172.18.0.2): icmp_seq=2 ttl=64 time=0.056 ms # 4.3.用容器名访问 ping mysql # 结果: PING mysql (172.18.0.2) 56(84) bytes of data. 64 bytes from mysql.hmall (172.18.0.2): icmp_seq=1 ttl=64 time=0.044 ms 64 bytes from mysql.hmall (172.18.0.2): icmp_seq=2 ttl=64 time=0.054 ms
总结:
具体参考如下链接 实现Java mysql nginx项目的部署。
https://b11et3un53m.feishu.cn/wiki/MWQIw4Zvhil0I5ktPHwcoqZdnec
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。