[英]How to update DNS configuration of K8S Pod
我有一个项目想用 Operator 更新 Pod 的 DNS 配置,
get dns message
get matched pod
modify:
pod.Spec.DNSConfig = CRD_SPEC
pod.Spec.DNSPolicy = corev1.DNSNone
client.Update(ctx,&pod)
但是当我实现它时,出现以下错误
ERROR controller-runtime.manager.controller.dnsinjection Reconciler error {"reconciler group": "xxxx", "reconciler kind": "xxxxx", "name": "dnsinjection", "namespace": "default", "error": "Pod \"busybox\" is invalid: spec: Forbidden: pod updates may not change fields other than `spec.containers[*].image`, `spec.initContainers[*].image`, `spec.activeDeadlineSeconds` or `spec.tolerations` (only additions to existing tolerations)\n core.PodSpec{\n \t... // 21 identical fields\n \tPriority: &0,\n \tPreemptionPolicy: nil,\n \tDNSConfig: &core.PodDNSConfig{\n \t\tNameservers: []string{\n \t\t\t\"1.2.3.4\",\n- \t\t\t\"0.0.0.0\",\n \t\t},\n \t\tSearches: []string{\"ns1.svc.cluster-domain.example\", \"my.dns.search.suffix\"},\n \t\tOptions: []core.PodDNSConfigOption{{Name: \"ndots\", Value: &\"2\"}, {Name: \"edns0\"}},\n \t},\n \tReadinessGates: nil,\n \tRuntimeClassName: nil,\n \t... // 3 identical fields\n }\n"}
源代码中没有声明DNSConfig和DNSPoicy字段无法更新,那么为什么更新失败呢?
我在使用kubect edit pod busybox
和kubectl apply -f modifyed_pod.yml(add DNSConfig)
命令时遇到了同样的错误
如果您能告诉我如何解决它,我将不胜感激。
正如消息所说,Kubernetes 不支持直接更新大多数 pod 的字段:
Kubernetes 不会阻止您直接管理 Pod。 可以就地更新正在运行的 Pod 的某些字段。 但是,诸如
patch
和replace
类的 Pod 更新操作有一些限制:
- 大多数关于 Pod 的元数据是不可变的。 例如,您不能更改
namespace
、name
、uid
或creationTimestamp
字段;generation
字段是唯一的。 它只接受增加字段当前值的更新。- 如果设置了
metadata.deletionTimestamp
,则不能将新条目添加到metadata.finalizers
列表中。- Pod 更新不能更改除
spec.containers[*].image
、spec.initContainers[*].image
、spec.activeDeadlineSeconds
或spec.tolerations
。 对于spec.tolerations
,您只能添加新条目。
这是为什么?
Kubernetes 中的 Pod 被设计为相对短暂的、一次性的实体:
您很少会直接在 Kubernetes 中创建单独的 Pod——即使是单例 Pod。 这是因为 Pod 被设计为相对短暂的、一次性的实体。 当 Pod 被创建时(直接由您创建,或由控制器间接创建),新 Pod 将被安排在集群中的节点上运行。 Pod 将保留在该节点上,直到 Pod 完成执行、删除 Pod 对象、由于缺乏资源而驱逐Pod 或节点失败。
Kubernetes 假设为了管理 Pod 和执行任何更新,您应该使用工作负载资源而不是直接创建 Pod:
Pod 通常不是直接创建的,而是使用工作负载资源创建的。 有关如何将 Pod 与工作负载资源一起使用的更多信息,请参阅使用 Pod 。 以下是管理一个或多个 Pod 的工作负载资源的一些示例:
您可以轻松更新工作负载资源定义中的大多数字段,它会正常工作。 请记住,它不会编辑任何现有的 pod——它将删除当前运行的具有旧配置的 pod 并启动新的 pod——Kubernetes 将确保此过程顺利进行:
修改 Pod 模板或切换到新的 Pod 模板对已经存在的 Pod 没有直接影响。 如果您更改工作负载资源的 Pod 模板,则该资源需要创建使用更新模板的替换 Pod。
例如,StatefulSet 控制器确保正在运行的 Pod 与每个 StatefulSet 对象的当前 Pod 模板匹配。 如果您编辑 StatefulSet 以更改其 pod 模板,StatefulSet 将开始基于更新的模板创建新的 Pod。 最终,所有旧 Pod 都替换为新 Pod,更新完成。
每个工作负载资源都实现自己的规则来处理对 Pod 模板的更改。 如果您想详细了解 StatefulSet,请阅读 StatefulSet 基础教程中的更新策略。
因此,基于以上所有信息,我建议切换到工作负载资源,例如部署:
Deployment为Pods和ReplicaSets提供声明性更新。
例如 - 现在我有以下定义的 pod:
apiVersion: v1
kind: Pod
metadata:
name: busybox
namespace: default
spec:
containers:
- image: busybox:1.28
command:
- sleep
- "9999999"
imagePullPolicy: IfNotPresent
name: busybox
restartPolicy: Always
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
当我尝试运行kubectl edit pod busybox
命令来更改dnsPolicy
我dnsPolicy
了与您相同的错误。 但是,如果我更改为具有相同 pod 定义的部署:
apiVersion: apps/v1
kind: Deployment
metadata:
name: busybox-deployment
labels:
app: busybox
spec:
replicas: 1
selector:
matchLabels:
app: busybox
template:
metadata:
labels:
app: busybox
spec:
containers:
- image: busybox:1.28
command:
- sleep
- "9999999"
imagePullPolicy: IfNotPresent
name: busybox
restartPolicy: Always
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
然后,如果我运行kubectl edit deploy busybox-deployment
并更改dnsPolicy
字段,我将获得一个具有新配置的新 pod(旧 pod 将被自动删除)。
请记住,如果您想坚持使用直接 pod 定义,您可以随时删除 pod 并在尝试时应用一个新的、修改过的 yaml( kubectl delete pod {your-pod-name} && kubectl apply -f {modified.yaml}
)。 它会正常工作。
还要检查:
就像消息说您无法更新 pod 的 DNS 配置: Forbidden: pod updates may not change fields other than spec.containers[*].image, spec.initContainers[*].image
。
如果要将 DNS 配置注入所有 Pod,则需要在创建 Pod 之前添加配置。 将MutatingAdmissionWebhook视为解决此问题的一种方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.