# Kubernetes生命周期管理

# 步骤

  • 制作镜像
  • 使用Deployment控制器部署镜像
kubectl create deployment my-blog --image=registry.cn-hangzhou.aliyuncs.com/liuxiaoluxx/blog:v1.0
kubectl get deploy,pods
  • 使用Service发布Pod
kubectl expose deployment my-blog --port=80 --type=NodePort --target-port=8080 --name=my-blog-service
kubectl get service

# Pod与Deployment的关系

Deployment是最为常用的controllers(也称为workload),其他控制器还有DaemonSet、StatefulSet等。

Controllers作用:

  • 管理Pod对象

  • 使用标签与Pod关联

  • 控制器了Pod的运维,例如滚动更新、伸缩、副本管理、维护Pod状态等。

pod-controller

Deployment的功能:

  • 管理Pod和ReplicaSet

  • 具有上线部署、副本设定、滚动升级、回滚等功能

  • 提供声明式更新,例如只更新一个新的Image

应用场景:

  • 网站
  • API
  • 微服务

示例:

使用yaml文件的方式创建deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

在该例中:

  • 创建名为 nginx-deployment(由 .metadata.name 字段标明)的 Deployment。

    • 该 Deployment 创建三个(由 replicas 字段标明)Pod 副本。

    • selector 字段定义 Deployment 如何查找要管理的 Pods。 在这里,你只需选择在 Pod 模板中定义的标签(app: nginx)。 不过,更复杂的选择规则是也可能的,只要 Pod 模板本身满足所给规则即可。

      说明: matchLabels 字段是 {key,value} 偶对的映射。在 matchLabels 映射中的单个 {key,value} 映射等效于 matchExpressions 中的一个元素,即其 key 字段是 “key”,operator 为 “In”,value 数组仅包含 “value”。在 matchLabelsmatchExpressions 中给出的所有条件都必须满足才能匹配。

    • template字段包含以下子字段:

      • Pod 被使用 labels 字段打上 app: nginx 标签。
      • Pod 模板规约(即 .template.spec 字段)指示 Pods 运行一个 nginx 容器, 该容器运行版本为 1.14.2 的 nginx Docker Hub (opens new window)镜像。
      • 创建一个容器并使用 name 字段将其命名为 nginx

使用service发布deploy

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: NodePort

在该例中

  • 创建名为my-service(由 .metadata.name 字段标明)的Service。
  • spec.selector将绑定标签为app=nginx的所有pod
  • spec.ports[0].targetPort表示代理容器内部的80端口

# 服务编排

# YAML文件创建资源对象

pod-controller

# YAML文件格式说明

YAML 是一种简洁的非标记语言。

语法格式:

  • 缩进表示层级关系
  • 不支持制表符“tab”缩进,使用空格缩进
  • 通常开头缩进 2 个空格
  • 字符后缩进 1 个空格,如冒号、逗号等
  • “---”表示YAML格式,一个文件的开始
  • “#”注释

示例

在刚才的例子中,我们创建了两个yaml文件,分别创建了pod,和service,我们也可以将两个文件合并,用---隔开即可。这样就实现了在创建deploy的同时,创建service,对外发布服务

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: NodePort

# 资源字段太多,记不住怎么办

  • 用create命令生成 我们无需强行记住一个yaml文件应该有哪些属性,只需命令生成可生成基本的yaml结构,如果有附加属性,只需根据模板调整即可。

    kubectl create deployment nginx --image=nginx:1.16 -o yaml --dry-run=client > nginx-deploy.yaml

    示例

    执行命令如下:

    kubectl create deploy nginx-deploy --image=nginx -o yaml --dry-run=client > nginx-deploy.yaml
    

    查看生成的yaml文件

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: nginx-deploy
  name: nginx-deploy
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-deploy
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx-deploy
    spec:
      containers:
      - image: nginx
        name: nginx
        resources: {}
status: {}

可以看到,基本的yaml结构已有,这里还需要注意一点,我们需要将creationTimestamp的部分删除。

修改后,内容如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx-deploy
  name: nginx-deploy
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-deploy
  strategy: {}
  template:
    metadata:
      labels:
        app: nginx-deploy
    spec:
      containers:
      - image: nginx
        name: nginx
        resources: {}
status: {}
  • 用get命令导出

    我们也可以使用直接将现有的deployment的yaml配置文件导出

    kubectl get deployment nginx -o yaml > my-deploy.yaml

    示例

    执行命令如下:

    kubectl get deploy nginx-deployment -o yaml > nginx-deployment2.yaml
    

    查看生成的nginx-deplotment2.yaml文件

apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "1"
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"labels":{"app":"nginx"},"name":"nginx-deployment","namespace":"default"},"spec":{"replicas":3,"selector":{"matchLabels":{"app":"nginx"}},"template":{"metadata":{"labels":{"app":"nginx"}},"spec":{"containers":[{"image":"nginx:1.14.2","name":"nginx","ports":[{"containerPort":80}]}]}}}}
  creationTimestamp: "2021-01-25T13:51:37Z"
  generation: 1
  labels:
    app: nginx
  managedFields:
  - apiVersion: apps/v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          .: {}
          f:kubectl.kubernetes.io/last-applied-configuration: {}
        f:labels:
          .: {}
          f:app: {}
      f:spec:
        f:progressDeadlineSeconds: {}
        f:replicas: {}
        f:revisionHistoryLimit: {}
        f:selector:
          f:matchLabels:
            .: {}
            f:app: {}
        f:strategy:
          f:rollingUpdate:
            .: {}
            f:maxSurge: {}
            f:maxUnavailable: {}
          f:type: {}
        f:template:
          f:metadata:
            f:labels:
              .: {}
              f:app: {}
          f:spec:
            f:containers:
              k:{"name":"nginx"}:
                .: {}
                f:image: {}
                f:imagePullPolicy: {}
                f:name: {}
                f:ports:
                  .: {}
                  k:{"containerPort":80,"protocol":"TCP"}:
                    .: {}
                    f:containerPort: {}
                    f:protocol: {}
                f:resources: {}
                f:terminationMessagePath: {}
                f:terminationMessagePolicy: {}
            f:dnsPolicy: {}
            f:restartPolicy: {}
            f:schedulerName: {}
            f:securityContext: {}
            f:terminationGracePeriodSeconds: {}
    manager: kubectl-client-side-apply
    operation: Update
    time: "2021-01-25T13:51:37Z"
  - apiVersion: apps/v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          f:deployment.kubernetes.io/revision: {}
      f:status:
        f:availableReplicas: {}
        f:conditions:
          .: {}
          k:{"type":"Available"}:
            .: {}
            f:lastTransitionTime: {}
            f:lastUpdateTime: {}
            f:message: {}
            f:reason: {}
            f:status: {}
            f:type: {}
          k:{"type":"Progressing"}:
            .: {}
            f:lastTransitionTime: {}
            f:lastUpdateTime: {}
            f:message: {}
            f:reason: {}
            f:status: {}
            f:type: {}
        f:observedGeneration: {}
        f:readyReplicas: {}
        f:replicas: {}
        f:updatedReplicas: {}
    manager: kube-controller-manager
    operation: Update
    time: "2021-01-25T13:52:01Z"
  name: nginx-deployment
  namespace: default
  resourceVersion: "3800213"
  selfLink: /apis/apps/v1/namespaces/default/deployments/nginx-deployment
  uid: e68c77ca-d9da-4ef5-a446-d46baea9de89
spec:
  progressDeadlineSeconds: 600
  replicas: 3
  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.14.2
        imagePullPolicy: IfNotPresent
        name: nginx
        ports:
        - containerPort: 80
          protocol: TCP
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
status:
  availableReplicas: 3
  conditions:
  - lastTransitionTime: "2021-01-25T13:52:01Z"
    lastUpdateTime: "2021-01-25T13:52:01Z"
    message: Deployment has minimum availability.
    reason: MinimumReplicasAvailable
    status: "True"
    type: Available
  - lastTransitionTime: "2021-01-25T13:51:37Z"
    lastUpdateTime: "2021-01-25T13:52:01Z"
    message: ReplicaSet "nginx-deployment-66b6c48dd5" has successfully progressed.
    reason: NewReplicaSetAvailable
    status: "True"
    type: Progressing
  observedGeneration: 1
  readyReplicas: 3
  replicas: 3
  updatedReplicas: 3

可以看到,这个文件内容非常多,我们需要将不需要的信息剔除

删减后内容如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx-deployment
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:1.14.2
        imagePullPolicy: IfNotPresent
        name: nginx
        ports:
        - containerPort: 80
          protocol: TCP
        resources: {}
      dnsPolicy: ClusterFirst
      restartPolicy: Always
  • Pod容器的指定字段下,不清楚支持哪些子字段怎么查询?

    • kubectl explain pods.spec.containers
    • kubectl explain deployment

# 应用升级,弹性伸缩,回滚,删除

# 应用升级

  • kubectl set image deployment web nginx=nginx:1.16

    将名为web的deployment中,name为nginx的pod的镜像更新到1.16版本

    这里需要提到一点,这是一个滚动更新的过程,先创建新的容器,然后将旧的容器删掉,对用户来说是无感的

# 弹性伸缩

# 手动扩容

  • kubectl scale deployment web --replicas=3

    将名为web的deployment的副本设置为3个

# 自动水平扩容(注意Pod必须配置resource.request)

HPA机制:pod水平扩容,根据设置的阈值,自动触发扩容

  • kubectl autoscale deployment web --min=3 --max=10 --cpu-percent=80

    设定名为web的deployment,最小的pod数为3,最大的pod数为10,在cpu到达80%的时候触发扩容,注意需要与metric-server配合使用

    在这里,我们可以调整一下之前的yaml,增加pod的资源使用限制,这里限制cpu为0.5核

    新增内容如下:

resources:
  requests:
    cpu: 0.5

以下为修改后的完整版本:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: 0.5
---
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: NodePort
  • kubectl get hpa

  • 压测

    • 这里可使用httpd-tools进行一个简单的压力测试
    [root@liuxiaolu-master ~]# yum install httpd-tools
    
    • 使用ab命令,主要使用两个参数,其他参数可使用ab --help查看
     -n requests     Number of requests to perform                  # 请求数
     -c concurrency  Number of multiple requests to make at a time  # 并发数
    
    • 执行命令,只需用k8s内部的service地址即可
    • 查看k8s内部的service地址
    [root@liuxiaolu-master ~]# kubectl get svc
    NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
    kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP        21d
    my-service   NodePort    10.105.226.230   <none>        80:30331/TCP   2d1h
    
    • 可以看到,我们之前创建的my-service的地址是10.105.226.230,接下来执行压测命令(100000个请求,每次同时有1000请求执行)
    [root@liuxiaolu-master ~]# ab -n 100000000 -c 10000 http://10.105.226.230/html
    
    • 稍等一两分钟之后查看hpa,可以看到,机器的负载已经上来了,超过5%了,这时候应该是会执行自动拉起pod的
    [root@liuxiaolu-master ~]# kubectl get hpa
    NAME               REFERENCE                     TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
    nginx-deployment   Deployment/nginx-deployment   22%/5%    3         10        10         22m
    
    • 查看pod, 可以看到,有三个pending状态的pod,已经被自动拉起。这里提到一点,在我们没有进行压测后,负载下去之后,大概5分钟,将会进行自动缩容
    [root@liuxiaolu-master ~]# kubectl get pod
    NAME                                READY   STATUS    RESTARTS   AGE
    nginx-deployment-7c5784685b-5w56n   1/1     Running   0          5m
    nginx-deployment-7c5784685b-64znz   1/1     Running   0          5m
    nginx-deployment-7c5784685b-6scjx   0/1     Pending   0          4m45s
    nginx-deployment-7c5784685b-6v5rw   0/1     Pending   0          4m45s
    nginx-deployment-7c5784685b-bml66   1/1     Running   0          5m
    nginx-deployment-7c5784685b-bv5wk   1/1     Running   0          27m
    nginx-deployment-7c5784685b-bx6q6   1/1     Running   0          27m
    nginx-deployment-7c5784685b-t4t9g   1/1     Running   0          4m45s
    nginx-deployment-7c5784685b-t4wjp   1/1     Running   0          27m
    nginx-deployment-7c5784685b-xpgkp   0/1     Pending   0          4m45s
    

# 回滚

  • kubectl rollout history deployment web # 查看历史版本
  • kubectl rollout undo deployment web # 回滚上一个版本
  • kubectl rollout undo deployment web --to-revision=2 # 回滚指定版本

# 删除

  • kubectl delete deploy web # 删除名为web的deploy(deploy是deployment的缩写词)
  • kubectl delete svc web # 删除名为web的svc(svc是service的缩写词)
Last Updated: 6/26/2022, 4:44:06 PM