术语表
KDP 业务术语
集群
Kubernetes 集群,下称作 K8s Cluster(或K8s) 是由多个节点(Nodes)组成的集群,它可以协调管理容器化应用程序的部署、运行和维护。一个 Kubernetes Cluster 包括一个 Master 节点和多个 Worker 节点,Master 节点用于控制集群中的所有操作,例如调度应用程序、监控和伸缩工作负载。而 Worker 节点则负责运行容器化应用程序的实例
K8s 集群包含多个组件,这些组件协同工作,共同实现 K8s 的功能。下面是一些常见的 K8s 组件:
- etcd: 一个分布式键值存储数据库,用于存储集群中的所有配置信息,包括所有节点、服务、副本集、部署等。
- API Server: K8s 集群中的核心组件,用于管理集群中所有的对象,包括节点、服务、副本集、部署等。所有的操作都通过 API Server 进行。
- Scheduler: 用于监控集群中所有未调度的 Pod,按照一定的调度策略将其调度到合适的节点上。
- Controller Manager: 包含多个控制器,用于监控和管理集群中的对象,例如副本集、部署等。Controller Manager 会根据对象的状态和用户定义的期望状态,自动进行调整和修复。
- kubelet: 运行在每个节点上,用于管理该节点上的 Pod。它会与 API Server 通信,获取 Pod 的调度信息,负责启动和停止 Pod。
- kube-proxy: 在每个节点上运行,负责实现 K8s 服务发现和负载均衡的功能。它通过修改节点上的 iptables 规则,将服务请求转发到正确的 Pod 上。
除了上述组件外,K8s 还有其他的一些组件,例如 Ingress Controller、Persistent Volume Controller、Container Runtime 等,不同的组件可以根据需要进行部署和配置
节点
节点是指集群中由K8s系统管理的虚拟机或者物理机。
master服务端(主控节点)
- 集群的大脑,负责管理所有节点
- 负责调度Pod在哪些节点运行
- 负责控制集群运行过程中的所有状态
- 组件 kube-apiserver(rest api接口,集群控制的入口)
- kube-controller-manger(所有资源对象的自动化控制中心)
- kube-scheduler(Pod资源对象的调度)
node客户端(工作节点)
- 负责管理所有容器(container)
- 负责监控/上报所有Pod的运行状态
- 组件 kubelet(节点上容器的创建、删除、启停等任务,与Master节点通信)
- kube-proxy(k8s服务的通信及负载均衡服务)
- container runtime(负责容器的基础管理服务,接收kubelet组件的指令)
系统
属于「源码级」概念,在KDP中也称之为 Catalog(目录)。同样业务目的的应用的逻辑集合
运行时/配置时/源码级
当我们在讨论 Kubernetes 平台的管理和运维时,有时会涉及到以下三个概念:运行时、配置时和源码级。这些概念都是为了更好地描述管理和操作 Kubernetes 平台的不同层次和阶段。
运行时(Runtime)是指 Kubernetes 集群正在运行时的状态。在运行时阶段,可以通过使用 Kubernetes 的命令行工具或 Web 界面来查看集群的当前状态,并且可以在这个状态下执行一些特定的操作,比如查看 Pod 的状态、调整资源限制、扩容/缩容应用等。在这个阶段的工作是确保 Kubernetes 平台运行稳定、可靠,并且满足应用的性能和可用性要求。
配置时(Configuration)是指 Kubernetes 集群的配置,包括定义 Kubernetes 资源(如 Pod、Service、Deployment 等)的 YAML 文件、Secret、ConfigMap 等。在配置时阶段,可以通过修改这些配置文件或执行一些配置命令来修改集群的状态,例如增加、删除或更新 Kubernetes 资源的数量和配置。这个阶段的任务是确保所有的 Kubernetes 资源都被正确地定义和配置,以保证应用程序能够正常部署、扩展和升级。
源码级(Source code level)是指在 Kubernetes 平台上运行应用程序时所依赖的代码和配置,通常是源代码或者构建配置。在这个阶段,需要确保应用程序被正确地构建、配置和部署,以满足它的功能和性能要求。例如,可能需要使用 CI/CD 工具自动化构建、测试、部署应用程序,并确保代码和配置与 Kubernetes 平台相兼容。
在 Kubernetes 平台上,不同的组件通常运行在不同的阶段,例如 Kubernetes 资源的定义和配置通常发生在配置时阶段,而应用程序的构建、部署和管理通常发生在运行时阶段。理解这些概念将有助于您更好地管理 Kubernetes 平台并了解不同组件的职责和功能。
应用模板
属于「源码级」概念,在KDP中也称之为 AppForm
带参数的应用配置模版,用户可通过指定模版中的参数来生成一个实际可运行的应用配置。一般来说有以下的用法
- 系统应用:计算引擎、大数据组件 等丰富系统组件
- 用户自定义应用:docker/tomcat/spring boot/python 应用
应用配置
属于「配置时」概念,在KDP中也称之为 RenderedAppForm
- RenderedAppForm: 这个对应了我们使用
bdos instantiate -c ${CLUSTER_NAME} -g ${GROUP_NAME} -a ${APP_NAME}
之后生成的配置文件。- 在一个namespace里对于同一个AppForm运行多个应用实例时,需要生成多个RenderedAppForm,这些不同的RenderedAppForm会以APP_NAME来区分,而且可能使用不同的app_settings
- Application Components (应用模块):例如HS2中有hs2-ss(实际的服务), hs2-service(暴露的服务),hs2-prometheus-exporter(监控数据采集配置),hs2-create-hs2-secret (创建secret的任务,一次性的)。实际在运行中的可能只有一个应用负载 (hs2-ss). 【注:理论上来讲一个应用配置中是可能允许指定多个应用负载的。】
- RenderedCustomAppForm: 这个对应了我们生成的自定义应用配置,和上面的 RenderedAppForm 类似
应用实例
属于「运行时」概念
- 应用负载:对应应用实例运行的workload(运行时)
- 应用模块:对应AppInstance里的Component, 见应用配置中 应用模块说明
应用负载
属于「运行时」概念
工作负载是K8s上的物理模型,包含了一组pods。是应用组织pods运行的方式(Deployment、StatefulSets, ReplicaSets, Job 等)
Pod
属于「运行时」概念
是Kubernetes最基本的操作单元,一个Pod中可以包含一个或多个紧密相关的容器,一个Pod可以被一个容器化的环境看作应用层的逻辑宿主机。一个Pod中的多个容器应用通常是紧密耦合的,Pod在Node上被创建、启动或者销毁。每个Pod里运行着一个特殊的被称之为Pause的容器,其他容器则为业务容器,这些业务容器共享Pause容器的网络栈和Volume挂载卷,因此它们之间通信和数据交换更为高效。在设计时我们可以充分利用这一特性,将一组密切相关的服务进程放入同一个Pod中。
Master节点会以Pod为单位 将其调度单至node节点上。
容器
属于「运行时」概念
- 每个运行的容器都是可重复的; 包含依赖环境在内的标准,意味着无论你在哪里运行它都会得到相同的行为。容器将应用程序从底层的主机设施中解耦。 这使得在不同的云或 OS 环境中部署更加容易。
- 容器镜像是一个随时可以运行的软件包, 包含运行应用程序所需的一切:代码和它需要的所有运行时、应用程序和系统库,以及一些基本设置的默认值。
- 根据设计,容器是不可变的:你不能更改已经运行的容器的代码。 如果有一个容器化的应用程序需要修改,则需要构建包含更改的新镜像,然后再基于新构建的镜像重新运行容器。
命名空间
同一集群中的资源划分为相互隔离的组,使得在共享使用整个集群的资源的同时还能被分别管理。用户创建安全组时也会创建同名 NameSpace
安全组
支持 “公共”、“机构”、“其他”三类安全组,在用户使用FM/DS子系统功能时,均需要用户存在于一个机构安全组内。创建一个安全组,会对应在K8s中创建一个同名命名空间。一个安全组在BDOS中目前只能对应一个namespace。
安全组数多于 namespace 是因为 namespace 像资源一样可回收,而安全组则一直存在状态为禁用。
用户
可登录BDOS系统的用户,创建用户默认归属为user安全组 赋予common角色
系统支持通过邮件关联来创建用户账号,用户可归属于一个或多个安全组,并在每个安全组中拥有一个或多个角色。已创建的用户,包含用户/安全组下各类账户资源,创建了各种系统需要使用的账户,比如数据库、Keycloak账户;包含用户/安全组下各类其他资源,比如数据库、CPU、内存等应用资源。
角色
用于设置用户在安全组中的权限,可用于设置登录页面、菜单权限、接口权限的集合。一个安全组中缺省设置有admin, devops, common三个角色。
网络模型
Kubernetes中的网络模型指的是Kubernetes集群中容器之间以及容器与外部世界之间的通信方式。在Kubernetes集群中,Pod是最小的调度单元,而Pod中包含了一个或多个容器。这些容器需要在网络上互相通信以及与外部世界进行通信。
Kubernetes中使用的网络模型是基于CNI(Container Network Interface)标准的插件式网络模型。CNI是一个开放的容器网络接口规范,它定义了容器网络的配置和管理方式,使得Kubernetes集群可以使用不同的网络插件来提供网络服务。
Kubernetes集群中的网络模型通常包含以下几个组件:
- CNI插件:CNI插件是Kubernetes集群中最关键的组件之一,它负责为每个Pod创建和管理网络接口。不同的CNI插件有不同的网络实现方式,例如使用Linux桥接、VXLAN、Overlay等技术来实现网络通信。
- Pod网络:Kubernetes集群中的Pod需要被分配一个唯一的IP地址,以便它们能够在网络上进行通信。Kubernetes使用Pod网络来管理Pod IP地址的分配和路由。
- Service:Kubernetes中的Service是一个抽象的概念,它为Pod提供了一个稳定的IP地址和DNS名称,以便其他应用程序可以通过它们来访问Pod。Service使用Kubernetes中的负载均衡器来将请求路由到后端的Pod上。
- Ingress:Kubernetes中的Ingress是一个资源对象,它允许外部的HTTP和HTTPS流量进入Kubernetes集群,并将请求路由到后端的Service上。
这些组件一起构成了Kubernetes集群中的网络模型,使得集群中的Pod能够相互通信以及与外部世界进行通信
服务
如果一组 Pod(称为“后端”)为集群内的其他 Pod(称为“前端”)提供功能, 那么后端需要暴露一个Service为前端提供可以连接的 IP 地址,即使在后端有多个Pod或者后端Pod发生迁移时仍然可以使用
技术术语
Kubelet
Kubelet 实现了集群中最重要的关于 Node 和 Pod 的控制功能。Master 节点的 Scheduler 组件,它会调度未绑定的 Pod 到符合条件的 Node 上,而至于最终该 Pod 是否能运行于 Node 上,则是由 Kubelet 来裁定的。
Kubelet 会从 Kubernetes API Server 获取 Pod 的配置信息,然后将这些信息用于启动和停止 Pod 中的容器。Kubelet 还会监控容器的状态,包括容器是否在运行、容器的资源使用情况以及容器的健康状况等。如果容器停止运行或者健康状态不佳,Kubelet 会自动重启该容器或者将其从节点中删除。
Kube Proxy
通常来说想要访问某个服务,那要么通过域名,要么通过 IP。在K8s中而每个 Pod 在创建后都会有一个虚拟 IP,K8S 中有一个抽象的概念,叫做 Service ,kube-proxy 便是提供一种代理的服务,让你可以通过 Service 访问到 Pod。实际的工作原理是在每个 Node 上启动一个 kube-proxy 的进程,通过编排 iptables 规则来达到此效果。
Kube Proxy可以在不同的模式下运行,包括userspace、iptables和ipvs模式。在userspace模式下,Kube Proxy使用用户空间的代理程序来处理网络流量。在iptables模式下,Kube Proxy使用iptables规则来处理流量。在ipvs模式下,Kube Proxy使用IPVS(IP Virtual Server)来处理网络流量。
Kube Proxy的重要性在于它为Kubernetes中的Service提供了负载均衡和服务发现功能。Service是一种抽象,用于将一组后端Pod暴露给其他应用程序或服务。通过使用Kube Proxy,Kubernetes能够自动地将请求路由到正确的Pod,从而使应用程序具有高可用性和可伸缩性。Kube Proxy还提供了一些高级功能,如支持会话保持和负载均衡算法的自定义等。
Kube apiserver
它是Kubernetes API的前端接口,负责处理所有对集群的API请求。它充当控制平面的核心,并处理其他组件(如kubelet、kube-scheduler、kube-controller-manager等)和外部系统(如kubectl、helm等)的请求。
Kube apiserver与其他组件之间的配合是密切的。例如,kubelet会定期向apiserver报告其节点上的容器状态,并从apiserver获取Pod更新。kube-scheduler会从apiserver获取当前集群中所有节点的信息,并根据需要将Pod调度到这些节点上。kube-controller-manager会监控集群状态的变化,并相应地处理控制器的操作。
在Kubernetes集群中,apiserver通常是唯一暴露给外部的组件,并且是唯一可以授权和验证访问集群API的组件。因此,对于需要进行集群管理和调度的任何应用程序或工具,都需要使用Kube apiserver来执行其操作。各类 API 请求先后通过认证,授权,准入控制等一系列环节后,进入到 kube-apiserver 进行相关逻辑处理
部署
备注:Pod 是 K8S 中最小的调度单元,所以无法直接在 K8S 中运行一个 container 但是可以运行一个 Pod 而这个 Pod 中只包含一个或者多个 container
在Kubernetes中,部署应用的基本单位是Pod,它是一个可以包含一个或多个容器的最小单元。然而,单独的Pod不足以满足复杂应用的需求,因此Kubernetes提供了Deployment、ReplicaSet和Service资源来管理和扩展Pod。它们的需求和关联关系如下:
- Deployment: Deployment是一种资源对象,用于管理Pod的多个副本。通过Deployment可以控制Pod的副本数量、容器镜像版本等属性。Deployment还提供了滚动更新和回滚等策略,保证应用更新的平滑和安全。Deployment通常与ReplicaSet结合使用。更推荐的方式便是使用 yaml 格式的配置文件。在配置文件中主要是声明一种预期的状态,而其他组件则负责协同调度并最终达成这种预期的状态,将 Pod 托管给 ReplicaSet
- ReplicaSet: ReplicaSet是Deployment的实现机制,用于确保一定数量的Pod副本在任何时候都处于运行状态。当Pod数量不足或过多时,ReplicaSet会自动进行扩容或缩容。每个ReplicaSet都与一个Pod模板关联,定义了要创建的Pod的规格。ReplicaSet也可单独使用。
- Service: Service是一种虚拟的网络对象,为一组Pod提供统一的访问入口。通过Service可以实现Pod的负载均衡、服务发现和应用暴露等功能。Service会自动将请求转发到后端Pod中的一个或多个容器。Service与Pod通过标签关联,也可以与Deployment和ReplicaSet关联。
- Pod: Pod是Kubernetes最基本的部署单元,是一组共享网络和存储资源的容器集合。Pod通常包含一个或多个紧密关联的容器,共享同一主机、IP地址和端口空间。每个Pod都有自己的IP地址,用于容器之间的通信。Pod通常由Deployment或ReplicaSet创建和管理
- label:K8S 会默认增加一些标签(Label),它们可作为选择条件进行使用,典型的应用场景是在在应用部署或更新时总是会考虑的一个问题是如何平滑升级,利用 Deployment 通过 Label 可以进行这种操作。
Helm
Helm 是构建于 K8S 之上的包管理器,可与我们平时接触到的 Yum,APT,Homebrew 或者 Pip 等包管理器相类比。使用 Helm 可简化包分发,安装,版本管理等操作流程。通过YAML配置文件进行部署是一种更加灵活和可控的方法,适合需要更细粒度控制的场景,而使用Helm则更加便捷,适合需要频繁部署、更新和管理应用程序的场景。
但是通过 Helm 也有以下一些需要注意的内容
- 依赖于第三方仓库:Helm 需要依赖第三方仓库来存储和管理 Charts,如果仓库出现问题或者仓库中的 Chart 不再受支持,就会出现问题。
- 安全性问题:Helm 部署的 Chart 可能包含不受信任的代码或者配置,这可能导致安全问题。
- 版本管理:Helm 部署的 Chart 有可能出现版本管理的问题。例如,如果 Chart 的版本更新了,但是已经部署的应用还是使用旧版本,那么就会出现版本不一致的问题。
- 维护复杂度:Helm 部署需要对 Kubernetes 的资源对象、Helm 的命令和 Charts 的结构有一定的了解,所以对于一些不熟悉 Kubernetes 的人员来说,可能会感到比较复杂。
- 定制化问题:Helm 部署的 Chart 可能无法满足用户的特定需求,这时需要自己对 Chart 进行修改和定制化,这会带来额外的工作量和复杂度。
etcd
etcd 在 K8S 中,最主要的作用便是其高可用,强一致的键值存储以及监听机制。例如:在 kube-apiserver 收到对应请求经过一系列的处理后,最终如果是集群所需要存储的数据,便会存储至 etcd 中。主部分主要是集群状态信息和元信息。Kubernetes的各种组件通过与etcd进行交互,实现对集群状态、配置信息和元数据等的读写。比如,当Kubernetes的apiserver需要读取或写入集群的状态或元数据时,就会将请求发送到etcd中。同时,etcd也会将其数据的变化通知给其他组件,如kube-controller-manager和kube-scheduler等,以便它们可以相应地更新自己的状态。
通常情况下,在Kubernetes集群中,我们不需要直接使用etcd,而是由Kubernetes自动管理。只有在需要进行etcd集群管理或监控等操作时,才需要直接操作etcd。同时,在进行高可用的Kubernetes集群部署时,我们需要对etcd进行集群化部署以保证其高可用性和可靠性。
LVM 和 PV
LVM是Linux中的一个逻辑卷管理器,它允许管理员在多个硬盘分区上创建虚拟卷。在Kubernetes中,LVM通常用于将物理存储转换为Kubernetes中使用的持久卷(PV)。
PV是Kubernetes中的一种资源对象,它提供了一种将外部存储资源(例如磁盘或网络存储)映射到Kubernetes中的Pod的方式。PV与底层存储技术无关,因此它可以将不同类型的存储抽象为统一的接口。Kubernetes中的Pod可以使用PV来访问持久化数据,PV则负责将Pod的请求路由到实际的存储后端。
LVM和PV在Kubernetes中通常用于应用的存储。下面是它们在应用发布过程中的使用方式:
- 配置PV:首先,需要在Kubernetes集群中配置PV(Persistent Volumes)来定义存储设备,如云盘或本地磁盘,并指定存储的类型、大小、访问模式等属性。PV是由Kubernetes管理员或开发者在Kubernetes集群上创建和管理的,可以被多个Pod使用。
- 配置PVC:接下来,需要创建PVC(Persistent Volume Claims),以请求PV提供存储。PVC是由应用程序开发者或管理员在Kubernetes上创建的,它们与应用程序的Pods相关联,并声明它们需要的存储资源。
- 将PVC与Pod关联:最后,将PVC与应用程序的Pod关联,以将PV挂载到Pod中,并使应用程序可以使用该存储。
在发布应用程序时,开发者可以使用LVM和PV来定义应用程序所需的存储资源,并确保它们在应用程序运行时可靠和可扩展。
Ingress
在 Kubernetes 中,Ingress是一种资源对象,用于暴露集群中服务的HTTP和HTTPS路由。它充当流量控制器,允许管理员轻松配置应用程序的路由规则,以便外部用户可以访问集群中的应用程序。
Ingress资源本身只定义了路由规则,要使其生效,需要使用Ingress Controller。Ingress Controller是一个运行在集群中的负责读取Ingress资源并将其配置到负载均衡器或代理服务器上的组件。常见的Ingress Controller包括Nginx、Traefik、HAProxy等。
在运维中,使用Ingress可以方便地为Kubernetes集群中的应用程序提供外部访问方式,可以实现负载均衡、安全策略、TLS加密等功能。此外,Ingress还可以作为应用程序的URL入口,方便用户访问和使用。
Docker 容器运行时(容器引擎)
容器运行时Docker 是一个开源的应用容器引擎,让开发者可以打包应用及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接触。
Docker Registry
Docker Registry(容器镜像仓库)是一个开源的镜像仓库软件,用于存放和分发Docker镜像。
Docker 网络模式(Container vs Bridge)
容器网络模式是Docker用来控制容器网络访问的一种方式,有三种模式可供选择:bridge、host和none,其中bridge是默认模式,而container模式是Kubernetes中的一种特殊模式。
在bridge模式下,Docker会为每个容器分配一个IP地址,并将这些容器放在一个网桥上,容器可以通过该网桥进行通信。此模式适用于需要将容器隔离到自己的网络栈中,并且需要与主机和其他容器进行通信。
在container模式下,容器将共享同一个网络栈,因此可以直接通过localhost相互访问。此模式适用于需要在同一个Pod中运行多个容器的情况,这些容器需要相互通信。
选择网络模式的关键因素是容器之间是否需要通信。如果容器需要通过localhost直接通信,则应使用container模式。否则,应使用bridge模式或其他网络模式。如果您不想让容器访问网络或网络访问容器,则可以使用none模式。需要注意的是,无论选择哪种网络模式,都应该避免使用硬编码的IP地址或主机名,而应该使用服务发现机制,如Kubernetes中的Service,以确保容器与其他容器和服务之间的通信始终是可靠和可移植的。
Configmap
在 Kubernetes 中,Pod 的管理通常需要关注 Configmap。Pod 可以引用 Configmap 中的数据,并将这些数据作为环境变量、命令行参数或者配置文件的形式传递给容器。这使得应用程序能够在运行时动态地加载配置信息,从而使得应用程序更加灵活和可配置。
具体的应用程序的开发人员需要关注 Configmap,因为他们需要决定哪些配置参数需要被放在 Configmap 中,并在应用程序中使用这些参数。运维人员也需要关注 Configmap,因为他们需要创建和维护 Configmap,并在部署应用程序时将 Configmap 中的数据传递给容器。
Configmap 不属于任何一个具体的 Kubernetes 组件,而是可以被各种组件使用,如 Deployment、StatefulSet、DaemonSet 等。通过 Configmap 可以将应用程序的配置数据从容器镜像中剥离出来,这样可以更加方便地进行配置文件的修改和管理。