在 Kubernetes 上部署应用程序

KubernetesKubernetesBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

在这个实验中,你将学习如何在 Kubernetes 集群上部署应用程序。我们将从使用 Minikube 设置本地 Kubernetes 环境开始。然后,你将探索基本的 kubectl 命令,以便与你的集群交互并管理 Kubernetes 资源。接下来,你将创建一个简单的 YAML 清单文件(manifest file),将其应用到你的集群,并检查部署的状态。最后,你将学习如何使用 kubectl proxy 访问你部署的应用程序。

这个实验将涵盖基本的 Kubernetes 技能,包括集群设置、基本资源管理和应用程序部署。完成这个实验后,你将对如何使用 Kubernetes 和部署自己的应用程序有扎实的理解。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL kubernetes(("`Kubernetes`")) -.-> kubernetes/BasicCommandsGroup(["`Basic Commands`"]) kubernetes(("`Kubernetes`")) -.-> kubernetes/AdvancedCommandsGroup(["`Advanced Commands`"]) kubernetes(("`Kubernetes`")) -.-> kubernetes/TroubleshootingandDebuggingCommandsGroup(["`Troubleshooting and Debugging Commands`"]) kubernetes(("`Kubernetes`")) -.-> kubernetes/ConfigurationandVersioningGroup(["`Configuration and Versioning`"]) kubernetes/BasicCommandsGroup -.-> kubernetes/get("`Get`") kubernetes/BasicCommandsGroup -.-> kubernetes/create("`Create`") kubernetes/AdvancedCommandsGroup -.-> kubernetes/apply("`Apply`") kubernetes/TroubleshootingandDebuggingCommandsGroup -.-> kubernetes/describe("`Describe`") kubernetes/TroubleshootingandDebuggingCommandsGroup -.-> kubernetes/proxy("`Proxy`") kubernetes/ConfigurationandVersioningGroup -.-> kubernetes/version("`Version`") subgraph Lab Skills kubernetes/get -.-> lab-434644{{"`在 Kubernetes 上部署应用程序`"}} kubernetes/create -.-> lab-434644{{"`在 Kubernetes 上部署应用程序`"}} kubernetes/apply -.-> lab-434644{{"`在 Kubernetes 上部署应用程序`"}} kubernetes/describe -.-> lab-434644{{"`在 Kubernetes 上部署应用程序`"}} kubernetes/proxy -.-> lab-434644{{"`在 Kubernetes 上部署应用程序`"}} kubernetes/version -.-> lab-434644{{"`在 Kubernetes 上部署应用程序`"}} end

启动 Kubernetes 集群

在这一步中,我们将使用 Minikube 启动一个本地 Kubernetes 集群。Minikube 是一个用于开发和学习 Kubernetes 的优秀工具,因为它允许你在本地机器上运行单节点 Kubernetes 集群。然后,我们将验证集群是否正确运行并已准备好使用。

首先,打开你的终端。你将在这里输入命令来与你的计算机交互。要启动 Minikube 集群,输入以下命令并按 Enter 键:

minikube start

这个命令将启动创建和启动本地 Kubernetes 集群的过程。Minikube 将下载必要的组件并配置你的集群。当 Minikube 启动时,你将在终端中看到输出。以下是输出可能的样子示例:

😄  minikube v1.29.0 on Ubuntu 22.04
✨  Automatically selected the docker driver
📌  Using Docker driver with root permissions
🔥  Creating kubernetes in kubernetes cluster
🔄  Restarting existing kubernetes cluster
🐳  Preparing Kubernetes v1.26.1 on Docker 20.10.23 ...
🚀  Launching Kubernetes ...
🌟  Enabling addons: storage-provisioner, default-storageclass
🏄  Done! kubectl is now configured to use "minikube" cluster and "default" namespace

一旦 Minikube 启动,让我们验证它是否正在运行,以及 Minikube 内的 Kubernetes 集群是否已准备就绪。依次运行以下命令,并在每个命令后按 Enter 键:

minikube status
kubectl get nodes

minikube status 命令将告诉你 Minikube 本身的状态。kubectl get nodes 命令将与你的 Kubernetes 集群通信,并检索有关集群中节点(计算机)的信息。由于 Minikube 是一个单节点集群,你应该看到列出一个节点。

以下是你可能看到的输出示例:

minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured

NAME       STATUS   ROLES           AGE   VERSION
minikube   Ready    control-plane   1m    v1.26.1

让我们分解一下这个输出告诉我们的信息:

  1. minikube 状态显示 hostkubeletapiserver 的状态为 Running。这表明 Minikube 的核心组件正在正确运行。
  2. kubectl get nodes 显示一个名为 minikube 的节点,其 STATUSReadyReady 表示此节点已准备好运行应用程序。ROLES 下的 control-plane 表示此节点充当 Kubernetes 集群的控制平面(control plane),管理和编排集群。

这些命令确认:

  1. Minikube 正在你的机器上运行。
  2. 一个本地 Kubernetes 集群已在 Minikube 内创建。
  3. Kubernetes 集群处于 Ready 状态,可以使用。
  4. 你有一个单节点 Kubernetes 集群,其中 minikube 节点充当控制平面。

学习基本的 kubectl 命令和语法

在这一步中,你将探索基本的 kubectl 命令。kubectl 是一个命令行工具,允许你与你的 Kubernetes 集群交互。它是管理 Kubernetes 资源所必需的。我们将演示如何使用 kubectl 查看资源并理解基本的 Kubernetes 对象管理。

让我们首先探索你的 Kubernetes 集群中的命名空间(namespaces)。命名空间是一种组织 Kubernetes 资源的方式。默认情况下,Kubernetes 集群有几个用于系统组件和用户资源的命名空间。要查看命名空间的列表,请运行以下命令:

kubectl get namespaces

此命令将列出你的集群中所有可用的命名空间。示例输出:

NAME              STATUS   AGE
default           Active   10m
kube-node-lease   Active   10m
kube-public       Active   10m
kube-system       Active   10m

你通常会看到至少这些默认命名空间:

  • default:如果未指定其他命名空间,则为用户创建的资源的默认命名空间。
  • kube-node-lease:用于节点租约(node leases),这有助于控制平面跟踪节点的健康状况。
  • kube-public:用于应该公开访问的资源(尽管这很少用于敏感信息)。
  • kube-system:包含系统级资源,例如核心 Kubernetes 组件。

接下来,让我们查看在 kube-system 命名空间中运行的系统组件。许多核心 Kubernetes 组件在此命名空间中作为 Pod 运行。要查看特定命名空间中的 Pod,请使用 -n--namespace 标志,后跟命名空间名称。运行以下命令以查看 kube-system 命名空间中的 Pod:

kubectl get pods -n kube-system

此命令将列出在 kube-system 命名空间中运行的所有 Pod。示例输出:

NAME                               READY   STATUS    RESTARTS   AGE
coredns-787d4945fb-j8rhx           1/1     Running   0          15m
etcd-minikube                       1/1     Running   0          15m
kube-apiserver-minikube             1/1     Running   0          15m
kube-controller-manager-minikube    1/1     Running   0          15m
kube-proxy-xb9rz                    1/1     Running   0          15m
kube-scheduler-minikube             1/1     Running   0          15m
storage-provisioner                 1/1     Running   0          15m

此输出显示 Pod 的名称、它们的 READY 状态(Pod 中准备就绪的容器数量/总数)、它们的 STATUS(例如,Running)、它们 RESTARTED 的次数以及它们的 AGE。这些是使 Kubernetes 工作的基本组件。

现在,让我们探索一些基本的 kubectl 命令模式。kubectl 命令的通用语法是:

kubectl [command] [TYPE] [NAME] [flags]

让我们分解一下:

  • kubectl:命令行工具本身。
  • [command]:指定你要执行的操作。常用命令包括:
    • get:显示一个或多个资源。
    • describe:显示有关特定资源的详细信息。
    • create:创建新资源。
    • delete:删除资源。
    • apply:将配置应用于资源。我们稍后会经常使用它。
  • [TYPE]:指定你要与之交互的 Kubernetes 资源类型。常见的资源类型包括:
    • pods:Kubernetes 中最小的可部署单元。
    • deployments:管理用于扩展和更新的 Pod 集。
    • services:公开在 Pod 中运行的应用程序。
    • nodes:Kubernetes 集群中的工作机器。
    • namespaces:资源的逻辑分组。
  • [NAME]:特定资源的名称。这是可选的;如果省略名称,kubectl 将对指定类型的所有资源进行操作。
  • [flags]:用于修改命令行为的可选标志(例如,-n <namespace>-o wide)。

让我们看一些例子:

## 获取 default 命名空间中的所有资源
kubectl get all

## 描述特定资源类型('minikube' 节点)
kubectl describe nodes minikube

kubectl get all 命令将检索有关 default 命名空间中所有资源类型(服务、部署、Pod 等)的信息。示例输出可能如下所示:

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   20m

这表明在 default 命名空间中,我们有一个名为 kubernetesservice

kubectl describe nodes minikube 命令将提供有关 minikube 节点的许多详细信息,包括其状态、容量、地址等。这有助于了解你的节点的状态和配置。

这些命令可以帮助你:

  1. 查看 Kubernetes 集群中的资源。
  2. 获取有关集群组件及其当前状态的详细信息。
  3. 了解 kubectl 的基本命令结构和语法。

创建一个简单的 YAML 清单

在你创建你的第一个 YAML 清单之前,重要的是要理解你将要使用的关键 Kubernetes 对象。这些对象是在 Kubernetes 中管理和编排你的应用程序的构建块。

理解 Kubernetes 对象

  • Pod:Kubernetes 中最基本的单元。一个 Pod 就像一个可以容纳一个或多个容器的盒子。Pod 中的这些容器共享相同的网络和存储。可以将 Pod 视为代表你的应用程序的单个实例。
  • Deployment(部署):Deployment 用于管理 Pod。它们确保始终运行所需数量的 Pod 副本。如果一个 Pod 失败,Deployment 将自动替换它。Deployment 还以受控的方式处理你的应用程序的更新,例如滚动更新。
  • Service(服务):Service 提供了一种稳定的方式来访问在 Pod 中运行的应用程序。由于 Pod 可以被创建和销毁,它们的 IP 地址可能会更改。Service 提供一个固定的 IP 地址和 DNS 名称,始终指向它管理的 Pod 集。这允许你的应用程序的其他部分或外部用户可靠地访问你的应用程序,而无需跟踪单个 Pod 的 IP。

这是一个说明这些对象之间关系的图表:

graph TD; A[Deployment] -->|管理| B[Pods] B -->|包含| C[Containers] B -->|通过...通信| D[Services] D -->|暴露| E[外部客户端]

理解这些对象至关重要,因为你将使用 YAML 清单定义它们的期望状态和配置。

YAML 清单概述

Kubernetes 中的 YAML 清单是一个以 YAML 格式编写的文件,描述了你要创建或管理的 Kubernetes 对象。YAML 是一种人类可读的数据序列化语言。使用 YAML 进行 Kubernetes 清单有几个优点:

  1. 声明式管理:你在 YAML 文件中描述资源的期望状态(例如,“我希望我的应用程序运行 3 个副本”)。然后,Kubernetes 会努力使实际状态与你的期望状态匹配。这称为声明式管理。
  2. 版本控制:YAML 文件是基于文本的,可以轻松存储在 Git 等版本控制系统中。这允许你跟踪 Kubernetes 配置随时间的变化,回滚到以前的配置,并与他人协作。
  3. 可重用性和可移植性:你可以在不同的环境(开发、测试、生产)中重用 YAML 清单,只需进行最少的更改。这使你的部署更加一致和可重现。

现在你已经了解了 Kubernetes 对象和 YAML 清单的基础知识,你就可以创建你的第一个清单了。

创建 YAML 清单

首先,导航到你的项目目录。假设你的主目录(~)中有一个 project 目录。如果你没有它,请立即使用 mkdir project 创建它。然后,使用 cd project 将你的当前目录更改为 project

cd ~/project

接下来,创建一个新目录来存储你的 Kubernetes 清单。我们将其命名为 k8s-manifests。使用 mkdir 命令创建目录,然后使用 cd 进入该目录:

mkdir -p k8s-manifests
cd k8s-manifests

现在,你将创建你的第一个 YAML 清单文件。让我们从一个简单的 NGINX Pod 的清单开始。NGINX 是一个流行的 Web 服务器。我们将创建一个运行单个 NGINX 容器的 Pod。使用 nano 文本编辑器创建一个名为 nginx-pod.yaml 的文件:

nano nginx-pod.yaml

nano 是一个在你的终端中运行的简单文本编辑器。一旦 nano 打开,将以下内容粘贴到文件中:

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
    app: nginx
spec:
  containers:
    - name: nginx
      image: nginx:latest
      ports:
        - containerPort: 80

让我们理解这个 YAML 清单的每个部分:

  • apiVersion: v1:指定用于创建此对象的 Kubernetes API 版本。v1 是核心 API 组,用于 Pod、Service 和命名空间等基本对象。
  • kind: Pod:表示你正在定义一个 Pod 资源。
  • metadata::包含有关 Pod 的数据,例如其名称和标签。
    • name: nginx-pod:将 Pod 的名称设置为 nginx-pod。这是你在 Kubernetes 中引用此 Pod 的方式。
    • labels::标签是附加到对象的键值对。它们用于组织和选择对象的子集。在这里,我们向此 Pod 添加一个标签 app: nginx
  • spec::描述 Pod 的期望状态。
    • containers::要在 Pod 中运行的容器列表。在这种情况下,我们只有一个容器。
      • - name: nginx:将容器的名称设置为 nginx
      • image: nginx:latest:指定要使用的容器镜像。nginx:latest 指的是 Docker Hub 中 NGINX Docker 镜像的最新版本。
      • ports::此容器将暴露的端口列表。
        • - containerPort: 80:指定容器将暴露端口 80。端口 80 是标准的 HTTP 端口。

粘贴内容后,保存文件并退出 nano。为此,请按 Ctrl+X(退出),然后键入 Y(是,保存),最后按 Enter 键确认文件名并保存。

现在你已经创建了 nginx-pod.yaml 文件,你需要将其应用到你的 Kubernetes 集群以创建 Pod。使用带有 -f 标志的 kubectl apply 命令,该标志指定包含清单的文件:

kubectl apply -f nginx-pod.yaml

此命令将清单发送到你的 Kubernetes 集群,Kubernetes 将按照定义创建 Pod。你应该看到类似于以下的输出:

pod/nginx-pod created

要验证 Pod 是否已创建并正在运行,请使用 kubectl get pods 命令。这将列出默认命名空间中的所有 Pod。你还可以使用 kubectl describe pod nginx-pod 获取有关 nginx-pod 的详细信息。运行这些命令:

kubectl get pods
kubectl describe pod nginx-pod

kubectl get pods 的示例输出:

NAME        READY   STATUS    RESTARTS   AGE
nginx-pod   1/1     Running   0          1m

此输出显示 nginx-podREADY(1 个容器中的 1 个已准备就绪),并且其 STATUSRunning。这意味着你的 NGINX Pod 已成功创建并正在运行。

现在,让我们为更复杂的资源创建一个清单:Deployment。Deployment 将管理一组 Pod,确保运行所需数量的副本。使用 nano 创建一个名为 nginx-deployment.yaml 的新文件:

nano nginx-deployment.yaml

将以下内容粘贴到 nginx-deployment.yaml 中:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:latest
          ports:
            - containerPort: 80

让我们重点介绍与 nginx-pod.yaml 清单相比的主要区别和新部分:

  • apiVersion: apps/v1:对于 Deployment,你使用 apps/v1 API 版本,它是 apps API 组的一部分,用于处理更高级别的应用程序管理资源。
  • kind: Deployment:表示你正在定义一个 Deployment 资源。
  • spec::Deployment 的 spec 部分更复杂,因为它定义了 Deployment 应如何管理 Pod。
    • replicas: 3:这是新的。它指定你希望运行 3 个 Pod 副本。Deployment 将确保始终有 3 个与 template 中定义的条件匹配的 Pod。
    • selector::Deployment 使用选择器来标识它应该管理哪些 Pod。
      • matchLabels::定义 Pod 必须具有的标签才能被此 Deployment 选择。在这里,它选择带有标签 app: nginx 的 Pod。
    • template:template 定义了 Deployment 将用于创建新 Pod 的 Pod 规范。它本质上与我们的 nginx-pod.yaml 示例中的 Pod 定义相同,包括 metadata.labelsspec.containers重要:此处在 template.metadata.labels 中定义的标签必须与 selector.matchLabels 匹配,以便 Deployment 可以管理这些 Pod。

保存并退出 nano(Ctrl+X,Y,Enter)。

现在,将此 Deployment 清单应用到你的集群:

kubectl apply -f nginx-deployment.yaml

你应该看到如下输出:

deployment.apps/nginx-deployment created

验证 Deployment 及其创建的 Pod。使用 kubectl get deployments 检查 Deployment 状态,并使用 kubectl get pods 查看 Pod。

kubectl get deployments
kubectl get pods

示例输出:

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           1m

NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-xxx-yyy            1/1     Running   0          1m
nginx-deployment-xxx-zzz            1/1     Running   0          1m
nginx-deployment-xxx-www            1/1     Running   0          1m
  • kubectl get deployments 显示 nginx-deploymentREADY 为 3/3,UP-TO-DATE 为 3,AVAILABLE 为 3。这意味着 Deployment 已成功创建并正在管理 3 个 Pod,并且所有 Pod 都已准备就绪并可用。
  • kubectl get pods 现在列出了三个名称以 nginx-deployment- 开头的 Pod。这些是由你的 nginx-deployment 创建和管理的 Pod。

应用 YAML 清单

在这一步中,你将更详细地探索 kubectl apply 命令,并学习应用 Kubernetes 清单的不同方法。在上一节的 YAML 文件的基础上,我们将演示应用清单的各种技术。

首先,确保你在正确的目录中:

cd ~/project/k8s-manifests

让我们创建一个新的子目录来进一步组织我们的清单。创建一个名为 manifests 的目录并导航到其中:

mkdir -p manifests
cd manifests

现在,让我们为一个简单的 Web 应用程序创建一个清单,该清单在一个文件中包含 Deployment 和 Service。使用 nano 创建一个名为 web-app.yaml 的新文件:

nano web-app.yaml

将以下内容添加到 web-app.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: web
          image: nginx:alpine
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  selector:
    app: web
  type: ClusterIP
  ports:
    - port: 80
      targetPort: 80

此清单在一个文件中定义了两个 Kubernetes 资源,用 --- 分隔。这是一种将相关资源分组在一起的常见方法。让我们分解一下新内容:

  • 一个文件中的多个资源web-app.yaml 文件现在包含两个单独的 Kubernetes 资源定义:一个 Deployment 和一个 Service。--- 分隔符用于区分它们。
  • kind: Service:这定义了一个 Service 资源。
    • spec.selector.app: web:此 Service 将以具有标签 app: web 的 Pod 为目标。这与我们为 web-app Deployment 创建的 Pod 设置的标签匹配。
    • spec.type: ClusterIP:将服务类型指定为 ClusterIP。这意味着该服务将在集群内的内部 IP 地址上公开,通常用于集群内服务之间的通信。
    • spec.ports:定义服务如何将端口映射到目标 Pod。
      • port: 80:你将访问的服务本身的端口。
      • targetPort: 80:服务将流量转发到的目标 Pod 上的端口。

现在,让我们使用不同的方法应用此清单。

方法 1:应用整个文件

这是应用清单的最常见方法。使用 kubectl apply -f 后跟文件名:

kubectl apply -f web-app.yaml

此命令将创建 web-app.yaml 中定义的 Deployment 和 Service。你应该看到如下输出:

deployment.apps/web-app created
service/web-service created

方法 2:从目录应用

你可以一次应用目录中的所有清单。如果你的 manifests 目录中有多个清单文件,你可以通过指定目录而不是特定文件来应用它们:

kubectl apply -f .

. 表示当前目录。kubectl 将在此目录中查找 YAML 文件并应用所有文件。当你将清单组织到目录中的多个文件中时,这非常有用。

方法 3:从 URL 应用(可选)

kubectl apply 还可以直接从 URL 应用清单。这对于快速部署在线托管的示例应用程序或配置非常有用。例如,你可以从 Kubernetes 示例存储库部署 Redis 主部署:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/examples/master/guestbook/redis-master-deployment.yaml

这将从 URL 下载清单并将其应用到你的集群。注意:从不受信任的 URL 应用清单时要小心,因为它们可能会修改你的集群。

让我们探索 kubectl apply 的一些其他选项。

Dry Run(模拟运行)

你可以使用 --dry-run=client 标志来模拟应用清单,而无需实际更改集群。这对于检查你的清单是否有效以及查看将创建或修改哪些资源非常有用:

kubectl apply -f web-app.yaml --dry-run=client

此命令将输出将要创建或更改的内容,但它不会实际将更改应用到你的集群。

Verbose Output(详细输出)

要从 kubectl apply 获取更详细的输出,你可以使用 -v 标志,后跟详细级别(例如,-v=7)。较高的详细级别提供更详细的信息,这对于调试很有帮助:

kubectl apply -f web-app.yaml -v=7

这将打印有关正在进行的 API 请求和清单处理的更多信息。

验证通过应用 web-app.yaml 创建的资源。使用 kubectl get deploymentskubectl get services 列出集群中的 Deployment 和 Service:

## 列出 deployments
kubectl get deployments

## 列出 services
kubectl get services

## 描述 deployment 以查看更多详细信息
kubectl describe deployment web-app

kubectl get deployments 的示例输出:

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           3m33s
redis-master       0/1     1            0           23s
web-app            2/2     2            2           42s

kubectl get services 的示例输出:

NAME          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes    ClusterIP   10.96.0.1       <none>        443/TCP   8m28s
web-service   ClusterIP   10.106.220.33   <none>        80/TCP    46s

请注意,现在你有一个 web-app Deployment,其中 2/2 个 READY 副本,以及一个类型为 ClusterIPweb-service

让我们简要讨论 Kubernetes 中声明式和命令式管理之间的区别,尤其是在 kubectl applykubectl create 的上下文中。

  • kubectl apply:使用声明式方法。你在清单文件中定义期望状态,kubectl apply 尝试实现该状态。如果你使用相同的清单多次运行 kubectl apply,则仅当清单中的期望状态与集群中的当前状态之间存在差异时,Kubernetes 才会进行更改。通常建议使用 kubectl apply 来管理 Kubernetes 资源,因为它更健壮,并且更容易管理随时间的变化。它跟踪资源的配置并允许增量更新。
  • kubectl create:使用命令式方法。你直接指示 Kubernetes 创建资源。如果你尝试为已存在的资源运行 kubectl create,通常会导致错误。与 kubectl apply 相比,kubectl create 在管理更新和更改方面不太灵活。

在大多数情况下,尤其是在管理应用程序部署时,由于其声明式特性以及对更新和配置管理的更好处理,kubectl apply 是首选和推荐的方法

验证 Deployment 状态

在这一步中,你将学习如何使用各种 kubectl 命令检查和验证 Kubernetes Deployment 和其他资源的状态。你将探索不同的方法来收集有关你的 Kubernetes 集群中正在运行的应用程序及其运行状况的信息。

首先,确保你在项目中的 manifests 目录中:

cd ~/project/k8s-manifests/manifests

让我们首先列出当前命名空间(除非你已更改,否则为 default)中的所有 Deployment。使用 kubectl get deployments

kubectl get deployments

此命令提供了你的 Deployment 的简洁概述。示例输出:

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           4m44s
redis-master       1/1     1            1           94s
web-app            2/2     2            2           113s

以下是每列的含义:

  • NAME:Deployment 的名称。
  • READY:显示就绪的副本数与所需的副本数(例如,3/3 表示 3 个所需的副本已就绪)。
  • UP-TO-DATE:指示有多少副本已更新到最新的期望状态。
  • AVAILABLE:显示当前有多少副本可用于服务流量。
  • AGE:Deployment 运行的时间。

要以更宽的格式获取更详细的信息,你可以将 -o wide 标志与 kubectl get deployments 一起使用:

kubectl get deployments -o wide

示例输出:

NAME               READY   UP-TO-DATE   AVAILABLE   AGE     CONTAINERS   IMAGES                      SELECTOR
nginx-deployment   3/3     3            3           4m58s   nginx        nginx:latest                app=nginx
redis-master       1/1     1            1           108s    master       registry.k8s.io/redis:e2e   app=redis,role=master,tier=backend
web-app            2/2     2            2           2m7s    web          nginx:alpine                app=web

-o wide 输出包括其他列,如 CONTAINERSIMAGESSELECTOR,提供有关 Deployment 的更多上下文。

要检查属于特定 Deployment 的 Pod,你可以使用标签。请记住,在我们的 web-app Deployment 清单中,我们为 Pod 设置了标签 app: web。你可以使用此标签通过 kubectl get pods -l <label_selector> 过滤 Pod。要查看与 web-app Deployment 关联的 Pod,请运行:

kubectl get pods -l app=web

示例输出:

NAME                      READY   STATUS    RESTARTS   AGE
web-app-xxx-yyy           1/1     Running   0          10m
web-app-xxx-zzz           1/1     Running   0          10m

这将列出与标签选择器 app=web 匹配的 Pod,这些 Pod 由 web-app Deployment 管理。

要获取有关特定 Deployment 的深入信息,请使用 kubectl describe deployment <deployment_name>。让我们描述 web-app Deployment:

kubectl describe deployment web-app

kubectl describe 提供了有关 Deployment 的大量信息,包括:

  • Name, Namespace, CreationTimestamp, Labels, Annotations:有关 Deployment 的基本元数据。
  • Selector:用于标识此 Deployment 管理的 Pod 的标签选择器。
  • Replicas:期望的、更新的、总的、可用的和不可用的副本计数。
  • StrategyType, RollingUpdateStrategy:有关更新策略的详细信息(例如,RollingUpdate)。
  • Pod Template:用于为此 Deployment 创建 Pod 的规范。
  • Conditions:指示 Deployment 状态的条件(例如,AvailableProgressing)。
  • Events:与 Deployment 相关的事件列表,这对于故障排除很有帮助。

查看 describe 输出中的 ConditionsEvents 部分。如果你的 Deployment 存在问题,这些部分通常会提供线索。例如,如果 Deployment 没有变为 Available,则 Events 可能会显示与镜像拉取、Pod 创建失败等相关的错误。

要检查 Service 的状态,你可以使用类似的命令。首先,列出所有 Service:

kubectl get services

示例输出:

NAME          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes    ClusterIP   10.96.0.1       <none>        443/TCP   10m
web-service   ClusterIP   10.106.220.33   <none>        80/TCP    2m47s

这显示了 web-service 及其 TYPEClusterIP)、CLUSTER-IP 和暴露的 PORT(S)

要获取有关 Service 的更多详细信息,请使用 kubectl describe service <service_name>

kubectl describe service web-service

describe service 输出包括:

  • Name, Namespace, Labels, Annotations:基本元数据。
  • Selector:用于标识目标 Pod 的标签选择器。
  • Type:Service 类型(在本例中为 ClusterIP)。
  • IP, IPs:分配给 Service 的集群 IP 地址。
  • Port, TargetPort:为 Service 定义的端口映射。
  • Endpoints:显示当前支持此 Service 的 Pod 的 IP 地址和端口。这非常重要。如果你没有看到任何端点,则表示 Service 未正确连接到任何 Pod,这可能是由于选择器不匹配造成的。
  • Session Affinity, Events:其他 Service 配置和事件。

在验证 Deployment 状态时,要查找的关键事项是:

  • Deployment READY 状态:确保它显示所需的副本数(例如,web-app2/2)。
  • Pod STATUS:所有 Pod 都应处于 Running 状态。
  • Service Endpoints:检查 Service 是否具有端点,并且它们是否与正在运行的 Pod 的 IP 地址相对应。如果没有端点,请对 Service 的选择器和 Pod 标签进行故障排除。
  • 检查警告或错误:检查 kubectl describe deployment <deployment_name>kubectl describe service <service_name> 的输出中 Events 部分的任何异常情况或错误。

通过使用这些 kubectl 命令,你可以有效地监视和验证 Kubernetes 中 Deployment 和 Service 的状态,确保你的应用程序按预期运行。

使用 kubectl proxy 访问应用程序

在这一步中,你将学习如何使用 kubectl proxy 访问你的 Kubernetes 应用程序。kubectl proxy 创建一个到 Kubernetes API 服务器的安全代理连接,允许你从本地计算机访问集群服务和 Pod。这对于开发和调试非常有用,尤其是在你想访问未在外部公开的服务时。

首先,确保你在项目目录中:

cd ~/project/k8s-manifests/manifests

在后台启动 kubectl proxy。此命令将在单独的进程中运行代理,允许你继续使用终端。

kubectl proxy --port=8080 &

命令末尾的 & 使其在后台运行。你应该看到如下输出:

Starting to serve on 127.0.0.1:8080

如果在运行此命令后终端似乎挂起,你可能需要按一次 Ctrl+C 返回到提示符。代理应该仍在后台运行。

现在,让我们找到属于你的 web-app Deployment 的 Pod 的名称。你可以再次使用 kubectl get pods -l app=web

## 获取 'web-app' 的 Pod 名称
kubectl get pods -l app=web

示例输出:

NAME                      READY   STATUS    RESTARTS   AGE
web-app-xxx-yyy           1/1     Running   0          20m
web-app-xxx-zzz           1/1     Running   0          20m

记下其中一个 Pod 的名称,例如 web-app-xxx-yyy。你将使用此 Pod 名称来构造 API 路径,以访问在该 Pod 中运行的 NGINX Web 服务器。

Kubernetes API 资源可以通过特定路径访问。要通过 kubectl proxy 访问 Pod,你需要构造如下 URL:

http://localhost:8080/api/v1/namespaces/<namespace>/pods/<pod_name>/proxy/

让我们分解一下这个 URL:

  • http://localhost:8080kubectl proxy 正在运行的地址。默认情况下,它监听本地计算机上的端口 8080。
  • /api/v1:指定 Kubernetes API 版本 (v1)。
  • /namespaces/<namespace>:你的 Pod 正在运行的命名空间。在我们的例子中,它是 default
  • /pods/<pod_name>:你要访问的 Pod 的名称。将 <pod_name> 替换为你的 Pod 的实际名称(例如,web-app-xxx-yyy)。
  • /proxy/:表示你要代理到 Pod 的连接。

为了更容易在 URL 中使用 Pod 名称,让我们将第一个 Pod 的名称存储在 shell 变量中。运行此命令,该命令使用 kubectl get podsjsonpath 来提取标签为 app=web 的第一个 Pod 的名称:

## 获取标签为 'app=web' 的第一个 Pod 的名称
POD_NAME=$(kubectl get pods -l app=web -o jsonpath='{.items[0].metadata.name}')
echo $POD_NAME ## 可选:打印 Pod 名称以进行验证

现在,你可以在 curl 命令中使用 $POD_NAME 变量来访问你的 Pod 提供的 NGINX 默认页面。使用 curl 向代理 URL 发送 HTTP 请求。将 URL 中的 ${POD_NAME} 替换为我们刚刚设置的变量:

curl http://localhost:8080/api/v1/namespaces/default/pods/${POD_NAME}/proxy/

如果一切正常,此命令应返回默认 NGINX 欢迎页面的 HTML 内容。示例输出将是 HTML 内容,以以下内容开头:

<!doctype html>
<html>
  <head>
    <title>Welcome to nginx!</title>
    ...
  </head>
  <body>
    <h1>Welcome to nginx!</h1>
    ...
  </body>
</html>

此输出确认你已通过 kubectl proxy 成功访问了在你的 Pod 中运行的 NGINX Web 服务器。

让我们探索一下你可以使用 kubectl proxy 执行的其他一些操作。

通过代理列出默认命名空间中的所有 Pod

你可以通过代理直接访问 Kubernetes API。例如,要列出 default 命名空间中的所有 Pod,你可以使用此 URL:

curl http://localhost:8080/api/v1/namespaces/default/pods/

这将返回一个 JSON 响应,其中包含有关 default 命名空间中所有 Pod 的信息。

通过代理获取有关特定 Pod 的详细信息

要获取有关特定 Pod 的详细信息(类似于 kubectl describe pod),你可以直接访问 Pod 的 API 端点:

curl http://localhost:8080/api/v1/namespaces/default/pods/${POD_NAME}

这将返回一个 JSON 响应,其中包含有关指定 Pod 的详细信息。

停止 kubectl proxy

当你完成使用 kubectl proxy 时,你应该停止它。由于我们在后台启动了它,你需要找到它的进程 ID (PID) 并终止它。你可以使用 jobs 命令列出后台进程:

jobs

这将显示从当前终端会话运行的后台进程。你应该看到列出的 kubectl proxy。要停止它,你可以使用 kill 命令,后跟进程 ID。例如,如果 jobs 显示 [1] Running kubectl proxy --port=8080 &,则进程 ID 为 1。你将使用:

kill %1

%1 替换为 jobs 命令显示的作业 ID。或者,你可以使用 ps aux | grep kubectl proxy 找到进程 ID,然后使用 kill <PID>

关于 kubectl proxy 要记住的关键点:

  • kubectl proxy 创建一个到 Kubernetes API 服务器的安全、经过身份验证的连接。
  • 它允许你从本地计算机访问集群资源(Pod、Service 等),就像你在集群网络内部一样。
  • 它对于调试、开发和探索 Kubernetes API 非常有用。
  • 出于安全原因,kubectl proxy 只能在 localhost (127.0.0.1) 上访问。它不适合用于公开暴露服务。

总结

在这个实验中,你已成功学习了如何使用 Minikube 在 Kubernetes 集群上部署应用程序。你首先使用 Minikube 设置了一个本地 Kubernetes 集群并验证了其状态。然后,你探索了用于与集群交互和管理资源的基本 kubectl 命令。你学习了如何列出命名空间、获取有关节点和 Pod 的详细信息,以及了解 kubectl 的基本命令结构。这些步骤为你使用 Kubernetes 奠定了坚实的基础。

你继续为 Pod 和 Deployment 创建了简单的 YAML 清单,使用 kubectl apply 将它们应用到你的集群,并使用各种 kubectl 命令(如 getdescribe)验证了 Deployment 状态。这种实践经验使你能够理解在 Kubernetes 上部署应用程序的声明式方法,以及如何有效地与集群交互。

最后,你学习了如何使用 kubectl proxy 访问已部署的应用程序,这提供了一种安全的方式来与集群的 API 交互,并从本地计算机访问服务和 Pod。这是一种用于开发、调试和探索 Kubernetes 环境的宝贵技术。

通过完成此实验,你已经获得了基本 Kubernetes 概念和工具的实践经验,为你在 Kubernetes 上部署和管理更复杂的应用程序奠定了基础。

您可能感兴趣的其他 Kubernetes 教程