docker 基本知识
docker 优势
对于传统虚拟机,有以下几个缺点:
1. 资源占用多,虚拟机启动的时候会独自启动一部分内存和部分磁盘,导致虚拟机运行的时候这些资源无法被其他程序占用,导致资源浪费
2. 虚拟机的启动慢
3. 冗余步骤多
docker的基本思想
docker的基本思想是将软件以及相关关联的Lib打包在一起,做为一个容器,他们共享一个内核,相较于传统的虚拟机,简洁很多,简要图如下
docker的基本组成
镜像(Image):docker镜像就好比一个模板,我们可以通过这个模板来创建容器服务,tomcat镜像===>run==>tomcat01 容器(提供服务器),通过这个镜像可以创建多个容器(最终服务运行或者项目运行就是在容器中的)。
容器(container):docker利用容器技术,独立运行一个或者一组应用 通过镜像来创建,启动,停止,删除,基本命令! 目前就可以把这个容器理解为就是一个简易的linux系统。
仓库(repository):仓库就是存放 镜像(image)的地方!仓库又可以分为 公有仓库和私有仓库。
底层原理
- Docker有着比虚拟机更少的抽象层。
- docker利用的是宿主机的内核,vm需要是Guest OS
- Guest OS: 安装在虚拟机(Virtual Machine, VM)中的操作系统。它运行在虚拟化软件(Hypervisor 或虚拟机管理程序)提供的虚拟硬件之上。
- Host OS: 运行在物理机上的操作系统,负责管理硬件资源,并且提供给虚拟机使用。
docker 本质上是利用 Linux 的 CGroup(Linux 内核机制,提供 资源限制、统计和控制) 和 NameSpace(Linux 内核机制,提供资源 隔离,让进程看到的资源独立),实现轻量化隔离。
基本操作(hello-world)
image 是一个静态的文件集合,包含了运行应用程序所需的所有代码、库、配置文件和依赖项。它类似于一个“蓝图”或“模板”,定义了容器的内容和环境。
而 image 本质上是一个二进制文件,实际中开发可以继承另一个文件的 image 形成自己的 image。别人的 image 可以通过 Docker Hub 访问。
1 | 列出所有的 image 文件 |
从 DockerHub 抓取 image 的方法是
1 | docker image pull library/hello-world |
怎么运行呢?
container 是镜像的运行实例,可以理解为根据镜像“蓝图”构建的“实体”。容器是一个独立的运行环境,其中包含了镜像中定义的所有文件和配置。
1 | 运行一个 image,生成一个正在运行的容器,如果本地没有指定的容器,那么就会自动的从远端抓取 image |
如果我们想查看当前有哪些 container 正在运行,那么
1 | 以下 cli 可以列出正在运行的 container |
现在,我们想要关闭正在运行的容器
1 | 这个相当于强制关闭,相当于发送 SIGKILL |
但是已经终止的 container 文件依然会占据文件内存,那么我们可以使用这个指令来删除
1 | docker container rm [container ID] |
再次查看,已经将 cae8003170ad
的 container 删除。
- 如果我们想要查看 container 的 log 输出应该怎么办呢(没有 -it )?
其中 -i 指的是创建标准化输入输出, -t 是创建一个终端
那么, -it 指的是创建一个标准化的虚拟终端
1 | docker container logs [containerID] |
- 如果我们现在有多个正在运行的 container,现在我想要进入到某一个 container 中,那么
1 | docker container exec -it [containerID] /bin/bash |
docker container cp
命令用于从正在运行的 Docker 容器里面,将文件拷贝到本
机。下面是拷贝到当前目录的写法。
1 | docker container cp [containID]:[/path/to/file] . |
制作自己的 image
基础教程
这里是参考的Docker 入门教程 - 阮一峰的网络日志,以及自己的一些补充
首先准备相关源码
1 | git clone https://github.com/ruanyf/koa-demos.git |
编写 dockerfile
.gitignore
相似,docker 也有 .dockerignore
,写入自己想要排除的文件即可。这样就可以不用打包在 image 中。
项目中已经有相关的 dockerfile
1 | # 该 image 文件继承官方的 node image,冒号表示标签,这里标签是`8.4`,即8.4版本的 node。 |
补充一下 dockerfile 的关键词
- ADD将主机上的源文件复制到容器文件系统的目标位置。
- CMD可用于在容器内执行特定命令。
- ENTRYPOINT设置一个默认应用程序,每次使用该镜像创建容器时都会使用该程序。
- ENV设置环境变量。
- EXPOSE关联一个特定的端口,以实现容器与外部世界之间的网络连接。
- FROM定义用于启动构建过程的基础镜像。
- MAINTAINER定义镜像创建者的全名和电子邮件地址。
- RUN是 Dockerfile 的核心执行指令,也称为 run Dockerfile 命令。
- USER设置运行容器的 UID(或用户名)。
- VOLUME用于启用从容器到主机上目录的访问。
- WORKDIR设置使用 CMD 定义的命令要执行的路径。
- LABEL允许您向 Docker 镜像添加标签。
创建 image 文件
1 | # docker build -f /path/DataFile -t 镜像名 [:TAG] . |
上面代码中,-t
参数用来指定 image 文件的名字,后面还可以用冒号指定标签。如果不指定,默认的标签就是latest
。最后的那个点表示 Dockerfile 文件所在的路径,上例是当前路径,所以是一个点。
炸了,是我自己忘记配置相关镜像源了。。。
MyChat
这是我自己的项目,想着复习一些 dockerfile 怎么写的,也算是一个小总结,但是本质上也是套上面的模板。
1 | # 构建阶段, 其中 alpine 表示超级精简版 |
随后执行编译:
1 | # docker build -f /path/DataFile -t 镜像名 [:TAG] . |
执行结果:
1 | ❯ docker build -t mychat:lastest . |
然后执行,正常的话会返回一串 hash 值,随后就可以随意进行操作了:
1 | docker run -d -p 8080:8080 --name MyChat mychat:lastest |
我们可以进入到容器中:
1 | docker exec -it MyChat sh |
然后查看容器内的文件,我们发现就是我们 COPY
的文件:
1 | /MyChat # ls |