13. Interview-Docker&k8s
1 什么是虚拟化?
虚拟化允许您在相同的硬件上运行两个完全不同的操作系统。每个客户操作系统都经历了引导,加载内核等所有过程。您可以拥有非常严格的安全性,例如,客户操作系统无法完全访问主机操作系统或其他客户端并搞砸了。
可以基于虚拟化方法如何模仿客户操作系统的硬件并模拟客户操作环境来对虚拟化方法进行分类。主要有三种类型的虚拟化:
- 仿真
- 半虚拟化
- 基于容器的虚拟化
2 物理机、虚拟机与容器有何不同?
Docker不是虚拟化方法。它依赖于实际实现基于容器的虚拟化或操作系统级虚拟化的其他工具。为此,Docker最初使用LXC驱动程序,然后移动到libcontainer现在重命名为runc。Docker主要专注于在应用程序容器内自动部署应用程序。应用程序容器旨在打包和运行单个服务,而系统容器则设计为运行多个进程,如虚拟机。因此,Docker被视为容器化系统上的容器管理或应用程序部署工具。
虚拟机&Docker image.png- 应用场景不同:
- 虚拟机更擅长资源调配,用于彻底隔离整个运行环境。例如,云服务提供商通常采用虚拟机技术隔离不同的用户。
- Docker解决问题是应用开发测试部署,通常用于隔离不同的应用,例如前端,后端以及数据库。
- 启动速度:
- Docker基于宿主机的系统内核,可以在几秒钟之内创建大量容器,启动速度上有数量级的差距。
- Docker是秒级,虚拟机是分钟级
- 隔离级别:
- 虚拟机是操作系统级,Docker是进程级别
- 隔离策略:
- 虚拟机是Hypervisor(虚拟机管理系统,利用它可以在主操作系统之上运行多个不同的从操作系统),Docker是CGroups
- 性能:
- 由于基于容器的虚拟化为主机增加了很少或没有开销,因此基于容器的虚拟化具有接近本机的性能
- 对于基于容器的虚拟化,与其他虚拟化不同,不需要其他软件。
- 主机上的所有容器共享主机的调度程序,从而节省了额外资源的需求。
3 容器内部机制?Docker底层实现原理?Docker架构?Docker网络实现?
大约在2006年,包括Google的一些员工在内的人们实现了名为命名空间的新的Linux内核级功能(不过这个想法早在FreeBSD中就已存在)。操作系统的一个功能是允许将全局资源(如网络和磁盘)共享到进程。如果将这些全局资源包装在命名空间中,以使它们仅对在同一命名空间中运行的那些进程可见,该怎么办?比如说,你可以获得一大块磁盘并将其放在命名空间X中,然后在命名空间Y中运行的进程无法查看或访问它。类似地,名称空间X中的进程无法访问分配给名称空间Y的内存中的任何内容。当然,X中的进程无法查看或与名称空间Y中的进程通信。这为全局资源提供了一种虚拟化和隔离。
这就是Docker的工作原理:每个容器都在自己的命名空间中运行,但使用与所有其他容器完全相同的内核。发生隔离是因为内核知道分配给进程的命名空间,并且在API调用期间确保进程只能访问其自己的命名空间中的资源。
Docker底层实现原理
-
命名空间(Namespaces):Linux内核特性
- pid:进程隔离
- net:网络隔离
- ipc
- mnt
- uts
- user
-
控制组(Control groups):Linux内核特性
- 主要用来对共享资源进行隔离、限制、审计等。只有能控制分配到容器的资源,才能避免当多个容器同时运行时的对系统资源的竞争。
- 控制组技术最早是由 Google 的程序员在 2006 年提出,Linux 内核自 2.6.24 开始支持。
-
Union 文件系统(Union file systems)
- 联合文件系统是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。
- 联合文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
- 不同 Docker 容器就可以共享一些基础的文件系统层,同时再加上自己独有的改动层,大大提高了存储的效率。
- Docker 中使用的 AUFS(AnotherUnionFS)就是一种联合文件系统。
AUFS
支持为每一个成员目录(类似 Git 的分支)设定只读(readonly)、读写(readwrite)和写出(whiteout-able)权限, 同时AUFS
里有一个类似分层的概念, 对只读权限的分支可以逻辑上进行增量地修改(不影响只读部分的)。 - Docker 目前支持的联合文件系统包括
OverlayFS
,AUFS
,Btrfs
,VFS
,ZFS
和Device Mapper
。
-
容器格式(Container format)
- Docker诞生之初 采用了
LXC
中的容器格式。 - 从 0.7 版本以后开始去除 LXC(Linux Container),转而使用自行开发的 libcontainer
- 从 1.11 开始,则进一步演进为使用 runC和 containerd
- Docker诞生之初 采用了
Docker架构
- Docker 采用了
C/S
架构,包括客户端和服务端。Docker 守护进程 (Daemon
)作为服务端接受来自客户端的请求,并处理这些请求(创建、运行、分发容器)。客户端和服务端既可以运行在一个机器上,也可通过socket
或者RESTful API
来进行通信。 - Docker 守护进程一般在宿主主机后台运行,等待接收来自客户端的消息。
- Docker 客户端则为用户提供一系列可执行命令,用户用这些命令实现跟 Docker 守护进程交互。
Docker网络实现
- Linux 上的网络命名空间
- 虚拟网络设备(特别是 veth pair)
- 首先,要实现网络通信,机器需要至少一个网络接口(物理接口或虚拟接口)来收发数据包;此外,如果不同子网之间要进行通信,需要路由机制。
- Docker 中的网络接口默认都是虚拟的接口。虚拟接口的优势之一是转发效率较高。 Linux 通过在内核中进行数据复制来实现虚拟接口之间的数据转发,发送接口的发送缓存中的数据包被直接复制到接收接口的接收缓存中。对于本地系统和容器内系统看来就像是一个正常的以太网卡,只是它不需要真正同外部网络设备通信,速度要快很多。
- Docker 容器网络就利用了这项技术。它在本地主机和容器内分别创建一个虚拟接口,并让它们彼此连通(这样的一对接口叫做
veth pair
)。
4 什么是Docker?Docker常用概念?
- Docker是一个容器化平台,它以容器的形式将您的应用程序及其所有依赖项打包在一起,以确保您的应用程序在开发,测试或生产的任何环境中无缝运行。
- Docker容器,将一个软件包装在一个完整的文件系统中,该文件系统包含运行所需的一切:代码,运行时,系统工具,系统库等可以安装在服务器上的任何东西。
- 这可以保证软件始终运行相同,无论其环境如何。
5 什么是Docker容器?
Docker容器包括应用程序及其所有依赖项,但与其他容器共享内核,作为主机操作系统上用户空间中的独立进程运行。Docker容器不依赖于任何特定的基础架构,可以在任何计算机,任何基础架构和任何云中运行。
6 什么是Docker镜像?
Docker镜像是Docker容器的源代码。换句话说,Docker镜像用于创建容器。使用build命令创建映像,并且在使用run启动时它们将生成容器。镜像存储在Docker注册表中,因为它们可能变得非常大,镜像被设计为由其他镜像层组成,允许在通过网络传输镜像时发送最少量的数据。镜像是类,容器是对象。
7 如何使用Docker构建与环境无关的系统?
有三个主要功能有助于实现这一目标:
- 存储卷(Volumes)
- 环境变量(Environment variable)注入
- 只读(Read-only)文件系统
8 什么是仓库(Repository)、仓库注册服务器(Registry)、Docker Hub?
- 仓库注册服务器:存放仓库的地方,仓库里面又包含很多镜像,每个镜像有不同的标签(tag)
- 仓库:存放镜像的地方
- 公开仓库(public)
- 全球最大的公开仓库是Docker Hub(https://hub.docker.com)
- 国内公开仓库:阿里云、网易云等
- 私有仓库(private)
- 公开仓库(public)
9 什么是Docker Swarm?
Docker Swarm是Docker的本机群集。它将Docker主机池转变为单个虚拟Docker主机。Docker Swarm提供标准的Docker API,任何已经与Docker守护进程通信的工具都可以使用Swarm透明地扩展到多个主机。
10 Docker容器有几种状态?
- 运行
- 已暂停
- 重新启动
- 已退出
我们可以通过运行命令来识别Docker容器的状态:
docker ps –a
这将依次列出所有可用的docker容器及其在主机上的相应状态。从那里我们可以很容易地识别感兴趣的容器,以相应地检查其状态。
11 什么类型的应用程序更适合Docker容器?
最好为Docker Container创建无状态应用程序。我们可以从应用程序中创建一个容器,并从应用程序中取出可配置的状态参数。现在我们可以在生产和具有不同参数的QA环境中运行相同的容器。这有助于在不同场景中重用相同的图像。使用Docker Containers比使用有状态应用程序更容易扩展无状态应用程序。
12 解释基本的Docker使用流程
- 一切都从Dockerfile开始。Dockerfile是镜像的源代码。
- 创建Dockerfile后,您可以构建它以创建容器的镜像。镜像只是“源代码”的“编译版本”,即Dockerfile。
- 获得容器的镜像后,应使用注册表重新分发容器。注册表就像一个git存储库 - 你可以推送和拉取镜像。
- 使用该镜像来运行容器。在许多方面,正在运行的容器与虚拟机(但没有管理程序)非常相似。
13 Dockerfile中最常见的指令是什么?
- FROM:我们使用FROM为后续指令设置基本镜像。在每个有效的Dockerfile中,FROM是第一条指令。
- LABEL:我们使用LABEL按照项目,模块,许可等组织我们的镜像。我们也可以使用LABEL来帮助实现自动化。在LABEL中,我们指定一个键值对,以后可用于以编程方式处理Dockerfile。
- RUN:我们使用RUN命令在当前镜像之上的新图层中执行任何指令。使用每个RUN命令,我们在镜像顶部添加一些内容,并在Dockerfile的后续步骤中使用它。
- CMD:我们使用CMD命令提供执行容器的默认值。在Dockerfile中,如果我们包含多个CMD命令,则只使用最后一条指令。
14 Dockerfile中的命令COPY和ADD命令有什么区别?
- 一般而言,虽然ADD并且COPY在功能上类似,但是COPY是优选的。
- 那是因为它比ADD更透明。COPY仅支持将本地文件基本复制到容器中,而ADD具有一些功能(如仅限本地的tar提取和远程URL支持),这些功能并不是很明显。因此,ADD的最佳用途是将本地tar文件自动提取到镜像中,如ADD rootfs.tar.xz /中所示。
15 解释一下dockerfile的ONBUILD指令?
当镜像用作另一个镜像构建的基础时,ONBUILD指令向镜像添加将在稍后执行的触发指令。如果要构建将用作构建其他镜像的基础的镜像(例如,可以使用特定于用户的配置自定义的应用程序构建环境或守护程序),这将非常有用。
16 Docker镜像和层有什么区别?
- 镜像(Docker Image):Docker镜像是由一系列只读层构建的
- 层(Docker Layer):每个层代表镜像Dockerfile中的一条指令。
下面的Dockerfile包含四个命令,每个命令都创建一个层。
FROM ubuntu:15.04
COPY . /app
RUN make /app
CMD python /app/app.py
重要的是,每个层只是与之前一层的一组差异层(相同的就不再放到新层中)。
17 如何在生产中监控Docker?
Docker提供docker stats和docker事件等工具来监控生产中的Docker。我们可以使用这些命令获取重要统计数据的报告。
- Docker统计数据:当我们使用容器ID调用docker stats时,我们获得容器的CPU,内存使用情况等。它类似于Linux中的top命令。
- Docker事件:Docker事件是一个命令,用于查看Docker守护程序中正在进行的活动流。
一些常见的Docker事件是:attach,commit,die,detach,rename,destroy等。我们还可以使用各种选项来限制或过滤我们感兴趣的事件。
18 Docker如何在非Linux系统中运行容器?
通过添加到Linux内核版本2.6.24的名称空间功能,可以实现容器的概念。容器将其ID添加到每个进程,并向每个系统调用添加新的访问控制检查。它由clone()系统调用访问,该调用允许创建先前全局命名空间的单独实例。
如果由于Linux内核中可用的功能而可以使用容器,那么显而易见的问题是非Linux系统如何运行容器。Docker for Mac和Windows都使用Linux VM来运行容器。Docker Toolbox用于在Virtual Box VM中运行容器。但是,最新的Docker在Windows中使用Hyper-V,在Mac中使用Hypervisor.framework。
19 如何在多个环境中使用Docker?
- 删除应用程序代码的任何卷绑定,以便代码保留在容器内,不能从外部更改
- 绑定到主机上的不同端口
- 以不同方式设置环境变量(例如,减少日志记录的详细程度,或启用电子邮件发送)
- 指定重启策略(例如,重启:始终)以避免停机
- 添加额外服务(例如,日志聚合器)
因此,您可能希望定义一个额外的Compose文件,例如production.yml,它指定适合生产的配置。此配置文件只需要包含您要从原始Compose文件中进行的更改。
20 为什么Docker Compose不会等待容器准备就绪,然后继续以依赖顺序启动下一个服务?
- 等待数据库(例如)准备就绪的问题实际上只是分布式系统更大问题的一个子集。在生产中,您的数据库可能随时变得不可用或移动主机。您的应用程序需要能够适应这些类型的故障。
- 要处理此问题,请将应用程序设计为在发生故障后尝试重新建立与数据库的连接。如果应用程序重试连接,它最终可以连接到数据库。
- 最佳解决方案是在启动时以及出于任何原因丢失连接时,在应用程序代码中执行此检查。
21 项目中怎么用Docker的?
结合云厂商系统
22 Docker常用命令
- docker build:构建docker镜像
- docker tag:为镜像打tag
- docker images:列出本地所有镜像
- docker pull 拉取或者更新指定镜像
- docker push 将镜像推送至远程仓库
- docker rm 删除容器
- docker rmi 删除镜像
- docker ps 列出所有容器
- docker cp 命令用于容器与主机之间的数据拷贝。
- 主机到容器:
docker cp /www 96f7f14e99ab:/www/ - 容器到主机:
docker cp 96f7f14e99ab:/www /tmp/
- 主机到容器:
- 启动nginx容器(随机端口映射),并挂载本地文件目录到容器html的命令
docker run -d -P --name nginx2 -v /home/nginx:/usr/share/nginx/html nginx
23 虚拟管理层(Hypervisor)是什么?
hypervisor -- 虚拟管理层(程序)-- 负责创建客户虚拟机系统运行所需虚拟硬件环境。它监管客户虚拟操作系统的运行,并为客户系统提供必要的运行资源,保证客户虚拟系统的运行。虚拟管理层(程序)驻留在物理主机系统和虚拟客户系统之间,为虚拟客户系统提供必要的虚拟服务。如何理解它,它侦听运行在虚拟机中的客户操作系统的操作并在主机操作系统中模拟客户操作系统所需硬件资源请求。满足客户机的运行需求。
虚拟化技术的快速发展,主要在云平台,由于在虚拟管理程序的帮助下,可允许在单台物理服务器上生成多个虚拟服务器,驱动着虚拟化技术快速发展及广泛应用。诸如,Xen,VMware,KVM 等,以及商业化的处理器硬件生产厂商也加入在硬件层面支持虚拟化技术的支持。诸如,Intel 的 VT 和 AMD-V 。
24 什么是孤儿卷及如何删除它?
孤儿卷是未与任何容器关联的卷。在 Docker v1.9 之前的版本中,删除这些孤儿卷存在很大问题。
25 什么是半虚拟化(Paravirtualization)?
Paravirtualization,也称为第 1 类虚拟机管理(层)程序,其直接在硬件或 裸机(bare-metal)上运行,提供虚拟机直接使用物理硬件的服务,它帮助主机操作系统,虚拟化硬件和实际硬件进行协作以实现最佳性能。这种虚拟层管理技术的程序一般占用系统资源较小,其本身并不需要占用大量系统资源。这种虚拟层管理程序有 Xen, KVM 等。
26 Docker与k8s关系?
k8s,Kubernetes,中文意思是舵手或导航员,k8s是一个容器集群管理系统,主要职责是容器编排(Container Orchestration):启动容器、回收容器、自动化部署、扩展和管理容器应用。
Docker&k8s27 k8s与Docker Swarm区别?
Docker&k8s28 k8s架构
k8s架构图 k8s架构-1个master2个node一个K8S集群由两部分构成 master节点和node节点。master节点和node节点一般不要部署在一台机器上。
-
master节点主要负责集群的控制,对pod进行调度,已经令牌管理等等功能。
- Api Server:对外暴露K8S的api接口,是外界进行资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;
- apiserver是可以水平扩展的。
- scheduler负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上;就是监视新创建的 Pod,如果没有分配节点,就选择一个节点供他们运行,这就是pod的调度
- 有leader选举
- controller manager负责维护集群的状态,比如故障检测、自动扩展、滚动更新等,它们是处理集群中常规任务的后台线程
- 有leader选举
- etcd:kubernetes的后端数据库,k/v方式存储,所有的k8s集群数据都存放在此处。保存了整个集群的状态
- Api Server:对外暴露K8S的api接口,是外界进行资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;
-
node节点主要是负责干活,启动容器、管理容器。
- kubelet负责维护容器的生命周期,同时也负责Volume(CSI)和网络(CNI)的管理;
- kube-proxy负责为Service提供cluster内部的服务发现和负载均衡;
- fluentd 是一个守护进程,它有助于提供集群层面日志 集群层面的日志
29 k8s优势
- 可移动: 公有云、私有云、混合云、多态云
- 可扩展: 模块化、插件化、可挂载、可组合
- 自修复: 自动部署、自动重启、自动复制、自动伸缩