Jiankun
发布于 2025-02-13 / 6 阅读
0
0

Docker 核心概念与使用指南

引言

Docker 是一种轻量级的容器化技术,广泛应用于应用程序的打包、分发和部署。本文将介绍 Docker 的基本概念、常用命令以及如何将本地环境封装到 Docker 中,帮助读者快速上手 Docker。


一、Docker 基本概念

Docker 的核心概念包括 镜像容器仓库

1. 镜像 (Image)

操作系统分为 内核空间用户空间。对于 Linux 系统,在内核启动后,会加载 root 文件系统为其提供用户空间支持。Docker 镜像类似于一个 root 文件系统,它是一个特殊的文件系统,包含了容器运行时所需的程序、库、资源、配置等文件,同时还包含了一些运行时的配置参数(如匿名卷、环境变量、用户等)。镜像本身是不可变的,其内容在构建完成后不会改变。

2. 容器 (Container)

镜像(Image)和容器(Container)的关系类似于面向对象程序设计中的 对象。镜像是静态的定义,而容器是镜像的动态运行实例。通过镜像,可以创建多个独立的容器实例,每个容器都相互隔离。

3. 仓库 (Repository)

镜像构建完成后,可以在当前宿主机上通过启动容器运行,但如果需要在其他服务器上使用,就需要一个集中的存储和分发服务。Docker Registry 就是这样一个服务。一个 Docker Registry 中可以包含多个 仓库,每个仓库可以包含多个 标签,每个标签对应一个镜像版本。通过 <仓库名>:<标签> 的方式可以指定镜像的具体版本。

常用的 Docker Registry 服务包括:

  • Docker Hub
  • GitHub Container Registry (ghcr.io)
  • Google Container Registry

在国内,由于网络原因,访问 Docker Hub 可能较慢,因此可以使用国内提供的 镜像加速器(Registry Mirror)来提高下载速度。


二、Docker 镜像的使用

1. 获取镜像

从 Docker 镜像仓库获取镜像的命令如下:

docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]

2. 使用 Dockerfile 定制镜像

镜像的定制实际上是通过定制每一层的配置和文件来实现的。可以将每一层的修改、安装、构建、操作写入一个脚本文件 Dockerfile 来定制镜像。具体步骤如下:

  1. 指定基础镜像
    使用 FROM 指令指定基础镜像。例如:

    FROM ubuntu:20.04
    

    特殊的基础镜像 scratch 表示空白镜像,用于从零开始构建镜像。

  2. 运行命令
    使用 RUN 指令指定命令行工具。每个 RUN 指令都会新建一层。为了避免不必要的层,可以将多个命令用 && 连接在同一层中。例如:

    RUN apt-get update && apt-get install -y nginx
    
  3. 构建镜像
    Dockerfile 文件所在目录执行以下命令:

   docker build -t <镜像名>:<标签> 
  • -t, --tag: 为构建的镜像指定名称和标签

三、常用 Docker 命令

命令描述
docker images列出本地镜像
docker ps列出正在运行的容器
docker stop <容器ID或容器名称>停止容器
docker rm <容器ID或容器名称>删除容器
docker rmi <镜像ID或镜像名称>删除镜像
docker logs <容器ID或容器名称>查看容器日志
docker run创建并启动一个新的容器(如果镜像不存在,会先拉取镜像)
docker exec在已运行的容器中执行命令

1. docker run 参数详解

示例:

sudo docker run -d -p 3000:8080 --add-host=host.docker.internal:host-gateway --gpus=all -v ollama:/root/.ollama -v open-webui:/app/backend/data --name open-webui --restart always ghcr.nju.edu.cn/open-webui/open-webui:main
  • -d:表示以“后台模式”(detached mode)运行容器。容器会在后台运行,不会占用终端。
  • -p 3000:8080:将容器的 8080 端口映射到主机的 3000 端口。这样,访问主机的 localhost:3000 就可以访问容器内的服务。
  • --add-host=host.docker.internal:host-gateway:向容器的 /etc/hosts 文件中添加一条主机映射,将 host.docker.internal 解析为 Docker 主机的网关地址。在 Docker 中,host.docker.internal 是一个特殊的 DNS 名称,用于从容器内部访问宿主机的服务。
  • --gpus=all:允许容器使用主机的 所有 GPU 资源
  • -v ollama:/root/.ollama:将主机的 ollama挂载到容器内的 /root/.ollama 目录。用于持久化存储数据。
  • -v open-webui:/app/backend/data:将主机的 open-webui挂载到容器内的 /app/backend/data 目录。同样用于持久化存储数据。
  • --name open-webui:为容器指定一个名称 open-webui,方便后续管理和操作。
  • --restart always:设置容器的重启策略为 always。如果容器意外停止,Docker 会自动重新启动它。重启时机:在重启 Docker 时,自动启动容器。
  • ghcr.nju.edu.cn/open-webui/open-webui:main:指定要运行的 Docker 镜像及其版本。

2. docker rundocker start 的区别

  • docker run:用于创建并启动一个新的容器。如果镜像不存在,会先拉取镜像。
  • docker start:用于启动已存在的容器。它不会创建新的容器,而是重新启动一个已经存在但停止的容器。

3. 查看容器日志

可以实时刷新日志:

sudo docker logs container_name -f

显示日志时间戳:

sudo docker logs container_name --timestamps

4. 停止容器

  • 停止所有容器

    sudo docker ps -q | sudo xargs docker stop
    

四、使用加速器

在国内,Docker 下载镜像可能会比较慢。通过使用加速器可以显著提高下载速度。例如,阿里云提供的加速器可以通过以下步骤配置:

  1. 创建 /etc/docker/daemon.json 文件:
  sudo mkdir -p /etc/docker
  sudo tee /etc/docker/daemon.json <<-'EOF'
  {
      "registry-mirrors": ["https://<你的阿里云加速器地址>.mirror.aliyuncs.com"]
  }
  EOF
  1. 重新加载 Docker 配置并重启服务:
   sudo systemctl daemon-reload
   sudo systemctl restart docker

五、将本地python环境封装到 Docker

1. 在 Docker 中安装 Anaconda 镜像

  1. 搜索 Anaconda 镜像:
docker search anaconda
  1. 拉取镜像:
docker pull continuumio/anaconda3
  1. 运行镜像:
docker run -i -t continuumio/anaconda3 /bin/bash

2. 封装本地 Anaconda 环境

在 Docker 环境下

查找 Anaconda 环境:

# anaconda: /opt/conda/bin/anaconda
whereis anaconda

然后这里拷贝的不应该是直接结果的 anaconda 路径,应该往上找两级下面的 conda/envs。

在本地环境下

复制本地环境到 Docker 容器内:

# docker cp /home/zxxx/anaconda3/envs/torch c6ebff84b63f:/opt/conda/envs
docker cp your_path/anaconda3/envs/env_name docker_name:anaconda_path/envs

docker cp 中的 docker_name 应该是 CONTAINER ID,不是 Image ID

将 Docker 容器保存为镜像:

# docker commit -a sunjk -m "save torch env" c6ebff84b63f anaconda
docker commit -a [author] -m [instruction] docker_name image_name

查看镜像:

docker image ls

将镜像压为压缩包:

docker save image_name -o compressed_package_name

3. Docker 镜像导入

  1. 将压缩包拷贝到另一台主机。
  2. 导入 Docker 环境:
docker load -i conda_zip
  1. 启动 Docker:
docker run -i -t image_name /bin/bash
  • -it : 交互式运行容器,分配一个伪终端。

七、非 root 用户运行 Docker

  1. 创建 docker 组(如果不存在):
sudo groupadd docker
  1. 将当前用户添加到 docker 组:
sudo usermod -aG docker $USER
  1. 重新登录以应用组更改(或重启系统):
newgrp docker
  1. 检查 Docker 是否可以非 root 运行:
docker run hello-world

参考资料


评论