Kubernetes资源管理
Kubernetes(K8s)资源管理是 Kubernetes 集群中最核心的功能之一,它允许用户定义、创建、更新、删除和查询集群中的各种资源,如 Pods、Services、Deployments、ConfigMaps 等。通过声明式配置(如 YAML 文件),用户可以精确地定义资源的期望状态,而 Kubernetes 集群则负责确保资源实际状态与期望状态一致。这种管理方式极大地简化了资源的操作
1.1 资源管理介绍
Kubernetes(通常缩写为 k8s)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。在 Kubernetes 中,资源管理是核心概念之一,以下是 Kubernetes 资源管理的一些关键组件和概念:
Kubernetes 资源管理对象 | 描述 |
---|---|
Pods | Kubernetes 中的最小部署单元,可以包含一个或多个容器(通常是 Docker 容器),为容器提供运行环境,包括网络和存储。 |
Deployments | 负责 Pod 的声明式更新,定义应用的期望状态,确保指定数量的 Pod 副本始终运行。 |
Services | 提供一种访问 Pod 的方式,通过固定的 IP 地址(ClusterIP)或 DNS 名称,为一组 Pod 提供统一的访问接口。 |
Volumes | 存储机制,允许数据持久化,即使 Pod 被删除或重新调度,数据也不会丢失。可以与外部存储系统集成。 |
Namespaces | 将集群资源划分为多个逻辑分区,允许不同用户、团队或项目在同一个物理集群中运行而不互相干扰。 |
ConfigMaps 和 Secrets | 存储配置数据和敏感信息的对象,供 Pods 使用,避免将信息硬编码在应用程序中。 |
Ingress | 管理外部访问到集群内服务的 HTTP 和 HTTPS 路由,提供 URL 路由、负载均衡、SSL 终止和名称基的虚拟托管。 |
Persistent Volumes (PV) | 集群中的一块预先配置好的存储,可以作为 Volume 使用。 |
Persistent Volume Claims (PVC) | 用户对持久存储的请求,允许申请特定大小和访问模式的存储。 |
Resource Quotas | 限制一个 Namespace 中所有 Pods 可以使用的资源总量,如 CPU 和内存。 |
LimitRanges | 为 Namespace 中的资源设置默认和最大资源限制,防止资源过度使用。 |
Horizontal Pod Autoscaler (HPA) | 根据 CPU 使用率或其他度量自动扩展 Pod 的数量。 |
Network Policies | 定义 Pod 之间网络通信的规则,控制哪些 Pod 可以相互通信。 |
-
PodController:是 Kubernetes 中用于管理一组 Pods 的控制器,确保这些 Pods 的数量符合用户指定的数量。
-
Deployment:一种 Pod 控制器,用于声明式地管理无状态应用的 Pods。它允许定义应用的期望状态,并且可以自动滚动更新应用。
-
CronJob:用于在给定的时间点或周期性地创建 Jobs,通常用于定时任务。
-
DaemonSet:确保所有(或某些)节点上都运行一个 Pod 的副本,通常用于运行集群存储、日志收集等系统守护进程。
-
ReplicaSet:确保指定数量的 Pod 副本始终运行,是 Deployment 的底层实现。
-
Job:用于创建一个或多个 Pods,并确保它们以某种方式完成(例如,成功退出)。Job 负责重启失败的 Pods。
-
StatefulSet:用于管理有状态应用的 Pods,与 Deployment 类似,但提供了额外的功能,如稳定的持久化存储和网络标识。
-
Service:定义了一种访问 Pod 的方式,无论这些 Pod 如何分布,通常通过一个固定的 IP 地址或 DNS 名称。
-
Pod:Kubernetes 中的最小部署单元,可以包含一个或多个容器。
-
Container:Pod 中的容器,通常是 Docker 容器,是运行应用程序的执行环境。
-
Volume:Kubernetes 中的存储机制,允许数据在 Pod 之间共享和持久化。
-
ConfigMap:用于存储配置数据的键值对,可以被 Pods 作为环境变量或文件挂载使用。
-
PVC (Persistent Volume Claim):用户对持久存储的请求,允许用户申请特定大小和访问模式的存储。
-
Secret:用于存储敏感信息,如密码、密钥等,可以被 Pods 作为环境变量或文件挂载使用。
1.2 YAML语法
1.2.1 YAML语法介绍
YAML(YAML Ain't Markup Language)是一种数据序列化格式,它被设计为易于人类阅读和编写,常用于配置文件和数据交换。以下是 YAML 语言的一些核心特性和语法规则:
-
大小写敏感:YAML 中的键(key)和值(value)的大小写是敏感的,这意味着
Key
和key
被视为不同的键。 -
缩进表示层级:YAML 使用缩进来定义数据结构的层级关系。相同层级的元素需要保持对齐。
-
空格缩进:YAML 严格使用空格进行缩进,不允许使用制表符(Tab)。不同版本的 YAML 对缩进的空格数有不同的要求,但通常是两个或四个空格。
-
对齐的灵活性:虽然不同层级的元素可以有不同的缩进空格数,但只要它们左对齐,就被认为是相同层级的。
-
注释:以
#
开头的行表示注释,直到行尾。 -
数据类型:
-
纯量(Scalar):表示单个的、不可再分的值,如字符串、数字、布尔值等。
1、布尔类型 (Boolean): c1: true 2、整型 (Integer): c2: 234 3、浮点型 (Float): c3: 3.14 4、Null类型 (Null): c4: ~ 5、日期类型 (Date): c5: 2018-02-17 日期格式遵循 ISO 8601 标准。 6、时间类型 (Time): c6: 2018-02-17T15:02:31+08:00 时间格式同样遵循 ISO 8601 标准,使用 T 连接日期和时间,最后是时区信息。 7、字符串类型 (String): c7: openlab c8: | # 使用管道符号表示字符串可以跨越多行 line1 line2
-
对象(Mapping):由键值对组成,也称为映射或字典。在 YAML 中,键值对通常用冒号(
:
)分隔。对象在 YAML 中由键值对组成,可以使用两种形式表示: 1、形式一(推荐):使用块格式,每个键值对占据一行,推荐用于清晰性和扩展性。 openlab: age: 15 address: Beijing 2、形式二(了解):使用紧凑格式,键值对写在一起,用花括号 {} 包围。这种格式在需要节省空间时可以使用,但在复杂的配置中可能导致可读性降低。 openlab: {age: 15, address: Beijing}
-
数组(Sequence):表示一组有序的值,也称为序列或列表。在 YAML 中,数组中的元素通常用短划线(
-
)开头。数组在 YAML 中是有序的元素集合,也可以使用两种形式表示: 1、形式一(推荐):使用块格式,数组中的每个元素都以短划线 - 开头,占据一行。 address: - 顺义 - 昌平 2、形式二(了解):使用紧凑格式,数组中的所有元素放在一个行内,用方括号 [] 包围。 address: [顺义, 昌平]
-
1.2.2 YAML 语法的最佳实践
-
缩进:在块格式中,每个层级的缩进应该是空格,通常是两个或四个空格,但必须保持一致。
-
简洁性:YAML 旨在简洁,块格式通常更易于阅读和维护,特别是在配置文件较大或包含复杂结构时。
-
注释:使用
#
添加注释,注释行不会被程序解析。 -
键值对分隔:键和值之间用冒号
:
分隔,后面通常跟一个空格。 -
多行字符串:如果字符串跨越多行,可以使用
|
或>
来表示,|
保留换行,>
折叠换行。 -
标点:YAML 中的标点符号很重要,确保正确使用短划线
-
来表示数组元素,使用连字符-
来开始列表项。 -
一致性:在同一个 YAML 文件中,尽量保持一致的格式,这样有助于提高可读性和减少错误。
小提示:
键值对分隔:在 YAML 中,键和值之间使用冒号
:
分隔。重要的是,冒号后面应该紧跟一个空格(如果键和值之间没有空格,某些 YAML 解析器可能会报错或产生不预期的结果)。key: value多文档分隔:YAML 允许一个文件中存在多个文档,每个文档之间使用
---
分隔。这在将多个配置块组合在同一个文件中时非常有用,例如,当你想要在同一个文件中定义多个 Kubernetes 资源时。--- apiVersion: v1 kind: Pod metadata: name: pod1 --- apiVersion: v1 kind: Pod metadata: name: pod2YAML 转 JSON 工具:您提供了一个在线工具的链接 https://www.json2yaml.com/convert-yaml-to-json这个工具可以帮助用户将 YAML 格式的配置转换为 JSON 格式,也可以用于验证 YAML 配置的书写是否正确。如果用户在尝试使用该工具时遇到问题,可能是因为网络连接问题,或者网站本身的问题。建议用户检查网络连接,并在必要时重试。
1.3 Kubernetes资源管理方式
-
命令式对象管理:通过
kubectl run
等命令直接操作 Kubernetes 资源。 -
命令式对象配置:通过
kubectl create
或kubectl patch
命令结合配置文件操作 Kubernetes 资源。 -
声明式对象配置:通过
kubectl apply
命令结合配置文件操作 Kubernetes 资源,这是推荐的做法,因为它允许跟踪资源的声明式状态。
管理方法 | 操作对象 | 适用环境 | 优点 | 缺点 |
---|---|---|---|---|
命令式对象管理 | 对象 | 测试 | - 简单,快速执行单个命令 - 适合快速迭代和临时变更 | - 无法审计和跟踪历史变更 - 不适合管理复杂的部署和应用状态 |
命令式对象配置 | 文件 | 开发 | - 可以审计和跟踪历史变更 - 方便管理和记录资源的期望状态 | - 项目规模大时,配置文件数量增多,管理变得复杂 |
声明式对象配置 | 目录 | 开发 | - 支持目录操作 - 允许系统跟踪资源的期望状态 | - 意外情况下,调试可能比较困难 |
1.3.1 命令式对象管理
-
kubectl
是 Kubernetes 集群的命令行工具,它允许用户与 Kubernetes 集群交互,执行各种资源管理和应用部署任务。以下是kubectl
命令的一些基本语法和使用示例:
1.3.1.1 基本语法
kubectl [command] [TYPE] [NAME] [flags]
-
command
:要执行的操作,如get
,create
,delete
,apply
等。 -
TYPE
:资源类型,如pods
,services
,deployments
等。 -
NAME
:资源的名称,可以是名称、标签选择器或资源文件路径。 -
flags
:可选的标志或配置项,用于修改命令的行为。
1.3.1.2 使用示例
-
获取资源信息:
[root@K8s-master ~]# kubectl run nginx --image=nginx:latest pod/nginx created [root@K8s-master ~]# kubectl get pods NAME READY STATUS RESTARTS AGE nginx 0/1 ContainerCreating 0 3s [root@K8s-master ~]# kubectl get pod nginx #显示指定一个pod信息 NAME READY STATUS RESTARTS AGE nginx 0/1 ContainerCreating 0 28s [root@K8s-master ~]# kubectl get pod nginx -o wide #-o wide选项获取Pod详细信息 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx 1/1 Running 0 2m45s 10.244.2.3 k8s-node-02 <none> <none> [root@K8s-master ~]# kubectl get pod nginx -o yaml #以yaml格式显示出来
-
创建资源:
[root@K8s-master ~]# kubectl create -f nginx-deployment.yaml
-
应用配置:
[root@K8s-master ~]# kubectl apply -f nginx-deployment.yaml
1.3.1.3 资源类型
[root@K8s-master ~]# kubectl api-resources
资源分类 | 资源名称 | 缩写 | 资源作用 |
---|---|---|---|
集群级别资源 | nodes | no | 集群组成部分 |
namespaces | ns | 隔离 Pod | |
Pod资源 | pods | po | 装载容器 |
Pod资源控制器 | replicationcontrollers | rc | 控制 Pod 资源 |
replicasets | rs | 控制 Pod 资源 | |
deployments | deploy | 控制 Pod 资源,用于无状态应用 | |
daemonsets | ds | 控制 Pod 资源,确保所有(或某些)节点上运行 Pod 的副本 | |
jobs | 控制 Pod 资源,用于批处理作业 | ||
cronjobs | cj | 控制 Pod 资源,用于定时任务 | |
horizontalpodautoscalers | hpa | 控制 Pod 资源,根据 CPU 使用率自动扩展 Pod 数量 | |
statefulsets | sts | 控制 Pod 资源,用于有状态应用 | |
服务发现资源 | services | svc | 统一 Pod 对外接口,提供服务发现 |
ingress | ing | 统一 Pod 对外接口,管理外部访问到集群内服务的路由 | |
存储资源 | volumeattachments | 存储资源 | |
persistentvolumes | pv | 存储资源,集群中的一块预先配置好的存储 | |
persistentvolumeclaims | pvc | 存储资源,用户对持久存储的请求 | |
配置资源 | configmaps | cm | 配置资源,存储配置数据的键值对 |
secrets | 配置资源,存储敏感信息,如密码、密钥等 |
1.3.1.4 kubectl命令参数
[root@K8s-master ~]# kubectl --help
1.3.1.4.1 基本命令
命令 | 翻译 | 描述 |
---|---|---|
create | 创建 | 从文件或标准输入创建资源 |
expose | 暴露 | 将复制控制器、服务、部署或 Pod 暴露为一个新的 Kubernetes 服务 |
run | 运行 | 在集群上运行特定的镜像 |
set | 设置 | 对对象设置特定功能 |
explain | 解释 | 获取资源的文档 |
get | 获取 | 显示一个或多个资源 |
edit | 编辑 | 在服务器上编辑资源 |
delete | 删除 | 通过文件名、标准输入、资源和名称或标签选择器删除资源 |
[root@K8s-master ~]# kubectl explain --help #一层一层的查看
1.3.1.4.2 部署命令
命令 | 翻译 | 描述 |
---|---|---|
rollout | 推出 | 管理资源的 rollout |
scale | 扩展 | 为部署、副本集或复制控制器设置新的尺寸 |
autoscale | 自动扩展 | 自动扩展部署、副本集、有状态集或复制控制器 |
1.3.1.4.3 集群管理命令
命令 | 翻译 | 描述 |
---|---|---|
certificate | 证书 | 修改证书资源 |
cluster-info | 集群信息 | 显示集群信息 |
top | 资源使用 | 显示资源(CPU/内存)使用情况 |
cordon | 隔离 | 将节点标记为不可调度 |
uncordon | 解除隔离 | 将节点标记为可调度 |
drain | 排空 | 为维护准备排空节点 |
taint | 污点 | 更新一个或多个节点上的污点 |
1.3.1.4.4 故障排查和调试命令
命令 | 翻译 | 描述 |
---|---|---|
describe | 描述 | 显示特定资源或资源组的详细信息 |
logs | 日志 | 打印 Pod 中容器的日志 |
attach | 连接 | 连接到正在运行的容器 |
exec | 执行 | 在容器中执行命令 |
port-forward | 端口转发 | 将一个或多个本地端口转发到 Pod |
proxy | 代理 | 运行到 Kubernetes API 服务器的代理 |
cp | 复制 | 复制文件和目录到容器中或从容器中复制 |
auth | 授权 | 检查授权 |
debug | 调试 | 为故障排查工作负载和节点创建调试会话 |
1.3.1.4.5 高级命令
命令 | 翻译 | 描述 |
---|---|---|
diff | 差异 | 对比实时版本和将要应用的版本 |
apply | 应用 | 通过文件名或标准输入将配置应用到资源 |
patch | 补丁 | 更新资源的字段 |
replace | 替换 | 通过文件名或标准输入替换资源 |
wait | 等待 | 实验性:等待一个或多个资源上的特定条件 |
kustomize | 自定义 | 从目录或 URL 构建 kustomization 目标 |
1.3.1.4.6 设置命令
命令 | 翻译 | 描述 |
---|---|---|
label | 标签 | 更新资源上的标签 |
annotate | 注解 | 更新资源上的注解 |
completion | 补全 | 输出指定 shell(bash、zsh 或 fish)的 shell 完成代码 |
1.3.1.4.7 其他命令
命令 | 翻译 | 描述 |
---|---|---|
alpha | Alpha | Alpha 功能中的命令 |
api-resources | API 资源 | 打印服务器上支持的 API 资源 |
api-versions | API 版本 | 打印服务器上支持的 API 版本,形式为 "group/version" |
config | 配置 | 修改 kubeconfig 文件 |
plugin | 插件 | 提供与插件交互的实用工具 |
version | 版本 | 打印客户端和服务器版本信息 |
1.3.1.5 基本命令使用示例
[root@K8s-master ~]# kubectl get ns #获取命名空间 NAME STATUS AGE default Active 2d kube-node-lease Active 2d kube-public Active 2d kube-system Active 2d [root@K8s-master ~]# kubectl create ns dev #创建一个名称为dev的名称空间 namespace/dev created [root@K8s-master ~]# kubectl get ns NAME STATUS AGE default Active 2d dev Active 4s kube-node-lease Active 2d kube-public Active 2d kube-system Active 2d [root@K8s-master ~]# kubectl run test --image nginx -n dev #在dev命名空间中创建了一个名test的Pod pod/test created [root@K8s-master ~]# kubectl get pod -n dev -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES test 1/1 Running 0 42s 10.244.2.4 k8s-node-02 <none> <none> [root@K8s-master ~]# kubectl delete pod test -n dev #删除pod pod "test" deleted [root@K8s-master ~]# kubectl delete ns dev #删除名称空间 namespace "dev" deleted
1.3.2 命令式对象配置
1.3.2.1 查看apiVersion版本
[root@K8s-master ~]# kubectl explain namespace.apiVersion
KIND: Namespace
VERSION: v1
FIELD: apiVersion <string>
DESCRIPTION:
APIVersion defines the versioned schema of this representation of an
object. Servers should convert recognized schemas to the latest internal
value, and may reject unrecognized values. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
1.3.2.2 编写TAML文件创建命名空间
[root@K8s-master ~]# vim nginxpod.yml --- apiVersion: v1 kind: Namespace metadata: name: dev [root@K8s-master ~]# kubectl create -f nginxpod.yml namespace/dev created [root@K8s-master ~]# kubectl get ns NAME STATUS AGE default Active 2d1h dev Active 7s kube-node-lease Active 2d1h kube-public Active 2d1h kube-system Active 2d1h
1.3.2.3 编写TAML文件创建Pod
[root@K8s-master ~]# kubectl explain Pod #查帮助 kubectl explain Pod.metadata #一层一层的看 kubectl explain Pod.spec [root@K8s-master ~]# vim pod.yml --- apiVersion: v1 kind: Pod metadata: name: nginxpod namespace: dev spec: containers: - name: nginx-containers image: nginx:1.17.1 [root@K8s-master ~]# kubectl create -f pod.yml pod/nginxpod created [root@K8s-master ~]# kubectl get pod -n dev -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginxpod 1/1 Running 0 2m1s 10.244.2.6 k8s-node-02 <none> <none> [root@K8s-master ~]# kubectl describe pod nginxpod -n dev #查看详细信息 Name: nginxpod Namespace: dev Priority: 0 Node: k8s-node-02/192.168.110.23 Start Time: Mon, 06 May 2024 15:37:42 +0800 Labels: <none> Annotations: <none> Status: Running IP: 10.244.2.6 IPs: IP: 10.244.2.6 Containers: nginx-containers: Container ID: containerd://289c686267b373fe722c6f6c43a922b5bfae1732cb73208e0d0a4c8fc910daa3 Image: nginx:1.17.1 Image ID: docker.io/library/nginx@sha256:b4b9b3eee194703fc2fa8afa5b7510c77ae70cfba567af1376a573a967c03dbb Port: <none> Host Port: <none> State: Running Started: Mon, 06 May 2024 15:38:48 +0800 Ready: True Restart Count: 0 Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-vnk9w (ro) Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: kube-api-access-vnk9w: Type: Projected (a volume that contains injected data from multiple sources) TokenExpirationSeconds: 3607 ConfigMapName: kube-root-ca.crt ConfigMapOptional: <nil> DownwardAPI: true QoS Class: BestEffort Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s node.kubernetes.io/unreachable:NoExecute op=Exists for 300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 2m42s default-scheduler Successfully assigned dev/nginxpod to k8s-node-02 Normal Pulling 2m41s kubelet Pulling image "nginx:1.17.1" Normal Pulled 96s kubelet Successfully pulled image "nginx:1.17.1" in 1m4.92839306s Normal Created 96s kubelet Created container nginx-containers Normal Started 96s kubelet Started container nginx-containers [root@K8s-master ~]# kubectl delete -f nginxpod.yml #删除 namespace "dev" deleted
总结:命令式对象配置的方式操作资源,可以简单的认为:命令 + yaml配置文件(里面是命令需要的各种参数)
1.3.3 声明式对象配置
声明式对象配置是 Kubernetes 中的一种资源管理方法,它允许用户通过声明资源的期望状态来配置系统。这种方法与命令式对象配置形成对比,其中命令式配置侧重于执行特定的操作来达到某种状态。声明式配置的核心概念如下:
-
声明资源的期望状态:用户通过 YAML、JSON 或其他格式的配置文件来描述资源的期望状态,而不是指定如何达到该状态的具体步骤。
-
使用 kubectl apply:使用
kubectl apply -f <filename>
命令来应用配置文件中定义的资源状态。如果资源已经存在,kubectl apply
将更新资源以匹配配置文件中的描述;如果资源不存在,它将创建新的资源。 -
资源版本控制:声明式配置利用 Kubernetes 的资源版本控制机制(通过
metadata.resourceVersion
字段)来确保一致性和避免冲突。当用户尝试应用一个旧的或过时的配置时,系统会检测到版本不匹配并拒绝应用,从而避免潜在的冲突。 -
幂等性:声明式配置是幂等的,这意味着多次应用相同的配置文件将保持资源状态不变,不会导致意外的错误或副作用。
-
自动化处理:Kubernetes 系统会自动处理配置文件中声明的状态,无需用户介入。这包括创建、更新、删除和滚动更新资源。
-
记录和审计:由于声明式配置通过配置文件记录资源的期望状态,它便于审计和记录资源变更历史。
[root@K8s-master ~]# kubectl apply -f nginxpod.yml namespace/dev created [root@K8s-master ~]# kubectl apply -f pod.yml pod/nginxpod created [root@K8s-master ~]# vim pod.yml #更改文件 --- apiVersion: v1 kind: Pod metadata: name: nginxpod namespace: dev spec: containers: - name: nginx-containers image: nginx [root@K8s-master ~]# kubectl apply -f pod.yml #会重新配置,如果是create必须先删除 pod/nginxpod configured
-
创建资源:如果资源不存在,
kubectl apply
会根据 YAML 文件中的定义来创建资源。这与kubectl create
命令的功能相似。 -
更新资源:如果资源已经存在,
kubectl apply
会将资源更新为 YAML 文件中定义的状态。这与kubectl patch
命令的功能相似,但kubectl apply
会更全面地更新资源,包括所有字段,而不仅仅是指定的字段。
1.3.4 再node节点上运行kubectl
[root@K8s-node-01 ~]# kubectl get pod #正常是无法运行的 The connection to the server localhost:8080 was refused - did you specify the right host or port? #只需将master点的 ~/.kube/ 目录(Kubernetes 配置目录)复制到node节点上 [root@K8s-master ~]# scp -r ~/.kube/ K8s-node-02:~ [root@K8s-master ~]# scp -r ~/.kube/ K8s-node-02:~ [root@K8s-node-01 ~]# kubectl get pod NAME READY STATUS RESTARTS AGE nginx 1/1 Running 0 69m
1.3.5 推荐管理方式
1.3.5.1 创建/更新资源
-
声明式对象配置:使用
kubectl apply -f XXX.yaml
命令来创建或更新资源。这种方法允许你通过 YAML 文件来定义资源的期望状态,然后 Kubernetes 集群会根据这些定义来创建或更新资源。
1.3.5.2 删除资源
-
命令式对象配置:使用
kubectl delete -f XXX.yaml
命令来删除资源。这种方法允许你直接在命令行中指定要删除的资源,而无需定义资源的期望状态。
1.3.5.3 查询资源
-
命令式对象管理:使用
kubectl get
或kubectl describe
命令来查询资源的状态。这些命令允许你直接在命令行中查看资源的当前状态,而无需定义资源的期望状态。
更多推荐
所有评论(0)