Kubernetes API资源对象

1、API资源对象Pod

在K8s里,YAML用来声明API对象的,那么API对象都有哪些?可以这样查看资源对象:

$ kubectl api-resources

Pod为K8s里最小、最简单的资源对象。

运行一个pod

$ kubectl run pod-demo --image=busybox

从已知Pod导出YAML文件:

$ kubectl get pod pod-demo -o yaml  > pod-demo.yaml

Pod YAML示例:
四个核心部分:apiVersion、Kind、metadata、spec

$ vi ngx-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: ngx-pod
  namespace: aming
  labels:  ## labels字段非常关键,它可以添加任意数量的Key-Value,目的是为了让pod的信息更加详细
    env: dev

spec:  ##用来定义该pod更多的资源信息,比如containers, volume, storage
  containers:  ##定义容器属性
  - image: nginx:1.23.2
    imagePullPolicy: IfNotPresent  ##镜像拉取策略,三种:Always/Never/IfNotPresent,一般默认是IfNotPresent,也就是说只有本地不存在才会远程拉取镜像,可以减少网络消耗。
    name: ngx
    env:  ##定义变量,类似于Dockerfile里面的ENV指令
      - name: os
        value: "Rocky Linux"
    ports:
    - containerPort: 80

使用YAML创建pod:

$ kubectl apply -f ngx-pod.yaml

删除pod:

$ kubectl delete -f ngx-pod.yaml

1.1 Pod原理

Pod 是在 K8s集群中运行部署应用或服务的最小单元。

在同一个Pod中其实可以同时运行多个容器,这些容器能够共享网络、存储以及 CPU/内存等资源。
每个Pod都有一个特殊的被称为 “根容器” 的Pause容器。Pause容器的主要作用是为Pod中的其他容器提供一些基本的功能,比如网络和PID命名空间的共享、 负责管理Pod内其他容器的生命周期。

  • 网络命名空间共享:pause容器为整个Pod创建一个网络命名空间,Pod内的其他容器都将加入这个网络命名空间。这样,Pod中的所有容器都可以共享同一个IP地址和端口空间,从而实现容器间的紧密通信。
  • PID命名空间共享:pause容器充当Pod内其他容器的父容器,它们共享同一个PID命名空间。这使得Pod内的容器可以通过进程ID直接发现和相互通信,同时也使得Pod具有一个统一的生命周期。
  • 生命周期管理:pause容器作为Pod中其他容器的父容器,负责协调和管理它们的生命周期。当pause容器启动时,它会成为Pod中其他容器的根容器。当pause容器终止时,所有其他容器也会被自动终止,确保了整个Pod的生命周期的一致性。
  • 保持Pod状态:pause容器保持运行状态,即使Pod中的其他容器暂时停止或崩溃,也可以确保Pod保持活跃。这有助于Kubernetes更准确地监视和管理Pod的状态。

Kubernetes API资源对象

1.2 Pod生命周期

Pod生命周期包括以下几个阶段:

  • Pending:在此阶段,Pod已被创建,但尚未调度到运行节点上。此时,Pod可能还在等待被调度,或者因为某些限制(如资源不足)而无法立即调度。
  • Running:在此阶段,Pod已被调度到一个节点,并创建了所有的容器。至少有一个容器正在运行,或者正在启动或重启。
  • Succeeded:在此阶段,Pod中的所有容器都已成功终止,并且不会再次重启。
  • Failed:在此阶段,Pod中的至少一个容器已经失败(退出码非零)。这意味着容器已经崩溃或以其他方式出错。
  • Unknown:在此阶段,Pod的状态无法由Kubernetes确定。这通常是因为与Pod所在节点的通信出现问题。

除了这些基本的生命周期阶段之外,还有一些更详细的容器状态,用于描述容器在Pod生命周期中的不同阶段:

  • ContainerCreating:容器正在创建,但尚未启动。
  • Terminating:容器正在终止,但尚未完成。
  • Terminated:容器已终止。
  • Waiting:容器处于等待状态,可能是因为它正在等待其他容器启动,或者因为它正在等待资源可用。
  • Completed:有一种Pod是一次性的,不需要一直运行,只要执行完就会是此状态。

1.3 创建Pod流程

Kubernetes API资源对象

1. 用户通过kubectl或其他API客户端提交Pod对象给API server。
2. API server尝试将Pod对象的相关信息存入etcd中,写入操作完成后API server会返回确认信息至客户端。
3. API server开始反映etcd中的状态变化。
4. 所有的Kubernetes组件均使用watch机制来跟踪检查API server上的相关变化。
5. Kube-scheduler通过其watcher观察到API server创建了新的Pod对象但尚未绑定至任何节点。
6. Kube-scheduler为Pod对象挑选一个工作节点并将结果更新至API server。
7. 调度结果由API server更新至etcd,而且API server也开始反映此Pod对象的调度结果。
8. Pod 被调度的目标工作节点上的kubelet尝试在当前节点上调用Containerd启动容器,并将容器的结果状态返回至API server。
9. API server将Pod 状态信息存入etcd。
10. 在etcd确认写操作完成后,API server将确认信息发送至相关的kubelet。

1.4 删除Pod流程

Kubernetes API资源对象

1. 请求删除Pod。
2. API server将Pod标记为Terminating状态。
3. (与第 2 步同时进行)kubelet在监控到Pod对象转为Terminating状态的同时启动Pod关闭过程。
4. (与第 2 步同时进行)Service将Endpoint摘除。
5. 如果当前Pod对象定义了preStop hook,则在其标记为Terminating后会以同步的方式执行,宽限期开始计时。
6. Pod中的容器进程收到TERM信号。
7. 宽限期结束后,若进程仍在运行,会收到SIGKILL信号。
8. kubelet请求API server将此Pod对象的宽限期设置为0,从而完成删除操作。

2、Pod资源限制

2.1 Resource Quota

资源配额Resource Quotas(简称quota)是对namespace进行资源配额,限制资源使用的一种策略。
K8S是一个多用户架构,当多用户或者团队共享一个K8S系统时,SA使用quota防止用户(基于namespace的)的资源抢占,定义好资源分配策略。
Quota应用在Namespace上,默认情况下,没有Resource Quota的,需要另外创建Quota,并且每个Namespace最多只能有一个Quota对象。

可限定资源类型:
计算资源:limits.cpurequests.cpulimits.memoryrequests.memory
存储资源,包括存储资源的总量以及指定storage class的总量
requests.storage:存储资源总量,如500Gi
persistentvolumeclaims:pvc的个数

limits:最多可以使用多少
requests:最少需要分配多少

对象数,即可创建的对象的个数
pods, replicationcontrollers, configmaps, secrets,persistentvolumeclaims,services, services.loadbalancers,services.nodeports

注意:
Quota依赖于资源管理器,可以使用资源对象limits或者在创建资源对象时为pod设置资源限制(resources),如果不设置,资源对象无法创建。
当该namespace中的任意个额度达到预设Quota时,将无法创建资源对象。

Resource Quota示例:

$ cat > quota.yaml <<EOF
apiVersion: v1
kind: ResourceQuota
metadata:
  namespace: aming
  name: aming-quota

spec:
  hard:
    pods: 50  ## 该命名空间里最多支持启动50个Pods
    requests.cpu: 0.5 ##最低保证0.5个CPU资源
    requests.memory: 512Mi ##最低保证512M内存
    limits.cpu: 5  ##最多使用5核CPU
    limits.memory: 16Gi ##最多使用16G内存
    configmaps: 20 ##最多支持20个configMaps
    persistentvolumeclaims: 20 ##最多支持20个pvc
    replicationcontrollers: 20 ##最多支持20个replicationControllers
    secrets: 20 ##最多支持20个secrets
    services: 50 ##最多支持50个services
EOF

生效

$ kubectl apply -f quota.yaml

查看

$ kubectl get quota -n aming

测试:
为了显示限额效果,修改quota.yaml,将pod限制数改为5,其它先删除掉

命令行创建deployment,指定Pod副本为7

$ kubectl create deployment testdp --image=nginx:1.23.2 -n aming --replicas=7

查看deployment和pod

$ kubectl get deploy,po -n aming

2.2 Pod的limits和requests

Resource Quota是针对namespace下面所有的Pod的限制,而Pod自身也有限制。
示例:

$ cat > quota-pod.yaml <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: quota-pod
  namespace: aming

spec:
  containers:
  - image: nginx:1.23.2
    name: ngx
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 80
    resources:
      limits:
        cpu: 0.5  ##限制Pod CPU资源最多使用500m,这里的0.5=500m,1=1000m
        memory: 2Gi ##限制内存资源最多使用2G
      requests:
        cpu: 200m  ##K8s要保证Pod使用的最小cpu资源为200m,如果node上资源满足不了,则不会调度到该node上
        memory: 512Mi ##K8s要保证Pod使用最小内存为512M,如果node上资源满足不了,则不会调度到该node上
EOF

3、API资源对象Deployment

Deployment是Kubernetes1.2引入的新概念,引入的目的是为了更好的解决Pod的编排问题,为此Deployment内部使用了Replica Set来实现目的

Deployment 相对于RC的一个最大升级是我们可以随时知道当前Pod”部署”的进度,实际上由于一个Pod的创建、调度、绑定节点及在Node上启动对应的容器这一完整过程需要一定的时间,所以我们期待系统启动N个Pod副本的目标状态,实际上是一个连续变化的”部署过程”导致的最终状态

Deployment经典常用场景

  • 1.创建一个Deployment对象来生成对应的Replica Set并完成Pod副本的创建过程
  • 2.检查Deployment的状态来看部署动作是否完成(Pod副本的数量是否达到预期的值)
  • 3.更新Deployment以创建新的Pod (比如镜像升级)
  • 4.如果当前Deployment不稳定,则回滚到一个早先的Deployment版本
  • 5.暂停Deployment以便于一次性修改多个PodTemplateSpec的配置项,之后再恢复Deployment,进行新的发布
  • 6.扩展Deployment以应对高负载
  • 7.查看Deployment的状态,以此作为发布是否成功的指标。
  • 8.清理不再需要的旧版本ReplicaSets

Deployment YAML示例:

$ vi ng-deploy.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: myng
  name: ng-deploy
spec:
  replicas: 2 ##副本数
  selector:
    matchLabels:
      app: myng
  template:
    metadata:
      labels:
        app: myng
    spec:
      containers:
        - name: myng
          image: nginx:1.23.2
          ports:
          - name: myng-port
            containerPort: 80

在 Kubernetes(K8s)中,matchLabelslabels 都是用于筛选和管理 Kubernetes 资源的关键概念。它们之间的关系可以通过以下几点来解释:

  1. 定义:
    • labels:是用于标识 Kubernetes 资源(如 Pod、Service 等)的键值对。您可以在资源对象的 metadata 部分定义 labels。
    • matchLabels:是 labels 的一个子集,用于定义如何根据标签过滤资源。它是一个字符串数组,其中包含两个部分:键和操作符(如等于、存在、不等于等)。
  2. 作用:
    • labels:用于区分和识别不同的资源,方便您在集群中管理和组织资源。例如,您可以为不同的应用程序分配不同的标签,以便轻松识别它们。
    • matchLabels:用于定义资源筛选条件,以便在基于标签的策略中应用规则。例如,您可以使用 matchLabels 来匹配具有特定标签的 Pod,以便执行滚动更新或实现蓝绿部署。

matchLabels和labels之间的关系:
Kubernetes API资源对象

假设您有两个 Pod,一个用于运行应用程序 A,另一个用于运行应用程序 B。您可以为这两个 Pod 分配不同的标签:

- Pod A:
 labels:
   app: A

- Pod B:
 labels:
   app: B

现在,您可以使用 matchLabels 来根据标签过滤这两个 Pod:

matchLabels: app: A

这将匹配具有 “app: A” 标签的 Pod A,而不匹配具有 “app: B” 标签的 Pod B。

总之,matchLabelslabels 在 Kubernetes 中共同作用,帮助您根据标签筛选和管理资源。labels 用于为资源分配标识,而 matchLabels 用于根据这些标识执行特定操作。

使用YAML创建deploy:

$ kubectl apply -f ng-deploy.yaml

查看:

$ kubectl get deploy 
$ kubectl get po

4、API资源对象Service

Kubernetes API资源对象

Service是Kubernetes里最核心的资源对象之一,Service定义了一个服务的访问入口地址,前端的应用(Pod)通过这个入口地址访问其背后的一组由Pod副本组成的集群实力。 Service与其后端Pod副本集群之间则是通过Label Selector来实现”无缝对接“。而RC的作用实际上是保证Service 的服务能力和服务质量处于预期的标准。

Service简称(svc) YAML示例:

$ vi ng-svc.yaml

apiVersion: v1
kind: Service
metadata:
  name: ngx-svc
spec:
  selector:
    app: myng
  ports:
  - protocol: TCP
    port: 80 #service的port
    targetPort: 80 #pod的port

使用YAML创建service:

$ kubectl apply -f ng-svc.yaml

查看:

$ kubectl get svc

NAME              TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
ngx-svc           ClusterIP   10.111.213.169   <none>        8990/TCP         4s

三种Service 类型:
1)ClusterIP
该方式为默认类型,即,不定义type字段时(如上面service的示例),就是该类型。

spec:
  selector:
    app: myng
  type: ClusterIP
  ports:
  - protocol: TCP
    port: 8080  ##service的port
    targetPort: 80  ##pod的port

2)NodePort
如果想直接通过k8s节点的IP直接访问到service对应的资源,可以使用NodePort,Nodeport对应的端口范围:30000-32767

spec:
  selector:
    app: myng
  type: NodePort
  ports:
  - protocol: TCP
    port: 8080  ##service的port
    targetPort: 80  ##pod的port
    nodePort: 30009  ##可以自定义,也可以不定义,它会自动获取一个端口

3)LoadBlancer
这种方式,需要配合公有云资源比如阿里云、亚马逊云来实现,这里需要一个公网IP作为入口,然后来负载均衡所有的Pod。

spec:
  selector:
    app: myng
  type: LoadBlancer
  ports:
  - protocol: TCP
    port: 8080  ##service的port
    targetPort: 80  ##pod的port

5、API资源对象DaemonSet

有些场景需要在每一个node上运行Pod(比如,网络插件calico、监控、日志收集),Deployment无法做到,而Daemonset(简称ds)可以。Deamonset的目标是,在集群的每一个节点上运行且只运行一个Pod。
Daemonset不支持使用kubectl create获取YAML模板,所以只能照葫芦画瓢了,参考Deployment的YAML编写,其实Daemonset和Deployment的差异很小,除了Kind不一样,还需要去掉replica配置。

适用场景

  • 集群存储守护程序,如glusterd、ceph要部署在每个节点上提供持久性存储
  • 节点监视守护进程,如prometheus监控集群,可以在每个节点上运行一个node-exporter进程来收集监控节点的信息
  • 日志收集守护程序,如fluentd或logstash,在每个节点运行容器
$ vi  ds-demo.yaml

apiVersion: apps/v1
kind: DaemonSet
metadata:
  labels:
    app: ds-demo
  name: ds-demo
spec:
  selector:
    matchLabels:
      app: ds-demo
  template:
    metadata:
      labels:
        app: ds-demo
    spec:
      containers:
        - name: ds-demo
          image: nginx:1.23.2
          ports:
          - name: mysql-port
            containerPort: 80

使用YAML创建ds

$ kubectl apply -f ds-demo.yaml

查看:

$ kubectl get ds
$ kubectl get po

但只在两个node节点上启动了pod,没有在master上启动,这是因为默认master有限制。

$ kubectl describe node k8s01 |grep -i 'taint'
Taints:             node-role.kubernetes.io/control-plane:NoSchedule
  • 说明:Taint叫做污点,如果某一个节点上有污点,则不会被调度运行pod。
  • 但是这个还得取决于Pod自己的一个属性:toleration(容忍),即这个Pod是否能够容忍目标节点是否有污点。
  • 为了解决此问题,我们可以在Pod上增加toleration属性。下面改一下YAML配置:
$ vi  ds-demo.yaml

apiVersion: apps/v1
kind: DaemonSet
metadata:
  labels:
    app: ds-demo
  name: ds-demo
spec:
  selector:
    matchLabels:
      app: ds-demo
  template:
    metadata:
      labels:
        app: ds-demo
    spec:
      tolerations:
        - key: node-role.kubernetes.io/control-plane
          effect: NoSchedule
      containers:
        - name: ds-demo
          image: nginx:1.23.2
          ports:
          - name: mysql-port
            containerPort: 80

再次应用此YAML

$ kubectl apply -f ds-demo.yaml

6、API资源对象StatefulSet

Pod根据是否有数据存储分为有状态和无状态:

  • 无状态:指的Pod运行期间不会产生重要数据,即使有数据产生,这些数据丢失了也不影响整个应用。比如Nginx、Tomcat等应用适合无状态。
  • 有状态:指的是Pod运行期间会产生重要的数据,这些数据必须要做持久化,比如MySQL、Redis、RabbitMQ等。

Deployment和Daemonset适合做无状态,而有状态也有一个对应的资源,那就是Statefulset(简称sts)。

StatefulSet是为了解决有状态服务的问题(对应DeploymentReplica Set是为无状态服务而设计),其应用场景包括:

  • 稳定的持久化存储,即Pod重新调度后还是能访问到相同的持久化数据,基于PVC来实现
  • 稳定的网络标志,即Pod重新调度后其PodName和HostName不变,基于Headless Service(即没有Cluster IP的Service)来实现
  • 有序部署,有序扩展,即Pod是有顺序的,在部署或者扩展的时候要依据定义的顺序依次依次进行(即从0到N-1,在下一个Pod运行之前所有之前的Pod必须都是Running和Ready状态),基于init containers来实现
  • 有序收缩,有序删除(即从N-1到0)

说明:由于StatefulSet涉及到了数据持久化,用到了StorageClass,需要先创建一个基于NFS的StorageClass

额外开一台虚拟机,搭建NFS服务(具体步骤略)
假设NFS服务器IP地址为192.168.222.128,共享目录为/data/nfs

另外,要想使用NFS的sc,还需要安装一个NFS provisioner,它的作用是自动创建NFS的pv
github地址: https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner

将源码下载下来:

$ git clone https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner
$ cd nfs-subdir-external-provisioner/deploy
$ sed -i 's/namespace: default/namespace: kube-system/' rbac.yaml  ##修改命名空间为kube-system
$ kubectl apply -f rbac.yaml  ##创建rbac授权

修改deployment.yaml

$ sed -i 's/namespace: default/namespace: kube-system/' deployment.yaml ##修改命名空间为kube-system

  ##需要修改带注释的地方 
   spec:
      serviceAccountName: nfs-client-provisioner
      containers:
        - name: nfs-client-provisioner
          image: chronolaw/nfs-subdir-external-provisioner:v4.0.2  ##改为dockerhub地址
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: k8s-sigs.io/nfs-subdir-external-provisioner
            - name: NFS_SERVER
              value: 192.168.222.128  ##nfs服务器地址
            - name: NFS_PATH
              value: /data/nfs  ##nfs共享目录
      volumes:
        - name: nfs-client-root
          nfs:
            server: 192.168.222.128  ##nfs服务器地址
            path: /data/nfs  ##nfs共享目录

应用yaml

$ kubectl apply -f deployment.yaml 
$ kubectl apply -f class.yaml ##创建storageclass

SC YAML示例

$ cat class.yaml

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-client
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner # or choose another name, must match deployment's env PROVISIONER_NAME'
parameters:
  archiveOnDelete: "false"  ##自动回收存储空间

Sts示例:

$ vi redis-sts.yaml

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: redis-sts

spec:
  serviceName: redis-svc ##这里要有一个serviceName,Sts必须和service关联

  volumeClaimTemplates:
  - metadata:
      name: redis-pvc
    spec:
      storageClassName: nfs-client
      accessModes:
        - ReadWriteMany
      resources:
        requests:
          storage: 500Mi

  replicas: 2
  selector:
    matchLabels:
      app: redis-sts

  template:
    metadata:
      labels:
        app: redis-sts
    spec:
      containers:
      - image: redis:6.2
        name: redis
        ports:
        - containerPort: 6379

        volumeMounts:
        - name: redis-pvc
          mountPath: /data
$ vi redis-svc.yaml

apiVersion: v1
kind: Service
metadata:
  name: redis-svc

spec:
  selector:
    app: redis-sts

  ports:
  - port: 6379
    protocol: TCP
    targetPort: 6379

应用两个YAML文件

$ kubectl apply -f redis-sts.yaml -f redis-svc.yaml

对于Sts的Pod,有如下特点:

  • ① Pod名固定有序,后缀从0开始;
  • ② “域名”固定,这个“域名”组成: Pod名.Svc名,例如 redis-sts-0.redis-svc;
  • ③ 每个Pod对应的PVC也是固定的;
  • 域名组成
    普通Service: _port-name._port-protocol.my-svc.my-namespace.svc.cluster-domain.example
    无头Service:hostname.my-svc.my-namespace.svc.cluster-domain.example

实验:

ping 域名

$ kubectl exec -it redis-sts-0 -- bash   ##进去可以ping redis-sts-0.redis-svc 和  redis-sts-1.redis-svc

创建key

$ kubectl exec -it redis-sts-0 -- redis-cli
$ 127.0.0.1:6379> set k1 'abc'
OK
$ 127.0.0.1:6379> set k2 'bcd'
OK

模拟故障

$ kubectl delete pod redis-sts-0

删除后,它会自动重新创建同名Pod,再次进入查看redis key

$ kubectl exec -it redis-sts-0 -- redis-cli
$ 127.0.0.1:6379> get k1
"abc"
$ 127.0.0.1:6379> get k2
"bcd"

数据依然存在。

  • 关于Sts里的多个Pod之间的数据同步
    K8s并不负责Sts里的Pod间数据同步, 具体的数据同步和一致性策略取决于我们部署的有状态应用程序。不同的应用程序可能使用不同的数据同步和一致性策略。例如,关系型数据库(如 MySQL)可能使用主-从复制,而分布式数据库(如 MongoDB)可能使用一种基于分区和副本的数据同步机制。

7、API资源对象Job

可以理解成一次性运行后就退出的Pod。
先来生成一个YAML文件:

$ kubectl create job job-demo --image=busybox  --dry-run=client  -o yaml > job-demo.yaml
vi job-demo.yaml  ##编辑此配置

apiVersion: batch/v1
kind: Job
metadata:
  name: job-demo
spec:
  template:  ##模板,基于此模板来创建pod,它用来定义pod的属性,比如container
    spec:
      restartPolicy: OnFailure ##定义Pod运行失败时的策略,可以是OnFailure和Never,其中OnFailure表示失败的话需要重启容器,Never表示失败的话不重启容器,而是重新生成一个新的Pod
      containers:
      - image: busybox
        name: job-demo
        command: ["/bin/echo"]
        args: ["hellow", "world"]

创建Job

$ kubectl apply -f job-demo.yaml

查看Job

$ kubectl get job,pod

可以看到该容器运行完成后状态就变成了Completed。

对于Job,还有几个特殊字段:

  • activeDeadlineSeconds,设置 Pod 运行的超时时间。
  • backoffLimit,设置 Pod 的失败重试次数。
  • completions,Job 完成需要运行多少个 Pod,默认是 1 个。
  • parallelism,它与 completions 相关,表示允许并发运行的 Pod 数量,避免过多占用资源。
$ vi  myjob.yaml

apiVersion: batch/v1
kind: Job
metadata:
  name: sleep-job

spec:
  activeDeadlineSeconds: 15  #15s就超时
  backoffLimit: 2 #失败重试2次就放弃
  completions: 4 #要运行4个pod,才算完成
  parallelism: 2 #允许并发运行2个pod

  template:
    spec:
      restartPolicy: Never
      containers:
      - image: busybox
        name: echo-job
        imagePullPolicy: IfNotPresent
        command:
          - sh
          - -c
          - sleep 10; echo done

创建job,并查看job情况

$ kubectl apply -f myjob.yaml ; kubectl get pod -w

8、API资源对象CronJob

CronJob简称(cj)是一种周期运行的Pod,比如有些任务需要每天执行一次,就可以使用CronJob。

先来生成一个YAML文件:

$ kubectl create cj cj-demo --image=busybox --schedule="" --dry-run=client  -o yaml > cj-demo.yaml
$ vi job-demo.yaml  ##编辑此配置

apiVersion: batch/v1
kind: CronJob
metadata:
  name: cj-demo

spec:
  schedule: '*/1 * * * *'
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: OnFailure
          containers:
          - image: busybox
            name: cj-demo
            imagePullPolicy: IfNotPresent
            command: ["/bin/echo"]
            args: ["hello", "world"]

运行并查看

$ kubectl apply -f cj-demo.yaml
$ kubectl get cj
$ kubectl get pod

9、API资源对象Endpoint

Endpoint(简称ep)资源是和Service一一对应的,也就是说每一个Service都会对应一个Endpoint。

$ kubectl get ep

NAME         ENDPOINTS                           AGE
kubernetes   192.168.222.131:6443                3d5h
ngx-svc      10.18.235.159:80,10.18.236.173:80   21h

$ kubectl get svc
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.15.0.1      <none>        443/TCP   3d5h
ngx-svc      ClusterIP   10.15.41.113   <none>        80/TCP    21h

Endpoint可以理解成Service后端对应的资源。

有时候K8s里的Pod需要访问外部资源,比如访问外部的MySQL服务,就可以定义一个对外资源的Ednpoint,然后再定义一个Service,就可以让K8s里面的其它Pod访问了。

$ vim testep.yaml

apiVersion: v1
kind: Endpoints
metadata:
  name: external-mysql
subsets:
  - addresses:
    - ip: 192.168.222.128
    ports:
      - port: 3306

---
apiVersion: v1
kind: Service  ##注意,该service里并不需要定义selector,只要Service name和Endpoint name保持一致即可
metadata:
  name: external-mysql
spec:
  ports:
    - port: 3306

应用YAML文件

$ kubectl apply -f testep.yaml

测试

$ kubectl get ep
$ kubectl get svc

安装mariadb包(需要mysql命令),然后命令行连接Service external-mysql对应的Cluster IP测试

  • 容器内访问时可以直接通过域名访问即svc名称

10、API资源对象ConfigMap

在Kubernetes 1.2中新添加了功能ConfigMap,主要功能是为了解决应用程序会从配置文件、环境变量中获取配置信息。但是默认情况下配置信息需要与docker images解耦,ConfigMap API为我们提供了向容器中注入配置信息的机制,ConfigMap可以被用来保存单个属性,也可以用来保存整个配置文件或者JSON二进制对象

ConfigMap API资源用来保存key-vlaue pair配置数据,这个数据可以在pods里使用,或者被用来为contaroller一样的系统组件存储配置数据。ConfigMap 是为了方便的处理不含铭感信息的字符串,你可以将它理解为Linux系统中的/etc目录,专门用来存储配置文件的目录

注意: ConfigMap不是属性配置文件的代替品,ConfigMap只是作为多个properties文件的引用。

ConfigMap(简称cm)用来存储配置信息,比如服务端口、运行参数、文件路径等等。

直接上示例吧:

$ vi mycm.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: mycm

data:
  DATABASE: 'db'
  USER: 'wp'
  PASSWORD: '123456'
  ROOT_PASSWORD: '123456'

创建cm

$ kubectl apply -f mycm.yaml

查看

$ kubectl get cm
$ kubectl describe cm mycm

在其它pod里引用ConfigMap

$ vi  testpod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: testpod
  labels:
    app: testpod

spec:
  containers:
  - image: mariadb:10
    name: maria
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 3306

    envFrom:   ##将cm里的字段全部导入该pod
    - prefix: 'MARIADB_'  ##将导入的字段名前面自动加上前缀,例如MARIADB_DATABASE, MARIADB_USER
      configMapRef:  ##定义哪个cm
        name: mycm

验证:

$ kubectl exec -it testpod -- bash  ##进入pod,查看变量$MARIADB_DATABASE

11、API资源对象Secret

Secret和cm的结构和用法很类似,不过在 K8s里Secret 对象又细分出很多类,比如:

  • 访问私有镜像仓库的认证信息
  • 身份识别的凭证信息
  • HTTPS 通信的证书和私钥
  • 一般的机密信息(格式由用户自行解释)

前几种我们现在暂时用不到,所以就只使用最后一种。

YAML示例:

$ vi  mysecret.yaml

apiVersion: v1
kind: Secret
metadata:
  name: mysecret

data:
  user: YW1pbmc=   ## echo -n "aming"|base64
  passwd: bGludXgxMjM=  ## echo -n "linux123"|base64

查看:

$ kubectl apply -f mysecret.yaml
$ kubectl get secret
$ kubectl describe secret mysecret

在其它pod里引用Secret

$ vi testpod2.yaml

apiVersion: v1
kind: Pod
metadata:
  name: testpod2

spec:
  containers:
  - image: busybox
    name: busy
    imagePullPolicy: IfNotPresent
    command: ["/bin/sleep", "300"]

    env:
      - name: USERNAME
        valueFrom:
          secretKeyRef:
            name: mysecret
            key: user
      - name: PASSWORD
        valueFrom:
          secretKeyRef:
            name: mysecret
            key: passwd

查看

$ kubectl exec -it testpod2 -- sh  ##进去后可以 echo $PASSWORD查看变量值
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

给TA打赏
共{{data.count}}人
人已打赏
Kubernetes云原生

Kubernetes基础概念及核心组件

2025-3-18 8:06:15

Kubernetes云原生

kubeadm部署kubernetes

2025-3-18 8:08:15

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索
Index