AIOps基石容器云原生docker
什么是容器技术
-
容器技术的定义与概念
- 定义:容器技术是一种操作系统级别的虚拟化技术,它允许在单个操作系统上运行多个隔离的应用程序及其依赖项。每个容器都包含了一个完整的运行环境,包括应用程序、运行时环境、系统工具、库等,就好像每个容器是一个独立的小型操作系统。
- 类比传统虚拟机:与传统虚拟机不同,容器不需要为每个应用程序模拟一个完整的操作系统。虚拟机是在硬件层面进行虚拟化,每个虚拟机都有自己独立的操作系统内核;而容器是在操作系统层面进行虚拟化,多个容器共享主机操作系统内核,通过内核的资源隔离机制(如cgroups和namespaces)来提供隔离环境。例如,在一台服务器上,如果使用虚拟机技术运行多个应用,每个虚拟机可能都要安装完整的操作系统(如Windows、Linux等),这会占用大量的磁盘空间和系统资源;而使用容器技术,多个容器可以共享主机的Linux内核,大大减少了资源的占用。
-
核心技术原理(Namespaces和Cgroups)
- Namespaces(命名空间):
- 作用:Namespaces是Linux内核提供的一种资源隔离机制,用于将系统的全局资源进行划分,使得每个容器都有自己独立的资源视图。例如,通过PID Namespace,每个容器都有自己独立的进程编号系统,容器内的进程在容器外看起来有独立的进程ID,容器内的进程1和容器外的进程1是不同的概念;通过Mount Namespace,每个容器可以有自己独立的文件系统挂载点,容器可以挂载自己的目录结构,而不会影响其他容器和主机的文件系统。
- 示例:在网络方面,Net Namespace可以让每个容器有自己独立的网络接口、IP地址、路由表等。一个容器可以配置自己的网络环境,如设置为桥接模式,通过虚拟网桥与外部网络通信,就好像这个容器是一个独立的网络节点,与其他容器的网络环境相互隔离。
- Cgroups(控制组):
- 作用:Cgroups主要用于对容器的资源使用进行限制和管理。它可以控制容器对CPU、内存、磁盘I/O、网络带宽等资源的使用量。例如,可以通过Cgroups设置一个容器最多只能使用主机CPU资源的50%,或者限制容器的内存使用量为2GB。这样可以确保在多个容器共享主机资源时,每个容器不会过度占用资源,从而保证系统的稳定性和公平性。
- 示例:在内存限制方面,如果一个容器运行的应用程序出现内存泄漏,通过Cgroups设置的内存限制可以防止这个容器耗尽主机的所有内存,当容器使用的内存达到限制值时,系统可以根据配置采取相应的措施,如限制进程的内存分配或者发出警告。
- Namespaces(命名空间):
-
容器技术的优势
- 资源高效利用:
- 共享内核节省资源:容器共享主机操作系统内核,相比于传统虚拟机,减少了大量操作系统层面的资源重复占用。例如,在服务器资源有限的情况下,可以在同一台服务器上部署更多的容器。以内存资源为例,一个容器化的小型Web应用可能只需要几百MB的内存,而虚拟机可能需要几GB的内存来运行相同的应用。
- 快速启动和停止:容器的启动和停止速度非常快,因为不需要像虚拟机那样进行完整的操作系统启动过程。容器可以在几秒内启动,快速响应用户的需求。例如,在处理突发流量时,可以快速启动多个容器来分担负载,流量过后又可以快速停止这些容器,节省资源。
- 环境一致性与可移植性:
- 环境一致保证运行:容器将应用程序及其所有依赖项打包在一起,确保在不同的环境(如开发环境、测试环境、生产环境)中运行的一致性。例如,一个用Python编写的Web应用,在容器中打包了Python运行时环境、所需的库(如Flask、Django等)以及应用代码,无论在开发人员的本地机器还是在云端的生产服务器上,只要容器运行环境相同,应用就能以相同的方式运行。
- 方便移植跨平台部署:容器可以方便地在不同的操作系统和云平台之间进行移植。只要目标平台支持容器运行时(如Docker),就可以将容器化的应用轻松部署到该平台。例如,一个在本地开发测试完成的容器化应用,可以直接部署到亚马逊AWS、微软Azure或者谷歌云等不同的云平台上。
- 资源高效利用:
-
容器技术的应用场景
- 微服务架构:
- 独立部署和扩展:在微服务架构中,每个微服务可以打包成一个容器独立部署。不同的微服务可以使用不同的技术栈,通过容器化可以方便地管理和扩展。例如,一个电商系统可以将用户服务、商品服务、订单服务等分别打包成容器,这些容器可以独立地进行升级、扩展和维护。当用户流量增加时,可以快速增加用户服务容器的数量来提高性能。
- 服务发现和编排:容器编排工具(如Kubernetes)可以帮助管理大量的容器化微服务。通过服务发现机制,容器可以方便地找到其他容器并进行通信。例如,在一个分布式的微服务系统中,订单服务容器可以通过服务发现机制找到用户服务容器并获取用户信息,实现业务功能。
- 持续集成/持续交付(CI/CD):
- 构建和测试环境一致性:在CI/CD流程中,容器可以提供一致的构建和测试环境。开发人员可以将应用代码和测试环境打包成容器,在不同的阶段(如代码提交、构建、测试、部署)都使用相同的容器环境,确保测试结果的准确性和可靠性。例如,在自动化测试过程中,每次运行测试都在相同的容器环境中进行,避免了因为环境差异导致的测试失败。
- 快速部署和回滚:容器的快速启动和停止特性使得在CI/CD流程中可以快速地将应用部署到生产环境,并且在出现问题时可以快速回滚。例如,当新的版本部署后出现故障,可以立即启动旧版本的容器,快速恢复服务,减少对用户的影响。
- 微服务架构:
容器技术优劣势
- 容器技术的优势
(1)高效的资源利用
- 轻量级特性:
- 容器共享主机操作系统内核,相比于传统虚拟机,容器不需要为每个应用程序模拟一个完整的操作系统。这使得容器在磁盘空间占用上非常小,通常一个容器镜像可能只有几十MB到几百MB大小,而一个虚拟机镜像可能需要数GB。例如,一个简单的Node.js容器应用,其镜像大小可能只有100MB左右,这大大节省了磁盘存储资源。
- 在内存使用方面,容器也更加高效。因为它们没有虚拟机那样的额外操作系统开销,多个容器可以在同一台主机上共享内存资源,并且可以根据实际需求灵活分配。例如,在一台具有8GB内存的服务器上,可以同时运行更多的容器,而如果使用虚拟机,由于每个虚拟机都需要独立的内存来运行操作系统和应用,可运行的数量会少很多。
- 快速启动和停止:
- 容器的启动速度极快,通常可以在几秒内完成启动。这是因为容器不需要像虚拟机那样进行完整的操作系统引导过程,如硬件检测、内核加载等。例如,在应对突发的流量高峰时,如电商平台的促销活动,容器可以快速启动来处理增加的请求。当流量高峰过去后,这些容器又可以快速停止,释放资源,这种快速的伸缩能力能够有效地应对业务的动态变化。
(2)环境一致性与可移植性
- 环境一致性保障:
- 容器将应用程序及其所有依赖(包括运行时环境、库、配置文件等)打包在一起。这确保了应用在不同的环境(如开发环境、测试环境、生产环境)中运行时,具有完全相同的环境设置。例如,一个使用Python Flask框架构建的Web应用,在容器中包含了Python运行时环境、Flask库以及应用代码,无论在开发人员的本地开发环境,还是在云端的生产服务器环境,只要容器运行时环境相同,应用就能以相同的方式运行,避免了因环境差异导致的“在我机器上可以运行”(It works on my machine)的问题。
- 跨平台可移植性:
- 容器可以很方便地在不同的操作系统和云平台之间进行移植。只要目标平台支持容器运行时(如Docker),就可以轻松地将容器化的应用部署到该平台。例如,一个在本地Linux环境下开发和测试完成的容器化应用,可以无缝地部署到亚马逊AWS、微软Azure或谷歌云等云平台上,而且在不同的云平台之间迁移也相对容易,只需要将容器镜像传输到目标平台并运行即可。
(3)版本控制与更新管理
- 精确的版本管理:
- 容器技术通过镜像来打包应用,这些镜像可以进行版本控制。就像代码仓库中的代码版本管理一样,容器镜像也可以有版本号、标签等标识。例如,开发团队可以为每个版本的应用容器镜像打上标签,如
v1.0、v1.1等,方便跟踪和管理应用的不同版本。当需要回滚应用版本时,可以根据标签快速地找到并部署之前的版本。
- 容器技术通过镜像来打包应用,这些镜像可以进行版本控制。就像代码仓库中的代码版本管理一样,容器镜像也可以有版本号、标签等标识。例如,开发团队可以为每个版本的应用容器镜像打上标签,如
- 轻松的更新部署:
- 在更新应用时,只需构建新的容器镜像,并将其部署到运行环境中即可。与传统的应用更新方式相比,容器更新更加方便和安全。例如,在一个微服务架构的系统中,更新一个服务的容器镜像,只需要将新的镜像推送到容器运行环境中,通过容器编排工具(如Kubernetes)可以控制更新的策略,如滚动更新(逐步替换旧容器为新容器),这样可以在不中断服务的情况下完成应用的更新。
(4)微服务架构支持
- 独立部署和扩展便利:
- 在微服务架构中,每个微服务都可以打包成一个独立的容器进行部署。不同的微服务可以使用不同的技术栈,并且可以独立地进行开发、测试、部署和扩展。例如,在一个电商系统中,用户服务、商品服务、订单服务等微服务可以分别打包成容器。当用户服务的流量增加时,可以单独对用户服务的容器进行扩展,如增加容器数量,而不会影响其他微服务的运行。
- 服务发现和编排集成优势:
- 容器编排工具(如Kubernetes)与容器技术紧密配合,能够实现微服务之间的高效服务发现和编排。容器可以通过内置的服务发现机制轻松地找到其他容器并进行通信。例如,在一个分布式的微服务系统中,订单服务容器可以通过服务发现机制找到用户服务容器并获取用户信息,实现业务功能,并且可以根据业务需求动态地调整微服务容器的数量、位置等。
- 容器技术的劣势
(1)安全性挑战
- 共享内核风险:
- 容器共享主机操作系统内核,这虽然提高了资源利用率,但也带来了一定的安全风险。如果一个容器中的应用被攻破,攻击者有可能利用内核漏洞来影响其他容器或者主机系统。例如,某些内核级别的漏洞可能会允许恶意攻击者突破容器的隔离边界,访问其他容器的资源或者进行恶意操作,如窃取数据、篡改配置等。
- 安全配置复杂:
- 要确保容器的安全,需要进行复杂的安全配置。这包括设置合适的用户权限、网络访问控制、资源限制等。例如,在容器网络方面,如果没有正确配置网络策略,容器之间可能会出现非预期的网络访问,增加安全风险。而且,随着容器数量的增加,安全管理的复杂性也会呈指数级增长。
(2)存储和数据管理复杂
- 数据持久化问题:
- 容器本身是无状态的,这意味着当容器停止或重新启动时,容器内的数据会丢失。对于需要持久化数据的应用,如数据库应用,需要额外的存储解决方案。例如,在容器中运行的MySQL数据库,需要将数据存储在外部的存储卷(如分布式存储系统或主机挂载的存储设备)中,并且需要正确地配置数据挂载点和权限,否则可能会导致数据丢失或无法访问。
- 存储性能和管理挑战:
- 与传统的物理机或虚拟机相比,容器的存储性能可能会受到影响。由于容器的存储通常是通过挂载存储卷实现的,在高并发的读写操作下,存储卷的性能和稳定性需要特别关注。同时,管理大量容器的存储配置(如存储容量规划、存储备份和恢复等)也是一个复杂的任务。
(3)监控和调试难度
- 监控指标多样性和复杂性:
- 容器环境下的监控指标比传统环境更加复杂多样。除了要监控应用程序本身的性能指标(如响应时间、吞吐量等),还需要监控容器的资源使用情况(如CPU、内存、网络带宽等)、容器的生命周期(如启动、停止、重启等)以及容器编排系统的状态。例如,在一个大规模的容器集群中,要实时监控每个容器的资源消耗情况,需要收集和分析大量的数据,这对监控工具和技术提出了更高的要求。
- 调试困难:
- 当容器化应用出现问题时,调试的难度相对较大。由于容器的隔离性和动态性,很难像在传统环境中那样直接对应用进行调试。例如,容器可能会在不同的主机之间迁移,或者容器的资源限制可能会影响调试工具的使用。而且,在容器集群中,要确定问题所在的具体容器和具体原因,需要综合考虑容器的配置、运行时环境、应用代码等多个因素。
docker是什么
-
定义与概述
- 容器化平台:Docker是一个开源的容器化平台,它可以让开发者将应用程序及其依赖(包括运行时环境、库、配置文件等)打包成一个可移植的容器。这个容器就像一个独立的小盒子,里面包含了运行应用所需的一切,并且可以在任何支持Docker的环境中运行,确保应用在不同环境下的一致性。
- 基于容器技术构建:Docker是基于前面提到的容器技术构建的,利用了Linux内核的Namespaces(用于资源隔离,如进程、网络、文件系统等隔离)和Cgroups(用于资源控制,如限制容器对CPU、内存等资源的使用)来提供容器的隔离和资源管理功能。例如,通过Namespaces,每个Docker容器都有自己独立的进程空间,容器内的进程ID在容器外部是不可见的;通过Cgroups,可限制一个容器最多只能使用主机一定比例的CPU或内存资源。
-
主要组件和工作原理
- Docker镜像(Image):
- 定义与作用:Docker镜像是一个只读的模板,用于创建Docker容器。它包含了运行应用程序所需的所有文件和配置信息,如操作系统文件、应用程序代码、运行时环境、库等。例如,一个Python Web应用的Docker镜像可能包含了一个精简版的Linux操作系统、Python运行时环境、Flask或Django等Web框架以及应用的代码文件。
- 构建过程:可以通过编写Dockerfile来构建镜像。Dockerfile是一个文本文件,其中包含了一系列指令,用于告诉Docker如何构建镜像。例如,
FROM指令用于指定基础镜像(如FROM ubuntu:latest表示以最新版的Ubuntu为基础镜像),COPY指令用于将本地文件复制到镜像中(如COPY. /app将当前目录下的所有文件复制到镜像中的/app目录),RUN指令用于在镜像构建过程中执行命令(如RUN pip install - requirements.txt用于安装应用所需的Python库)。
- Docker容器(Container):
- 定义与作用:Docker容器是从Docker镜像创建出来的运行实例,是真正运行应用程序的地方。容器在运行时是相互隔离的,可以在同一台主机上运行多个容器,每个容器都好像是一个独立的小系统。例如,在一台服务器上可以同时运行多个不同的容器,一个容器运行Web应用,一个容器运行数据库应用,它们之间互不干扰。
- 启动和运行:通过
docker run命令可以从镜像启动一个容器。例如,docker run -d -p 80:80 my_web_app_image这个命令会在后台(-d)启动一个容器,将容器内的80端口映射到主机的80端口(-p 80:80),其中my_web_app_image是之前构建好的Web应用镜像。容器启动后,就会按照镜像中的配置运行应用程序。
- Docker仓库(Repository):
- 定义与作用:Docker仓库用于存储和共享Docker镜像。就像代码仓库存储代码一样,Docker仓库可以是公共的,也可以是私有的。公共仓库(如Docker Hub)中有大量由官方和社区提供的镜像,开发者可以直接拉取这些镜像来使用,也可以将自己构建的镜像推送到仓库中共享。例如,要使用官方的MySQL镜像,可以通过
docker pull mysql:latest从Docker Hub拉取最新版的MySQL镜像。 - 仓库分类:分为官方仓库和第三方仓库。官方仓库是由Docker官方维护的,包含了许多常用软件的官方镜像,如各种操作系统、数据库、编程语言环境等的镜像。第三方仓库则是由其他组织或个人维护的,用于存储特定的镜像,如一些公司内部开发的应用镜像会存储在公司内部的私有仓库中。
- 定义与作用:Docker仓库用于存储和共享Docker镜像。就像代码仓库存储代码一样,Docker仓库可以是公共的,也可以是私有的。公共仓库(如Docker Hub)中有大量由官方和社区提供的镜像,开发者可以直接拉取这些镜像来使用,也可以将自己构建的镜像推送到仓库中共享。例如,要使用官方的MySQL镜像,可以通过
- Docker镜像(Image):
-
应用场景
- 应用开发与测试环境一致性:
- 本地开发:在开发应用程序时,开发人员可以使用Docker来创建一个与生产环境高度一致的开发环境。例如,一个团队开发一个Java Web应用,开发人员可以通过拉取包含Java运行时环境、Web服务器(如Tomcat)和数据库(如MySQL)的Docker镜像,在本地快速搭建一个完整的开发环境。这样,无论开发人员的本地机器是Windows还是Linux,都能确保开发环境的一致性。
- 测试环境:在测试阶段,测试人员可以使用与开发环境相同的Docker容器来进行测试,避免了因环境差异导致的测试问题。例如,在进行自动化测试时,可以通过脚本快速启动包含应用程序和测试工具的Docker容器,在相同的环境下多次重复测试,提高测试的准确性和可靠性。
- 微服务架构部署:
- 独立部署微服务:在微服务架构中,每个微服务可以打包成一个独立的Docker容器进行部署。例如,在一个电商系统中,用户服务、商品服务、订单服务等微服务可以分别构建成Docker容器。这些容器可以独立地进行版本更新、扩展和维护。当某个微服务需要升级时,只需要更新对应的Docker容器,而不会影响其他微服务的运行。
- 服务编排:配合容器编排工具(如Kubernetes),Docker容器可以实现高效的服务编排。例如,通过Kubernetes可以自动管理Docker容器的生命周期,包括启动、停止、伸缩等操作。可以根据业务需求动态地调整微服务容器的数量,如在流量高峰时增加容器数量,在流量低谷时减少容器数量,提高系统的资源利用率和性能。
- 持续集成/持续交付(CI/CD):
- 构建和测试自动化:在CI/CD流程中,Docker可以提供一致的构建和测试环境。例如,在代码提交后,自动化构建系统可以使用Dockerfile来构建应用程序的Docker容器,然后在容器中进行单元测试、集成测试等。这样可以确保每次构建和测试都是在相同的环境下进行,减少了因环境变化导致的构建和测试失败。
- 快速部署到生产环境:在完成测试后,可以将经过测试的Docker容器快速部署到生产环境。由于容器的可移植性,从测试环境到生产环境的部署过程变得更加简单和可靠。例如,通过容器编排工具可以将容器从测试环境无缝地迁移到生产环境,并且可以通过滚动更新等策略来减少对生产服务的影响。
- 应用开发与测试环境一致性:
docker组成
-
Docker镜像(Image)
- 定义与概念:
- Docker镜像是一个只读的模板,它包含了运行容器化应用所需的所有文件和配置信息。可以把镜像想象成一个容器的蓝图或者配方,用于创建一个或多个容器实例。例如,一个Python Web应用的镜像会包含一个基础的操作系统(如Ubuntu的精简版)、Python运行时环境、相关的库(如Flask或Django)以及应用程序的代码。
- 构建方式:
- 使用Dockerfile构建:Dockerfile是构建镜像的文本指令文件。它包含一系列指令,用于告诉Docker如何构建镜像。例如,
FROM指令用于指定基础镜像,如FROM ubuntu:latest表示以最新版的Ubuntu为基础镜像开始构建。COPY指令用于将本地文件复制到镜像中,如COPY. /app将当前目录下的所有文件复制到镜像中的/app目录。RUN指令用于在镜像构建过程中执行命令,如RUN pip install - requirements.txt用于安装应用所需的Python库。 - 基于现有镜像构建:可以在已有的镜像基础上进行修改来创建新的镜像。例如,从官方的MySQL镜像开始,通过添加自定义的配置文件或者插件来构建一个满足特定需求的MySQL镜像。
- 使用Dockerfile构建:Dockerfile是构建镜像的文本指令文件。它包含一系列指令,用于告诉Docker如何构建镜像。例如,
- 分层结构:
- Docker镜像采用分层结构。每一个指令(如
RUN、COPY等)在构建镜像时都会生成一个新的层。这种分层结构有很多好处,比如可以复用已有的层,当多个镜像基于相同的基础镜像构建时,它们可以共享基础层,从而节省磁盘空间。例如,多个基于Ubuntu基础镜像构建的应用镜像,只需要在服务器上存储一份Ubuntu基础层,不同的应用镜像只需要存储自己独有的层。
- Docker镜像采用分层结构。每一个指令(如
- 定义与概念:
-
Docker容器(Container)
- 定义与概念:
- Docker容器是从镜像创建出来的运行实例,是真正运行应用程序的地方。容器是独立运行的,可以把每个容器看作是一个隔离的小型操作系统环境。例如,在同一台服务器上可以同时运行多个容器,一个容器运行Web应用,另一个容器运行数据库应用,它们之间相互隔离,互不干扰。
- 启动与运行:
- 通过
docker run命令可以从镜像启动一个容器。例如,docker run -d -p 80:80 my_web_app_image这个命令会在后台(-d)启动一个容器,将容器内的80端口映射到主机的80端口(-p 80:80),其中my_web_app_image是之前构建好的Web应用镜像。容器启动后,就会按照镜像中的配置运行应用程序。
- 通过
- 生命周期管理:
- 包括启动(
docker start)、停止(docker stop)、重启(docker restart)、删除(docker rm)等操作。例如,docker stop container_id可以停止一个正在运行的容器,其中container_id是容器的唯一标识符,可以通过docker ps -a命令查看。
- 包括启动(
- 资源隔离与限制:
- 容器利用Linux内核的Namespaces和Cgroups技术实现资源隔离和限制。Namespaces提供了进程、网络、文件系统等资源的隔离,使得每个容器都有自己独立的资源视图。例如,每个容器都有自己独立的进程空间,容器内的进程ID在容器外部是不可见的。Cgroups用于控制容器对CPU、内存等资源的使用,比如可以限制一个容器最多只能使用主机一定比例的CPU或内存资源。
- 定义与概念:
-
Docker仓库(Repository)
- 定义与概念:
- Docker仓库用于存储和共享Docker镜像。它类似于代码仓库,是集中存放镜像的地方。仓库可以是公共的,也可以是私有的。
- 公共仓库:
- 如Docker Hub是最著名的公共Docker仓库,其中包含了大量由官方和社区提供的镜像。开发者可以通过
docker pull命令从公共仓库拉取镜像,例如docker pull mysql:latest可以从Docker Hub拉取最新版的MySQL镜像。这些公共镜像涵盖了各种操作系统、数据库、编程语言环境、工具软件等,方便开发者快速获取和使用。
- 如Docker Hub是最著名的公共Docker仓库,其中包含了大量由官方和社区提供的镜像。开发者可以通过
- 私有仓库:
- 企业或组织为了安全和隐私原因,通常会搭建自己的私有仓库来存储内部开发的镜像。例如,一个公司开发了一个自定义的Web应用,会将这个应用的镜像存储在公司内部的私有仓库中,只有授权的用户才能访问和使用这些镜像。可以使用工具如Docker Registry来搭建私有仓库,并且通过配置访问权限来确保镜像的安全性和可控性。
- 镜像标签与版本管理:
- 仓库中的镜像可以通过标签(Tag)进行版本管理。例如,一个镜像可以有标签
v1.0、v2.0等来表示不同的版本。标签有助于开发者区分不同版本的镜像,并且可以根据标签来拉取特定版本的镜像,如docker pull my_app_image:v2.0。
- 仓库中的镜像可以通过标签(Tag)进行版本管理。例如,一个镜像可以有标签
- 定义与概念:
对比虚拟机
-
资源利用效率方面
- Docker:
- 共享内核优势:Docker容器共享主机操作系统内核。这使得容器在资源占用上非常高效,特别是在磁盘空间和内存方面。因为不需要为每个容器安装完整的操作系统,一个容器镜像通常只有几十MB到几百MB大小。例如,一个简单的Node.js容器应用镜像可能只有100MB左右。在内存使用上,多个容器可以共享主机内存,相比虚拟机可以在相同的硬件资源下运行更多的应用。例如,在一台具有8GB内存的服务器上,可能可以同时运行几十个容器,而如果是虚拟机,由于每个虚拟机都需要独立的内存来运行操作系统和应用,可运行的数量会少很多。
- 启动速度快:Docker容器的启动速度极快,通常可以在几秒内完成启动。这是因为容器不需要像虚拟机那样进行完整的操作系统引导过程,如硬件检测、内核加载等。例如,在应对突发流量时,容器可以快速启动来处理请求,当流量过去后又可以快速停止,这种快速的伸缩能力能够有效利用资源。
- 虚拟机:
- 完整操作系统导致资源消耗大:虚拟机需要为每个虚拟机模拟一个完整的操作系统,包括内核。这导致虚拟机镜像文件较大,通常需要数GB的磁盘空间。例如,一个安装了Windows Server操作系统的虚拟机镜像可能就需要10GB以上。在内存使用方面,每个虚拟机都需要独立的内存来运行操作系统和应用,所以资源消耗较大。在相同的硬件资源下,可运行的虚拟机数量相对较少。
- 启动速度慢:虚拟机的启动过程相对复杂,需要进行完整的硬件初始化、操作系统加载等步骤,启动时间可能需要几分钟。这在需要快速响应的场景下,如处理突发流量,就显得不够灵活。
- Docker:
-
隔离性和安全性方面
- Docker:
- 基于内核的隔离机制:Docker通过Linux内核的Namespaces和Cgroups技术实现隔离。Namespaces提供了进程、网络、文件系统等资源的隔离,使得每个容器都有自己独立的资源视图。例如,每个容器有自己独立的进程空间,容器内的进程ID在容器外不可见。但这种隔离不是绝对的,因为容器共享内核,如果内核出现漏洞,可能会影响多个容器。
- 安全措施依赖配置和工具:要确保Docker容器的安全,需要进行复杂的安全配置,如设置合适的用户权限、网络访问控制、资源限制等。并且需要使用安全工具来扫描容器镜像和运行时环境,防止漏洞。例如,通过配置网络策略来防止容器之间的非预期网络访问。
- 虚拟机:
- 硬件级别的隔离:虚拟机是在硬件层面进行虚拟化,每个虚拟机都有自己独立的操作系统内核,这种隔离是基于硬件的,相对更加安全。例如,一个虚拟机的操作系统崩溃或被攻击,通常不会直接影响其他虚拟机。
- 安全管理相对简单:由于虚拟机之间的隔离性较强,在安全管理方面相对简单一些。例如,安全策略可以基于每个虚拟机独立设置,如防火墙规则、用户权限等。
- Docker:
-
可移植性和环境一致性方面
- Docker:
- 高度可移植:Docker容器将应用程序及其所有依赖打包在一起,形成一个独立的运行单元。这使得容器可以很方便地在不同的操作系统和云平台之间进行移植。只要目标平台支持Docker运行时,就可以轻松地将容器化的应用部署到该平台。例如,一个在本地Linux环境下开发和测试完成的容器化应用,可以无缝地部署到亚马逊AWS、微软Azure或谷歌云等云平台上。
- 环境一致性好:容器保证了应用在不同环境(如开发、测试、生产)中运行的一致性。因为容器包含了运行应用所需的一切,包括运行时环境、库、配置文件等。例如,一个Python Web应用的容器,无论在开发人员的本地机器还是在云端的生产服务器上,只要容器运行时环境相同,应用就能以相同的方式运行。
- 虚拟机:
- 可移植性受操作系统限制:虚拟机的可移植性相对较差。因为虚拟机包含了完整的操作系统,将虚拟机从一个平台移植到另一个平台可能会遇到操作系统兼容性问题。例如,将一个基于Windows Server的虚拟机从本地服务器移植到云平台,可能会遇到驱动程序不兼容、操作系统授权等问题。
- 环境一致性较难保证:在不同的虚拟机中,要保证环境一致性也比较复杂。因为每个虚拟机的操作系统安装和配置过程可能不同,即使安装了相同的应用,由于操作系统的差异(如不同的更新补丁、不同的系统配置),也可能导致应用运行情况不同。
- Docker:
-
应用场景和灵活性方面
- Docker:
- 适合微服务和CI/CD:在微服务架构中,每个微服务可以打包成一个容器独立部署,方便进行版本更新和扩展。例如,在一个电商系统中,用户服务、商品服务、订单服务等微服务可以分别打包成容器。在持续集成/持续交付(CI/CD)过程中,Docker可以提供一致的构建和测试环境,方便快速部署。例如,在代码提交后,可以快速构建容器进行测试,然后将测试通过的容器部署到生产环境。
- 轻量级和快速迭代:Docker的轻量级特性使得开发人员可以快速创建和销毁容器,用于测试不同的应用版本或配置。例如,在开发一个新的Web应用功能时,可以快速启动一个容器来测试,测试完成后可以立即销毁容器,不占用过多资源。
- 虚拟机:
- 适合运行复杂操作系统和传统应用:虚拟机适合运行那些对操作系统有特定要求的复杂应用,如一些企业级的大型软件,需要完整的操作系统环境来支持。例如,运行一些旧版本的企业资源规划(ERP)系统,这些系统可能依赖特定版本的Windows Server操作系统和复杂的硬件配置。
- 资源分配相对固定:虚拟机的资源分配相对固定,一旦创建,其CPU、内存等资源分配就相对稳定。这在一些需要稳定资源的场景下比较合适,但在需要灵活调整资源的场景下,不如Docker容器方便。例如,对于一个长期运行的数据库虚拟机,分配了固定的内存和CPU资源,不容易像容器那样快速地增加或减少资源。
- Docker:
namespace技术
-
定义与概念
- 资源隔离机制:Namespace(命名空间)是Linux内核提供的一种资源隔离技术。它的主要作用是将系统的全局资源进行划分,使得不同的进程组(例如容器)能够拥有独立的资源视图。这就好比在一个大型的公寓楼(操作系统)里,通过划分不同的房间(命名空间),每个房间里的住户(进程)都感觉自己拥有独立的一套设施,而不会受到其他房间的干扰。
-
主要的Namespace类型及其作用
- PID Namespace(进程ID命名空间)
- 进程隔离:PID Namespace用于隔离进程ID。在不同的PID Namespace中,进程可以有相同的ID。例如,在一个容器内部,进程ID从1开始计数,这个1与宿主机或其他容器中的进程ID 1没有任何关系。这使得每个容器内的进程就好像在一个独立的系统中运行,容器内的进程无法直接访问或影响其他容器中的进程。
- 应用场景示例:在一个多容器的应用环境中,如一个Web应用容器和一个数据库容器,每个容器内的进程在自己的PID Namespace里运行。这样,即使Web应用容器中的进程出现异常(如进程崩溃或占用过多资源),也不会影响数据库容器中的进程,因为它们处于不同的PID Namespace。
- Mount Namespace(文件系统挂载命名空间)
- 文件系统隔离:Mount Namespace允许每个容器拥有独立的文件系统挂载点。容器可以挂载自己的目录结构,对文件系统的挂载和卸载操作不会影响其他容器和宿主机的文件系统。例如,一个容器可以将一个本地目录或远程存储挂载到容器内的特定目录下,而这个挂载操作在其他容器和宿主机上是不可见的。
- 应用场景示例:在容器化的应用部署中,不同的容器可以根据自己的需求挂载不同的配置文件或存储卷。比如,一个配置管理容器可以挂载包含应用配置文件的目录,而一个数据存储容器可以挂载存储数据的卷,它们之间的文件系统挂载操作相互独立,互不干扰。
- Net Namespace(网络命名空间)
- 网络隔离:Net Namespace提供了独立的网络环境。每个容器在自己的Net Namespace中有独立的网络接口、IP地址、路由表等。这使得容器可以像独立的网络节点一样进行配置,如设置自己的网络协议、IP地址分配方式等。例如,一个容器可以配置为桥接模式,通过虚拟网桥与外部网络通信;另一个容器可以配置为主机模式,直接使用宿主机的网络接口。
- 应用场景示例:在微服务架构中,不同的微服务容器可能需要不同的网络配置。例如,一个用户认证微服务容器可能需要与外部的身份验证服务器通信,而一个内部数据处理微服务容器可能只需要在内部网络中进行通信。通过Net Namespace,这些微服务容器可以有各自独立的网络设置,确保网络通信的安全性和独立性。
- UTS Namespace(主机名和域名命名空间)
- 主机名和域名隔离:UTS Namespace允许每个容器有自己独立的主机名和域名。这对于容器的标识和网络通信中的主机识别非常重要。例如,一个容器可以设置自己的主机名为“web - app - container”,域名为“example.com”,这样在网络通信中,它就以这个独立的主机名和域名来进行标识,与其他容器和宿主机的主机名和域名区分开来。
- 应用场景示例:在分布式系统中,不同的容器可能需要以不同的主机名来进行服务发现和通信。例如,在一个容器集群中,通过UTS Namespace设置不同的主机名,可以方便地识别和管理各个容器,并且在容器之间进行基于主机名的网络通信时,不会出现混淆。
- IPC Namespace(进程间通信命名空间)
- 进程间通信隔离:IPC Namespace隔离了进程间通信的机制,如消息队列、共享内存等。这意味着不同的容器内的进程不能直接使用共享内存或消息队列进行通信,除非进行特殊的配置。例如,一个容器内的两个进程可以通过共享内存进行高效的数据交换,但这个共享内存在其他容器内是不可访问的。
- 应用场景示例:在安全要求较高的多容器环境中,通过IPC Namespace隔离进程间通信可以防止恶意进程跨容器进行非法的数据访问或干扰。例如,一个包含敏感数据处理的容器可以通过IPC Namespace确保其内部进程间通信的安全性,防止其他容器中的进程窃取数据或干扰处理过程。
- PID Namespace(进程ID命名空间)
-
在容器技术中的应用(以Docker为例)
- 构建隔离环境:Docker利用Namespace技术来构建容器的隔离环境。当启动一个Docker容器时,Docker会为容器创建一系列的Namespace,将容器内的进程与宿主机和其他容器的进程进行隔离。例如,为容器创建PID Namespace、Mount Namespace、Net Namespace等,使得容器在进程、文件系统、网络等方面都能独立运行,就好像是一个独立的小型操作系统。
- 资源管理与分配:通过Namespace和其他内核机制(如Cgroups)的配合,Docker可以有效地管理容器的资源。例如,在Net Namespace中,可以为容器分配独立的网络带宽;在Mount Namespace中,可以限制容器对文件系统的访问范围和权限,从而实现对容器资源的合理分配和管理,确保每个容器都能在安全、独立的环境中运行。
# 启动2个容器,验证namespace docker run -d --name ngx-1 -P nginx docker run -d --name ngx-2 -P nginx docker run -d --name ngx-3 -P nginx [root@www.yuchaoit.cn ~]$>docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 24fc96bec738 nginx "/docker-entrypoint.…" 5 seconds ago Up 3 seconds 0.0.0.0:32770->80/tcp, [::]:32770->80/tcp ngx-3 75992d57ab0e nginx "/docker-entrypoint.…" 8 seconds ago Up 7 seconds 0.0.0.0:32769->80/tcp, [::]:32769->80/tcp ngx-2 70ee33884604 nginx "/docker-entrypoint.…" 19 seconds ago Up 18 seconds 0.0.0.0:32768->80/tcp, [::]:32768->80/tcp ngx-1 [root@www.yuchaoit.cn ~]$>touch /我是宿主机.log [root@www.yuchaoit.cn ~]$>ls / bin boot dev home lib64 lost+found mnt proc run sbin.usr-is-merged srv tmp var bin.usr-is-merged cdrom etc lib lib.usr-is-merged media opt root sbin snap sys usr 我是宿主机.log [root@www.yuchaoit.cn ~]$> [root@www.yuchaoit.cn ~]$>docker exec ngx-1 ls /
# debian基础包 apt update && apt install procps iputils-ping net-tools -y # UTS 名称空间 [root@www.yuchaoit.cn ~]$>uname -a Linux www.yuchaoit.cn 6.8.0-40-generic #40-Ubuntu SMP PREEMPT_DYNAMIC Fri Jul 5 10:34:03 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux [root@www.yuchaoit.cn ~]$>docker exec ngx-1 uname -a Linux 70ee33884604 6.8.0-40-generic #40-Ubuntu SMP PREEMPT_DYNAMIC Fri Jul 5 10:34:03 UTC 2024 x86_64 GNU/Linux
容器网络
-
Docker网络基础概念
- 网络驱动(Network Drivers):Docker使用网络驱动来创建和管理网络。不同的网络驱动提供不同的网络功能和拓扑结构。例如,
bridge驱动是默认的网络驱动,用于创建桥接网络,使得容器可以通过虚拟网桥与外部网络通信;host驱动则使得容器直接使用主机的网络接口,容器和主机共享网络命名空间;none驱动会禁用容器的网络功能。 - 网络命名空间(Net Namespace):这是Linux内核提供的用于网络隔离的机制,在Docker中得到了应用。每个Docker容器都有自己独立的网络命名空间,这意味着容器有独立的网络接口、IP地址、路由表等。例如,一个容器可以在自己的网络命名空间中配置IP地址为
172.17.0.2,这个IP地址与主机和其他容器的网络命名空间中的IP地址相互独立。
- 网络驱动(Network Drivers):Docker使用网络驱动来创建和管理网络。不同的网络驱动提供不同的网络功能和拓扑结构。例如,
-
Docker网络模式
- 桥接模式(Bridge Mode)
- 工作原理:这是最常用的模式。在桥接模式下,Docker会创建一个虚拟网桥(通常是
docker0),连接到主机的物理网络接口。当启动一个容器时,容器会被连接到这个虚拟网桥,容器会获得一个与主机在不同网段的私有IP地址(通常是172.17.0.0/16或192.168.0.0/16等)。容器可以通过虚拟网桥与主机和外部网络进行通信。例如,主机的IP地址是192.168.1.100,容器的IP地址可能是172.17.0.2,容器可以通过虚拟网桥将数据包转发到主机的物理网络接口,进而与外部网络通信。 - 应用场景:适用于大多数需要与外部网络交互的容器应用,如Web服务器容器、数据库容器等。例如,在一个Web应用部署中,Web服务器容器通过桥接模式可以接收来自外部浏览器的请求,并将响应返回给外部网络。
- 工作原理:这是最常用的模式。在桥接模式下,Docker会创建一个虚拟网桥(通常是
- 主机模式(Host Mode)
- 工作原理:在主机模式下,容器直接使用主机的网络接口,容器和主机共享网络命名空间。这意味着容器的网络配置与主机完全相同,容器可以直接使用主机的IP地址进行通信。例如,如果主机的IP地址是
10.0.0.10,容器在主机模式下也使用10.0.0.10这个IP地址进行通信,容器中的网络服务端口直接暴露在主机上。 - 应用场景:适用于一些对网络性能要求极高或者需要直接使用主机网络资源的应用。例如,在进行网络性能测试的容器应用中,使用主机模式可以减少网络虚拟化带来的性能损耗。
- 工作原理:在主机模式下,容器直接使用主机的网络接口,容器和主机共享网络命名空间。这意味着容器的网络配置与主机完全相同,容器可以直接使用主机的IP地址进行通信。例如,如果主机的IP地址是
- 无网络模式(None Mode)
- 工作原理:容器处于无网络模式时,不会进行任何网络配置,容器内的网络功能被禁用。这种模式下,容器无法与外部网络或其他容器进行通信,除非通过主机进行转发或者手动配置网络。
- 应用场景:适用于一些不需要网络功能的容器,如只进行本地数据处理或者计算任务的容器,通过禁用网络可以提高安全性和资源利用率。
- 桥接模式(Bridge Mode)
-
网络配置与管理
- 自定义网络创建:可以使用
docker network create命令创建自定义网络。例如,docker network create -d bridge my - network会创建一个名为my - network的桥接网络。在创建自定义网络时,可以设置网络的子网、网关、IP范围等参数。 - 容器连接到网络:通过
docker run命令的--network参数可以将容器连接到指定的网络。例如,docker run -d --network my - network my - container会将my - container容器连接到my - network网络中。连接到同一网络的容器之间可以直接通过容器名称进行通信,这是因为Docker会自动在容器的/etc/hosts文件中添加其他容器的名称和IP地址信息。 - 端口映射(Port - Mapping):在桥接模式下,为了使外部网络能够访问容器内的服务,可以使用端口映射。例如,
docker run -d -p 80:80 my - web - container会将容器内的80端口映射到主机的80端口,这样外部网络通过访问主机的80端口就可以访问到容器内的Web服务。 - 网络隔离与安全:可以通过网络策略来实现容器之间的网络隔离和安全防护。例如,使用
docker network命令可以设置容器之间的访问规则,限制某些容器只能访问特定的其他容器,或者禁止某些容器访问外部网络,从而提高容器网络的安全性。
- 自定义网络创建:可以使用
veth

-
容器中的
eth0接口- 概念和作用:在容器内部,
eth0通常是容器的网络接口。它就像是容器与外部世界进行网络通信的门户。例如,当容器中的应用程序(如Web服务器)需要发送和接收网络数据包时,这些数据包会通过eth0接口进出容器。在桥接网络模式下,eth0接口会连接到Docker创建的虚拟网桥,从而使容器能够与外部网络(包括宿主机和其他网络设备)进行通信。 - IP地址分配:
eth0接口会被分配一个IP地址,这个IP地址使得容器在网络中有一个独立的标识。例如,在常见的Docker桥接网络中,容器的eth0接口可能会被分配一个类似于172.17.0.2(这是一个私有IP地址)的地址。这个IP地址与宿主机的IP地址处于不同的网段,并且和其他容器的IP地址也是相互独立的,除非它们通过特定的网络配置(如自定义网络)共享相同的网段。 - 通信原理:当容器中的应用程序想要访问外部网络(如访问互联网上的某个网站或者与宿主机上的其他服务通信)时,数据会从应用程序通过
eth0接口发送出去。数据首先会到达Docker创建的虚拟网桥(如果是桥接模式),然后经过宿主机的网络接口转发到外部网络。相反,当外部网络的数据要发送到容器中时,数据会先到达宿主机,然后通过虚拟网桥转发到容器的eth0接口,最后被容器内的应用程序接收。
- 概念和作用:在容器内部,
-
宿主机的
veth接口(虚拟以太网接口)- 概念和与容器的关系:在Docker的网络模型中,
veth接口是一种虚拟以太网接口,它是宿主机与容器之间网络连接的关键部分。当Docker为容器创建网络时,会创建一对veth接口,其中一个端点在容器内部(连接到容器的eth0接口),另一个端点在宿主机上。这一对veth接口就像是一根虚拟的网线,将容器和宿主机连接起来,实现网络通信。 - 工作原理:在桥接模式下,宿主机上的
veth接口会连接到Docker创建的虚拟网桥(如docker0)。当容器通过eth0接口发送数据时,数据会通过veth接口对传输到宿主机的虚拟网桥,然后再从宿主机的物理网络接口发送到外部网络。从外部网络接收数据时,过程相反,数据先到达宿主机的物理网络接口,然后通过虚拟网桥和veth接口对传输到容器的eth0接口。 - 网络配置与可见性:宿主机上的
veth接口在网络配置中是可见的,可以通过一些网络工具(如ip命令)来查看。例如,使用ip a命令可以看到宿主机上的veth接口及其相关的网络信息,包括MAC地址、IP地址分配情况等。这些veth接口的名称通常是类似vethxxxx的形式,其中xxxx是一串随机的字符或数字。它们的配置和状态会根据容器的网络模式和具体的网络操作(如容器的启动、停止、网络连接的更改等)而变化。
- 概念和与容器的关系:在Docker的网络模型中,
cgroup
-
定义与基本概念
- 资源控制机制:Cgroup(Control Group)是Linux内核提供的一种用于控制和限制进程组资源使用的机制。在容器技术中,Cgroup发挥着至关重要的作用,它可以对容器所使用的各种资源(如CPU、内存、磁盘I/O、网络带宽等)进行精确的控制和分配。可以将Cgroup理解为一种资源管理工具,就像一个资源分配器,确保每个容器都能在合理的资源范围内运行,避免某个容器过度占用资源而影响其他容器或系统的正常运行。
-
Cgroup的主要功能和资源控制类型
- CPU资源控制
- CPU份额分配:可以通过Cgroup为容器分配CPU份额。例如,在一个有多容器运行的系统中,如果容器A被分配了1024的CPU份额,容器B被分配了2048的CPU份额,那么在CPU资源竞争时,容器B理论上可以获得两倍于容器A的CPU时间。这种份额分配方式可以根据容器的重要性或性能需求来合理分配CPU资源。
- CPU核心绑定:Cgroup还支持将容器的进程绑定到特定的CPU核心上。这在一些对性能要求极高且需要避免CPU缓存抖动等情况的应用场景中非常有用。例如,对于一个对实时性要求很高的高性能计算容器,可以将其进程绑定到特定的CPU核心,以确保其性能的稳定性和可预测性。
- 内存资源控制
- 内存使用限制:可以设置容器能够使用的最大内存量。例如,通过Cgroup配置一个容器最多只能使用2GB的内存。当容器内的应用程序尝试使用超过这个限制的内存时,系统可以根据预先配置的策略(如阻止进程继续分配内存、触发内存回收机制或者向管理员发出警告等)来处理。
- 内存交换空间控制:除了控制物理内存的使用,Cgroup还可以对容器使用的内存交换空间(swap)进行管理。例如,限制容器最多只能使用一定比例的内存交换空间,以防止容器过度依赖交换空间而导致系统性能下降。
- 磁盘I/O资源控制
- I/O带宽限制:Cgroup能够限制容器对磁盘I/O的带宽使用。例如,在一个存储密集型的多容器环境中,可以为每个容器分配一定的磁盘I/O带宽,确保容器之间不会因为过度竞争磁盘I/O资源而导致性能下降。可以设置每秒的字节数或者每秒的I/O操作次数等指标来控制容器的磁盘I/O使用。
- I/O优先级分配:类似于CPU份额分配,Cgroup也可以为容器分配磁盘I/O优先级。高优先级的容器在进行磁盘I/O操作时会比低优先级的容器更容易获得资源,从而保证重要容器的磁盘I/O性能。
- 网络带宽资源控制
- 入站和出站带宽限制:可以通过Cgroup限制容器的网络入站(接收数据)和出站(发送数据)带宽。例如,在一个有多容器提供网络服务的系统中,为了防止某个容器占用过多的网络带宽而影响其他容器的网络服务质量,可以使用Cgroup为每个容器设置合理的网络带宽限制,如限制一个容器的出站带宽为10Mbps,入站带宽为5Mbps。
- CPU资源控制
-
在容器技术中的应用(以Docker为例)
- 容器资源配置:当使用Docker启动一个容器时,可以通过相关参数来配置Cgroup对容器资源的控制。例如,使用
docker run命令的--cpu - shares参数可以设置容器的CPU份额,--memory参数可以设置容器的内存限制。这些参数使得管理员能够根据容器的实际需求和系统资源情况,为每个容器合理地分配资源。 - 系统资源管理和隔离:在一个多容器的环境中,Cgroup确保了容器之间的资源隔离。例如,即使某个容器出现异常情况(如内存泄漏或者CPU占用过高的程序),由于Cgroup的资源限制,这个容器也不会耗尽系统的所有资源,从而保证了其他容器的正常运行和系统的整体稳定性。
- 性能优化和资源利用效率提升:通过Cgroup对容器资源的精细管理,可以优化系统的资源利用效率。例如,根据容器的负载情况动态地调整资源分配,在容器负载较低时适当减少其资源分配,将资源分配给负载较高的容器,从而提高整个系统的性能和资源利用率。
- 容器资源配置:当使用Docker启动一个容器时,可以通过相关参数来配置Cgroup对容器资源的控制。例如,使用
容器管理工具
- Docker Compose
- 定义与用途:
- Docker Compose是一个用于定义和运行多容器Docker应用的工具。它允许用户通过一个YAML文件(
docker - compose.yml)来配置多个容器的应用,包括容器的启动顺序、网络连接、挂载卷等信息。这样可以方便地管理和部署由多个相互关联的容器组成的应用,例如一个包含Web服务器、数据库和缓存服务器的应用。
- Docker Compose是一个用于定义和运行多容器Docker应用的工具。它允许用户通过一个YAML文件(
- 主要功能和优势:
- 简单的配置文件格式:使用YAML格式的配置文件,易于理解和编写。例如,以下是一个简单的
docker - compose.yml文件,用于启动一个包含Web应用和MySQL数据库的应用:
- 简单的配置文件格式:使用YAML格式的配置文件,易于理解和编写。例如,以下是一个简单的
- 定义与用途:
version: '3'
services:
web:
build:./web
ports:
- "80:80"
depends_on:
- db
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: password
- 容器编排功能:可以定义容器之间的依赖关系,如
depends_on字段用于指定容器启动的顺序。在上面的例子中,web容器会在db容器启动之后再启动。同时,它还可以自动创建网络,使得容器之间能够相互通信,并且可以挂载数据卷,方便数据的持久化。 - 适合开发和测试环境:在开发和测试过程中,开发人员可以快速地使用Docker Compose启动整个应用环境,并且可以通过修改配置文件轻松地对应用进行调整。例如,更改容器的端口映射、添加或删除服务等操作都非常方便。
-
Kubernetes(K8s)
- 定义与用途:
- Kubernetes是一个开源的容器编排平台,用于自动化容器的部署、扩展和管理。它提供了一个强大的容器管理框架,能够在集群环境中高效地运行和调度大量的容器。Kubernetes主要用于大规模的生产环境,如处理企业级应用、微服务架构等复杂的容器化应用场景。
- 主要功能和优势:
- 自动调度和资源管理:Kubernetes可以根据容器的资源需求(如CPU、内存等)和集群中节点的资源情况,自动将容器调度到合适的节点上运行。例如,当有新的容器需要启动时,它会寻找具有足够空闲资源的节点来运行这个容器,并且可以动态地调整容器的资源分配。
- 高可用性和容错性:通过副本机制(如ReplicaSet和Deployment),Kubernetes可以确保应用的高可用性。例如,一个Web服务可以有多个副本,当其中一个副本出现故障时,Kubernetes会自动创建新的副本来替换故障的副本,保证服务的持续运行。同时,它还可以进行滚动更新,在更新应用时不会导致服务中断。
- 服务发现和负载均衡:Kubernetes提供了内置的服务发现机制,容器之间可以通过服务名称进行通信。例如,一个后端服务可以通过服务名称被前端服务发现并访问。并且它还支持多种负载均衡策略,如基于轮询、基于权重等,以确保流量均匀地分配到多个容器副本上。
- 定义与用途:
-
Rancher
- 定义与用途:
- Rancher是一个开源的企业级容器管理平台,它提供了一个直观的用户界面,用于管理容器和Kubernetes集群。Rancher可以简化容器的部署、管理和监控,尤其适合企业用户和需要大规模管理容器的场景。
- 主要功能和优势:
- 多集群管理:Rancher可以同时管理多个Kubernetes集群,无论是在本地数据中心还是在云端。例如,一个企业可能有多个不同的业务部门,每个部门都有自己的Kubernetes集群,Rancher可以统一管理这些集群,包括集群的创建、配置、升级等操作。
- 应用商店和模板:它提供了一个应用商店,里面包含了各种预构建的应用模板。用户可以通过应用商店快速地部署常见的应用,如WordPress、Jenkins等。这些模板可以简化应用的部署过程,并且可以根据用户的需求进行定制。
- 用户权限管理和安全策略:Rancher具有强大的用户权限管理功能,可以根据不同的用户角色和权限级别来控制对容器和集群的访问。同时,它还可以设置安全策略,如网络策略、访问控制列表等,以确保容器的安全运行。
- 定义与用途:
-
Containerd
- 定义与用途:
- Containerd是一个轻量级的容器运行时,它专注于容器的生命周期管理,包括容器的创建、启动、停止和删除等操作。它是Docker的底层容器运行时,也可以独立于Docker使用,并且被许多其他容器管理工具和平台所采用。
- 主要功能和优势:
- 高性能和低资源占用:Containerd具有高效的容器启动和运行性能,并且在资源占用方面比较低。这使得它适合在资源有限的环境中运行大量的容器。例如,在一些边缘计算设备或者物联网设备中,Containerd可以很好地管理容器的运行。
- 标准的容器运行时接口:它提供了一个符合OCI(Open Container Initiative)标准的容器运行时接口,这使得它可以与各种上层的容器管理工具和平台兼容。例如,Kubernetes可以通过这个接口来调用Containerd来运行容器,从而实现容器的管理和调度。
- 定义与用途:
Docker优势
-
高效的资源利用
- 轻量级特性
- 共享内核节省空间:Docker容器共享主机操作系统内核,与传统虚拟机相比,不需要为每个容器安装完整的操作系统。这使得容器在磁盘空间占用上非常小,通常一个容器镜像可能只有几十MB到几百MB大小。例如,一个简单的Node.js容器应用,其镜像大小可能只有100MB左右,相比虚拟机镜像(可能需要数GB),大大节省了磁盘存储资源。
- 高效的内存使用:容器在内存使用方面也更加高效,因为没有虚拟机那样的额外操作系统开销。多个容器可以在同一台主机上共享内存资源,并且可以根据实际需求灵活分配。例如,在一台具有8GB内存的服务器上,可以同时运行更多的容器;而如果使用虚拟机,由于每个虚拟机都需要独立的内存来运行操作系统和应用,可运行的数量会少很多。
- 快速启动和停止
- 秒级启动响应迅速:Docker容器的启动速度极快,通常可以在几秒内完成启动。这是因为容器不需要像虚拟机那样进行完整的操作系统引导过程,如硬件检测、内核加载等。例如,在应对突发的流量高峰时,如电商平台的促销活动,容器可以快速启动来处理增加的请求。当流量高峰过去后,这些容器又可以快速停止,释放资源,这种快速的伸缩能力能够有效地应对业务的动态变化。
- 轻量级特性
-
高度的可移植性
- 跨平台运行能力
- 操作系统无关性:Docker容器将应用程序及其所有依赖打包在一起,形成一个独立的运行单元。这使得容器可以很方便地在不同的操作系统和云平台之间进行移植。只要目标平台支持Docker运行时,就可以轻松地将容器化的应用部署到该平台。例如,一个在本地Linux环境下开发和测试完成的容器化应用,可以无缝地部署到亚马逊AWS、微软Azure或谷歌云等云平台上。
- 环境一致性保证:容器保证了应用在不同环境(如开发、测试、生产)中运行的一致性。因为容器包含了运行应用所需的一切,包括运行时环境、库、配置文件等。例如,一个Python Web应用的容器,无论在开发人员的本地机器还是在云端的生产服务器上,只要容器运行时环境相同,应用就能以相同的方式运行,避免了因环境差异导致的“在我机器上可以运行”(It works on my machine)的问题。
- 跨平台运行能力
-
出色的应用隔离性
- 基于内核的隔离机制
- 资源隔离保障安全:Docker通过Linux内核的Namespaces和Cgroups技术实现隔离。Namespaces提供了进程、网络、文件系统等资源的隔离,使得每个容器都有自己独立的资源视图。例如,每个容器有自己独立的进程空间,容器内的进程ID在容器外不可见。这种隔离可以防止容器之间相互干扰,保障应用的安全性和稳定性。
- 灵活的资源控制:Cgroups用于控制容器对CPU、内存等资源的使用,比如可以限制一个容器最多只能使用主机一定比例的CPU或内存资源。这使得在多容器环境下,可以根据容器的重要性和负载情况,合理地分配资源,避免某个容器过度占用资源。
- 基于内核的隔离机制
-
方便的版本控制与更新管理
- 精确的版本管理
- 镜像版本标识清晰:Docker通过镜像来打包应用,这些镜像可以进行版本控制。就像代码仓库中的代码版本管理一样,容器镜像也可以有版本号、标签等标识。例如,开发团队可以为每个版本的应用容器镜像打上标签,如
v1.0、v2.0等,方便跟踪和管理应用的不同版本。当需要回滚应用版本时,可以根据标签快速地找到并部署之前的版本。
- 镜像版本标识清晰:Docker通过镜像来打包应用,这些镜像可以进行版本控制。就像代码仓库中的代码版本管理一样,容器镜像也可以有版本号、标签等标识。例如,开发团队可以为每个版本的应用容器镜像打上标签,如
- 轻松的更新部署
- 简单的更新流程:在更新应用时,只需构建新的容器镜像,并将其部署到运行环境中即可。与传统的应用更新方式相比,容器更新更加方便和安全。例如,在一个微服务架构的系统中,更新一个服务的容器镜像,只需要将新的镜像推送到容器运行环境中,通过容器编排工具(如Kubernetes)可以控制更新的策略,如滚动更新(逐步替换旧容器为新容器),这样可以在不中断服务的情况下完成应用的更新。
- 精确的版本管理
-
对微服务架构的良好支持
- 独立部署和扩展便利
- 微服务容器化独立运行:在微服务架构中,每个微服务可以打包成一个独立的容器进行部署。不同的微服务可以使用不同的技术栈,并且可以独立地进行开发、测试、部署和扩展。例如,在一个电商系统中,用户服务、商品服务、订单服务等微服务可以分别构建成Docker容器。当用户服务的流量增加时,可以单独对用户服务的容器进行扩展,如增加容器数量,而不会影响其他微服务的运行。
- 服务发现和编排集成优势
- 高效的服务通信与管理:容器编排工具(如Kubernetes)与Docker容器紧密配合,能够实现微服务之间的高效服务发现和编排。容器可以通过内置的服务发现机制轻松地找到其他容器并进行通信。例如,在一个分布式的微服务系统中,订单服务容器可以通过服务发现机制找到用户服务容器并获取用户信息,实现业务功能,并且可以根据业务需求动态地调整微服务容器的数量、位置等。
- 独立部署和扩展便利
Docker安装
apt update
root@www.yuchaoit.cn:~# apt install docker.io -y
root@www.yuchaoit.cn:~# docker version
Client:
Version: 24.0.7
API version: 1.43
Go version: go1.21.1
Git commit: 24.0.7-0ubuntu2~22.04.1
Built: Wed Mar 13 20:23:54 2024
OS/Arch: linux/amd64
Context: default
Server:
Engine:
Version: 24.0.7
API version: 1.43 (minimum version 1.12)
Go version: go1.21.1
Git commit: 24.0.7-0ubuntu2~22.04.1
Built: Wed Mar 13 20:23:54 2024
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.7.12
GitCommit:
runc:
Version: 1.1.12-0ubuntu2~22.04.1
GitCommit:
docker-init:
Version: 0.19.0
GitCommit:
# 出现网桥
root@www.yuchaoit.cn:~# ifconfig docker0
docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:8c:85:c7:c2 txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
# 看容器信息
root@www.yuchaoit.cn:~# docker info
docker镜像加速
https://cr.console.aliyun.com/cn-beijing/instances
https://ms9glx6x.mirror.aliyuncs.com
-
什么是Docker镜像加速
- 定义:Docker镜像加速是一种通过配置来提高拉取Docker镜像速度的技术。由于Docker镜像通常存储在官方或第三方的镜像仓库(如Docker Hub)中,这些仓库的服务器可能位于国外或者网络带宽有限,在拉取镜像时可能会出现速度慢甚至拉取失败的情况。镜像加速服务通过在国内或离用户更近的服务器上缓存镜像,使用户能够更快地拉取所需的镜像。
-
使用国内镜像加速器的方法
- 以Docker官方中国镜像加速服务为例
- 注册与获取加速器地址:用户需要在Docker官方网站(https://www.docker.com/)或者相关的云服务商平台(如阿里云、腾讯云等,如果它们提供了Docker镜像加速服务)进行注册或登录,然后获取专属的镜像加速器地址。这个地址通常是一个URL,类似于
https://xxxx.mirror.aliyuncs.com(以阿里云为例)。 - 配置Docker守护进程(daemon):
- 在Linux系统(以Ubuntu为例)中,需要编辑
/etc/docker/daemon.json文件(如果该文件不存在,可以创建一个新的)。在文件中添加以下内容(将your - accelerator - address替换为实际获取的加速器地址):
- 在Linux系统(以Ubuntu为例)中,需要编辑
- 注册与获取加速器地址:用户需要在Docker官方网站(https://www.docker.com/)或者相关的云服务商平台(如阿里云、腾讯云等,如果它们提供了Docker镜像加速服务)进行注册或登录,然后获取专属的镜像加速器地址。这个地址通常是一个URL,类似于
- 以Docker官方中国镜像加速服务为例
{
"registry - mirrors": ["your - accelerator - address"]
}
-
保存文件后,重启Docker服务,可以使用命令
sudo systemctl restart docker。之后,当使用docker pull命令拉取镜像时,Docker就会通过配置的加速器来获取镜像,从而提高拉取速度。 -
使用云服务商提供的镜像加速服务(以阿里云为例)
- 开通服务并获取配置信息:登录阿里云控制台,在容器服务相关的板块(如容器镜像服务)中开通镜像加速服务。开通后,会得到一个类似
https://xxxx.mirror.aliyuncs.com的加速地址以及详细的配置步骤。 - 配置Docker客户端(与上述守护进程配置类似但针对客户端):
- 对于Linux系统,同样是编辑
/etc/docker/daemon.json文件,添加加速地址到registry - mirrors字段。 - 在Windows系统中,右键点击系统托盘中的Docker图标,选择“Settings”(设置),在“Docker Engine”(Docker引擎)选项卡下的“Registry mirrors”(注册镜像)部分添加加速地址,然后点击“Apply & Restart”(应用并重启)来使配置生效。
- 在Mac系统中,点击菜单栏中的Docker图标,选择“Preferences”(偏好设置),在“Daemon”(守护进程)选项卡下的“Registry mirrors”(注册镜像)区域添加加速地址,接着点击“Apply & Restart”来完成配置。
- 对于Linux系统,同样是编辑
- 开通服务并获取配置信息:登录阿里云控制台,在容器服务相关的板块(如容器镜像服务)中开通镜像加速服务。开通后,会得到一个类似
- 镜像加速的原理
- 缓存机制:镜像加速服务提供商在其服务器上建立了镜像缓存。当用户第一次拉取某个镜像时,加速服务会从原始的镜像仓库(如Docker Hub)将镜像拉取到自己的缓存服务器。之后,当其他用户拉取相同的镜像时,就可以直接从缓存服务器获取,避免了从原始仓库拉取可能遇到的网络延迟、带宽限制等问题。
- 分布式存储与优化网络路径:这些缓存服务器通常采用分布式存储系统,能够更高效地存储和分发镜像。并且,镜像加速服务会根据用户的地理位置等因素,选择最优的网络路径来提供镜像。例如,在国内的镜像加速服务会通过国内的数据中心和高速网络线路来传输镜像,减少了数据传输的跳数和距离,从而提高了传输速度。
自 2024-06-06 开始,国内的 Docker Hub 镜像加速器相继停止服务,可选择为 Docker daemon 配置代理或自建镜像加速服务。
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://docker.m.daocloud.io"
]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
# 2024-11-4 实测,daocloud还可以用
root@www.yuchaoit.cn:~#
root@www.yuchaoit.cn:~# docker info |grep -A 5 -i registry
Registry Mirrors:
https://docker.m.daocloud.io/
Live Restore Enabled: false
root@www.yuchaoit.cn:~# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
a480a496ba95: Pull complete
f3ace1b8ce45: Pull complete
11d6fdd0e8a7: Pull complete
f1091da6fd5c: Pull complete
40eea07b53d8: Pull complete
6476794e50f4: Pull complete
70850b3ec6b2: Pull complete
Digest: sha256:28402db69fec7c17e179ea87882667f1e054391138f77ffaf0c3eb388efc3ffb
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
最佳办法,上魔法
export https_proxy=http://192.168.110.214:26001;export http_proxy=http://192.168.110.214:26001;export all_proxy=socks5://192.168.110.214:26001
root@www.yuchaoit.cn:~# curl -I -L www.youtube.com
启动nginx
root@www.yuchaoit.cn:~# docker run -P -d --name yu-nginx nginx
981ad0dbd90a5a5c4ca7a3565b79b555ed6b42a349a0c8711d902c541dc14be4
root@www.yuchaoit.cn:~#
root@www.yuchaoit.cn:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
981ad0dbd90a nginx "/docker-entrypoint.…" 1 second ago Up 1 second 0.0.0.0:32768->80/tcp, :::32768->80/tcp yu-nginx
root@www.yuchaoit.cn:~#

容器常用操作
| 命令分类 | 命令 | 描述 | 示例 |
|---|---|---|---|
| 镜像操作 | docker pull |
从镜像仓库拉取镜像 | docker pull ubuntu:latest |
| 镜像操作 | docker push |
将本地构建的镜像推送到镜像仓库 | docker push my_image:v1.0 |
| 镜像操作 | docker build |
根据Dockerfile构建镜像 | docker build -t my_image.(.表示当前目录包含Dockerfile) |
| 镜像操作 | docker images |
查看本地已有的镜像列表 | docker images |
| 镜像操作 | docker rmi |
删除本地镜像 | docker rmi my_image:v1.0 |
| 容器操作 | docker run |
从镜像创建并启动容器 | docker run -d -p 80:80 nginx(-d后台运行,-p端口映射) |
| 容器操作 | docker start |
启动已停止的容器 | docker start container_id |
| 容器操作 | docker stop |
停止正在运行的容器 | docker stop container_id |
| 容器操作 | docker restart |
重新启动容器 | docker restart container_id |
| 容器操作 | docker ps |
查看正在运行的容器列表 | docker ps |
| 容器操作 | docker ps -a |
查看所有容器(包括已停止的)列表 | docker ps -a |
| 容器操作 | docker rm |
删除容器 | docker rm container_id |
| 容器操作 | docker exec |
在运行的容器中执行命令 | docker exec -it container_id bash(进入容器的bash环境) |
| 网络操作 | docker network create |
创建自定义网络 | docker network create -d bridge my_network |
| 网络操作 | docker network ls |
查看已有的网络列表 | docker network ls |
| 网络操作 | docker network rm |
删除网络 | docker network rm my_network |
| 网络操作 | docker connect |
将容器连接到网络 | docker connect container_id my_network |
| 存储操作 | docker volume create |
创建数据卷 | docker volume create my_volume |
| 存储操作 | docker volume ls |
查看已有的数据卷列表 | docker volume ls |
| 存储操作 | docker volume rm |
删除数据卷 | docker volume rm my_volume |
| 存储操作 | docker volume attach |
将数据卷附加到容器 | docker volume attach container_id my_volume |
| 系统操作 | docker system df |
查看Docker使用的磁盘空间情况 | docker system df |
| 系统操作 | docker system prune |
清理未使用的容器、镜像、网络和数据卷等 | docker system prune -a(-a表示全部清理) |
root@www.yuchaoit.cn:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 3b25b682ea82 4 weeks ago 192MB
root@www.yuchaoit.cn:~# docker save nginx -o /tmp/nginx.tar
root@www.yuchaoit.cn:~#
root@www.yuchaoit.cn:~# file /tmp/nginx.tar
/tmp/nginx.tar: POSIX tar archive
root@www.yuchaoit.cn:~#
root@www.yuchaoit.cn:~# tar -tf /tmp/nginx.tar
008e2c8c56289c0b4af588526246839724d0abea365febc180ebbe3b896f8e53/
008e2c8c56289c0b4af588526246839724d0abea365febc180ebbe3b896f8e53/VERSION
...
manifest.json
repositories
# 强制删除容器
root@www.yuchaoit.cn:~# docker rm -f `docker ps -aq`
981ad0dbd90a
# 强制删除镜像
root@www.yuchaoit.cn:~# docker rmi -f `docker images -qa`
# 导入镜像
root@www.yuchaoit.cn:~# docker load < /tmp/nginx.tar
98b5f35ea9d3: Loading layer [==================================================>] 77.83MB/77.83MB
b33db0c3c3a8: Loading layer [==================================================>] 117.9MB/117.9MB
63d7ce983cd5: Loading layer [==================================================>] 3.584kB/3.584kB
296af1bd2844: Loading layer [==================================================>] 4.608kB/4.608kB
8ce189049cb5: Loading layer [==================================================>] 2.56kB/2.56kB
6ac729401225: Loading layer [==================================================>] 5.12kB/5.12kB
e4e9e9ad93c2: Loading layer [==================================================>] 7.168kB/7.168kB
Loaded image: nginx:latest
root@www.yuchaoit.cn:~#
root@www.yuchaoit.cn:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 3b25b682ea82 4 weeks ago 192MB
# 创建且进入容器,结束自动删除
# 注意此操作,是覆盖容器原本的启动命令,而执行bash,你只是借用人家namespace了
root@www.yuchaoit.cn:~# docker run -i -t --rm nginx bash
root@f82fa575c2ff:/#
root@f82fa575c2ff:/#
root@f82fa575c2ff:/# ps aux
bash: ps: command not found
root@f82fa575c2ff:/#
root@f82fa575c2ff:/# ip
bash: ip: command not found
root@f82fa575c2ff:/#
root@f82fa575c2ff:/# nginx -V
nginx version: nginx/1.27.2
built by gcc 12.2.0 (Debian 12.2.0-14)
...

# 可以看出容器进程关系
root@www.yuchaoit.cn:~# pstree -s -p 4395 -h
# 由于覆盖nginx容器默认命令,执行了bash,没启动端口
root@www.yuchaoit.cn:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f82fa575c2ff nginx "/docker-entrypoint.…" 5 minutes ago Up 5 minutes 80/tcp laughing_bose
# 看容器端口映射情况
root@www.yuchaoit.cn:~# docker port f82
# 由于--rm参数,容器退出,看不到任何记录
root@www.yuchaoit.cn:~# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# 随机端口映射
root@www.yuchaoit.cn:~# docker run -P --rm nginx
# 注意-d参数,是否后台运行
root@www.yuchaoit.cn:~# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d6f8f984fdf1 nginx "/docker-entrypoint.…" 20 seconds ago Up 19 seconds 0.0.0.0:32770->80/tcp, :::32770->80/tcp objective_sammet
root@www.yuchaoit.cn:~#
root@www.yuchaoit.cn:~# docker port d6f
80/tcp -> 0.0.0.0:32770
80/tcp -> [::]:32770
# 指定端口映射
root@www.yuchaoit.cn:~# docker run -d -p 11888:80 --rm nginx
fac7d489c071a54ceef95d9e6e8fc44f48fc6badb10da5b82e0535ca44e57023
http://192.168.110.16:11888
# 修改容器内数据页面
root@www.yuchaoit.cn:~# docker exec -i -t fac bash
root@fac7d489c071:/#
root@fac7d489c071:/# echo 'www.yuchaoit.cn' > /usr/share/nginx/html/index.html
root@www.yuchaoit.cn:~# curl http://192.168.110.16:11888
www.yuchaoit.cn
#获取容器PID
root@www.yuchaoit.cn:~# docker inspect -f "{{.State.Pid}}" fac
5335
root@www.yuchaoit.cn:~# ps -ef |grep nginx
root 5335 5313 0 16:43 ? 00:00:00 nginx: master process nginx -g daemon off;
systemd+ 5377 5335 0 16:43 ? 00:00:00 nginx: worker process
systemd+ 5378 5335 0 16:43 ? 00:00:00 nginx: worker process
systemd+ 5379 5335 0 16:43 ? 00:00:00 nginx: worker process
systemd+ 5380 5335 0 16:43 ? 00:00:00 nginx: worker process
root 5715 2084 0 18:32 pts/1 00:00:00 grep --color=auto nginx
root@www.yuchaoit.cn:~#
制作docker镜像
- 容器没有独立内核
- Docker容器没有自己的内核。容器是基于宿主机操作系统内核运行的。它利用了Linux内核的特性(如Namespaces和Cgroups)来实现资源隔离和限制,但从本质上来说,容器共享宿主机的内核。
- 例如,当在一个Linux主机上运行多个Docker容器时,这些容器中的进程都是通过宿主机的内核来进行系统调用和资源管理。这就好比住在公寓里的居民(容器中的进程)共享公寓的基础设施(宿主机内核)来满足自己的生活需求(系统调用、资源分配等)。
- 共享内核的优势和影响
- 优势:
- 资源高效利用:由于不需要为每个容器安装独立的内核,容器在磁盘空间和内存占用等方面非常高效。一个容器镜像通常只有几十MB到几百MB大小,相比虚拟机(需要独立的内核和完整的操作系统)可以节省大量的磁盘空间。在内存使用上,多个容器共享宿主机内存,能够在相同的硬件资源下运行更多的应用。
- 启动速度快:容器的启动速度极快,通常可以在几秒内完成启动。这是因为容器不需要像虚拟机那样进行完整的操作系统引导过程,如硬件检测、内核加载等。共享内核使得容器在启动时只需要加载自己的应用程序和相关配置,就可以快速开始运行。
- 影响:
- 安全考虑:由于容器共享内核,如果宿主机内核存在安全漏洞,可能会影响到所有的容器。因此,在容器环境中,保持宿主机内核的安全性和及时更新非常重要。同时,需要合理配置容器的安全策略,如使用安全的用户权限、限制容器的资源访问等,以降低安全风险。
- 兼容性限制:容器对宿主机内核的版本和功能有一定的依赖。如果容器中的应用程序需要特定的内核功能或特性,而宿主机内核不支持,可能会导致应用无法正常运行。因此,在部署容器时,需要确保宿主机内核满足容器应用的要求。
- 优势:
# 制作业务镜像,和安装虚拟机一样,你得有基础操作系统,看你们公司如何选型
root@www.yuchaoit.cn:~# docker pull centos
Using default tag: latest
latest: Pulling from library/centos
a1d0c7532777: Pull complete
Digest: sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177
Status: Downloaded newer image for centos:latest
docker.io/library/centos:latest
root@www.yuchaoit.cn:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 3b25b682ea82 4 weeks ago 192MB
centos 7 eeb6ee3f44bd 3 years ago 204MB
centos latest 5d0da3dc9764 3 years ago 231MB
root@www.yuchaoit.cn:~#\
root@www.yuchaoit.cn:~# docker run -t -i centos:latest bash
[root@54921b228767 /]#
[root@54921b228767 /]# cat /etc/redhat-release
CentOS Linux release 8.4.2105
# 换源
curl -o /etc/yum.repos.d/centos8.repo https://mirrors.aliyun.com/repo/Centos-8.repo
[root@54921b228767 /]# ls /etc/yum.repos.d/
centos8.repo epel.repo
[root@54921b228767 /]#
[root@54921b228767 /]# yum install nginx -y
[root@54921b228767 /]# nginx -V
nginx version: nginx/1.14.1
built by gcc 8.2.1 20180905 (Red Hat 8.2.1-3) (GCC)
built with OpenSSL 1.1.1 FIPS 11 Sep 2018 (running with OpenSSL 1.1.1k FIPS 25 Mar 2021)
TLS SNI support enabled
configure arguments: --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --pid-path=/run/nginx.pid --lock-path=/run/lock/subsys/nginx --user=nginx --group=nginx --with-file-aio --with-ipv6 --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-http_stub_status_module --with-http_perl_module=dynamic --with-http_auth_request_module --with-mail=dynamic --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream=dynamic --with-stream_ssl_module --with-debug --with-cc-opt='-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-***-protection -fcf-protection' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -Wl,-E'
[root@54921b228767 /]#
# 安装常用运维工具
dnf install vim wget pcre pcre-devel zlib zlib-devel openssl openssl-devel iproute net-tools iotop -y
# 容器内应用需要前台启动,修改nginx的daemon功能
[root@54921b228767 /]# vim /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
daemon off;
# 定义网站页面
[root@54921b228767 /]# echo 'Yuchao website ,www.yuchaoit.cn' > /usr/share/nginx/html/index.html
# 退出容器即可,注意保留容器,别删了
root@www.yuchaoit.cn:~# docker ps -a |grep 549
54921b228767 centos:latest "bash" 8 minutes ago Exited (0) 7 seconds ago festive_kowalevski
# 提交容器为镜像
root@www.yuchaoit.cn:~# docker commit -a "yc_uuu@163.com" -m "my nginx-v1" 54921b228767 my-nginx:v1
sha256:bdbb717448e695b2f2f43d230b11d47d35589dbdffa76ed55146f1117679be8d
# 查看镜像
root@www.yuchaoit.cn:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
my-nginx v1 bdbb717448e6 8 seconds ago 391MB
# 此业务容器,可以使用了,发给其他机器也一样,无需任何部署,直接启动
root@www.yuchaoit.cn:~#
root@www.yuchaoit.cn:~# docker run -d -p 80:80 --name yuchao-nginx my-nginx:v1 nginx
-
容器生命周期与应用进程关联
- 在Docker容器中,容器的生命周期是和容器内的主进程(通常是应用程序的启动进程)紧密关联的。当容器启动时,Docker会启动容器内指定的主进程。如果这个主进程结束,Docker会认为容器的任务已经完成,从而自动停止容器。
- 例如,在一个运行简单Web服务器的容器中,如果Web服务器进程(如Nginx或Apache的主进程)作为前台进程启动,那么当这个进程正常运行时,容器就会保持运行状态。一旦Web服务器进程意外终止(比如由于应用程序错误或收到终止信号),容器也会随之停止。这就使得容器的运行状态能够真实地反映应用程序的运行状态。
-
后台进程可能导致容器提前退出或资源浪费
- 如果在容器内启动应用程序作为后台进程,容器可能会因为主进程(在容器启动命令执行完后就结束了)结束而立即退出。例如,在一个容器中,如果只是简单地运行一个脚本,这个脚本启动了一个后台服务后就结束了自身的执行,那么容器会认为它的主要任务已经完成而停止,导致后台服务也随之停止,这显然不是我们想要的结果。
- 另外,即使容器没有因为主进程结束而退出,由于容器的主要任务(主进程)已经完成,Docker可能无法正确地管理和监控容器内的资源使用情况,可能会导致一些资源(如CPU、内存等)无法被合理分配和回收,造成资源浪费。
-
容器编排和管理的需要
- 在容器编排系统(如Kubernetes)中,容器的健康检查通常是基于容器内主进程的状态来进行的。如果应用程序在容器内以后台方式运行,编排系统可能无法准确地判断容器内应用的真实运行状态,从而影响到诸如自动伸缩、故障恢复等功能的正常实施。
- 例如,在一个微服务架构中,容器编排系统需要根据各个微服务容器内应用的负载情况(通过监控主进程的资源使用等状态来判断)来决定是否要增加或减少容器的数量。如果应用以后台方式运行,编排系统可能会错误地认为容器已经空闲或者出现故障,进而做出错误的决策。

Dockerfile脚本
https://docs.docker.com/reference/dockerfile/
-
定义与概念
- Dockerfile是一个文本文件,它包含了一系列用于构建Docker镜像的指令。可以将其看作是一个构建镜像的“配方”或者“蓝图”。通过这些指令,Docker可以自动化地从一个基础镜像开始,逐步添加应用程序、配置文件、运行时环境等所需的组件,最终构建出一个完整的、可以用于运行容器的镜像。
-
主要指令介绍
- FROM:
- 这是构建镜像的起始指令,用于指定基础镜像。例如,
FROM ubuntu:latest表示以最新版本的Ubuntu镜像作为基础来构建新的镜像。基础镜像可以是操作系统(如Ubuntu、CentOS等),也可以是已经包含了特定软件栈(如Python、Node.js等)的镜像。选择合适的基础镜像非常重要,它决定了后续构建步骤的起点和环境。
- 这是构建镜像的起始指令,用于指定基础镜像。例如,
- RUN:
- 用于在构建镜像过程中执行命令。这些命令可以是安装软件包、配置系统等操作。例如,
RUN apt - update && apt - install - y nginx会在镜像构建时更新软件包列表并安装Nginx服务器。需要注意的是,每个RUN指令都会在镜像中创建一个新的层,过多不必要的RUN指令可能会导致镜像体积过大。
- 用于在构建镜像过程中执行命令。这些命令可以是安装软件包、配置系统等操作。例如,
- COPY和ADD:
- 这两个指令都用于将文件从宿主机复制到镜像中。
COPY指令相对简单,主要用于复制本地文件或目录。例如,COPY. /app会将当前目录下的所有内容复制到镜像中的/app目录下。ADD指令功能更强大一些,它除了可以复制本地文件外,还可以处理一些特殊情况,如从URL获取文件并复制到镜像中,但在大多数情况下,建议使用COPY指令,因为ADD指令在处理某些复杂情况(如自动解压文件等)时可能会产生意外的结果。
- 这两个指令都用于将文件从宿主机复制到镜像中。
- WORKDIR:
- 用于设置容器内的工作目录。例如,
WORKDIR /app会将容器内的工作目录设置为/app。之后的COPY、RUN等指令如果涉及到相对路径,都会以这个工作目录为基准。这个指令可以方便地组织容器内的文件结构,使得容器内的操作更加有序。
- 用于设置容器内的工作目录。例如,
- EXPOSE:
- 用于声明容器在运行时会监听的端口。例如,
EXPOSE 80表示容器内的应用程序会在80端口提供服务,但这只是一个声明,并没有实际将端口映射到宿主机上。在使用docker run命令启动容器时,还需要通过-p或-P参数来进行端口映射,使得外部可以访问容器内的服务。
- 用于声明容器在运行时会监听的端口。例如,
- CMD和ENTRYPOINT:
- 这两个指令都用于指定容器启动时要执行的命令。它们的区别在于,
CMD的指令可以在docker run命令启动容器时被覆盖,而ENTRYPOINT的指令相对更固定。例如,CMD ["python", "app.py"]表示容器启动时默认会运行python app.py命令。如果在docker run命令中指定了其他命令,那么CMD的命令就会被替换。而ENTRYPOINT更适合用于定义容器的主要执行程序,在docker run命令中添加的参数会作为参数传递给ENTRYPOINT指定的程序。
- 这两个指令都用于指定容器启动时要执行的命令。它们的区别在于,
- FROM:
-
构建镜像的流程
- 当执行
docker build命令并指定包含Dockerfile的目录时,Docker会按照Dockerfile中的指令顺序进行操作。首先,根据FROM指令拉取基础镜像(如果本地不存在)。然后,依次执行RUN、COPY等指令,每执行一个指令就会在基础镜像的基础上创建一个新的层,这些层会堆叠起来形成最终的镜像。最后,根据CMD或ENTRYPOINT指令设置容器启动时要执行的命令,完成镜像的构建。这个构建过程是分层的,这种分层结构使得镜像的复用和管理更加方便,例如,如果多个镜像基于相同的基础镜像构建,它们可以共享基础层,从而节省磁盘空间。
- 当执行
# Author: www.yuchaoit.cn
# 把你理解的,手工配置运维流程,写成脚本
FROM centos
MAINTAINER www.yuchaoit.cn
RUN rm -f /etc/yum.repos.d/*.repo
RUN curl -o /etc/yum.repos.d/centos8.repo https://mirrors.aliyun.com/repo/Centos-8.repo
RUN yum install nginx vim wget pcre pcre-devel zlib zlib-devel openssl openssl-devel iproute net-tools iotop -y
RUN echo 'Yuchao website ,www.yuchaoit.cn' > /usr/share/nginx/html/index.html
EXPOSE 80 443
CMD ["nginx","-g","daemon off;"]
#构建
root@www.yuchaoit.cn:~# docker build . -t my_centos_nginx:v1
root@www.yuchaoit.cn:~# docker images my_centos_nginx
REPOSITORY TAG IMAGE ID CREATED SIZE
my_centos_nginx v1 e897c31c946c 33 seconds ago 391MB
# 查看镜像层关系
root@www.yuchaoit.cn:~# docker history my_centos_nginx:v1
IMAGE CREATED CREATED BY SIZE COMMENT
e897c31c946c 48 seconds ago /bin/sh -c #(nop) CMD ["nginx" "-g" "daemon… 0B
5b56fe99cda0 48 seconds ago /bin/sh -c #(nop) EXPOSE 443 80 0B
d2c0b12d3078 48 seconds ago /bin/sh -c echo 'Yuchao website ,www.yuchaoi… 32B
24a073903008 48 seconds ago /bin/sh -c yum install nginx vim wget pcre … 160MB
199377d8c0e3 About a minute ago /bin/sh -c curl -o /etc/yum.repos.d/centos8.… 2.59kB
cdd61fae20b9 About a minute ago /bin/sh -c rm -f /etc/yum.repos.d/*.repo 0B
06ab627d64cc 2 minutes ago /bin/sh -c #(nop) MAINTAINER www.yuchaoit.cn 0B
5d0da3dc9764 3 years ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 3 years ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B
<missing> 3 years ago /bin/sh -c #(nop) ADD file:805cb5e15fb6e0bb0… 231MB
root@www.yuchaoit.cn:~#
# 运行容器
root@www.yuchaoit.cn:~# docker run -d -P my_centos_nginx:v1
581dd1f7e6b52723703df59c99fdfec9451c04f161ca7ec745d434b3cffb1f2f
root@www.yuchaoit.cn:~# docker run -d -P my_centos_nginx:v1
a12c7394b52ae5c8b726302fe6e7e5a830d8f65ad7d0f2ad55c8b6d868771543
root@www.yuchaoit.cn:~#
root@www.yuchaoit.cn:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a12c7394b52a my_centos_nginx:v1 "nginx -g 'daemon of…" 5 seconds ago Up 4 seconds 0.0.0.0:32774->80/tcp, :::32774->80/tcp, 0.0.0.0:32773->443/tcp, :::32773->443/tcp affectionate_yalow
581dd1f7e6b5 my_centos_nginx:v1 "nginx -g 'daemon of…" 6 seconds ago Up 5 seconds 0.0.0.0:32772->80/tcp, :::32772->80/tcp, 0.0.0.0:32771->443/tcp, :::32771->443/tcp pedantic_kapitsa
f1acb3f7f394 my-nginx:v1 "nginx" 11 minutes ago Up 11 minutes 0.0.0.0:80->80/tcp, :::80->80/tcp yuchao-nginx
root@www.yuchaoit.cn:~#
# 分别修改网页内容
root@www.yuchaoit.cn:~# docker exec affectionate_yalow bash -c "echo 'nginx by a12c7394b52a' > /usr/share/nginx/html/index.html"
root@www.yuchaoit.cn:~#
root@www.yuchaoit.cn:~# docker exec pedantic_kapitsa bash -c "echo 'nginx by pedantic_kapitsa'>/usr/share/nginx/html/index.html"

Harbor仓库
-
定义与概述
- Harbor是一个开源的企业级容器镜像仓库,用于存储、管理和分发Docker容器镜像。它提供了安全、可靠的镜像管理功能,能够帮助企业在内部网络或者云环境中更好地控制容器镜像的生命周期,包括镜像的上传、下载、复制、删除等操作,并且提供了用户认证、访问控制、镜像签名等安全机制。
-
主要功能
- 镜像存储与管理
- 多租户支持:Harbor支持多租户模式,不同的用户或者团队可以有自己独立的命名空间来存储和管理镜像。例如,在一个大型企业中,开发部门、测试部门和运维部门可以分别拥有自己的命名空间,如
dev - namespace、test - namespace和ops - namespace,每个命名空间下可以存储该部门相关的容器镜像,方便组织和管理。 - 镜像版本控制:提供了完善的镜像版本管理功能。每个镜像可以有多个版本标签,用户可以方便地查看、搜索和使用特定版本的镜像。例如,一个应用的容器镜像可以有版本标签如
v1.0、v2.0等,通过Harbor的界面或者API可以轻松地管理这些版本,包括回滚到旧版本。 - 镜像复制功能:可以在不同的Harbor仓库之间或者从外部仓库复制镜像。这在分布式环境或者多数据中心场景下非常有用。例如,企业可以将在开发环境中验证过的镜像从开发仓库复制到测试仓库或者生产仓库,确保镜像在不同环境中的一致性。
- 多租户支持:Harbor支持多租户模式,不同的用户或者团队可以有自己独立的命名空间来存储和管理镜像。例如,在一个大型企业中,开发部门、测试部门和运维部门可以分别拥有自己的命名空间,如
- 安全功能
- 用户认证与授权:支持多种用户认证方式,如LDAP(轻量级目录访问协议)、OIDC(开放身份验证连接)等。通过认证后,用户可以根据角色和权限访问不同的镜像资源。例如,管理员角色的用户可以对仓库进行全面的管理,包括创建和删除用户、命名空间等;普通用户可能只能上传和下载自己命名空间下的镜像。
- 镜像签名与验证:提供了镜像签名机制,确保镜像的完整性和来源可靠性。镜像创建者可以对镜像进行签名,使用者在下载和使用镜像时可以验证签名,防止镜像在传输过程中被篡改。这对于企业的安全和合规性要求非常重要,特别是在使用第三方或者外部来源的镜像时。
- 漏洞扫描:集成了漏洞扫描工具,可以对存储在仓库中的镜像进行安全扫描,检测镜像中是否包含已知的安全漏洞。扫描结果可以帮助用户及时发现和修复潜在的安全问题,避免在生产环境中部署存在安全风险的镜像。
- 与其他工具集成
- 与Docker和容器编排工具集成:可以无缝地与Docker客户端配合使用。用户可以通过配置Docker客户端,将镜像推送到Harbor仓库或者从Harbor仓库拉取镜像,就像使用Docker Hub一样方便。同时,它也能很好地与容器编排工具(如Kubernetes)集成,在Kubernetes的部署文件中可以指定使用Harbor仓库中的镜像,实现容器化应用的自动化部署。
- 与CI/CD工具集成:支持与持续集成/持续交付(CI/CD)工具(如Jenkins、GitLab CI/CD等)集成。在CI/CD流程中,容器镜像可以在构建完成后自动推送到Harbor仓库,并且可以根据不同的触发条件(如代码提交、测试通过等)进行自动化的镜像更新和部署,提高软件开发和交付的效率。
- 镜像存储与管理
-
安装与部署
- 环境要求:Harbor可以安装在Linux服务器上,一般推荐使用Ubuntu、CentOS等主流的Linux发行版。它对硬件资源有一定的要求,具体取决于要存储的镜像数量、用户数量等因素。通常需要足够的磁盘空间来存储镜像,以及适量的内存和CPU资源来保证服务的正常运行。
- 安装步骤:
- 下载安装包:可以从Harbor官方网站(https://goharbor.io/)下载适合的安装包,如
.tar.gz格式的压缩包。 - 配置文件修改:解压安装包后,需要修改
harbor.yml配置文件。在这个文件中,可以配置Harbor的各种参数,如访问地址、存储路径、用户认证方式等。例如,设置hostname为Harbor服务器的主机名或者IP地址,以便用户能够通过正确的地址访问仓库。 - 安装过程:运行安装脚本(通常是
install.sh)来完成Harbor的安装。安装过程中会拉取和安装所需的容器镜像,这些镜像用于运行Harbor的各个服务组件,如数据库、Web服务器、镜像存储服务等。安装完成后,就可以通过配置的访问地址访问Harbor仓库了。
- 下载安装包:可以从Harbor官方网站(https://goharbor.io/)下载适合的安装包,如
-
使用案例
- 企业内部开发与部署:在企业内部的软件开发和部署过程中,开发团队可以将构建好的容器镜像推送到Harbor仓库。测试团队从仓库中拉取镜像进行测试,测试通过后,运维团队可以将镜像部署到生产环境。通过Harbor的用户认证和权限控制功能,每个团队都可以在安全、合规的环境中完成自己的工作,并且可以方便地进行镜像的管理和版本控制。
- 混合云环境下的镜像管理:在混合云环境中,企业可能在本地数据中心和云平台都有容器化应用的部署。可以使用Harbor来统一管理这些环境中的镜像。例如,在本地数据中心构建的镜像可以复制到云平台的Harbor仓库,然后在云平台上进行部署,确保镜像在不同环境中的一致性和安全性。
https://github.com/goharbor/harbor/releases/download/v2.11.1/harbor-offline-installer-v2.11.1.tgz
https://github.com/goharbor/harbor/releases/tag/v1.8.0
https://storage.googleapis.com/harbor-releases/release-1.8.0/harbor-offline-installer-v1.8.0.tgz
# 官方安装
# 先配置
root@www.yuchaoit.cn:/opt/harbor# ./prepare
#安装
root@www.yuchaoit.cn:/opt/harbor# ./install.sh
admin
harbor_admin_password = Harbor12345

harbor管理镜像
root@www.yuchaoit.cn:~# systemctl daemon-reload
root@www.yuchaoit.cn:~# systemctl restart docker
root@www.yuchaoit.cn:/opt/harbor# cat /etc/docker/daemon.json
{
"registry-mirrors": [
"https://docker.m.daocloud.io"
]
,
"insecure-registries": ["192.168.110.16"]
}
# 修改tag
docker tag e897c31c946c 192.168.110.16/my-nginx/my_nginx:v1
docker push 192.168.110.16/my-nginx/my_nginx:v1


docker pull 192.168.110.16/my-nginx/my_nginx:v1


浙公网安备 33010602011771号