<p>I'm in the process of moving web services from one Kubernetes cluster to another. The goal is to do that without service interruption.</p>
<p>This is difficult with cert-manager and HTTP challenges, because cert-manager on the new cluster can only retrieve a certificate once the DNS entry points to that cluster. However, if I switch the DNS entry to the new cluster, clients will potentially talk to the new cluster <em>before</em> a valid certificate has been generated. This is like a chicken-and-egg problem.</p>
<p>How do I move the cert-manager certificates to the new cluster, so that it already has the certs once I make the DNS switch?</p>

theDmi
<p>Certificates are stored in Kubernetes secrets. Cert-manager will pick up existing secrets instead of creating new ones, if the secret matches the ingress object.</p>
<p>So assuming that the ingress object looks the same on both clusters, and that the same namespace is used, copying the secret is as simple as this:</p>
<pre class="lang-sh prettyprint-override"><code>kubectl --context OLD_CLUSTER -n NAMESPACE get secret SECRET_NAME --output yaml \
  | kubectl --context NEW_CLUSTER -n NAMESPACE apply -f -
</code></pre>
<ul>
<li>Replace <code>OLD_CLUSTER</code> and <code>NEW_CLUSTER</code> with the kubectl context names of the respective clusters (see <code>kubectl config get-contexts</code>).</li>
<li>Replace <code>SECRET_NAME</code> with the name of the secret where the certificate is stored. This name can be found in the ingress.</li>
<li>Replace <code>NAMESPACE</code> with the actual namespace that you're using.</li>
</ul>
<p>The command simply exports the secret in YAML format, and then uses <code>kubectl apply -f</code> to create the same resource in the new cluster.</p>
<p>Once the ingress is in place on the new cluster, you can verify that the cert works by using <code>openssl s_client</code>:</p>
<pre class="lang-sh prettyprint-override"><code>openssl s_client -connect CLUSTER_IP:443 -servername SERVICE_DNS_NAME 
</code></pre>
<p>Again, replace <code>CLUSTER_IP</code> and <code>SERVICE_DNS_NAME</code> accordingly.</p>
