前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >K8s面试系列:K8s常用 API 资源总结速记

K8s面试系列:K8s常用 API 资源总结速记

作者头像
山河已无恙
发布2025-02-25 20:49:14
发布2025-02-25 20:49:14
7900
代码可运行
举报
文章被收录于专栏:山河已无恙
运行总次数:0
代码可运行

写在前面

  • 博文内容为 K8s 中常用的 API 资源简单总结
  • 适合对 K8s 有基本认知,温习,面试准备的小伙伴
  • 内容涉及:API 资源组成SSACSA 资源操作方式,以及资源类别工作负载,服务,配置和存储,认证,鉴权,策略,扩展,集群 等简单描述

整理这部分笔记,在找 K8s干扰预算相关笔记的时候,突然看到那篇笔记末尾之前摘的一句话; "我曾以为总有一天,我能够改变一些什么,可当我看见她渐渐淹没在人海的时候,我才明白,我们这一生除了相遇大概注定一事无成了。 ——网易云" 。似水流年,却未曾三十而立...


Kubernetes API概述

官方文档位置:

https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/

在 k8s 体系中,把涉及部署环境,自动化运维相关所有行为、实体抽象为 API 对象,用对应的 API 对象来表示相关的容器化应用部署行为,或者叫动作实体

比如抽象出Pod API 来表示一组在共享网络(IP)、存储和计算资源的环境下运行的容器,这里实际上是抽象了多个容器化应用部署在一个逻辑主机的环境中。

通过 抽象出Service API 来表示一个高可用的服务,不同的Service 类型对应的不同的服务发布方式,。

通过抽象deploy API 来描述一个 高可用集群环境的部署行为

通过 ReplicaSet 来表示一个任何时候都能保持副本数不变的集群的行为。

API 资源组成

在 K8s中 一个常见的 API 对象由下面四部分构成:

  1. 资源种类和API版本ResourceKind、Version: 这是关于 API 资源的类型和版本说明
代码语言:javascript
代码运行次数:0
复制
apiVersion: v1
kind: Pod
  1. 资源对象元数据ResourceMeta: 这是关于资源的元数据,名称、所属命名空间、注释和标签,从属关系等。
代码语言:javascript
代码运行次数:0
复制
metadata:
  creationTimestamp: null
  labels:
    run: pod-static
  name: pod-static
  namespeace: default
  1. 资源对象规格参数ResourceSpec: 这是由用户定义的,描述资源的期望状态。在创建或更新一个对象时填写这个。
代码语言:javascript
代码运行次数:0
复制
spec:
  containers:
  - image: nginx
    imagePullPolicy: IfNotPresent
    name: pod-demo
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
......
  1. 资源对象状态ResourceStatus: 这是由服务动态生成的,用于描述API对象当前状态。在大多数情况下,用户不需要改变这个。
代码语言:javascript
代码运行次数:0
复制
status:
  phase: Running
  conditions:
    - type: Initialized
      status: 'True'
      lastProbeTime: null
      lastTransitionTime: '2023-02-18T14:46:54Z'
    - type: Ready
      status: 'True'
      lastProbeTime: null
      lastTransitionTime: '2023-02-18T14:54:04Z'
    - type: ContainersReady
      status: 'True'
      lastProbeTime: null
      lastTransitionTime: '2023-02-18T14:54:04Z'
    - type: PodScheduled
      status: 'True'
      lastProbeTime: null
      lastTransitionTime: '2023-02-11T04:11:46Z'
  hostIP: 192.168.26.105
  podIP: 10.244.169.101
  podIPs:
    - ip: 10.244.169.101
  startTime: '2023-02-11T04:11:46Z'
  ..................

通过上面的组成,可以很直观的体会到 K8s声明式的操作风格,告诉系统我们需要什么,而不是告诉系统你需要做什么,使用kubectl apply 创建指定配置文件所定义的所有对象。通常,此配置文件采用yaml 进行描述。也就是我们上面的4部分。

声明式操作在分布式系统中的好处是稳定,不怕丢操作或运行多次。例如,设置副本数为3 的操作运行多次也还是一个结果,而通过kubectl 给副本数加1的操作就不是声明式的,指令或者命令式运行多次结果不一样。

API资源的操作

API 资源对象的基本操作分为4 类,即传统的增删改查。

  1. 创建(Create):在存储后端创建资源,并应用期望的状态:kubectl create -f deployment.yaml
  2. 更新(Update):有两种形式的更新:替换(Replace)修补(Patch)
    • 替换(Replace):通过用提供的新规范替换现有规范来更新资源需要用户提供完整的资源定义。如果在读取和写入之间资源被修改,那么乐观锁定失败将会发生只有在满足一定更新要求之后才会被更新。注意,ResourceStatus将被系统忽略,不会被更新。要更新状态,必须调用特定的状态更新操作。替换资源对象可能不会立即导致更改传播到下游对象。对上游资源(如ConfigMapSecret)所做的更改可能不会立即反映到依赖于它们的下游对象(如Pods)中.kubectl replace -f deployment.yaml
    • 修补(Patch):对特定字段应用更改。更改的合并方式是按字段定义的。列表可以被替换或合并修补从不会导致乐观锁定失败,后写入将胜出。当在更新之前没有读取完整状态,或者不希望在乐观锁定失败时失败的情况下,建议使用修补。

乐观锁定:乐观锁定是一种并发控制策略,它允许多个用户或进程同时修改资源,但在提交更改时会检查资源版本是否已被其他用户修改,当乐观锁定失败时,Kubernetes 会阻止更新操作并返回错误。用户需要获取最新的资源版本并再次尝试更新操作,或者使用--force--force-conflicts 标志强制更新(谨慎使用)

  1. 读取(Read):有三种形式的读取:获取(Get)列出(List)监视(Watch)
    • 获取(Get):通过名称检索特定资源对象kubectl get pods productpage-v1-979d4d9fc-k88z7
    • 列出(List):检索命名空间内特定类型的所有资源对象,结果可以限制为匹配选择器查询的资源。kubectl get pods
    • 列出所有命名空间(List All Namespaces):类似于列出,但检索所有命名空间中的资源kubectl get pods -A
    • 监视(Watch):流式传输对象更新的结果。类似于回调,监视用于响应资源更改kubectl get pods -w
  2. 删除(Delete):删除资源。kubectl delete pods reviews-v1-569db879f5-hdx2h,删除特定资源,服务器可能会或可能不会对子对象进行垃圾收集,比如删除一个Deployment 资源时,默认情况下,Kubernetes 会自动删除由该Deployment 创建的所有Pod 子对象。然而,在某些情况下,您可能希望保留这些子对象,而不是让它们被垃圾收集。在这种情况下,您可以使用--cascade=orphan 选项来删除 Deployment,同时保留其子对象
  3. 附加操作(Additional Operations):资源可能定义特定于该资源类型的附加操作。
    • 回滚(Rollback):将PodTemplate回滚到以前的版本。仅适用于某些资源类型kubectl rollout undo deployment/my-deployment
    • 读/写规模(Read / Write Scale):读取或更新给定资源的副本数量。仅适用于某些资源类型。kubectl get deployment my-deployment -o jsonpath='{.spec.replicas}'/ kubectl scale deployment my-deployment --replicas=5
    • 读/写状态(Read / Write Status):读取或更新资源对象的状态。状态只能通过这些更新操作更改。kubectl get deployment my-deployment -o jsonpath='{.status.availableReplicas}'

这些操作允许用户灵活地控制资源的创建、更新、读取和删除。实际上通过命令行方式,我们用的最多的是apply ,即应用操作,一般直接指定 声明文件。

kubectl apply 用于创建或更新资源配置,具有更高的灵活性和并发处理能力;默认情况下,使用Client-Side Apply 的处理方式

可以创建新的资源,还可以更新现有的资源。当管理员或开发者对资源的配置进行修改后,可以使用此命令将更改应用到集群中。

  • 如果指定的资源不存在,kubectl apply 会根据提供的配置文件创建新的资源。
  • 如果资源已经存在,客户端会根据比较结果生成一个补丁(patch),然后将补丁发送到 Kubernetes API 服务器以应用更改。

这种特性使得kubectl apply成为在Kubernetes中创建和更新资源的统一方法。

kubectl apply 还具有一种称为Server-Side Apply的特性。当多个用户或进程同时修改同一资源时,Kubernetes 会在服务器端处理并发更新,以确保资源的一致性。

要使用 Server-Side Apply,只需在kubectl apply 命令中添加--server-side 标志。例如:

代码语言:javascript
代码运行次数:0
复制
kubectl apply -f deployment.yaml --server-side

CSA & SSA

  • Client-Side Apply:客户端负责比较资源定义和状态
  • Server-Side Apply:服务器端负责比较资源定义和状态

通过kubectl apply -f rs.yaml 的方式,使用的是Client-Side Apply 的方式, 要使用Server-Side Apply,需在kubectl apply 命令中添加--server-side 标志。例如:

代码语言:javascript
代码运行次数:0
复制
kubectl apply -f deployment.yaml --server-side

Server-Side ApplyKubernetes 1.14 版本引入的新特性,并在后续版本中得到了改进。在使用 Server-Side Apply 时,请确保您的 Kubernetes 集群和 kubectl 客户端版本支持此特性。1.16 版本为 beta,到1.18 版本beta2,在1.22V 升级为GA

如何区分资源操作是CSA 还是SSA

CSA

在使用kubectl apply进行Client-Side Apply时,kubectl会自行填充元数据注解kubectl.kubernetes.io/last-applied-configuration

下面为通过kubectl 工具 直接kubectl apply -f vs.yaml 创建的VS,kubectl.kubernetes.io/last-applied-configuration 为 kubectl 客户端自行填充。

代码语言:javascript
代码运行次数:0
复制
liruilong@liruilongdeMacBook-Air .kube % kubectl get vs -n defalut m-liruilong-online-vs  -o yaml --show-managed-fields 
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"networking.istio.io/v1beta1","kind":"VirtualService","metadata":{"annotations":{},"name":"m-liruilong-online-vs","namespace":"defalut"},"spec":{"gateways":["istio-system/gw-any-liruilong-online"],"hosts":["m.liruilong.online"],"http":[{"match":[{"uri":{"prefix":"/"}}],"route":[{"destination":{"host":"share-web-svc.defalut.svc.cluster.local","port":{"number":8083}}}]}]}}
  creationTimestamp: "2024-11-11T12:40:54Z"
  generation: 3
  managedFields:
  - apiVersion: networking.istio.io/v1beta1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          .: {}
          f:kubectl.kubernetes.io/last-applied-configuration: {}
      f:spec:
        .: {}
        f:gateways: {}
        f:hosts: {}
        f:http: {}
    manager: kubectl-client-side-apply
    operation: Update
    time: "2024-11-11T17:49:04Z"
  name: m-liruilong-online-vs
  namespace: defalut
  resourceVersion: "16170709"
  uid: 1b772566-d540-459e-9b2d-3b42f5d7e088
spec:
  ........
liruilong@liruilongdeMacBook-Air .kube % 

这个注解主要用于标识哪些字段是通过 kubectl apply 来管理的,kubectl会将本次apply的配置文件全量的记录在last-applied-configurationannotation中。

前面我们有讲,当apply一个对象,如果该对象不存在,则创建它(同时写入last-applied-configuration)。如果对象已经存在,则kubectl需要根据以下三个状态计算出patch报文,通过patch方式进行更新(patch 更新特定字段,避免乐观锁定)。

  • 当前配置文件所表示的对象在集群中的真实状态。(修改对象前先Get一次
  • 当前apply的配置。
  • 以及上次apply的配置。 (在last-applied-configuration里)

patch报文的计算方法如下:

  • 计算要删除的字段,即在last-applied-configuration 中存在但在配置文件中不再存在的字段,同时对于本地对象配置文件中显式设置为空的字段,清除其在现时配置中的设置, 无论这些字段是否出现在last-applied-configuration
  • 计算要添加或设置的字段,即在配置文件中存在但其取值与现时配置不同的字段。设置现时配置的值

之后设置last-applied-configuration注解的内容,使之与配置文件匹配。将前面步骤得出的结果合并,构成向 API 服务器发送的补丁(patch)请求内容。

详细可以参考官方文档的Demo:

https://kubernetes.io/zh-cn/docs/tasks/manage-kubernetes-objects/declarative-config/

SSA

使用 kubectl 进行Server-Side Apply操作,需要显示指定,

要使用Server-Side Apply,只需在kubectl apply 命令中添加--server-side 标志。

代码语言:javascript
代码运行次数:0
复制
kubectl apply -f deployment.yaml --server-side

同时会在元数据中添加managedFields字段,。managedFields的出现导致kubectl get xxx -oyaml | json的输出变得非常冗长,难以阅读。 这个问题在v1.20版本中得到优化,使用v1.20+版本的kubectl 将默认不显示managedFields

下面的cm 即通过SSAapply 的资源

代码语言:javascript
代码运行次数:0
复制
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: test-cm
  namespace: default
  labels:
    test-label: test
  managedFields:
  - manager: kubectl
    operation: Apply # 注意大写: “Apply” (或者 “Update”)
    apiVersion: v1
    time: "2010-10-10T0:00:00Z"
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:labels:
          f:test-label: {}
      f:data:
        f:key: {}
data:
  key: some value

根据以上输出的yamlmetadata.managedFields 字段,我们不难得出它想表达的含义:该configmapdata.key 字段都是由kubectl来管理的。manager: kubectl 为 kubectl ,如果最后更改该字段的请求是服务器端应用的patch操作,则operation 的值为 Apply;否则为 Update。

下面这个 deploy 是通过在阿里云上通过面板工具创建的,所以manager: okhttp 可以看到 通过 API 来操作资源也是使用过的Server-Side Apply 的方式, 并且管理的对象为整个资源对象

管理器(manager)识别出正在修改对象的工作流程(在冲突时尤其有用), 并且可以作为修改请求的一部分,通过 manager 查询参数来指定。 当你Apply 某个资源时,需要指定manager 参数。 对于其他更新,API 服务器使用 “User-Agent:” HTTP 头(如果存在)推断字段管理器标识(为什么是 okhttp)。

字段管理(field management)机制追踪对象字段的变化。 当一个字段值改变时,其所有权从当前管理器(manager)转移到施加变更的管理器。

当尝试将新配置应用到一个对象时,如果字段有不同的值,且由其他管理器管理, 将会引发冲突。冲突引发警告信号:此操作可能抹掉其他协作者的修改

冲突可以被刻意忽略,这种情况下,值将会被改写,所有权也会发生转移

当你使用kubectl 工具执行服务器端应用操作时,kubectl 默认情况下会将管理器标识设置为kubectl。下面的 yaml 中存在多个管理器的对象,

代码语言:javascript
代码运行次数:0
复制
liruilong@liruilongdeMacBook-Air .kube % kubectl get deploy ams-hotel-cloudr-server -n  defalut  -o yaml --show-managed-fields 
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "19"
  creationTimestamp: "2024-11-08T07:32:43Z"
  generation: 27
  labels:
    app: ams-hotel-cloudr-server
  managedFields:
  - apiVersion: apps/v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations: {}
        f:labels:
          .: {}
          f:app: {}
      f:spec:
        f:progressDeadlineSeconds: {}
        f:replicas: {}
        f:revisionHistoryLimit: {}
        f:selector: {}
        f:strategy:
          f:rollingUpdate:
            .: {}
            f:maxSurge: {}
            f:maxUnavailable: {}
          f:type: {}
        f:template:
          f:metadata:
            f:labels:
              .: {}
              f:app: {}
          f:spec:
            f:containers:
              k:{"name":"ams-hotel-cloudr-server"}:
                .: {}
                f:env:
                  .: {}
                  k:{"name":"TZ"}:
                    .: {}
                    f:name: {}
                    f:value: {}
                f:image: {}
                f:imagePullPolicy: {}
                f:name: {}
                f:ports:
                  .: {}
                  k:{"containerPort":8080,"protocol":"TCP"}:
                    .: {}
                    f:containerPort: {}
                    f:protocol: {}
                f:resources:
                  .: {}
                  f:requests:
                    .: {}
                    f:cpu: {}
                    f:memory: {}
                f:terminationMessagePath: {}
                f:terminationMessagePolicy: {}
            f:dnsPolicy: {}
            f:imagePullSecrets:
              .: {}
              k:{"name":"acck"}: {}
            f:restartPolicy: {}
            f:schedulerName: {}
            f:securityContext: {}
            f:terminationGracePeriodSeconds: {}
    manager: okhttp
    operation: Update
    time: "2024-11-21T09:49:35Z"
  - apiVersion: apps/v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          f:deployment.kubernetes.io/revision: {}
      f:status:
        f:availableReplicas: {}
        f:conditions:
          .: {}
          k:{"type":"Available"}:
            .: {}
            f:lastTransitionTime: {}
            f:lastUpdateTime: {}
            f:message: {}
            f:reason: {}
            f:status: {}
            f:type: {}
          k:{"type":"Progressing"}:
            .: {}
            f:lastTransitionTime: {}
            f:lastUpdateTime: {}
            f:message: {}
            f:reason: {}
            f:status: {}
            f:type: {}
        f:observedGeneration: {}
        f:readyReplicas: {}
        f:replicas: {}
        f:updatedReplicas: {}
    manager: kube-controller-manager
    operation: Update
    subresource: status
    time: "2024-11-21T09:49:44Z"
  name: ams-hotel-cloudr-server
  namespace: defalut
  resourceVersion: "21530560"
  uid: c9fb0c9c-2129-4ffe-9675-96e01c396289
spec:
   .....
liruilong@liruilongdeMacBook-Air .kube % 

可以看到两个update 操作,一个由okhttp 管理器操作,主要进行基础资源的定义,第二个由kube-controller-manager 管理器操作,进行一些元数据添加,主要为status 字段的添加。两个管理器没有直接的冲突。

这部分更多信息小伙伴可以官网了解;

https://kubernetes.io/zh-cn/docs/reference/using-api/server-side-apply/

apply 改变一个字段时,而恰巧该字段被其他用户声明了,此时会发生冲突。 这可以防止一个管理者不小心覆盖掉其他用户设置的值。

参考博客Demo:

https://juejin.cn/post/7173328614644006942

如果修改我们刚刚通过SSA创建的test-server-side-applyconfigmap,并且手动设置管理者为test(通过--field-manager字段),此时kubectl会拒绝我们的提交,提示冲突:

代码语言:javascript
代码运行次数:0
复制
$ kubectl apply --server-side=true --field-manager="test" -f - <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
  name: test-server-side-apply
data:
  a: "a"
  # 把b,改成c了。
  b: "c" 
EOF
error: Apply failed with 1 conflict: conflict with "kubectl": .data.b
Please review the fields above--they currently have other managers. Here
are the ways you can resolve this warning:
* If you intend to manage all of these fields, please re-run the apply
  command with the `--force-conflicts` flag.
* If you do not intend to manage all of the fields, please edit your
  manifest to remove references to the fields that should keep their
  current managers.
* You may co-own fields by updating your manifest to match the existing
  value; in this case, you'll become the manager if the other manager(s)
  stop managing the field (remove it from their configuration).
See https://kubernetes.io/docs/reference/using-api/server-side-apply/#conflicts


从kubectl返回的提示,我们可以得知当冲突发生的时我们有三种选择:

  • 覆盖前值,成为当前字段的唯一管理者——通过增加--force-conflicts flag
  • 不覆盖前值,放弃管理权——在本次配置中,把修改的字段删掉(本例中是data.b
  • 不覆盖前值,成为共享管理者——把冲突值改成和服务器对象一致

Kubernetes API资源类别

工作负载资源

工作负载资源负责管理和运行集群中的容器容器 是由控制器 通过Pod 创建的。Pods 运行容器并提供环境依赖,如共享网络环境,持久性存储卷和配置或注入容器密码数据。

Deployments

用于无状态的持久性应用(如HTTP服务器)。它可以实现PodReplicaSets 的声明式更新。

代码语言:javascript
代码运行次数:0
复制
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

template 字段用于声明Pod 模版,selector 用于约束 Pod 的选择器,replicas 为副本数

StatefulSets

用于有状态的持久化应用(如数据库)。 为Pod 提供持久存储持久标识符

代码语言:javascript
代码运行次数:0
复制
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx # has to match .spec.template.metadata.labels
  serviceName: "nginx"
  replicas: 3 # by default is 1
  minReadySeconds: 10 # by default is 0
  template:
    metadata:
      labels:
        app: nginx # has to match .spec.selector.matchLabels
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx
        image: registry.k8s.io/nginx-slim:0.24
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "my-storage-class"
      resources:
        requests:
          storage: 1Gi

在 StatefulSets中,serviceName字段是必须的,它指定了一个Headless Service的名称,该ServiceStatefulSet中的每个Pod提供了一个稳定的DNS名称和网络身份

volumeClaimTemplates 字段也是必须的,允许你为Pod 定义PersistentVolumeClaims(PVC)模板。这为每个Pod 提供了独立的持久化存储

HorizontalPodAutoscaler (HPA)

根据负载自动扩展工作负载的副本数量.

代码语言:javascript
代码运行次数:0
复制
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: php-apache-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: php-apache
  minReplicas: 1
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 50

根据需要自动调整 Pod 的数量,最少保持一个 Pod 在运行,最多可以扩展到 10 个 Pod,当平均 CPU 利用率超过50% 时触发伸缩操作

ControllerRevision

保存特定控制器版本的状态信息。ControllerRevision 实现了状态数据的不可变快照。客户端负责序列化和反序列化对象,包含对象内部状态。 成功创建ControllerRevision 后,将无法对其进行更新。 API 服务器将无法成功验证所有尝试改变 data 字段的请求。 但是,可以删除ControllerRevisions。 请注意,由于DaemonSetStatefulSet 控制器都使用它来进行更新和回滚,所以这个对象是Beta 版。

代码语言:javascript
代码运行次数:0
复制
apiVersion: apps/v1
kind: ControllerRevision
metadata:
  name: example-controllerrevision
  namespace: default
  labels:
    app: example-app
spec:
  revision: 2
  selector:
    matchLabels:
      app: example-app
  template:
    metadata:
      labels:
        app: example-app
    spec:
      containers:
      - name: example-container
        image: nginx:1.16.1
        ports:
        - containerPort: 80
Jobs/CronJob

用于(周期)运行完成的应用程序的Job(如批处理Job),类似定时任务,只是线程变成了 Pod

代码语言:javascript
代码运行次数:0
复制
apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  template:
    spec:
      containers:
      - name: pi
        image: perl:5.34.0
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never
  backoffLimit: 4

周期性Job

代码语言:javascript
代码运行次数:0
复制
apiVersion: batch/v1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "* * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox:1.28
            imagePullPolicy: IfNotPresent
            command:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster
          restartPolicy: OnFailure

restartPolicy 定义了当Pod 失败时应该如何处理

DaemonSet

用于节点守护应用,确保全部(或者某些)节点上运行一个Pod 的副本。类似守护进程一样,当节点存在对应的Pod 就会存在

代码语言:javascript
代码运行次数:0
复制
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd-elasticsearch
  namespace: kube-system
  labels:
    k8s-app: fluentd-logging
spec:
  selector:
    matchLabels:
      name: fluentd-elasticsearch
  template:
    metadata:
      labels:
        name: fluentd-elasticsearch
    spec:
      tolerations:
      # these tolerations are to have the daemonset runnable on control plane nodes
      # remove them if your control plane nodes should not run pods
      - key: node-role.kubernetes.io/control-plane
        operator: Exists
        effect: NoSchedule
      - key: node-role.kubernetes.io/master
        operator: Exists
        effect: NoSchedule
      containers:
      - name: fluentd-elasticsearch
        image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
        resources:
          limits:
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 200Mi
        volumeMounts:
        - name: varlog
          mountPath: /var/log
      # it may be desirable to set a high priority class to ensure that a DaemonSet Pod
      # preempts running Pods
      # priorityClassName: important
      terminationGracePeriodSeconds: 30
      volumes:
      - name: varlog
        hostPath:
          path: /var/log

一般会结合亲和性做一些配置,用于集群监控,收集每个节点的指标数据,或者网络代理等。

ReplicaSet

ReplicaSet 的目的是维护一组在任何时候都处于运行状态的 Pod 副本的稳定集合。 一般不会主动创建

代码语言:javascript
代码运行次数:0
复制
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: frontend
  labels:
    app: guestbook
    tier: frontend
spec:
  # modify replicas according to your case
  replicas: 3
  selector:
    matchLabels:
      tier: frontend
  template:
    metadata:
      labels:
        tier: frontend
    spec:
      containers:
      - name: php-redis
        image: us-docker.pkg.dev/google-samples/containers/gke/gb-frontend:v5

ReplicationController

在k8s之前的版本用于无状态应用部署,现在推荐使用deployment

代码语言:javascript
代码运行次数:0
复制
apiVersion: v1
kind: ReplicationController
metadata:
  name: nginx
spec:
  replicas: 3
  selector:
    app: nginx
  template:
    metadata:
      name: nginx
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80

Pod

简单讲,Pod为一组容器,这组容器共享存储,网络,命名空间以及运行容器的一些声明,是在 K8s 中创建管理的最小的可部署的计算单元, Pod 所建模的是特定于应用的 “逻辑主机”。

代码语言:javascript
代码运行次数:0
复制
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2
    ports:
    - containerPort: 80

Binding

Binding 将一个对象与另一个对象绑定在一起;例如,调度程序将一个 Pod 绑定到一个节点。1.7 版中已弃用

PodTemplate

定义Pod模板。

Container

单个容器,容器只能在Pod 中创建,通常通过 控制器来完成,单个 Pod 中的容器会在共同调度下,于同一位置运行在相同的节点上。

代码语言:javascript
代码运行次数:0
复制
  containers:
  - name: nginx
    image: nginx:1.14.2
    ports:
    - containerPort: 80
PodSchedulingContext

控制Pod调度相关的资源。PodSchedulingContext 对象包含使用 "WaitForFirstConsumer" 分配模式的ResourceClaims 来调度Pod 所需的信息。

关于动态资源 部分,当前1.31 版本中,需要显式启用,动态资源分配是一个用于在 Pod 之间和 Pod 内部容器之间请求和共享资源的 API。我没怎么接触,这里不做整理,感兴趣小伙伴可以看看官网文档。

https://kubernetes.io/zh-cn/docs/concepts/scheduling-eviction/dynamic-resource-allocation/

PriorityClass

定义Pod 优先级。在一个并非所有用户都是可信的集群中,恶意用户可能以最高优先级创建 Pod, 导致其他 Pod 被驱逐或者无法被调度。 管理员可以使用 ResourceQuota 来阻止用户创建高优先级的 Pod

代码语言:javascript
代码运行次数:0
复制
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: high-priority
value: 1000000 # 优先级值
globalDefault: false # 不是全局默认优先级
description: "此优先级类应仅用于 XYZ 服务 Pod。"

没有指定preemptionPolicy,因此在默认情况下,如果集群资源不足,使用这个优先级类的 Pod 可能会抢占(驱逐)低优先级的 Pod 以获取所需的资源。

代码语言:javascript
代码运行次数:0
复制
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: high-priority-nonpreempting
value: 1000000
preemptionPolicy: Never #使用这个优先级类的 Pod 永远不会抢占(驱逐)其他 Pod
globalDefault: false
description: "This priority class will not cause other pods to be preempted."

创建Pod,并将其priorityClassName 设置为新增的PriorityClass

服务资源

服务资源负责将你的工作负载拼接成一个可访问的负载均衡服务。默认情况下,工作负载只能在集群内访问,外部访问必须使用LoadBalancerNodePort服务在外部公开。

Service

用于在多个工作负载副本中提供单一端点负载平衡。并且提供相同的访问方式。在集群中通过DNS 访问

代码语言:javascript
代码运行次数:0
复制
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app.kubernetes.io/name: MyApp
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 9376
Ingress

简单讲,类似一个反向代理,可以理解为Haproxy 或者Nginx ,一个规则集合,对集群中服务的外部访问进行管理的 API 对象,允许入站连接到后端定义某个端点。提供一个https(s)端点路由到一个或多个服务。

代码语言:javascript
代码运行次数:0
复制
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: minimal-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx-ingress
  rules:
  - http:
      paths:
      - path: /testpath
        pathType: Prefix
        backend:
          service:
            name: test
            port:
              number: 80

元数据中的annotations 字段nginx.ingress.kubernetes.io/rewrite-target 用于指定路由跳转,所有匹配/testpath前缀的请求在转发到后端服务时,其 URL 路径被重写为/

ingressClassName: 用于明确指定 Ingress 类,即提供能力的后端控制器,Kubernetes 1.18 及更高版本中引入的字段,在低版本中一般会在元数据的注解中声明kubernetes.io/ingress.class: "nginx" 用于指定 Ingress 控制器。

这里需要注意使用Ingress 进行负载分发时,Ingress Controller 基于Ingress 规则将客户端请求直接转发到Service 对应的后端Endpoint (Pod) 上,这样会跳过kube-proxy 的转发功能,kube-proxy不再起作用。如果IngressController提供的是对外服务,则实际上实现的是边缘路由器的功能。

其他资源类型:

Endpoints

是实现实际服务的后端Pod端点的集合。1.21 以及之后的版本,Endpoints 同时会生成EndpointSlicp

代码语言:javascript
代码运行次数:0
复制
apiVersion: v1
kind: Endpoints
metadata:
  creationTimestamp: "2024-11-11T02:14:27Z"
  name: ams-hotel-xxl-job-svc
  namespace: smart-campus
  resourceVersion: "18254844"
  uid: 4f5b5662-5c7a-48ad-a386-49a5ecfbde7c
subsets:
- addresses:
  - ip: 172.27.99.11
    nodeName: cn-huhehaote.10.1.20.40
    targetRef:
      kind: Pod
      name: ams-hotel-xxl-job-74c66f67bd-fjz4x
      namespace: smart-campus
      uid: 8948324e-0289-4a04-8a2d-7174252b011c
  ports:
  - port: 8888
    protocol: TCP
EndpointSlice

代表实现服务的后端Pod端点的一个子集。当Endpoints 超过100个,会形成新的 EndpointSlice

代码语言:javascript
代码运行次数:0
复制
apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
  name: example-abc
  labels:
    kubernetes.io/service-name: example
addressType: IPv4
ports:
  - name: http
    protocol: TCP
    port: 80
endpoints:
  - addresses:
      - "10.1.2.3"
    conditions:
      ready: true
    hostname: pod-1
    nodeName: node-1
    zone: us-west2-a
Ingress controller

Ingress 资源的后端实现,集群必须有一个正在运行的 Ingress 控制器。可以理解为 Ingress 的后端,提供实际的负载能力,

Ingress-nginx 为Demo,实际上就是一个集群中的的流量入口,本质是上一个 Nginx 无状态控制器 作反向代理,可以配置路由规则。

IngressClass

IngressClass 表示 Ingress 的类别,由 Ingress Spec 引用。指定实现的Ingress Controller 名称,建立Ingress 和 Ingress controller 之间的关系。

代码语言:javascript
代码运行次数:0
复制
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  name: nginx-ingress
  labels:
    app: nginx-ingress
spec:
  controller: k8s.io/ingress-nginx
  parameters:
    apiGroup: k8s.io
    kind: IngressParameters
    name: default-backend-parameters

配置和存储资源

服务资源负责将你的工作负载拼接,通过环境变量、命令行参数或文件注入到应用程序中。

常见的资源类型:

ConfigMap

持有供pod使用的配置数据。对应实际应用中的配置文件,它提供文本键值对,通过环境变量命令行参数文件注入到应用程序中。

代码语言:javascript
代码运行次数:0
复制
apiVersion: v1
kind: ConfigMap
metadata:
  name: game-demo
data:
  # property-like keys; each key maps to a simple value
  player_initial_lives: "3"
  ui_properties_file_name: "user-interface.properties"

  # file-like keys
  game.properties: |
    enemy.types=aliens,monsters
    player.maximum-lives=5    
  user-interface.properties: |
    color.good=purple
    color.bad=yellow
    allow.textmode=true 
Secrets

保存某种类型的秘密数据。它提供二进制数据,通过文件注入到应用程序中。对应实际应用中的密码,连接串等数据。

代码语言:javascript
代码运行次数:0
复制
apiVersion: v1
kind: Secret
metadata:
  name: dotfile-secret
data:
  .secret-file: dmFsdWUtMg0KDQo=
---
apiVersion: v1
kind: Pod
metadata:
  name: secret-dotfiles-pod
spec:
  volumes:
    - name: secret-volume
      secret:
        secretName: dotfile-secret
  containers:
    - name: dotfile-test-container
      image: registry.k8s.io/busybox
      command:
        - ls
        - "-l"
        - "/etc/secret-volume"
      volumeMounts:
        - name: secret-volume
          readOnly: true
          mountPath: "/etc/secret-volume"
Volumes

用于提供容器外部的文件系统。可能在同一Pod 内的不同容器之间共享,并具有超越容器或Pod的持久性。不作为一个单独的API 存在,有多种后端实现

代码语言:javascript
代码运行次数:0
复制
apiVersion: v1
kind: Pod
metadata:
  name: configmap-pod
spec:
  containers:
    - name: test
      image: busybox:1.28
      command: ['sh', '-c', 'echo "The app is running!" && tail -f /dev/null']
      volumeMounts:
        - name: config-vol
          mountPath: /etc/config
  volumes:
    - name: config-vol
      configMap:
        name: log-config
        items:
          - key: log_level
            path: log_level

Pod 中通过volumes 挂载上面的configMap

PersistentVolumeClaim(PVC)

PersistentVolumeClaim(PVC)是一种声明式方式来请求存储资源。它允许用户以一种与特定存储后端无关的方式请求存储空间,而不需要了解底层存储的具体实现细节,PV,PVCSCLVM 的思想有些类似,化零为整,动态分配

代码语言:javascript
代码运行次数:0
复制
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: myclaim
spec:
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem
  resources:
    requests:
      storage: 8Gi
  storageClassName: slow
  selector:
    matchLabels:
      release: "stable"
    matchExpressions:
      - {key: environment, operator: In, values: [dev]}

PersistentVolume(PV)

是一个由管理员提供的存储资源。直接映射到每个Pod,代表集群中的一块持久化存储空间。PV 可以由管理员预先创建,也可以由存储类(Storage Class)动态创建。PV ,PVC 之类属于集群资源,不基于命名空间隔离

代码语言:javascript
代码运行次数:0
复制
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv0003
spec:
  capacity:
    storage: 5Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  storageClassName: slow
  mountOptions:
    - hard
    - nfsvers=4.1
  nfs:
    path: /tmp
    server: 172.17.0.2
StorageClass

描述了一个可以动态配置PersistentVolumes 的存储类别的参数。用户可以通过指定 Storage Class 来选择不同的存储后端,如云提供商的存储服务、本地存储、网络存储等

代码语言:javascript
代码运行次数:0
复制
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: example-vol-default
provisioner: vendor-name.example/magicstorage
parameters:
  resturl: "http://192.168.10.100:8080"
  restuser: ""
  secretNamespace: ""
  secretName: ""
allowVolumeExpansion: true
VolumeAttachment

VolumeAttachment 抓取将指定卷挂接到指定节点或从指定节点解除挂接指定卷的意图,VolumeAttachment 对象未划分命名空间。

表示一个卷(通常是持久卷 Persistent Volume,PV)被绑定到某个节点的状态,确保卷在 Pod 需要时已挂载在指定节点,便于后续 CSI 驱动程序将其挂载到容器中,维护卷和节点的绑定关系,记录卷在哪些节点上可用

代码语言:javascript
代码运行次数:0
复制
apiVersion: storage.k8s.io/v1
kind: VolumeAttachment
metadata:
  annotations:
    csi.alpha.kubernetes.io/node-id: test-vpc-k8s-worker06
# 注解中指定了 node-id,用来表明该 VolumeAttachment 所属的节点;这有助于 CSI 驱动定位挂载目标节点
finalizers:
  - external-attacher/evs-csi-huawei-cn
# 这里 external-attacher/evs-csi-huawei-cn 表示该卷在删除前需要由 evs-csi-huawei-cn 驱动的 external-attacher 进行卸载操作
# 只有在 ControllerUnpublishVolume 成功完成并移除 finalizer 后,VolumeAttachment 才会真正被删除
name: csi-0dc8eaebe8d1f7dc6e035ec06be0dc926f17e7da71edda5fe7a0cdda34d774bc
# csi-0dc8eaebe8d1f7dc6e035ec06be0dc926f17e7da71edda5fe7a0cdda34d774bc VolumeAttachment 对象的名称;
# 通常由 CSI 驱动生成一个唯一的 ID,用于标识此挂载请求
spec:
  attacher: evs-csi-huawei-cn
# 用于指定 CSI 驱动的名称,表明哪个驱动程序负责处理此挂载请求
  nodeName: test-vpc-k8s-worker06
# 指定将卷挂载到的节点名称
  source:
    persistentVolumeName:pvc-19ea9ae8-8b42-45ad-9bcf-7ba216c1c87c
status:
  # 表示挂载状态,通常由 CSI 驱动更新
  attached: true
  # 布尔值,表示卷是否已成功挂载
  attachmentMetadata:
    # 可选字段,包含 CSI 驱动在挂载过程中生成的元数据(例如设备路径)
    evs-csi-huawei-cn/volume-name:pvc-19ea9ae8-8b42-45ad-9bcf-7ba216c1c87c
VolumeAttributesClass

存储类资源(StorageClass)的补充,用来控制存储卷的行为,比如性能参数、备份策略等

代码语言:javascript
代码运行次数:0
复制
apiVersion: storage.k8s.io/v1beta1
kind: VolumeAttributesClass
metadata:
  name: silver
driverName: pd.csi.storage.gke.io
parameters:
  provisioned-iops: "3000"
  provisioned-throughput: "50" 
------
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: example-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  volumeAttributesClassName: example-va-class

provisioned-iops:指定预配置的IOPS(每秒输入/输出操作数)为3000

CSIDriver

捕获有关部署在集群上的容器存储接口(CSI)卷驱动器的信息。使用CSIDriver资源来注册和管理CSI驱动程序,确保驱动程序与Kubernetes API服务器正确交互。一般由存储厂商实现

代码语言:javascript
代码运行次数:0
复制
apiVersion: storage.k8s.io/v1
kind: CSIDriver
metadata:
  name: my-csi-driver
spec:
  attachRequired: true
  podInfoOnMount: true
  volumeLifecycleModes:
    - Persistent
  storageCapacity: true
  topologyAware: true
StorageVersionMigration

StorageVersionMigration 表示存储的数据向最新存储版本的一次迁移。这里的版本是只apiVersion: v1 中的版本

代码语言:javascript
代码运行次数:0
复制
kind: StorageVersionMigration
apiVersion: storagemigration.k8s.io/v1alpha1
metadata:
  name: secrets-migration
spec:
  resource:
    group: ""
    version: v1
    resource: secrets

如果你想迁移secrets资源 到 V1 版本

认证

下面API 资源用于身份认证

TokenRequest

TokenRequest 为给定的服务账号SA请求一个令牌

代码语言:javascript
代码运行次数:0
复制
apiVersion: authentication.k8s.io/v1
kind: TokenRequest
spec:
  audiences:
  - "https://example.com"  # 这里应该填写你希望令牌有效的受众(audience),通常是 API 服务器的地址或某个特定的服务
  boundObjectRef:
    apiVersion: v1
    kind: ServiceAccount
    name: your-service-account-name  # 替换为你的服务账户名称
    namespace: your-namespace  # 替换为你的命名空间
  expirationSeconds: 86400  # 令牌的过期时间(秒),默认为1小时(3600秒),这里设置为24小时

令牌可以用于身份验证和授权,以便访问 Kubernetes API 或其他需要身份验证的资源。

TokenReview

TokenReview 尝试通过验证令牌来确认已知用户。 注意:TokenReview 请求可能会被 kube-apiserver 中的 webhook 令牌验证器插件缓存。

代码语言:javascript
代码运行次数:0
复制
apiVersion: authentication.k8s.io/v1
kind: TokenReview
spec:
  token: <YOUR_TOKEN_HERE>

apply 之后填充的数据

代码语言:javascript
代码运行次数:0
复制
{
  "apiVersion": "authentication.k8s.io/v1",
  "kind": "TokenReview",
  "status": {
    "authenticated": true,
    "user": {
      "username": "system:serviceaccount:<your-namespace>:<your-service-account>",
      "uid": "<uid>",
      "groups": [
        "system:serviceaccounts",
        "system:serviceaccounts:<your-namespace>",
        "system:authenticated"
      ],
      "extra": {
        "kubernetes.io/serviceaccount/namespace": [
          "<your-namespace>"
        ],
        "kubernetes.io/serviceaccount/secret.name": [
          "<your-secret-name>"
        ],
        "kubernetes.io/serviceaccount/secret.uid": [
          "<secret-uid>"
        ],
        "kubernetes.io/serviceaccount/name": [
          "<your-service-account>"
        ]
      }
    }
  }
}

如果authenticated 字段为true,则表示令牌是有效的,并且响应中的user 字段包含了与该令牌关联的用户信息。

ServiceAccount

服务账号,用于为 Pod 提供相对于集群管理的身份验证凭据,简单来讲,用于为 Pod 提供访问集群的能力,Pod 中访问 集群需要做认证和授权,sa 通过 token 认证,通过 绑定的角色,基于RBAC 授权。

代码语言:javascript
代码运行次数:0
复制
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    app: metallb
  name: controller
  namespace: metallb-system
SelfSubjectReview

SelfSubjectReview 包含kube-apiserver 所拥有的与发出此请求的用户有关的用户信息。

代码语言:javascript
代码运行次数:0
复制
apiVersion: authorization.k8s.io/v1
kind: SelfSubjectReview

在官方文档中,SelfSubjectReview 资源被归纳到身份认证资源,而不是鉴权资源

可以看到具体的用户信息,所属的组,以及角色和权限

代码语言:javascript
代码运行次数:0
复制
apiVersion: authentication.k8s.io/v1alpha1
kind: SelfSubjectReview
status:
  userInfo:
    username: jane.doe
    uid: b79dbf30-0c6a-11ed-861d-0242ac120002
    groups:
    - students
    - teachers
    - system:authenticated
    extra:
      skills:
      - reading
      - learning
      subjects:
      - math
      - sports
CertificateSigningRequest

用于请求签名证书。要创建一个指定权限的kubeconfig 文件的话,我们需要一个私钥,以及集群CA 授权颁发的证书。不能直接用私钥生成公钥,而必须是用私钥生成证书请求文件(申请书),然后根据证书请求文件CA(权威机构)申请证书(身份证),CA 审核通过之后会颁发证书。

上面讲的 申请证书 即为CertificateSigningRequest

代码语言:javascript
代码运行次数:0
复制
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: liruilong
spec:
  signerName: kubernetes.io/kube-apiserver-client
  request: LS0tLS1CRUdJTiBDRVJUSUZJ...............
  usages:
  - client auth

之后需要通过批准证书

代码语言:javascript
代码运行次数:0
复制
kubectl certificate approve liruilong
ClusterTrustBundle

用于管理集群中的信任证书。ClusterTrustBundle 是一个集群范围的容器,用于存放X.509 信任锚(根证书)。 当前为v1alpha1 版本.

可以被集群中的任何经过身份验证的用户读取

代码语言:javascript
代码运行次数:0
复制
apiVersion: certificates.k8s.io/v1alpha1
kind: ClusterTrustBundle
metadata:
  name: example-trust-bundle
spec:
  trustBundle: |
    -----BEGIN CERTIFICATE-----
    MIIDQTCCAimgAwIBAgIThAOxVoDEnEXQfankuXrJestQDzANBgkqhkiG9w0BAQsF
    ADAVMRMwEQYDVQQDEwpleGFtcGxlLmNvbTAeFw0xNTEyMTYwMTI1MjZaFw0yMDEy
    MTUwMTI1MjZaMBUxEzARBgNVBAMTCmV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0B
    AQEFAAOCAQ8AMIIBCgKCAQEA7bYaCSHxc91o4LRXzxxtVufus1OqV6dMJFEKTIE5
    z23f6BbQoiX4kS/ALCaRj+BPJj+IxstD7M0iDCHVH0jW43yDK2qai0FvgZPuD9vY
    -----END CERTIFICATE-----
    -----BEGIN CERTIFICATE-----
    MIIDAzCCAeugAwIBAgIQCHMGwmqMm8SQR/vdxwIrODANBgkqhkiG9w0BAQsFADAV
    MRMwEQYDVQQDEwpleGFtcGxlLmNvbTAeFw0xNTEyMTYwMTI1MjZaFw0yMDEyMTUw
    MTI1MjZaMBUxEzARBgNVBAMTCmV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEF
    AAOCAQ8AMIIBCgKCAQEA7bYaCSHxc91o4LRXzxxtVufus1OqV6dMJFEKTIE5z23f
    6BbQoiX4kS/ALCaRj+BPJj+IxstD7M0iDCHVH0jW43yDK2qai0FvgZPuD9vYKKGs
    -----END CERTIFICATE-----
  signerName: example.com/my-signer

鉴权

SelfSubjectAccessReview

鉴权这部分资源API文档地址

https://kubernetes.io/zh-cn/docs/reference/kubernetes-api/authorization-resources/

SelfSubjectAccessReview(SSAR) 检查当前用户是否可以执行某操作。 不填写spec.namespace 表示 “在所有命名空间中”。Self 是一个特殊情况,因为用户应始终能够检查自己是否可以执行某操作。

代码语言:javascript
代码运行次数:0
复制
apiVersion: authorization.k8s.io/v1
kind: SelfSubjectAccessReview
metadata:
  name: check-create-pods-in-namespace
spec:
  resourceAttributes:
    namespace: "default"  # 替换为你要检查的命名空间
    verb: "create"
    resource: "pods"
LocalSubjectAccessReview

LocalSubjectAccessReview(LSAR)SubjectAccessReview(SAR)都是K8s 中用于权限检查的API对象,关键的区别在于作用域不同:

  • SubjectAccessReview(SAR):用于检查集群范围内的权限。它可以检查特定用户用户组在集群中的任何命名空间下是否有权执行特定操作。
  • LocalSubjectAccessReview(LSAR):用于检查特定命名空间内的权限。它只能检查在指定命名空间下,特定用户用户组是否有权执行特定操作。

LocalSubjectAccessReview 检查用户或组是否可以在给定的命名空间内执行某操作。

LocalSubjectAccessReview 与上面SelfSubjectAccessReview 区别是SelfSubjectAccessReview 是用于评估当前用户自身的权限,self 这个关键字小伙伴们应该不陌生

SelfSubjectAccessReview 不需要指定主体,因为它默认评估当前用户LocalSubjectAccessReview 需要指定要评估的用户或组,即下面配置文件中usergroup部分。

代码语言:javascript
代码运行次数:0
复制
apiVersion: authorization.k8s.io/v1
kind: LocalSubjectAccessReview
spec:
  subjectAccessReviewSpec:
    resourceAttributes:
      namespace: default
      verb: get
      group: apps
      resource: deployments
    user: alice
    group:
    - team-a
    - team-b

上面的 Demo,用于检查用户alice 和组team-ateam-b 是否有 命名空间 中 无状态应用的 get 权限.

apply 上面的资源声明,可以在statusallowed字段下看到是否拥有权限

代码语言:javascript
代码运行次数:0
复制
status:
  allowed: true
SubjectAccessReview

SubjectAccessReview :检查一个用户在整个集群中的权限,无论在哪个命名空间下,你应该使用SAR

对于SubjectAccessReview(SAR),这里没有命名空间资源,意味着作用在所有的命名空间

代码语言:javascript
代码运行次数:0
复制
apiVersion: authorization.k8s.io/v1
kind: SubjectAccessReview
metadata:
  name: check-pods-list-cluster-wide
spec:
  user: "example-user"
  resourceAttributes:
    verb: "list"
    resource: "pods"
SelfSubjectRulesReview

SelfSubjectRulesReview(SSRR) 枚举当前用户可以在某命名空间内执行的操作集合。返回的操作列表可能不完整,具体取决于服务器的鉴权模式以及评估过程中遇到的任何错误。

代码语言:javascript
代码运行次数:0
复制
apiVersion: authorization.k8s.io/v1
kind: SelfSubjectRulesReview
spec:
  namespace: default

apply 之后返回的结果大概是这个样子

代码语言:javascript
代码运行次数:0
复制
apiVersion: authorization.k8s.io/v1
kind: SelfSubjectRulesReview
status:
  evaluationError: ""
  incomplete: false
  nonResourceRules:
  - apiGroups: [""]
    nonResourceURLs: ["/healthz", "/version", "/openapi/*"]
    verbs: ["get"]
  resourceRules:
  - apiGroups: ["apps", ""]
    resourceNames: []
    resources: ["deployments", "replicasets", "pods"]
    verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
Role

用于定义命名空间范围内的角色

角色(Role) 一个角色就是一组权限的集合。在同一个命名空间中,可以用Role来定义一个角色,如果是集群级别的,就需要使用ClusterRole了`。角色只能对命名空间内的资源进行授权

代码语言:javascript
代码运行次数:0
复制
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  labels:
    app: metallb
  name: controller
  namespace: metallb-system
rules:
- apiGroups:
  - ''
  resources:
  - secrets
  verbs:
  - create
- apiGroups:
  - ''
  resources:
  - secrets
  resourceNames:
  - memberlist
  verbs:
  - list
- apiGroups:
  - apps
  resources:
  - deployments
  resourceNames:
  - controller
  verbs:
  - get
RoleBinding

RoleBinding 用来把一个角色绑定到一个目标上,绑定目标可以是User (用户) 、Group (组)或者Service Account

代码语言:javascript
代码运行次数:0
复制
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  labels:
    app: metallb
  name: controller
  namespace: metallb-system
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: controller
subjects:
- kind: ServiceAccount
  name: controller

这里绑定到了 controller 这个 sa 上

ClusterRole

用于定义集群范围内的角色。ClusterRole集群角色,基于RBAC 的鉴权,角色申明方式为资源+动作

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-12-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 山河已无恙 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 写在前面
  • Kubernetes API概述
    • API 资源组成
    • API资源的操作
      • CSA & SSA
    • Kubernetes API资源类别
      • 工作负载资源
      • 服务资源
      • 配置和存储资源
      • 认证
      • 鉴权
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档