4.k8s:cronJob计划任务,初始化容器,污点、容忍,亲和力,身份认证和权限

一、高级调度

1.CronJob 计划任务

在 k8s 中周期性运行计划任务,与 linux 中的 crontab 相同。

注意点:CronJob 执行的时间是 controller-manager 的时间,所以一定要确保 controller-manager 时间是准确的

(1)cron表达式

* * * * *
分钟、小时、天、月、周几

周几:0表示周日,1表示周一

(2)cron示例

cd /opt/k8s/
mkdir jobs
cd jobs/
vim cron-job-pd.yaml

##############################################################
apiVersion: batch/v1
kind: CronJob #定时任务
metadata:
  name: cron-job-test #定时任务名字
spec:
  concurrencyPolicy: Allow # 并发调度策略:Allow 允许并发调度,Forbid:不允许并发执行,Replace:如果之前的任务还没执行完,就直接执行新的,放弃上一个任务
  failedJobsHistoryLimit: 1 # 保留多少个失败的任务
  successfulJobsHistoryLimit: 3 # 保留多少个成功的任务
  suspend: false # 是否挂起任务,若为 true 则该任务不会执行
#  startingDeadlineSeconds: 30 # 间隔多长时间检测失败的任务并重新执行,时间不能小于 10
  schedule: "* * * * *" # 调度策略
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: busybox
            image: busybox:1.28
            imagePullPolicy: IfNotPresent
            command:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster
          restartPolicy: OnFailure
##############################################################

#启动
kubectl create -f cron-job-pd.yaml 
kubectl get cj cron-job-test
kubectl get po
kubectl logs -f cron-job-test-28703645-8rdgv

2.初始化容器 InitContainer

在真正的容器启动之前,先启动 InitContainer,在初始化容器中完成真实容器所需的初始化操作,完成后再启动真实的容器。

相对于 postStart 来说,首先 InitController 能够保证一定在 EntryPoint 之前执行,而 postStart 不能,其次 postStart 更适合去执行一些命令操作,而 InitController 实际就是一个容器,可以在其他基础容器环境下执行更复杂的初始化功能。

注意放置的位置:

spec:
  initContainers:
  - image: nginx
    imagePullPolicy: IfNotPresent
    command: ["sh", "-c", "echo 'inited;' >> ~/.init"]
    name: init-test

3.污点(Taint)和容忍(Toleration)

(1)概念

污点(Taint):主节点很重要,一般不想把很多不相干的任务放在主节点上执行,因此我们给主节点打污点,那么任务就不会放置到主节点上。

  • NoSchedule:如果不能容忍该污点,那么 Pod 就无法调度到该节点上。但是已经存在的会继续保留

  • NoExecute:

    • 如果 Pod 不能忍受这类污点,Pod 会马上被驱逐。
    • 如果 Pod 能够忍受这类污点,但是在容忍度定义中没有指定 tolerationSeconds, 则 Pod 还会一直在这个节点上运行。
    • 如果 Pod 能够忍受这类污点,而且指定了 tolerationSeconds, 则 Pod 还能在这个节点上继续运行这个指定的时间长度。

容忍(Toleration):任务如果不配置容忍,不会部署到主节点上。但是如果配置了容忍,而主节点的污点正好匹配了这个容忍,则任务可以部署到主节点。

  • Equal:比较操作类型为 Equal,则意味着必须与污点值做匹配,key/value都必须相同,才表示能够容忍该污点

  • Exists:容忍与污点的比较只比较 key,不比较 value,不关心 value 是什么东西,只要 key 存在,就表示可以容忍。

(2)操作示例

#给kubernete141添加污点,并且是NoSchedule类型
kubectl taint node kubernete141 key=value:NoSchedule

#查看,能够看到这个污点信息
kubectl describe no kubernete141 

#移除污点
kubectl taint node kubernete141 key=value:NoSchedule-

kubectl edit deploy nginx-deploy

##########################################
spec:
  template:
    spec:
      tolerations:
      - key: "memory"
        operator: "Equal"
        value: "low"
        effect: "NoSchedule"
##########################################

kubectl get po -o wide


##########################################
spec:
  template:
    spec:
      tolerations:
      - key: "memory"
        operator: "Exists"
        effect: "NoSchedule"
##########################################

4.亲和力

污点主要是驱逐为主,不适配的驱逐走。亲和力主要是优先适配。

(1)节点亲和力:NodeAffinity

硬亲和力(RequiredDuringSchedulingIgnoredDuringExecution):即支持必须部署在指定的节点上,也支持必须不部署在指定的节点上

软亲和力(PreferredDuringSchedulingIgnoredDuringExecution):尽量部署在满足条件的节点上,或尽量不要部署在被匹配的节点上

kubectl edit deploy nginx-deploy

############################################################################
spec:
  template:
    spec:
      affinity: # 亲和力配置
        nodeAffinity: # 节点亲和力
          requiredDuringSchedulingIgnoredDuringExecution: # 节点必须匹配下方配置
            nodeSelectorTerms: # 选择器
            - matchExpressions: # 匹配表达式
              - key: topology.kubernetes.io/zone # 匹配 label 的 key
                operator: In # 匹配方式,只要匹配成功下方的一个 value 即可
                values:
                - antarctica-east1 # 匹配的 value
                - antarctica-west1 # 匹配的 value
          preferredDuringSchedulingIgnoredDuringExecution: # 节点尽量匹配下方配置
          - weight: 1 # 权重[1,100],按照匹配规则对所有节点累加权重,最终之和会加入优先级评分,优先级越高被调度的可能性越高
            preference:
              matchExpressions: # 匹配表达式
              - key: another-node-label-key # label 的 key
                operator: In # 匹配方式,满足一个即可
                values:
                - another-node-label-value # 匹配的 value
############################################################################


#打标签
kubectl label no kubernete141 topology.kubernetes.io/zone=antarctica-east1
kubectl label no kubernete142 topology.kubernetes.io/zone=antarctica-east1
kubectl label no kubernete141 another-node-label-key=another-node-label-value

#可以看到都去了141
kubectl get po -o wide

匹配类型

  • In:满足一个就行

  • NotIn:一个都不能满足,反亲和性

  • Exists:只要存在就满足

  • DoesNotExist:不存在就满足

  • Gt:大于

  • Lt:小于

(2)PodAffinity:pod亲和性

将与指定 pod 亲和力相匹配的 pod 部署在同一节点。前提是必须已经有一个pod了。

apiVersion: v1
kind: Pod
metadata:
  name: with-pod-affinity
spec:
  affinity: # 亲和力配置
    podAffinity: # pod 亲和力配置
      requiredDuringSchedulingIgnoredDuringExecution: # 当前 pod 必须匹配到对应条件 pod 所在的 node 上
      - labelSelector: # 标签选择器
          matchExpressions: # 匹配表达式
          - key: security # 匹配的 key
            operator: In # 匹配方式
            values: # 匹配其中的一个 value
            - S1
        topologyKey: topology.kubernetes.io/zone #节点必须要有这个标签
    podAntiAffinity: # pod 反亲和力配置
      preferredDuringSchedulingIgnoredDuringExecution: # 尽量不要将当前节点部署到匹配下列参数的 pod 所在的 node 上
      - weight: 100 # 权重
        podAffinityTerm: # pod 亲和力配置条件
          labelSelector: # 标签选择器
            matchExpressions: # 匹配表达式
            - key: security # 匹配的 key
              operator: In # 匹配的方式
              values:
              - S2 # 匹配的 value
          topologyKey: topology.kubernetes.io/zone
  containers:
  - name: with-pod-affinity
    image: pause:2.0

二、身份认证与权限

Kubernetes 中提供了良好的多租户认证管理机制,如 RBAC、ServiceAccount 还有各种策略等。

通过该文件可以看到已经配置了 RBAC 访问控制:/usr/lib/systemd/system/kube-apiserver.service

(1)服务账户和普通账户

所有 Kubernetes 集群有两类用户:由 Kubernetes 管理的Service Accounts (服务账户)和(Users Accounts) 普通账户。

普通账户是假定被外部或独立服务管理的,由管理员分配 keys,用户像使用 Keystone 或 google 账号一样,被存储在包含 usernames 和 passwords 的 list 的文件里。

需要注意:在 Kubernetes 中不能通过 API 调用将普通用户添加到集群中。

  • 普通帐户是针对(人)用户的,服务账户针对 Pod 进程
  • 普通帐户是全局性。在集群所有namespaces中,名称具有惟一性。
  • 通常,群集的普通帐户可以与企业数据库同步,新的普通帐户创建需要特殊权限。服务账户创建目的是更轻量化,允许集群用户为特定任务创建服务账户。
  • 普通帐户和服务账户的审核注意事项不同。
  • 对于复杂系统的配置包,可以包括对该系统的各种组件的服务账户的定义。

(2)服务账户的控制器

服务账户主要有3个控制器构成。

*1)Service Account Admission Controller

通过 Admission Controller 插件来实现对 pod 修改,它是 apiserver 的一部分。创建或更新 pod 时会同步进行修改 pod。当插件处于激活状态(在大多数发行版中都默认情况)创建或修改 pod 时,会按以下操作执行:

  • 如果 pod 没有设置 ServiceAccount,则将 ServiceAccount 设置为 default。
  • 确保 pod 引用的 ServiceAccount 存在,否则将会拒绝请求
  • 如果 pod 不包含任何 ImagePullSecrets,则将ServiceAccount 的 ImagePullSecrets 会添加到 pod 中
  • 为包含 API 访问的 Token 的 pod 添加了一个 volume。
  • 把 volumeSource 添加到安装在 pod 的每个容器中,挂载在 /var/run/secrets/kubernetes.io/serviceaccount

*2)TokenController

TokenController 作为 controller-manager 的一部分运行。异步行为:

  • 观察 serviceAccount 的创建,并创建一个相应的 Secret 来允许 API 访问。
  • 观察 serviceAccount 的删除,并删除所有相应的ServiceAccountToken Secret
  • 观察 secret 添加,并确保关联的 ServiceAccount 存在,并在需要时向 secret 中添加一个 Token。
  • 观察 secret 删除,并在需要时对应 ServiceAccount 的关联

*3)Service Account Controller

Service Account Controller 在 namespaces 里管理ServiceAccount,并确保每个有效的 namespaces 中都存在一个名为 "default" 的 ServiceAccount。

#查看服务账户
kubectl get sa
kubectl get sa -n kube-system

(3)授权rbac

*1)role

代表一个角色,会包含一组权限,没有拒绝规则,只是附加允许。它是 Namespace 级别的资源,只能作用与 Namespace 之内。

#查看角色
kubectl get role -n ingress-nginx -o yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
  name: nginx-ingress
  namespace: ingress-nginx
roles:
- apiGroups:
  - ""
  resources:
  - configmaps
  - pods
  - secrets
  - namespaces
  verbs:
  - get
- apiGroups:
  - ""
  resourceNames:
  - ingress-controller-label-nginx
  resources:
  - configmaps
  verbs:
  - get
  - update
- apiGroups:
  - ""
  resources:
  - configmaps
  verbs:
  - create

*2)ClusterRole

功能与 Role 一样,区别是资源类型为集群类型,而 Role 只在 Namespace

kubectl get clusterrole view -oyaml

*3)RoleBinding

Role 或 ClusterRole 只是用于制定权限集合,具体作用与什么对象上,需要使用 RoleBinding 来进行绑定。

作用于 Namespace 内,可以将 Role 或 ClusterRole 绑定到 User、Group、Service Account 上。

kubectl get rolebinding --all-namespaces

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  ......
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name nginx-ingress-role
subjects:
- kind: ServiceAccount
  name: nginx-ingress-serviceaccount
  namespace: ingress-nginx

*4)ClusterRoleBinding

与 RoleBinding 相同,但是作用于集群之上,可以绑定到该集群下的任意 User、Group 或 Service Account

3.感谢支持

感谢各位大佬支持,如果觉得满意可以请喝一杯咖啡吗:

相关推荐
白手小弟2 小时前
docker部署Stirling-PDF
docker·容器·pdf
HoweWWW3 小时前
k8s 微服务 ingress-nginx 金丝雀发布
微服务·容器·kubernetes
向往风的男子3 小时前
【从问题中去学习k8s】k8s中的常见面试题(夯实理论基础)(三十一)
学习·容器·kubernetes
HoweWWW3 小时前
k8s中的存储
linux·容器·kubernetes
djgxfc4 小时前
Docker概述
spring cloud·云原生·eureka
苏supper4 小时前
k8s的NodeIP、PodIP、ClusterIP、ExternalIP
kubernetes
夜猫逐梦4 小时前
【docker】阿里云使用docker,2024各种采坑
阿里云·docker·容器
c1tenj24 小时前
docker发布redis容器
redis·docker·容器
研究司马懿5 小时前
【云原生监控】Prometheus之PushGateway
云原生·prometheus·云原生监控·企业级监控系统·promesql
骇客野人9 小时前
【开端】docker基线漏洞修复
运维·docker·容器