K8S学习及实践【v1.25】

K8S学习及实践【v1.25】

  • 1 K8S文档
  • 2 Kubernetes 特性
  • 3 K8S介绍
    • 3.1 K8S是什么
    • 3.2 为什么需要 Kubernetes,它能做什么?
  • 4 Kubernetes 架构
    • 4.1 K8S集群架构图
    • 4.2 控制平面组件(Control Plane Components)
      • 4.2.1 kube-apiserver
      • 4.2.2 etcd
      • 4.2.3 kube-scheduler
      • 4.2.4 kube-controller-manager
      • 4.2.5 cloud-controller-manager【可选】
    • 4.3 Node 组件
      • 4.3.1 kubelet
      • 4.3.2 kube-proxy
      • 4.3.3 容器运行时(Container Runtime)
    • 4.4 插件(Addons)
      • 4.4.1 DNS
      • 4.4.2 Web 界面(仪表盘)
      • 4.4.3 容器资源监控
      • 4.4.4 集群层面日志
  • 5 Kubernetes API
    • 5.1 OpenAPI V2
    • 5.2 OpenAPI V3
    • 5.3 持久化
    • 5.4 API 组和版本控制
    • 5.5 API 变更
    • 5.6 API 扩展
  • 6 使用 Kubernetes 对象
    • 6.1 理解 Kubernetes 对象
      • 6.1.1 对象规约(Spec)与状态(Status)
      • 6.1.2 描述 Kubernetes 对象
      • 6.1.3 必需字段
      • 6.1.4 K8S中yaml文件详解
    • 6.2 Kubernetes 对象管理
    • 6.3 对象名称和 IDs
    • 6.4 命名空间
    • 6.5 标签和选择算符
    • 6.6 注解
    • 6.7 Finalizers
    • 6.8 属主与附属
    • 6.9 字段选择器
    • 6.10 推荐使用的标签
  • 7 节点
  • 8 容器
  • 9 Pod

1 K8S文档

1、K8S官方网站
2、K8S官方文档

2 Kubernetes 特性

参考1:官方介绍

  1. 自动化上线和回滚
    Kubernetes 会分步骤地将针对应用或其配置的更改上线,同时监视应用程序运行状况以确保你不会同时终止所有实例。如果出现问题,Kubernetes 会为你回滚所作更改。你应该充分利用不断成长的部署方案生态系统。

  2. 服务发现与负载均衡
    无需修改你的应用程序即可使用陌生的服务发现机制。Kubernetes 为容器提供了自己的 IP 地址和一个 DNS 名称,并且可以在它们之间实现负载均衡。

  3. 存储编排
    自动挂载所选存储系统,包括本地存储、诸如 AWS 或 GCP 之类公有云提供商所提供的存储或者诸如 NFS、iSCSI、Ceph、Cinder 这类网络存储系统。

  4. Secret 和配置管理
    部署和更新 Secret 和应用程序的配置而不必重新构建容器镜像, 且不必将软件堆栈配置中的秘密信息暴露出来。

  5. 自动装箱
    根据资源需求和其他限制自动放置容器,同时避免影响可用性。 将关键性的和尽力而为性质的工作负载进行混合放置,以提高资源利用率并节省更多资源。

  6. 批量执行
    除了服务之外,Kubernetes 还可以管理你的批处理和 CI 工作负载,在期望时替换掉失效的容器。

  7. IPv4/IPv6 双协议栈
    为 Pod 和 Service 分配 IPv4 和 IPv6 地址。

  8. 水平扩缩
    使用一个简单的命令、一个 UI 或基于 CPU 使用情况自动对应用程序进行扩缩。

  9. 自我修复
    重新启动失败的容器,在节点死亡时替换并重新调度容器,杀死不响应用户定义的健康检查的容器,并且在它们准备好服务之前不会将它们公布给客户端。

  10. 为扩展性设计
    无需更改上游源码即可扩展你的 Kubernetes 集群。

3 K8S介绍

3.1 K8S是什么

参考1:官方介绍
参考2:K8S是什么? K8S实现了什么?

官方介绍:Kubernetes 是一个可移植、可扩展的开源平台,用于管理容器化的工作负载和服务,方便进行声明式配置和自动化。Kubernetes 拥有一个庞大且快速增长的生态系统,其服务、支持和工具的使用范围广泛。

通俗理解:K8S是一个编排容器的工具,其实也是管理应用的全生命周期的一个工具,从创建应用,应用的部署,应用提供服务,扩容缩容应用,应用更新,都非常的方便,而且可以做到故障自愈,例如一个服务器挂了,可以自动将这个服务器上的服务调度到另外一个主机上进行运行,无需进行人工干涉。

3.2 为什么需要 Kubernetes,它能做什么?

  1. 服务发现和负载均衡
    Kubernetes 可以使用 DNS 名称或自己的 IP 地址来曝露容器。 如果进入容器的流量很大, Kubernetes 可以负载均衡并分配网络流量,从而使部署稳定。

  2. 存储编排
    Kubernetes 允许你自动挂载你选择的存储系统,例如本地存储、公共云提供商等。

  3. 自动部署和回滚
    你可以使用 Kubernetes 描述已部署容器的所需状态, 它可以以受控的速率将实际状态更改为期望状态。 例如,你可以自动化 Kubernetes 来为你的部署创建新容器, 删除现有容器并将它们的所有资源用于新容器。

  4. 自动完成装箱计算
    你为 Kubernetes 提供许多节点组成的集群,在这个集群上运行容器化的任务。 你告诉 Kubernetes 每个容器需要多少 CPU 和内存 (RAM)。 Kubernetes 可以将这些容器按实际情况调度到你的节点上,以最佳方式利用你的资源。

  5. 自我修复
    Kubernetes 将重新启动失败的容器、替换容器、杀死不响应用户定义的运行状况检查的容器, 并且在准备好服务之前不将其通告给客户端。

  6. 密钥与配置管理
    Kubernetes 允许你存储和管理敏感信息,例如密码、OAuth 令牌和 ssh 密钥。 你可以在不重建容器镜像的情况下部署和更新密钥和应用程序配置,也无需在堆栈配置中暴露密钥。

4 Kubernetes 架构

注意Kubernetes是一个集群

4.1 K8S集群架构图

Kubernetes集群分为两部分:

  1. 左侧的控制平面(Control Plane)组件
    控制平面管理集群中的工作节点和 Pod。

  2. 右侧的工作节点(Node)
    一组工作机器,称为 节点, 会运行容器化应用程序。每个集群至少有一个工作节点。工作节点会托管 Pod ,而 Pod 就是作为应用负载的组件。

K8S学习及实践【v1.25】_第1张图片

4.2 控制平面组件(Control Plane Components)

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

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

控制平面组件的构成

  1. kube-apiserver
  2. etcd
  3. kube-scheduler
  4. kube-controller-manager
  5. cloud-controller-manager【可选】

4.2.1 kube-apiserver

kube-apiserver 负责公开了 Kubernetes API,负责处理接受请求的工作。 API 服务器是 Kubernetes 控制平面的前端。

Kubernetes API 服务器的主要实现是 kube-apiserverkube-apiserver 设计上考虑了水平扩缩,也就是说,它可通过部署多个实例来进行扩缩。 你可以运行 kube-apiserver 的多个实例,并在这些实例之间平衡流量。

4.2.2 etcd

一致且高度可用的键值存储,用作 Kubernetes 的所有集群数据的后台数据库。

如果你的 Kubernetes 集群使用 etcd 作为其后台数据库, 请确保你针对这些数据有一份 备份计划。

4.2.3 kube-scheduler

kube-scheduler 负责监视新创建的、未指定运行节点(node)的 Pods, 并选择节点来让 Pod 在上面运行。

调度决策考虑的因素包括单个 PodPods 集合的资源需求、软硬件及策略约束、 亲和性及反亲和性规范、数据位置、工作负载间的干扰及最后时限。

4.2.4 kube-controller-manager

kube-controller-manager 负责运行控制器进程。

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

这些控制器包括:

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

4.2.5 cloud-controller-manager【可选】

嵌入了特定于云平台的控制逻辑。 云控制器管理器(Cloud Controller Manager)允许你将你的集群连接到云提供商的 API 之上, 并将与该云平台交互的组件同与你的集群交互的组件分离开来。

cloud-controller-manager 仅运行特定于云平台的控制器。 因此如果你在自己的环境中运行 Kubernetes,或者在本地计算机中运行学习环境, 所部署的集群不需要有云控制器管理器。

kube-controller-manager 类似,cloud-controller-manager 将若干逻辑上独立的控制回路组合到同一个可执行文件中, 供你以同一进程的方式运行。 你可以对其执行水平扩容(运行不止一个副本)以提升性能或者增强容错能力。

下面的控制器都包含对云平台驱动的依赖:

  • 节点控制器(Node Controller):用于在节点终止响应后检查云提供商以确定节点是否已被删除。
  • 路由控制器(Route Controller):用于在底层云基础架构中设置路由。
  • 服务控制器(Service Controller):用于创建、更新和删除云提供商负载均衡器。

4.3 Node 组件

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

Node 组件的构成

  1. kubelet
  2. kube-proxy
  3. 容器运行时(Container Runtime)

4.3.1 kubelet

kubelet 会在集群中每个节点(node)上运行。 它保证容器(containers)都运行在 Pod 中。

kubelet 接收一组通过各类机制提供给它的 PodSpecs, 确保这些 PodSpecs 中描述的容器处于运行状态且健康。 kubelet 不会管理不是由 Kubernetes 创建的容器。

4.3.2 kube-proxy

kube-proxy 是集群中每个节点(node)所上运行的网络代理, 实现 Kubernetes 服务(Service) 概念的一部分。

kube-proxy 维护节点上的一些网络规则, 这些网络规则会允许从集群内部或外部的网络会话与 Pod 进行网络通信。

如果操作系统提供了可用的数据包过滤层,则 kube-proxy 会通过它来实现网络规则。 否则,kube-proxy 仅做流量转发。

4.3.3 容器运行时(Container Runtime)

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

Kubernetes 支持许多容器运行环境,例如 containerdCRI-O 以及 Kubernetes CRI (容器运行环境接口) 的其他任何实现。

4.4 插件(Addons)

插件使用 Kubernetes 资源(DaemonSet、 Deployment 等)实现集群功能。 因为这些插件提供集群级别的功能,插件中命名空间域的资源属于 kube-system 命名空间。

DNS 、Web 界面(仪表盘)、容器资源监控、集群层面日志。

4.4.1 DNS

尽管其他插件都并非严格意义上的必需组件,但几乎所有 Kubernetes 集群都应该有集群 DNS, 因为很多示例都需要 DNS 服务。

集群 DNS 是一个 DNS 服务器,和环境中的其他 DNS 服务器一起工作,它为 Kubernetes 服务提供 DNS 记录。

Kubernetes 启动的容器自动将此 DNS 服务器包含在其 DNS 搜索列表中。

4.4.2 Web 界面(仪表盘)

Dashboard 是 Kubernetes 集群的通用的、基于 Web 的用户界面。 它使用户可以管理集群中运行的应用程序以及集群本身, 并进行故障排除。

4.4.3 容器资源监控

容器资源监控 将关于容器的一些常见的时间序列度量值保存到一个集中的数据库中, 并提供浏览这些数据的界面。

4.4.4 集群层面日志

集群层面日志机制负责将容器的日志数据保存到一个集中的日志存储中, 这种集中日志存储提供搜索和浏览接口。\

5 Kubernetes API

Kubernetes 控制面的核心是 API 服务器。 API 服务器负责提供 HTTP API,以供用户集群中的不同部分和集群外部组件相互通信。

Kubernetes API 使你可以查询和操纵 Kubernetes API 中对象(例如:PodNamespaceConfigMapEvent)的状态。

大部分操作都可以通过 kubectl 命令行接口或类似 kubeadm 这类命令行工具来执行, 这些工具在背后也是调用 API。不过,你也可以使用 REST 调用来访问这些 API。

5.1 OpenAPI V2

Kubernetes API 服务器通过 /openapi/v2 端点提供聚合的 OpenAPI v2 规范。 你可以按照下表所给的请求头部,指定响应的格式

头部 可选值 说明
Accept-Encoding gzip 不指定此头部也是可以的
Accept application/[email protected]+protobuf 主要用于集群内部
Accept application/json 默认值
Accept * 提供application/json

Kubernetes 为 API 实现了一种基于 Protobuf 的序列化格式,主要用于集群内部通信。 关于此格式的详细信息,可参考 Kubernetes Protobuf 序列化设计提案。 每种模式对应的接口描述语言(IDL)位于定义 API 对象的 Go 包中。

5.2 OpenAPI V3

Kubernetes v1.25 提供将其 API 以 OpenAPI v3 形式发布的 beta 支持; 这一功能特性处于 beta 状态,默认被开启。 你可以通过为 kube-apiserver 组件关闭 OpenAPIV3 特性门控来禁用此 beta 特性。

发现端点 /openapi/v3 被提供用来查看可用的所有组版本列表。 此列表仅返回 JSON。这些组、版本以下面的格式提供:

{
    "paths": {
        ...,
        "api/v1": {
            "serverRelativeURL": "/openapi/v3/api/v1?hash=CC0E9BFD992D8C59AEC98A1E2336F899E8318D3CF4C68944C3DEC640AF5AB52D864AC50DAA8D145B3494F75FA3CFF939FCBDDA431DAD3CA79738B297795818CF"
        },
        "apis/admissionregistration.k8s.io/v1": {
            "serverRelativeURL": "/openapi/v3/apis/admissionregistration.k8s.io/v1?hash=E19CC93A116982CE5422FC42B590A8AFAD92CDE9AE4D59B5CAAD568F083AD07946E6CB5817531680BCE6E215C16973CD39003B0425F3477CFD854E89A9DB6597"
        },
        ....
    }
}

为了改进客户端缓存,相对的 URL 会指向不可变的 OpenAPI 描述。 为了此目的,API 服务器也会设置正确的 HTTP 缓存标头 (Expires 为未来 1 年,和 Cache-Controlimmutable)。 当一个过时的 URL 被使用时,API 服务器会返回一个指向最新 URL 的重定向。

Kubernetes API 服务器会在端点 /openapi/v3/apis//?hash= 发布一个 Kubernetes 组版本的 OpenAPI v3 规范。

请参阅下表了解可接受的请求头部。

头部 可选值 说明
Accept-Encoding gzip 不指定此头部也是可以的
Accept application/[email protected]+protobuf 主要用于集群内部
Accept application/json 默认值
Accept * 提供application/json

5.3 持久化

Kubernetes 通过将序列化状态的对象写入到 etcd 中完成存储操作。

5.4 API 组和版本控制

为了更容易消除字段或重组资源的呈现方式,Kubernetes 支持多个 API 版本,每个版本位于不同的 API 路径, 例如 /api/v1/apis/rbac.authorization.k8s.io/v1alpha1

版本控制是在 API 级别而不是在资源或字段级别完成的,以确保 API 呈现出清晰、一致的系统资源和行为视图, 并能够控制对生命结束和/或实验性 API 的访问。

为了更容易演进和扩展其 API,Kubernetes 实现了 API 组, 这些 API 组可以被启用或禁用。

API 资源通过其 API 组资源类型命名空间(用于命名空间作用域的资源)和名称来区分。 API 服务器透明地处理 API 版本之间的转换:所有不同的版本实际上都是相同持久化数据的呈现。 API 服务器可以通过多个 API 版本提供相同的底层数据。

例如,假设针对相同的资源有两个 API 版本:v1v1beta1。 如果你最初使用其 API 的 v1beta1 版本创建了一个对象, 你稍后可以使用 v1beta1v1 API 版本来读取、更新或删除该对象, 直到 v1beta1 版本被废弃和移除为止。此后,你可以使用 v1 API 继续访问和修改该对象。

5.5 API 变更

一般而言,新的 API 资源和新的资源字段可以被频繁地添加进来。 删除资源或者字段则要遵从 API 废弃策略。

Kubernetes 对维护达到正式发布(GA)阶段的官方 API 的兼容性有着很强的承诺,通常这一 API 版本为 v1。 此外,Kubernetes 保持与 Kubernetes 官方 APIBeta API 版本持久化数据的兼容性, 并确保在该功能特性已进入稳定期时数据可以通过 GA API 版本进行转换和访问。

如果你采用一个 Beta API 版本,一旦该 API 进阶,你将需要转换到后续的 Beta 或稳定的 API 版本。 执行此操作的最佳时间是 Beta API 处于弃用期,因为此时可以通过两个 API 版本同时访问那些对象。 一旦 Beta API 结束其弃用期并且不再提供服务,则必须使用替换的 API 版本。

5.6 API 扩展

有两种途径来扩展 Kubernetes API

  1. 你可以使用自定义资源来以声明式方式定义 API 服务器如何提供你所选择的资源 API。
  2. 你也可以选择实现自己的聚合层来扩展 Kubernetes API

6 使用 Kubernetes 对象

6.1 理解 Kubernetes 对象

参考1:理解 Kubernetes 对象

Kubernetes 系统中,Kubernetes 对象 是持久化的实体。 Kubernetes 使用这些实体去表示整个集群的状态。 比较特别地是,它们描述了如下信息:

  • 哪些容器化应用正在运行(以及在哪些节点上运行)
  • 可以被应用使用的资源
  • 关于应用运行时表现的策略,比如重启策略、升级策略以及容错策略

Kubernetes 对象是“目标性记录” —— 一旦创建该对象,Kubernetes 系统将不断工作以确保该对象存在。 通过创建对象,你就是在告知 Kubernetes 系统,你想要的集群工作负载状态看起来应是什么样子的, 这就是 Kubernetes 集群所谓的 期望状态(Desired State)

6.1.1 对象规约(Spec)与状态(Status)

每个 Kubernetes 对象包含两个嵌套的对象字段,它们负责管理对象的配置: 对象 spec(规约) 和 对象 status(状态)。对于具有 spec 的对象,你必须在创建对象时设置其内容,描述你希望对象所具有的特征: 期望状态(Desired State)

status 描述了对象的当前状态(Current State),它是由 Kubernetes 系统和组件设置并更新的。 在任何时刻,Kubernetes 控制平面 都一直都在积极地管理着对象的实际状态,以使之达成期望状态

例如,Kubernetes 中的 Deployment 对象能够表示运行在集群中的应用。 当创建 Deployment 时,可能会去设置 Deploymentspec,以指定该应用要有 3 个副本运行。 Kubernetes 系统读取 Deploymentspec, 并启动我们所期望的应用的 3 个实例 —— 更新状态以与规约相匹配。 如果这些实例中有的失败了(一种状态变更),Kubernetes 系统会通过执行修正操作来响应 spec 和状态间的不一致 —— 意味着它会启动一个新的实例来替换。

6.1.2 描述 Kubernetes 对象

创建 Kubernetes 对象时,必须提供对象的 spec,用来描述该对象的期望状态,以及关于对象的一些基本信息(例如名称)。 当使用 Kubernetes API 创建对象时(直接创建,或经由 kubectl), API 请求必须在请求本体中包含 JSON 格式的信息。 大多数情况下,你需要提供 .yaml 文件为 kubectl 提供这些信息。 kubectl 在发起 API 请求时,将这些信息转换成 JSON 格式。

这里有一个 .yaml 示例文件,展示了 Kubernetes Deployment 的必需字段和对象 spec

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2 # 告知 Deployment 运行 2 个与该模板匹配的 Pod
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

相较于上面使用 .yaml 文件来创建 Deployment,另一种类似的方式是使用 kubectl 命令行接口(CLI)中的 kubectl apply 命令, 将 .yaml 文件作为参数。下面是一个示例:

kubectl apply -f https://k8s.io/examples/application/deployment.yaml

输出类似下面这样:

deployment.apps/nginx-deployment created

6.1.3 必需字段

在想要创建的 Kubernetes 对象所对应的 .yaml 文件中,需要配置的字段如下:

  • apiVersion:创建该对象所使用的 Kubernetes API 的版本。
  • kind:想要创建的对象的类别。
  • metadata:帮助唯一标识对象的一些数据,包括一个 name 字符串、UID 和可选的 namespace
  • spec:你所期望的该对象的状态。

对每个 Kubernetes 对象而言,其 spec 之精确格式都是不同的,包含了特定于该对象的嵌套字段。 我们能在 Kubernetes API 参考 找到我们想要在 Kubernetes 上创建的任何对象的规约格式。

6.1.4 K8S中yaml文件详解

参考1:K8s中yaml文件详解(超详细)

6.2 Kubernetes 对象管理

6.3 对象名称和 IDs

6.4 命名空间

6.5 标签和选择算符

6.6 注解

6.7 Finalizers

6.8 属主与附属

6.9 字段选择器

6.10 推荐使用的标签

7 节点

8 容器

9 Pod

你可能感兴趣的:(K8S,kubernetes)