2.4.2 探查 Pod 及应用详情
资源创建或运行过程中偶尔会因故出现异常,此时用户需要充分获取相关的状态及配置信息以便确定问题的所在。另外,在对资源对象进行创建或修改完成之后,也需要通过其详细的状态来了解操作成功与否。kubectl有多个子命令可用于从不同的角度显示对象的状态信息,这些信息有助于用户了解对象的运行状态、属性详情等信息。
- kubctl describe:显示资源的详情,包括运行状态、事件等信息,但不同的资源类型其输出的内容不尽相同。
- kubectl logs:查看Pod对象中容器输出在控制台的日志信息。在Pod中运行有多个容器时,需要使用“-c”指定容器名称。
- kubectl exec:在Pod对象某容器内运行指定的程序,其功能类似与“docker exec”命令,可用于了解容器各方面的相关信息或执行必需的设定等操作等,其具体功能取决于容器内可用的程序。
1. 查看Pod对象的详细描述
下面给出的命令打印了此前由myapp创建的Pod对象的详细状态信息,为了便于后续的多次引用,这里先将其名称保存与变量POD_NAME中。命令的执行结果中省略了部分输出:
**[terminal]
**[delimiter $ ]**[command POD_NAME=myapp-5c647497bf-9km8t]
**[delimiter $ ]**[command kubectl describe pods $POD_NAME]
Name: myapp-5c647497bf-9km8t
Namespace: default
Priority: 0
PriorityClassName: <none>
Node: kube-node-2.localdomain/192.168.0.183
Start Time: Wed, 27 Nov 2019 14:38:42 +0800
Labels: pod-template-hash=5c647497bf
run=myapp
Annotations: <none>
Status: Running
IP: 10.244.3.3
Controlled By: ReplicaSet/myapp-5c647497bf
Containers:
myapp:
Container ID: docker://7b5fd18032fe6dee9f9f7b144e388483c8cd592b6906ac612c777bc1bd3e8973
Image: ikubernetes/myapp:v1
Image ID: docker-pullable://ikubernetes/myapp@sha256:40ccda7b7e2d080bee7620b6d3f5e6697894befc409582902a67c963d30a6113
Port: 80/TCP
Host Port: 0/TCP
State: Running
Started: Wed, 27 Nov 2019 14:38:47 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-fwfzr (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-fwfzr:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-fwfzr
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 48m default-scheduler Successfully assigned default/myapp-5c647497bf-9km8t to kube-node-2.localdomain
Normal Pulling 48m kubelet, kube-node-2.localdomain Pulling image "ikubernetes/myapp:v1"
Normal Pulled 48m kubelet, kube-node-2.localdomain Successfully pulled image "ikubernetes/myapp:v1"
Normal Created 48m kubelet, kube-node-2.localdomain Created container myapp
Normal Started 48m kubelet, kube-node-2.localdomain Started container myapp
不同的需求场景中,用户需要关注不同维度的输出,但一般来说,Events 和 Status 字段会是重点关注的对象,它们分别代表了Pod对象运行过程中的重要信息及当前状态。上面命令执行结果中的不少字段都将可以见名而知义,而且部分字段再前面介绍其他命令输出时已经给出,还有一部分会在本书后面的篇幅中给予介绍。
2. 查看容器日志
Docker容器一般仅运行单个应用程序,其日志信息将通过标准错误输出等方式直接打印至控制台,“kubelet logs”命令即用于查看这些日志。例如,查看由 Deployment 控制器 myapp 创建的 Pod 对象的控制台日志,命令如下:
**[terminal]
**[delimiter $ ]**[command kubectl logs $POD_NAME]
10.244.0.0 - - [27/Nov/2019:07:15:50 +0000] "GET / HTTP/1.1" 200 65 "-" "curl/7.29.0" "-"
如果Pod中运行有多个容器,则需要再查看日志时为其使用“-c”选项指定容器名称。例如,当读者所部署的是KubeDNS附件而非CoreDNS时,kube-system名称空间内的kube-dns相关的Pod中同时运行这kubedns、dnsmasq、sidecar三个容器,如果要查看kubedns容器的日志,需要使用类似如下的命令:
**[terminal]
**[delimiter $ ]**[command DNS_POD=$(kubectl get pods -o name -n kube-system|grep kube-dns)]
**[delimiter $ ]**[command kubectl logs $DNS_POD -c kubedns -n kube-system]
需要注意的是,日志查看命令仅能用于打印存在Kubernetes系统之上的Pod中容器的日志,对于已删除的Pod对象,其容器日志信息将无从获取。日志信息是用于辅助用户获取容器中应用程序运行状态的最有效的途径之一,也是非常重要的排错手段,因此通常需要使用集中式的日志服务器统一收集存储与各Pod对象中容器的日志信息。
3. 在容器中运行额外的程序
运行着非交互式进程的容器中,默认运行的唯一进程及其子进程启动后,容器即进入独立、隔离的运行状态。对容器内各种详情的了解需要穿透容器边界进入其中运行其他的应用程序来进行,“kubectl exec”可以让用户在Pod的某容器中运行用户所需的任何存在于容器中的程序。在“kubectl logs”获取的信息不够全面时,此命令可以通过再Pod中运行其他指定的命令(前提是容器中存在此程序)来辅助用户获取更多的信息。一个更便捷的使用接口的方式是直接交互式运行容器中的某个shell程序。例如,直接查看Pod中的容器运行的进程:
**[terminal]
**[delimiter $ ]**[command kubectl exec $POD_NAME ps aux]
PID USER TIME COMMAND
1 root 0:00 nginx: master process nginx -g daemon off;
6 nginx 0:00 nginx: worker process
7 root 0:00 ps aux
如果Pod对象中运行了多个容器,那么在程序运行时还需要使用“-c
”选项指定要于其内部运行程序的容器名称。
若要进入容器的交互式Shell接口,可使用类似如下的命令,斜体部分表示在容器的交互式接口中执行的命令:
**[terminal]
**[delimiter $ ]**[command kubectl -it exec $POD_NAME /bin/sh]
/ # hostname
myapp-5c647497bf-9km8t
/ # 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
/ #