查看 Pod 和节点

了解如何使用 kubectl get、kubectl describe、kubectl logs 和 kubectl exec 来排查 Kubernetes 应用程序的故障。

目标

  • 了解 Kubernetes Pod。
  • 了解 Kubernetes 节点。
  • 排查已部署应用程序的故障。

Kubernetes Pod

当你在模块 2 中创建 Deployment 时,Kubernetes 创建了一个 Pod 来托管你的应用程序实例。Pod 是 Kubernetes 的一种抽象,表示一组或多个应用程序容器(如 Docker),以及这些容器的一些共享资源。这些资源包括:

  • 共享存储,即卷
  • 网络,作为唯一的集群 IP 地址
  • 有关如何运行每个容器的信息,例如容器镜像版本或要使用的特定端口

Pod 对特定应用程序的“逻辑主机”进行建模,并且可以包含相对紧密耦合的不同应用程序容器。例如,一个 Pod 可能既包含运行你的 Node.js 应用程序的容器,又包含另一个容器,该容器将数据馈送到由 Node.js Web 服务器发布的数据。Pod 中的容器共享 IP 地址和端口空间,始终位于同一位置并共同调度,并在同一节点上的共享上下文中运行。

Pod 是 Kubernetes 平台上的原子单元。当我们在 Kubernetes 上创建 Deployment 时,该 Deployment 会创建其中包含容器的 Pod(而不是直接创建容器)。每个 Pod 都绑定到它被调度的节点,并保留在那里直到终止(根据重启策略)或删除。如果节点出现故障,则相同的 Pod 将在集群中其他可用的节点上调度。

总结

  • Pod
  • 节点
  • Kubectl 主要命令

Pod 是一组或多个应用程序容器(如 Docker),包括共享存储(卷)、IP 地址以及有关如何运行它们的信息。


Pod 概述


节点

Pod 始终在 节点 上运行。节点是 Kubernetes 中的工作机器,可以是虚拟机或物理机,具体取决于集群。每个节点都由控制平面管理。一个节点可以有多个 Pod,并且 Kubernetes 控制平面会自动处理跨集群中各个节点的 Pod 调度。控制平面的自动调度会考虑每个节点上的可用资源。

每个 Kubernetes 节点至少运行

  • Kubelet,一个负责 Kubernetes 控制平面和节点之间通信的进程;它管理在机器上运行的 Pod 和容器。
  • 容器运行时(如 Docker),负责从注册表拉取容器镜像、解压容器以及运行应用程序。

只有当容器紧密耦合并且需要共享磁盘等资源时,才应该将它们一起调度到单个 Pod 中。


节点概述


使用 kubectl 进行故障排除

在模块 2 中,你使用了 kubectl 命令行界面。你将在模块 3 中继续使用它来获取有关已部署应用程序及其环境的信息。可以使用以下 kubectl 子命令完成最常见的操作:

  • kubectl get- 列出资源
  • kubectl describe- 显示有关资源的详细信息
  • kubectl logs- 打印 Pod 中容器的日志
  • kubectl exec- 在 Pod 中的容器上执行命令

你可以使用这些命令来查看应用程序何时部署、它们的当前状态是什么、它们在哪里运行以及它们的配置是什么。

现在我们对集群组件和命令行有了更多的了解,让我们来探索一下我们的应用程序。

节点是 Kubernetes 中的工作机器,可以是虚拟机或物理机,具体取决于集群。一个节点上可以运行多个 Pod。

检查应用程序配置

让我们验证一下我们在上一个场景中部署的应用程序是否正在运行。我们将使用 kubectl get 命令并查找现有的 Pod

kubectl get pods

如果没有 Pod 正在运行,请等待几秒钟,然后再次列出 Pod。看到一个 Pod 正在运行后,你可以继续。

接下来,要查看该 Pod 内有哪些容器以及用于构建这些容器的镜像,我们运行 kubectl describe pods 命令

kubectl describe pods

我们在这里看到了关于 Pod 的容器的详细信息:IP 地址、使用的端口以及与 Pod 生命周期相关的事件列表。

的输出describe子命令内容广泛,涵盖了一些我们尚未解释的概念,但请不要担心,在本次训练营结束时,你将熟悉它们。

注意:describe子命令可以用于获取有关大多数 Kubernetes 原语的详细信息,包括节点、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 Pod 名称:$POD_NAME

要查看应用程序的输出,请运行 curl 请求

curl https://127.0.0.1:8001/api/v1/namespaces/default/pods/$POD_NAME:8080/proxy/

该 URL 是 Pod 的 API 的路由。

查看容器日志

应用程序通常发送到标准输出的任何内容都会成为 Pod 中容器的日志。我们可以使用 kubectl logs 命令检索这些日志

kubectl logs "$POD_NAME"

注意:我们不需要指定容器名称,因为我们只有一个容器在 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 https://127.0.0.1:8080

注意:这里我们使用了localhost因为我们在 NodeJS Pod 内执行了该命令。如果你无法连接到 localhost:8080,请检查以确保你已运行 kubectl exec 命令,并且是从 Pod 内启动该命令的

要关闭你的容器连接,请键入 exit

准备好后,请继续访问使用 Service 公开你的应用

上次修改时间为太平洋标准时间 2023 年 11 月 30 日下午 12:00:将 kubernetes 教程从 deploy-intro.html 更新为 update-intro.html (6ad170bf17)