{"id":23109,"date":"2024-07-07T23:26:09","date_gmt":"2024-07-07T20:26:09","guid":{"rendered":"https:\/\/kifarunix.com\/?p=23109"},"modified":"2024-07-11T23:37:58","modified_gmt":"2024-07-11T20:37:58","slug":"how-to-use-secrets-in-kubernetes-applications","status":"publish","type":"post","link":"https:\/\/kifarunix.com\/how-to-use-secrets-in-kubernetes-applications\/","title":{"rendered":"How to Use Secrets in Kubernetes Applications"},"content":{"rendered":"\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1069\" height=\"598\" src=\"https:\/\/kifarunix.com\/wp-content\/uploads\/2024\/07\/using-secrets-in-kubernetes-cluster.png\" alt=\"kubernetes secrets\" class=\"wp-image-23135\" title=\"\" srcset=\"https:\/\/kifarunix.com\/wp-content\/uploads\/2024\/07\/using-secrets-in-kubernetes-cluster.png?v=1720383873 1069w, https:\/\/kifarunix.com\/wp-content\/uploads\/2024\/07\/using-secrets-in-kubernetes-cluster-768x430.png?v=1720383873 768w\" sizes=\"(max-width: 1069px) 100vw, 1069px\" \/><\/figure>\n\n\n\n<p>In this blog post, you will learn how to use Secrets in Kubernetes applications. In Kubernetes, managing configuration data and sensitive information securely is crucial for maintaining robust and scalable applications. Kubernetes provides two primary resources for this purpose: <strong>Secrets<\/strong> and <strong>ConfigMaps<\/strong>. Understanding how to effectively create, use, and manage these resources is essential for Kubernetes administrators and developers.<\/p>\n\n\n\n<div class=\"wp-block-rank-math-toc-block\" id=\"rank-math-toc\"><h2>Table of Contents<\/h2><nav><ul><li><a href=\"#introduction-to-secrets-and-config-maps-in-kubernetes\">Introduction to Secrets and ConfigMaps in Kubernetes<\/a><ul><li><a href=\"#what-are-secrets-in-kubernetes\">What are Secrets in Kubernetes?<\/a><\/li><li><a href=\"#what-are-config-maps-in-kubernetes\">What are ConfigMaps in Kubernetes?<\/a><\/li><li><a href=\"#types-of-kubernetes-secrets\">Types of Kubernetes Secrets<\/a><ul><li><a href=\"#opaque-secrets\">Opaque Secrets<\/a><\/li><li><a href=\"#service-account-token\">Service Account Token<\/a><\/li><li><a href=\"#docker-config-secrets\">Docker Config Secrets<\/a><\/li><li><a href=\"#basic-authentication-secrets\">Basic Authentication Secrets<\/a><\/li><li><a href=\"#ssh-authentication-secrets\">SSH Authentication Secrets<\/a><\/li><li><a href=\"#tls-secrets\">TLS Secrets<\/a><\/li><li><a href=\"#bootstrap-secrets\">Bootstrap Secrets<\/a><\/li><\/ul><\/li><li><a href=\"#how-to-use-secrets-in-kubernetes\">How to Use Secrets in Kubernetes<\/a><ul><li><a href=\"#creating-kubernetes-secrets\">Creating Kubernetes Secrets<\/a><\/li><li><a href=\"#listing-available-secrets-in-kubernetes-cluster\">Listing Available Secrets in Kubernetes Cluster<\/a><\/li><li><a href=\"#get-details-of-a-secret-in-kubernetes\">Get Details of a Secret in Kubernetes<\/a><\/li><\/ul><\/li><li><a href=\"#using-secrets-in-deployment-pods\">Using Secrets in Deployment\/Pods<\/a><ul><li><a href=\"#using-secrets-as-environment-variables\">Using Secrets as Environment Variables<\/a><\/li><li><a href=\"#mounting-secrets-as-volumes\">Mounting Secrets as Volumes<\/a><\/li><\/ul><\/li><li><a href=\"#updating-kubernetes-secrets\">Updating Kubernetes Secrets<\/a><ul><li><a href=\"#editing-via-kubectl-edit\">Editing via kubectl edit<\/a><\/li><li><a href=\"#using-kubectl-apply\">Using kubectl apply<\/a><\/li><li><a href=\"#recreate-the-secret-with-new-value\">Recreate the Secret with New Value<\/a><\/li><li><a href=\"#patch-kubernetes-secret-with-kubectl-patch\">Patch Kubernetes Secret with kubectl patch<\/a><\/li><\/ul><\/li><li><a href=\"#deleting-kubernetes-secrets\">Deleting Kubernetes Secrets<\/a><ul><li><a href=\"#delete-a-specific-secret-by-name\">Delete a Specific Secret by Name:<\/a><\/li><li><a href=\"#delete-all-secrets-in-a-namespace\">Delete All Secrets in a Namespace:<\/a><\/li><li><a href=\"#delete-secrets-using-manifest-file\">Delete Secrets Using Manifest File:<\/a><\/li><\/ul><\/li><li><a href=\"#conclusion\">Conclusion<\/a><\/li><\/ul><\/li><\/ul><\/nav><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"introduction-to-secrets-and-config-maps-in-kubernetes\">Introduction to Secrets and ConfigMaps in Kubernetes<\/h2>\n\n\n\n<p>Secrets and ConfigMaps in Kubernetes provides a way to manage and store configuration data and sensitive information such as passwords for Kubernetes applications. But what are they exactly?<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"what-are-secrets-in-kubernetes\">What are Secrets in Kubernetes?<\/h3>\n\n\n\n<p>In Kubernetes, <strong>Secrets<\/strong> are objects that are used to store sensitive information such as <strong>passwords<\/strong>, <strong>OAuth<\/strong> <strong>tokens<\/strong>, <strong>keys<\/strong>, <strong>TLS certificates<\/strong> and any other sensitive data required by applications thus reducing the risk of accidental exposure. They are stored as <strong>Base64<\/strong>-encoded strings by default.<\/p>\n\n\n\n<p>While Kubernetes Secrets provide a convenient way to manage sensitive information within your cluster, they are not fully secure against potential threats. First of all, they are not encrypted by default and thus, anyone with API access, or access to etcd cluster can access, view or modify the secrets. Best practices include limiting access to Secrets through RBAC, rotating them regularly, and using additional encryption or external secret management tools where needed for enhanced security.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"what-are-config-maps-in-kubernetes\">What are ConfigMaps in Kubernetes?<\/h3>\n\n\n\n<p>On the other hand, ConfigMaps are Kubernetes API objects that are used store and manage non-sensitive configuration data in key-value pairs. ConfigMaps provides a way to decouple configuration artifacts from the application code thus making containerized applications portable.<\/p>\n\n\n\n<p>ConfigMaps are often used to store configuration parameters such as:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Environment variables<\/strong>: You can inject ConfigMap data into a container as environment variables, which allows you to configure how the application behaves without changing its container image.<\/li>\n\n\n\n<li><strong>Configuration files<\/strong>: ConfigMaps can also be mounted as volumes into containers, allowing applications to read configuration files directly from the volume.<\/li>\n\n\n\n<li><strong>Command Line arguments<\/strong>: ConfigMaps can also store command-line arguments that can be passed to containers in Kubernetes. This is particularly useful when applications need to start with specific runtime options or flags.<\/li>\n<\/ol>\n\n\n\n<p>ConfigMaps are useful when you want to:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Centralize configuration<\/strong>: Instead of embedding configuration directly into application code, container images or Kubernetes manifests, ConfigMaps provide a centralized way to manage configuration data.<\/li>\n\n\n\n<li><strong>Override configuration<\/strong>: You can update ConfigMaps independently of the application code, which makes it easier to change configurations without rebuilding or redeploying the containers.<\/li>\n<\/ul>\n\n\n\n<p>Read more on <a href=\"https:\/\/kifarunix.com\/step-by-step-guide-to-using-configmaps-in-kubernetes\/\" target=\"_blank\" rel=\"noreferrer noopener\">Step-by-Step Guide to Using ConfigMaps in Kubernetes<\/a><\/p>\n\n\n\n<p>The table below gives a summary of the difference between ConfigMaps and Secrets in Kubernetes;<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Aspect<\/th><th class=\"has-text-align-left\" data-align=\"left\">Secrets<\/th><th class=\"has-text-align-left\" data-align=\"left\">ConfigMaps<\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-left\" data-align=\"left\"><strong>Security<\/strong><\/td><td class=\"has-text-align-left\" data-align=\"left\">Intended for storing sensitive information.<\/td><td class=\"has-text-align-left\" data-align=\"left\">Stores non-sensitive configuration data.<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\"><strong>Data Format<\/strong><\/td><td class=\"has-text-align-left\" data-align=\"left\">Stores data as Base64-encoded strings (not encrypted by default).<\/td><td class=\"has-text-align-left\" data-align=\"left\">Stores data as plain text as key-value pairs.<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\"><strong>Use Case<\/strong><\/td><td class=\"has-text-align-left\" data-align=\"left\">Used for sensitive credentials and secure information.<\/td><td class=\"has-text-align-left\" data-align=\"left\">Used for general configuration settings.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Are you getting started with Kubernetes and you need a book that offers a beginner-friendly approach to mastering Kubernetes architecture and core concepts such as Pods, Deployments, Services, StatefulSets, Ingress, ConfigMaps, and more? Look no further, The Kubernetes Book: 2024 Edition by Nigel Poulton is the best bet.<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-rich is-provider-amazon wp-block-embed-amazon\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"The Kubernetes Book: 2024 Edition\" type=\"text\/html\" width=\"1200\" height=\"550\" frameborder=\"0\" allowfullscreen style=\"max-width:100%\" src=\"https:\/\/read.amazon.com\/kp\/card?preview=inline&#038;linkCode=ll1&#038;ref_=k4w_oembed_8Y7ssRtDtwcxsR&#038;asin=B072TS9ZQZ&#038;tag=dc42a8f60962-20\"><\/iframe>\n<\/div><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"types-of-kubernetes-secrets\">Types of Kubernetes Secrets<\/h3>\n\n\n\n<p>There are different types of Kubernetes Secrets as outlined below;<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"opaque-secrets\">Opaque Secrets<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Opaque secrets are generic secrets that store arbitrary data as key-value pairs. They are encoded in base64 within Kubernetes to maintain confidentiality.<\/li>\n\n\n\n<li>They are commonly used for storing passwords, API tokens, and other sensitive data that applications need to access securely.<\/li>\n\n\n\n<li>It is the default Secret type if you don&#8217;t explicitly specify a type in a Secret manifest or command line.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"service-account-token\">Service Account Token<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>ServiceAccoun token secrets are used to store a token credential that identifies a&nbsp;ServiceAccount in Kubernetes.<\/li>\n\n\n\n<li>Pods use these tokens to authenticate and interact securely with the Kubernetes API server, enabling them to perform actions such as retrieving configuration information or accessing other resources.<\/li>\n\n\n\n<li><strong>type<\/strong>: kubernetes.io\/service-account-token<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"docker-config-secrets\">Docker Config Secrets<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>These are secrets used to authenticate with private Docker registries.<\/li>\n\n\n\n<li>They store Docker registry credentials (username, password, or token) securely, allowing Kubernetes to pull private images from Docker registries during deployments.<\/li>\n\n\n\n<li><strong><strong>type<\/strong>: <\/strong>kubernetes.io\/dockercfg<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"basic-authentication-secrets\">Basic Authentication Secrets<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>These are secrets that are used for basic authentication, typically used for integrating with legacy systems or services that require simple username\/password authentication.<\/li>\n\n\n\n<li>They store credentials in a manner similar to Opaque secrets but are specifically used for basic authentication purposes.<\/li>\n\n\n\n<li><strong>type<\/strong>: kubernetes.io\/basic-auth<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"ssh-authentication-secrets\">SSH Authentication Secrets<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>They are used to authenticate SSH connections.<\/li>\n\n\n\n<li>They store SSH keys and other related data required for secure SSH access to pods or nodes within the Kubernetes cluster.<\/li>\n\n\n\n<li><strong>type<\/strong>: kubernetes.io\/ssh-auth<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"tls-secrets\">TLS Secrets<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>They are secrets used for storing TLS certificates and private keys.<\/li>\n\n\n\n<li>They secure communication within Kubernetes, such as enabling HTTPS endpoints for services or securing communication between pods.<\/li>\n\n\n\n<li><strong>type<\/strong>: kubernetes.io\/tls or <strong>&#8211;type=&#8217;tls&#8217;<\/strong><\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"bootstrap-secrets\">Bootstrap Secrets<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>These are secrets used during the initial bootstrapping of Kubernetes cluster nodes.<\/li>\n\n\n\n<li>They are used for securely configuring and initializing the Kubernetes cluster, including initial setup and configuration tasks.<\/li>\n\n\n\n<li><strong>type<\/strong>: bootstrap.kubernetes.io\/token<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"how-to-use-secrets-in-kubernetes\">How to Use Secrets in Kubernetes<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"creating-kubernetes-secrets\">Creating Kubernetes Secrets<\/h4>\n\n\n\n<p>Kubernetes offers multiple ways to create secrets, imperatively using <strong>kubectl create secret<\/strong> or declaratively using the manifest file. You can specify the secret type using <strong>&#8211;type<\/strong> option in command line or <strong>type:<\/strong> in the manifest file.<\/p>\n\n\n\n<p>Command Syntax;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl create secret (docker-registry | generic | tls) &#91;options]<\/code><\/pre>\n\n\n\n<p>Rest of the other Secret types if you are creating them via command line can take the generic type!<\/p>\n\n\n\n<p>1.  Creating Secrets from Literal Values (specify each key-value pair directly in the command):<\/p>\n\n\n\n<p>Use <strong>kubectl create secret<\/strong> with the <strong>&#8211;from-literal<\/strong> flag to create secrets directly from command-line input. This method is suitable for small pieces of sensitive data.<\/p>\n\n\n\n<p>You can specify the respective namespace for the secrets (<strong>-n|&#8211;namespace &lt;namespace&gt;<\/strong>)<\/p>\n\n\n\n<p>For example, to create a secret called <strong>user-logins<\/strong> with a <strong>username<\/strong> (username) and <strong>password<\/strong> (mypassword);<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl create secret generic user-logins --from-literal=username=myuser --from-literal=password=mypassword<\/code><\/pre>\n\n\n\n<p>Replace the values accordingly.<\/p>\n\n\n\n<p>This will create a secret names <strong>user-login<\/strong> in the default namespace.<\/p>\n\n\n\n<p>2. Creating Secrets from Files:<\/p>\n\n\n\n<p>Use <strong>kubectl create secret<\/strong> with the <strong>&#8211;from-file<\/strong> flag to create secrets from one or more files. This method is useful for storing larger pieces of sensitive data, such as TLS certificates.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl create secret generic tls-secret --from-file=cert.pem=\/path\/to\/cert.pem --from-file=key.pem=\/path\/to\/key.pem<\/code><\/pre>\n\n\n\n<p>Replace <strong>\/path\/to\/cert.pem<\/strong> and <strong>\/path\/to\/key.pem<\/strong> with the actual paths to your certificate and key files.<\/p>\n\n\n\n<p>3. Creating Secret from Environment File:<\/p>\n\n\n\n<p>This allows you to store multiple environment variables in a single file, which simplifies management and reduces the chance of errors.<\/p>\n\n\n\n<p>Create a text file (let&#8217;s say <code>env-file.txt<\/code>) that contains your environment variables in the format <code>KEY=VALUE<\/code>, each on a new line:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cat env-file.txt<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>DB_USERNAME=username\nDB_PASSWORD=password<\/code><\/pre>\n\n\n\n<p>Then use <code>kubectl create secret<\/code> with the <code>--from-env-file<\/code> option followed by the path to your environment file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl create secret generic my-secret --from-env-file=env-file.txt<\/code><\/pre>\n\n\n\n<p>4. Creating a Secret from a Directory<\/p>\n\n\n\n<p>When you have multiple files that you want to store as different keys in a secret, you can put them under a specific directory and create them right from the directory. When creating a secret in Kubernetes based on a directory, each file whose basename (filename without the path) corresponds to a valid key in the directory will be packaged into the secret.<\/p>\n\n\n\n<p>Let&#8217;s say you have a directory named <code>secrets<\/code> with the following files:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>username.txt<\/code> containing <code>user<\/code><\/li>\n\n\n\n<li><code>password.txt<\/code> containing <code>password<\/code><\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>tree secrets\/<\/code><\/pre>\n\n\n\n<pre class=\"scroll-box\"><code>secrets\/\n\u251c\u2500\u2500 password.txt\n\u2514\u2500\u2500 username.txt\n\n1 directory, 2 files\n<\/code><\/pre>\n\n\n\n<p>To create a Kubernetes secret named <code>mysecret<\/code> from this directory, where each file becomes a key-value pair in the secret:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl create secret generic mysecret --from-file=secrets\/<\/code><\/pre>\n\n\n\n<p>Kubernetes will package each file (<code>username.txt<\/code> and <code>password.txt<\/code>) in the <code>secrets<\/code> directory into the secret <code>mysecret<\/code>, with the filenames as keys and their contents as values.<\/p>\n\n\n\n<p>5. Creating Secrets Declaratively from YAML Manifest:<\/p>\n\n\n\n<p>You can define secrets directly in a YAML manifest file. The secret values has to base64-encoded;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cat my-secret.yaml<\/code><\/pre>\n\n\n\n<pre class=\"scroll-box\"><code>apiVersion: v1\nkind: Secret\nmetadata:\n  name: my-secret\ntype: Opaque\ndata:\n  username: dXNlcm5hbWU=   # base64 encoded 'username'; echo -n \"value\" | base64\n  password: cGFzc3dvcmQ=   # base64 encoded 'password'; echo -n \"value\" | base64\n<\/code><\/pre>\n\n\n\n<p>Then apply;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl apply -f my-secret.yaml<\/code><\/pre>\n\n\n\n<p>To specify the namespace, define it under metadata.<\/p>\n\n\n\n<pre class=\"scroll-box\"><code>apiVersion: v1\nkind: Secret\nmetadata:\n  name: my-secret\n  namespace: my-namespace\ntype: Opaque\ndata:\n  username: dXNlcm5hbWU=   # base64 encoded 'username'; echo -n \"value\" | base64\n  password: cGFzc3dvcmQ=   # base64 encoded 'password'; echo -n \"value\" | base64\n<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"listing-available-secrets-in-kubernetes-cluster\">Listing Available Secrets in Kubernetes Cluster<\/h4>\n\n\n\n<p>You can use <strong>kubectl get secrets<\/strong> command to list available secrets in Kubernetes.<\/p>\n\n\n\n<p>To list the secrets in the default namespace;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl get secrets<\/code><\/pre>\n\n\n\n<pre class=\"scroll-box\"><code>NAME          TYPE     DATA   AGE\nuser-logins   Opaque   2      23m\n<\/code><\/pre>\n\n\n\n<p>To list secrets in a specific namespace;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl get secrets -n &lt;namespace&gt; <\/code><\/pre>\n\n\n\n<p>To list secrets in all namespaces;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl get secrets -A<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"get-details-of-a-secret-in-kubernetes\">Get Details of a Secret in Kubernetes<\/h4>\n\n\n\n<p>You can use <strong>kubectl describe secret<\/strong> or <strong>kubectl get secret<\/strong> commands to view secrets details;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl describe secrets &lt;name-of-secret&gt; &#91;-n|--namespace &lt;namespace&gt;]<\/code><\/pre>\n\n\n\n<p>Or;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl get secrets &lt;name-of-secret&gt; -o yaml &#91;-n|--namespace &lt;namespace&gt;]<\/code><\/pre>\n\n\n\n<p>You can also decode data field from secret using json output;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl get secret &lt;name-of-secret&gt; -o jsonpath='{.data}' &#91;-n|--namespace &lt;namespace&gt;]<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"using-secrets-in-deployment-pods\">Using Secrets in Deployment\/Pods<\/h3>\n\n\n\n<p>Once you have created a secret, you can use it in your pods to securely access sensitive information.<\/p>\n\n\n\n<p>There are two ways in which you can inject the secrets into the Pod;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Via the Environment variables<\/li>\n\n\n\n<li>By mounting it as volumes in the Pod.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"using-secrets-as-environment-variables\">Using Secrets as Environment Variables<\/h4>\n\n\n\n<p>Inject secrets as environment variables in your Deployment\/pod specifications. For example, below is a manifest file for creating a MariaDB pods with root user password stored in Kubernetes secret.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cat mariadb.yaml<\/code><\/pre>\n\n\n\n<pre class=\"scroll-box\"><code>apiVersion: apps\/v1\nkind: Deployment\nmetadata:\n  name: mariadb-deployment\n  namespace: apps\nspec:\n  replicas: 2\n  selector:\n    matchLabels:\n      app: mariadb\n  template:\n    metadata:\n      labels:\n        app: mariadb\n    spec:\n      containers:\n      - name: mariadb\n        image: mariadb:latest\n        ports:\n        - containerPort: 3306\n        env:\n        - name: MARIADB_ROOT_PASSWORD\n          valueFrom:\n            secretKeyRef:\n              name: mariadb-secret\n              key: mariadb-root-password\n<\/code><\/pre>\n\n\n\n<p>As you can see, the MariaDB root user password is injected as an environment variable, <strong>MYSQL_ROOT_PASSWORD<\/strong>. The value of the environment variable is sourced securely from a Kubernetes Secret named <code>mariadb-secret<\/code>, using the key <code>mariadb-root-password<\/code> from that secret.<\/p>\n\n\n\n<p>To create a secret, you can follow steps above.<\/p>\n\n\n\n<p>We have already created one.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl get secret mariadb-secret -n apps -o yaml<\/code><\/pre>\n\n\n\n<pre class=\"scroll-box\"><code>apiVersion: v1\ndata:\n  mariadb-root-password: aEBja2VyMTIz\nkind: Secret\nmetadata:\n  creationTimestamp: \"2024-07-06T19:35:49Z\"\n  name: mariadb-secret\n  namespace: apps\n  resourceVersion: \"4324348\"\n  uid: 3316104a-7079-4bba-8751-554637d51b9f\ntype: Opaque\n<\/code><\/pre>\n\n\n\n<p>Then let&#8217;s create our deployment;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl apply -f mariadb.yaml<\/code><\/pre>\n\n\n\n<p>Pods are already running;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl get pods -n apps -l app=mariadb<\/code><\/pre>\n\n\n\n<pre class=\"scroll-box\"><code>NAME                                  READY   STATUS    RESTARTS   AGE\nmariadb-deployment-7f46d75896-6t666   1\/1     Running   0          77s\nmariadb-deployment-7f46d75896-g7dss   1\/1     Running   0          77s\n<\/code><\/pre>\n\n\n\n<p>Let&#8217;s try to login to our MariaDB Pod;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl exec -it mariadb-deployment-7f46d75896-6t666 -n apps -- mariadb -u root -p<\/code><\/pre>\n\n\n\n<p>You will be prompted to enter the password that was defined\/stored in the secret.<\/p>\n\n\n\n<p>Upon providing the correct password, you should drop into MariaDB prompt;<\/p>\n\n\n\n<pre class=\"scroll-box\"><code>Enter password: \nWelcome to the MariaDB monitor.  Commands end with ; or \\g.\nYour MariaDB connection id is 4\nServer version: 11.4.2-MariaDB-ubu2404 mariadb.org binary distribution\n\nCopyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.\n\nType 'help;' or '\\h' for help. Type '\\c' to clear the current input statement.\n\nMariaDB [(none)]&gt;\n<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"mounting-secrets-as-volumes\">Mounting Secrets as Volumes<\/h4>\n\n\n\n<p>You can also mount secrets as files in your pod&#8217;s filesystem for applications to read.<\/p>\n\n\n\n<p>Let&#8217;s create a simple nginx app with basic authentication.<\/p>\n\n\n\n<p>Set the basic auth credentials;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>htpasswd -c -B -C 10 .\/auth webadmin<\/code><\/pre>\n\n\n\n<p>Enter the password and confirm.<\/p>\n\n\n\n<p>Create a basic auth secret from basic auth file;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl create secret generic nginx-auth --from-file=.\/auth -n apps<\/code><\/pre>\n\n\n\n<p>Create a ConfigMap for Nginx configuration that defines path to basic auth file (<strong>\/etc\/nginx\/auth\/auth<\/strong>) that will be mounted as a volume in the Pod.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cat nginx.conf<\/code><\/pre>\n\n\n\n<pre class=\"scroll-box\"><code>server {\n\tlisten 80 default_server;\n\n\troot \/usr\/share\/nginx\/html;\n\tindex index.html index.htm index.nginx-debian.html;\n\n\tserver_name _;\n    \tlocation \/ {\n        \ttry_files $uri $uri\/ =404;\n    \t}\t\n\n\tlocation \/private {\n\t\tauth_basic \"Restricted Content\";\n                auth_basic_user_file \/etc\/nginx\/auth\/auth;\n\t\ttry_files $uri $uri\/ \/index.html;\n\t}\n}\n<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl create configmap nginx-config --from-file=nginx.conf -n apps<\/code><\/pre>\n\n\n\n<p>Create the NGINX Deployment;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cat nginx.yaml<\/code><\/pre>\n\n\n\n<pre class=\"scroll-box\"><code>apiVersion: apps\/v1\nkind: Deployment\nmetadata:\n  name: nginx-deployment\n  namespace: apps\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      app: nginx\n  template:\n    metadata:\n      labels:\n        app: nginx\n    spec:\n      containers:\n      - name: nginx\n        image: nginx:latest\n        ports:\n        - containerPort: 80\n        volumeMounts:\n        - name: auth-volume\n          mountPath: \/etc\/nginx\/auth\n          readOnly: true\n        - name: nginx-config\n          mountPath: \/etc\/nginx\/conf.d\/default.conf\n          subPath: nginx.conf\n      volumes:\n      - name: auth-volume\n        secret:\n          secretName: nginx-auth\n      - name: nginx-config\n        configMap:\n          name: nginx-config\n<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The configuration mounts two volumes into the container: <strong>auth-volume<\/strong> and <strong>nginx-config<\/strong>.<\/li>\n\n\n\n<li>The <code>auth-volume<\/code> is sourced from a Kubernetes Secret named <code>nginx-auth<\/code>, providing Basic Authentication credentials stored securely in <code>\/etc\/nginx\/auth<\/code> within the container.<\/li>\n\n\n\n<li>The <code>nginx-config<\/code> volume is sourced from a ConfigMap named <code>nginx-config<\/code>, specifically mounting the <code>nginx.conf<\/code> file from the ConfigMap at <code>\/etc\/nginx\/conf.d\/default.conf<\/code> using <code>subPath<\/code> to reference the specific file.<\/li>\n\n\n\n<li>This setup allows the NGINX server to authenticate users access <strong>\/private<\/strong> page with Basic Authentication and use a custom NGINX configuration defined in the ConfigMap for its operation.<\/li>\n<\/ul>\n\n\n\n<p>Apply the manifest file;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl apply -f nginx.yaml<\/code><\/pre>\n\n\n\n<p>Check the Nginx Pods;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl get pods -n apps -l app=nginx<\/code><\/pre>\n\n\n\n<pre class=\"scroll-box\"><code>NAME                                READY   STATUS    RESTARTS   AGE\nnginx-deployment-6fc846f549-hwjc6   1\/1     Running   0          36s\n<\/code><\/pre>\n\n\n\n<p>Let&#8217;s try to access the default page;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl exec -it nginx-deployment-6fc846f549-hwjc6 -n apps -- curl localhost<\/code><\/pre>\n\n\n\n<p>Sample output;<\/p>\n\n\n\n<pre class=\"scroll-box\"><code>&lt;!DOCTYPE html&gt;\n&lt;html&gt;\n&lt;head&gt;\n&lt;title&gt;Welcome to nginx!&lt;\/title&gt;\n&lt;style&gt;\nhtml { color-scheme: light dark; }\nbody { width: 35em; margin: 0 auto;\nfont-family: Tahoma, Verdana, Arial, sans-serif; }\n&lt;\/style&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n&lt;h1&gt;Welcome to nginx!&lt;\/h1&gt;\n&lt;p&gt;If you see this page, the nginx web server is successfully installed and\nworking. Further configuration is required.&lt;\/p&gt;\n\n&lt;p&gt;For online documentation and support please refer to\n&lt;a href=\"http:\/\/nginx.org\/\"&gt;nginx.org&lt;\/a&gt;.&lt;br\/&gt;\nCommercial support is available at\n&lt;a href=\"http:\/\/nginx.com\/\"&gt;nginx.com&lt;\/a&gt;.&lt;\/p&gt;\n\n&lt;p&gt;&lt;em&gt;Thank you for using nginx.&lt;\/em&gt;&lt;\/p&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;\n<\/code><\/pre>\n\n\n\n<p>Now, try to access restricted page without basic auth creds;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl exec -it nginx-deployment-6fc846f549-hwjc6 -n apps -- curl localhost\/private<\/code><\/pre>\n\n\n\n<pre class=\"scroll-box\"><code>&lt;html&gt;\n&lt;head&gt;&lt;title&gt;401 Authorization Required&lt;\/title&gt;&lt;\/head&gt;\n&lt;body&gt;\n&lt;center&gt;&lt;h1&gt;401 Authorization Required&lt;\/h1&gt;&lt;\/center&gt;\n&lt;hr&gt;&lt;center&gt;nginx\/1.27.0&lt;\/center&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;\n<\/code><\/pre>\n\n\n\n<p>Authorization required!<\/p>\n\n\n\n<p>Provide authentication credentials and check;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl exec -it nginx-deployment-6fc846f549-hwjc6 -n apps -- curl localhost\/private -u webadmin<\/code><\/pre>\n\n\n\n<p>When prompted for password, provide the password created with htpasswd above.<\/p>\n\n\n\n<pre class=\"scroll-box\"><code>Enter host password for user 'webadmin':\n&lt;!DOCTYPE html&gt;\n&lt;html&gt;\n&lt;head&gt;\n&lt;title&gt;Welcome to nginx!&lt;\/title&gt;\n&lt;style&gt;\nhtml { color-scheme: light dark; }\nbody { width: 35em; margin: 0 auto;\nfont-family: Tahoma, Verdana, Arial, sans-serif; }\n&lt;\/style&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n&lt;h1&gt;Welcome to nginx!&lt;\/h1&gt;\n&lt;p&gt;If you see this page, the nginx web server is successfully installed and\nworking. Further configuration is required.&lt;\/p&gt;\n\n&lt;p&gt;For online documentation and support please refer to\n&lt;a href=\"http:\/\/nginx.org\/\"&gt;nginx.org&lt;\/a&gt;.&lt;br\/&gt;\nCommercial support is available at\n&lt;a href=\"http:\/\/nginx.com\/\"&gt;nginx.com&lt;\/a&gt;.&lt;\/p&gt;\n\n&lt;p&gt;&lt;em&gt;Thank you for using nginx.&lt;\/em&gt;&lt;\/p&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;\n<\/code><\/pre>\n\n\n\n<p>And there you go!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"updating-kubernetes-secrets\">Updating Kubernetes Secrets<\/h3>\n\n\n\n<p>There are different ways in which you can update your Kubernetes Secrets;<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"editing-via-kubectl-edit\">Editing via kubectl edit<\/h4>\n\n\n\n<p>Edit the secret interactively using the <strong>kubectl edit<\/strong> command. This opens the secret in your default editor (which can either be <code>vi<\/code>, <code>nano<\/code>, etc.) and allows you to modify it directly.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl edit secret &lt;name-of-secret&gt; &#91;-n|--namespace &lt;namespace&gt;]<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"using-kubectl-apply\">Using kubectl apply<\/h4>\n\n\n\n<p>You can update a secret by applying changes from a YAML file. Once you make the changes to the Secrets manifest file, then re-run the <strong>kubectl apply<\/strong> command.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl apply -f updated-secret.yaml<\/code><\/pre>\n\n\n\n<p>Assuming that <code>updated-secret.yaml<\/code> contains the updated secret definition with the changes you want to make.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"recreate-the-secret-with-new-value\">Recreate the Secret with New Value<\/h4>\n\n\n\n<p>You can recreate your secret with new value. Replace <code>my-secret<\/code> with your secret&#8217;s name and <code>key=newvalue<\/code> with the key and new value pair you want to update.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl create secret generic my-secret --from-literal=key=newvalue<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"patch-kubernetes-secret-with-kubectl-patch\">Patch Kubernetes Secret with kubectl patch<\/h4>\n\n\n\n<p>You can patch the secret to update specific fields using the <strong>kubectl patch<\/strong> command.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl patch secret my-secret --type='json' -p='&#91;{\"op\": \"replace\", \"path\": \"\/data\/key\", \"value\": \"newvalue\"}]'<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Operation (<code>op<\/code>):<\/strong> <code>\"op\": \"replace\"<\/code>: Specifies the operation to perform. In this case, it indicates that you want to replace the value of a specific field.<\/li>\n\n\n\n<li><strong>Path (<code>path<\/code>):<\/strong> <code>\"path\": \"\/data\/key\"<\/code>: Defines the path to the field within the secret that you want to update. <code>\/data\/key<\/code> refers to the key within the <code>data<\/code> section of the secret.<\/li>\n\n\n\n<li><strong>Value (<code>value<\/code>):<\/strong> <code>\"value\": \"newvalue\"<\/code>: Specifies the new value that you want to set for the field identified by the path.<\/li>\n<\/ul>\n\n\n\n<p>For example, to update my MariaDB root password with the following current details;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl get secret mariadb-secret -n apps -o yaml<\/code><\/pre>\n\n\n\n<pre class=\"scroll-box\"><code>apiVersion: v1\ndata:\n  mariadb-root-password: aEBja2VyMTIz\nkind: Secret\nmetadata:\n  creationTimestamp: \"2024-07-06T19:35:49Z\"\n  name: mariadb-secret\n  namespace: apps\n  resourceVersion: \"4324348\"\n  uid: 3316104a-7079-4bba-8751-554637d51b9f\ntype: Opaque\n<\/code><\/pre>\n\n\n\n<p>To patch this secret;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl patch secret mariadb-secret -n apps --type='json' -p='&#91;{\"op\": \"replace\", \"path\": \"\/data\/mariadb-root-password\", \"value\": \"newbase64encodedpassword\"}]'<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"deleting-kubernetes-secrets\">Deleting Kubernetes Secrets<\/h3>\n\n\n\n<p>To delete Kubernetes secrets, you can use the <code>kubectl delete<\/code> command.<\/p>\n\n\n\n<p>Deleting a secret is irreversible. Ensure that you have backed up any data or configurations stored in the secret before deleting it. Similarly, ensure that you have appropriate permissions (<code>delete<\/code> role) to delete secrets in the namespace.<\/p>\n\n\n\n<p>Here are a few ways to delete secrets:<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"delete-a-specific-secret-by-name\">Delete a Specific Secret by Name:<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl delete secret &lt;secret-name&gt; -n &lt;namespace&gt;<\/code><\/pre>\n\n\n\n<p>Replace <code>&lt;secret-name&gt;<\/code> with the name of the secret you want to delete and <code>&lt;namespace&gt;<\/code> with the namespace where the secret resides. For example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl delete secret mariadb-secret -n apps<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"delete-all-secrets-in-a-namespace\">Delete All Secrets in a Namespace:<\/h4>\n\n\n\n<p>To delete all secrets in a specific namespace, you can use a similar command without specifying a label selector:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl delete secret --all -n &lt;namespace&gt;<\/code><\/pre>\n\n\n\n<p>Replace <code>&lt;namespace&gt;<\/code> with the namespace where you want to delete all secrets. For example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl delete secret --all -n apps<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"delete-secrets-using-manifest-file\">Delete Secrets Using Manifest File:<\/h4>\n\n\n\n<p>If the secret was created using a manifest file (<code>yaml<\/code> or <code>json<\/code>), you can delete it by applying the same manifest file with the <code>delete<\/code> action:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl delete -f secret-manifest.yaml<\/code><\/pre>\n\n\n\n<p>Ensure that <code>secret-manifest.yaml<\/code> contains the correct definition of the secret you want to delete.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"conclusion\">Conclusion<\/h3>\n\n\n\n<p>And that conclude our guide on how to use Secrets in Kubernetes.<\/p>\n\n\n\n<p>Read more on <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/configuration\/secret\/\" target=\"_blank\" rel=\"noreferrer noopener\">Kubernetes Secrets page<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this blog post, you will learn how to use Secrets in Kubernetes applications. In Kubernetes, managing configuration data and sensitive information securely is crucial<\/p>\n","protected":false},"author":10,"featured_media":23135,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"rank_math_lock_modified_date":false,"footnotes":""},"categories":[1668,1076,121],"tags":[7561,7563,7562,7564],"class_list":["post-23109","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-kubernetes","category-containers","category-howtos","tag-kubernetes-secrets","tag-kubernetes-secrets-from-literals","tag-kubernetes-types-of-secrets","tag-secrets-vs-configmaps","generate-columns","tablet-grid-50","mobile-grid-100","grid-parent","grid-50","resize-featured-image"],"_links":{"self":[{"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/posts\/23109"}],"collection":[{"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/users\/10"}],"replies":[{"embeddable":true,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/comments?post=23109"}],"version-history":[{"count":32,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/posts\/23109\/revisions"}],"predecessor-version":[{"id":23172,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/posts\/23109\/revisions\/23172"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/media\/23135"}],"wp:attachment":[{"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/media?parent=23109"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/categories?post=23109"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/tags?post=23109"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}