<p>Consider this partial k8s deployment manifest for a basic rest application called <code>myapp</code></p>
<pre><code>spec:
  replicas: 1
     ...
      containers:
        name: myapp
        image: us.gcr.io/my-org/myapp.3
      ...
      resources:
        limits:
          cpu: 1000m
          memory: 1.5Gi

</code></pre>
<p>We store incremental builds in Google Container Registry (GCR) eg (<code>myapp.1, myapp.2, myapp.3</code>). In the current setup, our CI system (Jenkins) does the following:</p>
<ul>
<li>Docker builds new image <code>myapp.4</code> and uploads to GCR</li>
<li>Runs <code>kubectl set image myapp.4</code> to update the deployment.</li>
</ul>
<p>This works well for most deploys, but what about changes to the deployment manifest itself?  For example, if we changed <code>resource &gt; cpu</code> to 1500m, we'd now have to manually run <code>kubectl apply</code>.  <strong>This step needs to be automated, which brings me to my point:</strong> instead of using <code>kubectl set image</code> couldn't the build system itself just run <code>kubectl apply</code> each time?  When is it appropriate to use <code>kubectl set image</code> vs. <code>kubectl apply</code> in a CI/CD pipeline?</p>
<p>As long as the new image were provided, wouldn't <code>kubectly apply</code> handle both image updates AND other config changes?  If so, what are the pros/cons against just <code>kubcetl set image</code>?</p>
<p>PS - our deploys are simple and mainly rely on single replica and 100% uptime is not necessarily required.</p>

Adam Hughes
<p>With a <code>kubectl set image</code>, you only patch the image deployed in your deployment. To patch the other values (CPU, memory, replicas,...) you can use other commands like <code>path</code> or <code>set repiclas</code></p>
<p>The problem is that you loose the consistency with your original YAML definition. If your cluster crash and you want to recreate one, you won't have the exact same deployment because your YAML file will be outdated (the &quot;patches&quot; won't be known)</p>
<hr />
<p>With <code>kubectl apply</code> you overwrite the existing control plane config and you set the exact content of your YAML. It's more consistent and it's a common practice when you are in GitOps mode.</p>
<hr />
<p>Which one to use? All depends on what you need and what you want to achieve. I prefer the <code>kubectl apply</code> mode for its consistency and its replayability, but it's up to you!</p>
