Docker:容器(Container)和镜像(Image)的关系


引言

首先阐述下我对容器和镜像这两者关系的理解:我从一个服务器(仓库)pull下来CentOS 7的基础镜像,然后用docker run命令创建了一个容器,这个容器就相当于一个沙盒,于是在我原本系统里又有一个系统(就好像创建了一个虚拟机),之后我在这个容器里安装所有OpenStack的依赖项服务如:mysql、RabbitMQ、Chrony等后,我把这个容器打包成镜像push到公共服务器上(公有仓库),别人pull我的这个镜像后docker run又在他的系统创建了一个容器,由于我之前这个在容器安装好了OpenStack的依赖服务,他就可以在我的基础上安装必要组件开始搭建OpenStack了,而不需要再去解决那些依赖的问题


一、广义上的Docker

Docker 可以被定义为一个开放源代码的容器化平台,它使开发人员能够打包、交付其运行应用程序及其依赖项在一个容器中。容器能够在任何地方运行:无论是在开发者的本地机器上、在公司的数据中心、在云服务上,还是在任何其他支持 Docker 的环境中。

二、与Docker相关的名词和概念

1.容器(Container)

容器是一种轻量级、可移植的、独立的环境,它包含应用程序及其所有依赖项。与传统的虚拟机不同,容器共享主机操作系统的内核,但具有隔离的用户空间。

2.镜像(Image)

镜像是一个只读的模板,用于创建容器。镜像包含了应用程序运行所需的一切,比如代码、运行时、库和环境变量等。镜像可以通过 Dockerfile 定义并构建。

3.仓库(Registry)

Docker 镜像存储在仓库中。Docker Hub 是一个公共的 Docker 镜像仓库,用户可以从中下载和上传镜像。你也可以设置私有仓库来存储公司内部的镜像。

4.Docker 引擎(Docker Engine)

Docker 引擎是一个客户端-服务器应用程序,包含以下主要组件:

1.服务器:一种长期运行的守护进程(dockerd),负责管理容器。

2.REST API:用于与守护进程进行交互的接口。

3.客户端(Client):用户与 Docker 进行交互的命令行工具(docker)

5.Dockerfile

Dockerfile 是一个文本文件,包含了一系列指令,用于构建 Docker 镜像。每一条指令都在镜像中创建一个新的层次。例如,FROM 指令指定了基础镜像,COPY 指令将文件复制到镜像中,RUN 指令执行命令。


三、对容器和镜像理解*

1.什么是容器?

这里我们采用对比理解的方式来解读容器,容器和虚拟机(VM)有一些相似之处,所以我们可以结合这点来理解什么是容器。

虚拟机(VM):

  1. 包含的内容:虚拟机包含一个完整的操作系统(OS)、应用程序和所有的依赖项。每个虚拟机运行在一个虚拟的硬件环境上,由虚拟机监控程序(Hypervisor)管理。

  2. 资源开销:由于每个虚拟机都有完整的操作系统,它们的启动时间较长,占用的资源(如 CPU、内存)也较多。

  3. 隔离性:虚拟机提供强隔离,每个虚拟机都有独立的内核,彼此之间完全隔离,安全性较高。

  4. 快照:虚拟机快照是一个存储虚拟机状态的副本,包括内存状态、虚拟机设置和虚拟磁盘文件,可用于快速恢复或创建新虚拟机。

容器:

  1. 包含的内容:容器包含应用程序及其所有依赖项,但共享主机操作系统的内核。容器使用主机操作系统的资源,运行在隔离的用户空间中。

  2. 资源开销:容器启动速度快,占用资源少,因为它们不需要运行一个完整的操作系统。

  3. 隔离性:容器通过内核名称空间(namespace)和控制组(cgroups)提供进程级隔离,虽然隔离性不如虚拟机强,但在大多数应用场景下已经足够。

  4. 镜像:容器镜像类似于虚拟机的快照,它包含应用程序及其依赖项的文件系统快照,但不包含操作系统内核。容器可以通过镜像快速启动和复制。

关键区别

  1. 架构:

    虚拟机:每个虚拟机都有自己的内核和完整操作系统。
    容器:容器共享主机操作系统的内核,只有应用程序和其依赖项。

  2. 启动时间和资源利用:

    虚拟机:启动时间较长,占用较多系统资源。
    容器:启动时间极快,资源利用率高。

  3. 隔离性和安全性:

    虚拟机:提供强隔离,安全性较高。
    容器:通过内核机制提供隔离,隔离性相对较弱,但效率更高。

  4. 管理和可移植性:

    虚拟机:更适合运行需要完整操作系统的复杂任务。
    容器:更适合微服务架构和需要快速部署和扩展的场景。

2.什么是Docker镜像?

这里我们也采用对比理解的方式来解读Docker镜像

Docker 镜像

  1. 轻量级:

    Docker 镜像是轻量级的,因为它们共享主机操作系统内核。每个容器都只包含应用程序及其依赖项、运行时环境和配置文件等,而不需要额外的操作系统。

  2. 快速启动:

    由于 Docker 镜像是轻量级的,容器可以在几秒钟内启动,启动速度远远快于虚拟机。

  3. 资源利用率高:

    因为 Docker 容器共享主机操作系统内核,多个容器可以在同一台物理机上并行运行,有效地利用了硬件资源。

  4. 隔离性:

    Docker 提供了一定程度的隔离性,通过 Linux 命名空间和控制组等技术实现容器之间的隔离,但与虚拟机相比,隔离性相对较弱。

虚拟机镜像

  1. 完整操作系统:

    虚拟机镜像包含了完整的操作系统,包括内核、驱动程序、系统服务等。每个虚拟机都运行独立的操作系统实例。

  2. 启动慢:

    由于虚拟机镜像包含完整的操作系统,启动一个虚拟机通常需要几分钟的时间.

  3. 资源消耗高:

    虚拟机占用的资源比较多,因为每个虚拟机都需要独立的操作系统内核和系统服务。

  4. 隔离性强:

    虚拟机之间的隔离性比 Docker 容器强,每个虚拟机都运行在独立的虚拟硬件上,彼此之间互相隔离。

3.Docker 镜像的主要组成部分

  1. 基础镜像(Base Image):

    Docker 镜像通常基于一个基础镜像。基础镜像提供了基本的操作系统用户空间环境,如 Ubuntu、Alpine、CentOS等。它包含了一些基础工具和库,支持应用程序的运行。

  2. 应用程序代码:

    这是你的应用程序的实际代码和二进制文件。例如,如果是一个 Python 应用程序,镜像中会包含 .py 文件。

  3. 依赖项和库:

    镜像包含了应用程序运行所需的所有依赖项和库。例如,一个 Node.js 应用程序镜像会包含 Node.js 运行时和所有 npm 模块。

  4. 配置文件:

    镜像可以包含应用程序所需的配置文件和环境变量设置。例如,数据库连接字符串、配置文件等。

  5. 运行时环境:

    包含应用程序运行时所需的环境,例如 Java 应用程序的 JRE,Python 应用程序的 Python 解释器,Node.js应用程序的 Node 运行时等。

  6. 启动脚本和命令:

    镜像中包含启动容器时执行的命令和脚本,这些定义了容器启动时应该运行什么。例如,一个启动 Web 服务器的命令。

四、容器和镜像的关系*

  1. 镜像是容器的模板:

    镜像是一个只读的模板,包含了运行容器所需的文件系统内容、运行时环境、应用程序和依赖项等。它类似于一个软件的安装包或一个虚拟机的快照。

  2. 容器是镜像的运行实例:

    容器是镜像的运行实例,是镜像的一个可写的、可执行的实体。当你运行一个镜像时,Docker
    会创建一个新的容器实例,该容器会继承镜像的内容,并在其上添加一个可写层。

  3. 镜像可以生成多个容器:

    你可以基于同一个镜像创建多个运行中的容器实例。每个容器都相互独立,拥有自己的文件系统和运行环境,但它们共享相同的镜像作为基础。

关系示例
假设你有一个名为 ubuntu 的镜像,它是一个包含 Ubuntu 操作系统的基本文件系统和工具的模板。你可以基于这个镜像创建多个运行中的容器实例,每个容器实例都是一个独立的 Ubuntu 环境,但它们共享相同的 ubuntu 镜像作为基础。这些容器可以独立运行、启动、停止和删除,而不会影响到其他容器或镜像。

五、容器的创建

  1. 选择合适的镜像:

    首先,你需要选择一个适合你应用程序的 Docker 镜像。你可以从 DockerHub、公共或私有的镜像仓库中选择现有的镜像,或者自己通过 Dockerfile 构建一个镜像。

  2. 运行容器:

    使用 docker run 命令来运行容器。这个命令会从指定的镜像启动一个容器实例。例如:

docker run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND] [ARG...]

六、Docker 镜像的编写

Docker 镜像通常通过编写 Dockerfile 来定义。Dockerfile 是一个文本文件,包含了构建镜像所需的一系列指令

指令意义
FROM指定基础镜像。例如:FROM ubuntu:20.04
COPY 和 ADD将文件和目录复制到镜像中。例如:COPY myapp /app
RUN在镜像构建时运行命令,例如安装依赖项。例:RUN apt-get update && apt-get install -y python3
ENV设置环境变量。例如:ENV DATABASE_URL=postgres://user:password@db:5432/mydb
EXPOSE声明容器监听的端口。例如:EXPOSE 8080
CMD 和 ENTRYPOINT指定容器启动时运行的命令。例:CMD [“python3”, “/app/myapp.py”]

示例

# 使用官方的 Python 3.8 镜像作为基础镜像
FROM python:3.8

# 设置工作目录
WORKDIR /app

# 将当前目录的内容复制到 /app 目录中
COPY . /app

# 安装应用程序依赖项
RUN pip install --no-cache-dir -r requirements.txt

# 设置环境变量
ENV ENVIRONMENT=production

# 暴露应用程序运行的端口
EXPOSE 5000

# 运行应用程序
CMD ["python", "app.py"]


总结

镜像是容器的模板,容器是镜像的实例

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值