-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
239 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,198 @@ | ||
--- | ||
title: docker入门 | ||
date: 2024-04-08 07:24:40 | ||
permalink: /pages/479a6c/ | ||
categories: | ||
- 技术学习 | ||
- docker | ||
tags: | ||
- | ||
author: | ||
name: lan-dian | ||
link: https://github.com/lan-dian | ||
--- | ||
## 是什么 | ||
|
||
Docker是一个容器技术,对进程进行封装隔离,进一步提供了文件系统,网络的隔离,屏蔽底层运行环境的差异,做到了完全一致。而且,比虚拟机的性能高出数倍。 | ||
|
||
> 和传统虚拟技术的差异 | ||
传统的虚拟技术会虚拟硬件,虚拟操作系统,然后在该系统上运行进程。而Docker直接使用Linux提供的各种隔离技术,直接运行于主机上。 | ||
|
||
> 架构 | ||
Docker 在运行时分为 Docker 引擎(也就是服务端守护进程)和客户端工具。 | ||
也就是说,看起来是本地执行命令,其实原创也是支持的。 | ||
|
||
## 怎么用 | ||
|
||
> 一致的运行环境 | ||
由于开发环境、测试环境、生产环境不一致,导致有些 bug 并未在开发过程中被发现。而 Docker 的镜像提供了**除内核外**完整的运行时环境,确保了应用运行环境一致性。 | ||
环境一致对开发也非常重要,如果是因为环境因素导致的问题,那么本地和上线的代码就不一样,而且解决起问题也会十分的麻烦。 | ||
|
||
> 一次编写,到处运行 | ||
使用DockerFile,可以做到一次配置,可以快速的任何环境下完成部署,我们也常常感受到自己配置环境是非常麻烦的,而且在不同的机器上,由于之前环境的干扰,会出现很多意想不到的问题。 | ||
|
||
> 部署服务 | ||
刚接触Linux,我们部署MySql,可能是下载安装配置等等,每个应用的流程都不一样,非常繁琐。 | ||
之后我们知道了apt这样的管理工具可以让我们的部署大幅度简化。 | ||
但是,如果之后需要部署什么东西,我们可以优先在网络上查询docker安装xxx,以此来提高速度,节约我们在环境上的时间。 | ||
|
||
## 概念 | ||
|
||
任何技术的学习都要明确他的概念,他基于了设计者的设计理念,方便我们和其他人交流复杂的概念。 | ||
|
||
### 镜像(image) | ||
|
||
可以理解为一个独立系统打包后的所有内容,不包含任何的动态数据,本质是一个文件。 | ||
|
||
#### 分层存储 | ||
|
||
镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。 | ||
甚至在删除一层文件的时候,都仅仅只是标记删除,会对镜像的体积照成影响,额外的东西要在本层构建结束之前删掉。 | ||
这样的分层设计,支持镜像的复用,我们也可以在已经有的镜像之上构建新的镜像。 | ||
|
||
### 容器 | ||
|
||
如果说镜像是文件,那么容器就是运行时。容器可以被创建、启动、停止、删除、暂停等。本质是一个进程。 | ||
但是这个进程有自己独立的命名空间,所以有自己的文件系统,网络等等隔离特性。 | ||
容器运行的本质就是,以镜像为基础层,在其上创建一个当前容器的存储层,我们可以称这个为容器**运行时读写**而准备的存储层为**容器存储层**。容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡。因此,任何保存于容器存储层的信息都会随容器删除而丢失。所以要求我们必须在数据卷读写,其实本质就是文件读写的重定向。 | ||
|
||
### Registry | ||
|
||
镜像是本地文件,docker的本质就为了让不同的环境运行,势必要方便拿到镜像。仓库是类型github的网址,里面有多个tag,一般代表不同的版本。默认tag是最新的版本。 | ||
|
||
## 使用 | ||
|
||
### 基本命令 | ||
|
||
> docker pull | ||
``` | ||
docker pull ubuntu | ||
``` | ||
|
||
从Registry拉取镜像。 | ||
下载的时候,本质是在下载一个文件组,通过分层下载的方式,之前下载的过的文件会直接复用。 | ||
同理,push可以把本地构建的镜像推送到云端。 | ||
|
||
> docker run | ||
``` | ||
docker run -itd ubuntu bash | ||
``` | ||
|
||
运行镜像->容器。 | ||
可以加-it参数,一个是 -i:交互式操作,一个是 -t 终端。 | ||
-d:后台执行。 | ||
通过exit退出。 | ||
进入正在运行容器是exec,其他的完全一样 | ||
|
||
> 容器命令 | ||
docker ps -a | ||
查看容器 | ||
docker start xxx | ||
docker stop xxx | ||
docker restart xxx | ||
docker rm xxx | ||
|
||
> docker logs -f | ||
可以和tail -f一样,查看日志。 | ||
|
||
> docker image ls | ||
列出已经下载的镜像,后面可以加关键词搜索我们想看的 | ||
这里有一个关键概念,ID,在我们需要操作镜像的时候,需要输入ID前3位,知道可以区分出他们就可以。 | ||
可以使用docker image prune来清理镜像空间 | ||
|
||
> docker image rm | ||
remove删除镜像 | ||
值得注意的是,docke保护我们不会删除有运行容器的镜像,所以必须先删除容器,再删除镜像。 | ||
|
||
### 数据卷(volume) | ||
|
||
数据卷就是挂载在我们磁盘空间的,不受容器影响的文件系统。我的理解是,可以让容器操作我们的目录,这个和容器无关的目录,数据卷提供了这种映射关系。 | ||
可以通过-v 源目录:容器目录 | ||
我们可以发现,docker都是源目录在前,容器目录在后的,此外,源目录必须是绝对路径。 | ||
|
||
### 网络 | ||
|
||
docker数据比较简单,但是网络确实是有难度的,之前我们说了网络会被隔离,那么我们如何访问docker内的服务呢。 | ||
docker提供了端口映射的功能,使用-p来指定,如果我们访问了本地的某个端口,就可以访问到容器内的某个端口。 | ||
可是docker容器内的网络如何访问呢,这里docker给我们提供了一个机制,可以把容器加入一个互通的网络里面,docker network create -d bridge my-net,可以都使用这一个网络。 | ||
运行的时候,使用 --network my-net 就可以接入这个网络了。 | ||
但是如果你有多个容器之间需要互相连接,推荐使用 Docker Compose。 | ||
|
||
## DockerFile | ||
|
||
docker build -t xxxx:xxx . | ||
|
||
> docker build工作原理 | ||
我们执行的命令本质是一个客户端,真正的打包是在docker服务端完成的,当我们进行镜像构建的时候,并非所有定制都会通过 RUN 指令完成,经常会需要将一些本地文件复制进镜像,比如通过 COPY 指令、ADD 指令等。如何才能让服务端获得本地文件呢? | ||
这就是上下文的概念,会把这个路径下的所有文件打包,放进上传给docker服务端。 | ||
所以:COPY 这类指令中的源文件的路径都是相对路径。为什么 COPY ../package.json /app 或者 COPY /opt/xxxx /app 无法工作的原因,因为这些路径已经超出了上下文的范围,Docker 引擎无法获得这些位置的文件。如果真的需要那些文件,应该将它们复制到上下文目录中去。 | ||
同理,可以用 .gitignore 一样的语法写一个 .dockerignore,该文件是用于剔除不需要作为上下文传递给 Docker 引擎的。 | ||
|
||
### FROM | ||
|
||
基于哪个镜像开始构建,操作系统都是轻量级的,比如apt,我们必须先执行apt update,然后才能进行安装,不然会报错 | ||
|
||
### RUN | ||
|
||
运行命令,这里有个小细节,因为每次RUN都会构建新的层,所以我们可以使用Linux的换行命令实现 | ||
|
||
``` | ||
RUN set -x; buildDeps='mysql' \ | ||
&& apt update \ | ||
&& apt install -y $buildDeps \ | ||
&& apt purge -y --auto-remove $buildDeps | ||
``` | ||
|
||
### COPY | ||
|
||
COPY 源路径 目标路径 | ||
|
||
> 源路径 | ||
基于build时指定的路径,相当于把哪些文件复制到一个地方的相对路径。 | ||
如果源路径为文件夹,复制的时候不是直接复制该文件夹,而是将文件夹中的内容复制到目标路径。 | ||
|
||
> 目标路径 | ||
可以是系统的绝对路径 也可以相对于工作路径。目标路径不需要事先创建,如果目录不存在会在复制文件前先行创建缺失目录。 | ||
|
||
### CMD | ||
|
||
容器运行起来之后,执行的命令,比如运行什么什么服务,可以支持变量,因为这个本质是sh xxx 会解析环境变量。 | ||
如果我们在docker run 最后写了一些指令,那么这些指令就会直接代替cmd的内容。 | ||
|
||
### ENV | ||
|
||
可以给其他的docker命令支持统一的环境变量,建议把一些需要修改的变量,或者统一的东西作为常量放在ENV里面,这些参数会被加到容器的环境变量中 | ||
格式为k1=v1 k2=v2 | ||
|
||
### AVG | ||
|
||
参数,不会加入运行的环境变量中,支持默认值 | ||
|
||
--- | ||
|
||
### 例子 | ||
|
||
> Spring Boot的DockerFile | ||
``` | ||
FROM openjdk:17-jdk-alpine | ||
MAINTAINER baeldung.com | ||
COPY target/xxxx-1.0.0.jar app.jar | ||
ENTRYPOINT ["java","-jar","/app.jar"] | ||
``` | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
--- | ||
title: 原理 | ||
date: 2024-04-09 17:24:43 | ||
permalink: /pages/4d9eaa/ | ||
categories: | ||
- 技术学习 | ||
- docker | ||
tags: | ||
- | ||
author: | ||
name: lan-dian | ||
link: https://github.com/lan-dian | ||
--- | ||
## 联合文件系统(Union File System) | ||
|
||
它可以把多个目录(也叫分支)内容联合挂载到同一个目录下,而目录的物理位置是分开的。UnionFS允许只读和可读写目录并存,就是说可同时删除和增加内容。也就说这个不是docker支持的,而且是docker去运用的。 | ||
|
||
## docker run | ||
|
||
- 检查本地是否存在指定的镜像,不存在就从 registry 下载 | ||
- 利用镜像创建并启动一个容器 | ||
- **分配一个文件系统,并在只读的镜像层外面挂载一层可读写层** | ||
- 从**宿主主机配置的网桥接口中桥接一个虚拟接口到容器**中去 | ||
- 从**地址池配置一个 ip 地址给容器** | ||
- 执行用户指定的应用程序 | ||
- 执行完毕后容器被终止 | ||
|
||
## 网络 | ||
|
||
Docker 原生网络是基于 Linux 的 网络命名空间(net namespace) 和 虚拟网络设备(veth pair)实现的。当 Docker 进程启动时,会在宿主机上创建一个名称为 docker0 的 虚拟网桥,在该宿主机上启动的 Docker 容器会连接到这个虚拟网桥上。 | ||
虚拟网桥的工作方式和物理交换机类似,宿主机上所有的容器通过虚拟网桥连接在一个二层网络中。 | ||
从 docker0 子网中分配一个 IP 给容器使用,并设置 docker0 的 IP 地址为容器的默认网关。在宿主机上创建一对虚拟网卡 veth pair 设备, Docker 将 veth pair 设备的一端放在新创建的容器中,并命名为 eth0(容器的网卡), 另一端放在宿主机中,以 vethxxx 类似的名字命名, 并将这个网络设备连接到 docker0 网桥中。 | ||
虚拟网桥 docker0 通过 iptables 配置与宿主机器上的网卡相连,符合条件的请求都会通过 iptables 转发到 docker0, 然后分发给对应的容器。 | ||
|
||
| 名称 | 描述 | | ||
| ------- | ---------------------------------------------------- | | ||
| bridge | 默认的网络设备,当应用程序所在的容器需要通信时使用 | | ||
| host | 移除容器与宿主机之间的网络隔离,直接使用宿主机的网络 | | ||
| overlay | 将多个容器连接,并使集群服务能够相互通信 | | ||
|