查看 Pod 和节点
目标
- 了解 Kubernetes Pods。
- 了解 Kubernetes Nodes。
- 排查已部署的应用故障。
Kubernetes Pods
当你在模块 2 中创建 Deployment 时,Kubernetes 会创建一个 Pod 来托管你的应用实例。Pod 是 Kubernetes 的一个抽象概念,代表一组一个或多个应用容器(例如 Docker)以及这些容器的一些共享资源。这些资源包括:
- 共享存储,例如卷(Volume)
- 网络,例如唯一的集群 IP 地址
- 关于如何运行每个容器的信息,例如容器镜像版本或要使用的特定端口
Pod 模拟了一个应用程序特定的“逻辑主机”,可以包含多个相对紧密耦合的不同应用容器。例如,一个 Pod 可能既包含运行 Node.js 应用的容器,也包含一个为 Node.js Web 服务器提供待发布数据的不同容器。Pod 中的容器共享 IP 地址和端口空间,始终是协同安置和协同调度的,并在同一 Node 上运行在共享上下文中。
Pod 是 Kubernetes 平台上的原子单元。当我们在 Kubernetes 上创建 Deployment 时,Deployment 会创建包含容器的 Pod(而不是直接创建容器)。每个 Pod 都绑定到调度它的 Node,并一直保留在那里直到终止(根据重启策略)或删除。如果 Node 发生故障,相同的 Pod 会被调度到集群中其他可用的 Node 上。
Pod 概览
节点
Pod 始终运行在 Node 上。Node 是 Kubernetes 中的工作机器,根据集群的不同,它可以是虚拟机或物理机。每个 Node 都由控制平面管理。一个 Node 可以有多个 Pod,Kubernetes 控制平面会自动处理 Pod 在集群中 Node 之间的调度。控制平面的自动调度会考虑每个 Node 上可用的资源。
每个 Kubernetes Node 至少运行:
Kubelet,负责 Kubernetes 控制平面与 Node 之间通信的进程;它管理机器上运行的 Pod 和容器。
容器运行时(例如 Docker),负责从注册表拉取容器镜像、解压容器并运行应用。
Node 概览
使用 kubectl 进行故障排查
在模块 2 中,你使用了 kubectl 命令行界面。在模块 3 中,你将继续使用它来获取有关已部署应用及其环境的信息。最常见的操作可以使用以下 kubectl 子命令完成:
kubectl get
- 列出资源kubectl describe
- 显示资源的详细信息kubectl logs
- 打印 Pod 中容器的日志kubectl exec
- 在 Pod 中容器上执行命令
你可以使用这些命令查看应用何时部署、当前状态如何、在哪里运行以及配置是什么。
现在我们对集群组件和命令行有了更多了解,接下来让我们来探索我们的应用。
检查应用配置
让我们验证一下我们在上一个场景中部署的应用是否正在运行。我们将使用 kubectl get
命令来查找现有的 Pod:
kubectl get pods
如果没有任何 Pod 正在运行,请稍等几秒钟,再次列出 Pod。看到有一个 Pod 正在运行后,你就可以继续了。
接下来,要查看该 Pod 中有哪些容器以及用于构建这些容器的镜像,我们运行 kubectl describe pods
命令:
kubectl describe pods
我们在这里看到了关于 Pod 容器的详细信息:IP 地址、使用的端口以及与 Pod 生命周期相关的事件列表。
describe
子命令的输出很详细,涵盖了一些我们尚未解释的概念,但别担心,在本教程结束时,你就会熟悉它们。
注意
describe
子命令可以用来获取大多数 Kubernetes 原语(包括 Node、Pod 和 Deployment)的详细信息。describe 输出是为了方便人工阅读而设计的,不适合用于脚本处理。在终端中显示应用
回想一下,Pod 运行在隔离的私有网络中 - 所以我们需要通过代理访问它们以便进行调试和交互。为此,我们将使用 kubectl proxy
命令在**第二个终端**中运行代理。打开一个新的终端窗口,并在新终端中运行:
kubectl proxy
现在,我们再次获取 Pod 名称并直接通过代理查询该 Pod。要获取 Pod 名称并将其存储在 POD_NAME
环境变量中:
export POD_NAME="$(kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}')"
echo Name of the Pod: $POD_NAME
要查看我们应用的输出,运行一个 curl
请求:
curl http://localhost:8001/api/v1/namespaces/default/pods/$POD_NAME:8080/proxy/
这个 URL 是通往 Pod API 的路由。
注意
我们无需指定容器名称,因为我们的 Pod 中只有一个容器。在容器上执行命令
一旦 Pod 启动并运行,我们可以直接在容器上执行命令。为此,我们使用 exec
子命令,并使用 Pod 的名称作为参数。让我们列出环境变量:
kubectl exec "$POD_NAME" -- env
同样值得一提的是,由于 Pod 中只有一个容器,因此可以省略容器本身的名称。
接下来,让我们在 Pod 的容器中启动一个 bash 会话:
kubectl exec -ti $POD_NAME -- bash
我们现在拥有了在我们运行 NodeJS 应用的容器上的一个开放控制台。应用源代码在 server.js
文件中:
cat server.js
你可以通过运行 curl 命令来检查应用是否已启动:
curl http://localhost:8080
注意
这里我们使用localhost
是因为我们在 NodeJS Pod 内部执行了命令。如果无法连接到 localhost:8080
,请检查确保你已经运行了 kubectl exec
命令并且是在 Pod 内部启动的命令。要关闭容器连接,输入 exit
。
下一步
- 教程:使用 Service 公开你的应用。
- 了解更多关于 Pods 的信息。
- 了解更多关于 Nodes 的信息。