Docker
更适合前端宝宝的 Docker 教程
CentOS 中安装 docker
Windows 中安装 docker
docker hub
使用 docker bash
:Windows 配置:需要先开启 hyper-V 或手动追加环境变量 PATH 路径 C:\Program Files\Docker\Docker\resources\bin
。重启后生效
docker 可以理解成一个集装箱,里面有各种服务和环境。不必考虑里面装了什么,只在要有 docker 的主机上,就可以运行 docker 镜像,移植性强。
比如:你要跑一个陌生语言的服务,该服务如果提供 docker 镜像的话,就不用在自己本地捣鼓该服务的环境了,直接 pull 该服务镜像让其在本机 docker 的容器中运行即可。
Docker 技术的三大核心概念
镜像 Image、容器 Container、仓库 Repository
<font style="color:rgb(37, 41, 51);">image</font>
: 镜像,可以理解为一个容器的模板,通过一个镜像可以创建多个容器
<font style="color:rgb(37, 41, 51);">container</font>
: 最小型的一个操作系统环境(虚拟机),可以对各种服务以及应用容器化,是镜像的运行实例
<font style="color:rgb(37, 41, 51);">registry</font>
: 镜像仓库,存储大量镜像,可以从镜像仓库拉取和推送镜像
基础使用
linux 中 启动 docker => sudo 表示 允许普通用户使用 root 的超级权限以及命令的工具。
1 |
|
查看下载的 docker 镜像
1 |
|
搜索 镜像资源
1 |
|
拉取镜像
1 |
|
查看容器
1 |
|
宿主机和容器之间复制文件或目录 cp
1 |
|
资源管理
1 |
|
发布镜像到 docker hub
1 |
|
docker 中 启动容器
先构建镜像
1 |
|
启动!
1 |
|
-d
(deamon) 即后台运行
--rm
当停止容器时自动清楚容器
-p
端口映射 => 本机端口:
容器端口
-v
指定挂载卷 => 本机路径:
容器路径
<font style="color:rgb(37, 41, 51);">-e</font>
指定环境变量
<font style="color:rgb(37, 41, 51);">--name</font>
设置容器名
<font style="color:rgb(37, 41, 51);">--network</font>
指定 network namespace最后的是镜像名
关闭服务
1 |
|
dockerfile 例子
1 |
|
这里有个细节就是,docker 是分层存储的,dockerfile 里的每一行指令是一层,会做缓存。每次 docker build 的时候,只会从变化的层开始重新构建,没变的层会直接复用。所以上面示例中 只是 <font style="color:rgb(37, 41, 51);">COPY package.json . </font>
后才执行 <font style="color:rgb(37, 41, 51);">npm install</font>
, 而非是在COPY整个目录后执行。为的就是只有在package.json变化后才重新装包。
关键字
**<font style="color:rgb(37, 41, 51);">FROM</font>**
:基于一个基础镜像来修改**<font style="color:rgb(37, 41, 51);">WORKDIR</font>**
:指定当前工作目录**<font style="color:rgb(37, 41, 51);">COPY</font>**
:把容器外的内容复制到容器内**<font style="color:rgb(37, 41, 51);">EXPOSE</font>**
:声明当前容器要访问的网络端口,比如这里起服务会用到 8080**<font style="color:rgb(37, 41, 51);">RUN</font>**
:在容器内,docker build 时执行的命令**<font style="color:rgb(37, 41, 51);">CMD</font>**
:容器启动即 docker run 时执行的命令**<font style="color:rgb(37, 41, 51);">VOLUME</font>**
指令看起来没啥用,但能保证你所指定的容器内那个目录下的数据一定会被持久化,能保证没挂载数据卷的时候,数据不丢失。(未指定挂载卷时会随机生成一个目录作为数据卷挂载上去)
细节
- 使用
**<font style="color:rgb(37, 41, 51);">alpine</font>**
的镜像,而不是默认的 linux 镜像,可以极大减小镜像体积,比如<font style="color:rgb(37, 41, 51);">node:18-alpine3.14</font>
、<font style="color:rgb(37, 41, 51);">node:lts-alpine3.19</font>
这种 - 不同容器可以使用相同的
<font style="color:rgb(37, 41, 51);">EXPOSE</font>
端口,但是每个容器在主机上的映射端口必须是唯一的。否则,启动容器时会出现端口冲突错误。 - 使用多阶段构建,比如一个阶段来执行 build,一个阶段把文件复制过去,跑起服务来,最后只保留最后一个阶段的镜像。这样使镜像内只保留运行需要的文件以及 dependencies。
1 |
|
- 使用 ARG 增加构建灵活性,ARG 可以在 docker build 时通过 –build-arg xxx=yyy 传入,在 dockerfile 中生效,可以使构建过程更灵活。如果是想定义运行时可以访问的变量,可以通过 ENV 定义环境变量,值使用 ARG 传入。
<font style="color:rgb(37, 41, 51);">CMD</font>
和<font style="color:rgb(37, 41, 51);">ENTRYPOINT</font>
都可以指定容器跑起来之后运行的命令,CMD 可以被覆盖,而 ENTRYPOINT 不可以,两者结合使用可以实现参数默认值的功能。<font style="color:rgb(37, 41, 51);">ADD</font>
和<font style="color:rgb(37, 41, 51);">COPY</font>
都可以复制文件到容器内,但是 ADD 处理 tar.gz 的时候,还会做一下解压。- docker build 的时候会把 dockerfile 和它的构建上下文(也就是所在目录)打包发送给 docker daemon (docker 守护程序) 来构建镜像。可以通过
<font style="color:rgb(37, 41, 51);">.dockerignore</font>
(语法和 .gitignore 一致) 指定哪些文件不发送,这样能加快构建时间,减小镜像体积。
1 |
|
原理
Docker 实现原理的三大基础技术:
<font style="color:rgb(37, 41, 51);">Namespace</font>
:实现各种资源的隔离- PID namespace: 进程 id 的命名空间
- IPC namespace: 进程通信的命名空间
- Mount namespace:文件系统挂载的命名空间
- Network namespace:网络的命名空间
- User namespace:用户和用户组的命名空间
- UTS namespace:主机名和域名的命名空间
<font style="color:rgb(37, 41, 51);">Control Group</font>
:实现容器进程的资源访问限制- 比如 cpu 用多少、内存用多少、磁盘用多少,然后加到这个组里的进程就会受到这个限制。
<font style="color:rgb(37, 41, 51);">UnionFS</font>
:实现容器文件系统的分层存储,相同层可复用,镜像合并- dockerfile 描述镜像构建的过程,每一条指令都是一个镜像层。
- 镜像通过 docker run 就可以跑起来,对外提供服务,这时会添加一个
<font style="color:rgb(37, 41, 51);">可写层(容器层</font>
。挂载一个 volume 数据卷到 Docker 容器,就可以实现数据的持久化。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!