Docker和K8s面试题
1.Docker底层依托于linux怎么实现资源隔离的?
基于Namespace
的视图隔离:Docker利用Linux命名空间(Namespace
)来实现不同容器之间的隔离。每个容器都运行在自己的一组命名空间中、包括PID(进程)、网络、挂载点、IPC(进程间通信)等。这样容器中的进程只能看到自己所在命名空间内的进程、而不会影响其他容器中的进程。
基于cgroups
的资源隔离:cgroups
是Linux内核的一个功能、允许在进程组之间分配、限制和优先处理系统资源、如CPU、内存和磁盘I/O。
它们提供了一种机制、用于管理和隔离进程集合的资源使用、有助于资源限制、工作负载隔离以及在不同进程组之间进行资源优先处理。
2.Docker的工作原理是什么
docker是一个Client-Server
结构的系统、docker守护进程运行在宿主机上、守护进程从客户端接受命令并管理运行在主机上的容器。容器是一个运行时环境、这就是我们说的集装箱。
3.Docker的组成包含哪几大部分
一个完整的Docker有以下几个部分组成:
docker client
:客户端、为用户提供一系列可执行命令、用户用这些命令实现跟docker daemon交互
docker daemon:
守护进程、一般在宿主主机后台运行、等待接收来自客户端的请求消息;
docker image
:镜像、镜像run之后就生成为docker容器
docker container
:容器、一个系统级别的服务、拥有自己的IP和系统目录结构。运行容器前需要本地存在对应的镜像、如果本地不存在该镜像则就去镜像仓库下载。
docker 使用客户端-服务器(C/S)架构模式
、使用远程api来管理和创建docker容器。docker 容器通过docker 镜像来创建。容器与镜像的关系类似于面向对象编程中的对象与类。
4.Docker与传统虚拟机的区别什么?
传统虚拟机是需要安装整个操作系统的、然后再在上面安装业务应用、启动应用、通常需要几分钟去启动应用。而docker是直接使用镜像来运行业务容器的。传统虚拟机自带一个完整操作系统、而容器本身不带完整操作系统、容器的基础镜像实际上只包含了操作系统的核心依赖库和配置文件等必要组件。Docker 容器本质上只是个自带独立运行环境的特殊进程、底层用的其实是宿主机
Docker需要的资源更少。Docker在操作系统级别进行虚拟化、Docker容器和内核交互、几乎没有性能损耗,而虚拟机运行着整个操作系统、占用物理机的资源就比较多;
Docker更轻量:Docker的架构可以共用一个内核与其应用程序库、所占内存极小。同样的硬件环境、Docker运行的镜像数远多于虚拟机数量、对系统的利用率非常高;
与虚拟机相比:Docker隔离性更弱、Docker属于进程之间的隔离、虚拟机可实现系统级别隔离
Docker的安全性也更弱、Docker的租户root和宿主机root相同、一旦容器内的用户从普通用户权限提升为root权限、它就直接具备了宿主机的root权限,进而可进行无限制的操作。虚拟机租户root权限和宿主机的root虚拟机权限是分离的、并且虚拟机利用如intel的VT-d和VT-x等硬件隔离技术、这种技术可以防止虚拟机突破和彼此交互,而容器至今还没有任何形式的硬件隔离;
Docker的集中化管理工具还不算成熟、各种虚拟化技术都有成熟的管理工具。比如:VMWare vCenter提供完备的虚拟机管理能力
Docker对业务的高可用支持是通过快速重新部署实现的、虚拟化具备负载均衡,高可用、容错、迁移和数据保护等经过生产实践检验的成熟保障机制、VMware可承诺虚拟机99.999%高可用、保证业务连续性
虚拟化创建是分钟级别的、Docker容器创建是秒级别的、Docker的快速迭代性,决定了无论是开发、测试、部署都可以节省大量时间;
虚拟机可以通过镜像实现环境交付的一致性、但镜像分发无法体系化、Docker在Dockerfile中记录了容器构建过程、可在集群中实现快速分发和快速部署。
总结:
传统虚拟机是需要安装整个操作系统的、然后再在上面安装业务应用、启动应用、通常需要几分钟去启动应用。而docker是直接使用镜像来运行业务容器的。传统虚拟机自带一个完整操作系统、而容器本身不带完整操作系统、容器的基础镜像实际上只包含了操作系统的核心依赖库和配置文件等必要组件。Docker 容器本质上只是个自带独立运行环境的特殊进程、底层用的其实是宿主机
Docker资源占用少,启动速度快,隔离性更弱但安全性更高。
Docker的集中化管理工具不成熟,但创建和部署速度快。
5.Docker技术的三大核心概念是什么?
镜像:镜像是一种轻量级、可执行的独立软件包、它包含运行某个软件所需的所有内容、我们把应用程序和配置依赖打包好形成一个可交付的运行环境(包括代码、运行时需要的库、环境变量和配置文件等)、这个打包好的运行环境就是image镜像文件
容器:容器是基于镜像创建的、是镜像运行起来之后的一个实例、容器才是真正运行业务程序的地方。如果把镜像比作程序里面的类、那么容器就是对象。
镜像仓库:存放镜像的地方、研发工程师打包好镜像之后需要把镜像上传到镜像仓库中去、然后就可以运行有仓库权限的人拉取镜像来运行容器了
6.简单描述一下Dockerfile的整个构建镜像过程
首先创建一个目录用于存放应用程序以及构建过程中使用到的各个文件等
然后在这个目录下创建一个Dockerfile文件、一般建议Dockerfile的文件名就是Dockerfile
编写Dockerfile文件、编写指令,如使用FROM指令指定基础镜像、COPY指令复制文件、RUN指令指定要运行的命令、ENV设置环境变量、EXPOSE指定容器要暴露的端口、WORKDIR设置当前工作目录、CMD容器启动时运行命令、等等指令构建镜像;
Dockerfile编写完成就可以构建镜像了、使用 docker build -t 镜像名:tag .命令来构建镜像、最后一个点是表示当前目录、docker会默认寻找当前目录下的Dockerfile文件来构建镜像。如果不使用默认、可以使用-f 参数来指定dockerfile文件、如:docker build -t 镜像名:tag -f /xx/xxx/Dockerfile;
使用 docker build 命令构建之后、docker就会将当前目录下所有的文件发送给docker daemon、顺序执行Dockerfile文件里的指令、在这过程中会生成临时容器、在临时容器里面安装RUN指定的命令、安装成功后、docker底层会使用类似于docker commit 命令来将容器保存为镜像、然后删除临时容器、以此类推、一层层的构建镜像、运行临时容器安装软件、直到最后的镜像构建成功
总结:简单描述一下Dockerfile的整个构建镜像过程
创建目录和Dockerfile文件。
编写Dockerfile指令,如FROM、COPY、RUN、ENV、EXPOSE、WORKDIR、CMD。
使用docker build命令构建镜像。
使用docker run命令运行容器。
7.Dockerfile构建镜像出现异常如何排查?
首先Dockerfile是一层一层的构建镜像、期间会产生一个或多个临时容器、构建过程中其实就是在临时容器里面安装应用、如果因为临时容器安装应用出现异常导致镜像构建失败、这时容器虽然被清理掉了、但是期间构建的中间镜像还在、那么我们可以根据异常时上一层已经构建好的临时镜像、将临时镜像运行为容器、然后在容器里面运行安装命令找出具体的异常
总结:
Dockerfile是一层一层构建镜像、期间会产生临时容器。
如果构建失败、可以查看上一层构建好的临时镜像、运行容器并检查具体异常。
8.Dockerfile的基本指令有哪些?
FROM 指定基础镜像(必须为第一个指令、因为需要指定使用哪个基础镜像来构建镜像);
MAINTAINER 设置镜像作者相关信息,如作者名字、日期、邮件、联系方式等;
COPY 复制文件到镜像
ADD 复制文件到镜像(ADD 与 COPY 的区别在于、ADD 会自动解压tar、zip、tgz、xz等归档文件、而 COPY 不会。同时 ADD 指令还可以接一个url下载文件地址、一般建议使用COPY复制文件即可、文件在宿主机上是什么样子复制到镜像里面就是什么样子这样子这样比较好);
ENV 设置环境变量
EXPOSE 暴露容器进程的端口、仅仅是提示别人容器使用的哪个端口、没有过多作用
VOLUME 数据卷持久化、挂载一个目录
WORKDIR 设置工作目录、如果目录不在、则会自动创建目录
RUN 在容器中运行命令、RUN 指令会创建新的镜像层、RUN 指令经常被用于安装软件包
CMD 指定容器启动时默认运行哪些命令、如果有多个 CMD、则只有最后一个生效。另外CMD 指令可以被 docker run 之后的参数替换
ENTRYPOINT 指定容器启动时运行哪些命令、如果有多个 ENTRYPOINT、则只有最后一个生效。另外如果 Dockerfile中同时存在 CMD 和 ENTRYPOINT、那么 CMD 或 docker run 之后的参数将被当做参数传递给 ENTRYPOINT
总结:Dockerfile的基本指令有哪些?
FROM:指定基础镜像。
MAINTAINER:设置镜像作者信息。
COPY:复制文件到镜像。
ADD:复制文件并解压。
ENV:设置环境变量。
EXPOSE:暴露容器端口。
VOLUME:数据卷持久化。
WORKDIR:设置工作目录。
RUN:在容器中运行命令。
CMD:指定容器启动时默认运行命令。
ENTRYPOINT:指定容器启动时运行命令。
9.如何进入容器?使用哪个命令
进入容器有两种方法:使用docker attach或docker exec命令进入容器。
docker attach是attach到容器启动命令的终端。
docker exec是在容器内启动一个新的TTY终端。
🌟🌟🌟K8s面试题😊😊😊😊
10.什么是k8s?说出你的理解
K8s是kubernetes的简称、其本质是一个开源的容器编排系统、主要用于管理容器化的应用、其目标是让部署容器化的应用简单并且高效(powerful)。Kubernetes提供了应用部署、规划、更新、维护的一种机制。
说简单点:K8s就是一个编排容器的系统、一个它可以管理容器应用全生命周期的工具、从创建应用、应用的部署、应用提供服务、扩容缩容应用、应用更新、都非常的方便、而且还可以做到故障自愈
所以K8s是一个非常强大的容器编排系统
11.k8s中命名空间的作用是什么?
namespace是kubernetes系统中的一种非常重要的资源,namespace的主要作用是用来实现多套环境的资源隔离、或者说是多租户的资源隔离。
k8s通过将集群内部的资源分配到不同的namespace中、可以形成逻辑上的隔离、以方便不同的资源进行隔离使用和管理。不同的命名空间可以存在同名的资源、命名空间为资源提供了一个作用域
可以通过k8s的授权机制、将不同的namespace交给不同的租户进行管理、这样就实现了多租户的资源隔离、还可以结合集群的资源配额机制、限定不同的租户能占用的资源、例如CPU使用量、内存使用量等等来实现租户可用资源的管理
12.Pod是什么?
在kubernetes的世界中、k8s并不直接处理容器、而是使用多个容器共存的理念、这组容器就叫做Pod。
Pod是k8s中可以创建和管理的最小单元、是资源对象模型中由用户创建或部署的最小资源对象模型。其他的资源对象都是用来支撑pod对象功能的、比如pod控制器就是用来管理pod对象的、service或者ingress资源对象是用来暴露pod引用对象的、persistentvolume资源是为pod提供存储等等。
参考面试回答:
简而言之k8s不会直接处理容器、而是pod,Pod是k8s中可以创建和管理的最小单元、也是基本单元。包含一个或多个容器、这些容器共享网络和存储资源。
13.Pod的原理是什么?
在微服务的概念里、一般的一个容器会被设计为运行一个进程、除非进程本身产生了进程。
这样由于不能将多个进程聚集在同一个单独的容器中、所以需要一种更高级的结构将容器绑定在一起、并将它们作为一个单元进行管理。这就是k8s中pod的背后原理
Pod是一种结构为运行一个或多个进程、需要更高级的结构将容器绑定在一起进行管理。
14.Pod有什么特点?
每个pod就像一个独立的逻辑机器、k8s会为每个pod分配一个集群内部唯一的IP地址、所以每个pod都拥有自己的IP地址、主机名、进程等
一个pod可以包含1个或多个容器,1个容器一般被设计成只运行1个进程,1个pod只可能运行在单个节点上,即不可能1个pod跨节点运行,pod的生命周期是短暂,也就是说pod可能随时被消亡(如节点异常,pod异常等情况);
每一个pod都有一个特殊的被称为“根容器”的pause容器、也称init容器,pause容器对应的镜像属于K8s平台的一部分、除了pause容器,每个pod还包含一个或多个跑业务相关组件的应用容器;
一个pod中的容器共享network命名空间
一个pod里的多个容器共享pod IP,这就意味着1个pod里面的多个容器的进程所占用的端口不能相同,否则在这个pod里面就会产生端口冲突;既然每个pod都有自己的IP和端口空间,那么对不同的两个pod来说就不可能存在端口冲突;
应该将应用程序组织到多个pod中,而每个pod只包含紧密相关的组件或进程;
pod是K8s中扩容、缩容的基本单位、也就是说K8s中扩容缩容是针对pod而言而非容器
15.pause容器作用是什么
每个pod里运行着一个特殊的被称之为pause的容器,也称根容器,而其他容器则称为业务容器;创建pause容器主要是为了为业务容器提供Linux命名空间、共享基础:包括pid、icp、net等,以及启动init进程,并收割僵尸进程
这些业务容器共享pause容器的网络命名空间和volume挂载卷,当pod被创建时,pod首先会创建pause容器、从而把其他业务容器加入pause容器,从而让所有业务容器都在同一个命名空间中,这样可以实现网络共享。pod还可以共享存储,在pod级别引入数据卷volume,业务容器都可以挂载这个数据卷从而实现持久化存储。
16.Pod的重启策略有哪些?
pod重启容器策略是指针对pod内所有容器的重启策略、不是重启pod、其可以通过restartPolicy字段配置pod重启容器的策略。如下:
Always:当容器终止退出后、总是重启容器、默认策略就是Always
OnFailure:当容器异常退出、退出状态码非0时、才重启容器。
Never:当容器终止退出、不管退出状态码是什么、从不重启容器。
17.Pod的镜像拉取策略有哪几种?
pod镜像拉取策略可以通过imagePullPolicy字段配置镜像拉取策略、主要有3中镜像拉取策略。如下:
IfNotPresent:默认值、镜像在node节点宿主机上不存在时才拉取。
Always:总是重新拉取、即每次创建pod都会重新从镜像仓库拉取一次镜像。
Never:永远不会主动拉取镜像、仅使用本地镜像、需要你手动拉取镜像到node节点、如果node节点不存在镜像则pod启动失败
18.简单讲一下Pod创建过程
用户通过kubectl或其他api客户端工具提交需要创建的pod信息给apiserver
apiserver验证客户端的用户权限信息,验证通过开始处理创建请求生成pod对象信息、并将信息存入etcd,然后返回确认信息给客户端
apiserver开始反馈etcd中pod对象的变化,其他组件使用watch机制跟踪apiserver上的变动;
scheduler发现有新的pod对象要创建,开始调用内部算法机制为pod分配最佳的主机,并将结果信息更新至apiserver;
node节点上的kubelet通过watch机制跟踪apiserver发现有pod调度到本节点,尝试调用docker启动容器,并将结果反馈apiserver;
apiserver将收到的pod状态信息存入etcd中。
至此整个pod调度完成、创建完毕。
19.简单描述一下pod的终止过程
用户向apiserver发送删除pod对象的命令
apiserver中的pod对象信息会随着时间的推移而更新、在宽限期内(默认30s)、pod被视为dead
将pod标记为terminating状态
kubelet在监控到pod对象为terminating状态了就会启动pod关闭过程
endpoint控制器监控到pod对象的关闭行为时将其从所有匹配到此endpoint的server资源endpoint列表中删除
如果当前pod对象定义了PreStop钩子处理器、则在其被标记为terminating后会同步的方式启动执行;
pod对象中的容器进程收到停止信息;
宽限期结束后、若pod中还存在运行的进程、那么pod对象会收到立即终止的信息
kubelet请求apiserver将此pod资源的宽限期设置为0从而完成删除操作、此时pod对用户已不可见。
20.Pod的生命周期有哪几种
pod生命周期有5种状态(也称5种相位)如下:
Pending(挂起):API server已经创建pod、但是该pod还有一个或多个容器的镜像没有创建、包括正在下载镜像的过程
Running(运行中):Pod内所有的容器已经创建、且至少有一个容器处于运行状态、正在启动或正在重启状态
Succeeded(成功):Pod内所有容器均已退出、且不会再重启
Failed(失败):Pod内所有容器均已退出,且至少有一个容器为退出失败状态
Unknown(未知):某于某种原因apiserver无法获取该pod的状态、可能由于网络通行问题导致