容器简介
容器(Container)是一种轻量级、可移植、可执行的软件打包技术。它将应用程序及其所有依赖关系(如代码、库、配置文件等)打包在一个独立的环境(容器镜像)中,使其能够在任何支持容器的系统上运行。容器与传统的虚拟化技术相比,具有更高的效率和更低的开销,因为它不需要虚拟化整个操作系统,而是共享宿主机的操作系统内核。
主要特性
- 轻量级:容器使用宿主操作系统的内核,而不是每个容器都有一个独立的操作系统。它们的启动速度非常快,并且占用的资源相对较少。
- 可移植性:容器中包含了应用程序及其所有依赖项,因此可以确保在不同环境下(开发、测试、生产等)保持一致性。无论是在本地开发机、云环境还是集群中,容器都可以像在本地一样运行。
- 隔离性:容器提供了良好的进程隔离,每个容器运行时在自己的环境中,不会干扰其他容器。容器通过命名空间和控制组(cgroups)技术来实现这种隔离。
- 可扩展性:容器可以轻松进行扩展和缩减,适合自动化部署和弹性伸缩。容器编排工具如 Kubernetes 可以帮助管理容器的生命周期、自动扩展、负载均衡等。
- 易于部署和更新:容器中的应用程序和依赖项被打包在一起,简化了部署和更新的流程。容器镜像可以方便地推送到镜像仓库,其他机器可以直接拉取并运行。
容器 vs 虚拟化
| 特性 | 容器 (Container) | 虚拟机 (VM) |
|---|---|---|
| 资源占用 | 较低,多个容器共享宿主操作系统内核 | 较高,每个虚拟机有自己的操作系统 |
| 启动时间 | 极快(秒级) | 较慢(分钟级) |
| 隔离性 | 良好(进程隔离) | 优秀(硬件层隔离) |
| 性能开销 | 低(直接使用宿主机操作系统内核) | 高(虚拟化带来额外开销) |
| 可移植性 | 高,跨平台一致性强 | 较低,需要虚拟化环境支持 |
容器的关键技术
- 镜像(Image):容器镜像是容器的蓝图,它包含了应用程序及其所有的依赖项、库文件、配置文件等。镜像是只读的,可以通过 Dockerfile 进行定义。
- 容器(Container):容器是镜像的一个实例。它在一个隔离的环境中运行,包含了应用程序及其依赖。容器可以启动、停止、删除等。
- 容器引擎(Container Engine):容器引擎是用来创建、运行和管理容器的工具,最常见的是 Docker 和 containerd。
- 容器编排(Orchestration):在大规模应用中,容器需要被管理和协调。工具如 Kubernetes、Docker Swarm 提供了容器的自动化部署、扩展、负载均衡等功能。
常见容器工具
- Docker:最广泛使用的容器平台,提供了容器的创建、发布、运行等功能。它简化了容器化应用程序的开发和部署。
- Kubernetes:一个开源的容器编排平台,帮助管理大规模容器化应用的生命周期。它提供了自动化部署、扩展、滚动更新等功能。
- Podman:与 Docker 类似,但 Podman 是无守护进程的,容器的管理完全依赖于用户的命令,支持 rootless(无权限)容器。
容器的使用场景
- 微服务架构:容器为每个微服务提供独立的运行环境,易于开发、部署和扩展。
- 开发与测试环境:容器能够确保开发和生产环境的一致性,从而减少环境差异带来的问题。
- CI/CD:容器化的应用可以帮助实现持续集成和持续交付(CI/CD),加速软件的开发与部署。
- 云计算:容器适合云环境,能够通过弹性扩展和负载均衡来优化资源利用。
总的来说,容器是一种非常强大的工具,能够提升应用的可移植性、可扩展性和开发效率,特别适合现代 DevOps 和云原生环境。
容器依赖的相关技术
- 命名空间(Namespaces) 命名空间是 Linux 内核的一种技术,它提供了对进程、网络、文件系统等资源的隔离。每个容器都在自己的命名空间内运行,确保它们不会与其他容器或宿主机上的进程干扰。Linux 提供了以下几种命名空间类型:
- PID Namespace:隔离进程 ID,使得容器内的进程 ID 与宿主机或其他容器中的进程 ID 不同。容器内可以有自己的进程管理体系。
- Network Namespace:为每个容器提供独立的网络栈,包括网络接口、IP 地址、路由等。容器内的应用可以使用独立的网络配置。
- Mount Namespace:提供对文件系统的隔离,每个容器拥有自己独立的文件系统挂载点。容器内的文件系统与宿主机和其他容器的文件系统隔离开来。
- UTS Namespace:为容器提供独立的主机名和域名信息,使得容器内的主机名与宿主机不同。
- IPC Namespace:为容器提供独立的进程间通信(IPC)机制,使得容器之间的信号、共享内存等通信方式不互相干扰。
- User Namespace:实现容器内的用户与宿主机的用户隔离,使得容器内的用户和权限与宿主机隔离。容器内的普通用户可以拥有宿主机上 root 用户的权限,但不影响宿主机的安全性。
- 控制组(Cgroups) 控制组(Cgroups,Control Groups)是 Linux 内核中的一种资源管理技术,用于对容器使用的资源(如 CPU、内存、磁盘 IO、网络带宽等)进行限制和监控。Cgroups 允许操作系统对容器的资源使用进行精细化管理,从而防止某个容器消耗过多的资源,影响其他容器或宿主机的性能。
- 资源限制:可以对容器的 CPU、内存、磁盘 I/O 等资源进行配额管理,确保容器不会超出设定的资源限制。
- 资源监控:可以监控容器的资源使用情况,并根据实际需求进行动态调整。
- 联合文件系统(Union File System) 容器利用联合文件系统(例如 OverlayFS、AUFS、UnionFS)来构建容器的文件系统。联合文件系统允许多个文件系统层叠在一起,形成一个虚拟的文件系统视图。容器使用这些联合文件系统来管理其文件和目录。
- 镜像层:容器镜像通常由多个只读层组成,这些层描述了应用程序的不同部分。
- 容器层:容器的运行实例会在镜像的基础上创建一个可写层,容器的所有变更(如文件创建、修改)都会发生在这一层。 通过联合文件系统,容器可以高效地共享基础镜像,而不需要每个容器都复制文件,节省存储空间。
- 虚拟化(Lightweight Virtualization) 虽然容器并不是传统的虚拟机技术,但它们使用了某些虚拟化技术的概念,尤其是在资源隔离方面。容器并不虚拟化整个硬件,而是虚拟化操作系统内核,因此比虚拟机更加轻量。
- 与虚拟机的区别:虚拟机通过 hypervisor 来模拟整个硬件和操作系统,而容器是通过共享宿主机的操作系统内核,提供进程隔离、资源管理和文件系统隔离。
- Linux Seccomp 和 AppArmor/SELinux(安全) 为了增强容器的安全性,容器技术常常与 Linux 内核的 Seccomp、AppArmor 或 SELinux 等安全机制结合使用。
- Seccomp(安全计算模式):通过限制容器可以使用的系统调用,减少容器中的潜在安全漏洞。
- AppArmor 和 SELinux:这些是 Linux 中的强制访问控制(MAC)机制,用于细粒度的访问控制和限制容器对系统资源的访问权限。
容器管理工具
容器运行时(低层引擎)
这些是直接与 Linux 内核打交道的容器运行时,负责容器生命周期管理(启动、停止、资源限制等):
| 工具名称 | 简介 |
|---|---|
| runc | OCI 标准实现,最底层的容器运行工具,执行具体的容器创建与隔离工作。 |
| gVisor | Google 开发的用户态内核,主打安全性高的沙箱容器。 |
| Kata Containers | OpenStack 基金会项目,将容器封装在轻量虚拟机中,兼顾隔离性和启动速度。 |
容器引擎(高级运行时)
容器引擎是在运行时之上的接口层,提供用户友好的容器创建、构建、网络、镜像管理接口:
| 工具名称 | 简介 |
|---|---|
| Docker | 最主流的容器引擎,集成镜像构建、运行、网络、仓库管理等一体化功能。 |
| Podman | Red Hat 开发的无守护进程(daemonless)容器引擎,支持 rootless 容器,兼容 Docker CLI。 |
| Buildah | 专注于构建 OCI 容器镜像,不负责运行。与 Podman 配合可代替 Docker 全流程。 |
| LXC/LXD | 更接近系统容器(system containers),比 Docker 更适合运行完整的 OS 镜像。 |
不同的容器引擎都会遵循 OCI 标准,容器镜像通用。最主流的容器引擎还是 Docker,后边主要介绍 Docker。