K8s动态实现服务数量的扩缩容(HPA)、升级回滚

Pod

  • 每个Pod中都包含一个或者多个容器,这些容器可以分为两类:① 用户程序所在的容器,数量可多可少。② Pause容器,这是每个Pod都会有的一个根容器,它的作用有两个:

  • 可以以它为依据,评估整个Pod的健康状况。
  • 可以在根容器上设置IP地址,其它容器都共享此IP(Pod的IP),以实现Pod内部的网络通信

ReplicaSet

ReplicaSet的主要作用是保证一定数量的Pod能够正常运行,它会持续监听这些Pod的运行状态,一旦Pod发生故障,就会重启或重建。同时它还支持对Pod数量的扩缩容

ReplicaSet的资源清单文件:

apiVersion: apps/v1 # 版本号
kind: ReplicaSet # 类型
metadata: # 元数据
  name: pc-replicaset # rs名称
  namespace: dev # 命名类型
spec: # 详细描述
  replicas: 3 # 副本数量
  selector: # 选择器,通过它指定该控制器可以管理哪些Pod
    matchLabels: # Labels匹配规则
      app: nginx-pod
  template: # 模块 当副本数据不足的时候,会根据下面的模板创建Pod副本
    metadata:
      labels:
        app: nginx-pod
    spec:
      containers:
        - name: nginx # 容器名称
          image: nginx:1.17.1 # 容器需要的镜像地址
          ports:
            - containerPort: 80 # 容器所监听的端口

replicas:指定副本数量,其实就是当然rs创建出来的Pod的数量,默认为1

selector:选择器,它的作用是建立Pod控制器和Pod之间的关联关系,采用了Label Selector机制(在Pod模块上定义Label,在控制器上定义选择器,就可以表明当前控制器能管理哪些Pod了)。

template:模板,就是当前控制器创建Pod所使用的模板,里面其实就是前面学过的Pod的定义

创建rs

kubectl create -f pc-replicaset.yaml
查看
kubectl get rs pc-replicaset -n dev -o wide

扩缩容 编辑rs的副本数量,修改spec:replicas:6即可

kubectl edit rs pc-replicaset -n dev

删除

# 在kubernetes删除ReplicaSet前,会将ReplicaSet的replicas调整为0,等到所有的Pod被删除后,再执行ReplicaSet对象的删除
kubectl delete rs pc-replicaset -n dev
使用yaml直接删除
kubectl delete -f pc-replicaset.yaml

Deployment

Deployment控制器并不直接管理Pod,而是通过管理ReplicaSet来间接管理Pod,即:Deployment管理ReplicaSet,ReplicaSet管理Pod。所以Deployment的功能比ReplicaSet强大

主要功能:

 ○ 支持ReplicaSet的所有功能。
  ○ 支持发布的停止、继续。
  ○ 支持版本滚动更新和版本回退

创建pc-deployment.yaml文件

apiVersion: apps/v1 # 版本号 
kind: Deployment # 类型 
metadata: # 元数据 
  name: # rs名称 
  namespace: # 所属命名空间 
  labels: #标签 
    controller: deploy 
spec: # 详情描述 
  replicas: 3 # 副本数量 
  revisionHistoryLimit: 3 # 保留历史版本,默认为10 
  paused: false # 暂停部署,默认是false 
  progressDeadlineSeconds: 600 # 部署超时时间(s),默认是600 
  strategy: # 策略 
    type: RollingUpdate # 滚动更新策略 
    rollingUpdate: # 滚动更新 
      maxSurge: 30% # 最大额外可以存在的副本数,可以为百分比,也可以为整数 maxUnavailable: 30% # 最大不可用状态的    Pod 的最大值,可以为百分比,也可以为整数 
  selector: # 选择器,通过它指定该控制器管理哪些pod 
    matchLabels: # Labels匹配规则 
      app: nginx-pod 
    matchExpressions: # Expressions匹配规则 
      - {key: app, operator: In, values: [nginx-pod]} 
  template: # 模板,当副本数量不足时,会根据下面的模板创建pod副本 
    metadata: 
      labels: 
        app: nginx-pod 
    spec: 
      containers: 
      - name: nginx 
        image: nginx:1.17.1 
        ports: 
        - containerPort: 80

创建Deployment

kubectl create -f pc-deployment.yaml
查看
kubectl get deploy pc-deployment -n dev
查看ReplicaSet
kubectl get rs -n dev
使用scale命令实现扩缩容
kubectl scale deploy pc-deployment --replicas=5 -n dev
编辑Deployment的副本数量,修改spec:replicas:4即可
kubectl edit deployment pc-deployment -n dev

Deployment支持两种镜像更新的策略:重建更新滚动更新(默认),可以通过strategy选项进行配置

strategy: 指定新的Pod替代旧的Pod的策略,支持两个属性
  type: 指定策略类型,支持两种策略
    Recreate:在创建出新的Pod之前会先杀掉所有已经存在的Pod
    RollingUpdate:滚动更新,就是杀死一部分,就启动一部分,在更新过程中,存在两个版本的Pod
  rollingUpdate:当type为RollingUpdate的时候生效,用于为rollingUpdate设置参数,支持两个属性:
    maxUnavailable:用来指定在升级过程中不可用的Pod的最大数量,默认为25%。
    maxSurge: 用来指定在升级过程中可以超过期望的Pod的最大数量,默认为25%。

编辑pc-deployment.yaml文件,在spec节点下添加更新策略

更新Deployment
kubectl apply -f pc-deployment.yaml

镜像升级

kubectl set image deployment pc-deployment nginx=nginx:1.17.2 -n dev

版本回退

# 版本升级相关功能
kubetl rollout 参数 deploy xx  # 支持下面的选择
# status 显示当前升级的状态
# history 显示升级历史记录
# pause 暂停版本升级过程
# resume 继续已经暂停的版本升级过程
# restart 重启版本升级过程
# undo 回滚到上一级版本 (可以使用--to-revision回滚到指定的版本)

查看当前升级版本的状态

kubectl rollout status deployment pc-deployment -n dev
历史记录
kubectl rollout history deployment pc-deployment -n dev
版本回退
# 可以使用-to-revision=1回退到1版本,如果省略这个选项,就是回退到上个版本,即2版本
kubectl rollout undo deployment pc-deployment --to-revision=1 -n dev

删除Deployment,其下的ReplicaSet和Pod也会一起被删除:

kubectl delete -f pc-deployment.yaml

Horizontal Pod Autoscaler(HPA)

  • 动执行kubectl scale命令实现Pod的扩缩容,但是这显然不符合kubernetes的定位目标–自动化和智能化。kubernetes期望可以通过监测Pod的使用情况,实现Pod数量的自动调整,于是就产生了HPA这种控制器。

  • HPA可以获取每个Pod的利用率,然后和HPA中定义的指标进行对比,同时计算出需要伸缩的具体值,最后实现Pod的数量的调整。其实HPA和之前的Deployment一样,也属于一种kubernetes资源对象,它通过追踪分析目标Pod的负载变化情况,来确定是否需要针对性的调整目标Pod的副本数。

安装metrics-server

wget https://github.com/kubernetes-sigs/metrics-server/archive/v0.3.6.tar.gz
解压
tar -zxvf v0.3.6.tar.gz
进入metrics-server-0.3.6/deploy/1.8+/目录
cd metrics-server-0.3.6/deploy/1.8+/
修改metrics-server-deployment.yaml文件
vim metrics-server-deployment.yaml
添加
hostNetwork: true
image: registry.cn-hangzhou.aliyuncs.com/google_containers/metrics-server-amd64:v0.3.6 
args:
  - --kubelet-insecure-tls 
  - --kubelet-preferred-address-types=InternalIP,Hostname,InternalDNS,ExternalDNS,ExternalIP

 安装metrics-server(v0.3.6)

kubectl apply -f ./
查看metrics-server生成的Pod
kubectl get pod -n kube-system
查看资源使用情况
kubectl top node
kubectl top pod -n kube-system

安装metrics-server(v0.4.1)

wget https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.4.1/components.yaml

修改components.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    k8s-app: metrics-server
  name: metrics-server
  namespace: kube-system
spec:
  selector:
    matchLabels:
      k8s-app: metrics-server
  strategy:
    rollingUpdate:
      maxUnavailable: 0
  template:
    metadata:
      labels:
        k8s-app: metrics-server
    spec:
      containers:
      - args:
        - --cert-dir=/tmp
        - --secure-port=4443
        - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
        - --kubelet-use-node-status-port
        # 修改部分
        - --kubelet-insecure-tls
        # 修改部分
        image: registry.cn-shanghai.aliyuncs.com/xuweiwei-kubernetes/metrics-server:v0.4.1

安装metrics-server

kubectl apply -f components.yaml

准备Deployment和Service

  • 创建Deployment:创建nginx.yaml文件,内容如下

apiVersion: apps/v1 # 版本号
kind: Deployment # 类型
metadata: # 元数据
  name: nginx # deployment的名称
  namespace: dev # 命名类型
spec: # 详细描述
  selector: # 选择器,通过它指定该控制器可以管理哪些Pod
    matchLabels: # Labels匹配规则
      app: nginx-pod
  template: # 模块 当副本数据不足的时候,会根据下面的模板创建Pod副本
    metadata:
      labels:
        app: nginx-pod
    spec:
      containers:
        - name: nginx # 容器名称
          image: nginx:1.17.1 # 容器需要的镜像地址
          ports:
            - containerPort: 80 # 容器所监听的端口
          resources: # 资源限制
            requests:
              cpu: "100m" # 100m表示100millicpu,即0.1个CPU

创建Deployment

kubectl create -f nginx.yaml

查看Deployment和Pod

kubectl get pod,deploy -n dev

创建Service

kubectl expose deployment nginx --name=nginx --type=NodePort --port=80 --target-port=80 -n dev
查看
kubectl get svc -n dev

部署HPA

创建pc-hpa.yaml文件,内容如下

apiVersion: autoscaling/v1 # 版本号
kind: HorizontalPodAutoscaler # 类型
metadata: # 元数据
  name: pc-hpa # deployment的名称
  namespace: dev # 命名类型
spec:
  minReplicas: 1 # 最小Pod数量
  maxReplicas: 10 # 最大Pod数量
  targetCPUUtilizationPercentage: 3 # CPU使用率指标
  scaleTargetRef:  # 指定要控制的Nginx的信息
    apiVersion: apps/v1
    kind: Deployment
    name: nginx

创建hpa

kubectl create -f pc-hpa.yaml
查看
kubectl get hpa -n dev

StatefulSet(有状态)

无状态应用:

认为Pod都是一样的,没有顺序要求,不用考虑在哪个Node节点上运行,随意进行伸缩和扩展

有状态应用:

有顺序的要求,认为每个Pod都是不一样的,需要考虑在哪个Node节点上运行,需要按照顺序进行伸缩和扩展,让每个Pod都是独立的,保持Pod启动顺序和唯一性。

StatefulSet是Kubernetes提供的管理有状态应用的负载管理控制器,部署需要HeadLinessService(无头服务)

  • 在用Deployment时,每一个Pod名称是没有顺序的,是随机字符串,因此是Pod名称是无序的,但是在StatefulSet中要求必须是有序 ,每一个Pod不能被随意取代,Pod重建后pod名称还是一样的。

  • 而Pod IP是变化的,所以是以Pod名称来识别。Pod名称是Pod唯一性的标识符,必须持久稳定有效。这时候要用到无头服务,它可以给每个Pod一个唯一的名称 。

创建pc-stateful.yaml文件

apiVersion: v1
kind: Service
metadata:
  name: service-headliness
  namespace: dev
spec:
  selector:
    app: nginx-pod
  clusterIP: None # 将clusterIP设置为None,即可创建headliness Service
  type: ClusterIP
  ports:
    - port: 80 # Service的端口
      targetPort: 80 # Pod的端口
---

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: pc-statefulset
  namespace: dev
spec:
  replicas: 3
  serviceName: service-headliness
  selector:
    matchLabels:
      app: nginx-pod
  template:
    metadata:
      labels:
        app: nginx-pod
    spec:
      containers:
        - name: nginx
          image: nginx:1.17.1
          ports:
            - containerPort: 80

创建StatefulSet

kubectl create -f pc-stateful.yaml
查看StatefulSet
kubectl get statefulset pc-statefulset -n dev -o wide
查看Pod
kubectl get pod -n dev -o wide
删除StatefulSet
kubectl delete -f pc-stateful.yaml

Deployment和StatefulSet的区别

  • Deployment和StatefulSet的区别:Deployment没有唯一标识而StatefulSet有唯一标识。

  • StatefulSet的唯一标识是根据主机名+一定规则生成的。

  • StatefulSet的唯一标识是主机名.无头Service名称.命名空间.svc.cluster.local

StatefulSet支持两种更新策略:OnDelete和RollingUpdate(默认),其中OnDelete表示删除之后才更新,RollingUpdate表示滚动更新

updateStrategy:
  rollingUpdate: # 如果更新的策略是OnDelete,那么rollingUpdate就失效
    partition: 2 # 表示从第2个分区开始更新,默认是0
  type: RollingUpdate /OnDelete # 滚动更新

Pod的资源清单

apiVersion: v1     #必选,版本号,例如v1
kind: Pod         #必选,资源类型,例如 Pod
metadata:         #必选,元数据
  name: string     #必选,Pod名称
  namespace: string  #Pod所属的命名空间,默认为"default"
  labels:           #自定义标签列表
    - name: string                 
spec:  #必选,Pod中容器的详细定义
  containers:  #必选,Pod中容器列表
  - name: string   #必选,容器名称
    image: string  #必选,容器的镜像名称
    imagePullPolicy: [ Always|Never|IfNotPresent ]  #获取镜像的策略 
    command: [string]   #容器的启动命令列表,如不指定,使用打包时使用的启动命令
    args: [string]      #容器的启动命令参数列表
    workingDir: string  #容器的工作目录
    volumeMounts:       #挂载到容器内部的存储卷配置
    - name: string      #引用pod定义的共享存储卷的名称,需用volumes[]部分定义的的卷名
      mountPath: string #存储卷在容器内mount的绝对路径,应少于512字符
      readOnly: boolean #是否为只读模式
    ports: #需要暴露的端口库号列表
    - name: string        #端口的名称
      containerPort: int  #容器需要监听的端口号
      hostPort: int       #容器所在主机需要监听的端口号,默认与Container相同
      protocol: string    #端口协议,支持TCP和UDP,默认TCP
    env:   #容器运行前需设置的环境变量列表
    - name: string  #环境变量名称
      value: string #环境变量的值
    resources: #资源限制和请求的设置
      limits:  #资源限制的设置
        cpu: string     #Cpu的限制,单位为core数,将用于docker run --cpu-shares参数
        memory: string  #内存限制,单位可以为Mib/Gib,将用于docker run --memory参数
      requests: #资源请求的设置
        cpu: string    #Cpu请求,容器启动的初始可用数量
        memory: string #内存请求,容器启动的初始可用数量
    lifecycle: #生命周期钩子
		postStart: #容器启动后立即执行此钩子,如果执行失败,会根据重启策略进行重启
		preStop: #容器终止前执行此钩子,无论结果如何,容器都会终止
    livenessProbe:  #对Pod内各容器健康检查的设置,当探测无响应几次后将自动重启该容器
      exec:         #对Pod容器内检查方式设置为exec方式
        command: [string]  #exec方式需要制定的命令或脚本
      httpGet:       #对Pod内个容器健康检查方法设置为HttpGet,需要制定Path、port
        path: string
        port: number
        host: string
        scheme: string
        HttpHeaders:
        - name: string
          value: string
      tcpSocket:     #对Pod内个容器健康检查方式设置为tcpSocket方式
         port: number
       initialDelaySeconds: 0       #容器启动完成后首次探测的时间,单位为秒
       timeoutSeconds: 0          #对容器健康检查探测等待响应的超时时间,单位秒,默认1秒
       periodSeconds: 0           #对容器监控检查的定期探测时间设置,单位秒,默认10秒一次
       successThreshold: 0
       failureThreshold: 0
       securityContext:
         privileged: false
  restartPolicy: [Always | Never | OnFailure]  #Pod的重启策略
  nodeName: <string> #设置NodeName表示将该Pod调度到指定到名称的node节点上
  nodeSelector: obeject #设置NodeSelector表示将该Pod调度到包含这个label的node上
  imagePullSecrets: #Pull镜像时使用的secret名称,以key:secretkey格式指定
  - name: string
  hostNetwork: false   #是否使用主机网络模式,默认为false,如果设置为true,表示使用宿主机网络
  volumes:   #在该pod上定义共享存储卷列表
  - name: string    #共享存储卷名称 (volumes类型有很多种)
    emptyDir: {}       #类型为emtyDir的存储卷,与Pod同生命周期的一个临时目录。为空值
    hostPath: string   #类型为hostPath的存储卷,表示挂载Pod所在宿主机的目录
      path: string                #Pod所在宿主机的目录,将被用于同期中mount的目录
    secret:          #类型为secret的存储卷,挂载集群与定义的secret对象到容器内部
      scretname: string  
      items:     
      - key: string
        path: string
    configMap:         #类型为configMap的存储卷,挂载预定义的configMap对象到容器内部
      name: string
      items:
      - key: string
        path: string

猜你喜欢

转载自blog.csdn.net/weixin_52210557/article/details/123836377