<p>I had a project that wanted to update the DNS configuration of Pod with Operator,</p>
<pre><code>get dns message
get matched pod
modify:
    pod.Spec.DNSConfig = CRD_SPEC
    pod.Spec.DNSPolicy = corev1.DNSNone
client.Update(ctx,&amp;pod)
</code></pre>
<p>But when I implemented it, I got the following error:</p>
<pre><code> ERROR   controller-runtime.manager.controller.dnsinjection      Reconciler error        {&quot;reconciler group&quot;: &quot;xxxx&quot;, &quot;reconciler kind&quot;: &quot;xxxxx&quot;, &quot;name&quot;: &quot;dnsinjection&quot;, &quot;namespace&quot;: &quot;default&quot;, &quot;error&quot;: &quot;Pod \&quot;busybox\&quot; 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:         &amp;0,\n  \tPreemptionPolicy: nil,\n  \tDNSConfig: &amp;core.PodDNSConfig{\n  \t\tNameservers: []string{\n  \t\t\t\&quot;1.2.3.4\&quot;,\n- \t\t\t\&quot;0.0.0.0\&quot;,\n  \t\t},\n  \t\tSearches: []string{\&quot;ns1.svc.cluster-domain.example\&quot;, \&quot;my.dns.search.suffix\&quot;},\n  \t\tOptions:  []core.PodDNSConfigOption{{Name: \&quot;ndots\&quot;, Value: &amp;\&quot;2\&quot;}, {Name: \&quot;edns0\&quot;}},\n  \t},\n  \tReadinessGates:   nil,\n  \tRuntimeClassName: nil,\n  \t... // 3 identical fields\n  }\n&quot;}
</code></pre>
<p><code>DNSConfig</code> and <code>DNSPoicy</code> fields are not declared to be unable to be <strong>updated</strong> in the source code, so why did the update fail?</p>
<p>I got the same error with <code>kubect edit pod busybox</code> and <code>kubectl apply -f modifyed_pod.yml(add DNSConfig)</code> command.</p>
<p>I would appreciate it if you could tell me how to solve it.</p>

<p>As the message says, Kubernetes <a href="https://kubernetes.io/docs/concepts/workloads/pods/#pod-update-and-replacement" rel="nofollow noreferrer">does not support updating most pod's fields directly</a>:</p>
<blockquote>
<p>Kubernetes doesn't prevent you from managing Pods directly. It is possible to update some fields of a running Pod, in place. However, Pod update operations like  <a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#patch-pod-v1-core" rel="nofollow noreferrer"><code>patch</code></a>, and  <a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#replace-pod-v1-core" rel="nofollow noreferrer"><code>replace</code></a>  have some limitations:</p>
<ul>
<li>Most of the metadata about a Pod is immutable. For example, you cannot change the  <code>namespace</code>,  <code>name</code>,  <code>uid</code>, or  <code>creationTimestamp</code>  fields; the  <code>generation</code>  field is unique. It only accepts updates that increment the field's current value.</li>
<li>If the  <code>metadata.deletionTimestamp</code>  is set, no new entry can be added to the  <code>metadata.finalizers</code>  list.</li>
<li>Pod updates may not change fields other than  <code>spec.containers[*].image</code>,  <code>spec.initContainers[*].image</code>,  <code>spec.activeDeadlineSeconds</code>  or  <code>spec.tolerations</code>. For  <code>spec.tolerations</code>, you can only add new entries.</li>
</ul>
</blockquote>
<p><em>Why is that?</em></p>
<p>Pods in Kubernetes <a href="https://kubernetes.io/docs/concepts/workloads/pods/#working-with-pods" rel="nofollow noreferrer">are designed as relatively ephemeral, disposable entities</a>:</p>
<blockquote>
<p>You'll rarely create individual Pods directly in Kubernetes—even singleton Pods. This is because Pods are designed as relatively ephemeral, disposable entities. When a Pod gets created (directly by you, or indirectly by a <a href="https://kubernetes.io/docs/concepts/architecture/controller/" rel="nofollow noreferrer">controller</a>), the new Pod is scheduled to run on a <a href="https://kubernetes.io/docs/concepts/architecture/nodes/" rel="nofollow noreferrer">Node</a> in your cluster. The Pod remains on that node until the Pod finishes execution, the Pod object is deleted, the Pod is <em>evicted</em> for lack of resources, or the node fails.</p>
</blockquote>
<p><a href="https://kubernetes.io/docs/concepts/workloads/pods/#using-pods" rel="nofollow noreferrer">Kubernetes assumes that for managing pods and doing any updates you should use</a> a <a href="https://kubernetes.io/docs/concepts/workloads/" rel="nofollow noreferrer">workload resources</a> instead of creating pods directly:</p>
<blockquote>
<p>Pods are generally not created directly and are created using workload resources. See  <a href="https://kubernetes.io/docs/concepts/workloads/pods/#working-with-pods" rel="nofollow noreferrer">Working with Pods</a>  for more information on how Pods are used with workload resources.
Here are some examples of workload resources that manage one or more Pods:</p>
<ul>
<li><a href="https://kubernetes.io/docs/concepts/workloads/controllers/deployment/" rel="nofollow noreferrer">Deployment</a></li>
<li><a href="https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/" rel="nofollow noreferrer">StatefulSet</a></li>
<li><a href="https://kubernetes.io/docs/concepts/workloads/controllers/daemonset" rel="nofollow noreferrer">DaemonSet</a></li>
</ul>
</blockquote>
<p>You can easily update most fields in workload resources definition and it will work properly. Keep in mind that it won't edit any existing pods - <a href="https://kubernetes.io/docs/concepts/workloads/pods/#pod-templates" rel="nofollow noreferrer">it will delete the currently running pods with old configuration and start the new ones - Kubernetes will make sure that this process goes smoothly</a>:</p>
<blockquote>
<p>Modifying the pod template or switching to a new pod template has no direct effect on the Pods that already exist. If you change the pod template for a workload resource, that resource needs to create replacement Pods that use the updated template.</p>
</blockquote>
<blockquote>
<p>For example, the StatefulSet controller ensures that the running Pods match the current pod template for each StatefulSet object. If you edit the StatefulSet to change its pod template, the StatefulSet starts to create new Pods based on the updated template. Eventually, all of the old Pods are replaced with new Pods, and the update is complete.</p>
</blockquote>
<blockquote>
<p>Each workload resource implements its own rules for handling changes to the Pod template. If you want to read more about StatefulSet specifically, read  <a href="https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/#updating-statefulsets" rel="nofollow noreferrer">Update strategy</a>  in the StatefulSet Basics tutorial.</p>
</blockquote>
<p>So based on all above information I'd suggest to switch to workload resource, for example <a href="https://kubernetes.io/docs/concepts/workloads/controllers/deployment/" rel="nofollow noreferrer">deployment</a>:</p>
<blockquote>
<p>A  <em>Deployment</em>  provides declarative updates for  <a href="https://kubernetes.io/docs/concepts/workloads/pods/" rel="nofollow noreferrer">Pods</a>  and  <a href="https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/" rel="nofollow noreferrer">ReplicaSets</a>.</p>
</blockquote>
<p>For example - right now I have pod with below definition:</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: v1
kind: Pod
metadata:
  name: busybox
  namespace: default
spec:
  containers:
  - image: busybox:1.28
    command:
      - sleep
      - &quot;9999999&quot;
    imagePullPolicy: IfNotPresent
    name: busybox
  restartPolicy: Always
  hostNetwork: true
  dnsPolicy: ClusterFirstWithHostNet
</code></pre>
<p>When I try to run <code>kubectl edit pod busybox</code> command to change <code>dnsPolicy</code> I have the same error as you.
However, If I changed to deployment with the same pod definition:</p>
<pre class="lang-yaml prettyprint-override"><code>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
        - &quot;9999999&quot;
        imagePullPolicy: IfNotPresent
        name: busybox
      restartPolicy: Always
      hostNetwork: true
      dnsPolicy: ClusterFirstWithHostNet
</code></pre>
<p>Then if I run <code>kubectl edit deploy busybox-deployment</code> and change <code>dnsPolicy</code> field I will  get a new pod with new configuration (the old pod will be automatically deleted).</p>
<p>Keep in mind, if you want to stick with direct pod definition, you can always just delete pod and apply a new, modified yaml as you tried (<code>kubectl delete pod {your-pod-name} &amp;&amp; kubectl apply -f {modified.yaml}</code>). It will work properly.</p>
<p>Also check:</p>
<ul>
<li><a href="https://stackoverflow.com/questions/41583672/kubernetes-deployments-vs-statefulsets">Kubernetes Deployments vs StatefulSets</a></li>
<li><a href="https://kubernetes.io/docs/concepts/workloads/controllers/" rel="nofollow noreferrer">Workload Resources</a></li>
<li><a href="https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/" rel="nofollow noreferrer">Pod Lifecycle</a></li>
</ul>
