Docker 篇-Docker 详细安装、了解和使用 Docker 核心功能(数据卷、自定义镜像 Dockerfile、网络)

🔥博客主页: 【小扳_-CSDN博客】**
❤感谢大家点赞👍收藏⭐评论✍**

文章目录

[1.0 Docker 概述](#1.0 Docker 概述)

[1.1 Docker 主要组成部分](#1.1 Docker 主要组成部分)

[1.2 Docker 安装](#1.2 Docker 安装)

[2.0 Docker 常见命令](#2.0 Docker 常见命令)

[2.1 常见的命令介绍](#2.1 常见的命令介绍)

[2.2 常见的命令演示](#2.2 常见的命令演示)

[3.0 数据卷](#3.0 数据卷)

[3.1 数据卷常见的命令](#3.1 数据卷常见的命令)

[3.2 常见数据卷命令的演示](#3.2 常见数据卷命令的演示)

[3.3 挂载本地目录或文件](#3.3 挂载本地目录或文件)

[4.0 自定义镜像](#4.0 自定义镜像)

[4.1 Dockerfile 文件](#4.1 Dockerfile 文件)

[5.0 网络](#5.0 网络)

[5.1 常见的命令](#5.1 常见的命令)


1.0 Docker 概述

Docker 是一个开源平台,用于自动化应用程序的部署、扩展和管理,采用的是容器化技术。它允许开发者将应用程序及其所有依赖项打包成轻量级、可移植的容器,从而确保无论在何种环境中运行,应用程序都能够保持一致的行为。

1.1 Docker 主要组成部分

Docker 镜像:镜像是一个轻量级、可执行的独立软件包,包含了运行某个软件所需的所有代码、库、环境变量和配置文件。镜像是不可变的,可以从它们创建容器。

Docker 容器:容器是从镜像创建的运行实例,是轻量级的、隔离的执行环境。容器共享宿主操作系统的核心,但相互之间是隔离的。

Docker Hub:这是 Docker 的公共仓库,用户可以在这里存储和分享 Docker 镜像。

1.2 Docker 安装

通过在华为云上安装 Ubuntu 版本的 Docker:

1)若您安装过 Docker,需要先删掉,之后再安装依赖

bash 复制代码
sudo apt-get remove docker docker-engine docker.io
sudo apt-get install apt-transport-https ca-certificates curl gnupg2 software-properties-common

2)根据版本不同,运行公钥,添加软件仓库

信任 Docker 的 GPG 公钥:

bash 复制代码
curl -fsSL https://mirrors.huaweicloud.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -

对于 amd64 架构的计算机,添加软件仓库:

bash 复制代码
sudo add-apt-repository "deb [arch=amd64] https://mirrors.huaweicloud.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"

对于树莓派或其它 Arm 架构计算机,请运行:

bash 复制代码
echo "deb [arch=armhf] https://mirrors.huaweicloud.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list

3)更新索引文件并安装

bash 复制代码
sudo apt-get update
sudo apt-get install docker-ce

4)添加镜像

首先执行命令,打开文件:

bash 复制代码
vi /etc/docker/daemon.json 

添加镜像信息:

bash 复制代码
{
        "registry-mirrors": [
                "https://docker.m.daocloud.io",
                "https://dockerhub.timeweb.cloud",
                "https://huecker.io"
  ]
}

如图:

文件内容输入后,再执行以下命令:

bash 复制代码
sudo systemctl daemon-reload
sudo systemctl restart docker

5)最后,测试 Docker 是否安装好

输入以下命令:

bash 复制代码
docker images

出现的结果为:

这就完成 Dcoker 安装了。

2.0 Docker 常见命令

先来介绍常见的命令,其他不常见的命令可以参考:

Docker 的官方文档:docker | Docker Docs

2.1 常见的命令介绍

1)docker pull:拉取镜像

2)docker push:推送镜像

3)docker images:查看本地镜像

4)docker rmi:删除指定本地镜像

5)docker run:创建容器并运行容器

6)docker stop:停止指定容器

7)docker start:启动指定容器

8)docker restart:重启指定容器

9)docker rm:删除指定容器

10)docker ps:查看容器

11)docker logs:查看容器运行日志

12)docker exec:进入容器

13)docker save:保存镜像到本地压缩文件

14)docker load:加载本地压缩文件到镜像

15)docker inspect:查看容器详情信息

16)docker build:创建本地镜像

用一副图来表示这些命令的关系:

默认情况下,每次重启虚拟机我们都需要手动启动 Docker 和 Docker 中的容器。通过命令可以实现开机自启:

bash 复制代码
# Docker开机自启
systemctl enable docker

# Docker容器开机自启
docker update --restart=always [容器名/容器id]

2.2 常见的命令演示

使用 Docker 安装 Nginx 软件为例子:

1)首先从 Docker 中央仓库中拉取 nginx镜像:

bash 复制代码
docker pull nginx

具体如下:

2)查看镜像:

bash 复制代码
docker images

具体如下:

成功从 Docker 中央仓库中拉取到 nginx 镜像。

3)创建并运行容器:

bash 复制代码
docker run -d --name nginx -p 80:80 nginx

命令解析:-d 指在后台运行,--name 指定容器的名字,-p 端口映射,nignx 镜像名

具体如下:

4)查看运行容器:

bash 复制代码
docker ps

具体如下:

也可以加格式化访问,会更加清爽:

bash 复制代码
docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"

具体如下:

5)访问网址:

因为 nginx 已经部署到了云服务器了,那么通过 IP:端口号进行访问

具体如下:

成功访问了。

6)停止容器:

bash 复制代码
docker stop nginx

具体如下:

停止之后,通过查看容器运行情况,发现 nginx 容器已经停止了。

7)启动容器:

bash 复制代码
docker start nginx

具体如下:

通过启动命令之后,再查看运行容器,发现 nginx 正在运行。

8)查看容器详情:

bash 复制代码
docker inspect nginx

具体如下:

9)进入容器,查看容器目录

bash 复制代码
docker exec -it nginx bash

具体如下:

进入到 nginx 容器中,通过 ls 命令查看容器中的目录

额外举个 MySQL 的例子:

通过 docker exec -it mysql bash 进入到 mysql 容器,再通过 mysql -uroot -p 进入到 mysql 控制台

具体如下:

10)强制删除运行中的容器

bash 复制代码
docker rm nginx -f

具体如下:

删除完之后,查看运行中的容器,发现 nginx 已经被删除了。

11)查看日志

通过 mysql 举个例子

bash 复制代码
docker logs -f mysql

具体如下:

3.0 数据卷

数据卷(Volume) 是一个虚拟目录,是容器内目录与宿主机目录之间映射的桥梁。

因此,容器提供程序的运行环境,但是程序运行产生的数据、程序运行依赖都配置都应该与容器解耦。

比如说,MySQL、nginx 容器运行后,如果需要修改其中某些配置该怎么办?这时候,就需要用到数据卷,将宿主机与容器内的配置信息进行映射。

以 nginx 为例,在 nginx 中有两个关键的目录:

1)html:放置一些静态资源。

2)conf:放置配置文件。

利用数据卷将两个目录与宿主机目录关联,如图:

在上图中:
我们创建了两个数据卷:conf、html,Nginx 容器内部的 conf 目录和 html 目录分别与两个数据卷关联。
而数据卷 conf 和 html 分别指向了宿主机的 /var/lib/docker/volumes/conf/_data 目录和 /var/lib/docker/volumes/html/_data 目录。
这样以来,容器内的 conf 和 html 目录就 与宿主机的 conf 和 html 目录关联起来,我们称为挂载。此时,我们操作宿主机的 /var/lib/docker/volumes/html/_data 就是在操作容器内的 /usr/share/nginx/html/_data 目录。只要我们将静态资源放入宿主机对应目录,就可以被 Nginx 代理了。

/var/lib/docker/volumes 这个目录就是默认的存放所有容器数据卷的目录,其下再根据数据卷名称创建新目录,格式为 /数据卷名 /_data。

3.1 数据卷常见的命令

1)docker volume create:创建数据卷

2)docker volume ls:查看所有数据卷

3)docker volume inspect:查看某个数据卷的详情

4)docker volume rm:删除指定数据卷

5)docker volume prune:清除数据卷

注意:容器与数据卷的挂载要在创建容器时配置,对于创建好的容器,是不能设置数据卷的。而且创建容器的过程中,数据卷会自动创建。

3.2 常见数据卷命令的演示

以 niginx 为例子,将容器中的 /usr/share/nginx/html 目录挂载到宿主机中。

1)首先创建容器并指定数据卷,注意通过 -v 参数来指定数据卷:

bash 复制代码
docker run -d --name nginx -p 80:80 -v html:/usr/share/nginx/html nginx

具体如下:

2)查看数据卷:

bash 复制代码
docker volume ls

具体如下:

可以通过修改宿主机中的 html 来修改配置,从而会自动映射到 nginx 容器中的配置:

修改之前:

修改宿主机的 html:


此时,宿主机中的 index.html 文件被修改了,观察是否映射到容器中的 index.html 文件:

发现已经被修改了,但是修改文字对不上号,这可能是字符集导致的乱码。

使用英文再测试一遍:

宿主机中的 index.html:

再来访问 nginx

因此,宿主机中的 index.html 与容器中的 index.html 成功完成了映射。

3)查看数据卷详情:

bash 复制代码
docker volume inspect html

具体如下:

3.3 挂载本地目录或文件

可以发现,数据卷的目录结构较深,如果我们去操作数据卷目录会不太方便。在很多情况下,我们会直接将容器目录与宿主机指定目录挂载。挂载语法与数据卷类似:

bash 复制代码
# 挂载本地目录
-v 本地目录:容器内目录
# 挂载本地文件
-v 本地文件:容器内文件

注意:本地目录或文件必须以 / 或 ./ 开头,如果直接以名字开头,会被识别为数据卷名而非本地目录名。

例如:

bash 复制代码
-v mysql:/var/lib/mysql # 会被识别为一个数据卷叫mysql,运行时会自动创建这个数据卷
-v ./mysql:/var/lib/mysql # 会被识别为当前目录下的mysql目录,运行时如果不存在会创建目录

使用 mysql 为例,将 mysql 容器中的 /var/lib/mysql 文件挂载到 ./mysql/data 本地目录。

bash 复制代码
docker run -d \
  --name mysql \
  -p 3306:3306 \
  -e TZ=Asia/Shanghai \
  -e MYSQL_ROOT_PASSWORD=123 \
  -v ./mysql/data:/var/lib/mysql \
  mysql

具体如下:


本地目录与容器中的 /var/lib/mysql 文件挂载成功了,因此可以通过修改本地目录的数据,从而实现对容器中的 mysql 数据进行修改。

4.0 自定义镜像

要想自己构建镜像,必须先了解镜像结构。镜像之所以能让我们快速跨操作系统部署应用而忽略器运行环境、配置,就是因为镜像中包含了程序运行需要的系统函数库、环境、配置、依赖。

因此,自定义镜像本质就是依次准备好程序运行的基础环境、依赖、应用本身、运行配置等文件,并且打包而成。

举个例子,从 0 部署一个 Java 应用,大概的流程:

1)准备一个 linux 服务(CentOS 或者 Ubuntu 均可)

2)安装并配置 JDK

3)上传 Jar 包

4)运行 Jar 包

那因此,打包镜像也是分为这么几步:

1)准备 Linx 环境,Java 项目并不需要完整的操作系统,仅仅是基础运行环境即可。

2)安装并配置 JDK 。

3)拷贝 Jar 包。

4)配置启动脚本。

上述步骤中每一个操作其实都是在生产一些文件,系统运行环境、函数库、配置最终都是磁盘文件,所以镜像就是一堆文件的集合。

但是需要注意的是,镜像文件不是随意堆放的,而是按照操作的步骤分层叠加而成,每一层形成的文件都会单独打包并标记一个唯一 id,称为 Layer(层)。这样,在构建一些重复的层,就不需要重复拷贝这些层了。

4.1 Dockerfile 文件

由于制作镜像的过程中,需要逐层处理和打包,比较复杂,所以 Docker 就提供了自动打包镜像的功能。我们只需要将打包的过程,每一层要做的事情用固定的语法写下来,交给 Docker 去执行即可。

而这种记录镜像结构的文件就称为 Dockerfile,其对应的语法可以参考官方文档:Dockerfile reference | Docker Docs

其中的语法比较多,比较常用的有:

1)FROM:指定基础镜像。

2)ENV:设置环境变量,可在后面指令使用。

3)COPY:拷贝本地文件到镜像的指定目录。

4)RUN:执行 Linux 的 shell 命令,一般是安装过程的命令。

5)EXPOSE:指定容器运行时监听的端口,是给镜像使用者看的。

6)ENTRYPOINT:镜像中应用的启动命令,容器运行时调用。

例如,要基于 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"]

思考一下:以后我们会有很多很多 java 项目需要打包为镜像,他们都需要 Linux 系统环境、JDK 环境这两层,只有上面的3层不同(因为 jar 包不同)。如果每次制作 java 镜像都重复制作前两层镜像,是不是很麻烦。

所以,就有人提供了基础的系统加JDK环境,我们在此基础上制作 java 镜像,就可以省去 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"]

因此,我们只需要准备 JDK 的基础镜像和 jar 包即可。

举个例子:

1)现在准备好了 Dockerfile 文件和 jar 包、jdk.jar

先将 jdk.jar 的基础镜像加载到镜像中:

docker load -i jdk.tar

具体如下:

2)接着指定命令:

进入 demo 目录:

再执行该命令:

# 直接指定Dockerfile目录
docker build -t docker-demo .

命令说明:
docker build : 就是构建一个 docker 镜像
-t docker-demo :-t 参数是指定镜像的名称(repository 和 tag)
. : 最后的点是指构建时 Dockerfile 所在路径,由于我们进入了 demo 目录,所以指定的是 . 代表当前目录,也可以直接指定 Dockerfile 目录。

因为 Dockerfile 就在当前目录下,直接使用 . 来声明 Dockerfile 的位置。

具体如下:

3)查看镜像:

具体如下:

4)创建并运行容器:

docker run -d --name dd -p 8080:8080 docker-demo

具体如下:

运行之后,查看运行容器

5)访问容器:

5.0 网络

假设创建了一个 Java 项目的容器,而 Java 项目往往需要访问其它各种中间件,例如 MySQL、Redis 等。现在,我们的容器之间能否互相访问呢?我们来测试一下:

首先,我们查看下 MySQL 容器的详细信息,重点关注其中的网络 IP 地址:

# 1.用基本命令,寻找Networks.bridge.IPAddress属性
docker inspect mysql
# 也可以使用format过滤结果
docker inspect --format='{{range .NetworkSettings.Networks}}{{println .IPAddress}}{{end}}' mysql
# 得到IP地址如下:
172.17.0.2

# 2.然后通过命令进入dd容器
docker exec -it dd bash

# 3.在容器内,通过ping命令测试网络
ping 172.17.0.2
# 结果
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.053 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.059 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.058 ms

但是,容器的网络 IP 其实是一个虚拟的 IP,其值并不固定与某一个容器绑定,如果我们在开发时写死某个 IP,而在部署时很可能 MySQL 容器的IP会发生变化,连接会失败。

所以,我们必须借助于 docker 的网络功能来解决这个问题。

5.1 常见的命令

1)docker network create:创建一个网络

2)docker network ls:查看所有网络

3)docker network rm:删除指定网络

4)docker network prune:清除未使用的网络

5)docker network connect:使指定容器连接加入某网络

6)docker network disconnect:使指定容器连接离开某网络

7)docker network inspect:查看网络详情信息

自定义网络演示:

首先,创建一个网络:

docker network create xbs

具体如下:

接着查看网络:

docker network ls

具体如下:

再接着详细了解 xbs 网络:

docker network inspect xbs

具体如下:

网关为:172.18.0.1

将 mysql 加入到该网络中:

docker network connect xbs mysql

具体如下:

查看 mysql 网络详情:

docker inspect mysql

具体如下:

此时 mysql 容器中的网关为 172.18.0.1,IP 为 172.18.0.2 。

配置完 mysql 容器之后,只要在该网段中的所有容器,都可以根据容器名进行相互访问。

接着将 Java 项目的容器加入该网段:

docker network connect xbs dd

具体如下:

查看详情信息

网关为 172.18.0.1,Java 项目的 IP 为 172.18.0.4 。因此,dd 容器可以与 mysql 容器进行相互访问,联通的。

dd 容器与 mysql 容器尝试进行拼接:

docker exec -it dd bash

具体如下:

在加入了同一个网段之后,只需要通过访问容器名就可以实现 dd 容器与 mysql 容器进行连通。

总结:

1)在自定义网络中,可以给容器其多个别名,默认的别名是容器名本身。

2)在同一个自定义网络中的容器,可以通过别名互相访问。

3)现在无需记住 IP 地址也可以实现容器互联。

相关推荐
Json____2 分钟前
学法减分交管12123模拟练习小程序源码前端和后端和搭建教程
前端·后端·学习·小程序·uni-app·学法减分·驾考题库
IpdataCloud4 分钟前
IP数据云 识别和分析tor、proxy等各类型代理
运维·服务器
monkey_meng22 分钟前
【Rust类型驱动开发 Type Driven Development】
开发语言·后端·rust
想学习java初学者23 分钟前
Docker compose部署elasticsearch(单机版)
运维·docker·容器
落落落sss30 分钟前
MQ集群
java·服务器·开发语言·后端·elasticsearch·adb·ruby
人类群星闪耀时1 小时前
未来运维的发展趋势:运维领域的新技术与趋势
运维
落非1 小时前
NFS存储基础操作
运维
大鲤余1 小时前
Rust,删除cargo安装的可执行文件
开发语言·后端·rust
她说彩礼65万1 小时前
Asp.NET Core Mvc中一个视图怎么设置多个强数据类型
后端·asp.net·mvc
陈随易1 小时前
农村程序员-关于小孩教育的思考
前端·后端·程序员