在使用kubectl apply操作workload产生的非预期行为

来自三线的随记
Admin讨论 | 贡献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简要记录