Sealed Secrets on connectVM Cloud Kubernetes[πŸ”—](#sealed-secrets-on-brand-name-kubernetes "Permalink to this headline") ======================================================================================================================= Sealed Secrets improve security of our Kubernetes deployments by enabling encrypted Kubernetes secrets. This allows to store such secrets in source control and follow GitOps practices of storing all configuration in code. In this article we will install tools to work with Sealed Secrets and demonstrate using Sealed Secrets on connectVM Cloud cloud. What We Are Going To Cover[πŸ”—](#what-we-are-going-to-cover "Permalink to this headline") --------------------------------------------------------------------------------------- > * Install the Sealed Secrets controller > * Install the **kubeseal** command line utility > * Create a sealed secret > * Unseal the secret > * Verify Prerequisites[πŸ”—](#prerequisites "Permalink to this headline") ------------------------------------------------------------- No. 1 **Account** You need a connectVM Cloud hosting account with access to the Horizon interface: . No. 2 **Understand Helm deployments** To install Sealed Secrets on Kubernetes cluster, we will use the appropriate Helm chart. The following article explains the procedure: [Deploying Helm Charts on Magnum Kubernetes Clusters on connectVM Cloud Cloud](Deploying-Helm-Charts-on-Magnum-Kubernetes-Clusters-on-connectVM-Cloud-Cloud.html.md) No. 3 **Kubernetes cluster** General explanation of how to create a Kubernetes cluster is here: [How to Create a Kubernetes Cluster Using connectVM Cloud connectVM Magnum](How-to-Create-a-Kubernetes-Cluster-Using-connectVM-Cloud-connectVM-Magnum.html.md) For new cluster, using the latest version of the cluster template is always recommended. This article was tested with Kubernetes 1.25. No. 4 **Access to cluster with kubectl** [How To Access Kubernetes Cluster Post Deployment Using Kubectl On connectVM Cloud connectVM Magnum](How-To-Access-Kubernetes-Cluster-Post-Deployment-Using-Kubectl-On-connectVM-Cloud-connectVM-Magnum.html.md) Step 1 Install the Sealed Secrets controller[πŸ”—](#step-1-install-the-sealed-secrets-controller "Permalink to this headline") --------------------------------------------------------------------------------------------------------------------------- In order to use Sealed Secrets we will first install the Sealed Secrets controller to our Kubernetes cluster. We can use Helm for this purpose and the first step is to download the Helm repository. To add the repo locally use the following command: ``` helm repo add sealed-secrets https://bitnami-labs.github.io/sealed-secrets ``` The next step is to install the SealedSecrets controller chart. We need to install it to the namespace **kube-system**. Note we also override the name of the controller, so that it corresponds to the default name used by the CLI utility **kubeseal** which we will install in the following section. ``` helm install sealed-secrets -n kube-system --set-string fullnameOverride=sealed-secrets-controller sealed-secrets/sealed-secrets ``` The chart downloads several resources to our cluster. The key ones are: > * **SealedSecret Custom Resource Definition (CRD)** - defines the template for sealed secrets that will be created on the cluster > * The **SealedSecrets controller pod** running in the kube-system namespace. Step 2 Install the kubeseal command line utility[πŸ”—](#step-2-install-the-kubeseal-command-line-utility "Permalink to this headline") ----------------------------------------------------------------------------------------------------------------------------------- Kubeseal CLI tool is used for encrypting secrets using the public certificate of the controller. To proceed, install **kubeseal** with the following set of commands: ``` KUBESEAL_VERSION='0.23.0' wget "https://github.com/bitnami-labs/sealed-secrets/releases/download/v${KUBESEAL_VERSION:?}/kubeseal-${KUBESEAL_VERSION:?}-linux-amd64.tar.gz" tar -xvzf kubeseal-${KUBESEAL_VERSION:?}-linux-amd64.tar.gz kubeseal sudo install -m 755 kubeseal /usr/local/bin/kubeseal ``` You can verify that **kubeseal** was properly installed by running: ``` kubeseal --version ``` which will return result similar to the following: ![image-2024-5-23_17-16-2.png](../_images/image-2024-5-23_17-16-2.png) Step 3 Create a sealed secret[πŸ”—](#step-3-create-a-sealed-secret "Permalink to this headline") --------------------------------------------------------------------------------------------- We can use Sealed Secrets to encrypt the secrets, which can be decrypted only by the controller running on the cluster. A sealed secret needs to be created based off a regular, unencrypted Kubernetes secret. However, we don’t want to commit this base secret to our Kubernetes cluster. We also do not want to create a permanent file with the unencrypted secret contents, to avoid accidentally committing it to source control. Therefore we will use **kubectl** to create a regular secret only temporarily, using **–dry-run=client** parameter. The secret has a key **foo** and value **bar**. **kubectl** outputs this temporary secret, we then pipe this output to **kubeseal** utility. **kubeseal** seals (encrypts) the secret and saves it to a file called **sealed-secret.yaml**. ``` kubectl create secret generic mysecret \ --dry-run=client \ --from-literal=foo=bar -o yaml | kubeseal \ --format yaml > mysecret.yaml ``` When we view the file we can see the contents are encrypted and safe to store in source control. Step 4 Unseal the secret[πŸ”—](#step-4-unseal-the-secret "Permalink to this headline") ----------------------------------------------------------------------------------- To unseal the secret and make it available and usable in the cluster, we perform the following command: ``` kubectl create -f mysecret.yaml ``` This, after few seconds, generates a regular Kubernetes secret which is readable to our cluster. We can verify this with these two commands: ``` kubectl get secret mysecret -o yaml echo YmFy | base64 --decode ``` The former command extracts output the yaml of the secret, while the latter decodes the value of the data stored under key **foo** which outputs the expected result: **bar**. The results can also be seen on the below screen: ![image-2024-5-23_17-39-37.png](../_images/image-2024-5-23_17-39-37.png) Step 5 Verify[πŸ”—](#step-5-verify "Permalink to this headline") ------------------------------------------------------------- The generated secret can be used as a regular Kubernetes secret. To test, create a file **test-pod.yaml** with the following contents: **test-pod.yaml** ``` apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: nginx:latest env: - name: TEST_VAR valueFrom: secretKeyRef: name: mysecret key: foo ``` This launches a minimal pod called **nginx** which is based on nginx server container image. In the container inside the pod, we create an environment variable called **TEST\_VAR**. The value of the variable is assigned from our secret **mysecret** by the available key **foo**. Apply the example with the following command: ``` kubectl apply -f test-pod.yaml ``` Then enter the container inside the **nginx** pod: ``` kubectl exec -it nginx -- sh ``` The command prompt will change to **#**, meaning the command you enter is executed inside the container. Execute the **printenv** command to see environment variables. We can see our variable **TEST\_VAR** with the value **bar**, as expected: ![image-end-of-article.png](../_images/image-end-of-article.png) What To Do Next[πŸ”—](#what-to-do-next "Permalink to this headline") ----------------------------------------------------------------- Sealed Secrets present a viable alternative to secret management using additional tools such as HashiCorp-Vault. For additional information, see [Installing HashiCorp Vault on connectVM Cloud Magnum](Installing-HashiCorp-Vault-on-connectVM-Cloud-Magnum.html.md).