Job资源对象,与k8s存储

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: Job资源对象,与k8s存储

屏幕截图 2023-08-28 163846.png

apiVersion

查看可用的apiversion命令:kubectl api-versions

k8s官方将apiversion分成了三个大类型,alpha、beta、stable。

 Alpha: 未经充分测试,可能存在bug,功能可能随时调整或删除。  

   Beta: 经过充分测试,功能细节可能会在未来进行修改。

   Stable: 稳定版本,将会得到持续支持。

常用apiversion:

v1: Kubernetes API的稳定版本,包含很多核心对象:pod、service等。    

   apps/v1: 包含一些通用的应用层的api组合,如:Deployments, RollingUpdates, ReplicaSets, Daemonset。

   batch/v1: 包含与批处理和类似作业的任务相关的对象,如:job、cronjob。

   autoscaling/v1: 允许根据不同的资源使用指标自动调整容器。

添加apiVersion库:

   vim /etc/kubernetes/manifests/kube-apiserver.yaml

   在yaml文件中command指令下添加:

   - --runtime-config=batch/v2alpha1=true

   然后重启kubelet服务,重新识别api yaml文件内容即可。

   systemctl restart kubelet

   kubectl api-versions

===========================================

Job资源对象:

服务类的Pod容器:RC、RS、DS、Deployment(Pod内运行的服务,要持续运行)

   工作类的Pod容器:Job--->执行一次,或者批量执行处理程序,完成之后退出容器。

特殊说明:  

   spec.template格式同Pod

   restartPolicy仅支持Never或onFailure

   单个Pod时,默认Pod成功运行后Job即结束

   .spec.completions标志Job结束需要成功运行的Pod个数,默认为1

   .spec.parallelism标志并行运行的Pod的个数,默认为1

   .spec.activeDeadlineSeconds标志失败Pod的重试最大时间,超时间不会继续重试

举例:

运行job,计算2000位的圆周率

---yaml
kind: Job 
apiVersion: batch/v1 
metadata: 
  name: pi 
spec: 
  template: 
    metadata: 
      name: pi
    spec: 
      containers: 
      - name: pi 
        image: perl
        imagePullPolicy: IfNotPresent  
        command: ["perl","-Mbignum=bpi","-wle","print bpi(2000)"] 
      restartPolicy: Never

查看容器日志结果:

kubectl logs -f pi-j5j4n

运行job,发送简单信息

---yaml
kind: Job 
apiVersion: batch/v1 
metadata: 
  name: test-job 
spec: 
  template: 
    metadata: 
      name: test-job 
    spec: 
      containers: 
      - name: hello 
        image: busybox
        imagePullPolicy: IfNotPresent  
        command: ["echo","hello k8s job!"] 
      restartPolicy: Never

注意,如果容器内执行任务有误,会根据容器的重启策略操作容器,不过这里的容器重启策略只能是: Never和 OnFailure。

提高Job的执行效率:

   我们可以在Job.spec字段下加上**parallelism**选项。表示同时运行多少个Pod执行任务。

   我们可以在Job.spec字段下加上**completions**选项。表示总共需要完成Pod的数量。

   举例将上述Job任务进行更改。提示,更改Job任务的时候,需要先将原来的Job资源对象删除

PS:

---yaml
kind: Job 
apiVersion: batch/v1 
metadata: 
  name: test-job1 
spec: 
  parallelism: 2 
  completions: 8 
  template: 
    metadata: 
      name: test-job 
    spec: 
      containers: 
      - name: hello 
        image: busybox
    imagePullPolicy: IfNotPresent 
        command: ["echo","hello k8s job!"] 
      restartPolicy: Never

Job的作用,与我们之前接触过的at有些类似,在k8s集群中,如果需要用到运行一次性工作任务的需

求,那么,就可以考虑使用Job资源对象。

工作类资源对象不仅只有一个Job,还有一个和crontab十分相像的cronJob.

------------------------------------

CronJob

管理基于时间的Job,即:

   在给定时间点只运行一次

   周期性地在给定时间点运行

典型用法:

   在给定的时间点调度Job运行

   创建周期性运行的Job,例如:数据库备份、发送邮件

CronJob Spec

   .spec.schedule:调度,必需字段,指定任务运行周期

   .spec.jobTemplate:Job模板,必需字段,指定需要运行的任务,格式同job

   .spec.startingDeadlineSeconds:启动Job的期限(秒级别),该字段是可选的。如果因为任何原因        

       而错过了被调度的时间,那么错过执行时间的job将被认为是失败的。如果没有指定,则没有期限。

   .sec.concurrencyPolicy: 并发策略,该字段也是可选的。它指定了如何处理CronJob创建的Job的并发执行。

       只允许指定下面策略中的一种:

           Allow (默认):允许并发job

           Forbid: 禁止并发运行,如果前一个还没有完成,则直接跳过下一个

           Replace: 取消当前正在运行的job,用一个新的来替换

   .spec.suspend: 挂起,该字段也是可选的,如果设置为true,后续所有执行都会被挂起,它对开始执行的job

       不起作用。默认值为false。

   .spec.successfulJobsHistoryLimit和.spec.failedJobsHistoryLimit: 历史限制,可选字段,它们指定了可

       以保留多少完成和失败的job。默认设置为3和1,如果值为0,相关类型的job完成后不被保留。

---yaml
kind: CronJob 
apiVersion: batch/v1beta1 
metadata: 
  name: hello 
spec: 
  schedule: "*/1 * * * *" 
  jobTemplate: 
    spec: 
      template: 
        spec: 
          containers: 
          - name: hello 
            image: busybox
            imagePullPolicy: IfNotPresent  
            command: ["echo","hello cronjob!"] 
          restartPolicy: OnFailure  
此时查看Pod的状态,会发现,每分钟都会运行一个新的Pod来执行命令规定的任务。
K8s存储

Volume: 数据卷

kubernetes Pod中多个容器访问的共享目录。volume被定义在pod上,被这个pod的多个容器

   挂载到相同或不同的路径下。volume的生命周期与pod的生命周期相同,pod内的容器停止和

   重启时一般不会影响volume中的数据。所以一般volume被用于持久化pod产生的数据。

volume类型:  

emptyDir  
    hostPath
    gcePersistentDisk
    awsElasticBlockStore
    nfs   
    iscsi
    flocker   
    glusterfs
    rbd
    cephfs 
    gitRepo
    secret  
    persistentVolumeClaim
    downwardAPI
    azureFileVolume
    azureDisk
    vsphereVolume   
    Quobyte
-----------------------------------------

 emptyDir:

   emptyDir的生命周期与所属的pod相同。  

   pod删除时,其emptyDir中的数据也会被删除。

   emptyDir类型的volume在pod分配到node上时被创建,kubernetes会在node上自动分配一个目录,因此无需指定宿主机node上对应的目录文件。

   emptyDir Volume主要用于某些应用程序无需永久保存的临时目录,多个容器的共享目录等。  

   注:一般用于容器数据卷共享,不能做持久化数据存储。

//写一个emptyDir.yaml的文件。

---yaml
kind: Pod 
apiVersion: v1 
metadata: 
  name: producer-consumer 
spec: 
  containers: 
  - name: producer 
    image: busybox
    imagePullPolicy: IfNotPresent 
    volumeMounts: 
    - mountPath: /producer_dir 
      name: shared-volume 
    args: 
    - /bin/sh 
    - -c 
    - echo "hello world" > /producer_dir/hello.txt ; sleep 30000 
  - name: consumer 
    image: busybox
    imagePullPolicy: IfNotPresent 
    volumeMounts: 
      - mountPath: /consumer_dir 
        name: shared-volume 
    args: 
    - /bin/sh 
    - -c 
    - cat /consumer_dir/hello.txt ;sleep 30000 
  volumes: 
  - name: shared-volume 
    emptyDir: {}

总结:  

根据上述yaml文件分析,volumes是指k8s的存储方案.容器内volumeMounts使用的是volumes内定义的存储,所以现在可以理解为,volumes定义的dockerHost上的目录或文件,分别挂载到了producer(/producer_dir)和consumer(/consumer_dir)这个两个容器的对应目录。那么安装这个方法,我们可以判断出,在consumer这个容器的/consumer_dir目录下,应该也会有一个hello.txt的文件。

//验证,查看conumer容器的日志。

[root@master volume]# kubectl logs producer-consumer consumer

hello world

//查看一个Pod运行在了那个Node节点上

[root@master volume]# kubectl get pod -o wide

//到对应Node节点上查看该容器的详细信息(Mounts)

[root@node01 ~]# docker inspect 413d5dbd0239    
...
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/var/lib/kubelet/pods/82a382ce-78aa-48f1-933b-685ce2ba7a3d/volumes/kubernetes.io~empty-dir/shared-volume",
                "Destination": "/producer_dir",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            },

PS: 查看到该容器的Mounts字段,等于是运行docker容器的时候使用这么一条命令:

docker run -v /producer_dir busybox

emptyDir的使用场景:如果Pod的被删除,那么数据也会被删除,不具备持久化。Pod内的容器,需要

共享数据卷的时候,使用的临时数据卷。

-----------------------------------------

HostPath

 hostPath卷将主机节点的文件系统中的文件或目录挂载到集群中。

   相对于emtpyDir来说,hostPath就等于运行容器是使用的命令:

       docker run -v /host/path:/container/path

除了path属性之外,用户还可以指定type:

   空                   空字符串(默认),挂载hostPath卷之前不会执行任何检查

   DirectoryOrCreate  如果指定的位置没有目录,将创建空目录,权限755,与kubelet具有相同的所有权

   Directory           指定的位置必须存在目录

   FileOrCreate       如果指定的位置没有文件,将创建空文件,权限644,与kubelet具有相同的所有权

   File           指定的位置必须存在文件

   Socket           指定的位置必须存在Unix套接字

   CharDevice            指定的位置必须存在字符设备

   BlockDevice        指定的路径下必须存在块设备

//这里没有创建新的yaml文件,直接将emptyDir.yaml文件的volumes字段更改为:hostPath.
[root@node01 volume]# 
...
  volumes: 
  - name: shared-volume 
    hostPath: 
      path: "/data/hostPath"
      type: DirectoryOrCreate

注:对比emptyDIR,hostPath具有持久性:即容器删除,数据卷还在

=================================

PV、PVC

PV: Persistent(持久的、稳固的)Volume

由管理员设置的存储,是集群的一部分,就像node节点一样,PV也是集群的资源。PV是volume之类的卷插件,但独立于使用PV的pod的生命周期。此api对象包含存储实现的细节,即nfs、iscsi、ceph或云存储等。

   是k8s集群的外部存储系统,一般是设定好的存储空间(文件系统中的一个目录)。

PVC: PersistentvolumeClaim(声明、申请)

   是用户存储的请求,它与pod相似。pod消耗节点资源,PVC消耗PV资源。pod可以请求特定级别的资源(CPU和内存)。声明可以请求特定的大小和访问模式(只读/读写)。

   如果应用需要用到持久化的时候,可以直接向PV申请空间。

基于NFS服务来创建的PV:

//3台节点都安装nfs-工具包和rpc-bind服务。

[root@master ~]# yum install nfs-utils rpcbind  -y

//这里准备将NFS服务部署在master节点上,需要在master节点上提前规划好共享的目录

[root@master ~]# mkdir /nfsdata 
[root@master ~]# vim /etc/exports 
/nfsdata *(rw,sync,no_root_squash) 
[root@master ~]# systemctl start rpcbind 
[root@master ~]# systemctl enable rpcbind 
[root@master ~]# systemctl start nfs-server 
[root@master ~]# systemctl enable nfs-server 
[root@master ~]# showmount -e

//创建pv1.yaml文件

---yaml
kind: PersistentVolume 
apiVersion: v1 
metadata: 
  name: pv1 
spec: 
  capacity: 
    storage: 1Gi 
  accessModes:  
    - ReadWriteOnce 
  persistentVolumeReclaimPolicy: Recycle 
  storageClassName: nfs 
  nfs:
    path: /nfsdata
    server: 192.168.8.10

PV所支持的访问模式:

   ReadWriteOnce: PV能以read-write的模式mount到单个节点。(命令模式:RWO)

   ReadOnlyMany: PV能以read-only 的模式mount到多个节点。(命令模式:ROX)

   ReadWriteMany: PV能以read-write的模式Mount到多个节点。(命令模式:RWX)

PV状态:

   Available(可用):一块空闲资源还没有被任何声明绑定

   Bound(绑定):卷已经被声明绑定

   Released(已释放):声明被删除,但是资源还未被集群重新声明

   Failed(失败):该卷的自动回收失败

PV空间的回收策略:persistentVolumeReclaimPolicy

   Recycle: 回收,会清除数据,自动回收(最新k8s版本已不支持)。

   Retain: 保留,需要手动清理回收。

   Delete: 删除,关联的存储资产(AWS EBS,GCE PD,Azure Disk和Openstack Cinder卷)将被删除

   注:只有nfs和hostPath支持回收策略,AWS EBS,GCE PD,Azure Disk和Cinder支持删除策略

关于pv所支持的访问模式的理解:

   读写方面: 如果是可以读写的,则认为,Pod可以在挂载的路径下,执行读写操作。如果是只读的,那么Pod就只能够读取PV共享目录下的数据了。

   节点方面:所谓挂载到单个或者多个节点,指的是Kuberntes的工作节点(node节点)

验证结果(不完全正确):

1)kubernetes官方表示,ReadOnly是以只读的方式挂载,但实际的验证结果仍需要在挂载时指定其挂

载类型为ReadOnly: true,才可以实现只读。

2)这里所说的挂载至单节点或多节点,和官方描述不一致。具体实现方法,有待进一步验证。

官网描述: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes

重要提醒!

每个卷只能同一时刻只能以一种访问模式挂载,即使该卷能够支持 多种访问模式。例如,一个 GCEPersistentDisk 卷可以被某节点以 ReadWriteOnce 模式挂载,或者被多个节点以ReadOnlyMany 模式挂载,但不可以同时以两种模式挂载。

//创建一个PVC,向刚才的PV申请使用空间,注意,这里PV与PVC的绑定,通过storageClassName和accessModes这两个字段共同决定。

---yaml
kind: PersistentVolumeClaim 
apiVersion: v1 
metadata: 
  name: pvc1 
spec: 
  accessModes: 
    - ReadWriteOnce
  storageClassName: nfs 
  resources: 
    requests: 
      storage: 1Gi

总结:

   1. 当系统中的pv被绑定之后,就不会被其他的PVC绑定了。

   2. 如果系统中有多个能够满足pvc要求的pv,那么,系统会自动选择一个符合pvc申请空间大小的PV,进行绑定,尽量不浪费存储空间。

//创建一个Pod,来使用上述PVC。

kind: Pod 
apiVersion: v1 
metadata: 
  name: pod1 
spec: 
  containers: 
  - name: pod1 
    image: busybox
    imagePullPolicy: IfNotPresent 
    args: 
    - /bin/sh 
    - -c 
    - sleep 30000 
    volumeMounts: 
    - mountPath: "/data" 
      name: mydata 
  volumes: 
  - name: mydata 
    persistentVolumeClaim: 
      claimName: pvc1 
=======================================

PV的空间回收

当回收策略为recycle

[root@master ~]# kubectl get pv,pvc

// 验证dockerhost上PV上存放的数据

[root@master ~]# ls /nfsdata/

test.txt

//删除Pd资源,PVC

[root@master ~]# kubectl delete pod pod1 
pod "pod1" deleted 
[root@master ~]# kubectl delete pvc pvc1 
persistentvolumeclaim "pvc1" deleted

//查看PV的过程,Released(释放)--->Available(可用)。

[root@master ~]# kubectl get pv

//验证,数据依然被删除

[root@master ~]# ls /nfsdata

无数据

PS: 在释放空间的过程中,其实K8S生成了一个新的Pod,由这个Pod执行删除数据的操作。

-------------------------------------

当回收策略为: Retain

...

 persistentVolumeReclaimPolicy: Retain //更改回收策略为保留

//重新运行pvc1,pod资源,然后在Pod内,创建对应的资源,再尝试删除PVC,和Pod,验证PV目录

下,数据是否还会存在?

[root@master ~]# kubectl apply -f pvc1.yaml 
[root@master ~]# kubectl apply -f pod.yaml 
[root@master ~]# kubectl exec pod1 touch /data/test.txt 
[root@master ~]# ls /nfsdata/
test.txt

//再次删除Pod,PVC,验证PV目录下存放的数据

[root@master ~]# kubectl delete pod pod1 
[root@master ~]# kubectl delete pvc pvc1 
[root@master ~]# ls /nfsdata/ 
test.txt

//修复状态released为 Available

[root@master ~]# kubectl edit pv pv1

删除 claimRef: 字段

claimRef:
    apiVersion: v1
    kind: PersistentVolumeClaim
    name: pvc1
    namespace: default
    resourceVersion: "111021"
    uid: d7ef17f9-ad63-4907-a277-0e172496e1ec
================================================

PV,PVC的运用

现在部署一个MySQL服务,并且将MySQL的数据进行持久化存储。

1、创建PV,PVC

vim mysql-pv.yaml
kind: PersistentVolume 
apiVersion: v1 
metadata: 
  name: mysql-pv 
spec: 
  accessModes: 
    - ReadWriteOnce  
  capacity: 
    storage: 1Gi 
  persistentVolumeReclaimPolicy: Retain 
  storageClassName: nfs 
  nfs:
    path: /nfsdata/mysql-pv 
    server: 192.168.8.10 
vim mysql-pvc.yaml
kind: PersistentVolumeClaim 
apiVersion: v1 
metadata: 
  name: mysql-pvc 
spec: 
  accessModes: 
    - ReadWriteOnce
  storageClassName: nfs 
  resources: 
    requests: 
      storage: 1Gi 
[root@master MySQL]# mkdir /nfsdata/mysql-pv 
[root@master MySQL]# kubectl apply -f mysql-pv.yaml 
[root@master MySQL]# kubectl apply -f mysql-pvc.yaml 
[root@master MySQL]# kubectl get pv,pvc

2、部署MySQL

vim mysql.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
  name: mysql
spec:
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:5.7
        imagePullPolicy: IfNotPresent
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: 123.com
        volumeMounts:
        - name: mysql-storage
          mountPath: /var/lib/mysql
      volumes:
      - name: mysql-storage
        persistentVolumeClaim:
          claimName: mysql-pvc 
--- 
kind: Service 
apiVersion: v1 
metadata: 
  name: mysql 
spec: 
  type: NodePort
  selector: 
    app: mysql 
  ports: 
    - port: 3306 
      targetPort: 3306 
      nodePort: 31306

3、在MySQL数据库中添加数据

[root@master ~]# kubectl exec -it mysql-6fccccd487-5q2dt -- mysql -uroot -p123.com
mysql> SHOW DATABASES; //查看当前的库。
mysql> CREATE DATABASE TEST; //创建test库。
mysql> USE TEST; //选择使用test库。 
mysql> CREATE TABLE my_id(id int(4)); //创建my_id表
mysql> INSERT my_id values (9527); //往my_id表中,插入数据。
mysql> SELECT * FROM my_id; //查看my_id表中所有数据

4、模拟MySQ服务器节点故障

k8s集群会生产一个新的Pod,验证这个Pod内是否有之前数据。

//先查看运行MySQL服务的Pod,在哪个节点,然后将该节点挂起,我们知道k8s肯定会在另外一个节点重新生成一个Pod

[root@master ~]# kubectl get pod -o wide

//新生成Pod后,同样进入Pod验证数据是否会会存在,

[root@master MySQL]# kubectl exec -it mysql-5d86c64fc9-p7hv6 -- mysql -u root -p123.com 
mysql> show databases; 
mysql> use TEST; 
mysql> show tables; 
mysql> select * from my_id;


相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
11天前
|
Kubernetes 调度 容器
【赵渝强老师】K8s中Job控制器单工作队列的串行方式
Kubernetes中的Job控制器用于管理一次性任务,确保任务完成后不再重启。本文介绍了Job的工作原理、运行方式及示例,包括创建Job、查看Job和Pod信息等步骤,并附有视频讲解。
|
3月前
|
存储 Kubernetes 容器
Kubernetes 存储选项:持久化卷与存储类
【8月更文第29天】随着容器化的普及,越来越多的应用程序需要持久化数据以保持状态信息。Kubernetes 提供了一套完整的解决方案来管理和配置持久化存储,包括持久卷 (Persistent Volume, PV)、持久卷声明 (Persistent Volume Claim, PVC) 和存储类 (StorageClass)。本文将详细介绍这些概念,并通过实际示例来演示如何在 Kubernetes 中配置存储。
297 1
|
1月前
|
JSON 运维 Kubernetes
|
11天前
|
Kubernetes 调度 容器
【赵渝强老师】K8s的Job控制器多工作队列的并行方式
Kubernetes Job 是一次性任务控制器,用于控制 Pod 中的容器执行特定任务。本文介绍了 Job 控制器的工作原理、运行方式及多工作队列并行执行的示例。示例中创建了 5 个作业,以 3 个队列并行执行,整个过程需 2 分钟。文中还提供了详细的 YAML 文件配置和执行命令。
|
3月前
|
存储 Kubernetes 容器
k8s创建NFS动态存储
k8s创建NFS动态存储
|
3月前
|
存储 Kubernetes 数据中心
在K8S中,同⼀个Pod内不同容器哪些资源是共用的,哪些资源是隔离的?
在K8S中,同⼀个Pod内不同容器哪些资源是共用的,哪些资源是隔离的?
|
3月前
|
边缘计算 人工智能 Kubernetes
边缘计算问题之理解 Kubernetes 节点资源的四层分配结构如何解决
边缘计算问题之理解 Kubernetes 节点资源的四层分配结构如何解决
32 1
|
3月前
|
存储 Kubernetes API
|
3月前
|
Kubernetes Cloud Native 应用服务中间件
Kubernetes 自动伸缩策略:优化资源利用率
【8月更文第29天】在现代云原生环境中,应用的流量往往具有不可预测性。为了应对这种变化,Kubernetes 提供了多种自动伸缩机制来动态调整应用实例的数量和每个实例分配的资源。本文将深入探讨两种主要的自动伸缩工具:水平 Pod 自动伸缩器 (HPA) 和垂直 Pod 伸缩器 (VPA),并提供实际的应用示例。
101 0
|
3月前
|
Prometheus Kubernetes 监控
在K8S中,DaemonSet类型的资源特性有哪些?
在K8S中,DaemonSet类型的资源特性有哪些?