PostsMapsLinks
Container

Docker

Docker 是一种容器管理工具,通过对系统资源的控制与隔离,把软件、软件运行时、系统工具、系统库和配置打包到一个镜像中,运行在有有独立命名空间的容器进程内,可以使软件的所有依赖都标准化。

简介

Docker 是什么?

Docker 本身不是容器,而是容器标准的一种实现及其管理工具。

容器是什么?

容器是一种软件打包的技术。通过对系统资源的控制与隔离,把软件、软件运行时、系统工具、系统库和配置打包到一个镜像中,运行在有有独立命名空间的容器进程内,可以使软件的所有依赖都标准化。所以使用容器技术能方便地将软件打包成标准单元。

原理

Docker 和虚拟机都希望能提供一个虚拟、完整、独立的运行时环境,通过提高虚拟环境的隔离型,以便管理。一般来说,虚拟机的原理是模拟硬件环境,所以需要安装客户端操作系统1,而 Docker 并不需要这层客户端操作系统, 所以 Docker 更加轻量,硬件利用率也更高。

虚拟机使用 Hypervisor 实现操作系统级别的模拟,而 Docker 通过操作系统的文件系统、命名空间、控制组实现进程级别的模拟。

命名空间:所有 Linux 的进程都从 init 进程 fork 派生。Linux 容器的一个主要组件是新的命名空间下的一个 init 进程,所以我们有能力去创建一个不影响外界的进程树出来。

控制组:通过控制组,我们能限制进程对 CPU、磁盘、内存的使用。

概念

  1. 隔离环境:虚拟文件系统;POSIX API;文件的只读和屏蔽;命名空间、环境变量等;
  2. 生命周期:created、running、pausing、paused、stopped;可以通过 update 动态调整硬件资源使用率
  3. 数据卷:数据卷由自己的独立的生命周期
  4. 网络:独立的网络命名空间、共享其他实例的网络命名空间、共享主机的网络命名空间

端口映射的绑定语义与暴露面

compose 里 ports: ["15432:5432"] 只写端口不写绑定地址时,Docker 默认同时绑 IPv4 通配 0.0.0.0 与 IPv6 通配 [::],docker ps 显示 0.0.0.0:15432->5432/tcp, :::15432->5432/tcp 两组。 绑定地址决定暴露面:0.0.0.0 公网可达;127.0.0.1:15432:5432 只递到宿主机回环, 配 ssh -L 隧道即可安全远程访问;不写 ports 则仅容器网络可达。

工程上应把「不映射端口」作为生产数据库的默认姿势:应用走容器内网,运维经 SSH 隧道或堡垒机接入。 公网可达的 PG 会进入扫描视野,是自动化爆破与删库勒索的经典目标; 测试环境图方便映射公网端口时,至少叠加来源 IP 白名单。

见:Docker port publishing

架构

Docker 引擎实际上由 Dockerd、Containerd、RunC 等组件构成

Dockerd:容器管理 -> 编排管理和集群管理。它接受来自外部的 HTTP 请求并作为 API 调用执行,对内与 Containerd 进行通讯。

Containerd:对镜像、容器的管理提供了一个更进一步的抽象,提供了内容、快照、差异、容器、镜像、任务等更加细粒度的概念。

Container 包含 Containerd-shim,用于正确处理由操作系统发送过来的信号。

RunC:Containerd 提供的容器管理等 API 的执行者是 RunC。

常见指令

  • ps:列表,如 docker ps
  • build:打包镜像,如 docker build -t test . -f Dockerfile
  • run:运行镜像,如 docker run -it test
  • exec:执行容器指令,如 docker exec -it xxx bash
  • copy:复制文件到 Docker 中,如 docker cp d://test dockerID:dockerPath

构建与发布

多平台构建

# 1. 开启模拟(一次即可)
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes

# 2. 创建构建器(一次即可)
docker buildx create --use --name multiarch --platform "linux/arm64,linux/amd64"

# 3. 构建并推送
docker buildx build --platform linux/arm64,linux/amd64 -t your/app --push .

镜像源

调试流程

  1. 拉远端镜像:docker pull registry.gitlab.p-ray.cn/moe:75150
  2. 启动容器:docker run -p 8081:7001 -it <imageID> sleep 999m
  3. 进入并调试:docker exec -it <instanceName> /bin/bash

-p 8081:7001,把本机的 8081 端口绑定到 Container 的 7001 端口。

常见问题

关闭 Hyper-V:bcdedit /set hypervisorlaunchtype off

镜像元数据解析失败

碰到一个 docker build 失败,但是如果先 docker pull image 再 docker build,流程就能成功的问题,是 HTTPS_PROXY 设置的问题。

Footnotes

  1. 虚拟机一般有三种模拟方式,裸机型(硬件 + 虚拟 OS + 虚拟 APP)、托管型(OS + Hypervisor + 虚拟 OS + 虚拟 APP)和操作系统虚拟化(OS + 容器 + 虚拟 APP)。 ↩
Copyright © 2024 Lionad - CC-BY-NC-CD-4.0