Kubernetes 常用命令
Kubernetes 通过 Kube Apiserver 作为整个集群管理的入口。Apiserver 是整个集群的主管理节点,用户通过 Apiserver 配置和组织集群,同时集群中各个节点同 etcd 存储的交互也是通过 Apiserver 进行交互。
Apiserver 实现了一套 RESTful 的接口,用户可以直接使用 API 同 Apiserver 交互。另外官方还提供了一个客户端 kubectl 随工具集打包,用于可直接通过 kubectl 以命令行的方式同集群交互。
help
-
<kubectl> 或 <kubectl help> | <kubectl --help>
get
注:集群中可以创建多个 namespace,未指定 namespace 情况下,所有操作都是针对 default namespace。
-
kubectl get po
当前运行的所有 pods 的信息。
-
kubectl get po -o wide
获取 pod 运行在哪个节点上的信息。
-
kubectl get po
显示 default namespace 下的 pods。
-
kubectl get po --namespace=<namespace _name>
显示指定 namespace下的 pods。
-
kubectl get po --all-namespaces
显示所有 namespace 的 pods。
-
kubectl get pod --selector name=redis
按 selector 名来查找 pod。
-
kubectl get namespace
-
kubectl get rc
-
kubectl get svc
-
kubectl get nodes
-
kubectl get node --show-labels
获取一些更具体的信息,可以通过使用选项“-o”:
-
kubectl get po <podname> -o yaml
以 yawl 格式输出 pod 的详细信息
-
kubectl get po <podname> -o json
以 json 格式输出 pod 的详细信息
-
-o=custom-columns=
定义直接获取指定内容的值。
例:kubectl get po -o=custom-columns=LABELS:.metadata.labels.app。其中 LABELS 为显示的列标题,“.metadata.labels.app”为查询的域名其他资源也可以使用类似的方式。
describe
describe 类似于 get,同样用于获取 resource 的相关信息。不同的是,get 获得的是更详细的 resource 个性的详细信息,describe 获得的是 resource 集群相关的信息。describe 命令同 get 类似,但是 describe 不支持 -o 选项,对于同一类型 resource,describe 输出的信息格式,内容域相同。
注:如果发现是查询某个 resource 的信息,使用 get 命令能够获取更加详尽的信息。但是如果想要查询某个 resource 的状态,如某个 pod 并不是在 running 状态,这时需要获取更详尽的状态信息时,就应该使用 describe 命令。
-
kubectl describe po rc-nginx-2-btv4j
label
为 kubernetes 集群的 resource 打标签,如前面实例中提到的为 rc 打标签对 rc 分组。还可以对 nodes 打标签,这样在编排容器时,可以为容器指定 nodeSelector 将容器调度到指定 label 的机器上,如果集群中有 I/O 密集型,计算密集型的机器分组,可以将不同的机器打上不同标签,然后将不同特征的容器调度到不同分组上。
在 1.2 之前的版本中,使用 kubectl get nodes 则可以列出所有节点的信息,包括节点标签,1.2 版本中不再列出节点的标签信息,如果需要查看节点被打了哪些标签,需要使用 describe 查看节点的信息。
-
kubectl label node <node-name> <label_Key>=<label_Value>
-
kubectl label pod redis-master-bobr0 role=backend
create
用于根据文件或输入来创建集群 resource。如果已经定义了相应 resource 的 yaml 或 json 文件,直接 kubectl create -f filename 即可创建文件内定义的 resource。也可以直接只用子命令 [namespace/secret/configmap/serviceaccount] 等直接创建相应的 resource。从追踪和维护的角度出发,建议使用 json 或 yaml 的方式定义资源。
例:文件名为:rc-nginx.yaml
- apiVersion: v1 - kind: ReplicationController - metadata: - name: rc-nginx-2 - spec: - replicas: 2 - template: - metadata: - labels: - app: nginx-2 - spec: - containers: - - name: nginx-2 - image: xingwangc.docker.rg/nginx - ports: - - containerPort: 80
-
kubectl create -f rc-nginx.yaml
直接使用 create 则可以基于 rc-nginx.yaml 文件创建出 ReplicationController(rc),rc 会创建两个副本。
创建后,使用“kubectl get rc”可以看到一个名 为rc-nginx-2 的 ReplicationController 将被创建,同时“kubectl get po”的结果中会多出两个前缀为“rc-nginx-2-”的 pod。
replace
replace 命令用于对已有资源进行更新、替换。如前面 create 中创建的 nginx,当我们需要更新 resource 的一些属性的时候,如果修改副本数量,增加、修改 label,更改 image 版本,修改端口等。都可以直接修改原 yaml 文件,然后执行 replace 命令。
-
kubectl replace -f rc-nginx.yaml
注:名字不能被更新。另外,如果是更新 label,原有标签的 pod 将会与更新 label 后的 rc 断开联系,有新 label 的 rc 将会创建指定副本数的新的 pod,但是默认并不会删除原来的 pod。所以此时如果使用 get po 将会发现 pod 数翻倍,进一步 check 会发现原来的 pod 已经不会被新 rc 控制。
例:
1)文件中添加:
spec: unschedulable: true
2)通过 kubectl replace 命令完成对 Node 状态的修改:
-
kubectl replace -f unschedule_node.yaml
3)查看 Node 的状态,可以观察到在 Node 的状态中增加了一项 SchedulingDisabled:
对于后续创建的 Pod,系统将不会再向该 Node 进行调度。
4)另一种方法是不使用配置文件,直接使用 kubectl patch 命令完成:
-
kubectl patch node kubernetes-minion1 -p '{"spec":{"unschedulable":true}}'
注:将某个 Node 脱离调度范围时,在其上运行的 Pod 并不会自动停止,管理员需要手动停止在该 Node 上运行的 Pod。
同样,如果需要将某个 Node 重新纳入集群调度范围,则将 unschedulable 设置为 false,再次执行 kubectl replace 或 kubectl patch 命令就能恢复系统对该 Node 的调度。
patch
如果一个容器已经在运行,这时需要对一些容器属性进行修改,又不想删除容器,或不方便通过 replace 的方式进行更新。kubernetes 还提供了一种在容器运行时,直接对容器进行修改的方式,就是 patch 命令。
如前面创建 pod 的 label 是 app=nginx-2,如果在运行过程中,需要把其 label 改为 app=nginx-3,这 patch 命令如下:
-
kubectl patch pod rc-nginx-2-kpiqt -p '{"metadata ": {"labels": {"app": "nginx-3"}}}'
edit
edit 提供了另一种更新 resource 源的操作,通过 edit 能够灵活的在一个 common 的 resource 基础上,发展出更过的 significant resource。例如,使用 edit 直接更新前面创建的 pod 的命令为:
-
kubectl edit po rc-nginx-btv4j
上面命令的效果等效于:
kubectl get po rc-nginx-btv4j -o yaml >> /tmp/nginx-tmp.yaml vim /tmp/nginx-tmp.yaml /*do some changes here */ kubectl replace -f /tmp/nginx-tmp.yaml
delete
根据 resource 名或 label 删除 resource。
-
kubectl delete -f rc-nginx.yaml
-
kubectl delete po rc-nginx-btv4j
-
kubectl delete po -lapp=nginx-2
apply
apply 命令提供了比 patch,edit 等更严格的更新 resource 的方式。通过 apply,用户可以将 resource 的 configuration 使用 source control 的方式维护在版本库中。每次有更新时,将配置文件 push 到server,然后使用 kubectl apply 将更新应用到 resource。kubernetes 会在引用更新前将当前配置文件中的配置同已经应用的配置做比较,并只更新更改的部分,而不会主动更改任何用户未指定的部分。
apply 命令的使用方式同 replace 相同,不同的是,apply 不会删除原有 resource,然后创建新的。apply 直接在原有 resource 的基础上进行更新。同时 kubectl apply 还会 resource 中添加一条注释,标记当前的 apply。类似于 git 操作。
logs
logs 命令用于显示 pod 运行中,容器内程序输出到标准输出的内容。跟 docker 的 logs 命令类似。如果要获得 tail -f 的方式,也可以使用 -f 选项。
-
kubectl logs rc-nginx-2-kpiqt
rolling-update
rolling-update 是一个非常重要的命令,对于已经部署并且正在运行的业务,rolling-update 提供了不中断业务的更新方式。rolling-update 每次起一个新的 pod,等新 pod 完全起来后删除一个旧的 pod,然后再起一个新的 pod 替换旧的 pod,直到替换掉所有的 pod。
rolling-update 需要确保新的版本有不同的 name,Version 和 label,否则会报错 。
-
kubectl rolling-update rc-nginx-2 -f rc-nginx.yaml
-
kubectl rolling-update rc-nginx-2 —rollback
如果在升级过程中,发现有问题还可以中途停止 update,并回滚到前面版本。
rolling-update 还有很多其他选项提供丰富的功能,如 update-period 指定间隔周期,使用时可以使用 -h 查看 help 信息。
scale
scale 用于程序在负载加重或缩小时副本进行扩容或缩小,如前面创建的 nginx 有两个副本,可以轻松的使用 scale 命令对副本数进行扩展或缩小。
-
kubectl scale rc rc-nginx-3 --replicas=4
扩展副本数到 4。
-
kubectl scale rc rc-nginx-3 --replicas=2
重新缩减副本数到 2。
autoscale
scale 虽然能够很方便的对副本数进行扩展或缩小,但是仍然需要人工介入,不能实时自动的根据系统负载对副本数进行扩、缩。autoscale 命令提供了自动根据 pod 负载对其副本进行扩缩的功能。
autoscale 命令会给一个 rc 指定一个副本数的范围,在实际运行中根据 pod 中运行的程序的负载自动在指定的范围内对 pod 进行扩容或缩容。如前面创建的 nginx,可以用如下命令指定副本范围在 1~4。
-
kubectl autoscale rc rc-nginx-3 --min=1 --max=4
cordon, drain, uncordon
这三个命令是正式 release 的 1.2 新加入的命令,三个命令一起介绍,是因为三个命令配合使用可以实现节点的维护。在 1.2 之前,因为没有相应的命令支持,如果要维护一个节点,只能 stop 该节点上的 kubelet 将该节点退出集群,是集群不在将新的 pod 调度到该节点上。如果该节点上本生就没有pod在运行,则不会对业务有任何影响。如果该节点上有 pod 正在运行,kubelet 停止后,master 会发现该节点不可达,而将该节点标记为 notReady 状态,不会将新的节点调度到该节点上。同时,会在其他节点上创建新的 pod 替换该节点上的 pod。这种方式虽然能够保证集群的健壮性,但是任然有些暴力,如果业务只有一个副本,而且该副本正好运行在被维护节点上的话,可能仍然会造成业务的短暂中断。
1.2 中新加入的这 3 个命令可以保证维护节点时,平滑的将被维护节点上的业务迁移到其他节点上,保证业务不受影响。如下图所示是一个整个的节点维护的流程(为了方便 demo 增加了一些查看节点信息的操作):
1)首先查看当前集群所有节点状态,可以看到共四个节点都处于 ready 状态;
2)查看当前 nginx 两个副本分别运行在 d-node1 和 k-node2 两个节点上;
3)使用 cordon 命令将 d-node1 标记为不可调度;
-
kubectl cordon d-node1
4)再使用 kubectl get nodes 查看节点状态,发现 d-node1 虽然还处于 Ready 状态,但是同时还被禁能了调度,这意味着新的 pod 将不会被调度到 d-node1 上。
5)再查看 nginx 状态,没有任何变化,两个副本仍运行在 d-node1 和 k-node2 上;
6)执行 drain 命令,将运行在 d-node1 上运行的 pod 平滑的赶到其他节点上;
-
kubectl drain d-node1
7)再查看 nginx 的状态发现,d-node1 上的副本已经被迁移到 k-node1 上;这时候就可以对 d-node1 进行一些节点维护的操作,如升级内核,升级 Docker 等;
8)节点维护完后,使用 uncordon 命令解锁 d-node1,使其重新变得可调度;
-
kubectl uncordon d-node1
9)检查节点状态,发现 d-node1 重新变回 Ready 状态。
attach
attach 命令类似于 docker 的 attach 命令,可以直接查看容器中以 daemon 形式运行的进程的输出,效果类似于 logs -f,退出查看使用 ctrl-c。如果一个 pod 中有多个容器,要查看具体的某个容器的的输出,需要在 pod 名后使用 -c containers name 指定运行的容器。
-
kubectl attach kube-dns-v9-rcfuk -c skydns —namespace= kube-system
查看 kube-system namespace 中的 kube-dns-v9-rcfuk pod 中的 skydns 容器的输出。
exec
exec 命令同样类似于 docker 的 exec 命令,为在一个已经运行的容器中执行一条 shell 命令,如果一个 pod 容器中,有多个容器,需要使用 -c 选项指定容器。
-
kubectl exec pod名 env
查看运行的pod的环境变量
port-forward
转发一个本地端口到容器端口,若使用 yaml 的方式编排容器,则基本不使用此命令。
proxy
此命令为 kubernetes api server 运行过 proxy。
run
类似于 docker 的 run 命令,直接运行一个 image。
其他
其他还有如 cluster-info 信息可以查看当前集群的一些信息,Version 查看集群版本信息等,还有一些集群配置相关的命令等。