Docker 入门 - 拉取/创建镜像 + 运行和管理容器

写在前面:

本篇简单介绍一下如何入手 Docker,从 创建/拉取 镜像,再到运行和管理容器,还包括导出容器等操作。这里先贴一下官方的文档地址:

Docker DocsDocker Documentation is the official Docker library of resources, manuals, and guides to help you containerize applications.https://docs.docker.com/

一、Docker 介绍

作为一个开源的应用容器引擎,Docker 可以让开发者将应用以及应用的依赖打包到一个可移植的容器中,然后发布到任何安装了 Docker 的服务器上运行。这些容器就像一个个轻量级的虚拟机,但与传统虚拟机相比,Docker 容器更加高效、快速和资源友好。

主要特点:

  1. 轻量级

    Docker 容器共享主机内核,不需要像虚拟机那样模拟完整的操作系统,因此启动速度极快,通常在几秒钟内就能启动。
    占用的资源少,多个容器可以在同一台服务器上高效运行,提高了服务器的利用率。

  2. 可移植性

    由于容器包含了应用及其所有依赖,所以可以在不同的环境中轻松迁移,无论是从开发环境到测试环境,还是从本地服务器到云服务器。
    保证了应用在不同环境中的一致性运行,减少了因环境差异导致的问题。

  3. 高效性

    容器的快速启动和停止特性使得应用的部署和扩展变得非常容易。
    可以根据需求快速创建和销毁容器,实现弹性的资源分配。

  4. 隔离性

    每个容器都有自己独立的文件系统、网络和进程空间,实现了应用之间的隔离。
    一个容器中的问题不会影响到其他容器,提高了系统的稳定性和安全性。

核心组成:

  1. 镜像(Image)

    是一个只读的模板,包含了应用程序及其所有依赖(如库、框架、配置文件等)。
    可以从 Docker 仓库中下载或自己创建镜像,然后基于镜像创建容器。

  2. 容器(Container)

    是由镜像创建的运行实例,是一个独立的运行环境。
    可以对容器进行启动、停止、删除等操作,也可以在容器中运行应用程序。

  3. 仓库(Repository)

    用于存储和分发 Docker 镜像,可以是公共仓库(如 Docker Hub),也可以是私有仓库。
    开发者可以将自己创建的镜像推送到仓库中,以便在不同的环境中使用。

使用场景

  1. 应用部署

    简化了应用的部署过程,提高了部署的效率和可靠性。
    可以快速将应用部署到多台服务器上,实现大规模的应用部署。

  2. 微服务架构

    适合用于构建微服务架构,每个微服务可以运行在一个独立的容器中。

  3. 开发环境一致性

    保证了开发、测试和生产环境的一致性,减少了因环境差异导致的问题。
    开发者可以在本地使用与生产环境相同的容器来进行开发和测试。

二、创建镜像

这里介绍几种常见的创建镜像的方式,大家可以根据自己需求选择。

2.1 从 Docker Hub 拉取镜像

第一步:登录/注册 Docker Hub

如果没有则先去官网(https://hub.docker.com/)注册一个,然后登录即可(Desktop版图形化操作即可,普通的则打开终端输入 " docker login ")。

第二步:查找所需的镜像

可以直接在官网去搜索即可,这里写几个常用的镜像:

  1. Alpine :基于轻量级 Linux 操作系统的镜像,体积非常小巧,只有 5MB 左右,提供了一些基本的工具和包,如 bashcurlgcc 等,适合构建轻量级的容器。
  2. Ubuntu:基于 Debian 的 Linux 操作系统,常用版本(LTS):22.04、20.04、18.04;
  3. Nginx:广泛使用的 Web 服务器软件,也可用作反向代理、负载均衡和 HTTP 缓存服务器。结合其他技术如 WordPress 等,可以用于构建高性能的 Web 应用程序。
  4. Redis:基于内存的数据存储系统,常用于实时数据缓存、排名、计数器、分布式会话管理等方面,具有快速、可靠且易于使用的特点,适合构建可扩展的分布式系统。
  5. MySQL:流行的关系数据库管理系统,支持多数据类型、多连接和高性能,是开发人员构建数据库应用程序的常用选择之一。
  6. Node.js:基于 JavaScript 的后端服务器技术,支持高性能、非阻塞 I/O 和事件驱动编程,许多开发者使用它来构建 Node.js 的 Web 应用程序和 Web 服务。
  7. Tomcat:一个流行的 Java Web 应用服务器,用于运行 Java Web 应用程序3。
  8. CentOS:一种常用的 Linux 发行版镜像,提供了稳定的操作系统环境,适合用于各种服务器应用的部署。

第三步:拉取所需镜像

在命令行中输入docker pull [镜像名称]:[标签]

如果不指定标签,默认会拉取 latest(最新)标签的镜像。

例如,要拉取官方的 Ubuntu 镜像,可输入

bash 复制代码
docker pull ubuntu # 最新版
docker pull ubuntu:22.04 # 特定版

后续:可创建自己的镜像仓库

登录上 Docker Hub,在存储库页面上,选择创建存储库。

将其进行命名,比如<you-username>/my-Privateal-repo,将可见性设置为私有。

配置完自己镜像后,可以上传到仓库。上传镜像之前,先对镜像进行标记:

bash 复制代码
docker tag my_image:latest <you-username>/my-Privateal-repo

使用 docker push 命令将标记后的镜像上传到私有仓:

bash 复制代码
docker push <you-username>/my-private-repo

当然,可以在另外机器上或使用 pull 拉取验证镜像。

2.2 用 Dockerfile 创建镜像

Dockerfile 是一个文本文件,包含了一系列指令,用于描述如何构建一个 Docker 镜像。这些指令会按照顺序依次执行,最终生成一个包含特定应用及其依赖的镜像,使用 Dockerfile 创建镜像是一种常见且高效的方式,

常见指令:

  1. FROM:指定基础镜像,它是构建新镜像的起点。例如:FROM ubuntu:22.04
  2. RUN:在镜像构建过程中执行命令。可以用于安装软件包、配置环境等。例如:RUN apt-get update && apt-get install -y python3
  3. COPYADD:将本地文件或目录复制到镜像中。例如:COPY. /app将当前目录下的所有文件复制到镜像中的/app目录。
  4. WORKDIR:设置工作目录。例如:WORKDIR /app将后续命令的工作目录设置为/app
  5. CMDENTRYPOINT:指定容器启动时要执行的命令。例如:CMD ["python", "app.py"]表示启动容器时运行python app.py命令。

示例:

先编写一个 app.py 文件:

python 复制代码
from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello, Docker!'

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

再创建一个 Dockerfile 文件:

bash 复制代码
FROM python:3.10

WORKDIR /app

COPY..

RUN pip install flask

EXPOSE 5000

CMD ["python", "app.py"]

上面的 Dockerfile 中,设置了工作目录,拷贝当前目录文件到镜像内,并安装了 Flask 库,暴露容器的 5000 端口,最后在容器启动后运行命令启动程序。

接下来只需要在包含 Dockerfile 和 app.py 文件的目录下,运行构建镜像即可:

bash 复制代码
docker build -t myflaskapp:latest .

其中 -t 参数指定镜像的名称和标签,最后的 . 表示 Dockerfile 所在的目录。

构建镜像后,启动容器即可:

bash 复制代码
docker run -p 5000:5000 myflaskapp:latest

这里将容器的 5000 端口映射到主机的 5000 端口,这样就可以在浏览器中访问http://localhost:5000 来查看 Flask 应用的输出。


Dockerfile 的优势:

  1. Dockerfile 本身就是一种文档,它清晰地展示了镜像的构建过程和包含的内容。其他开发人员可以更容易理解和使用这个镜像;
  2. 可以根据具体需求自定义镜像的内容和配置。可以选择不同的基础镜像、安装特定的软件包、设置环境变量等,满足各种复杂的应用场景;
  3. 可以确保每次构建的镜像都是一致的,无论在哪个环境中构建。

存在的不足:

  1. 当构建复杂的镜像时,Dockerfile 可能会变得冗长和复杂,需要合理组织指令和管理依赖关系;
  2. 如果配置中使用了不可信的源或安装了未知的软件包,可能会引入安全风险。需要谨慎选择基础镜像和软件源;
  3. 当基础镜像较大或者需要下载大量的软件包时,构建过程可能会比较耗时,并且依赖于良好的网络连接。

之前我们遇到过,当配置的软件源更新或者网络原因等,导致无法构建甚至版本控制不理想等问题。所以对于相对复杂的镜像环境,还是不建议这样构建,直接传输镜像会更稳定。

2.3 导出的镜像文件直接导入

Docker 支持直接把容器导出成 tar 的压缩文件,然后从这个文件导入镜像,即可完美复刻容器的环境和内容。

1. 找出要导出容器的 名称 或 ID

bash 复制代码
docker ps # 会列出正在运行的容器
docker ps -a # 会列出所有的容器

2. 导出容器到 .tar 文件

bash 复制代码
docker export container_name > container.tar

后面的文件名可以自己指定

3. 在目标电脑上导入镜像

bash 复制代码
docker import container.tar new_image_name:tag

其中 new_image_name 是新镜像的名称,tag 是标签(可选)。


这种方法的好处就是:对于特定状态的容器,可以快速地在不同环境中进行迁移,无需重新构建镜像。如果目标环境没有网络连接或者网络受限,这种方式可以避免从远程仓库拉取镜像的问题。

当然,与使用 Dockerfile 构建的镜像不同,通过这种方式导入的镜像没有构建历史记录。这可能会在一些需要追踪构建过程或进行调试的情况下带来不便。

三、运行和管理容器

3.1 命令行运行

可以基于之前生成的镜像来启动容器,当然一个镜像可以启动多个容器,但是一个容器一定是基于某个镜像的。命令比较简单,这里就着重给大家介绍几个常用的配置。

1. 分离模式

以分离模式(detached mode)运行容器,即容器在后台运行,不会将容器的输出打印到终端。

bash 复制代码
docker run -d my_image

2. 映射端口

将主机的 某个 端口映射到容器的 指定 端口,比如 8080-80,这样可以通过访问主机的 8080 端口来访问容器内运行在 80 端口的服务。

bash 复制代码
docker run -p 8080:80 my_image

3. 容器命名

为容器命名,方便后续对该容器进行管理和识别。不写则会随机生成,可用 docker ps -a 查找。

bash 复制代码
docker run --name my_container my_image

4. 挂载目录

将主机上的指定目录挂载到容器内的指定目录,实现数据持久化,并且两侧是同步的。

bash 复制代码
docker run --name my_container -v /host/data:/container/data my_image

5. 设置环境变量

设置环境变量和值,容器内的应用可以读取这个环境变量。

bash 复制代码
docker run --name my_container -e MY_ENV_VARIABLE=value my_image

6. 限制内存

限制容器使用的内存,防止容器过度占用主机资源。(Windows 下可能不行,得改 WSL2配置)

bash 复制代码
docker run --name my_container --memory 512m my_image

7. 限制核心

限制容器最多使用主机 CPU 核心数。(Windows 下可能不行,得改 WSL2配置)

bash 复制代码
docker run --name my_container --cpus 0.5 my_image

8. 连接网络

将容器连接到 Docker 网络,如果该网络不存在,Docker 会自动创建。这样可以方便容器之间的通信和网络隔离。(当然,网络模式有很多种,我的另一篇有详细介绍)

bash 复制代码
docker run --name my_container --network my_network my_image

9. 退出重启

设置容器的自动重启策略为总是在退出时自动重启。这在容器因某些原因意外退出时很有用,可以确保服务的连续性。

bash 复制代码
docker run --name my_container --restart always my_image

容器开启后,就可以运行程序了,当然可以打开新的终端,输入命令进入到容器内部:

bash 复制代码
   docker exec -it [容器名称或 ID] /bin/bash

这里的 -i 表示允许交互,-t 表示分配一个伪终端。这样就可以进入容器并启动一个 bash shell。

想退出用 exit 即可,但是退出后容器默认会在后台运行。

停止容器:

bash 复制代码
docker stop [容器名称或 ID]

发送一个 SIGTERM 信号给容器,让容器内的主进程有机会进行优雅的关闭。如果容器在一段时间内(默认是 10 秒)没有停止,Docker 会发送一个 SIGKILL 信号强制停止容器。

删除容器:

bash 复制代码
docker rm [容器名称或 ID]

删除一个已停止的容器。如果容器正在运行,需要先停止容器才能删除。

bash 复制代码
docker rm -f [容器名称或 ID]

强制删除一个正在运行的容器。使用这个命令时要注意,可能会导致数据丢失或其他问题。


查看容器日志:

bash 复制代码
docker logs [容器名称或 ID]

查看容器的日志输出。可以使用-f参数来实时跟踪日志输出。

重启容器:

bash 复制代码
docker restart [容器名称或 ID]

复制文件:

bash 复制代码
docker cp [源路径] [容器名称或 ID]:[目标路径]

将本地文件或目录复制到容器中。

bash 复制代码
docker cp [容器名称或 ID]:[源路径] [目标路径]

将容器中的文件或目录复制到本地。

3.2 Docker Compose

Docker Compose 是一个用于定义和运行多容器应用程序的工具,它是开启精简高效的开发和部署体验的关键。可以一次性启动或停止多个相关容器,提高开发和调试效率。

可以在单个易于理解的 YAML 配置文件中轻松管理服务、网络和卷。然后,通过一个命令,就可以从配置文件中创建并启动所有服务。

注意,适用于多容器和复杂管理的情况,容器较少的情况下就没有必要了。

使用之前需要安装,这里不具体介绍,根据官方文档即可。可以用此命令查看:


使用需要创建一个 docker-compose.yml 文件,在文件中定义服务(容器)、网络、卷等。

这里展示一个示例,包含一个 Web 服务器(Nginx)和一个后端应用(假设是一个 Python Flask 应用):

bash 复制代码
services:
  web:
    image: nginx
    ports:
      - "8080:80"
    volumes:
      -./nginx_config:/etc/nginx/conf.d
    networks:
      - mynetwork

  app:
    build:.
    command: python app.py
    volumes:
      - app_data:/app/data
    networks:
      - mynetwork
    environment:
      - DB_HOST=db
      - DB_PORT=5432
      - DB_NAME=mydb
      - DB_USER=myuser
      - DB_PASSWORD=mypassword

  db:
    image: postgres
    volumes:
      - db_data:/var/lib/postgresql/data
    environment:
      - POSTGRES_USER=myuser
      - POSTGRES_PASSWORD=mypassword
      - POSTGRES_DB=mydb
    networks:
      - mynetwork

volumes:
  app_data:
  db_data:

networks:
  mynetwork:
    driver: bridge

上面配置中,通过 networks 部分定义了一个名为 mynetwork 的网络,类型为 bridge。三个服务(webappdb)都连接到这个自定义网络,使得它们可以通过服务名称相互通信。

定义了两个卷 app_datadb_dataweb 服务将本地的 ./nginx_config 目录挂载到容器内的 /etc/nginx/conf.d,用于配置 Nginx。

app 服务将卷 app_data 挂载到容器内的 /app/data,用于数据存储。db 服务将卷 db_data 挂载到容器内的 /var/lib/postgresql/data,用于 PostgreSQL 数据库的数据存储。

四、总结

上面详细介绍了 Docker 的基本操作,涵盖了生成镜像、运行容器以及管理容器等多方面内容。然而,Docker 作为一款功能极为强大的软件,其能力远不止于此。

在容器间的交互方面,Docker 支持容器间的加密通讯,确保数据在不同容器之间传输的安全性和保密性。通过加密机制,敏感信息得以在复杂的容器化环境中安全流转。

同时,Docker 拥有丰富的插件功能。例如,某些插件可以实现更高效的存储管理,优化容器对存储资源的利用;还有些插件能够增强网络配置的灵活性,为容器间的通讯提供更多定制化的选项。此外,插件还可以与其他工具和技术进行集成,进一步提升 Docker 在不同场景下的适用性和实用性。

官方文档内容也比较多,大家按需学习即可。

相关推荐
Qayrup5 分钟前
docker 搭建私有仓库,推送并拉取
运维·docker·容器
闪耀星星9 分钟前
debian elctron-builder
运维·debian
会飞的土拨鼠呀10 分钟前
Debian 12 笔记本合盖不休眠设置指南
运维·debian
郭庆汝22 分钟前
docker拉取英伟达官方cuda11.8镜像
docker·cuda11.8
天下不喵2 小时前
Ubuntu24.04安装Docker过程记录
docker
黑黍2 小时前
如何在k8s中配置并使用nvidia显卡
云原生·容器·kubernetes
梁正雄2 小时前
6、prometheus资源规划
运维·服务器·服务发现·prometheus·监控
晨曦之旅3 小时前
零成本体验云计算!阿贝云免费服务器深度测评
运维·服务器·云计算
工具人55553 小时前
Linux 抓取 RAM Dump 完整指南
linux·运维·安全
冷血~多好3 小时前
使用docker部署elk,实现日志追踪
elk·docker·容器