Docker入门

Docker 是目前最主流的容器化技术之一,在 AI模型部署、微服务、DevOps 等场景中广泛使用。

本文将系统介绍:

  • Docker 核心概念

  • Docker 安装

  • 镜像与容器管理

  • Volume 数据持久化

  • Docker 网络

  • Docker Compose

  • 使用 Docker 部署 TEI 模型推理服务


Docker核心概念

Docker 的核心概念主要有三个:

  • 镜像(Image)

  • 容器(Container)

  • 镜像仓库(Registry)

简单理解:

概念 类比
镜像 安装包 / 模具
容器 运行后的程序
镜像仓库 软件商店

Docker 官方镜像仓库:

复制代码
https://hub.docker.com/

带有 Docker Official Image 标识的是官方维护镜像。


Docker技术原理

Docker 利用 Linux 内核的两个核心机制:

  • Cgroups

  • Namespaces

实现资源限制和进程隔离。


Cgroups(资源限制)

用于限制容器使用的系统资源,例如:

  • CPU

  • 内存

  • IO

  • 网络带宽

作用:

  • 防止某个容器占满服务器资源

  • 容器之间互不影响


Namespaces(资源隔离)

用于隔离系统资源视图,例如:

  • PID namespace(进程)

  • NET namespace(网络)

  • MNT namespace(文件系统)

  • UTS namespace(主机名)

  • IPC namespace

  • USER namespace

因此容器内部看到的:

  • 进程

  • 网络

  • 文件系统

都是 独立视图


容器本质

容器本质是:

运行在宿主机 Linux 内核上的一组受限进程。

因此:

Docker 不是虚拟机

容器 虚拟机
共享宿主机内核 独立内核
启动秒级 启动分钟级
资源占用小 资源占用大

Docker安装

官方安装入口

复制代码
https://get.docker.com/

⚠ `get.docker.com `是快速安装脚本

生产环境建议使用官方仓库安装。


Linux安装

复制代码
curl -fsSL https://get.docker.com -o install-docker.sh
sh install-docker.sh

验证:

复制代码
docker --version

Windows安装

步骤:

  1. 打开 启用或关闭 Windows 功能

  2. 勾选 Virtual machine platform/虚拟机平台 和 适用于Linux的Windos子系统 (WSL)

  3. 重启电脑

  4. 设置 WSL2(以管理员身份打开命令提示符)

    wsl --set-default-version 2
    wsl --update

    若处于国内网络可以加上 --web-download

下载 Docker Desktop

复制代码
https://www.docker.com/

若想指定安装目录,在安装文件目录中使用命令行方式,```--installation-dir=path```可指定安装位置

复制代码
start /w "" "Docker Desktop Installer.exe" install --installation-dir=D:\Docker

安装后测试:

复制代码
docker --version

Mac安装

只需在官网下载对应的安装包,安装即可运行


Docker镜像

下载镜像

完整格式:

复制代码
docker pull docker.io/library/nginx:latest

含义:

复制代码
docker.io registry
library namespace
nginx image
latest tag

简写:

复制代码
docker pull nginx

指定架构

复制代码
docker pull --platform=xxx nginx

常见架构:

架构 说明
amd64 x86服务器
arm64 ARM设备

镜像加速

修改配置文件:

复制代码
/etc/docker/daemon.json

{
 "registry-mirrors": [
   "https://docker.m.daocloud.io",
   "https://docker.m.1panel.live",
   "https://hub.rat.dev"
 ]
}

重启Docker环境:

复制代码
systemctl restart docker

Desktop配置镜像

Docker Desktop ------> 设置 ------> Docker Engine ------> 添加 配置文件内容的 registry-mirrors 部分的内容 ------> 点击 Apply&restart


Docker容器管理

查看镜像

复制代码
docker images

删除镜像

复制代码
docker rmi image_id

清理未使用镜像

复制代码
docker image prune

Docker运行容器

示例:部署 Huggingface TEI推理服务

复制代码
docker run -d \
  --name tei-cross-MiniLM-gpu2 \
  --gpus '"device=2"' \
  -p 18981:80 \
  -v /home/ghc/ebo_memory_test/models/models--cross-encoder--ms-marco-MiniLM-L-6-v2:/model/cross-encoder--ms-marco-MiniLM-L-6-v2 \
  --pull always \
  ghcr.io/huggingface/text-embeddings-inference:cuda-latest \
  --model-id /model/cross-encoder--ms-marco-MiniLM-L-6-v2 \
  --pooling mean \
  --dtype float16 \
  --max-concurrent-requests 2048 \
  --max-batch-tokens 65536 \
  --max-batch-requests 4096 \
  --max-client-batch-size 64 \
  --payload-limit 8000000 \
  --tokenization-workers 32

参数解释:

参数 作用
-d 后台运行
--name 容器名称
--gpus 指定GPU
-p 端口映射
-v 数据挂载
--pull always 每次拉取镜像

测试模型接口

复制代码
curl 127.0.0.1:18981/rerank \
 -X POST \
 -d '{
   "query": "什么是深度学习?",
   "texts": [
     "深度学习是机器学习的一个分支,它利用多层神经网络进行数据分析。",
     "深度学习已广泛应用于图像识别、自然语言处理等领域。",
     "深度学习使得计算机能够像人类一样进行决策和学习。",
     "深度学习的核心思想是通过大量的数据训练神经网络,自动提取特征。",
     "随着数据量的增大,深度学习的表现越来越好。"
   ]
 }' \
 -H 'Content-Type: application/json'

返回:

复制代码
{
 "results":[...]
}

表示 rerank 推理成功。


后台执行

复制代码
docker run -d image_name/image_id

-d在后台执行,不会阻塞当前窗口

-it让容器进入控制台进行交互

⚠ 服务型容器通常使用`-d`

端口映射

-p 宿主机port:容器port宿主机端口映射到Docker端口。容器内的网络与宿主机的网络默认是隔离的,需要在启动参数中指定映射

参数传递

-e arg_name=arg

一般在仓库的镜像网址中会列出可以传递的环境变量

容器命名

--name container_name容器名称必须唯一,与容器的ID等价

查看容器

查看正在运行的容器:

复制代码
docker ps

-a查看所有容器,包括已经停止运行的

停止/启动容器

复制代码
docker stop/start container_id/container_name

删除容器

复制代码
docker rm container_id/container_name

-f强制删除,可直接删除正在运行的容器

临时调试容器

-it让容器进入控制台进行交互

--rm让容器停止时自动删除

这对指令一般连用

复制代码
docker run -it --rm alpine
ls
exit
# alpine轻量级Linux镜像,这里退出后容器自动删除

重启策略

--restart always任何停止(容器内部崩溃/宿主机断电等)都会立即重启

--restart unless-stopped重启因意外原因停止的容器(手动停止后不重启)


Volume(数据持久化)

Docker数据持久化有两种方式:

绑定挂载

复制代码
-v host_path:container_path

特点:

  • 容器删除数据不丢

  • 与宿主机同步


命名卷

创建存储空间:

复制代码
docker volume create volume_name

使用命名卷:

复制代码
docker run -v volume_name:/data

查看真实路径:

复制代码
docker volume inspect volume_name

列出所有创建过的命名卷:

复制代码
docker volume list

删除命名卷:

复制代码
docker volume rm volume_name

删除所有没有任何容器在使用的卷:

复制代码
docker volume prune -a

Docker调试命令

查看容器参数

复制代码
docker inspect container_name

查看日志:

复制代码
docker logs container_name

-f滚动查看

在容器内部执行Linux命令:

复制代码
docker exec container_id/container_name linux_command

进入容器:

复制代码
docker exec -it container_name /bin/bash

Dockerfile

Dockerfile 定义镜像构建过程。

构建镜像

以Python程序为例,使用FastAPI创建一个get接口,运行在8000接口,requirements文件列出了程序的Python的依赖。

运行这个程序需要三步骤:1. 安装Python环境。 2. 安装依赖`pip install -r requirements.txt` 3.启动项目`python main.py`。最后浏览器访问`localhost:8000`

创建Dockerfile文件,所有Dockerfile第一行都是FROM,即该镜像从哪个镜像基础上构建而来。

搜索选择Python官方镜像Explore Docker's Container Image Repository | Docker Hub,选择3.13-slim

复制代码
# file:Dockerfile
FROM python:3.13-clim

# 类似cd,切换到镜像内的目录作为工作目录
WORKDIR /app

# 先确保环境依赖没有问题
COPY requirements.txt .
# 安装依赖
RUN pip install --no-cache-dir -r requirements.txt

# 将原本的代码文件拷贝到镜像内的工作目录
COPY . .

# 声明镜像提供的服务端口,并不强制,仅作提示
EXPOSE 8000

# 容器运行时的默认启动命令,一个Dockerfile文件里面只能写一个CMD。ENTRYPOINT优先级更高,不容易被覆盖
CMD ["python", "main.py"]

构建好Dockerfile文件后, 在当前目录执行构建镜像:

复制代码
docker build -t image_name[:version_name] .

同样能在本地基于这个镜像创建容器并运行

复制代码
docker run -d -p 8000:8000 image_name

推送镜像

用户名即镜像命名空间

本地工作目录中登录Docker:```docker login```打开网址填写验证码,回到本地命令行显示"Login Succeeded"

此时构建镜像必须带上用户名:

复制代码
docker build -t username/image_name[:version_name] .
docker push username/image_name[:version_name]

推送成功后即可在DockerHub上搜索


容器编排

一个应用往往由前端、后端、数据库等多部分组成。多应用的最佳实践时将每个模块打包成一个独立的容器。但单独配置、执行、管理会很复杂甚至出错,Docker Compose使用yml文件管理多个容器,里面列出容器之间是如何创建、以及如何协同工作的。

针对上述案例对应的Compose的yml文件配置,```depends_on```能指定启动顺序

复制代码
# docker-compose.yml
services:
  my_mongodb:
    image: mongo
    environment:
      MONGO_INITDB_ROOT_USERNAME: name
      MONGO_INITDB_ROOT_PASSWORD: pass
    volumes:
      - /my/datadir:/data/db
      
      
  my_mongodb_express:
    image:mongo-express
    ports:
      - "8081:8081"
    environment:
      ME_CONFIG_MONGODB_SERVER: my_mongodb
      ME_CONFIG_MONGODB_USERNAME: name
      ME_CONFIG_MONGODB_PASSWORD: pass
    depends_on:
      - my_mongodb

创建并启动Compose:

复制代码
docker compose up

-d后台运行

-f file_name指定文件名。若不指定文件名,必须是标准文件名```docker-compose.yml```

停止并删除容器:

复制代码
docker compose down

仅停止容器:

复制代码
docker compose stop

运行容器:

复制代码
docker compose start

若compose已经在运行了,重复执行```compose up```并不会启动新的容器,没有任何效果。


Docker网络

查看网络

复制代码
docker network list

默认模式:

复制代码
bridge
host
none

删除自定义子网:

复制代码
docker network rm network_name

Bridge模式

Docker网络默认是桥接模式,所有容器默认连接到这个网络,每个容器都分配了一个内部IP地址。

  • 默认子网 172.17开头

  • 容器间可通过容器名通信

  • 容器网络与宿主机的网络互相隔离

创建网络:

复制代码
docker network create mynetwork

默认情况下,创建的子网也是桥接模式。

加入网络:运行时使用参数```--network network_name```

指定容器加入不同的子网,同一个子网的不同容器之间可以互相通信,而跨子网则不可以通信。

同一个子网的容器可以使用容器名称互相访问,而不必使用内部IP地址。

Docker子网内部有一个DNS机制,可以把名字转换成IP地址。

同网络容器可直接通过 容器名通信

示例:创建子网network1;创建容器my_mongodb没有指定宿主机的端口映射;创建容器mongodb客户端my_mongodb_express指定子网,并与宿主机做映射;通过my_mongodb_express作为桥梁,实现了宿主机通过8081端口即可访问到mongodb的my_mongodb内的数据。

复制代码
docker network create network1

docker run -d \
--name my_mongodb \
-e MONGO_INITDB_ROOT_USERNAME=name \
-e MONGO_INITDB_ROOT_PASSWORD=pass \
-v /my/datadir:/data/db \
--network network1 \
mongo

docker run -d \
--name my_mongodb_express \
-p 8081:8081 \
-e ME_CONFIG_MONGODB_SERVER=my_mongodb \
-e ME_CONFIG_MONGODB_USERNAME=name \
-e ME_CONFIG_MONGODB_PASSWORD=pass \
--network network1 \
mongo-express

Host模式

Docker容器直接共享宿主机的网络,容器直接使用宿主机的IP地址,无需-p参数进行端口映射,容器内的服务直接运行在宿主机的端口上,通过宿主机的IP和端口能直接访问到容器。

复制代码
docker run -d --network host image_name

没有指定端口映射也能在宿主机直接访问`ip:port`

复制代码
# 进入容器查看IP地址
docker exec -it container_id/container_name /bin/sh
​
# 安装网络工具
apt update
apt install iproute2
ip addr show

None模式

复制代码
docker run --network none nginx

不联网模式


相关推荐
Riemann~~1 小时前
docker包括那些内容
运维·docker·容器
芒果披萨1 小时前
Linux目录详解
linux·运维·服务器
东方鲤鱼2 小时前
MAC部署openClaw 实现自动化助手实战
运维·macos·自动化
阿成学长_Cain2 小时前
Linux 打印队列管理:accept 命令超详细使用教程
linux·运维·服务器
王琦03182 小时前
部署RHEL9.7并优化
linux·运维·服务器
yatum_20142 小时前
MobaXterm SSH 登录 master 节点操作总结
运维·ssh
头发那是一根不剩了2 小时前
Ubuntu 离线环境升级 OpenSSH 修复漏洞
linux·运维·ubuntu
别退2 小时前
WSL2安装Freesurfer
linux·运维·服务器