Kubernetes进阶实战
上QQ阅读APP看书,第一时间看更新

2.3 kubectl使用基础与示例

Kubernetes API是管理其各种资源对象的唯一入口,它提供了一个RESTful风格的CRUD(Create、Read、Update和Delete)接口用于查询和修改集群状态,并将结果存储于集群状态存储系统etcd中。事实上,API server也是用于更新etcd中资源对象状态的唯一途径,Kubernetes的其他所有组件和客户端都要通过它来完成查询或修改操作,如图2-9所示。从这个角度来讲,它们都算得上是API server的客户端。

图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支持多种认证方式,客户端可以使用命令行选项或专用的配置文件(称为kubeconfig)提供认证信息。相关的内容将在后面的章节中给予详细说明。

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] (POD|TYPE/NAME) [-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选项来覆盖默认的宽限期。