ㅤㅤㅤ
ㅤㅤㅤ
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ(一个人的真正伟大之处就在于他能够认识到自己的渺小 —— 保罗)
ㅤㅤㅤ
ㅤㅤㅤ
ㅤㅤㅤㅤㅤㅤㅤㅤㅤ在这里插入图片描述
上一篇:kubernetes 入门实践-走进kubernetes
下一篇:kubernetes 入门实践-搭建集群

k8s基本组件

在这里插入图片描述
一个 Kubernetes 集群由一组被称作节点的机器组成。这些节点上运行 Kubernetes 所管理的容器化应用。集群具有至少一个工作节点。

工作节点托管作为应用负载的组件的 Pod 。控制平面管理集群中的工作节点和 Pod 。 为集群提供故障转移和高可用性,这些控制平面一般跨多主机运行,集群跨多个节点运行

控制平面组件

控制平面的组件对集群做出全局决策(比如调度),以及检测和响应集群事件(例如,当不满足部署的 replicas 字段时,启动新的 pod)。

控制平面组件可以在集群中的任何节点上运行。 然而,为了简单起见,设置脚本通常会在同一个计算机上启动所有控制平面组件, 并且不会在此计算机上运行用户容器

kube-apiserver

Kubernetes API 服务器验证并配置 API 对象的数据, 这些对象包括 pods、services、replicationcontrollers 等。 API 服务器为 REST 操作提供服务,并为集群的共享状态提供前端, 所有其他组件都通过该前端进行交互

etcd

etcd 是兼具一致性和高可用性的键值数据库,可以作为保存 Kubernetes 所有集群数据的后台数据库。

kube-scheduler

控制平面组件,负责监视新创建的、未指定运行节点(node)的 Pods,选择节点让 Pod 在上面运行。
调度决策考虑的因素包括单个 Pod 和 Pod 集合的资源需求、硬件/软件/策略约束、亲和性和反亲和性规范、数据位置、工作负载间的干扰和最后时限

kube-controller-manager

运行控制器进程的控制平面组件。
从逻辑上讲,每个控制器都是一个单独的进程, 但是为了降低复杂性,它们都被编译到同一个可执行文件,并在一个进程中运行。
这些控制器包括:

  • 节点控制器(Node Controller): 负责在节点出现故障时进行通知和响应
  • 任务控制器(Job controller): 监测代表一次性任务的 Job 对象,然后创建 Pods 来运行这些任务直至完成
  • 端点控制器(Endpoints Controller): 填充端点(Endpoints)对象(即加入 Service 与 Pod)
  • 服务帐户和令牌控制器(Service Account & Token Controllers): 为新的命名空间创建默认帐户和 API 访问令牌
节点组件

节点组件在每个节点上运行,维护运行的 Pod 并提供 Kubernetes 运行环境

kubelet

Kubelet组件运行在Node节点上,维持运行中的Pods以及提供kuberntes运行时环境,主要完成以下使命:
1.监视分配给该Node节点的pods
2.挂载pod所需要的volumes
3.下载pod的secret
4.通过docker/rkt来运行pod中的容器
5.周期的执行pod中为容器定义的liveness探针
6.上报pod的状态给系统的其他组件
7.上报Node的状态

kube-proxy

kubernetes 工作节点上的一个网络代理组件,运行在每个节点上
它维护节点上的网络规则,实现了Kubernetes Service 概念的一部分 。它的作用是使发往 Service 的流量(通过ClusterIP和端口)负载均衡到正确的后端Pod。

docker

容器运行环境是负责运行容器的软件。

Kubernetes 支持多个容器运行环境: Docker、 containerd、CRI-O 以及任何实现 Kubernetes CRI (容器运行环境接口)。

k8s核心概念

deployment

一个 Deployment 为 Pods 和 ReplicaSets 提供声明式的更新能力
你负责描述 Deployment 中的 目标状态,而 Deployment 控制器(Controller) 以受控速率更改实际状态, 使其变为期望状态。你可以定义 Deployment 以创建新的 ReplicaSet,或删除现有 Deployment, 并通过新的 Deployment 收养其资源。
总结:deployment是用来管理pod的,比如控制pod的伸缩和更新,以及pod的更新策略等

statefulSets

StatefulSet 是用来管理有状态应用的工作负载 API 对象。
StatefulSet 用来管理某 Pod 集合的部署和扩缩, 并为这些 Pod 提供持久存储和持久标识符。
和 Deployment 类似, StatefulSet 管理基于相同容器规约的一组 Pod。但和 Deployment 不同的是, StatefulSet 为它们的每个 Pod 维护了一个有粘性的 ID。这些 Pod 是基于相同的规约来创建的, 但是不能相互替换:无论怎么调度,每个 Pod 都有一个永久不变的 ID。
如果希望使用存储卷为工作负载提供持久存储,可以使用 StatefulSet 作为解决方案的一部分。 尽管 StatefulSet 中的单个 Pod 仍可能出现故障, 但持久的 Pod 标识符使得将现有卷与替换已失败 Pod 的新 Pod 相匹配变得更加容易

service

将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法。
主要实现集群内部通信,以及基于四层的内外通信(如端口)
为pod提供一个固定,统一的访问接口及负载均衡的能力,并借助新一代DNS的服务发现功能,解决客户端发现并访问容器化应用的难题
service的地址是不会发生改变的,它通过标签选择器和后端的pod关联
总结:因为客户端通常通过k8s service的方式来访问集群内的服务,但集群内的pod每次变更都会导致ip发生变动,所以就需要一种访问来固定访问pod的模式,所以就抽象出了service的概念

k8s的四种service

我们先了解k8s的四种类型的service

  • ClusterIp

通过集群的内部 IP 暴露服务,选择该值时服务只能够在集群内部访问。 这也是默认的 ServiceType

  • NodePort

通过每个节点上的 IP 和静态端口(NodePort)暴露服务。 NodePort 服务会路由到自动创建的 ClusterIP 服务。 通过请求 <节点 IP>:<节点端口>,你可以从集群的外部访问一个 NodePort 服务。

  • LoadBalancer

使用云提供商的负载均衡器向外部暴露服务。 外部负载均衡器可以将流量路由到自动创建的 NodePort 服务和 ClusterIP 服务上

  • ExternalName

通过返回 CNAME 和对应值,可以将服务映射到 externalName 字段的内容(例如,foo.bar.example.com)。 无需创建任何类型代理

或者使用ingress进行转发操作,但ingress不在本教程范围内,有兴趣的可以去了解ingress的网络策略配置

所以本教程采用较为直观的NodePort形式进行演示

service和pod之间的关系?

参考文章
官方:k8s服务代理
官方:使用service连接到应用
CSDN:十分钟了解k8s service到pod转发机制
CSDN:kubernetes endpoints是什么
总结:service和pod并没有直接的关系。pod通过endpoints暴露出来,只要pod发生变更,便会同步至endpoints中。有了service和endpoints后,kube-proxy会实时监听它们的更新和删除操作,然后更新iptables代理规则,重新生成该service访问pod的ip和端口映射规则

下图红框中endpoints中的ip是该service下所有的pod

相关命令

kubectl describe svc vue-pod-service -n vue
kubectl get service -n vue
kubectl get pods -n vue -o wide

在这里插入图片描述
将endpoints配置以yaml文件形式输出

kubectl get endpoints -n vue -o yaml

红框中的是该service和po关系的映射列表。记录了每个pod的信息,这里面的三个 Pod 信息就是我们刚才创建的三个 Pod 。addresses 里面记录了 Pod 的 ip、所在的主机名称、以及具体的 Resource Object 的引用
在这里插入图片描述
查看pod在iptables下的转发策略

# -S 打印链或所有链中的规则
# -t 要操作的表
# nat 网络地址
# 关键字匹配
# vue-pod-service k8s的service名称
iptables -S -t nat | grep "vue-pod-service"

下图红框中的代表k8s利用iptables中的statistic模块做概率轮询策略,百分之33的几率访问KUBE-SEP-RU2WS6VELU3XJ57F并送到10.244.1.106,百分之50的几率访问KUBE-SEP-QNVMXJN6GHH54P4U并送到10.244.1.107,否则默认走向KUBE-SEP-EIPMM2RHLXKNQK5T并送到10.244.1.108
在这里插入图片描述
但是往往我们还需要更多更灵活的算法,比如基于最少连接算法、源地址HASH算法等。而同样基于netfilter的ipvs却是专门做负载均衡的,配置简单,基于散列查找O(1)复杂度性能好,支持数十种调度算法。因此显然IPVS比iptables更适合做kube-proxy的后端

namespaces

名字空间是在多个用户之间划分集群资源的一种方法
它们在逻辑上彼此隔离。 他们可以为您和您的团队提供组织,安全甚至性能方面的帮助
总结:主要场景是区分业务,模块。利于后期的维护和管理

labels

标签(Labels) 是附加到 Kubernetes 对象(比如 Pods)上的键值对。 标签旨在用于指定对用户有意义且相关的对象的标识属性,但不直接对核心系统有语义含义。 标签可以用于组织和选择对象的子集。标签可以在创建时附加到对象,随后可以随时添加和修改。 每个对象都可以定义一组键/值标签。每个键对于给定对象必须是唯一的。
总结:当相同类型的资源越来越多,对资源划分管理是很有必要,此时就可以使用label为资源对象 命名,以便于配置,部署等管理工作,提升资源的管理效率

label selector

Label selector(标签选择器)是Kubernetes核心的分组机制,通过label selector客户端/用户能够识别一组有共同特征或属性的资源对象
主要作用

  1. 通过资源对象上定义的Label Selector来筛选要监控的Pod副本的数量,从而实现Pod副本的数量始终符合预期设定的全自动控制流程
  2. kupe-proxy进程通过Service的Label Selector来选择对应的Pod,自动建立器每个Service到对应Pod的请求转发路由表,从而实现Service的智能负载均衡机制
  3. 通过对某些Node定义特定的Label,并且在Pod定义文件中使用NodeSelector这种标签调度策略,Kube-scheduler进程可以实现Pod定向调度的特性

假设我们去掉service中的selector
在这里插入图片描述
查看k8s监控平台 dashboard,发现endpoints和pods全是空
在这里插入图片描述
查看service的描述信息

kubectl describe service -n vue

在这里插入图片描述
尝试访问31066端口,发现超时
在这里插入图片描述
那么现在只有两个办法

  1. 手动配置service的endpoints的配置 官方endpoints配置文档
  2. service标签选择器关联pod的标签

现在我们重新关联service的标签选择器
在这里插入图片描述
查看监控
在这里插入图片描述
查看service的描述信息

在这里插入图片描述
访问端口
在这里插入图片描述

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐