kubenetes的抽象概念,如Pod、Service、Volume、Namespace、ReplicaSet、Deployment、StatefulSet、DaemonSet、Job等统称对象,kubectl命令提供三种方式对这些对象进行操作、管理,三种方式分别为:Imperative commands(祈使命令)、Imperative object configuration(祈使对象配置)、Declarative object configuration(声明对象配置),后两种方式统称对象配置方式。本文分别介绍三种管理对象方式,并比较优缺点。在正式介绍之前,先说明一个重要的概念:live objects(实时对象)。实时对象的表现形式由两个部分组成,一部分由初始配置信息决定,称为规格,表示用户的期望值,例如用户定义了一个Deployment,并且将副本的个数设置成3,注意3是一个期望值。非常重要的一点是某些类型的对象,其规格并非完全由配置决定,比如负载均衡类型的服务。另一部分称之为状态,表示当前的实时状态,是动态变化的,比如当前系统中副本的数量是2。而kubenetes的工作就是调整系统当前的状态,以使状态与规格相符。所以live objects(实时对象)由两部分组成,静态的规格及动态的状态。
警告:应该只使用其中的一种方式管理相同的对象,如果混合使用后果不可预知。
1.Imperative commands(祈使命令)
用户直接通过设置命令行中的参数、标志,指示操作的具体对象以及操作,操作本身直接作用于集群中的实时对象(live objects)。这是最简单的在集群中启动、运行一次性任务的方法,原因是它直接作用于实时对象本身,不涉及对象的历史配置。
与对象配置比较的优点:
- 命令本身简单直观、易学、易记、易用
- 整个操作只需要一步就可以完成
与对象配置比较的缺点:
- 没有与变更审核流程集成
- 没有将变更与审计追踪关联
- 只针对实时对象而没有提供原始配置
- 不能为新创建对象提供模板
总体上看,这种方式简单但是功能不强,适合于开发测试场景而非生产环境。缺点产生的根本原因是在更新的时候没有涉及历史配置,没有将整个变更过程记录下来,而是直接作用于实时对象,不与历史配置对比就无法计算出“变更”,自然也就不能审核、审记、追踪“变更”,这种方式的优点也是因为这一原因而产生。
通过祈使命令管理对象的方法
如何创建对象?
kubenctl祈使命令管理对象的方式,又细分成两种,一种称之为“动词驱动”,可以用来创建大多数基础的对象类型,特点是简单直观,主要针对的是对kubenetes对象类型不熟悉的用户。
- run:创建Deployment类型对象,实现在一个或者多个Pod中运行容器。
- expose:创建Service对象,实现Pod之间流量的负载均衡。
- autoscale:创建弹性伸缩对象。
另一种称之为“对象类型驱动”,能够创建的对象类型更多,需要用户对kubenetes中的对象类型比较熟悉。
基本语法:create <objecttype> [<subtype>] <instancename>
在创建某些类型的对象时,可以在命令中指定其支持的子类型。如Service对象,包含ClusterIP、LoadBalancer、NodePort等数个子类型,以下是创建子类型为NodePort的Service的示例:
kubectl create service nodeport <myservicename>
在上例中,create service nodeport命令被称为create service的子命令。可以通过-h选项获得子命令支持的参数及标志的帮忙信息,如:
kubectl create service nodeport -h
如何更新对象?
以下是由易到难更新对象的方法
- scale:创建水平扩展控制器,通过更新对象控制器中副本的数据来增加或者减少Pod的数量。
- annotate:修改对象注解。
- label:修改对象标签,以上三种方法适用于对kubenetes对象不熟悉的用法。
- set:修改任意类型对象的任意属性,需要对对象的构成比较熟悉。
- edit:在直接在编辑器中打开实时对象的原始配置并编辑。
- patch:通过patch string修改实时对象的某个字段,详细参考https://git.k8s.io/community/contributors/devel/api-conventions.md#patch-operations。
如何删除对象?
基本语法:delete <type>/<name>
示例:
kubectl delete deployment/nginx
以上命令,删除类型为Deployment名为nginx的对象。
如何浏览对象?
以下命令打印对象信息。
- get:打印对象的基本信息,可以通过-h选项获取帮助。
- describe:打印对象详细信息。
- log:打印Pod中容器的标准与错误输出。
通过set命令在创建之前修改对象
这是一种高级用法。有些类型的对象比较复杂,对象的某些字段在执行create命令时无法直接指定。可以通过管道将create命令与set命令连接起来,实现对这种类型的对象字段的修改,示例如下:
kubectl create service clusterip my-svc --clusterip="None" -o yaml --dry-run | kubectl set selector --local -f - 'environment=qa' -o yaml | kubectl create -f -
上述命令用两个管道将三个命令连接起来,具体执行过程如下:
- kubectl create service clusterip my-svc --clusterip="None" -o yaml --dry-run,这个命令先创建对象的配置,但是并没有将配置传递给Kubernetes API server,而是以YAML格式输出到标准输出。
- kubectl set selector --local -f - 'environment=qa' -o yaml,这个命令通过管道接收步骤1的输出,并对内容进行修改,同样没有将配置传递给Kubernetes API server,而是以YAML格式输出到标准输出。
- kubectl create -f -,接收第2步的输出传递给Kubernetes API server,启动真正的创建工作。
通过--edit选项在创建之前修改对象
使用kubectl create --edit命令在对象创建之前进行任意修改,以下是例子:
ubectl create service clusterip my-svc --clusterip="None" -o yaml --dry-run > /tmp/srv.yaml
kubectl create --edit -f /tmp/srv.yaml
在以上命令中,kubectl create service命令创建service的配置文件并保存在/tmp/srv.yaml文件中。kubectl create --edit命令先编辑创建好的配置文件,再启动创建流程。
2.Imperative object configuration(祈使对象配置)
与祈使命令比较的优点:
- 对象的完整配置能以文件的形式存储在版本控制系统中如Git。
- 对象配置能够与其它的处理过程如变量审核、审讯追踪集成。
- 配置文件能提供创建对象的模板。
与祈使命令比较的缺点:
- 复杂
- 多了一个步骤,管理配置文件。
与声明对象配置比较的优点:
- 祈使对象配置的行为更简单且易于理解。
- 从版本1.5开始,祈使对象配置更加成熟。
与声明对象配置比较的缺点:
- 祈使对象配置善于处理配置文件,不能处理目录。
- 实时对象中独立于配置文件变化的规格必需手动反映在新的配置文件里,否则在更新的过程中这部分规格会丢失。
总体而言,祈使对象配置方法将对象的配置信息转移到配置文件中,通过与版本控制器的集成从而支持变更审核、审计等,最大的问题是在变更的过程中,丢失独立与配置文件的规格,对于某些特定类型的对象不适用。
通过祈使对象配置管理对象的方法
如何创建对象?
基本语法:kubectl create -f <filename|url>
如何更新对象?
基本语法:kubectl replace -f <filename|url>
警告:这种方法对于某些规格独立于配置文件类型的对象不适用。
如何删除对象?
基本语法:kubectl delete -f <filename|url>
如何浏览对象?
基本语法:kubectl get -f <filename|url> -o yaml
限制
这种方式的不足,在前文中的警告中已经提及,现集中说明。
当配置文件中包含对象的完整定义时(注意完整一词),create、replace、delete命令能够很好的工作。但是,当实时对象中独立于配置的规格没有被合并到配置文件中,也就是说配置文件中的定义是不“完整”的,那么在更新被执行时就会丢失掉这部分信息。例如:
- 从配置创建对象。
- 其它的源更新了对象的某个字段。
- 利用配置文件再次更新对象,如果部步骤2中的变更没有被手动反映在配置文件中,则信息丢失。
从URL创建、编辑对象,但是不保存修改
假如可以通过URL读取配置文件。可以通过create --edit命令先获取配置文件,在对象创建之前进行修改,然后再创建对象。此时的修改是临时的。