【问题标题】:Google cloud Kubernetes deployment error: Field is immutable谷歌云 Kubernetes 部署错误:字段不可变
【发布时间】:2019-11-18 06:21:56
【问题描述】:

从这个主题Can't use Google Cloud Kubernetes substitutions 解决问题后(yaml 文件都在那里,不要再次复制粘贴它们)我遇到了一个新问题。因为上一个题目有正确答案,所以制作一个新题目。

第 2 步:运行:kubectl apply -f deployment.yaml
第 2 步:警告: kubectl apply 应该用于由 kubectl 创建的资源 创建 --save-config 或 kubectl apply
第 2 步:部署 “myproject”无效:spec.selector:无效值: v1.LabelSelector{MatchLabels:map[string]string{"app":"myproject", “运行”:“我的项目”}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}:字段为 不可变

我检查了类似的问题,但找不到任何相关内容。

另外,这个错误是否可能与升级 App Engine -> Docker -> Kubernetes 有关?我在每一步都创建了有效的配置。也许现在有些东西是被创造出来的并且是不可变的?在这种情况下我该怎么办?

还有一点,也许这很重要,它说“kubectl apply 应该用于由 kubectl create --save-config 或 kubectl apply 创建的资源”(您可以在上面看到),但正在执行

kubectl create deployment myproject --image=gcr.io/myproject/myproject

给我这个

来自服务器的错误(已存在):deployments.apps "myproject" 已存在

这实际上是预期的,但同时与上述警告有争议(至少从我的角度来看)

有什么想法吗?

kubectl version的输出

Client Version: version.Info{Major:"1", Minor:"14", GitVersion:"v1.14.7", GitCommit:"8fca2ec50a6133511b771a11559e24191b1aa2b4", GitTreeState:"clean", BuildDate:"2019-09-18T14:47:22Z", GoVersion:"go1.12.9", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"13+", GitVersion:"v1.13.11-gke.14", GitCommit:"56d89863d1033f9668ddd6e1c1aea81cd846ef88", GitTreeState:"clean", BuildDate:"2019-11-07T19:12:22Z", GoVersion:"go1.12.11b4", Compiler:"gc", Platform:"linux/amd64"}



当前 YAML 文件:

steps:
  - name: 'gcr.io/cloud-builders/docker'
    entrypoint: 'bash'
    args: [
      '-c',
      'docker pull gcr.io/$PROJECT_ID/myproject:latest || exit 0'
    ]
  - name: 'gcr.io/cloud-builders/docker'
    args: [
      'build',
      '-t',
      'gcr.io/$PROJECT_ID/myproject:$BRANCH_NAME-$COMMIT_SHA',
      '-t',
      'gcr.io/$PROJECT_ID/myproject:latest',
      '.'
    ]
  - name: 'gcr.io/cloud-builders/kubectl'
    args: [ 'apply', '-f', 'deployment.yaml' ]
    env:
      - 'CLOUDSDK_COMPUTE_ZONE=<region>'
      - 'CLOUDSDK_CONTAINER_CLUSTER=myproject'
  - name: 'gcr.io/cloud-builders/kubectl'
    args: [
      'set',
      'image',
      'deployment',
      'myproject',
      'myproject=gcr.io/$PROJECT_ID/myproject:$BRANCH_NAME-$COMMIT_SHA'
    ]
    env:
      - 'CLOUDSDK_COMPUTE_ZONE=<region>'
      - 'CLOUDSDK_CONTAINER_CLUSTER=myproject'
      - 'DB_PORT=5432'
      - 'DB_SCHEMA=public'
      - 'TYPEORM_CONNECTION=postgres'
      - 'FE=myproject'
      - 'V=1'
      - 'CLEAR_DB=true'
      - 'BUCKET_NAME=myproject'
      - 'BUCKET_TYPE=google'
      - 'KMS_KEY_NAME=storagekey'
timeout: 1600s
images:
  - 'gcr.io/$PROJECT_ID/myproject:$BRANCH_NAME-$COMMIT_SHA'
  - 'gcr.io/$PROJECT_ID/myproject:latest

deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myproject
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myproject
  template:
    metadata:
      labels:
        app: myproject
    spec:
      containers:
        - name: myproject
          image: gcr.io/myproject/github.com/weekendman/{{repo name here}}:latest
          ports:
            - containerPort: 80

【问题讨论】:

  • 您是否正在尝试为 kubernetes 重新使用应用引擎配置?它们是完全不同的平台。你在哪里设置“应用程序”字段?您是在尝试创建新部署还是更新现有部署?这里发生了太多事情......
  • @TravisWebb,我对所有这些 DevOps 都是新手。我从更简单的东西开始,比如应用引擎,然后检查了 Docker 容器部署。然后开始阅读 Kubernetes。是的,它们完全不同,我理解。但我认为如果没有 GCloud + Docker 部署过程,那么容易理解 Kubernetes 文档并不容易。 “部署”yaml 文件中有“app”字段。如果您能解释配置中的多余内容,我很乐意尝试。
  • @WeekendMan 我试图重现它,但我没有收到任何问题。请提供一些信息。 1. 您使用的是 GCP(计算引擎 > VM 实例)还是 GKE?我问是因为 GKE 有点落后于最新版本的 kubernetes。提供$ kubectl version 的输出,因为部署 api:apps/v1 是在 kubernetes 1.16 中引入的,如果您要使用早期版本,问题可能在其他地方。 2. 是否可以发布您的原始 YAML 和新的?
  • @TravisWebb,是的,它是 GKE,而不是计算引擎。但我在 GKE 之前使用过计算引擎来处理 Docker 容器。然后我开始更改配置以使用 GKE。我用“kubectl version”输出更新了主题。您可以通过第一段中的链接看到以前的 yaml 文件(这也是我的问题)。我完全按照第一个(也是唯一一个)答案和评论对其进行了更改。我只是想让这个问题尽可能简短而不是重复细节,不是因为我很懒=)谢谢你的帮助!
  • @WeekendMan 之前和之后没有看到 YAML 很难说。它可能与特定的 apiVersions、添加/删除某些字段、拼写错误等有关。

标签: kubernetes google-cloud-platform


【解决方案1】:

从 apps/v1 开始,Deployment 的标签选择器在创建后是不可变的。

摘自 Kubernetes 的 document:

注意:在 API 版本 apps/v1 中,Deployment 的标签选择器是 创建后不可变。

因此,您可以先删除此部署,然后再应用它。

【讨论】:

  • 我刚刚在谷歌云面板中查看了部署列表,它是空的,应该是这样吗?
  • 这在生产中不是一个可行的选择,我们不希望任何停机时间,这就是我们选择滚动部署的原因,如何解决这个问题?
  • 您仍然可以进行滚动部署,只要您不更改部署的标签选择器。标签选择器将部署连接到它生成的 pod,因此,当您更改它时,它如何知道曾经属于它的 pod?因此,如果您确定要更改标签选择器,您可以使用新名称开始部署,然后将您的服务指向这个新部署,这是我能想到的影响最小的方式。
【解决方案2】:

MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable,因为它与您之前的部署不同。

尝试使用kubectl get deployment -o yaml 查看现有部署。我怀疑现有的 yaml 有不同的 matchLables 节。

具体来说,您的文件有:

    matchLabels:
      app: myproject

我的猜测是kubectl get deployment -o yaml 的输出,而有一些不同的东西,比如:

    matchLabels:
      app: old-project-name

    matchLabels:
      app: myproject
      version: alpha

新部署不能更改matchLabels 节,因为它是不可变的。新部署中的该节必须与旧部署相匹配。如果你想改变它,你需要删除带有kubectl delete deployment myproject的旧部署。

注意:如果您在生产环境中这样做,您的应用将有一段时间不可用。 (关于如何在生产中执行此操作的更长时间的讨论在这里没有用处。)

【讨论】:

    猜你喜欢
    • 2018-09-14
    • 1970-01-01
    • 1970-01-01
    • 2021-07-30
    • 2019-08-30
    • 2021-06-19
    • 2019-11-25
    • 2019-04-26
    • 2020-01-21
    相关资源
    最近更新 更多