在使用kubectl apply操作workload产生的非预期行为:修订间差异

来自三线的随记
无编辑摘要
无编辑摘要
 
(未显示同一用户的2个中间版本)
第1行: 第1行:
先创建一个普通的deployment
=== 简述 ===
 
* kubectl apply 对于之前本身就是 apply 或者 create --save-config 产生的resources,可能存在非预期行为( kubectl.kubernetes.io/last-applied-configuration ),例如修改原有的workload probe settings(bug at 1.18.x), 或者修改hostAlias(修改原有的 hostalias 的 ip)
 
=== hostalias复现: ===
先通过<code>kubectl create -f</code> 创建一个普通的deployment(不要用 <code>kubectl apply -f</code> 来创建,不然就绕过这个bug了~)
  apiVersion: apps/v1
  apiVersion: apps/v1
  kind: Deployment
  kind: Deployment
第7行: 第12行:
   name: yaml-test
   name: yaml-test
  spec:
  spec:
   replicas: 1
   replicas:0
   selector:
   selector:
     matchLabels:
     matchLabels:
第19行: 第24行:
     metadata:
     metadata:
       labels:
       labels:
        sit.k8s.io/app: yaml-test
         sit.k8s.io/app: yaml-test
         sit.k8s.io/app: yaml-test
       name: yaml-test
       name: yaml-test
第52行: 第56行:
       restartPolicy: Always
       restartPolicy: Always


 
然后修改一下hostAliases的值(例如下面这样),执行<code>kubectl apply -f  xxx.yaml --dry-run=server -oyaml</code>
然后修改一下hostAliases的值,执行kubectl apply -f  xxx.yaml --dry-run=server -oyaml
  apiVersion: apps/v1
  apiVersion: apps/v1
  kind: Deployment
  kind: Deployment
第61行: 第64行:
   name: yaml-test
   name: yaml-test
  spec:
  spec:
   replicas: 1
   replicas: 0
   selector:
   selector:
     matchLabels:
     matchLabels:
第73行: 第76行:
     metadata:
     metadata:
       labels:
       labels:
        sit.k8s.io/app: yaml-test
         sit.k8s.io/app: yaml-test
         sit.k8s.io/app: yaml-test
       name: yaml-test
       name: yaml-test
第105行: 第107行:
       dnsPolicy: ClusterFirst
       dnsPolicy: ClusterFirst
       restartPolicy: Always
       restartPolicy: Always




会发现apply以后的结果hostAliases字段非预期(1.1.1.8直接被追加了进去,而不是替换)
会发现apply以后的结果hostAliases字段非预期(1.1.1.8直接被追加了进去,而不是替换)
[[文件:Kubectl apply merge.png|无框|400x400像素]]


或者一开始使用apply创建资源,然后删除kubectl.kubernetes.io/last-applied-configuration: ,再修改ip,再apply
或者一开始使用apply创建资源,然后删除kubectl.kubernetes.io/last-applied-configuration: ,再修改ip,再apply


如果一开始是用kubectl apply -f xxxx创建资源,然后用apply -f更新资源,则不会复现
如果一开始是用<code>kubectl apply -f xxxx</code>创建资源,然后用<code>apply -f</code>更新资源,则不会复现
 
==== 这个也是跟k8s apply的实现方式有关系 ====
主要跟 kubectl.kubernetes.io/last-applied-configuration 这个annotation有关系
 
[https://kubernetes.io/docs/tasks/manage-kubernetes-objects/declarative-config/#how-apply-calculates-differences-and-merges-changes How apply calculates differences and merges changes]


这个也是跟k8s apply的实现方式有关系
[[文件:Kubectl apply patch strategy.png|无框|900x900像素]]





2025年5月7日 (三) 18:44的最新版本

简述

  • kubectl apply 对于之前本身就是 apply 或者 create --save-config 产生的resources,可能存在非预期行为( kubectl.kubernetes.io/last-applied-configuration ),例如修改原有的workload probe settings(bug at 1.18.x), 或者修改hostAlias(修改原有的 hostalias 的 ip)

hostalias复现:

先通过kubectl create -f 创建一个普通的deployment(不要用 kubectl apply -f 来创建,不然就绕过这个bug了~)

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    sit.k8s.io/app: yaml-test
  name: yaml-test
spec:
  replicas:0
  selector:
    matchLabels:
      sit.k8s.io/app: yaml-test
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        sit.k8s.io/app: yaml-test
      name: yaml-test
    spec:
      hostAliases:
      - hostnames:
        - testaaaa.com
        - testbbb.com
        ip: 1.1.1.7
      containers:
      - image: 192.168.150.181/test/nginx-2048:latest
        imagePullPolicy: IfNotPresent
        name: yaml-test
        readinessProbe:
            httpGet:
              path: /
              port: 80
              scheme: HTTP
            initialDelaySeconds: 10
            timeoutSeconds: 1
            periodSeconds: 10
            successThreshold: 1
            failureThreshold: 3
        resources:
          limits:
            cpu: "1"
            memory: "64Mi"
          requests:
            cpu: 64m
            memory: "64Mi"
      dnsPolicy: ClusterFirst
      restartPolicy: Always

然后修改一下hostAliases的值(例如下面这样),执行kubectl apply -f xxx.yaml --dry-run=server -oyaml

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    sit.k8s.io/app: yaml-test
  name: yaml-test
spec:
  replicas: 0
  selector:
    matchLabels:
      sit.k8s.io/app: yaml-test
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        sit.k8s.io/app: yaml-test
      name: yaml-test
    spec:
      hostAliases:
      - hostnames:
        - testaaaa.com
        - testbbb.com
        ip: 1.1.1.8
      containers:
      - image: 192.168.150.181/test/nginx-2048:latest
        imagePullPolicy: IfNotPresent
        name: yaml-test
        readinessProbe:
            httpGet:
              path: /
              port: 80
              scheme: HTTP
            initialDelaySeconds: 10
            timeoutSeconds: 1
            periodSeconds: 10
            successThreshold: 1
            failureThreshold: 3
        resources:
          limits:
            cpu: "1"
            memory: "64Mi"
          requests:
            cpu: 64m
            memory: "64Mi"
      dnsPolicy: ClusterFirst
      restartPolicy: Always


会发现apply以后的结果hostAliases字段非预期(1.1.1.8直接被追加了进去,而不是替换)

或者一开始使用apply创建资源,然后删除kubectl.kubernetes.io/last-applied-configuration: ,再修改ip,再apply

如果一开始是用kubectl apply -f xxxx创建资源,然后用apply -f更新资源,则不会复现

这个也是跟k8s apply的实现方式有关系

主要跟 kubectl.kubernetes.io/last-applied-configuration 这个annotation有关系

How apply calculates differences and merges changes


Related article: K8s的一些小坑或者bug简要记录