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