Docker笔记
- Published on
是什么
Docker 是一个开源的应用容器引擎,基于 Golang 语言开发,可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 服务器。容器是一个沙箱机制、相互隔离、相互之间不会有影响(类似于我们手机上运行的 App),并且容器开销是较低的。
作用
- 容器化,将应用及其所有依赖项打包在容器中,以便在任何环境运行
- 一致的运行环境,环境隔离。遇到的问题:本地/测试/线上 运行环境不一致,导致开发发布流程长,成本高。
- 资源效率,多容器基于操作系统,启动快速且占用资源少,相比虚拟机更轻量
- 结合 CI/CD 持续集成部署
- 微服务架构
对比带独立运行环境的虚拟机
- 打包:就是把你软件运行所需的依赖、第三方库、软件打包到一起,变成一个安装包
- 分发:你可以把你打包好的“安装包”上传到一个镜像仓库,其他人可以非常方便的获取和安装
- 部署:拿着“安装包”就可以一个命令运行起来你的应用,自动模拟出一样的运行环境,不管是在 Windows/Mac/Linux 自己在本地机器上开发、测试 --> 打包为 Docker 镜像(可以理解为软件安装包) --> 各种服务器上只需要一个命令部署好 核心概念
- Image 镜像: 一个包含有文件系统的面向 Docker 引擎的只读模板,装了一些系统的配置文件, 可以通过镜像建立容器。容器启动的“原料”。
- Container 容器:基于镜像创建的,相互隔离的执行单元。类比于“小型虚拟机”
- Registry 仓库:存放镜像的仓库
主要命令
- docker version
- sudo systemctl start docker 启动服务
镜像
- docker images // docker image ls 列出本机 image
- docker image rm helloworld 删除本地镜像 helloworld
- docker image build -t imageName path 构建 image 镜像
- docker pull 拉取镜像, 默认地址地址 Docker Hub. https://hub.docker.com/explore
容器
- docker container run helloworld 容器运行 hello world
- docker container run -p 3000:80 node-red 容器启动 80 端口转到本机的 3000 端口
- docker container run --rm -p 3000:80 node-red
- --rm 在容器终止运行后自动删除容器文件
- --name containerName 指定容器名字
- -d 在后台运行,不占用终端
- docker container start containerID run 会每次新建一个容器,start 会启动一个已经存在的容器
- docker container ls //
- docker ps 列出正在运行的容器
- docker ps -a 列出所有容器,包括不在运行的
- docker container kill [containID] 终止容器
- docker container rm [containerID] 删除容器
- docker container logs [containerID] docker 容器 log, 即容器里面 Shell 的标准输出
- docker container cp [containID]:[/path/to/file] .
- docker container cp e168f39fd043:/app/package.json .
命令中 image 和 container 可以省略掉。
DockerFile 创建镜像
根据 DockerFile 文件, docker image build 创建 docker image build -t node-red:tag .
- -t 指定镜像名称和标签
- -f 指定 Dockerfile
DockerFile
FROM node:18.17.0-alpine as builder
- 该 image 文件继承官方的 node image,冒号表示标签,这里标签是 18.7.0,即 18.7.0 版本的 node。(Alpine 操作系统是一个面向安全的轻型 Linux 发行版, 对比不带 -alpine 版本,Alpine 版本镜像更小,更轻量)
- as builder 多阶段构建,可以将前面阶段的构建产物复制到当前目录
- docker ignore FROM node:14 AS builder ... FROM node:14 AS production ... COPY --from=builder /app/dist ./dist
- 多阶段构建优化
WORKDIR /app 设置工作目录为 /app。后续的命令都将在这个目录中执行。如果目录不存在,Docker 会自动创建它。
COPY . /app/ 将当前目录下的所有文件复制到 /app 目录下。
RUN apk update && apk add git 更新包,安装 git (如有 git 依赖)
RUN npm install /app 目录下执行 npm install 安装依赖 RUN 命令写法:
- RUN /bin/bash -c 'source HOME
- RUN ["/bin/bash", "-c", "echo hello"]
RUN npm run build
EXPOSE 80 443 3000 容器暴露端口
CMD ["npm", "start"] CMD 容器启动要运行的命令。RUN 是 image 文件的构建阶段执行,执行结果都会打包进入 image 文件。CMD 命令则是在容器启动后执行。一个 Dockerfile 可以包含多个 RUN 命令,但是只能有一个 CMD 命令。 其他部分指令:
ENV 设置环境变量
ENV <key> <value>
容器中运行的程序都可以使用
ARGS ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量,在将来容器运行时是不会存在这些环境变量的。
USER 指定后续调用用户(组)
根据 Dockerfile 存在后, docker image build -t imageName path 构建 image. 如:docker image build -t node-red .
-t 指定名称, . 指定当前目录 (目录需要包含 DockerFile)
发布 image
发布流程类比于 npm 发包,登录后将镜像上传至镜像仓库
docker login docker image tag [imageName] [username]/[repository]:[tag] docker image push [username]/[repository]:[tag]
数据管理
对容器中的数据持久化管理以及多容器共享数据
数据卷
数据卷是被设计用来持久化数据的,它的生命周期独立于容器,Docker 不会在容器被删除后自动删除 数据卷,并且也不存在垃圾回收这样的机制来处理没有任何容器引用的 数据卷。如果需要在删除容器的同时移除数据卷。 volmue 创建在宿主机,Linux 文件系统,可以多个容器共享 创建数据卷
- docker volume create my-vol 创建数据卷
- docker volume ls 列出数据卷
- docker volume inspect my-vol 查看指定数据卷
- docker volume prune 清理无 container 引用的数据卷
- docker rm -v 删除
docker run -v volumeName:/path imageName
对比: docker run -p 9000:9000 hello_val docker run -p 9000:9000 -v my-vol:/app hello_vol curl -X POST -d "New data entry" http://localhost:9000
挂载主机目录
通过路径挂载目录,主机目录修改代码和数据在容器中实时生效 docker run -p 9000:9000 -v /path/to/host/directory:/app hello-node-app
- docker run -p 9000:9000 -v /Users/xuwei/Desktop/VProjects/Cocobolo/Docker:/app hello_vol tmpfs 临时数据,写入到主机内存中 [图片]
数据存储 https://docs.docker.com/engine/storage/
多容器
docker network
运行多个容器,比如前端,数据可能是独立的容器在运行,需要进行通信获取数据,使用同一个网络可以达成 创建网络: docker network create test-net docker run -p 8080:8080 --name test -v D:/test:/app --network test-net hello docker run --name js_server --network test-net server_image
docker-compose
https://docs.docker.com/compose/ (安装 docker-desktop 不需要额外安装) 如果同时运行更多的容器,都需要管理配置和指定网络,操作需要简化。 docker-compose 把项目的多个服务集合到一起,自动创建同一个网络,不需要手动指定。相当于编写脚本,将多个容器参数都写入文件中,串联一起执行 编写 docker-compose.yml: version: '3.8'
services: backend: image: node:18-alpine build: context: ./ dockerfile: Dockerfile ports: - "9000:9000" volumes: - ./backend:/app environment: NODE_ENV: production
frontend: image: nginx:alpine ports: - "80:80" volumes: - ./frontend:/usr/share/nginx/html Docker-compose 命令:
- 运行:docker-compose up
- 查看运行状态:docker-compose ps
- 停止运行:docker-compose stop
- 重启:docker-compose restart
- 重启单个服务:docker-compose restart service-name
后续 k8s 容器编排...
学习资料: