在此上下文中不允许映射值

Posted

技术标签:

【中文标题】在此上下文中不允许映射值【英文标题】:mapping values are not allowed in this context 【发布时间】:2017-11-03 19:07:30 【问题描述】:

我是 YAML 格式和 kubernetes 方面的新手。

以下是一个dep_prom.yml文件。

---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  labels:
    name: prometheus-deployment
  name: prometheus
  #namespace: prometheus
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: prometheus
    spec:
      containers:
      - image: prom/prometheus:master
        name: prometheus
        command:
        - "/bin/prometheus"
        args:
        - "-config.file=/etc/prometheus/prometheus.yml"
        - "-storage.local.path=/prometheus"
        - "-storage.local.retention=24h"
        ports:
        - containerPort: 9090
          protocol: TCP
        volumeMounts:
        - mountPath: "/prometheus"
          name: data
        - mountPath: "/etc/prometheus"
          name: config-volume
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
          limits:
            cpu: 500m
            memory: 2500Mi
      volumes:
      - name: data
        hostPath:
          path: /data/prometheus
      - name: config-volume
        configMap:
          name: prometheus
      nodeSelector: westporch-kubeminion-1
        kubernetes.io/hostname: 10.0.24.52
---

但是...当我执行 kubectl create -f dep_prom.yml

错误:将 YAML 转换为 JSON 时出错:yaml:第 47 行:此上下文中不允许映射值

第 47 行是 nodeSelector: westporch-kubeminion-1

我认为 YAML 文件格式是正常的。

是什么导致了这个错误?

【问题讨论】:

删除westporch-kubeminion-1nodeSelector 是一个映射,而不是单个值字段。 【参考方案1】:

您表示您认为 YAML 格式是正常的,但事实并非如此。这是由第一个文档末尾的行引起的 YAML 错误,从 kubernetes.io/hostname 开始相对于它之前的缩进。因为这些都是键值对行(即块样式映射的项目对)而不是

      nodeSelector: westporch-kubeminion-1
        kubernetes.io/hostname: 10.0.24.52

您需要这样做:

      nodeSelector: westporch-kubeminion-1
      kubernetes.io/hostname: 10.0.24.52

但可能nodeSelector 需要一个映射作为参数,而不是它现在拥有的标量westporch-kubeminion-1

      nodeSelector:
        kubernetes.io/hostname: 10.0.24.52

此错误可能会掩盖文件中的第二个错误,具体取决于 kubernetes 的宽松程度。 --- 是指令结束标记,由于指令是可选的,它可以出现在 YAML 文档的开头。示例底部的那个表示新文档的开始。解决第一个错误后,您可能会收到有关基于此的单个文档的警告。 (文档结束标记由三个点组成:... 位于行首,后跟空格。

当然,您所做的任何更改都应确认 kubernetes 的预期,但上述流本身作为 YAML 显然是无效的。

【讨论】:

【参考方案2】:

在我的例子中,错误的错误原因是 yaml 中的第一行是空的。

遇到此错误时 - 我强烈建议将 yaml 粘贴到 YAML Linters(例如 this 一个)中,这在某些情况下有助于更快地识别问题。

【讨论】:

【参考方案3】:

大多数情况下,当您遇到这样的错误时(笼统地说)是因为:-

1)。 yaml 文件中的语法错误(在您的情况下不是)。使用YAML linter 确保您的语法正确。 (感谢@rtmy 的回答,我现在在这里包括YAML Linter。)

2)。或者就像错误所说的“在这种情况下不允许映射值”。这意味着您在 yaml 中使用的键/值可能在语法上是正确的,但在语义上可能不正确。

例如,在您的情况下,上下文是属于“apiversion: extensions/v1beta1”的“部署”,它期望节点选择器如下所示:-

nodeSelector:
  kubernetes.io/hostname: 10.0.24.52

理想情况下,您不应该像上面那样使用 IP,而是像这样使用键值对:- topologyKey: failure-domain.beta.kubernetes.io/zone 或者在您的情况下,它可以是这样的:- kubernetes.io/hostname: zone-a-node

【讨论】:

【参考方案4】:

有时在 yaml 文件中,如果您使用 : 等特殊字符,则需要将整行放在单引号中 '

从 gitlab 文档中查看这个示例 https://docs.gitlab.com/ee/ci/yaml/README.html#script

有时,脚本命令必须用单引号或双引号括起来。例如,包含冒号 (:) 的命令必须用单引号 (') 括起来。 YAML 解析器需要将文本解释为字符串而不是“键:值”对。* 例如,此脚本使用冒号:*

job:
  script:
    - curl --request POST --header 'Content-Type: application/json' "https://gitlab/api/v4/projects"

要被视为有效的 YAML,您必须将整个命令用单引号括起来。如果命令已使用单引号,则应尽可能将其更改为双引号 ("):

job:
  script:
    - 'curl --request POST --header "Content-Type: application/json" "https://gitlab/api/v4/projects"'

【讨论】:

【参考方案5】:

就我而言,问题归结为 YML 文件的缩进(格式)。我被指向一条与错误无关的行。我不得不将文件与我拥有的另一个项目进行比较。 https://www.kubeval.com 工具对我发现并解决问题后的验证很有用。

【讨论】:

【参考方案6】:

正如大多数人所提到的,yaml 文件中有几个问题,yaml 文件通常很难识别问题,

幸运的是,它可以使用 yaml lint 等工具轻松识别,您可能不需要社区的帮助。

安装它

npm install -g yaml-lint

您可以通过以下方式进行验证

E:\>yamllint docker-compose.yaml
√ YAML Lint successful.

【讨论】:

【参考方案7】:

如前所述,nodeSelector 不能有这样的值。就是指定一个键值对的映射。你可以阅读更多关于具体用法here。例如,nodeSelector 的正确用法可能是:

    nodeSelector:
       disktype: ssd

【讨论】:

【参考方案8】:

默认情况下,'kubernetes.io/hostname' 是 well known label,其中包含节点的名称而不是其 IP 地址。这可以通过运行$ kubectl get nodes --show-labels 来检查。因此,我建议进行以下更改:

  nodeSelector: 
    kubernetes.io/hostname: westporch-kubeminion-1

【讨论】:

【参考方案9】:

不是对问题的直接回答,但它可能会帮助其他人收到相同的错误消息:

在我的例子中,我在构建管道中进行令牌替换,以在 YAML 文件中设置 Docker 映像标记。而且我正在读取要替换的值,因此将其设置为空字符串。

所以替换的结果不是这样:

my_image_name:1.0.0

我实际上得到的是:

my_image_name:

这被解释为没有值的 YAML 映射或字典键,因此出现错误消息。

【讨论】:

以上是关于在此上下文中不允许映射值的主要内容,如果未能解决你的问题,请参考以下文章

如何调试 Helm 图表错误,例如“将 YAML 转换为 JSON 时出错:yaml:在此上下文中不允许映射值”?

此上下文中不允许使用 YAML 映射值

检查是不是存在 PLS-00405:在此上下文中不允许子查询

在此上下文中不允许使用自动填充字段名称“邮政编码”

错误(12,1):PL/SQL:语句被忽略错误(12,15):PLS-00405:在此上下文中不允许子查询

绑定属性消息在此上下文中不支持值 mtom