使用 nomos 命令行工具

nomos 命令行工具是 Config Sync 的可选工具,可用于获取 Config Sync 的状态和可信来源的同步状态。nomos 工具会为您提供以下命令:

命令 使用情况
nomos status 检查 Config Sync 状态
nomos vet 检查可信来源是否存在错误
nomos hydrate 查看可信来源中的所有配置
nomos bugreport 创建错误报告
nomos migrate 从 ConfigManagement 对象迁移到 RootSync
nomos init 初始化分层可信来源

前提条件

在使用 nomos 工具与集群进行交互之前,Config Sync 必须已安装在目标集群上。您还必须安装和配置 kubectl 命令行工具。如果您正在与 Google Kubernetes Engine 集群交互,请确保也安装 gke-gcloud-auth-plugin

nomos 工具支持预览和验证 Kustomize 配置和 Helm 图表。如需使用此功能,请在本地工作站中安装 KustomizeHelm。如果您的可信来源仅包含完全渲染的配置,则 Kustomize 和 Helm 是可选的。

安装 nomos 工具

nomos 工具是通过 Go 代码编译的二进制文件,您可以在本地安装,例如在工作站或笔记本电脑上安装。

安装 Config Sync 时,系统不会包含 nomos 工具。您可以通过安装 Google Cloud CLI 来安装 nomos 工具。如果您使用 Cloud Shell,则系统会预安装 Google Cloud CLI。

如果您没有 Google Cloud CLI,我们建议您使用 gcloud components install nomos 安装 nomos 工具。使用 Google Cloud CLI 安装 nomos 工具后,您可以使用 gcloud components updatenomos 工具更新到最新版本。

如需了解安装 nomos 工具的其他方法,请参阅下载

基本用法

对于基本命令语法,请使用 --help 参数:

nomos --help

nomos 工具会从可信来源的本地克隆读取数据。使用 --path 标志指定可信来源的顶级位置。默认情况下,--path 设置为 .(当前目录)。例如:

nomos --path=PATH_TO_SOURCE vet

检查 Config Sync 状态

您可以使用 nomos status 命令监控所有注册集群上的 Config Sync 状态。对于每个集群,nomos status 会报告上次应用于集群的提交的哈希以及尝试应用最近的任何更改时发生的任何错误。

您还可以使用 nomos status 检查由 Config Sync 管理的资源是否已准备就绪。nomos status 会在输出的 Managed resources 部分的 STATUS 列中报告各项资源的状态。

以下示例展示了 nomos status 命令可能报告的一些不同条件:

nomos status

输出示例:

MANAGED_CLUSTER_1
  --------------------
  <root>   git@github.com:foo-corp/acme@main
  SYNCED   f52a11e4
  Managed resources:
   NAMESPACE   NAME                                                                   STATUS
               k8snoexternalservices.constraints.gatekeeper.sh/no-internet-services   Current
               namespace/hello                                                        Current

MANAGED_CLUSTER_2
  --------------------
  <root>   git@github.com:foo-corp/acme@main
  PENDING  9edf8444

MANAGED_CLUSTER_3
  --------------------
  <root>   git@github.com:foo-corp/acme@main
  ERROR    f52a11e4
  Error:   KNV1021: No CustomResourceDefinition is defined for the resource in the cluster.

MANGED_CLUSTER_4
  --------------------
  NOT INSTALLED

MANAGED_CLUSTER_5
  --------------------
  <root>   git@github.com:foo-corp/acme/admin@main
  SYNCED   f52a11e4
  Managed resources:
   NAMESPACE   NAME                                                                   STATUS
                namespace/gamestore                                                   Current
                namespace/monitoring                                                  Current
   gamestore    reposync.configsync.gke.io/repo-sync                                  Current
   gamestore    rolebinding.rbac.authorization.k8s.io/gamestore-admin                 Current
   gamestore    rolebinding.rbac.authorization.k8s.io/gamestore-webstore-admin        Current
   monitoring   deployment.apps/prometheus-operator                                   Current
   monitoring   prometheus.monitoring.coreos.com/acm                                  Current
   monitoring   service/prometheus-acm                                                Current
   monitoring   service/prometheus-operator                                           Current
   monitoring   serviceaccount/prometheus-acm                                         Current
   monitoring   serviceaccount/prometheus-operator                                    Current
   monitoring   servicemonitor.monitoring.coreos.com/acm-service                      Current
  --------------------
  bookstore  git@github.com:foo-corp/acme/bookstore@v1
  SYNCED     34d1a8c8
  Managed resources:
   NAMESPACE   NAME                                 STATUS
   gamestore   configmap/store-inventory            Current
   gamestore   webstore.marketplace.com/gameplace   Current

在此输出中:

  • MANAGED_CLUSTER_1 已同步对可信来源的最新更改,并且所有托管资源的状态均为 Current。状态为 Current 表示资源的状态与所需状态匹配。
  • MANAGED_CLUSTER_2 仍在同步。
  • MANAGED_CLUSTER_3 具有阻止应用更改的错误。在此示例中,MANAGED_CLUSTER_3 具有错误 KNV1021,因为它缺少其他集群已安装的 CustomResourceDefinition (CRD)。
  • MANAGED_CLUSTER_4 未安装 Config Sync。
  • MANAGED_CLUSTER_5 正在从两个 Git 代码库同步。<root> 可信来源属于集群管理员,bookstore 可信来源可能属于应用开发团队。

代管资源状态

代管资源的状态可以是以下值之一:

  • InProgress:资源的实际状态尚未达到您在资源清单中指定的状态。此状态意味着资源协调尚未完成。新创建的资源通常以此状态开头,但 ConfigMap 等一些资源会立即变成 Current

  • Failed:将实际状态与所需状态进行协调的过程遇到错误或跟不上进度。

  • Current:资源的实际状态与所需状态匹配。协调过程被视为完成,直到所需状态或实际状态发生更改。

  • Terminating:正在删除资源。

  • NotFound:集群中不存在资源。

  • Unknown:Config Sync 无法确定资源的状态。

如需关闭显示资源级层状态的功能,请将 --resources=false 添加到 nomos status 命令。

关于上次同步的提交

nomos status 命令会在输出的 status.sync.commit 下显示已应用于集群的最新提交哈希。如需获取此值,请查询 RootSyncRepoSync 对象并查看 status.sync 字段。

例如,如需查询 RootSync 对象,请运行以下命令:

kubectl get rootsyncs.configsync.gke.io -n config-management-system root-sync -o yaml

输出示例:

apiVersion: configsync.gke.io/v1beta1
kind: RootSync
status:
  sync:
    commit: f1739af550912034139aca51e382dc50c4036ae0
    lastUpdate: "2021-04-20T00:25:01Z"

如需查询 RepoSync 对象,请运行以下命令:

kubectl get reposync.configsync.gke.io -n NAMESPACE repo-sync -o yaml

NAMESPACE 替换为您在其中创建命名空间可信来源的命名空间。

输出示例:

apiVersion: configsync.gke.io/v1beta1
kind: RepoSync
status:
  sync:
    commit: ed95b50dd918cf65d8908f7561cb8d8d1f179c2f
    lastUpdate: "2021-04-20T00:25:20Z"

此提交表示针对集群的最新提交。但是,每次提交并不会影响集群中的每个资源;如需查看特定资源的最新提交,请查询该特定资源并查看 metadata.annotations.configmanagement.gke.io/token。例如:

kubectl get clusterroles CLUSTER_ROLE_NAME -o yaml

CLUSTER_ROLE_NAME 替换为您要查询的集群角色的名称。

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  annotations:
    configmanagement.gke.io/token: ed95b50dd918cf65d8908f7561cb8d8d1f179c2f

nomos 状态标志

如需自定义 nomos status 命令,请添加以下标志:

标志 说明
--contexts 接受要在多集群命令中使用的上下文的逗号分隔列表。默认为所有上下文。如果没有任何上下文,则使用 ""。
-h--help nomos status 命令的帮助。
--namespace 接受字符串。使用 namespace 标志可将该命令限制为特定命名空间可信来源。如果未设置,则可获取所有来源。仅当您启用了从多个可信来源的同步时,此标志才可用。
--poll 使用 poll 标志可持续运行 nomos status,并让它定期重新输出状态表。例如 3s。如果不设置此标志,将运行 nomos status 一次
--resources 接受 truefalse。如果为 true,则 nomos status 会显示从多个可信来源同步时的根可信来源或命名空间可信来源的资源级状态。 默认值为 true
--timeout 连接到每个集群时的超时。默认值为 3s
--name 接受字符串。使用此标志过滤具有提供的名称的 Root Sync 和 Repo Sync。此标志可以与 namespace 标志同时使用。

所需权限

如果您是项目所有者,则您拥有 cluster-admin RBAC 角色,并且可以将 nomos status 命令用于您项目中的任何集群,而无需添加任何进一步的权限。如果您没有 cluster-admin 角色,则可以通过创建以下 ClusterRole 来使用 nomos status

  1. 创建名为 nomos-status-reader.yaml 的文件,并将以下 ClusterRole 复制到其中。您需要的规则因您是否使用 RootSync 和 RepoSync 对象而异。

    使用 RootSync 和 RepoSync 对象

    # nomos-status-reader.yaml
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: nomos-status-reader
    rules:
    - apiGroups: ["configsync.gke.io"]
      resources: ["reposyncs", "rootsyncs"]
      verbs: ["get"]
    - nonResourceURLs: ["/"]
      verbs: ["get"]
    

    不使用 RootSync 和 RepoSync 对象

    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: nomos-status-reader
    rules:
    - apiGroups: ["configmanagement.gke.io"]
      resources: ["configmanagements", "repos"]
      verbs: ["get", "list"]
    - nonResourceURLs: ["/"]
      verbs: ["get"]
    
  2. 应用 nomos-status-reader.yaml 文件:

    kubectl apply -f nomos-status-reader.yaml
    

检查可信来源是否存在错误

在将配置提交到可信来源之前,请使用 nomos vet 命令检查可信来源中配置的语法和有效性:

nomos vet

如果发现语法错误,nomos vet 命令会以非零状态退出,并将错误消息记录到 STDERR

nomos vet 标志

如需自定义 nomos vet 命令,请添加以下标志:

标志 说明
--clusters 接受要在多集群命令中使用的集群名称的逗号分隔列表。默认为所有集群。使用 "" 表示不指定任何集群。
-h--help nomos vet 命令的帮助。
--namespace 接受字符串。如果设置了此字段,则使用提供的名称验证可信来源是否作为命名空间可信来源。自动设置 --source-format=unstructured
--no-api-server-check 接受布尔值。如果为 true,则禁止与 API 服务器通信以免发现。如需详细了解此标志,请参阅服务器端验证部分。
--path 接受字符串。指向 Config Sync 可信来源根目录的路径。默认值为“.”。
--source-format 接受 hierarchyunstructured。如果为 hierarchy 或未设置,则验证可信来源是否作为分层可信来源。如果为 unstructured,则验证可信来源是否为 非结构化可信来源。如果您使用的是非结构化可信来源,则必须提供此标志。
--keep-output 接受布尔值。如果为 true,则呈现的输出将保存到您可以使用 --output 标志指定的位置。
--output 接受字符串。所呈现输出的路径。默认为 compiled 目录。如果 --keep-output 设置为 false,则此标志会被忽略。
--format 接受 yamljson。输出的格式。默认值为 yaml

服务器端验证

如果 nomos vet 命令无法确定类型是否带命名空间,则 nomos 工具将连接到 API 服务器。因为 nomos 工具默认了解核心的 Kubernetes 类型和 Config Sync CRD,所以只有在存在没有相应声明的 CRD 的 CR 时,它才会尝试连接到 API 服务器。在这种情况下,如果 API 服务器未应用 CRD,则 nomos vet 命令会返回错误 KNV1021。如需停用这项检查并抑制由于缺少 CRD 而导致的错误,请传递 --no-api- server-check 标志。

缓存 API 服务器元数据

您可以在 API 服务器上缓存 nomos vet 命令的数据,而不是禁止 API 服务器检查。如需缓存 api-resources,请完成以下步骤:

  1. 连接到包含可靠来源所需的所有 CRD 的集群。集群无需启用 Config Sync。
  2. 前往可信来源的 policyDir 目录。此目录与您在 ConfigManagement 或 RootSync 资源中指定的目录相同。
  3. 运行以下命令:kubectl api-resources > api-resources.txt。此命令会创建一个名为 api-resources.txt 的文件,其中包含 kubectl api-resources 的确切输出。

从现在起,在可信来源内运行 nomos vet 时便知道这些类型定义。如果 api-resources.txt 文件被移除或重命名,nomos vet 将无法找到该文件。如果 nomos vet 发现未在 api-resources.txt 中声明的类型的清单,它仍将尝试连接到集群(除非传递了 --no-api-server-check)。

api-resources.txt 文件仅影响 nomos 工具的工作方式。它不会以任何方式修改 Config Sync 的行为。

api-resources.txt 文件中可以有额外的条目,这些条目用于验证来源不是可信来源的类型。nomos vet 会导入定义,但不会对其执行任何操作。

更新 api-resources.txt

确保集群上拥有需要的所有 CRD 后,运行以下命令:

kubectl api-resources > api-resources.txt
api-resources 中的列标题不匹配

Kubernetes 1.20 版及更高版本会将名为 APIGROUP 的列替换为 APIVERSION。对于 nomos 1.16.1 版及更早版本,使用 api-resources.txt 会导致错误:

[1] KNV1064: unable to find APIGROUP column. Re-run "kubectl api-resources > api-resources.txt" in the root policy directory

为解决此问题,请手动将 api-resources.txt 中的 APIVERSION 替换回 APIGROUP

提交时自动检查是否存在语法错误

如果您提交的文件包含 JSON 或 YAML 错误,Config Sync 不会应用相应的更改。但是,您可以使用客户端服务器端钩子来防止这些类型的错误进入可信来源。

在预提交钩子中使用 nomos vet

您可以配置运行 nomos vet 命令的预提交钩子,以在您向代码库的本地 Git 克隆提交更改时检查是否存在语法错误。如果预提交钩子以非零状态退出,则表示 git commit 操作失败。

如需将 nomos vet 命令作为预提交钩子运行,请修改可信来源中的 .git/hooks/pre-commit 文件(请注意,.git. 字符开头)。您可能需要手动创建该文件。将 nomos vet 命令添加到脚本中的新行。--path 参数是可选的。

nomos vet --path=/path/to/repo

确保 pre-commit 文件可执行:

chmod +x .git/hooks/pre-commit

现在,当您在可信来源的克隆中运行 git commit 命令时,nomos vet 会自动运行。

.git/ 目录的内容不由可信来源本身跟踪,并且不能提交到同一位置的可信来源。您可以在可信来源中为 Git 钩子创建目录,使用可信来源的人员可以将钩子复制到其本地克隆中的相应位置。

在服务器端钩子中使用 nomos vet

Git 提供了一种执行 git push 操作期间在服务器(而不是客户端)上运行检查的机制。如果检查失败,git push 也会失败。客户端无法绕过这些服务器端钩子。配置服务器端钩子的方法取决于您的 Git 服务器的托管方式。如需了解详情,请访问以下某个链接,或查看 Git 托管服务的文档。

查看可信来源中的所有配置

您可以使用 nomos hydrate 命令查看每个注册集群上的可信来源的组合内容。

如果您在没有使用选项的情况下运行 nomos hydrate,则该命令会在当前工作目录中创建一个 compiled/ 目录。在该目录中,系统会为每个注册集群创建一个子目录,该子目录包含 Operator 将应用到集群的完全解析的配置。

此命令还可以使用 compiled/ 目录中的内容,将分层可信来源转换为一个或多个非结构化可信来源

nomos hydrate 标志

如需自定义 nomos hydrate 命令,请添加以下标志:

标志 说明
--clusters 接受集群名称的逗号分隔列表。使用此标志将输出限制为单个集群或集群列表。默认为所有集群。使用 "" 表示不指定任何集群。
--flat 如果启用,则将所有输出输出到单个文件。如果要模拟 nomos view 的行为,请使用此标志。
-h--help nomos hydrate 命令的帮助。
--format 接受 yamljson。输出的格式。默认值为 yaml
--no-api-server-check 接受布尔值。如果为 true,则禁止与 API 服务器通信以免发现。如需详细了解此标志,请参阅服务器端验证部分。
--output 接受字符串。要将混合配置写入到的位置。默认值为 compiled 目录。如果未启用 --flat,则将每个资源清单写入单独的文件。如果已启用 --flat,则写入包含所有资源清单的单个文件。
--path 接受字符串。指向 Config Sync 可信来源根目录的路径。默认值为“.”。
--source-format 接受 hierarchyunstructured。如果为 hierarchy 或未设置,则验证可信来源是否作为分层可信来源。如果为 unstructured,则验证可信来源是否为 非结构化可信来源。如果您使用的是非结构化可信来源,则必须提供此标志。

创建错误报告

如果您在使用 Config Sync 时遇到问题,需要 Google Cloud 支持团队的帮助,您可以使用 nomos bugreport 命令向他们提供有价值的调试信息。您可以将此命令用于单个可信来源和多个仓库。

nomos bugreport

此命令会生成一个带有时间戳的 ZIP 文件,其中包含有关在 kubectl 上下文中设置的 Kubernetes 集群的信息。该文件包含来自 Config Sync Pod 的日志,但不包含来自与 Config Sync 同步的资源的信息。 如需详细了解 zip 文件的内容,请参阅 nomos bugreport 参考文档

限制

如果任何单个文件超过 1GiB,则 nomos bugreport 命令会失败并生成不完整的 zip 文件。这种情况通常是由于日志文件较大。

下表列出了导致日志文件过大的最常见原因以及解决方法:

原因 建议采取的操作
提高了日志详细程度 通过log level overrides降低日志详细程度
超大物体 取消管理大型对象或缩减其大小
很多对象 将代码库拆分为多个代码库
控制器对战 解决冲突

从 ConfigManagement 对象迁移到 RootSync 对象

您可以运行 nomos migrate 命令,从 ConfigManagement 对象迁移到 RootSync 对象,以启用 RootSyncRepoSync API。该命令在 1.10.0 版及更高版本的 nomos 工具中可用。

nomos migrate 支持通过试运行来预览迁移过程。

nomos migrate 会直接修改集群上的 ConfigManagement 对象。为避免通过 nomos migrate 所做的更改被还原,请确保 ConfigManagement 对象未签入可靠来源。

nomos migrate --contexts=KUBECONFIG_CONTEXTS --dry-run

如果试运行结果看起来正常,您可以使用 nomos migrate 迁移 ConfigManagement 对象:

nomos migrate --contexts=KUBECONFIG_CONTEXTS

输出类似于以下内容:

--------------------
Enabling the multi-repo mode on cluster "my_managed_cluster-1" ...
- A RootSync object is generated and saved in "/tmp/nomos-migrate/my_managed_cluster-1/root-sync.yaml".
- The original ConfigManagement object is saved in "/tmp/nomos-migrate/my_managed_cluster-1/cm-original.yaml".
- The ConfigManagement object is updated and saved in "/tmp/nomos-migrate/my_managed_cluster-1/cm-multi.yaml".
- Resources for the multi-repo mode have been saved in a temp folder. If the migration process is terminated, it can be recovered manually by running the following commands:
  kubectl apply -f /tmp/nomos-migrate/my_managed_cluster-1/cm-multi.yaml && \
  kubectl wait --for condition=established crd rootsyncs.configsync.gke.io && \
  kubectl apply -f /tmp/nomos-migrate/my_managed_cluster-1/root-sync.yaml.
- Updating the ConfigManagement object ....
- Waiting for the RootSync CRD to be established ....
- The RootSync CRD has been established.
- Creating the RootSync object ....
- Waiting for the reconciler-manager Pod to be ready ....
-   Haven't detected running Pods with the label selector "app=reconciler-manager".
-   Haven't detected running Pods with the label selector "app=reconciler-manager".
-   Haven't detected running Pods with the label selector "app=reconciler-manager".
- The reconciler-manager Pod is running.
- Waiting for the root-reconciler Pod to be ready ....
-   Haven't detected running Pods with the label selector "configsync.gke.io/reconciler=root-reconciler".
-   Haven't detected running Pods with the label selector "configsync.gke.io/reconciler=root-reconciler".
-   Haven't detected running Pods with the label selector "configsync.gke.io/reconciler=root-reconciler".
- The root-reconciler Pod is running.
- The migration process is done. Please check the sync status with `nomos status`.

Finished migration on all the contexts. Please check the sync status with `nomos status`.

回滚到先前的配置

如果您需要在使用 nomos migrate 执行迁移后回滚,请应用原始 ConfigManagement 对象。nomos migrate 会将原始 ConfigManagement 对象保存到文件中,并将名称输出到终端。该文件的名称格式为 /tmp/nomos-migrate/CURRENT_CONTEXT/cm-original.yaml

要回滚到先前的配置,请复制 cm-original.yaml 的文件路径,并将该文件应用到您的集群:

kubectl apply -f CM_ORIGINAL_PATH

nomos migrate 标志

如需自定义 nomos migrate 命令,请添加以下标志:

标志 说明
--connect-timeout 接受时长。连接到每个集群时的超时时长。默认为 3s
--contexts 接受要在多集群环境中使用的上下文的逗号分隔列表。默认为当前上下文。对所有上下文使用 "all"
--dry-run 接受布尔值。如果为 true,则仅会显示迁移输出。
-h--help nomos migrate 命令的帮助。
--wait-timeout 接受时长。等待 Kubernetes 资源的条件为 true 时的超时时长。默认值为 10m

初始化分层可信来源

如果您使用的是非结构化可信来源,则可以任意组织可信来源。如果您使用的是分层可信来源,则需要运行 nomos init 命令来初始化分层目录:

nomos init

这样即可创建分层可信来源(包括 system/cluster/namespaces/ 目录)的基本目录结构。

nomos init 标志

如需自定义 nomos init,请添加以下标志:

标志 说明
--force 写入目录(即使非空),覆盖冲突的文件
-h--help nomos init 命令的帮助。
--path 接受字符串。用于可信来源的根目录。默认值为 "."

问题排查

在 Linux 上执行 nomos 命令时,您可能会看到以下错误:

failed to create client configs: while getting config path: failed to get current user: user: Current not implemented on linux/amd64

如需解决此问题,请创建一个 USER 环境变量:

export USER=$(whoami)

后续步骤