1. docker的核心原理
Docker 的核心原理涉及到 Linux 内核中的一些特性和技术(例如 Namespaces 和 Cgroups)以及容器镜像的管理、容器的运行等方面的工作原理。
以下是 Docker 的核心原理的主要内容:
- 命名空间(Namespaces):Docker 使用命名空间技术来隔离容器之间的进程、网络、文件系统等资源,使得容器中的进程看起来是在独立的环境中运行。
- 控制组(Cgroups):Docker 使用 Cgroups 来限制容器的资源使用,包括 CPU、内存、I/O 等方面的资源。
- Union 文件系统:Docker 的容器镜像是通过 Union 文件系统来创建的,这使得容器的构建和部署更加高效,并且可以共享相同的底层文件系统。
- Docker 镜像:Docker 镜像是容器的基础,它是一个只读的模板,包含了文件系统、应用程序和它们的依赖关系。在创建容器时,Docker 使用镜像作为启动时的环境。
- 容器的运行:Docker 使用容器的主进程来保持容器的运行,一旦主进程退出,容器也会退出。容器内部的进程是由容器配置指定的。
总的来说,Docker 的核心原理主要涉及到了容器的隔离、资源控制、镜像管理和容器的运行。它利用 Linux 内核的一些特性和技术来实现容器的隔禆和资源控制,使得容器间彼此独立,并可以高效地利用系统资源。
2. docker与虚拟机有何不同

容器
- 共享内核和OS,隔离性弱!
- 计算/存储无损耗,无Guest OS内存开销(~200M)
- Docker容器镜象200~300M,且公共基础镜象实例化时可以共享
- Docker提供了容器应用镜象事实标准,OCI推动进一 步标准化
- 秒级创建(<10s)相当于建立索引
- 秒级(<1s,不含应用本身启动)
- 单机支持1000+容器密度很高,适合大规模的部署
虚拟化
- 隔离性强,有独立的GUEST OS
- 虚拟化性能差(>15%)
- 虚拟机镜像庞大(十几G~几十G), 且实例化时不能共享
- 虚拟机镜象缺乏统一标准
- 虚拟机创建慢(>2分钟)
- 虚拟机启动慢(>30s) 读文件逐个加载
- 资源虚拟化粒度低,单机10~100虚拟机
总结
- 资源利用率更高:一台物理机可以运行数百个容器,但一般只能运行数十个虚拟机
- 开销更小:不需要启动单独的虚拟机占用硬件资源
- 启动速度更快:可以在数秒内完成启动
3. docker容器的几种状态
- 已创建(Created):在已创建状态下,Docker 容器的文件系统已经被创建,但容器还没有被启动。
- 运行中(Running):容器正在运行,有一个活跃的进程正在内部执行任务。
- 已暂停(Paused):容器内的所有进程被暂停,并且容器文件系统的任何写操作也被暂停。容器处于已暂停状态时,其所有原始的进程都会持续保存在内存中。
- 已停止(Stopped):容器已经停止运行,但其相关的文件系统内容依然存在,可以通过 Docker run 重新运行容器。
4. docker的三大组件之间的关系
- Docker 镜像(Image):Docker 镜像是用于创建 Docker 容器的模板。它包含了操作系统的文件系统和必要的软件,以及用于运行容器的其他配置。镜像是只读的,可以被多个容器共享,并且可以作为模板来创建新的容器。
- Docker 容器(Container):Docker 容器是 Docker 镜像的可运行实例。当容器运行时,它会创建一个拥有自己文件系统、网络和运行时信息的隔离环境。容器可以被启动、停止、删除以及与其他组件进行交互。
- Docker 仓库(Repository):Docker 仓库是用于存储 Docker 镜像的地方。它可以分为公共仓库(如 Docker Hub)和私有仓库(如自建的镜像仓库)。仓库可以用于分享和分发镜像,无论是公共的还是私有的。
三大组件之间的关系
- 镜像用于创建容器,它保存了容器运行所需的所有文件和配置信息。
- 容器是镜像的运行实例,镜像以容器的形式运行并提供服务。
- 仓库作为集中存储 Docker 镜像的地方,可以用于分享、管理和存储镜像。
5. Dockerfile中的命令COPY和ADD命令有什么区别
COPY 命令:
- COPY 命令用于从构建上下文中复制文件或目录到镜像中。构建上下文是构建 Docker 镜像时的工作目录。一般情况下,COPY 只能复制本地文件或目录到镜像中的指定位置。
- 语法格式:
COPY <源路径> <目标路径>
- 例如:
COPY app.py /app/
,这将复制当前目录下的 app.py 文件到镜像的 /app/ 目录中。
ADD 命令:
- ADD 命令除了复制文件或目录,还支持复制 URL 地址或 tar 归档文件。这使得 ADD 比 COPY 功能更加强大。
- 语法格式:
ADD <源路径> <目标路径>
- 例如:
ADD https://example.com/file.tar.gz /tmp/
,这将从 URL 下载文件并解压到 /tmp/ 目录。
主要的区别在于 COPY 仅支持从构建上下文复制文件到镜像中,而 ADD 还支持复制远程文件和自动解压缩。根据最佳实践,通常会优先选用 COPY 命令,因为它是功能更清晰、更透明的选项,且不太容易出错。
6. Dockerfile中的cmd和run的区别
在 Dockerfile 中,CMD 和 RUN 是两个非常重要的指令,它们分别用于在容器启动时运行命令和在创建镜像过程中运行命令。
RUN 指令:
- RUN 指令用于在构建镜像时执行命令,例如安装软件包、下载文件、编译代码等。每个 RUN 指令都会在当前镜像基础上创建一个新的镜像层。
- 语法格式:
RUN <command>
。 - 例如:
RUN apt-get update && apt-get install -y nginx
。
CMD 指令:
- CMD 指令用于指定容器启动时要运行的默认命令。可以在 Dockerfile 中多次指定 CMD,但只有最后一个 CMD 指令会生效。如果在 docker run 命令中指定了要运行的命令,则会覆盖 Dockerfile 中的 CMD 指令。
- 语法格式:
CMD ["executable","param1","param2"]
或者CMD command param1 param2
。 - 例如:
CMD ["nginx", "-g", "daemon off;"]
。
因此,主要区别在于:
- RUN 用于构建镜像时执行命令,生成镜像的新层,影响镜像的构建过程。
- CMD 用于指定在容器启动时默认要运行的命令,可以被覆盖,并在 Dockerfile 中只会生效一次,影响容器启动时的行为。
7. Docker的优缺点
优点:
- 轻量级:Docker 容器可以在宿主机上使用相同的内核运行,因此比虚拟机更加轻量级,启动和停止速度更快,占用更少的系统资源。
- 隔离性:Docker 使用 Linux 命名空间和 cgroups 等技术来提供容器间的资源隔离,使得各个容器拥有独立的文件系统、进程空间和网络空间。
- 便携性:Docker 容器可以在不同的环境中运行,包括开发、测试和生产环境,保持环境一致性,简化部署流程。
- 高效的资源利用:Docker 提供了高效的资源利用和管理,可以更好地利用硬件和软件资源,能够更快速地部署和调整应用,提高应用的灵活性。
- 快速部署:Docker 镜像可以快速部署,即使在不同的环境中也可以迅速进行部署和启动。
缺点:
- 安全性问题:Docker 本身的安全问题和策略,容器之间的隔离不是绝对的。此外,由于使用了其他开源组件,也可能存在漏洞。
- 学习曲线:对于新手来说,Docker 的一些概念可能比较复杂,比如容器和镜像的概念,以及 Dockerfile 的编写等。
- 复杂网络配置:当涉及到复杂的网络配置、跨主机的容器交互等场景,可能需要更复杂的 Docker 网络配置。
- I/O 性能问题:在容器和宿主机之间的文件 I/O 性能上,可能会出现瓶颈,特别是在大规模的容器集群中。
总的来说,Docker 因其便捷、轻量、高效等特点,在应用开发和部署方面有明显的优势,但也会存在一些安全性和性能方面的挑战。
8. Docker容器意外退出,如何盘查和处理
当 Docker 容器出现意外退出时,可以通过以下步骤进行盘查和处理:
- 查看容器日志:首先查看容器的日志,了解容器退出的原因。使用
docker logs <container_id>
命令查看容器的日志输出,以便了解容器的运行状态和报错信息。 - 查看容器状态: 使用
docker ps -a
命令查看容器的状态和运行信息,以及检查容器的启动和退出时间。 - 排查容器运行环境:检查容器在运行时的环境,包括网络设置、文件系统、挂载的卷等。排查是否由于环境变化导致容器退出。
- 重启容器:如果容器出现意外退出,可以尝试使用
docker start <container_id>
命令重新启动容器,观察是否可以恢复正常。 - 分析日志:分析容器日志中的报错信息,排查可能的错误源。比如,查看是否有错误日志、异常占用资源等信息。
- 调整配置:根据容器日志和状态,调整容器的配置参数,例如内存、CPU、网络等。有时候是由于配置不合理导致容器退出。
- 更新镜像:如果容器中运行的应用或服务有更新版本,可以尝试更新镜像并重启容器。
- 排除硬件或软件问题:检查宿主机的硬件资源以及 Docker 引擎的运行状态,确保宿主机没有发生异常。
9. 有没有使用过docker搭建过什么服务,怎么搭建的
- 利用Docker数据卷,搭建不同版本的mysql
- 基于docker搭建web服务
10. k8s的控制平面和工作平面的区别
Kubernetes(K8s)中的控制平面和工作平面是 K8s 集群中的两个重要概念,具有不同的功能和角色。
- 控制平面 (Control Plane):
- 控制平面负责整个集群的管理和控制,包括调度、监控、集群状态管理等。
- 控制平面中的组件包括 API Server、Scheduler、Controller Manager 和 etcd 等。
- API Server 用于提供集群的 API 服务接口,Scheduler 用于调度 pod 到节点,Controller Manager 用于管理控制器并确保集群自愈能力,etcd 用于存储集群的状态和元数据信息。
- 工作平面 (Worker Nodes):
- 工作平面是运行容器化应用程序的主机节点,也称为节点(Node)。
- 节点上运行 kubelet 服务,负责与控制平面交互、维护容器的生命周期、组织容器的状态等。
- 另外,节点上还有一个叫做 kube-proxy 的组件,用于实现 K8s 服务的代理和负载均衡。
总体来说,控制平面是集群的“大脑”,用于控制和管理整个集群的配置和状态,而工作平面是集群中负责执行实际工作的节点。在 K8s 集群中,控制平面节点通常会运行核心控制和管理组件,而工作平面节点运行容器化应用并提供运行环境。
11. 两个平面分别包含哪些组件
控制平面和工作平面在 Kubernetes 集群中扮演着不同的角色,并包含不同的组件。
控制平面 (Control Plane):
控制平面主要负责集群的管理和控制,包括调度、监控、集群状态管理等。控制平面的组件通常包括以下内容:
- API Server:用于提供集群的 API 服务接口,是集群的前端接口。
- Scheduler:负责节点上容器的调度,将 Pod 放置在合适的节点上。
- Controller Manager:负责管理控制器,确保集群处于预期状态,并具备自愈能力。
- etcd:用于存储集群的状态和元数据信息,是集群的后端数据库。
工作平面 (Worker Nodes):
工作平面是运行容器化应用程序的主机节点,也称为节点(Node)。工作平面的组件通常包括以下内容:
- Kubelet:在每个节点都有一个 kubelet 服务,用于与控制平面交互、维护容器的生命周期、监控容器的状态等。
- Kube-proxy:负责实现 K8s 服务的代理和负载均衡。
- 容器运行时:常见的容器运行时包括 Docker、containerd 等,用于创建和管理容器。
这些组件共同构成了 Kubernetes 集群的核心,控制着集群的管理和调度,同时也包括了节点上容器的运行和服务代理。
12. 各个组件的原理详解
当谈到Kubernetes的各个组件的工作原理时,可以进行如下详细解释:
- API Server:API Server 是 Kubernetes 集群的前端接口,用于提供集群管理 API 服务。它接收来自 kubectl、kubelet、Controller Manager 和 Scheduler 等组件的 RESTful API 请求,然后对集群状态进行验证、处理和记录。它是一切操作的核心,负责集群的状态维护、服务发现以及对外提供接口。
- Scheduler:Scheduler 负责容器的调度和放置。当一个 Pod 被创建时,Scheduler 会根据节点的资源情况和 Pod 的调度策略决定将 Pod 放置在哪个节点上。Scheduler 是一个核心的调度器,根据 Pod 的资源需求和节点的资源情况制定调度策略,并将 Pod 放置在最合适的节点中。
- Controller Manager:它是 Kubernetes 控制器的核心组件,负责管理控制器循环的执行。控制器包括 Node Controller、Replication Controller、Endpoints Controller、Service Account and Token Controller 等,通过 Reconcile 循环来修正和调节资源的状态,确保集群处于预期的状态。控制器通过 API Server 监听资源和事件,并对资源状态进行调谐。
- etcd:etcd 是 Kubernetes 集群的后端数据库,用于存储集群的状态和元数据信息。etcd 是一个高可用的分布式键值存储系统,可以确保集群状态的一致性和持久性。Kubernetes 中的所有集群的状态信息,包括 Pod、Service、Configmaps,都存储在 etcd 中,并可以被写入和读取。
- Kubelet:Kubelet 是工作节点上的代理,它运行在每个节点上,负责管理容器的生命周期和节点的状态。它会从 API Server 中接收到调度的 Pod,根据调度的结果创建容器,并监控容器的状态和资源的使用情况,同时汇报节点的状态。
- Kube-proxy:Kube-proxy 负责为 Service 提供负载均衡和容器网络的代理管理,主要负责处理和重定向来自具有 Kubernets Service IP 的流量。它会根据 Service 的类型在节点上维护相应的规则和连接。
- 容器运行时(Container Runtime):容器运行时负责启动、停止和管理容器。在 Kubernetes 中,常见的容器运行时包括 Docker、containerd 等,它们提供了对容器的创建、管理和执行的功能。容器运行时利用了 Linux 命名空间和 Cgroups 等特性,实现容器之间的隔离和资源的控制。
13. 创建一个pod的流程
- 编写 Pod 描述文件:Pod 描述文件通常采用 YAML 或 JSON 格式进行编写,其中包括了 Pod 的元数据和规范。
# mypod.yaml
apiVersion: v1
kind: Pod
metadata:
name: mypod
labels:
app: myapp
spec:
containers:
- name: mycontainer
image: nginx
ports:
- containerPort: 80
- 通过 Kubectl 创建 Pod:将 Pod 描述文件应用到 Kubernetes 集群中,使用 kubectl apply 命令创建 Pod 对象。
kubectl apply -f mypod.yaml
- Kubernetes API Server 处理请求:Kubectl 将 Pod 描述文件发送到 Kubernetes API Server,API Server 验证 Pod 描述文件的合法性。
- 调度器进行调度:API Server 接收到合法的 Pod 描述文件后,将其发送给调度器,调度器根据 Pod 的资源需求和控制器的调度策略,将 Pod 调度到目标节点上。
- Kubelet 创建容器:被调度的节点上运行着 Kubelet 代理,它会根据自己的 Pod 配置,从 Docker Hub 或私有镜像仓库中下载相应的镜像,并创建 Pod 中的容器。
- Pod 运行:容器运行时启动容器,Pod 中的容器开始进行相关服务的初始化和运行。
- 状态更新:Pod 状态会被更新并同步给控制平面上的 API Server,API Server 将更新状态保存在 etcd 中。
- 监控和管理:Kubernetes 控制器和调度器会监控 Pod 的状态,并确保期望的 Pod 数量和服务状态达到预期。
14. 什么是k8s控制器
在 Kubernetes 中,控制器是一种负责管理集群中资源状态的控制器对象。它用于确保当前状态与期望状态一致,并根据集群的配置和策略来实现自动化操作。Kubernetes 提供了多种类型的控制器,用于管理不同类型的资源。
以下是 Kubernetes 中常见的一些控制器:
- ReplicaSet 控制器:确保运行指定数量的 Pod 副本,并在 Pod 发生故障或节点故障时自动进行恢复。它是 Deployment 和 StatefulSet 的基础。
- Deployment 控制器:管理应用的部署和更新,确保指定数量的 Pod 副本以及 Pod 配置的更新。
- StatefulSet 控制器:用于有状态服务的管理,确保指定数量的有状态的 Pod 副本并提供唯一标识。
- Job 和 CronJob 控制器:用于管理一次性任务(Job)和定时任务(CronJob)。
- Namespace 控制器:用于创建和管理 Namespace,确保 Namespace 中的资源符合预期状态。
- Service 控制器:确保 Service 对象能正常运行,提供服务发现和负载均衡功能。
- Ingress 控制器:用于管理 Ingress 资源,提供 HTTP 和 HTTPS 的路由规则,并暴露集群内的服务给集群外部。