02-k8s各应用管理器与pod介绍

前言:Deployment的发展

虽然ReplicaSet可以确保在任何给定时间运行的Pod副本达到指定的数量,但是Deployment(部署)是一个更高级的概念,它管理ReplicaSet并为Pod和ReplicaSet提供声明性更新以及许多其他有用的功能,所以建议在实际使用中,采用Deployment代替ReplicaSet。

如果在Deployment对象中描述了所需的状态,Deployment控制器就会以可控制的速率将实际状态更改为期望状态。也可以在Deployment中创建新的ReplicaSet,或者删除现有的Deployment并使用新的Deployment部署所用的资源。


一、无状态应用管理器Deployment

deployment用于部署无状态的服务,是k8s中最常用的控制器。管理对象为pod。

一般用于管理维护企业内部无状态的微服务,比如configserver、zuul、springboot。

deployment可以管理多个副本的Pod实现无缝迁移、自动扩容缩容、自动灾难恢复、一键回滚等功能。

Deployment管理器基础操作

创建Deployment

方式1:手动创建

kubectl create deployment {deployment-name} --image=nginx

方式2:以yaml格式或json格式创建Deployment

kubectl create -f test-nginx.yaml

查询deployment状态

查看指定deployment的详细信息

kubectl describe deployment {deployment-name} -n

kubectl get deployments -o wide

解析:-o wide 查看全部详情

导出deployment配置

导出已创建的deployment配置文件至指定路径:

kubectl get deployments test-nginx -o yaml >/data1/k8s-app/deploy/test-nginx.yaml

查看指定某一pod下的日志

kubectl logs {pod-name} -n

修改deployment配置

修改某个指定deployment配置

kubectl edit deployment {deployment-name} -n

kubectl apply -f xxx.yaml -n

kubectl replace -f xxx.yaml -n


版本升级操作:

手动改镜像并记录:

kubectl set image deploy {deployment-name} -n {namespace-name} XXX=xx(版本信息) --record

解析:
--record 表示记录本次修改

查看部署历史:

kubectl rollout history deploy {deployment-name} -n

更新多次,需要查看某次更新的详细信息:

kubectl rollout history deploy {deployment-name} -n {namespace-name} --revision=3

解析:
--revision 指定版本号

回滚到上一个版本:

kubectl rollout undo deploy {deployment-name} -n

回滚到指定版本:

kubectl rollout undo deploy {deployment-name} -n {namespace-name} --to-revision=2

解析:
--to-revision=2 表示回滚到更新的第2个版本


扩容与缩容

动态调整Pod的副本数:

kubectl scale deploy {deployment-name} -n {namespace-name} --replicas=5

解析:
--replicas=5 将原有副本数修改为5,若原有为2个,将扩容3个副本;若原有为10个,将缩容

注意:这里的扩容缩容,不会修改原有rs

Deployment更新的暂停与恢复(用set 修改多处更新)

暂停Deployment更新

kubectl rollout pause deploy {deployment-name} -n

set修改deployment资源

kubectl set image ......

kubectl set resources deploy {deployment-name} -c {container-name}(指定容器) --limits=cpu=200m,memory=128Mi --requests=cpu=10m,memory=16Mi

恢复Deployment更新:

kubectl rollout resume {deployment-name} -n

注意:恢复更新的Deployment创建了一个新的RS(复制集)

注意事项:
可修改yaml格式来更新Deployment,其中在spec下的几个参数配置解析为:

  • replicas: 4 表示副本数,4为4个副本
  • revisionHistoryLimit:设置保留RS旧的revision的个数,设置为0的话,不保留历史数据;
  • minReadySeconds:可选参数,指定新创建的Pod在没有任何容器崩溃的情况下视为Ready最小的秒数,默认为0,即一旦被创建就视为可用。
关于滚动更新的策略参数解析:

strategy.type:更新deployment的方式,默认是RollingUpdate;

  • RollingUpdate表示滚动更新,可以指定maxSurge和maxUnavailable
  • maxUnavailable:指定在回滚或更新时最大不可用的Pod的数量,可选字段,默认25%,可以设置成数字或百分比,如果该值为0,那么maxSurge就不能0
  • maxSurge:可以超过期望值的最大Pod数,可选字段,默认为25%,可以设置成数字或百分比,如果该值为0,那么maxUnavailable不能为0
  • Recreate:重建,先删除旧的Pod,在创建新的Pod

示例:

# kubectl get deploy nginx -oyaml
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "12"
    kubernetes.io/change-cause: kubectl set image deploy nginx nginx=nginx:1.15.3
      --record=true
  creationTimestamp: "2020-09-19T02:41:11Z"
  generation: 19
  labels:
    app: nginx
  name: nginx
  namespace: default
spec:
  progressDeadlineSeconds: 600
  replicas: 2
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: nginx
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:1.15.3
        imagePullPolicy: IfNotPresent
        name: nginx
        resources:
          limits:
            cpu: 200m
            memory: 128Mi
          requests:
            cpu: 10m
            memory: 16Mi
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30

二、有状态应用管理StatefulSet

StatefulSet(有状态集,缩写为sts)主要用于管理有状态应用程序的工作负载API对象。常用于部署有状态的且需要有序启动的应用程序。

和Deployment类似,一个StatefulSet也同样管理着基于相同容器规范的Pod。不同的是,StatefulSet为每个Pod维护了一个粘性标识。这些Pod是根据相同的规范创建的,但是不可互换,每个Pod都有一个持久的标识符,在重新调度时也会保留,一般格式为StatefulSetName-Number。比如定义一个名字是Redis-Sentinel的StatefulSet,指定创建三个Pod,那么创建出来的Pod名字就为Redis-Sentinel-0、Redis-Sentinel-1、Redis-Sentinel-2。

StatefulSet创建的Pod一般使用Headless Service(无头服务)负责Pod的网络身份和通信,需要提前创建此服务。和普通的Service的区别在于Headless Service没有ClusterIP,它使用的是Endpoint进行互相通信。在删除一个StatefulSet时,不保证对Pod的终止,要在StatefulSet中实现Pod的有序和正常终止,可以在删除之前将StatefulSet的副本缩减为0。

Headless一般格式为:
statefulSetName-{0..N-1}.serviceName.namespace.svc.cluster.local

解析:

  • statefulSetName 为StatefulSet的名字;
  • 0..N-1 为Pod所在的序号,从0开始到N-1;
  • serviceName 为Headless Service的名字,创建StatefulSet时,必须指定Headless Service名称;
  • namespace 为服务所在的命名空间;
  • .cluster.local 为Cluster Domain(集群域)。
StatefulSet注意事项:

一般StatefulSet用于有以下一个或者多个需求的应用程序:

  • 需要稳定的独一无二的网络标识符。
  • 需要持久化数据。
  • 需要有序的、优雅的部署和扩展。
  • 需要有序的自动滚动更新。
  • 如果应用程序不需要任何稳定的标识符或者有序的部署、删除或者扩展,应该使用无状态的控制器部署应用程序,比如Deployment或者ReplicaSet。

StatefulSet是Kubernetes 1.9版本之前的beta资源,在1.5版本之前的任何Kubernetes版本都没有。
Pod所用的存储必须由PersistentVolume Provisioner(持久化卷配置器)根据请求配置StorageClass,或者由管理员预先配置,当然也可以不配置存储。
为了确保数据安全,删除和缩放StatefulSet不会删除与StatefulSet关联的卷,可以手动选择性地删除PVC和PV(参考PV和PVC节)。

Deployment管理器基础操作

定义一个StatefulSet资源yaml文件

定义一个简单的StatefulSet的示例如下:

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  serviceName: "nginx"
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
          name: web

注意:
此示例没有添加存储配置

其中:

  • kind: Service 定义了一个名字为Nginx的Headless Service,创建的Service格式为nginx-0.nginx.default.svc.cluster.local,其他的类似,因为没有指定Namespace(命名空间),所以默认部署在default。
  • kind: StatefulSet 定义了一个名字为web的StatefulSet,replicas表示部署Pod的副本数。
  • 在StatefulSet中必须设置Pod选择器(.spec.selector)用来匹配其标签(.spec.template.metadata.labels)。在1.8版本之前,如果未配置该字段(.spec.selector),将被设置为默认值,在1.8版本之后,如果未指定匹配Pod Selector,则会导致StatefulSet创建错误。
  • 当StatefulSet控制器创建Pod时,它会添加一个标签statefulset.kubernetes.io/pod-name,该标签的值为Pod的名称,用于匹配Service。
查看更新过程

kubuctl rollout status sts {statefulset-name} -n

过滤查看pod配置中某一信息

kubectl get pod {pod-name} -n {namespace-name} -oyaml | grep image

kubectl get po -l app=nginx -w
-w 参数表示动态查看pod的更新过程

在pod的配置中,updateStrategy 表示更新策略,其中若type: RollingUpdate 表示滚动更新,修改pod配置后会根据创建顺序更新,配置为:

updateStrategy:
    rollingUpdate:
      partition: 0
    type: RollingUpdate

解析:
	partition: 0 表示分段更新,0表示小于0的pod不更新(即更新所有pod);其中数字表示更新的分段(pod)数;举例:若StatefulSet的pod数有5个,现在partition: 2;那么pod2前面的pod不会更新(pod0、pod1),更新的pod为pod2、pod3、pod4。多用于灰度发布(先让指定pod更新,在更新其它pod)

若type: OnDelete 表示只有删除pod时,才会更新修改的配置,且配置应为:

updateStrategy:
    type: RollingUpdate
StatefulSet的删除

一般情况,删除sts时,pod会被重建

涉及概念:级联删除与非级联删除

  • 级联删除:删除StatefulSet时同时删除pod,若不指定,默认为级联删除
  • 非级联删除:删除StatefulSet时不删除pod,但删除sts后,pod变成“孤儿”,此时删除pod不会被重建

设置级联删除或非级联删除
非级联删除:

kubectl delete sts {statefulset-name} -n {namespace-name} --cascade=false


三、守护进程服务DaemonSet

DaemonSet 是守护进程集,缩写为ds,在所有节点或者是匹配条件的节点(通过打标签形式)上都部署一个Pod。

使用DaemonSet的场景
  • 运行集群存储的daemon,比如ceph或者glusterd
  • 节点的CNI网络插件,calico
  • 节点日志的收集:fluentd或者是filebeat
  • 节点的监控:node exporter
  • 服务暴露:部署一个ingress-nginx
创建DaemonSet

kubectl create -f nginx-ds.yaml

示例:

apiVersion: apps/v1
kind: DaemonSet
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: nginx
  updateStrategy:
    rollingUpdate:
      maxUnavailable: 1
    type: RollingUpdate	  
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:1.15.2
        imagePullPolicy: IfNotPresent
        name: nginx
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
设置匹配条件的node部署pod

方法1命令部署:

kubectl label nodeXX(节点名称) nodeXX(节点名称-多个节点) ... ds=true

查看标签

kubectl get node --show-labels

方法2修改yaml文件:(注意,若replace YAML文件,会更新配置)

在spec下,添加

......
	  nodeSelector: 
	    ds: "ture"
......

另外,若需要添加或删除ds节点,需进行label添加或删除即可

DaemonSet更新配置
......
  updateStrategy:
    rollingUpdate:
      maxUnavailable: 1    ###最大不可用范围,建议设为1
......

注意:在DaemonSet的生产环境中,建议更新策略采用OnDelete,避免影响所有节点上的pod,可用几个不重要的pod做测试用

......
  updateStrategy:
    type: RollingUpdate	
......

四、Label与Selector

Label:对k8s中各种资源进行分类、分组,添加一个具有特别属性的一个标签。

Selector:通过一个过滤的语法进行查找到对应标签的资源

删除label

kubectl label node {node-name} app- -n

修改label

kubectl label pod {pod-name} app=xx(新名称) -n {namespace-name} --overwrite

查看所有ns下符合条件的标签

kubectl get svc -A --show-labels

kubectl get pod -A --show-labels

kubectl get node -A --show-labels

根据需求查看匹配条件的多种标签表达示例:

所有ns下,标签包含metrics-server和kubernetes-dashboad的pod

kubectl get po -A -l 'k8s-app in (metrics-server, kubernetes-dashboad)'

标签为nginx,但不包含v1版本的pod

kubectl get po -l version!=v1,app=nginx

所有ns下,标签为nginx,但不包含v1版本的pod

kubectl get po -A -l version!=v1,'app02 in (nginx,busybox)'

未完待续。。。。

posted @ 2021-11-20 21:42  校铖先森  阅读(182)  评论(0编辑  收藏  举报