带你读《Kubernetes进阶实战》之二:Kubernetes快速入门

点击这里查看第一章:Kubernetes系统基础
点击这里查看第三章:资源管理基础

第2章:Kubernetes快速入门

Kubernetes集群将所有节点上的资源都整合到一个大的虚拟资源池里,以代替一个个单独的服务器,而后开放诸如CPU、内存和I/O这些基本资源用于运行其基本单元—Pod资源对象。Pod的容器中运行着隔离的任务单元,它们以Pod为原子单位,并根据其资源需求从虚拟资源池中为其动态分配资源。若可以将整个集群类比为一台传统的服务器,那么Kubernetes(Master)就好比是操作系统内核,其主要职责在于抽象资源并调度任务,而Pod资源对象就是那些运行于用户空间中的进程。于是,传统意义上的向单节点或集群直接部署、配置应用的模型日渐式微,取而代之的是向Kubernetes的API Server提交运行Pod对象。
API Server是负责接收并响应客户端提交任务的接口,用户可使用诸如CLI工具(如kubectl)、UI工具(如Dashboard)或程序代码(客户端开发库)发起请求,其中,kubectl是最为常用的交互式命令行工具。快速了解Kubernetes的办法之一就是部署一个测试集群,并尝试测试使用它的各项基本功能。本章在简单介绍核心资源对象后将尝试使用kubectl创建Deployment和Service资源部署并暴露一个Web应用,以便读者快速了解如何在Kubernetes系统上运行应用程序的核心任务。

2.1 Kubernetes的核心对象

API Server提供了RESTful风格的编程接口,其管理的资源是Kubernetes API中的端点,用于存储某种API对象的集合,例如,内置Pod资源是包含了所有Pod对象的集合。资源对象是用于表现集群状态的实体,常用于描述应于哪个节点进行容器化应用、需要为其配置什么资源以及应用程序的管理策略等,例如,重启、升级及容错机制。另外,一个对象也是一种“意向记录”—一旦创建,Kubernetes就需要一直确保对象始终存在。Pod、Deployment和Service等都是最常用的核心对象。

2.1.1 Pod资源对象

Pod资源对象是一种集合了一到多个应用容器、存储资源、专用IP及支撑容器运行的其他选项的逻辑组件,如图2-1所示。换言之,Pod代表着Kubernetes的部署单元及原子运行单元,即一个应用程序的单一运行实例,它通常由共享资源且关系紧密的一个或多个应用容器组成。
Kubernetes的网络模型要求其各Pod对象的IP地址位于同一网络平面内(同一IP网段),各Pod之间可使用其IP地址直接进行通信,无论它们运行于集群内的哪个工作节点之上,这些Pod对象都像是运行于同一局域网中的多个主机。
读者可以将每个Pod对象想象成一个逻辑主机,它类似于现实世界中的物理主机或VM(Virtual Machine),运行于同一个Pod对象中的多个进程也类似于物理机或VM上独立运行的进程。不过,Pod对象中的各进程均运行于彼此隔离的容器中,并于各容器间共享两种关键资源:网络和存储卷。

带你读《Kubernetes进阶实战》之二:Kubernetes快速入门

  • 网络(networking):每个Pod对象都会被分配一个集群内专用的IP地址,也称为Pod IP,同一Pod内部的所有容器共享Pod对象的Network和UTS名称空间,其中包括主机名、IP地址和端口等。因此,这些容器间的通信可以基于本地回环接口lo进行,而与Pod外的其他组件的通信则需要使用Service资源对象的ClusterIP及其相应的端口完成。
  • 存储卷(volume):用户可以为Pod对象配置一组“存储卷”资源,这些资源可以共享给其内部的所有容器使用,从而完成容器间数据的共享。存储卷还可以确保在容器终止后被重启,甚至是被删除后也能确保数据不会丢失,从而保证了生命周期内的Pod对象数据的持久化存储。
    一个Pod对象代表某个应用程序的一个特定实例,如果需要扩展应用程序,则意味着为此应用程序同时创建多个Pod实例,每个实例均代表应用程序的一个运行的“副本”(replica)。这些副本化的Pod对象的创建和管理通常由另一组称之为“控制器”(Controller)的对象实现,例如,Deployment控制器对象。

创建Pod时,还可以使用Pod Preset对象为Pod注入特定的信息,如Conf?igMap、Secret、存储卷、卷挂载和环境变量等。有了Pod Preset对象,Pod模板的创建者就无须为每个模板显式提供所有信息,因此,也就无须事先了解需要配置的每个应用的细节即可完成模板定义。这些内容将在后面的章节中予以介绍。
基于期望的目标状态和各节点的资源可用性,Master会将Pod对象调度至某选定的工作节点运行,工作节点于指向的镜像仓库(image registry)下载镜像,并于本地的容器运行时环境中启动容器。Master会将整个集群的状态保存于etcd中,并通过API Server共享给集群的各组件及客户端。

2.1.2 Controller

Kubernetes集群的设计中,Pod是有生命周期的对象。用户通过手工创建或由Controller(控制器)直接创建的Pod对象会被“调度器”(Scheduler)调度至集群中的某工作节点运行,待到容器应用进程运行结束之后正常终止,随后就会被删除。另外,节点资源耗尽或故障也会导致Pod对象被回收。
但Pod对象本身并不具有“自愈”功能,若是因为工作节点甚至是调度器自身导致了运行失败,那么它将会被删除;同样,资源耗尽或节点故障导致的回收操作也会删除相关的Pod对象。在设计上,Kubernetes使用“控制器”实现对一次性的(用后即弃)Pod对象的管理操作,例如,要确保部署的应用程序的Pod副本数量严格反映用户期望的数目,以及基于Pod模板来重建Pod对象等,从而实现Pod对象的扩缩容、滚动更新和自愈能力等。例如,某节点发生故障时,相关的控制器会将此节点上运行的Pod对象重新调度到其他节点进行重建。
控制器本身也是一种资源类型,它有着多种实现,其中与工作负载相关的实现如Replication Controller、Deployment、StatefulSet、DaemonSet、DaemonSet和Jobs等,也可统称它们为Pod控制器。如图2-2中的Deployment就是这类控制器的代表实现,是目前最常用的管理无状态应用的Pod控制器。
Pod控制器的定义通常由期望的副本数量、Pod模板和标签选择器(Label Selector)组成。Pod控制器会根据标签选择器对Pod对象的标签进行匹配检查,所有满足选择条件的Pod对象都将受控于当前控制器并计入其副本总数,并确保此数目能够精确反映期望的副本数。
需要注意的是,在实际的应用场景中,在接收到的请求流量负载显著低于或接近于已有Pod副本的整体承载能力时,用户需要手动修改Pod控制器中的期望副本数量以实现应用规模的扩容或缩容。不过,若集群中部署了HeapSter或Prometheus一类的资源指标监控附件时,用户还可以使用“HorizontalPodAutoscaler”(HPA)计算出合适的Pod副本数量,并自动修改Pod控制器中期望的副本数以实现应用规模的动态伸缩,提高集群资源利用率,如图2-3所示。
Kubernetes集群中的每个节点都运行着cAdvisor以收集容器及节点的CPU、内存及磁盘资源的利用率指标数据,这些统计数据由Heapster聚合后可通过API Server访问。HorizontalPodAutoscaler基于这些统计数据监控容器健康状态并做出扩展决策。

带你读《Kubernetes进阶实战》之二:Kubernetes快速入门

   
      

图2-2 Replication

Controller  

带你读《Kubernetes进阶实战》之二:Kubernetes快速入门

  

图2-3 Horizontal Pod Autoscaler

2.1.3 Service

尽管Pod对象可以拥有IP地址,但此地址无法确保在Pod对象重启或被重建后保持不变,这会为集群中的Pod应用间依赖关系的维护带来麻烦:前端Pod应用(依赖方)无法基于固定地址持续跟踪后端Pod应用(被依赖方)。于是,Service资源被用于在被访问的Pod对象中添加一个有着固定IP地址的中间层,客户端向此地址发起访问请求后由相关的Service资源调度并代理至后端的Pod对象。
换言之,Service是“微服务”的一种实现,事实上它是一种抽象:通过规则定义出由多个Pod对象组合而成的逻辑集合,并附带访问这组Pod对象的策略。Service对象挑选、关联Pod对象的方式同Pod控制器一样,都是要基于Label Selector进行定义,其示意图如图2-4所示。

带你读《Kubernetes进阶实战》之二:Kubernetes快速入门


图2-4 Service对象功能示意图


Service IP是一种虚拟IP,也称为Cluster IP,它专用于集群内通信,通常使用专用的地址段,如“10.96.0.0/12”网络,各Service对象的IP地址在此范围内由系统动态分配。
集群内的Pod对象可直接请求此类的Cluster IP,例如,图2-4中来自pod client的访问请求即可以Service的Cluster IP作为目标地址,但集群网络属于私有网络地址,它们仅在集群内部可达。将集群外部的访问流量引入集群内部的常用方法是通过节点网络进行,实现方法是通过工作节点的IP地址和某端口(NodePort)接入请求并将其代理至相应的Service对象的Cluster IP上的服务端口,而后由Service对象将请求代理至后端的Pod对象的Pod IP及应用程序监听的端口。因此,诸如图2-4中的External Clients这种来自集群外部的客户端无法直接请求此Service提供的服务,而是需要事先经由某一个工作节点(如Node Y)的IP地址进行,这类请求需要两次转发才能到达目标Pod对象,因此在通信效率上必然存在负面影响。
事实上,NodePort会部署于集群中的每一个节点,这就意味着,集群外部的客户端通过任何一个工作节点的IP地址来访问定义好的NodePort都可以到达相应的Service对象。此种场景中,如果存在集群外部的一个负载均衡器,即可将用户请求负载均衡至集群中的部分或者所有节点。这是一种称为“LoadBalancer”类型的Service,它通常是由Cloud Provider自动创建并提供的软件负载均衡器,不过,也可以是由管理员手工配置的诸如F5 Big-IP一类的硬件设备。
简单来说,Service主要有三种常用类型:第一种是仅用于集群内部通信的ClusterIP类型;第二种是接入集群外部请求的NodePort类型,它工作于每个节点的主机IP之上;第三种是LoadBalancer类型,它可以把外部请求负载均衡至多个Node的主机IP的NodePort之上。此三种类型中,每一种都以其前一种为基础才能实现,而且第三种类型中的LoadBalancer需要协同集群外部的组件才能实现,并且此外部组件并不接受Kubernetes的管理。

2.1.4 部署应用程序的主体过程

Docker容器技术使得部署应用程序从传统的安装、配置、启动应用程序的方式转为于容器引擎上基于镜像创建和运行容器,而Kubernetes又使得创建和运行容器的操作不必再关注其位置,并在一定程度上赋予了它动态扩缩容及自愈的能力,从而让用户从主机、系统及应用程序的维护工作中解脱出来。
用到某应用程序时,用户只需要向API Server请求创建一个Pod控制器,由控制器根据镜像等信息向API Server请求创建出一定数量的Pod对象,并由Master之上的调度器指派至选定的工作节点以运行容器化应用。此外,用户一般还需要创建一个具体的Service对象以便为这些Pod对象建立起一个固定的访问入口,从而使得其客户端能够通过其服务名称或ClusterIP进行访问,如图2-5所示。

带你读《Kubernetes进阶实战》之二:Kubernetes快速入门


图2-5 应用程序简单的部署示例


API Server的常用客户端程序是Kubernetes系统自带的命令行工具kubectl,它通过一众子命令用于实现集群及相关资源对象的管理操作,并支持直接命令式、命令式配置清单及声明式配置清单等三种操作方式,特性丰富且功能强大。而需作为集群附件额外部署的Dashboard则提供了基于Web界面的图形客户端,它是一个通用目的管理工具,与Kubernetes紧密集成,支持多级别用户授权,能在一定程度上替代kubectl的大多数操作。
本章后面的篇幅将介绍在部署完成的Kubernetes集群环境中如何快速部署如图2-5所示的示例应用程序,并简单说明如何完成对容器化应用的访问,以及如何进行应用规模的动态伸缩,并借此让读者了解kubectl命令的基本功能和用法。

2.2 部署Kubernetes集群

Kubernetes系统可运行于多种平台之上,包括虚拟机、裸服务器或PC等,例如本地主机或托管的云端虚拟机。若仅用于快速了解或开发的目的,那么读者可直接于单个主机之上部署“伪”分布式的Kubernetes集群,将集群的所有组件均部署运行于单台主机上,著名的minukube项目可帮助用户快速构建此类环境。如果要学习使用Kubernetes集群的完整功能,则应该构建真正的分布式集群环境,将Master和Node等部署于多台主机之上,主机的具体数量要按实际需求而定。另外,集群部署的方式也有多种选择,简单的可以基于kubeadm一类的部署工具运行几条命令即可实现,而复杂的则可以是从零开始手动构建集群环境。

2.2.1 kubeadm部署工具

kubeadm是Kubernetes项目自带的集群构建工具,它负责执行构建一个最小化的可用集群以及将其启动等的必要基本步骤,简单来讲,kubeadm是Kubernetes集群全生命周期的管理工具,可用于实现集群的部署、升级/降级及拆除,如图2-6所示。不过,在部署操作中,kubeadm仅关心如何初始化并启动集群,余下的其他操作,例如安装Kubernetes Dashboard、监控系统、日志系统等必要的附加组件则不在其考虑范围之内,需要管理员按需自行部署。

带你读《Kubernetes进阶实战》之二:Kubernetes快速入门


图2-6 kubeadm功能示意图


kubeadm集成了kubeadm init和kubeadm join等工具程序,其中kubeadm init用于集群的快速初始化,其核心功能是部署Master节点的各个组件,而kubeadm join则用于将节点快速加入到指定集群中,它们是创建Kubernetes集群最佳实践的“快速路径”。另外,kubeadm token可于集群构建后管理用于加入集群时使用的认证令牌(token),而kubeadm reset命令的功能则是删除集群构建过程中生成的文件以重置回初始状态。
kubeadm还支持管理初始引导认证令牌(Bootstrap Token),完成待加入的新节点首次联系API Server时的身份认证(基于共享密钥)。另外,它们还支持管理集群版本的升级和降级操作。Kubernetes 1.8版本之前,kubeadm一直处于beta级别,并警告不能用于生产环境。不过,自1.9版本开始,其虽仍处于beta版本,但已经不再输出警告信息,而随着1.11版本发布的kubeadm又得到了进一步的增强,它支持动态配置kubelet,通过增强的CRI集成支持动态探测以判定所用的容器引擎,并引入了几个新的命令行工具,包括kubeadm conf?ig print-default、kubeadm conf?ig migrate、kubeadm conf?ig images pull和kubeadm upgrade node conf?ig等。总体来说,使用kubeadm部署Kubernetes集群具有如下几个方面的优势。
  • 简单易用:kubeadm可完成集群的部署、升级和拆除操作,并且对新手用户非常友好。
  • 适用领域广泛:支持将集群部署于裸机、VMware、AWS、Azure、GCE及更多环境的主机上,且部署过程基本一致。
  • 富有弹性:1.11版中的kubeadm支持阶段式部署,管理员可分为多个独立步骤完成部署操作。
  • 生产环境可用:kubeadm遵循以最佳实践的方式部署Kubernetes集群,它强制启用RBAC,设定Master的各组件间以及API Server与kublet之间进行认证及安全通信,并锁定了kubelet API等。
    由此可见,kubeadm并非一键安装类的解决方案,相反,它有着更宏大的目标,旨在成为一个更大解决方案的一部分,试图为集群创建和运营构建一个声明式的API驱动模型,它将集群本身视为不可变组件,而升级操作等同于全新部署或就地更新。目前,使用kubeadm部署集群已经成为越来越多的Kubernetes工程师的选择。

2.2.2 集群运行模式

Kubernetes集群支持三种运行模式:一是“独立组件”模式,系统各组件直接以守护进程的方式运行于节点之上,各组件之间相互协作构成集群,如图2-7b所示;第二种是“静态Pod模式”,除kubelet和Docker之外的其他组件(如etcd、kube-apiserver、kube-controller-manager和kube-scheduler等)都是以静态Pod对象运行于Master主机之上的,如图2-7a所示;第三种是Kubernetes的“自托管”(self-hosted)模式,它类似于第二种方式,将除了kubelet和Docker之外的其他组件运行为集群之上的Pod对象,但不同的是,这些Pod对象托管运行在集群自身之上受控于DaemonSet类型的控制器,而非静态的Pod对象。

带你读《Kubernetes进阶实战》之二:Kubernetes快速入门


图2-7 Kubernetes集群的运行模式(图2-7a为静态Pod模式)


使用kubeadm部署的Kubernetes集群可运行为第二种或第三种模式,默认为静态Pod对象模式,需要使用自托管模式时,kubeadm init命令使用“--features-gates=selfHosting”选项即可。第一种模式集群的构建需要将各组件运行于系统之上的独立守护进程中,其间需要用到的证书及Token等认证信息也都需要手动生成,过程烦琐且极易出错;若有必要用到,则建议使用GitHub上合用的项目辅助进行,例如,通过ansible playbook进行自动部署等。

2.2.3 准备用于实践操作的集群环境

本书后面的篇幅中用到的测试集群如图2-8所示,该集群由一个Master主机和三个Node主机组成,它基于kubeadm部署,除了kubelet和Docker之外其他的集群组件都运行于Pod对象中。多数情况下,两个或以上的独立运行的Node主机即可测试分布式集群的核心功能,因此其数量可按需定义,但两个主机是模拟分布式环境的最低需求。生产实践中,应该至少部署三个协同工作的Master节点以确保控制平面的服务可用性,不过,在测试环境中仅部署一个Master节点也是常见的选择。

带你读《Kubernetes进阶实战》之二:Kubernetes快速入门


图2-8 Kubernetes集群部署目标示意图


各Node上采用的容器运行时环境为docker,后续的众多容器的运行任务都将依赖于Docker Registry服务,包括DockerHub、GCR(Google Container Registry)和Quay等,甚至是私有的Registry服务,本书假设读者对Docker容器技术有熟练的使用基础。另外,本部署示例中使用的用于为Pod对象提供网络功能的插件是f?lannel,其同样以Pod对象的形式托管运行于Kubernetes系统之上。
具体的部署过程以及本书用到的集群环境请参考附录A,本章后续的操作都将依赖于根据其步骤部署完成的集群环境,读者需要根据其内容成功搭建出Kubernetes测试集群后才能进行后面章节的学习。

2.2.4 获取集群环境相关的信息

Kubernetes系统目前仍处于快速迭代阶段,版本演进频繁,读者所部署的版本与本书中使用的版本或将有所不同,其功能特性也将存在一定程度的变动。因此,事先查看系统版本,以及对比了解不同版本间的功能特性变动也将是不可或缺的步骤。当然,用户也可选择安装与本书相同的系统版本。下面的命令显示的是当前使用的客户端及服务端程序版本信息:

[root@master ~]# kubectl version --short=true
Client Version: v1.12.1
Server Version: v1.12.1

Kubernetes系统版本变动时的ChangeLog可参考github.com站点上相关版本中的介绍。
Kubernetes集群以及部署的附件CoreDNS等提供了多种不同的服务,客户端访问这些服务时需要事先了解其访问接口,管理员可使用“kubectl cluster-info”命令获取相关的信息。
[root@master ~]# kubectl cluster-info
Kubernetes master is running at https://172.16.0.70:6443
CoreDNS is running at https://172.16.0.70:6443/api/v1/namespaces/kube-system/
services/kube-dns:dns/proxy</pre>

一个功能完整的Kubernetes集群应当具备的附加组件还包括Dashboard、Ingress Controller和Heapster(或Prometheus)等,后续章节中的某些概念将会依赖到这些组件,读者可选择在将要用到时再进行部署。

2.3 kubectl使用基础与示例

Kubernetes API是管理其各种资源对象的唯一入口,它提供了一个RESTful风格的CRUD(Create、Read、Update和Delete)接口用于查询和修改集群状态,并将结
果存储于集群状态存储系统etcd中。事实上,API server也是用于更新etcd中资源对象状态的唯一途径,Kubernetes的其他所有组件和客户端都要通过它来完成查询或修改操作,如图2-9所示。从这个角度来讲,它们都算得上是API server的客户端。
任何RESTful风格API中的核心概念都是“资源”(resource),它是具有类型、关联数据、同其他资源的关系以及可对其执行的一组操作方法的对象,它与对象式编程语言中的对象实例类似,两者之间的重要区别在于RESTful API仅为资源定义了少量的标准方法(对应于标准HTTP的GET、POST、PUT和DELETE方法),而编程语言中的对象实例通常有很多方法。另外,资源可以根据其特性分组,每个组是同一类型资源的集合,它仅包含一种类型的资源,并且各资源间不存在顺序的概念,集合本身也是资源。对应于Kubernetes中,Pod、Deployment和Service等都是所谓的资源类型,它们由相应类型的对象集合而成。
API Server通过认证(Authentication)、授权(Authorization)和准入控制(Admission Control)等来管理对资源的访问请求,因此,来自于任何客户端(如kubectl、kubelet、kube-proxy等)的访问请求都必须事先完成认证之后方可进行后面的其他操作。API Server支持多种认证方式,客户端可以使用命令行选项或专用的配置文件(称为kubeconf?ig)提供认证信息。相关的内容将在后面的章节中给予详细说明。
kubectl的核心功能在于通过API Server操作Kubernetes的各种资源对象,它支持三种操作方式,其中直接命令式(Imperative commands)的使用最为简便,是了解Kubernetes集群管理的一种有效途径。
kubectl命令常用操作示例
为了便于读者快速适应kubectl的命令操作,这里给出几个使用示例用于说明其基本使用方法。
1.创建资源对象
直接通过kubectl命令及相关的选项创建资源对象的方式即为直接命令式操作,例如下面的命令分别创建了名为nginx-deploy的Deployment控制器资源对象,以及名为nginx-svc的Service资源对象:

$ kubectl run nginx-deploy --image=nginx:1.12 --replicas=2
$ kubectl expose deployment/nginx --name=nginx-svc --port=80

用户也可以根据资源清单创建资源对象,即命令式对象配置文件,例如,假设存在定义了Deployment对象的nginx-deploy.yaml文件,和定义了Service对象的nginx-svc.yaml文件,使用kubectl create命令即可进行基于命令式对象配置文件的创建操作:
$ kubectl create -f nginx-deploy.yaml -f nginx-svc.yaml

甚至还可以将创建交由kubectl自行确定,用户只需要声明期望的状态,这种方式称为声明式对象配置。例如,假设存在定义了Deployment对象的nginx-deploy.yaml文件,以及定义了Service对象的nginx-svc.yaml文件,那么使用kubectl apply命令即可实现声明式配置:
$ kubectl apply -f nginx-deploy.yaml -f nginx-svc.yaml

本章后面的章节主要使用第一种资源管理方式,第二种和第三种方式将在后面的章节中展开讲述。
2.查看资源对象
运行着实际负载的Kubernetes系统上通常会存在多种资源对象,用户可分类列出感兴趣的资源对象及其相关的状态信息,“kubectl get”正是用于完成此类功能的命令。例如,列出系统上所有的Namespace资源对象,命令如下:
$ kubectl get namespaces

用户也可一次查看多个资源类别下的资源对象,例如,列出默认名称空间内的所有Pod和Service对象,并输出额外信息,可以使用如下形式的kubectl get命令:
$ kubectl get pods,services -o wide

Kubernetes系统的大部分资源都隶属于某个Namespace对象,缺省的名称空间为default,若需要获取指定Namespace对象中的资源对象的信息,则需要使用-n或--namespace指明其名称。例如,列出kube-namespace名称空间中拥有k8s-app标签名称的所有Pod对象:
$ kubectl get pods -l k8s-app -n kube-system

3.打印资源对象的详细信息
每个资源对象都包含着用户期望的状态(Spec)和现有的实际状态(Status)两种状态信息,“kubectl get -o {yaml|josn}”或“kubectl describe”命令都能够打印出指定资源对象的详细描述信息。例如,查看kube-system名称空间中拥有标签component=kube-apiserver的Pod对象的资源配置清单(期望的状态)及当前的状态信息,并输出为yaml格式,命令如下:
$ kubectl get pods -l component=kube-apiserver -o yaml -n kube-system

而“kubectl describe”命令还能显示与当前对象相关的其他资源对象,如Event或Controller等。例如,查看kube-system名称空间中拥有标签component=kube-apiserver的Pod对象的详细描述信息,可以使用下面的命令:
$ kubectl describe pods -l component=kube-apiserver -n kube-system

这两个命令都支持以“TYPE NAME”或“TYPE/NAME”的格式指定具体的资源对象,如“pods kube-apiserver-master.ilinux.io”或“pods/kube-apiserver-master.ilinux.io”,以了解特定资源对象的详细属性信息及状态信息。
4.打印容器中的日志信息
通常一个容器中仅会运行一个进程(及其子进程),此进程作为PID为1的进程接收并处理管理信息,同时将日志直接输出至终端中,而无须再像传统的多进程系统环境那样将日志保存于文件中,因此容器日志信息的获取一般要到其控制上进行。“kubectl logs”命令可打印Pod对象内指定容器的日志信息,命令格式为“kubectl logs [-f] -p [-c CONTAINER] [options]”,若Pod对象内仅有一个容器,则-c选项及容器名为可选。例如,查看名称空间kube-system中仅有一个容器的Pod对象kube-apiserver-master.ilinux.io的日志:
$ kubectl logs kube-apiserver-master.ilinux.io -n kube-system

为上面的命令添加“-f”选项,还能用于持续监控指定容器中的日志输出,其行为类似于使用了-f选项的tail命令。
5.在容器中执行命令
容器的隔离属性使得对其内部信息的获取变得不再直观,这一点在用户需要了解容器内进程的运行特性、文件系统上的文件及路径布局等信息时,需要穿透其隔离边界进行。“kubectl exec”命令便是用于在指定的容器内运行其他应用程序的命令,例如,在kube-system名称空间中的Pod对象kube-apiserver-master.ilinux.io上的唯一容器中运行ps命令:
$ kubectl exec kube-apiserver-master.ilinux.io -n kube-system -- ps

注意,若Pod对象中存在多个容器,则需要以-c选项指定容器后再运行。
6.删除资源对象
使命已经完成或存在错误的资源对象可使用“kubectl delete”命令予以删除,不过,对于受控于控制器的对象来说,删除之后其控制器可能会重建出类似的对象,例如,Deployment控制器下的Pod对象在被删除时就会被重建。例如,删除默认名称空间中名为nginx-svc的Service资源对象:
$ kubectl delete services nginx-svc

下面的命令可用于删除kube-system名称空间中拥有标签“k8s-app=kube-proxy”的所有Pod对象:
$ kubectl delete pods -l app=monitor -n kube-system

若要删除指定名称空间中的所有的某类对象,可以使用“kubectl delete TYPE --all -n NS”命令,例如,删除kube-public名称空间中的所有Pod对象:
$ kubectl delete pods --all -n kube-public

另外,有些资源类型(如Pod),支持优雅删除的机制,它们有着默认的删除宽限期,不过,用户可以在命令中使用--grace-period选项或--now选项来覆盖默认的宽限期。

2.4 命令式容器应用编排

本节将使用示例镜像“ikubernetes/myapp: v1”来演示容器应用编排的基础操作:应用部署、访问、查看、服务暴露和扩缩容等。一般说来,Kubernetes之上应用程序的基础管理操作由如下几个部分组成。
1)通过合用的Controller类的资源(如Deployment或ReplicationController)创建并管控Pod对象以运行特定的应用程序,如Nginx或tomcat等。无状态(stateless)应用的部署和控制通常使用Deployment控制器进行,而有状态应用则需要使用StatefulSet控制器。
2)为Pod对象创建Service对象,以便向客户端提供固定的访问路径,并借助于CoreDNS进行服务发现。
3)随时按需获取各资源对象的简要或详细信息,以了解其运行状态。
4)如有需要,则手动对支持扩缩容的Controller组件进行扩容或缩容;或者,为支持HPA的Controller组件(如Deployment或ReplicationController)创建HPA资源对象以实现Pod副本数目的自动伸缩。
5)滚动更新:当应用程序的镜像出现新版本时,对其执行更新操作;必要时,为Pod对象中的容器更新其镜像版本;并可根据需要执行回滚操作。
本节中的操作示例仅演示了前三个部分的功能,即应用的部署、服务暴露及相关信息的查看。应用的扩缩容、升级及回滚等操作会在后面的章节中进行详细介绍。
以下操作命令在任何部署了kubectl并能正常访问到Kubernetes集群的主机上均可执行,包括集群外的主机。复制master主机上的/etc/kubernetes/admin.conf至相关用户主目录下的.kube/conf?ig文件即可正常执行,具体方法请参考kubeadm init命令结果中的提示。

2.4.1 部署应用(Pod)

在Kubernetes集群上自主运行的Pod对象在非计划内终止后,其生命周期即告结束,用户需要再次手动创建类似的Pod对象才能确保其容器中的应用依然可得。对于Pod数量众多的场景,尤其是对微服务业务来说,用户必将疲于应付此类需求。Kubernetes的工作负载(workload)类型的控制器能够自动确保由其管控的Pod对象按用户期望的方式运行,因此,Pod的创建和管理大多都会通过这种类型的控制器来进行,包括Deployment、ReplicaSet、ReplicationController等。
1.创建Deployment控制器对象
“kubectl run”命令可于命令行直接创建Deployment控制器,并以--image选项指定的镜像运行Pod中的容器,--dry-run选项可用于命令的测试运行,但并未真正执行资源对象的创建过程。例如,下面的命令要创建一个名为myapp的Deployment控制器对象,它使用镜像ikubernetes/myapp: v1创建Pod对象,但仅在测试运行后即退出:

~]$ kubectl run myapp --image=ikubernetes/myapp:v1 --port=80 --replicas=1
--dry-run

NAME AGE
myapp


镜像ikubernetes/myapp: v1中定义的容器主进程为默认监听于80端口的Web服务程序Nginx,因此,如下命令使用“--port=80”来指明容器要暴露的端口。而“--replicas=1”选项则指定了目标控制器对象要自动创建的Pod对象的副本数量。确认测试命令无误后,可移除“--dry-run”选项后再次执行命令以完成资源对象的创建:
~]$ kubectl run myapp --image=ikubernetes/myapp:v1 --port=80 --replicas=1
deployment.apps/myapp created

创建完成后,其运行效果示意图如图2-10所示,它在default名称空间中创建了一个名为myapp的Deployment控制器对象,并由它基于指定的镜像文件创建了一个Pod对象。

带你读《Kubernetes进阶实战》之二:Kubernetes快速入门


图2-10 Deployment对象myapp及其创建的Pod对象


kubectl run命令其他常用的选项还有如下几个,它们支持用户在创建资源对象时实现更多的控制,具体如下。
-l, --labels:为Pod对象设定自定义标签。
--record:是否将当前的对象创建命令保存至对象的Annotation中,布尔型数据,其值可为true或false。
--save-conf?ig:是否将当前对象的配置信息保存至Annotation中,布尔型数据,其值可为true或false。
--restart=Never:创建不受控制器管控的自主式Pod对象。
其他可用选项及使用方式可通过“kubectl run --help”命令获取。资源对象创建完成后,通常需要了解其当前状态是否正常,以及是否能够吻合于用户期望的目标状态,相关的操作一般使用kubectl get、kubectl describe等命令进行。
2.打印资源对象的相关信息
kubectl get命令可用于获取各种资源对象的相关信息,它既能够显示对象类型特有格式的简要信息,也能够指定出格式为YAML或JSON的详细信息,或者使用Go模板自定义要显示的属性及信息等。例如,下面是查看前面创建的Deployment对象的相关运行状态的命令及其输出结果:
~]$ kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
myapp 1 1 1 1 1m

上面命令的执行结果中,各字段的说明具体如下。
1)NAME:资源对象的名称。
2)DESIRED:用户期望由当前控制器管理的Pod对象副本的精确数量。
3)CURRENT:当前控制器已有的Pod对象的副本数量。
4)UP-TO-DATE:更新到最新版本定义的Pod对象的副本数量,在控制器的滚动更新模式下,它表示已经完成版本更新的Pod对象的副本数量。
5)AVAILABLE:当前处于可用状态的Pod对象的副本数量,即可正常提供服务的副本数。
6)AGE:Pod的存在时长。
Deployment资源对象通过ReplicaSet控制器实例完成对Pod对象的控制,而非直接控制。另外,通过控制器创建的Pod对象都会被自动附加一个标签,其格式为“run=”,例如,上面的命令所创建的Pod,会拥有“run=myapp”标签。后面的章节对此会有详细描述。
而此Deployment控制器创建的唯一Pod对象运行正常与否,其被调度至哪个节点运行,当前是否就绪等也是用户在创建完成后应该重点关注的信息。由控制器创建的Pod对象的名称通常是以控制器名称为前缀,以随机字符为后缀,例如,下面命令输出结果中的myapp-6865459dff-5nsjc:
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
myapp-6865459dff-5nsjc 1/1 Running 0 3m 10.244.3.2 node03.
ilinux.io</pre>

上面命令的执行结果中,每一个字段均代表着Pod资源对象一个方面的属性,除了NAME之外的其他字段及功用说明如下。
①READY:Pod中的容器进程初始化完成并能够正常提供服务时即为就绪状态,此字段用于记录处于就绪状态的容器数量。
②STATUS:Pod的当前状态,其值可能是Pending、Running、Succeeded、Failed和Unknown等其中之一。
③RESTARTS:Pod对象可能会因容器进程崩溃、超出资源限额等原因发生故障问题而被重启,此字段记录了它重启的次数。
④IP:Pod的IP地址,其通常由网络插件自动分配。
⑤NODE:创建时,Pod对象会由调度器调度至集群中的某节点运行,此字段即为节点的相关标识信息。
如果指定名称空间中存在大量的Pod对象而使得类似如上命令的输出结果存在太多的不相关信息时,则可通过指定选项“-l run=myapp”进行Pod对象过滤,其仅显示符合此标签选择器的Pod对象。
确认Pod对象已转为“Running”状态之后,即可于集群中的任一节点(或其他Pod对象)直接访问其容器化应用中的服务,如图2-11中节点NodeX上的客户端程序Client,或者集群上运行于Pod中的客户端程序。

带你读《Kubernetes进阶实战》之二:Kubernetes快速入门


图2-11 访问Pod中容器化应用服务程序


例如,在集群中任一节点上使用curl命令对地址为10.244.3.2的Pod对象myapp-6865459dff-5nsjc的80端口发起服务请求,命令及结果如下所示:
[ik8s@node03 ~]$ curl http://10.244.3.2:80/
Hello MyApp | Version: v1 | Pod Name

2.4.2 探查Pod及应用详情

资源创建或运行过程中偶尔会因故出现异常,此时用户需要充分获取相关的状态及配置信息以便确定问题的所在。另外,在对资源对象进行创建或修改完成之后,也需要通过其详细的状态来了解操作成功与否。kubectl有多个子命令可用于从不同的角度显示对象的状态信息,这些信息有助于用户了解对象的运行状态、属性详情等信息。
1)kubectl describe:显示资源的详情,包括运行状态、事件等信息,但不同的资源类型其输出内容不尽相同。
2)kubectl logs:查看Pod对象中容器输出在控制台的日志信息。在Pod中运行有多个容器时,需要使用选项“-c”指定容器名称。
3)kubectl exec:在Pod对象某容器内运行指定的程序,其功能类似于“docker exec”命令,可用于了解容器各方面的相关信息或执行必需的设定操作等,其具体功能取决于容器内可用的程序。
1.查看Pod对象的详细描述
下面给出的命令打印了此前由myapp创建的Pod对象的详细状态信息,为了便于后续的多次引用,这里先将其名称保存于变量POD_NAME中。命令的执行结果中省略了部分输出:

~]$ POD_NAME=myapp-6865459dff-5nsjc
~]$ kubectl describe pods $POD_NAME
Name: myapp-6865459dff-5nsjc
Namespace: default
Priority: 0
PriorityClassName:
Node: node03.ilinux.io/172.16.0.68
……
Status: Running
IP: 10.244.3.2
Controlled By: ReplicaSet/myapp-6865459dff
Containers:
myapp:
……

……
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 55m default-scheduler Successfully assigned

  default/myapp-6865459dff-5nsjc to node03.ilinux.io

Normal Pulling 55m kubelet, node03.ilinux.io pulling image "ikubernetes/

  myapp:v1"

Normal Pulled 54m kubelet, node03.ilinux.io Successfully pulled image

  "ikubernetes/myapp:v1"

Normal Created 54m kubelet, node03.ilinux.io Created container
Normal Started 54m kubelet, node03.ilinux.io Started container


不同的需求场景中,用户需要关注不同纬度的输出,但一般来说,Events和Status字段会是重点关注的对象,它们分别代表了Pod对象运行过程中的重要信息及当前状态。上面命令执行结果中的不少字段都可以见名而知义,而且部分字段在前面介绍其他命令输出时已经给出,还有一部分会在本书后面的篇幅中给予介绍。
2.查看容器日志
Docker容器一般仅运行单个应用程序,其日志信息将通过标准错误输出等方式直接打印至控制台,“kubectl logs”命令即用于查看这些日志。例如,查看由Deployment控制器myapp创建的Pod对象的控制台日志,命令如下:
~]$ kubectl logs $POD_NAME
10.244.3.1 - - [……] "GET / HTTP/1.1" 200 65 "-" "curl/7.29.0" "-"
……

如果Pod中运行有多个容器,则需要在查看日志时为其使用“-c”选项指定容器名称。例如,当读者所部署的是KubeDNS附件而非CoreDNS时,kube-system名称空间内的kube-dns相关的Pod中同时运行着kubedns、dnsmasq和sidecar三个容器,如果要查看kubedns容器的日志,需要使用类似如下的命令:
~]$ DNS_POD=$(kubectl get pods -o name -n kube-system | grep kube-dns)
~]$ kubectl logs $DNS_POD -c kubedns -n kube-system

需要注意的是,日志查看命令仅能用于打印存在于Kubernetes系统上的Pod中容器的日志,对于已经删除的Pod对象,其容器日志信息将无从获取。日志信息是用于辅助用户获取容器中应用程序运行状态的最有效的途径之一,也是非常重要的排错手段,因此通常需要使用集中式的日志服务器统一收集存储于各Pod对象中容器的日志信息。
3.在容器中运行额外的程序
运行着非交互式进程的容器中,默认运行的唯一进程及其子进程启动后,容器即进入独立、隔离的运行状态。对容器内各种详情的了解需要穿透容器边界进入其中运行其他的应用程序来进行,“kubectl exec”可以让用户在Pod的某容器中运行用户所需要的任何存在于容器中的程序。在“kubectl logs”获取的信息不够全面时,此命令可以通过在Pod中运行其他指定的命令(前提是容器中存在此程序)来辅助用户获取更多的信息。一个更便捷的使用接口的方式是直接交互式运行容器中的某个Shell程序。例如,直接查看Pod中的容器运行的进程:
~]$ kubectl exec $POD_NAME ps aux
PID USER TIME COMMAND
1 root       0:00 nginx: master process nginx -g daemon off;
8 nginx      0:00 nginx: worker process
9 root       0:00 ps aux</pre>

如果Pod对象中运行了多个容器,那么在程序运行时还需要使用“-c ”选项指定要于其内部运行程序的容器名称。
若要进入容器的交互式Shell接口,可使用类似如下的命令,斜体部分表示在容器的交互式接口中执行的命令:

~]$ kubectl -it exec $POD_NAME /bin/sh
/ # hostname
myapp-6865459dff-5nsjc
/ # netstat -tnl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
/

2.4.3 部署Service对象

简单来说,一个Service对象可视作通过其标签选择器过滤出的一组Pod对象,并能够为此组Pod对象监听的套接字提供端口代理及调度服务。
1.创建Service对象
“kubectl expose”命令可用于创建Service对象以将应用程序“暴露”(expose)于网络中。例如,下面的命令即可将myapp创建的Pod对象使用“NodePort”类型的服务暴露到集群外部:

~]$ kubectl expose deployments/myapp --type="NodePort" --port=80 --name=myapp
service "myapp" exposed

上面的命令中,--type选项用于指定Service的类型,而--port则用于指定要暴露的容器端口,目标Service对象的名称为myapp。创建完成后,default名称空间中的对象及其通信示意图如图2-12所示。

带你读《Kubernetes进阶实战》之二:Kubernetes快速入门


图2-12 Service对象在Pod对象前端添加了一个固定访问层


下面通过运行于同一集群中的Pod对象中的客户端程序发起访问测试,来模拟图2-12中的源自myapp Client Pod对象的访问请求。首先,使用kubectl run命令创建一个Pod对象,并直接接入其交互式接口,如下命令的-it组合选项即用于交互式打开并保持其shell命令行接口;而后通过wget命令对此前创建的Service对象的名称发起访问请求,如下命令中的myapp即Service对象名称,default即其所属的Namespace对象的名称:
$ kubectl run client --image=busybox --restart=Never -it -- /bin/sh
If you don't see a command prompt, try pressing enter.
/ # wget -O - -q http://myapp.default:80
Hello MyApp | Version: v1 | Pod Name

创建时,Service对象名称及其ClusterIP会由CoreDNS附件动态添加至名称解析库当中,因此,名称解析服务在对象创建后即可直接使用。
类似于列出Deployment控制器及Pod对象的方式,“kubectl get services”命令能够列出Service对象的相关信息,例如下面的命令显示了Service对象myapp的简要状态信息:
~]$ kubectl get svc/myapp
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
myapp NodePort 10.109.39.145 80:31715/TCP 5m

其中,“PORT(s)”字段表明,集群中各工作节点会捕获发往本地的目标端口为31715的流量,并将其代理至当前Service对象的80端口,于是,集群外部的用户可以使用当前集群中任一节点的此端口来请求Service对象上的服务。CLUSTER-IP字段为当前Service的IP地址,它是一个虚拟IP,并没有配置于集群中的任何主机的任何接口之上,但每个node之上的kube-proxy都会为CLUSTER-IP所在的网络创建用于转发的iptables或ipvs规则。此时,用户可于集群外部任一浏览器请求集群任一节点的相关端口来进行访问测试。
创建Service对象的另一种方式是使用“kubectl create service”命令,对应于每个类型,它分别有一个专用的子命令,例如“kubectl create service clusterip”和“kubectl create service nodeport”等,各命令在使用方式上也略有区别。
2.查看Service资源对象的描述
“kubectl describe services”命令用于打印Service对象的详细信息,它通常包括Service对象的Cluster IP,关联Pod对象时使用的标签选择器及关联到的Pod资源的端点等,示例如下:
~]$ kubectl describe services myapp-svc
Name: myapp
Namespace: default
Labels: run=myapp
Annotations:
Selector: run=myapp
Type: NodePort
IP: 10.109.39.145
Port: 80/TCP
TargetPort: 80/TCP
NodePort: 31715/TCP
Endpoints: 10.244.3.2:80
Session Affinity: None
External Traffic Policy: Cluster
Events:

上面命令的执行结果输出基本上可以做到见名而知义,此处需要特别说明的几个字段具体如下:
1)Selector:当前Service对象使用的标签选择器,用于选择关联的Pod对象。
2)Type:即Service的类型,其值可以是ClusterIP、NodePort和LoadBalancer等其中之一。
3)IP:当前Service对象的ClusterIP。
4)Port:暴露的端口,即当前Service用于接收并响应请求的端口。
5)TargetPort:容器中的用于暴露的目标端口,由Service Port路由请求至此端口。
6)NodePort:当前Service的NodePort,它是否存在有效值与Type字段中的类型相关。
7)EndPoints:后端端点,即被当前Service的Selector挑中的所有Pod的IP及其端口。
8)Session Aff?inity:是否启用会话粘性。
9)External Traff?ic Policy:外部流量的调度策略。

2.4.4 扩容和缩容

前面示例中创建的Deployment对象myapp仅创建了一个Pod对象,其所能够承载的访问请求数量即受限于这单个Pod对象的服务容量。请求流量上升到接近或超出其容量之前,用户可以通过Kubernetes的“扩容机制”来扩展Pod的副本数量,从而提升其服务容量。
简单来说,所谓的“伸缩”(Scaling)就是指改变特定控制器上Pod副本数量的操作,“扩容”(scaling up)即为增加副本数量,而“缩容”(scaling down)则意指缩减副本数量。不过,无论是扩容还是缩容,其数量都需要由用户明确给出。
Service对象内建的负载均衡机制可在其后端副本数量不止一个时自动进行流量分发,它还会自动监控关联到的Pod的健康状态,以确保仅将请求流量分发至可用的后端Pod对象。若某Deployment控制器管理包含多个Pod实例,则必要时用户还可以为其使用“滚动更新”机制将其容器镜像升级到新的版本或变更那些支持动态修改的Pod属性。
使用kubectl run命令创建Deployment对象时,“--replicas=”选项能够指定由该对象创建或管理的Pod对象副本的数量,且其数量支持运行时进行修改,并立即生效。“kubectl scale”命令就是专用于变动控制器应用规模的命令,它支持对Deployment资源对象的扩容和缩容操作。例如,如果要将myapp的Pod副本数量扩展为3个,则可以使用如下命令来完成:

~]$ kubectl scale deployments/myapp --replicas=3
deployment.extensions "myapp" scaled

而后列出由myapp创建的Pod副本,确认其扩展操作的完成状态。如下命令显示出其Pod副本数量已经扩增至3个,其中包括此前的myapp-6865459dff-5nsjc:
~]$ kubectl get pods -l run=myapp
NAME READY STATUS RESTARTS AGE
myapp-6865459dff-52j7t 0/1 ContainerCreating 0 53s
myapp-6865459dff-5nsjc 1/1 Running 0 2h
myapp-6865459dff-jz7t6 0/1 ContainerCreating 0 53s

Deployment对象myapp规模扩展完成之后,default名称空间中的资源对象及其关联关系如图2-13所示。


图2-13 Deployment对象规模扩增完成


而后由“kubectl describe deployment”命令打印Deployment对象myapp的详细信息,了解其应用规模的变动及当前Pod副本的状态等相关信息。从下面的命令结果可以看出,其Pod副本数量的各项指标都已经转换到了新的目标数量,而其事件信息中也有相应的事件显示其扩增操作已成功完成:
~]$ kubectl describe deployments/myapp
Name: myapp
……
Selector: run=myapp
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0
unavailable

……
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 2m deployment-controller Scaled up replica set

  myapp-6865459dff to 3</pre>

由myapp自动创建的Pod资源全都拥有同一个标签选择器“run=myapp”,因此,前面创建的Service资源对象myapp的后端端点也已经通过标签选择器自动扩展到了这3个Pod对象相关的端点,如下面的命令结果及图2-13所示:

~]$ kubectl describe services/myapp
Name: myapp
……
Endpoints: 10.244.1.3:80,10.244.2.2:80,10.244.3.2:80
……

回到此前创建的客户端Pod对象client的交互式接口,对Service对象myapp反复发起测试请求,即可验正其负载均衡的效果。由如下命令及其结果可以看出,它会将请求调度至后端的各Pod对象进行处理:
~]$ / # while true; do wget -O - -q http://myapp.default:80/hostname.html;
sleep 1; done

myapp-6865459dff-jz7t6
myapp-6865459dff-52j7t
myapp-6865459dff-5nsjc
……


应用规模缩容的方式与扩容相似,只不过是将Pod副本的数量调至比原来小的数字即可。例如,将myapp的Pod副本缩减至2个,可以使用如下命令进行:
~]$ kubectl scale deployments/myapp --replicas=2
deployment.extensions "myapp" scaled

至此,功能基本完整的容器化应用已在Kubernetes上部署完成,即便是一个略复杂的分层应用也只需要通过合适的镜像以类似的方式就能部署完成。

2.4.5 修改及删除对象

成功创建于Kubernetes之上的对象也称为活动对象(live object),其配置信息(live object conf?iguration)由API Server保存于集群状态存储系统etcd中,“kubectl get TYPE NAME -o yaml”命令可获取到相关的完整信息,而运行“kubectl edit”命令可调用默认编辑器对活动对象的可配置属性进行编辑。例如,修改此前创建的Service对象myapp的类型为ClusterIP,使用“kubectl edit service myapp”命令打开编辑界面后修改type属性的值为ClusterIP,并删除NodePort属性,然后保存即可。对活动对象的修改将实时生效,但资源对象的有些属性并不支持运行时修改,此种情况下,编辑器将不允许保存退出。
有些命令是kubectl edit命令某一部分功能的二次封装,例如,kubectl scale命令不过是专用于修改资源对象的replicas属性值而已,它也同样直接作用于活动对象。
不再有价值的活动对象可使用“kubectl delete”命令予以删除,需要删除Service对象myapp时,使用如下命令即可完成:

~]$ kubectl delete service myapp
service "myapp" deleted

有时候需要清空某一类型下的所有对象,只需要将上面命令对象的名称换成“--all”选项便能实现。例如,删除默认名称空间中所有的Deployment控制器的命令如下:
~]$ kubectl delete deployment --all
deployment.extensions "myapp" deleted

需要注意的是,受控于控制器的Pod对象在删除后会被重建,删除此类对象需要直接删除其控制器对象。不过,删除控制器时若不想删除其Pod对象,可在删除命令上使用“--cascade=false”选项。
虽然直接命令式管理的相关功能强大且适合用于操纵Kubernetes资源对象,但其明显的缺点是缺乏操作行为以及待运行对象的可信源。另外,直接命令式管理资源对象存在较大的局限性,它们在设置资源对象属性方面提供的配置能力相当有限,而且还有不少资源并不支持命令操作进行创建,例如,用户无法创建带有多个容器的Pod对象,也无法为Pod对象创建存储卷。因此,管理资源对象更有效的方式是基于保存有对象配置信息的配置清单来进行。

2.5 本章小结

本章着重介绍了Kubernetes的三个核心资源抽象Pod、Deployment和Service,并在介绍了kubectl的基本用法之后通过案例讲解了如何在集群中部署、暴露、访问及扩缩容容器化应用,具体如下。
Pod是运行容器化应用及调度的原子单元,同一个Pod中可同时运行多个容器,这些容器共享Mount、UTS及Network等Linux内核名称空间,并且能够访问同一组存储卷。
Deployment是最常见的无状态应用的控制器,它支持应用的扩缩容、滚动更新等操作,为容器化应用赋予了极具弹性的功能。
Service为弹性变动且存在生命周期的Pod对象提供了一个固定的访问接口,用于服务发现和服务访问。
kubectl是Kubernetes API Server最常用的客户端程序之一,它功能强大,特性丰富,几乎能够完成除了安装部署之外的所有管理操作。

上一篇:带你读《Kubernetes进阶实战》之一:Kubernetes系统基础


下一篇:智慧党建信息系统开发,组织部*任免大数据分析平台建设