K8S-Week5-K8S资源对象介绍(Pod、Job、cronjob、Service、emptyDir、Volume、[PV、PVC(动态、静态)])

K8S逻辑运行环境

 

 

K8S设计理念--分层架构

 

 

 

K8S设计理念--API设计原则

官方文档:https://www.kubernetes.org.cn/kubernetes%e8%ae%be%e8%ae%a1%e7%90%86%e5%bf%b5

 

 

 

K8SAPI简介

 

KBS资源对象操作命令

官方文档:https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/deployment/

 

 

 

 

 

 K8S的yaml文件规范

每个API对象都有三大类属性:元数据metadata,规范spec,状态status

spec是期望状态,status是实际状态

K8S资源简介

POD

  • pod是k8s中的最小单元
  • 一个pod可以运行一个或者多个容器
  • 运行多个容器的话这些容器是一起被调度的
  • pod的生命周期是短暂的,不会自愈,用完即毁的实体
  • 一般通过Controller来创建和管理pod

Job与CronJob

Job 会创建一个或者多个 Pod,并将继续重试 Pod 的执行,直到指定数量的 Pod 成功终止。 随着 Pod 成功结束,Job 跟踪记录成功完成的 Pod 个数。 当数量达到指定的成功个数阈值时,任务(即 Job)结束。 删除 Job 的操作会清除所创建的全部 Pod。 挂起 Job 的操作会删除 Job 的所有活跃 Pod,直到 Job 被再次恢复执行。

一种简单的使用场景下,你会创建一个 Job 对象以便以一种可靠的方式运行某 Pod 直到完成。 当第一个 Pod 失败或者被删除(比如因为节点硬件失效或者重启)时,Job 对象会启动一个新的 Pod。

你也可以使用 Job 以并行的方式运行多个 Pod。

官方文档:https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/job/

通常来说Job一般用于初始化数据(mysql/elasticsearch等等)

 

CronJob 用于执行排期操作,例如备份、生成报告等。 一个 CronJob 对象就像 Unix 系统上的 crontab(cron table)文件中的一行。 它用 Cron 格式进行编写, 并周期性地在给定的调度时间执行 Job。

官方文档:https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/cron-jobs/

CronJob示例

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

 

Deployment副本控制器

官方文档:https://kubernetes.io/zh-cn/docs/concepts/workloads/

Deployment控制器是比RS跟高以及的控制器,除了基础的支持等于、取反、包含功能外还支持很多高级功能,比如滚动升级、回滚等。

 

三种控制器管理下pod名字的区别

ReplicationController:
ng-rc-tbln8
ng-rc-5swk5

ReplicaSet:
frontend-bbtcc
frontend-qj5mw
kubectl set image replicaset/frontend ng-rs-80=nginx:1.20.0

Deployment:
nginx-deployment-ccbf969f7-d9w4t
nginx-deployment-ccbf969f7-f7zpr
ReplicaSet使用的是控制器名字+字符串,而deploymen使用的是pod名+控制器名+ReplicaSet生成的字符串+自己生成的字符串
Deloyment的基本功能实际上是调用ReplicaSet实现的,它本身主要负责实现高级功能


 

Service

官方文档:https://kubernetes.io/zh-cn/docs/concepts/services-networking/service/

Service是将运行在一组 Pods上的应用程序公开为网络服务的抽象方法。

Kubernetes 中 Service 的一个关键目标是让你无需修改现有应用程序就能使用不熟悉的服务发现机制。 你可以在 Pod 中运行代码,无需顾虑这是为云原生世界设计的代码,还是为已容器化的老应用程序设计的代码。 你可以使用 Service 让一组 Pod 在网络上可用,让客户端能够与其交互。

 

 

 目前调度模型主要使用ipvs,性能相较于userspace要高得多,iptables在超大规模集群中效果也并不理想,规则过多,匹配较慢、维护困难。

Service类型

  • ClusterIp: 在k8s内部使用,可以自动分配也可以固定
    • apiVersion: v1
      kind: Service
      metadata:
        name: my-service
      spec:
        ports:
          - protocol: TCP
            port: 80 #Service端口
            targetPort: 9376 #容器端口
        #type: ClusterIP #可以省略
        #clusterIP : 10.100.21.199 #可以手工分配
        selector:
          app: xxxxxxx  #匹配相应node
  • NodePort: 在每个node监听一个相同端口,用于客户端访问,会把请求转发至对应的Service,Service转发至对应pod,用于将k8s中的服务暴露给客户端访问
    • apiVersion: v1
      kind: Service
      metadata:
        name: my-service
      spec:
        type: NodePort
        selector:
          app: MyApp
        ports:
          - port: 80
            targetPort: 80
            # 可选字段
            # 默认情况下,为了方便起见,Kubernetes 控制平面会从某个范围内分配一个端口号(默认:30000-32767)
            nodePort: 30007
  • LoadBalence: 公有云环境使用较多
  • ExternalName: 用于将外部服务引入k8s

Volume存储卷

volume将容器中的指定数据和容器解耦,并且将数据存储到指定位置,不同的存储卷功能不同,如果是基于网络存储的存储卷可以实现容器间的数据共享和持久化。

静态存储卷需要在使用前手动创建PV和PVC,绑定至pod使用。

常用的几种卷:

  • Secret:是一种包含少量敏感信息的对象例如密码、令牌、密钥
  • configmap:配置文件
  • emptyDir:临时存储卷,容器删除时删除
  • hostPath:本地存储卷,容器删除时保留
  • nfs等:网络存储卷

emptyDir

当pod被分配给节点时,首先创建emptyDir卷,只要该pod在节点上运行,该卷就会存在,它最初为空,pod中的容器可以读写emptydir卷中的相同文件,当pod因任何原因从节点中删除时候,emptydir将被删除。

 

 

 示例:

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: registry.k8s.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir:
      sizeLimit: 500Mi

hostPath与emptyDir类似

 

nfs共享存储卷

nfs存储卷允许将现有的nfs挂载至容器,当删除pod时,nfs卷的内容会被保留,卷仅仅是被卸载,并且网络存储可以实现多pod间的数据共享。

 

 示例:

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: registry.k8s.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /my-nfs-data
      name: test-volume
  volumes:
  - name: test-volume
    nfs:
      server: my-nfs-server.example.com  #域名、ip均可      
path:
/my-nfs-volume readOnly: true

 

PV和PVC

  官方文档:https://v1-22.docs.kubernetes.io/zh/docs/concepts/storage/persistent-volumes/

  持久卷(PersistentVolume,PV)是集群中的一块存储,可以由管理员事先供应,或者使用存储类(Storage Class)来动态供应。 持久卷是集群资源,就像节点也是集群资源一样。PV 持久卷和普通的 Volume 一样,也是使用 卷插件来实现的,只是它们拥有独立于任何使用 PV 的 Pod 的生命周期。 此 API 对象中记述了存储的实现细节,无论其背后是 NFS、iSCSI 还是特定于云平台的存储系统。

  持久卷申领(PersistentVolumeClaim,PVC)表达的是用户对存储的请求。概念上与 Pod 类似。 Pod 会耗用节点资源,而 PVC 申领会耗用 PV 资源。Pod 可以请求特定数量的资源(CPU 和内存);同样 PVC 申领也可以请求特定的大小和访问模式 (例如,可以要求 PV 卷能够以 ReadWriteOnce、ReadOnlyMany 或 ReadWriteMany 模式之一来挂载,参见访问模式)。

  PV和PVC可以实现pod和storge的解耦,这样修改storge时候可以不需要修改pod,与NFS不同的是,可以在PV和PVC层面实现对存储服务器的空间分配,存储访问权限管理等。

  PersistentVolume 卷可以用资源提供者所支持的任何方式挂载到宿主系统上。 如下表所示,提供者(驱动)的能力不同,每个 PV 卷的访问模式都会设置为 对应卷所支持的模式值。 例如,NFS 可以支持多个读写客户,但是某个特定的 NFS PV 卷可能在服务器 上以只读的方式导出。每个 PV 卷都会获得自身的访问模式集合,描述的是 特定 PV 卷的能力。

访问模式有:

  • ReadWriteOnce(RWO):卷可以被一个节点以读写方式挂载。 ReadWriteOnce 访问模式也允许运行在同一节点上的多个 Pod 访问卷。
  • ReadOnlyMany(ROX):卷可以被多个节点以只读方式挂载。
  • ReadWriteMany(RWX):卷可以被多个节点以读写方式挂载。
  • ReadWriteOncePod:卷可以被单个 Pod 以读写方式挂载。 如果你想确保整个集群中只有一个 Pod 可以读取或写入该 PVC, 请使用ReadWriteOncePod 访问模式。目前只支持 CSI 卷以及需要 Kubernetes 1.22 以上版本。

在命令行接口(CLI)中,访问模式也使用以下缩写形式:

  • RWO - ReadWriteOnce
  • ROX - ReadOnlyMany
  • RWX - ReadWriteMany
  • RWOP - ReadWriteOncePod

 

 

 pesistenVolumeReclaimPolicy:删除机制,即删除存储卷时,已经创建好的存储卷有以下删除操作:

  • Reatin:删除PV后保持原状,需要管理员到存储上删除数据
  • Recycle:空间回收,删除存储卷的所有数据,包括目录和隐藏文件,目前仅支持NFS和hostPath,慎用
  • Delete:自动删除存储内容,慎用

 

 

 

 

 

 

 

 

 

静态PV、PVC(静态存储卷)

  • PV示例:
apiVersion: v1
kind: PersistentVolume
metadata:
  name: zookeeper-datadir-pv-1
spec:
  capacity:
    storage: 20Gi
  accessModes:
    - ReadWriteOnce 
  nfs:
    server: 172.31.7.109
    path: /data/zookeeper-datadir-1 

 

  • PVC示例:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: zookeeper-datadir-pvc-1
  namespace: magedu
spec:
  accessModes:
    - ReadWriteOnce
  volumeName: zookeeper-datadir-pv-1
  resources:
    requests:
      storage: 10Gi
  • Pod挂载PV示例:
kind: Deployment
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
  name: zookeeper1
  namespace: magedu
spec:
  replicas: 1
  selector:
    matchLabels:
      app: zookeeper
  template:
    metadata:
      labels:
        app: zookeeper
        server-id: "1"
    spec:
      volumes:
        - name: data
          emptyDir: {}
        - name: wal
          emptyDir:
            medium: Memory
      containers:
        - name: server
          image: 192.168.184.199:80/zookeeper/zookeeper:v3.4.14 
          imagePullPolicy: Always
          env:
            - name: MYID
              value: "1"
            - name: SERVERS
              value: "zookeeper1,zookeeper2,zookeeper3"
            - name: JVMFLAGS
              value: "-Xmx2G"
          ports:
            - containerPort: 2181
            - containerPort: 2888
            - containerPort: 3888
          volumeMounts:
          - mountPath: "/zookeeper/data"
            name: zookeeper-datadir-pvc-1 
      volumes:
        - name: zookeeper-datadir-pvc-1 
          persistentVolumeClaim:
            claimName: zookeeper-datadir-pvc-1

 

动态PV、PVC(动态存储卷)

先创建一个存储类strogeclass,后期pod在使用PV的时候可以通过存储类动态创建PVC,适用于有状态的服务集群如MySQL一主多从、zookeeper集群等。

示例:

  • 先定义服务账户与权限
apiVersion: v1
# 定义服务账户
kind: ServiceAccount
metadata:
  # 名字要知命达意,这个账户专门为数据库服务
  # {用途}-svc-{卷类型}-account
  name: db-svc-nfs-account 
  namespace: default
---
# 定义集群角色声明该角色的权限列表,可以看出全是存储相关
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  # 与 db-svc-nfs-account 相呼应
  name: db-svc-nfs-cluster-role
rules:
  - apiGroups: [""]
    resources: ["persistentvolumes"]
    verbs: ["get", "list", "watch", "create", "delete"]
  - apiGroups: [""]
    resources: ["persistentvolumeclaims"]
    verbs: ["get", "list", "watch", "update"]
  - apiGroups: ["storage.k8s.io"]
    resources: ["storageclasses"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["events"]
    verbs: ["create", "update", "patch"]
---
# 定义完角色后,就要将ServiceAccount与ClusterRole来绑定
kind: ClusterRoleBinding 
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: db-svc-nfs-account-cluster-role-bind
subjects:  # 这里用的数组结构,那么可以认为这一个“角色”可以被多个账户绑定
  - kind: ServiceAccount
    # 账户名字,见ServiceAccount的name
    name: db-svc-nfs-account
    namespace: default
roleRef:
  kind: ClusterRole
  # 角色的名字,见ClusterRole的name
  name: db-svc-nfs-cluster-role
  apiGroup: rbac.authorization.k8s.io
---
# 专门用来操作pvc与pv绑定时,ServiceAccount可以使用的权限
kind: Role # 角色
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: db-svc-nfs-role
  namespace: default
rules:
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
---
# 与角色绑定的ServiceAccount
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: db-svc-nfs-account-role-bind
subjects:
  - kind: ServiceAccount
    # 账户名字,见ServiceAccount的name
    name: db-svc-nfs-account
    namespace: default
roleRef:
  kind: Role
  # 角色名字,见role
  name: db-svc-nfs-role
  apiGroup: rbac.authorization.k8s.io
  • 创建StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: db-svc-nfs-storage-class
# 这个名字要记住
provisioner: db-svc-nfs-provistioner  
parameters:
  archiveOnDelete: "false"
reclaimPolicy: Retain
  • 创建NFS Provisioner
apiVersion: apps/v1
kind: Deployment
metadata:
  name: db-svc-nfs-provisioner
  labels:
    app: db-svc-nfs-provisioner
  namespace: default  
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: db-svc-nfs-provisioner
  template:
    metadata:
      labels:
        app: db-svc-nfs-provisioner
    spec:
      # 这里说明,用上面创建的service account来创建pv
      serviceAccountName: db-svc-nfs-account
      containers:
      - name: nfs-client-provisioner
        image: quay.io/external_storage/nfs-client-provisioner:latest
        volumeMounts:
        - name: nfs-client-root
          mountPath: /persistentvolumes
        env: #------ 这里是有学问的,见3.7
        - name: PROVISIONER_NAME
          value: db-svc-nfs-provistioner  
        - name: NFS_SERVER
          value: 192.168.56.4
        - name: NFS_PATH  
          value: /data/nfs/db-svc-dynamic-volume
      volumes:
        - name: db-svc-dynamic-volume
          nfs:
            server: 192.168.56.4  
            path: /data/nfs/db-svc-dynamic-volume
  • 创建Persistent Volume Claim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pvc
  namespace: default
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: db-svc-nfs-storage-class

 

posted @ 2023-02-26 23:55  ataATA  阅读(0)  评论(0)    收藏  举报