Kubernetes条记

分享
程序员 2024-9-13 11:17:00 9 0 来自 中国
资料泉源:痴者工良-Kubernetes
一、Docker底子

1.1 什么是容器化应用

containerized applications指容器化的应用,我们经常说利用镜像打包应用步调,利用Docker发布、部署应用步调,那么当你的应用乐成在Docker上运行时,称这个应用是containerized applications。
1.2 应用怎么打包

容器化应用的最重要特性是利用镜像打包应用的运行情况以及应用步调,可以通过 Docker 启动这个镜像,进而将 应用步调启动起来。将一个应用步调打包为镜像,约莫分为以下过程:

  • 编写 Dockerfile 文件 -- 界说构建镜像的流程
  • 选择一个底子镜像(利用系统) -- 利用系统
  • 安装应用的须要的情况 -- 运行情况
  • 复制步调文件 -- 应用步调
  • 启动 Dockerfile -- 生成镜像
1.3 Docker镜像构成

在Docker镜像中,利用系统是高度精简的,大概只有一个精简的Shell,乃至没有Shell。而且镜像中的利用系统还不包罗内核,容器都是共享所在的宿主机的内核。以是偶然会说容器仅包罗须要的利用系统(通常只有利用系统文件和文件系统对象),容器中查察到的Linux内核版本与宿主机同等。Docker镜像的是由一系统文件构成的。
1.4 联合文件系统

Linux又名为Unionfs的文件系统服务,可以将差异文件夹中的文件联合到一个文件夹中。Unionfs有称为分支的概念,一个分支包罗了多个目次和文件,多个分支可以挂载在一起,在挂载时,可以指定一个分支优先级大于另一个分支,如许当两个分支都包罗类似的文件名时,一个分支会优先于另一个分支,在归并的目次中,会看到高优先级分支的文件。
Docker中,层层构成镜像的技能也是联合文件系统,Union File System。Docker镜像中的利用系统是根文件系统,有bin、boot 等目次。我们都知道Docker镜像是由多层文件构成的,由三层构成:根文件系统、情况依靠包、应用步调文件。当镜像层生成后,便不能被修改,假如再举利用用,则会在原来的底子上生成新的镜像层,层层联合,终极生成镜像。固然生成的镜像大概会由于层数太多大概利用过多,导致出现大量冗余,镜像痴肥。
Docker的镜像分层是受Linux Unionfs开导而开发的,Docker 支持多种文件联合系统,如 AUFS、OverlayFS、VFS等。
1.5 Linux内核

既然Docker容器须要与Linux内核联合才华利用,那么我们看一下Linux内核的功能,轻微相识一下Linux内核在支持Docker容器运作中起到什么作用。
Linux内核重要包罗以下功能:

  • 内存管理:追踪纪录有多少内存存储了什么以及存储在那里;
  • 进程管理:确定哪些进程可以利用中央处置惩罚器(CPU)、何时利用以及连续多长时间;
  • 装备驱动步调:充当硬件与进程之间的调解步调/表明步调;
  • 系统调用和安全防护:担当步调哀求调用系统服务;
  • 文件系统:利用系统中负责管理长期数据的子系统,在 Linux 中,统统皆文件。
1.6 Docker服务与客户端

Docker由Service和Client两部分构成,在服务器上可以不安装Docker Client,可以通过Http Api等方式与Docker Servie通讯。在安装了Docker的主机上实行下令docker version查察版本号。
1.7 Docker客户端

要想跟Docker Server通讯,可以利用Restful API、UNIX 套接字或网络接口(Socket)。Docker 官方的客户端是一个二进制下令行步调,利用Go语言编写,我们也可以利用C#、Java等语言写一个类似的步调,Docker 客户端不须要安装到Docker Server所在的主机,Client跟Server可以远程通讯。
Docker的客户端是很多Docker用户与Docker交互的重要方式,当我们利用docker run之类的下令时,客户端会将这些下令发送到Docker Server,由Docker Server分析并实行下令。
Docker for Linux中最为常见的同主机通讯方式是Unix域套接字。很多软件都支持利用域套接字与Docker通讯,比方CI/CD软件Jenkins,利用域套接字毗连Docker,可以或许利用Docker启动容器构建应用步调。
1.8 容器运行时

容器运行时是提供运行情况并启动容器的软件,我们最常听说的是Docker,别的尚有containerd、CRI-O等。可以绝不浮夸的说,整个Kubernetes创建在容器之上。
默认情况下,Kubernetes 利用容器运行时接口(Container Runtime Interface,CRI) 来与服务器中容器运行时交互。以是Kubernetes支持多种容器软件,但只能利用一种容器运行时举行工作,在有多个容器运行时的情况下,我们须要指定利用何种运行时,假如你不指定运行时,则kubeadm会主动实行检测到系统上已经安装的运行时,方法是扫描一组众所周知的Unix域套接字。
Linux是多进程利用系统,为了让多个系统中的多个进程可以或许举行高效的通讯,出现和很多方法,此中一种是域套接字(Unix domain socket),只能用于在同一盘算机中的进程间通讯,但是其服从高于网络套接字(socket),域套接字不须要颠末网络协议处置惩罚,通过系统调用将数据从一个进程复制到另一个进程中。
1.9 Docker引擎

Docker引擎也可以说是Docker Server,它由Docker保卫进程(Docker daemon)、containerd 以及runc构成。当利用Docker client输入下令时,下令会被发送到Docker daemon ,daemon会侦听哀求并管理Docker对象,daemon可以管理镜像、容器、网络和存储卷等。
1.10 Docker引擎变革

Docker首次发布时,Docker引擎由两个核心组件构成:LXC和Docker daemon,这也是很多文章中称Docker是基于LXC的缘故原由,旧版本的Docker利用了 LXC、cgroups、Linux 内核编写。接下来我们相识一下 LXC 。
LXC (Linux Container)是 Linux 提供的一种内核捏造化技能,可以提供轻量级的捏造化,以便隔离进程和资源,它是利用系统层面上的捏造化技能。LXC提供了对诸如定名空间(namespace) 和控制组(cgroups) 等底子工具的利用本领,它们是基于 Linux 内核的容器捏造化技能。我们不须要深入相识这个东西。
Docker一开始是利用 LXC做的,LXC是一个很牛逼的开源项目,但是随着Docker的成熟,Docker开始扬弃LXC,自己动手手撕容器引擎。
为什么Docker要扬弃LXC 呢?起首,LXC是基于Linux 的。这对于一个立志于跨平台的Docker来说是个题目,脱离LXC,怎么在 MAC、Windows 下运行?其次,云云核心的组件依靠于外部工具,这会给项目带来巨大风险,乃至影响其发展。
1.11 Docker引擎的架构

1.11.1 containerd

containerd是一个开源容器引擎,是 Docker开源出去的。之前有消息说Kubernetes不再支持 Docker,只支持containerd,很多人以为Docker不可了。
一开始 Docker 是一个 “大单体”,随着Docker的成长,Docker开始举行模块化,Docker中的很多模块都是可更换的,如Docker网络。支持容器运行的核心代码天然也抽出来,单独做一个模块,便是 containerd。Kubernetes不再支持Docker,只不外是低落依靠水平,镌汰对其他模块的依靠,只会合在containerd上。当我们安装Docker时,天然会包罗containerd。假如我们不须要Docker太多组件,那么我们可以仅仅安装containerd,由Kubernetes调治,只不外我们不能利用Docker client了。因此可以说,Kubernetes不再支持Docker,并不代表会排挤Docker。
containerd的重要使命是容器的生命周期管理,如启动容器、停息容器、制止容器等。containerd 位于 daemon 和 runc 所在的 OCI 层之间。
1.11.2 shim

shim它的作用非常单一,那就是实现 CRI 规定的每个接口,然后把具体的 CRI 哀求“翻译”成对后端容器项目标哀求大概利用。这里要区别一下,dockershim和containerd-shim,dockershim是一个暂时性的方案,dockershim 会在Kubernetes v1.24中删除(2022年),这也是Kubernetes不再支持Docker的另一组件。
1.11.3 runc

runc实质上是一个轻量级的、针对Libcontainer举行了包装的下令行交互工具,runc生来只有一个作用——创建容器,即runc是一个由于运行容器的下令行工具。
假如主机安装了Docker,我们可以利用runc --help来查察利用阐明。我们可以如许来明白runc,runc是在隔离情况生成新的进程的工具,在这个隔离情况中有一个专用的根文件系统(ubuntu、centos等)和新的进程树,这个进程树的根进程 PID=1。
二、Docker捏造化

2.1 传统捏造化部署方式

传统捏造化方式的长处是:
1、捏造机之间通过捏造化技能隔离互不影响。
2、物理机上可部署多台捏造机,提升资源利用率。
3、应用资源分配、扩容通过捏造管理器直接可设置。
4、支持快照、捏造机克隆多种技能,快速部署、容灾减灾。
传统捏造化部署方式的缺点:
1、资源占用高,须要额外的利用系统镜像,须要占用GB级别的内存以及数十GB存储空间。
2、启动速率慢,捏造机启动须要先启动捏造机内利用系统,然后才华启动应用。
3、性能影响大,应用 => 捏造机利用系统=> 物理机利用系统=> 硬件资源。
2.2 Linux捏造化

我们知道,利用系统是以一个进程为单元举行资源调治的,当代利用系统为进程设置了资源界限,每个进程利用自己的内存地区等,进程之间不会出现内存混用。Linux 内核中,有 cgroups 和 namespaces 可以为进程界说界限,使得进程相互隔离。
2.2.1 Linux-Namespace

在容器中,当我们利用 top 下令或 ps 下令查察呆板的进程时,可以看到进程的 Pid,每个进程都有一个 Pid,而呆板的全部容器都具有一个 Pid = 1 的底子,但是为什么不会发生冲突?容器中的进程可以恣意利用全部端口,而差异容器可以利用类似的端口,为什么不会发生冲突?这些都是资源可以设定界限的表现。
在 Linux 中,namespace 是 Linux 内核提供的一种资源隔离技能,可以将系统中的网络、进程情况等举行隔离,使得每个 namespace 中的系统资源不再是全局性的。现在有以下 6 种资源隔离,Docker 也根本在这 6 种资源上对容器情况举行隔离。
2.2.2 unshare

Linux 中,unshare 下令行步调可以创建一个 namespace,而且根据参数创建在 namespace 中隔离各种资源,在这里我们可以用利用这个工具简朴地创建一个 namespace。
为了深刻明白 Linux 中的 namespace,我们可以在 Linux 中实行:
unshare --pid /bin/sh这下令类似于docker run -it {image}:{tag} /bin/sh 。当我们实行下令后,终端会进入一个 namespace 中,实行 top 下令查察进程列表。
可以看到,进程 PID 是从 1 开始的,阐明在这个 namespace 中,与主机的进程是隔脱离来的。这个下令中,只隔离了进程,由于并没有隔离网络,因此当我们实行netstat --tlap下令时,这个定名空间的网络跟别的定名空间的网络是相通的。
2.3 cgroups硬件资源隔离

前面提到的 namepace 是逻辑情势使得进程之间相互不可见,形成情况隔离,这跟 Docker 容器的一样平常利用是一样的,隔离根目次,隔离网络,隔离进程 PID 等。固然,Docker 处置惩罚情况隔离外,还能限定每个容器利用的物理资源,如 CPU 、内存等,这种硬件资源的限定是基于 Linux 内核的 cgroups 的。
groups 是 control groups 的缩写,是 Linux 内核提供的一种可以进程所利用的物理资源的机制。cgroups 可以控制多种资源,在 cgroups 中每种资源限定功能对应一个子系统,可以利用下令查察
mount | grep cgroup2.4 差异层次的捏造化

我们应该在很多册本、文章中,相识到捏造机跟 Docker 的比力,相识到 Docker 的长处,通过 Docker 打包镜像后可以随时在别的地方运行而不须要担心呆板的兼容题目。但是 Docker 的捏造化并不能让 Linux 跑 Windows 容器,也不能让 Windows 跑 Linux 容器,更不大概让 x86 呆板跑 arm 指令集的二进制步调。但是 VMware 可以在 Windows 运行 Linux 、Mac 的镜像,但 WMWare 也不能由 MIPS 指令构建的 Linux 系统。
Docker 和 VMware 都可以实现差异水平的捏造化,但也不是为所欲为的,它们捏造化的水平相差很大,由于它们是在差异层次举行捏造化的。
在指令集级别捏造化中,从指令系统上看,就是要在一种呆板上实现另一种呆板的指令系统。比方,QEMU 可以实现在 X64 呆板上模拟 ARM32/64、龙芯、MIPS 等处置惩罚器。
捏造化水平在于利用硬件实现与软件实现的比例,硬件部分比例越多一样平常来说性能就会越强,软件部分比例越多机动性会更强,但是性能会降落,差异层次的实现也会影响性能、兼容性等。随着现在盘算机性能越来越猛,很洪流平上产生了性能过剩;加之硬件研发的难度越来越高,越来越难突破,非硬件水平的捏造化将会越来越广泛。
三、Docker网络

3.1 Docker的四种网络模式

Docker 有 bridge、none、host、container 四种网络模式,提供网络隔离、端口映射、容器间互通网络等各种支持,下面开门见山地直接先容这四种网络模式。这四种网络模式可以通过启动容器的时间指定,其下令或参数个数如下:

  • host模式    -–net=host  容器和宿主机共享 Network namespace。
  • container模式   –-net={id}  容器和别的一个容器共享 Network namespace。 kubernetes 中的pod就是多个容器共享一个 Network namespace。
  • none模式    –-net=none  容器有独立的Network namespace,但并没有对其举行任何网络设置,如分配 veth pair 和网桥毗连,设置IP等。
  • bridge模式  -–net=bridge    默认为该模式,通过 -p 指定端口映射。
3.2 bridge模式

利用 Docker 创建一个 bridge 模式的容器下令格式如下:
docker run -itd -p 8080:80 nginx:latestbridge 模式称为网桥模式,起首 Docker 会在主机上创建一个名为 docker0 的捏造网桥,这个捏造网络处于七层网络模子的数据链路层,每当创建一个新的容器时,容器都会通过 docker0 与主机的网络毗连,docker0 相称于网桥。
利用 bridge 模式新创建的容器,其内部都有一个捏造网卡,名为 eth0,容器之间可以通过 172.17.x.x 相互访问。
一样平常情况下,网桥默认 IP 范围是 172.17.x.x ,可以在宿主机实行 ifpconfig 下令查察全部网卡,内里会包罗 Docker 容器的捏造网卡,可以查察某个容器的 ip。在容器中,也可以利用 ifconfig 下令查察自身的容器 ip
利用了 bride 创建的容器,其网络与主机以及其他容器隔离,以太网接口、端口、路由表以及 DNS设置 都是独立的。每个容器都好像是一个独立的主机 ,这便是 bridge(网桥)的作用。但是由于 docker0 的存在,对于容器来说,可以通过 ip 访问别的容器。
容器1 可以通过 172.17.0.3 访问容器2,同样,主机也可以利用这个 ip 访问容器2 中的服务。
3.3 none 模式

这种网络模式下容器只有 lo 回环网络,没有其他网卡,这种范例的网络没有办法联网,外界也无法访问它,封闭的网络能很好地包管容器的安全性。创建 none 网络的容器:
docker run -itd --net=none nginx:latest3.4 host 模式

host 模式会让容器与主机共享网络,此时映射的端口大概会生产冲突,但是容器的别的部分(文件系统、进程等)依然是隔离的,此时容器与宿主机共享网络。
3.5 container 模式

container 模式可以让多个容器之间相互通讯,即容器之间共享网络。起首启动一个 A 容器,A 一样平常为 bridge 网络,接着 B 利用 –-net={id} 毗连到 A 中,利用 A 的捏造网卡,此时 A、B 共享网络,可以接着参加 B、C、D 等容器。
四、 Docker与Pod

4.1 什么是容器化应用

containerized applications 指容器化的应用,我们经常说利用镜像打包应用步调,利用 Docker 发布、部署应用步调,那么当你的应用乐成在 Docker 上运行时,称这个应用是 containerized applications。
在一个产物中,好的容器化规范或方法,具有以下特点:

  • 利用声明式的格式举行设置主动化,以最大限度地镌汰新开发人员参加项目标时间和资本;
  • 与底层利用系统之间有一个干净的左券(资源隔离、同一接口),在实行情况之间提供最大的可移植性;
  • 恰当部署在当代云平台上,无需服务器和系统管理;
  • 最大限度地镌汰开发和生产之间的差异,实现连续部署以实现最大敏捷性;
  • 而且可以在不对工具、架构或开发实践举行庞大更改的情况下举行扩展。
4.2 Pod

最简朴的说法就是将多个容器打包起来一起运行,这个团体就是 Pod。
Pod通过Docker的container这网络模式,让 Pod 中的容器共享网络,也就是说,Pod 中的容器,网络是互通的,容器之间不能利用类似的端口。
Pod 是 Kubernetes 集群中最小的实行单元。在 Kubernetes 中,容器不直接在集群节点上运行,而是将一个或多个容器封装在一个 Pod 中,接着将 Pod 调治到节点上运行,这些容器会一起被运行、制止,它们是一个团体。
Pod 中的全部容器共享类似的资源和当地网络,从而简化了 Pod 中应用步调之间的通讯。在 Pod 中,全部容器中的进程共享网络,可以通过 127.0.0.1、localhost 相互举行访问。
Pod 启动时会启动一个容器,K8S 给这个容器分配捏造 IP,接着,其他容器利用 container 网络模式,毗连到这个容器中,此时有容器共享网络。
随着 Pod 负载的增长,Kubernetes 可以主动复制 Pod 以到达预期的可拓展性(部署更多的 Pod 提供类似的服务,负载平衡)。因此,计划一个尽大概精简的 Pod 是很紧张的,低落因复制扩容、镌汰紧缩过程中带来的资源丧失。
前面提到,容器应当是无状态的,以是拓展 Pod 时,每个实例都提供了如出一辙的服务,这些 Pod 分配到差异的节点上,可以利用更多的 CPU、内存资源。
4.3 容器与 Pod 的区别

容器包罗实行特定流程或函数所需的代码(编译后的二进制可实行步调)。在 Kubernetes 之前,可以直接在物理或捏造服务器上运行容器,但是缺乏 Kubernetes 集群所提供的可伸缩性和机动性。
Pod 为容器提供了一种抽象,可以将一个或多个应用步调包装到一个 Pod 中,而 Pod 是 Kubernetes 集群中最小的实行单元。比方 Pod 可以包罗初始化容器,这些容器为别的应用提供了准备情况,然后在应用步调开始实行前闭幕。Pod 是集群中复制的最小单元,Pod 中的容器作为团体被扩展或缩小。
比方对应前后端分离的项目,大概不须要把前端文件和后端步调放在一起,而是分别放在两个容器中。然后通过 Pod,将这两个容器作为一组服务打包在一起。
4.4 节点

Pod 是 Kubernetes 中最小的实行单元,而 Node 是 Kubernetes 中最小的盘算硬件单元,节点可以是物理的当地服务器,也可以是捏造机,节点纵然宿主服务器,可以运行 Docker 的呆板。
与容器一样,Node 提供了一个抽象层。多个 Node 一起工作形成了 Kubernetes 集群,它可以根据需求的变革主动分配工作负载,增长或镌汰在节点上的 Pod 数量。假如 A 节点和 B 节点的硬件资源是同等的,那么 A 、B 两个节点是等价的,假如 A 节点失败,它将主动从集群中移除,由 B 节点担当,不会出现题目。
每个节点都运行着一个名为 kubelet 的组件,它是节点的重要组件,Kubernetes 与集群控制平面组件(API Server)通讯,全部对节点有影响的利用都会通过 kubectl 控制此节点。kubelet 也是 master 节点跟 worker 节点之间直接通讯的唯一组件。
kubelet 的一些功能有:

  • 在节点上创建、更新、删除容器;
  • 到场调治 Pod;
  • 为容器创建和挂载卷;
  • 利用下令查察 Pod 、容器,比方 exec、log 等时,须要通过 kubelet;
比方,集群有 A、B 两个节点,Pod 部署在那里了,这不是用户关心的变乱,用户在想看到容器的日志,可以恣意找集群中的一台主机,实行下令,Kubernetes 会主动探求容器所在的节点,然后kubectl 取得须要的内容。别的节点上尚有 proxy,重要是为 Pod 提供署理服务,外界可通过此署理,利用节点的 IP 访问 Pod 中的容器。
您需要登录后才可以回帖 登录 | 立即注册

Powered by CangBaoKu v1.0 小黑屋藏宝库It社区( 冀ICP备14008649号 )

GMT+8, 2024-10-19 06:24, Processed in 0.166440 second(s), 32 queries.© 2003-2025 cbk Team.

快速回复 返回顶部 返回列表