Kubernetes 无状态应用扩缩容

347 阅读5分钟

本文来自于【阿里云官方镜像站:developer.aliyun.com/mirror/?utm…

原文链接:developer.aliyun.com/article/765…

Kubernetes 对象 是持久化的实体。Kubernetes 使用这些实体去表示整个集群的状态。
描述了如下信息:

  • 哪些容器化应用在运行(以及在哪个 Node 上)
  • 可以被应用使用的资源
  • 关于应用运行时表现的策略,比如重启策略、升级策略,以及容错策略

一但对象被创建,k8s集群就会开始持续工作以保证对象符合期望状态。

对象规约(Spec)与状态(Status)

每个 Kubernetes 对象包含两个嵌套的对象字段,它们负责管理对象的配置:对象 spec 和 对象 status 。 spec 是必需的,它描述了对象的 期望状态(Desired State) —— 希望对象所具有的特征。 status 描述了对象的 实际状态(Actual State) ,它是由 Kubernetes 系统提供和更新的。在任何时刻,Kubernetes 控制面一直努力地管理着对象的实际状态以与期望状态相匹配。

描述 Kubernetes 对象

一般使用yaml来描述一个k8s对象,yaml是专门用来写配置的语言。
基本语法规则如下:

  • 大小写敏感
  • 使用缩进表示层级关系
  • 缩进不允许使用tab,只允许空格
  • 缩进的空格数不重要,只要相同层级的元素左对齐即可
  • '#'表示注释

使用yaml描述k8s对象,需要以下必需字段:

  • apiVersion - 创建该对象所使用的 Kubernetes API 的版本
  • kind - 想要创建的对象的类型
  • metadata - 帮助识别对象唯一性的数据,包括一个 name 字符串、UID 和可选的 namespace
  • spec - 描述了对象的 期望状态(Desired State),k8s集群会持续保证对象符合描述的状态。

管理 Kubernetes 对象

管理k8s对象有三种方式
image.png

命令式命令(Imperative commands)

就是我们上文中使用的方式,在命令行直接操作。
如:

kubectl create deployment nginx --image nginx

与对象配置相比的优点:

  • 命令简单,易学且易于记忆。
  • 命令仅需一步即可对集群进行更改。

与对象配置相比的缺点:

  • 命令不与变更审查流程集成。
  • 命令不提供与更改关联的审核跟踪。
  • 除了实时内容外,命令不提供记录源。
  • 命令不提供用于创建新对象的模板。

命令式对象配置(Imperative object configuration)

需要操作指令和配置文件配合使用。
如:

kubectl create -f nginx.yaml

与命令式命令相比的优点:

  • 对象配置可以存储在源控制系统中,比如 Git。
  • 对象配置可以与流程集成,例如在推送和审计之前检查更新。
  • 对象配置提供了用于创建新对象的模板。

与命令式命令相比的缺点:

  • 对象配置需要对对象架构有基本的了解。
  • 对象配置需要额外的步骤来编写 YAML 文件。

与声明式对象配置相比的优点:

  • 命令式对象配置行为更加简单易懂。
  • 从 Kubernetes 1.5 版本开始,命令式对象配置更加成熟。

与声明式对象配置相比的缺点:

  • 命令式对象配置更适合文件,而非目录。
  • 对活动对象的更新必须反映在配置文件中,否则会在下一次替换时丢失。

声明式对象配置(Declarative object configuration)

使用声明式对象配置,不需要在命令中显示的指定操作,这样可以将配置文件放在目录中,对目录中的文件进行不同的操作。
比如:

kubectl apply -f configs/

与命令式对象配置相比的优点:

  • 对活动对象所做的更改即使未合并到配置文件中,也会被保留下来。
  • 声明性对象配置更好地支持对目录进行操作并自动检测每个文件的操作类型(创建,修补,删除)。

与命令式对象配置相比的缺点:

  • 声明式对象配置难于调试并且出现异常时结果难以理解。
  • 使用 diff 产生的部分更新会创建复杂的合并和补丁操作。

实践操作

创建Deployment

创建node-deployment.yaml文件

apiVersion: apps/v1
kind: Deployment
metadata:
  name: node-deployment
  labels:
    app: node
spec:
  replicas: 3
  selector:
    matchLabels:
      app: node
  template:
    metadata:
      labels:
        app: node
    spec:
      containers:
      - name: node
        image: registry.cn-hangzhou.aliyuncs.com/larswang/hello-node:1.0
        ports:
        - containerPort: 80

创建

kubectl apply -f node-deployment.yaml

查看deployments

kubectl get deployments

image.png
查看pods

kubectl get pods --show-labels

image.png

缩放Deployment

扩容到十个副本

kubectl scale deployment.v1.apps/node-deployment --replicas=10

扩展完成查看deployments和pods情况

kubectl get deployments
kubectl get pods --show-labels

image.png

缩容到三个副本

kubectl scale deployment.v1.apps/node-deployment --replicas=3

此时可以看到 其中7个pod处于Terminating状态。一段时间后,再次查看,只剩下了3个正在running的pod。
image.png

自动恢复

先查看pods列表

kubectl get pods --show-labels

选中其中一个pod并删除

kubectl delete pod node-deployment-57df45c5bf-d8xst

等删除成功后,再次查看pods列表

kubectl get pods --show-labels

image.png
会发现被删除的pod已经不存在了,但是Deployment又创建了一个新的pod。
这就是k8s会始终尽量保证集群的运行状态和配置描述的状态保持一致的特性。

获取Deployment描述信息

kubectl describe deployment node-deployment

image.png
可以看到Deployment的当前描述,及pod历史变化情况。
NewReplicaSet:

  • 当第一次创建 Deployment 时,它创建了一个 ReplicaSet (node-deployment-57df45c5bf) 并创建了3个副本。

Events:

  • 先扩容到了10个pods
  • 缩容到了3个pods
  • 缩容到了1个pods
  • 扩容到了3个pods

查看Deployment状态

kubectl get deployment node-deployment -o yaml

以yaml格式展示Deployment的配置情况及当前状态
image.png

总结

本文我们介绍了什么是k8s对象,以及使用yaml配置,创建了一个Deployment。
通过scale对Deployment进行缩放,并演示了手动删除一个pod后,k8s根据描述保持运行态与描述一致的特性。
在操作完一遍之后,回过头再看概念,会有种茅塞顿开的感觉。\