k8s主要分为控制平面和计算节点两个部分:
- Control plane:控制平面,主要负责对真实node以及其中Pod的管控,通过元信息存储、调度策略等管理pod实例来保障HA
- Compute nodes:真实计算节点,运行着各种程序和任务的pod实例
kube-apiserver
kube-apiserver是控制平面的核心管理组件,负责处理集群内外的 API 请求,并维护整个集群的状态
- API 服务器:kube-apiserver 是 K8s 集群的 API 服务器,它提供了集群内外的 API 接口,允许用户和其他组件通过 API 请求来管理和操作集群中的各种资源。kube-apiserver 实现了 Kubernetes API 的规范,包括资源的创建、更新、删除等操作。
- 集群状态的维护:kube-apiserver 负责维护整个集群的状态,它与 etcd 数据库进行交互,将集群的配置信息和资源状态持久化存储在 etcd 中。kube-apiserver 监听集群中各种资源对象的变化,并将这些变化反映到 etcd 中,以实现集群状态的一致性和持久性。
- 认证和授权:kube-apiserver 负责对 API 请求进行认证和授权。它支持多种认证方式,包括基于证书、令牌、用户名密码等方式。通过认证后,kube-apiserver 使用授权策略来决定用户是否有权限执行请求的操作。授权策略可以基于 RBAC、Webhook、Node 证书等进行配置。
- API 版本和扩展:kube-apiserver 支持多个 API 版本,并且具有良好的扩展性。新的 API 资源可以通过自定义资源定义(CRD)或聚合器(Aggregator)的方式添加到 kube-apiserver 中,从而扩展 Kubernetes 的功能。这使得用户可以根据自己的需求扩展和定制 Kubernetes 的 API。
- 高可用性和负载均衡:kube-apiserver 支持高可用性和负载均衡。用户可以通过运行多个 kube-apiserver 实例来实现高可用性,并使用负载均衡器将请求分发到这些实例上,以提高集群的可用性和性能。
总结来说,kube-apiserver 是 K8s 集群的 API 服务器,负责处理集群内外的 API 请求,并维护整个集群的状态。它与 etcd 数据库交互,将集群的配置信息和资源状态持久化存储在 etcd 中。kube-apiserver 支持认证和授权,具有多版本和扩展性,支持高可用性和负载均衡。
管理k8s有两种方式,一种是通过kubectl命令,另一种是restful api,都是与kube-apiserver直接交互
swift
获取资源列表:
kubectl get pods:获取当前命名空间下的所有 Pod 列表。
kubectl get deployments:获取当前命名空间下的所有部署(Deployment)列表。
kubectl get services:获取当前命名空间下的所有服务(Service)列表。
kubectl get nodes:获取集群中所有节点(Node)的列表。
查看资源详细信息:
kubectl describe pod <pod-name>:查看指定 Pod 的详细信息。
kubectl describe deployment <deployment-name>:查看指定部署的详细信息。
kubectl describe service <service-name>:查看指定服务的详细信息。
创建和删除资源:
kubectl create -f <manifest-file.yaml>:根据 YAML 文件创建资源对象。
kubectl apply -f <manifest-file.yaml>:根据 YAML 文件创建或更新资源对象。
kubectl delete pod <pod-name>:删除指定的 Pod。
kubectl delete deployment <deployment-name>:删除指定的部署。
kubectl delete service <service-name>:删除指定的服务。
执行命令和访问容器:
kubectl exec -it <pod-name> <command>:在指定 Pod 中执行命令。
kubectl logs <pod-name>:查看指定 Pod 的日志。
kubectl port-forward <pod-name> <local-port>:<pod-port>:将本地端口与 Pod 的端口进行转发,以便访问 Pod 内部的服务。
扩容和滚动更新:
kubectl scale deployment <deployment-name> --replicas=<replica-count>:扩容或缩容指定的部署。
kubectl rollout status deployment <deployment-name>:查看指定部署的滚动更新状态。
kubectl rollout history deployment <deployment-name>:查看指定部署的滚动更新历史。
kubectl rollout undo deployment <deployment-name>:回滚指定部署的滚动更新。
curl -X POST -H "Content-Type: application/json" --data '{"apiVersion":"v1","kind":"Service","metadata":{"name":"my-service"},"spec":{"selector":{"app":"my-app"},"ports":[{"protocol":"TCP","port":80,"targetPort":8080}]}}' http://<kubernetes-api-server>/api/v1/namespaces/<namespace-name>/services
etcd
etcd是一个基于raft+boltdb实现的强一致key-value数据库,它被广泛用于构建分布式系统。在 K8s 中,作为控制平面组件的一部分,etcd被用作主要的数据存储,它用于存储配置元信息、实例的state状态信息等,例如节点信息、Pod 信息、服务信息、配置信息等。
etcd 提供了高可用性、一致性和分布式存储的特性,这使得 K8s 能够实现高度可靠的集群管理。当 K8s 集群中的组件需要读取或写入集群的状态信息时,它们会与 etcd 进行通信。
总结来说,etcd 是 K8s 集群的关键组件之一,负责存储和管理集群的状态信息,确保 K8s 集群的可靠性和一致性。
Distributed watchable storage implementation via etcd
scheduler
scheduler是负责将新创建的 Pod 分配到集群中的节点上的组件,时刻关注着节点们的工作负载。在任期中,它会每隔一段换时间对 kube-apiserver 执行ping操作,目的是为了确定是否有一些工作负载需要进行调度
-
一旦有一些node的负载情况不再满足相应的限制规则,比如管理员修改了配置,磁盘空间不足等,这时scheduler会做出调度决策,选择一个更适合的node环境运行来pod
-
scheduler做出选择之后,会立刻进行调度吗?不会,它会告诉kube-apiserver如何去做,而不是自己做
-
kube-apiserver收到后,会立刻做出调度吗?不会,它会先将配置写入etcd,当写入成功之后,拿到对目标state,kube-apiserver会知道如何去做,并通过向目标node的kubelet发送指令,kubelet 与CRI密切合作完成pod的创建、删除
调度器根据一组预定义的规则和策略,将 Pod 分配给适合的节点,以实现资源的最优利用和负载均衡。下面是几个常见的调度器:
- 默认调度器(Default Scheduler):是一个基于优先级和资源需求的简单调度器。它使用一组预定义的调度策略来选择节点,并将 Pod 分配给具有足够资源的节点。
- 自定义调度器(Custom Scheduler):允许用户编写自定义调度器来满足特定的调度需求。自定义调度器可以根据用户定义的策略和规则,选择适合的节点来运行 Pod。
- 副本集调度器(ReplicaSet Scheduler):副本集调度器是一种特殊的调度器,用于管理副本集(ReplicaSet)中的 Pod。它确保在节点故障或扩容时,重新调度缺失的 Pod,以保持副本集的期望副本数。
- DaemonSet 调度器(DaemonSet Scheduler):DaemonSet 调度器用于管理 DaemonSet 中的 Pod。DaemonSet 是一种在集群中的每个节点上运行一个 Pod 的控制器。DaemonSet 调度器确保每个节点都有一个相应的 DaemonSet Pod。
- 节点亲和性调度器(Node Affinity Scheduler):节点亲和性调度器允许将 Pod 调度到满足特定标签要求的节点上。它可以根据节点的标签和 Pod 的亲和性规则,选择合适的节点来运行 Pod。
根据特定的需求和场景,可以使用默认调度器或自定义调度器来实现灵活的 Pod 调度策略。
kubelet
kubelet 是 K8s 集群中每个计算节点上运行的关键组件之一。它负责把当前节点注册到k8s集群中去,与控制平面进行通信,管理节点上的Pod,并确保节点上的容器处于预期的状态。
- 容器和 Pod 管理:负责在节点上创建、启动、停止和监控容器。它通过接收来自控制平面的请求并与CRI进行交互,执行容器的生命周期管理操作。还负责监控 Pod 的状态,并在需要时重新启动失败的容器。
- 资源管理:负责监控节点上的资源使用情况,包括 CPU、内存、磁盘和网络等。它根据 Pod 的资源需求和节点的资源容量,进行资源分配和调度,确保节点上的容器能够正常运行。
- 与控制平面通信:负责 与 K8s 控制平面中的各个组件进行通信,包括 kube-apiserver、scheduler 和 controller-manager 等。它通过与kube-apiserver交互,接收来自控制平面的指令和配置信息,并向控制平面报告节点和容器的状态。
- 健康检查和自愈:负责定期对节点上的容器进行健康检查,确保它们正常运行。如果容器失败或出现问题,Kubelet 将尝试重新启动容器,或者将容器标记为失败状态,并报告给控制平面。
- 安全性和认证:负责与控制平面进行安全的通信,并验证来自控制平面的请求。它使用节点上的证书和凭据进行身份验证,并确保只有授权的请求才能对节点进行操作。
总结来说,Kubelet负责管理节点上容器和 Pod 的重要组件。它与容器运行时交互,执行容器的生命周期管理操作,监控资源使用情况,与控制平面通信,并确保节点上的容器处于预期的状态。
CRI
CRI(Container Runtime Interface)符合容器运行时接口规范,它定义了 kubelet 如何与容器运行时(如 Docker、containerd、CRI-O 等)进行通信,以创建、销毁和管理容器
通过 CRI,K8s可以与多种容器运行时进行集成,而不依赖于特定的容器实现。这样就使得 k8s更具灵活性,可以在不同的环境中使用不同的容器运行时
controller-manager
k8s controller是插件化的,很多controller时刻关注 这整个k8s系统的不同部分。保证目的状态 和真实状态的一致性。controller-manager它包含了多个控制器,负责监控集群状态的变化,并根据预定义的规则和策略来维护和管理集群中的各种资源
- 多个控制器:Controller Manager 包含了多个控制器,每个控制器负责管理不同类型的资源。常见的控制器包括 ReplicaSet 控制器、Deployment 控制器、Namespace 控制器、Service 控制器等。每个控制器都有特定的功能和责任,用于确保集群中各种资源的状态和配置符合预期。
- 控制器的功能:每个控制器都有自己的功能和目标。例如,ReplicaSet 控制器负责监控副本集(ReplicaSet)的状态,并根据定义的副本数来创建或删除 Pod,以维持期望的副本数。Deployment 控制器负责管理应用的部署和更新,确保应用的副本数和版本符合预期。Service 控制器负责创建和管理服务等。
- 监控集群状态:Controller Manager 监控集群中各种资源的状态变化。它通过与 API Server 进行交互,获取资源的当前状态,并与预期状态进行比较。如果发现状态不符合预期,控制器会采取相应的操作来调整资源的状态,例如创建、删除、更新等。
- 调谐和自愈:Controller Manager 中的控制器具有调谐和自愈的能力。它们可以检测到节点故障、容器失败、资源不足等问题,并尝试自动修复这些问题。例如,Node 控制器可以监测到节点的不可用,并将 Pod 调度到其他可用节点上,以确保应用的高可用性。
- 扩展性和可插拔性:Controller Manager 具有良好的扩展性和可插拔性。用户可以根据自己的需求编写自定义的控制器,并将其添加到 Controller Manager 中。这使得用户可以根据特定的业务需求来扩展和定制 Kubernetes 的功能。
总结来说,Controller Manager 是控制平面中的一个核心组件,包含了多个控制器,用于监控和管理集群中的各种资源。它负责监控集群状态的变化,调整资源的状态以符合预期,并具有自愈和扩展性的能力。
kube-proxy
kube-proxy 是运行在每个计算节点上的网络代理组件,它负责实现网络转发和负载均衡功能。下面是关于 kube-proxy 的一些主要功能:
- 服务发现和负载均衡:kube-proxy 的主要功能之一是实现 Service 的服务发现和负载均衡。Service 是 K8s 中抽象的逻辑概念,用于将一组 Pod 暴露为一个统一的访问入口。kube-proxy 监听 kube-apiserver 中的 Service 和 Endpoint 对象的变化,并根据配置生成相应的网络规则,将请求转发到正确的目标 Pod 上,实现负载均衡。
- IPVS 模式和 iptables 模式:kube-proxy 可以以两种模式之一来实现负载均衡。一种是 IPVS 模式,它使用 Linux 内核的 IPVS(IP Virtual Server)功能来实现负载均衡,具有更高的性能和可扩展性。另一种是 iptables 模式,它使用 iptables 规则来进行转发和负载均衡。在 Kubernetes 1.14 版本及以前,默认使用 iptables 模式,而在 1.14 版本之后,默认使用 IPVS 模式。
- 网络规则和转发:kube-proxy 根据 Service 和 Endpoint 对象的变化生成相应的网络规则,并将这些规则应用到节点的网络栈中,以实现请求的转发和负载均衡。在 IPVS 模式下,kube-proxy 使用 IPVS 功能来管理虚拟服务和真实服务器的映射关系。在 iptables 模式下,kube-proxy 使用 iptables 规则来进行转发。
- 高可用性和故障恢复:kube-proxy 支持高可用性和故障恢复。它可以通过与其他 kube-proxy 实例的通信来实现负载均衡的高可用性。如果一个节点上的 kube-proxy 失败,其他节点上的 kube-proxy 可以接管其负载均衡的任务,确保服务的可用性。
- 配置和运行方式:kube-proxy 的配置信息存储在 etcd 中,kube-proxy 定期从 etcd 中获取最新的配置。kube-proxy 可以作为一个独立的进程运行,也可以与 kubelet 组件一起运行在同一个进程中。
总结来说,kube-proxy 是 K8s 集群中负责实现服务发现和负载均衡功能的网络代理组件。它根据 Service 和 Endpoint 对象的变化生成网络规则,并将请求转发到正确的目标 Pod 上,实现负载均衡。kube-proxy 支持高可用性和故障恢复,并可以以 IPVS 模式或 iptables 模式运行。
关于IPVS模式和iptables模式:
IPVS 模式(默认模式):
- kube-proxy 在主机上运行,并监视 Kubernetes API Server 中的 Service 和 Endpoint 对象的变化。
- 当创建或更新 Service 对象时,kube-proxy 会创建或更新 IPVS 规则,将 Service 的虚拟 IP(VIP)绑定到一组后端 Pod 的真实 IP 上。
- kube-proxy 还会为每个 Service 创建一个 IPVS 的虚拟服务器(Virtual Server),它监听 Service 的 VIP 和端口,并将流量转发到后端 Pod。
- 当 Service 的 Endpoint 对象发生变化(例如,Pod 的 IP 地址变化或 Pod 的状态发生变化),kube-proxy 会更新 IPVS 规则,以反映最新的后端 Pod 集合。
iptables 模式:
- 在某些环境中,IPVS 模式可能不可用或不适用。在这种情况下,kube-proxy 可以使用 iptables 模式进行服务代理。
- kube-proxy 在主机上运行,并监视 Kubernetes API Server 中的 Service 和 Endpoint 对象的变化。
- 当创建或更新 Service 对象时,kube-proxy 会创建或更新 iptables 规则,将 Service 的虚拟 IP(VIP)绑定到一组后端 Pod 的真实 IP 上。
- kube-proxy 还会为每个 Service 创建一个 iptables 规则,该规则将流量转发到后端 Pod。
- 当 Service 的 Endpoint 对象发生变化时,kube-proxy 会更新 iptables 规则,以反映最新的后端 Pod 集合。
无论是使用 IPVS 模式还是 iptables 模式,kube-proxy 都负责在主机上设置正确的网络规则,以确保服务的流量到达node计算节点后可以正确地路由到后端 Pod。它提供了负载均衡、会话保持和服务发现等功能,使得 Kubernetes 中的服务可以高效地运行和通信
回顾和杂谈
最后放几张图,供大家理解消化。