Pod资源对象+ReplicaSet+Job资源对象

Pod资源

格式

kind: Pod
apiVersion: v1
metadata:
  name: test-pod
spec:
  containers:
  - name: test-app
    image: httpd

  - name: test-web
    image: busybox

Pod中镜像获取策略:
将上述Pod资源的镜像下载策略改为IfNotPresent.

kind: Pod
apiVersion: v1
metadata:
  name: pod1
spec:
  containers:
  - name: pod1
    image: httpd
    imagePullPolicy: IfNotPresent

k8s默认根据镜像的TAG的不同,有3中不同策略:
Always:镜像标签为"latest"或镜像标签不存在时,总是从指定的仓库(默认的官方仓库、或者私有仓库)中获取最新镜像。
IfNotPresent:仅当本地镜像不存在时才从目标仓库中下载。也就意味着,如果本地存在,直接使用本地镜像,无需再联网下载
Never: 禁止从仓库中下载镜像,即只使用本地镜像
PS:对于标签为“latest”或者这标签不存在,其默认镜像下载策略为“Always”,而对于其他标签的镜像,默认则使用了“IfNotPresent”.
上述语句中提到的"本地"是指: docker images命令能够给查看到的镜像

容器的重启策略
将上述Pod资源添加重启策略为OnFailure.

kind: Pod
apiVersion: v1
metadata:
  name: pod2
spec:
  restartPolicy: OnFailure
  containers:
  - name: pod2
    image: httpd
    imagePullPolicy: IfNotPresent

Always:但凡Pod对象终止就将其重启,此为默认设定
OnFailure: 仅在Pod对象出现错误时才将其重启
以上两种方案:我们可以换个角度去理解,比如: echo $? 可以利用 Pod的退出状态
Always:如果Pod是正常退出,而且重启策略为Always,那么Pod也会被重启。
OnFailuer: 仅在Pod是异常退出的时候,才重启Pod
Never: 从不重启

小技巧:
同一个yaml文件内,可以同时存在多种资源对象,但最好是同一个服务相关的资源。并且在写的时候,不同的资源需要用“—” 将资源隔离。其实默认是一个资源的yaml,最上方也有“—"不过是通常会省略不写。
举个栗子:

---
apiVersion: v1
kind: Namespace
metadata:
 name: test
---
kind: Pod
apiVersion: v1
metadata:
 name: test-pod
 namespace: test
spec:
 restartPolicy: OnFailure
 containers:
 - name: test-app
   image: httpd
   imagePullPolicy: IfNotPresent

Pod的默认健康检查
根据Pod的默认重启策略,对Pod进行健康检查

kind: Pod
apiVersion: v1
metadata:
  name: healthcheck
  namespace: bdqn
spec:
  restartPolicy: OnFailure
  containers:
  - name: test-app
    image: httpd
    imagePullPolicy: IfNotPresent
    args:
    - sh
    - -c
    - sleep 10; exit 1        0:正常 1:异常

监测pod运行状态

[root@master ~]# kubectl get pod -n bdqn -w

如果此时,我们将推出状态码改为0,也就是正常退出,仍使用OnFailure策略,但它就不会重启Pod了

kind: Pod
apiVersion: v1
metadata:
  name: healthcheck
  namespace: bdqn
spec:
  restartPolicy: OnFailure
  containers:
  - name: test-app
    image: httpd
    imagePullPolicy: IfNotPresent
    args:
    - sh
    - -c
    - sleep 10; exit 0        0:正常 1:异常

监测pod运行状态

[root@master ~]# kubectl get pod -n bdqn -w

LivenessProbe(活跃度、存活性)

kind: Pod
apiVersion: v1
metadata:
  name: liveness
  labels:
    test: liveness
spec:
  restartPolicy: OnFailure
  containers:
  - name: liveness
    image: busybox
    args:
    - sh
    - -c
    - touch /tmp/test; sleep 30; rm -rf /tmp/test; sleep 300
    livenessProbe:
      exec:
        command:
        - cat
        - /tmp/test
      initialDelaySeconds: 10  #pod运行10秒后开始探测
      periodSeconds: 5  #每5秒探测一次

PS: Liveness活跃度探测,根据探测某个文件是否存在,来确认某个服务是否正常运行,如果存在则正常,否则,它会根据你设置的Pod的重启策略操作Pod。

Readiness(敏捷探测、就绪性探测)

kind: Pod
apiVersion: v1
metadata:
  name: readiness
  labels:
    test: readiness
spec:
  restartPolicy: OnFailure
  containers:
  - name: readiness
    image: busybox
    args:
    - sh
    - -c
    - touch /tmp/test; sleep 30; rm -rf /tmp/test; sleep 300
    readinessProbe:
      exec:
        command:
        - cat
        - /tmp/test
      initialDelaySeconds: 10
      periodSeconds: 5

PS: 总结liveness和 readiness探测
1)liveness和readiness是两种健康检查机制,如果不特意配置,k8s将两种探测采取相同的默认行为,即通过判断容器启动进程的返回值是否为零,来判断探测是否成功

2)两种探测配置方法完全一样,不同之处在于探测失败后的行为:liveness探测是根据Pod重启策略操作容器,大多数是重启容器。readiness则是将容器设置为不可用,不接收Service转发的请求

3)两种探测方法可以独立存在,也可以同时使用。用liveness判断容器是否需要重启实现自愈;用readiness判断容器是否已经准备好对外提供服务

健康检测的应用
在扩容中的应用

kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: web
spec:
  replicas: 5
  template:
    metadata:
      labels:
        run: web
    spec:
      containers:
      - name: web
        image: httpd
        ports:
        - containerPort: 80
        readinessProbe:
          httpGet:
            scheme: HTTP
            path: /healthy
            port: 80
          initialDelaySeconds: 10
          periodSeconds: 5
---
kind: Service
apiVersion: v1
metadata:
  name: web-svc
spec:
  type: NodePort
  selector:
    run: web
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 30000

总结:服务扩容中,如果没有针对性就绪探测,往往扩容之后,表面看Pod的状态是没有问题的,但其实Pod内的服务是否运行正常也是我们要关注的,而Readiness的关注点就在这,如果Pod内的服务运行有问题,那么,这些新扩容的Pod就不会被添加到Service资源的转发中,从而保证用户能够有最起码正常的服务体验。

在更新过程中的使用

[root@master ~]# vim updata.yaml
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: update
spec:
  replicas: 10
  template:
    metadata:
      labels:
        app: update
    spec:
      containers:
      - name: update
        image: 192.168.229.187:5000/httpd:v1
        args:
        - sh
        - -c
        - sleep 10; touch /tmp/health; sleep 300
        readinessProbe:
          exec:
            command:
            - cat
            - /tmp/health
          initialDelaySeconds: 10
          periodSeconds: 5

复制update1的yaml文件,命名update2.yaml,并更改镜像和args的命令部分,这里我们确定,更新肯定会失败,因为它没有符合readiness探测文件

vim updata2.yaml
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: update
spec:
  replicas: 10
  template:
    metadata:
      labels:
        app: update
    spec:
      containers:
      - name: update
        image: 192.168.229.187:5000/httpd:v2
        args:
        - sh
        - -c
        - sleep 300
        readinessProbe:
          exec:
            command:
            - cat
            - /tmp/health
          initialDelaySeconds: 10
          periodSeconds: 5

在更新的过程总,Readiness探测探测同样重要,想象一下,如果更新完成的Pod内没有更新的内容,并且也没有相对应的探测,那么有可能我们更新的Pod全部都会是不可用的,这是一个天大的灾难

其实在更新过程中,为了保证,即使更新失败,至少也有相对数量的副本数量仍能正常提供服务,其实是有数值可以设置
maxSurge: 此参数控制滚动更新过程中,副本总数超过预期数(replicas)的值。可以是整数,也可以是百分比,默认是1
maxUnavailable:不可用Pod的值。默认为1.可以是整数,也可以是百分比

ReplicaSet

Deployment是一种高级的Pod控制器,然后,这种高级Pod控制器,并不是像想象中直接管理后端的Pod,而是又创建了RS这种Pod控制器,然后由RS控制后端的Pod,那么为什么这么做那?因为:RS资源并不支持滚动滚新策略
RC: ReplicationController (老一代的Pod控制器)
用于确保由其管控的Pod对象副本数量,能够满足用户期望,多则删除,少则通过模板创建
特点:
1.确保Pod资源的对象的数量精准
2.确保Pod健康运行
3.弹性伸缩
同样,它也可以通过yaml或json格式的资源清单来创建。其中spec字段一般嵌套以下字段
replicas: 期望的Pod对象副本数量
selector: 当前控制器匹配Pod对象副本的标签选择器
template: Pod副本的模板
与RC相比而言,RS不仅支持基于等值的标签选择器,而且还支持基于集合的标签选择器

Labels与selector的关系:
举个栗子:
1)现在有一个Pod资源,且是拥有2个标签。还有svc资源,selector选择器,仅有一个符合,问:svc资源是否能成功的关联到上述的Pod资源?

kind: Pod
apiVersion: v1
metadata:
  name: pod1
  labels:
    test: web
    app: httpd
spec:
  containers:
  - name: pod1
    image: httpd
---
kind: Service
apiVersion: v1
metadata:
  name: test-svc1
spec:
  selector:
    app: httpd
  ports:
  - port: 80

2)现在有一个Pod资源,且是拥有1个标签。还有svc资源,selector选择器,需要2个满足条件,问:svc资源是否能成功的关联到上述的Pod资源?

kind: Pod
apiVersion: v1
metadata:
  name: pod1
  labels:
    test: web
spec:
  containers:
  - name: pod1
    image: httpd
---
kind: Service
apiVersion: v1
metadata:
  name: test-svc1
spec:
  selector:
    app: httpd
    test: web
  ports:
  - port: 80

结论:通过以上简单的小实验,可以得到的结论: selector我们可以是拥有选择权的,而labels只能够被动的“被选择”,
所以:简单一句话: labels必须全部满足selector的要求,才能被匹配

常用标签
标签:解决同类型的资源对象越来越多,为了更好的管理,按照标签分组
常用标签分类:
release(版本): stable(稳定版)、canary(金丝雀版本)、beta(测试版)
environment(环境变量): dev(开发)、qa(测试)、production(生产)
application(应用): ui、as(application software应用软件)、pc、sc
tier(架构层级): frontend(前端)、backend(后端)、cache(缓存)
partition(分区): customerA(客户A)、customerB(客户B)
track(品控级别): daily(每天)、weekly(每周)
标签要做到:见名知意

这里我们不举栗子,举个蚕豆: 写一个Pod的yaml文件

kind: Pod
apiVersion: v1
metadata:
  name: pod-labels
  labels:
    env: qa
    tier: frontend
spec:
  containers:
  - name: myapp
    image: httpd

通过–show-labels显示资源对象的标签

[root@master yaml]# kubectl get pod --show-labels 
NAME         READY   STATUS    RESTARTS   AGE   LABELS
pod-labels   1/1     Running   0          18s   env=qa,tier=frontend

通过-l 查看仅包含某个标签的资源。

[root@master yaml]# kubectl get pod -l env
NAME         READY   STATUS    RESTARTS   AGE
pod-labels   1/1     Running   0          65s

给Pod资源添加标签

[root@master yaml]# kubectl label pod pod-labels release=v1
[root@master yaml]# kubectl get pod pod-labels --show-labels
[root@master yaml]# kubectl get pod pod-labels --show-labels
NAME         READY   STATUS    RESTARTS   AGE     LABELS
pod-labels   1/1     Running   0          2m53s   env=qa,release=v1,tier=frontend

删除标签

[root@master yaml]# kubectl label pod pod-labels release-
pod/pod-labels labeled

修改标签

[root@master yaml]# kubectl label pod pod-labels env=dev --overwrite
pod/pod-labels labeled
[root@master yaml]# kubectl get pod -l tier  --show-labels
NAME         READY   STATUS    RESTARTS   AGE     LABELS
pod-labels   1/1     Running   0          6m26s   env=dev,tier=frontend

如果标签有多个,标签选择器选择其中一个,也可以关联成功。相反,如果选择器有多个,那么标签必须完全满足条件,才可以关联成功!
标签选择器:标签的查询过滤条件
基于等值关系的(equality-based):"=","==","!="前边两个都是相等,最后是不等
基于集合关系(set-based):“in”、“notin”、"exists"三种

举个栗子:

pod 条件
PodA app:nginx name:zhangsan age:18
PodB app:nginx name:lisi age:20
PodC name: wangwu age:45
...
selector:
  matchLabels:
      app: nginx
        matchExpressions:
          //Pod中有name这个关键字的,并且对应的值是:zhangsan,或者lisi,那么此处会关联到PodA、PodB
              - {
    
    key: name,operator: In,values: [zhangsan,lisi]}
              -   //所有关键字是age的,并且忽略它的值,都会被选中,此处会关联到PodA、PodB、PodC
              -     - {
    
    key: age,operator: Exists,values:}
...

matchLabels: 指定键值对表示的标签选择器
matchExpressions:基于表达式来指定的标签选择器。选择器列表间为“逻辑与”关系;使用In或者NotIn操作时,其values不强制要求为非空的字符串列表,而使用Exists或DostNotExist时,其values必须为空

使用标签选择器的逻辑

  1. 同时指定的多个选择器之间的逻辑关系为“与“操作
  2. 使用空值的标签选择器意味着每个资源对象都将被选择中
  3. 空的标签选择器无法选中任何资源
    RS的资源清单和RC和Deployment并无二致,所以在此不再过多介绍。

DaemonSet
它也是一种Pod控制器

特点:它会在每一个Node节点上都会生成并且只能生产一个Pod资源。
使用场景:如果必须将Pod运行在固定的某个或某几个节点,且要优先于其他Pod的启动。通常情况下,默认会每一个节点都会运行,并且只能运行一个Pod。这种情况推荐使用DaemonSet资源对象。
监控程序:
日志收集程序;

运行一个web服务,在每一个节点都运行一个Pod


kind: DaemonSet
apiVersion: extensions/v1beta1
metadata:
  name: test-ds
spec:
  template:
    metadata:
      labels:
        name: test-ds
    spec:
      containers:
      - name: test-ds
        image: httpd

RC、RS、Deployment、DaemonSet。 Pod控制器。–> Controller-manager(维护集群状态,保证Pod处于期望的状态。)

Job资源对象

服务类的Pod容器:RC、RS、DS、Deployment.(Pod内运行的服务,要持续运行)
工作类的Pod容器:Job—>执行一次,或者批量执行处理程序,完成之退出容器。

举栗子:

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

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

提高Job的执行效率
我们可以在Job.spec字段下加上parallelism选项。表示同时运行多少个Pod执行任务
我们可以在Job.spec字段下加上completions选项。表示总共需要完成Pod的数量

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

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

CronJob
如何定时执行Job

kind: CronJob
apiVersion: batch/v1
metadata:
  name: test-cronjob
spec:
  schedule: "*/1 * * * *"  #分、时、日、月、周
  jobTemplate:
  spec:
    template:
      spec:
        containers:
        - name: hello
          image: busybox
          command: ["echo","hello cronjob!"]
        restartPolicy: Never

此时查看Pod的状态,会发现,每分钟都会运行一个新的Pod来执行命令规定的任务

PS:如果规定具体时间,可能并不会执行任务。cronjob资源对象,开发还未完成此功能

添加apiVersion库

[root@master job]# vim /etc/kubernetes/manifests/kube-apiserver.yaml
在yaml文件中command指令下添加
- --runtime-config=batch/v2alpha1=true

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

查看api版本库

[root@master job]# kubectl api-versions

注意:此时仍然不能正常运行指定时间的cronJob,这是因为K8s官方在cronjob这个资源对象的支持中还没有完善此功能,还待开发。
跟Job资源一样在cronjob.spec.jobTemplate.spec下同样支持并发Job参数:parallelism,也支持完成Pod的总数参数:completions

猜你喜欢

转载自blog.csdn.net/hjyhjy0/article/details/109488606