While working with API Connect in setting up a two data center high available deployment in OpenShift, I learned a helpful trick to copy a secret containing certificates from the active cluster to the passive one.
While I often work with OpenShift and Kubernetes, it is rare for me to find differences between the two CLIs, and I happen to use either interchangeably. Still, in this particular case, the
oc extract
command that we will be using below is unique to the OpenShift CLI, while thekubectl
CLI does not have it.
The install activity for the clusters requires that the same certificate (stored as a kubernetes secret) should be present in both clusters, the instructions read:
...
3. Export ingress-ca secret as a yaml from DC1:
kubectl -n <namespace> get secret ingress-ca -o yaml > ingress-ca.yaml
4. Edit the ingress-ca.yaml file to remove all labels, annotations, creationTimestamp, resourceVersion, uid, and selfLink.
5. Copy the ingress-ca.yaml from DC1 to DC2 and apply that file on DC2:
kubectl -n <namespace> apply -f ingress-ca.yaml
...
I decided to automate this and create bash scripts that will allow the team to deploy APIC clusters with this configuration. Still, the manual step of editing the ingres-ca.yaml
seem like it was going to be a whole sed
and awk
adventure (that I did not have the time to take) or will have to add a dependency to a library like y2j (which by the way looks very interesting). Could it be a better way?
The better (and simpler) way
In the first cluster, we use the extract
command of the OpenShift CLI to write the secret contents into a temporary folder. After that, we create the secret with those files using the create secret
command.
Here is a code snippet to do so:
mkdir -p tmp
# In the first cluster extract the content of the secret into a tmp folder
~ oc extract secret/ingress-ca --to=./tmp --confirm -n <namespace>
ca.crt
tls.crt
tls.key
# In the second cluster (make sure you are authenticated in this cluster and not the other ones)
~ oc create secret generic ingress-ca --from-file=tls.crt=./tmp/tls.crt --from-file=tls.key=./tmp/tls.key --from-file=ca.crt=./tmp/ca.crt -n <namespace>
secret/ingress-ca created
rm -rf ./tmp
You could even do the two commands in a single one if you were to move a secret from one namespace to another. However, since we want to switch to the second cluster to execute the secret creation, I believe it is best to keep it separated as it provides more clarity.
To conclude, there is no need to export the secret to a yaml, manually edit that yaml to remove all the autogenerated values, and later import it into the second cluster. We should always look for less error-prone approaches.