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选项来覆盖默认的宽限期。