Kubernetes Secret (1)

An Introduction to Secret Types and How They Are Used

Basically, Secret is samilar as ConfigMap, which means we can (mostly) consuming it either as environment variables or as volume. In order to get a more concreting view of the secret, let’s go over each secret type with both command-line and YAML creation methods, followed by realistic pod consumption examples.

As in the official document present, there are many build-in types of secrets (here). But in this article, we will category them into 4 types:

  • Generic

  • Docker Registry

  • TLS

  • ServiceAccountToken

There are basically according to the secret create commands line.

# create secret
kubectl create secret generic NAME [--type=string] [--from-file=[key=]source] [--from-literal=key1=value1]
kubectl create secret tls NAME --cert=path/to/cert/file --key=path/to/key/file
kubectl create secret docker-registry NAME --docker-username=user --docker-password=password --docker-email=email
# create sa
kubectl create serviceaccount NAME

Next let’s talk these one by one.


1. Generic Type (Opaque, Basic Auth and SSH)

  • Opaque: This is the most general type, allowing any arbitrary key-value pairs. It can store various types of sensitive data (API keys, general tokens, configuration values).

  • Basic Auth: Specifically intended for username and password pairs.

  • SSH Auth: Typically used to store an SSH private key for secure access to Git repositories or remote servers. It only stores the private key in the ssh-privatekey key.

Consumption:

  • Opaque and Basic Auth: These can be consumed as environment variables or mounted as volumes.

  • SSH Auth: Kubernetes does not support using SSH secrets directly as environment variables due to security considerations (SSH keys are sensitive). Instead, SSH secrets must be mounted as volumes and accessed as files.

In the official doc (here), is a token secret type: bootstrap.kubernetes.io/token . Don’t confused with the gerneric token. The bootstrap token is specialized and typically only used for cluster initialization (eg. join nodes), not general application deployment or runtime security. More details about bootstrap token can be checked in the official documents chapter Authenticating with Bootstrap Tokens.

1.1 Opaque Secret

An Opaque secret is useful for general sensitive data, such as API keys, database connection strings, or custom configuration values or anything you want to used as a secret.

Creation

  • Command Line:

      kubectl create secret generic NAME --from-literal=api_key=12345-ABCDE
    
  • YAML:

      apiVersion: v1
      kind: Secret
      metadata:
        name: api-key-secret
      type: Opaque
      data:
        api_key: MTIzNDUtQUJDREU=  # "12345-ABCDE" in base64
    

Pod Consumption

This example shows how a pod consumes the api_key from the secret as an environment variable.

apiVersion: v1
kind: Pod
metadata:
  name: pod-with-api-key
spec:
  containers:
    - name: app
      image: nginx
      env:
        - name: API_KEY
          valueFrom:
            secretKeyRef:
              name: api-key-secret
              key: api_key
  restartPolicy: Never

1.2 Basic Auth Secret

Basic Auth secrets are ideal for username-password pairs, often used for simple authentication.

Creation

  • Command Line:

      kubectl create secret generic db-credentials \
        --from-literal=username=dbuser --from-literal=password=secretpassword
    
  • YAML:

      apiVersion: v1
      kind: Secret
      metadata:
        name: db-credentials
      type: Opaque
      data:
        username: ZGJ1c2Vy  # "dbuser" in base64
        password: c2VjcmV0cGFzc3dvcmQ=  # "secretpassword" in base64
    

Pod Consumption

The pod consumes the username and password as environment variables.

apiVersion: v1
kind: Pod
metadata:
  name: pod-with-db-credentials
spec:
  containers:
    - name: app
      image: nginx
      env:
        - name: DB_USERNAME
          valueFrom:
            secretKeyRef:
              name: db-credentials
              key: username
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: db-credentials
              key: password
  restartPolicy: Never

It is more offen to use the basic auth type secret for database authentication: Connecting securely to a database that requires username-password credentials.

1.3 SSH Auth Secret

SSH auth secrets are useful for private key authentication, such as accessing private Git repositories.

Creation

  • Command Line:

      kubectl create secret generic git-ssh-key \
        --from-file=ssh-privatekey=~/.ssh/id_rsa
    
  • YAML:

      apiVersion: v1
      kind: Secret
      metadata:
        name: git-ssh-key
      type: kubernetes.io/ssh-auth
      data:
        ssh-privatekey: <base64_encoded_ssh_private_key>
    

Pod Consumption

The SSH key can be mounted as a volume to allow the pod to clone a private Git repository.

apiVersion: v1
kind: Pod
metadata:
  name: pod-with-ssh-key
spec:
  containers:
    - name: app
      image: alpine
      command: ["sh", "-c", "apk add git && git clone git@github.com:private/repo.git"]
      volumeMounts:
        - name: ssh-key-volume
          mountPath: "/root/.ssh"
          readOnly: true
  volumes:
    - name: ssh-key-volume
      secret:
        secretName: git-ssh-key

Normally, when authenticating with a private Git repository to clone code during the build process.


2. Docker Registry Secret

This type is used to authenticate with private Docker registries for pulling images. There are 2 build-in types:

  • .dockercfg (older format): JSON file typically located at ~/.dockercfg in the user’s home directory.

  • .dockerconfigjson (newer, preferred format): JSON file located at ~/.docker/config.json.

Both files can be generated by running docker login on a machine with Docker installed. This command authenticates to the Docker registry and creates the appropriate configuration file.

  • Command for .dockerconfigjson:

      kubectl create secret docker-registry my-docker-secret \
        --docker-username=<username> --docker-password=<password> \
        --docker-server=<registry> --docker-email=<email>
    

    Alternatively, you can create the secret by providing the JSON file directly if it already exists.

Consumption:

  • Docker registry secrets can be referenced as imagePullSecrets for pulling images from private registries. Pods do not consume these secrets directly as environment variables or volumes.

  • File Storage: While the secret data is stored in file format, it is not mounted as a volume. Instead, it is referenced directly in the imagePullSecrets field of the pod specification.

2.1 Docker Registry Secret

Creation

  • Command Line:

      kubectl create secret docker-registry my-registry-secret \
        --docker-username=myuser --docker-password=mypassword \
        --docker-server=my.registry.com --docker-email=myemail@example.com
    
  • YAML:

      apiVersion: v1
      kind: Secret
      metadata:
        name: my-registry-secret
      type: kubernetes.io/dockerconfigjson
      data:
        .dockerconfigjson: <base64_encoded_dockerconfigjson>
    

Pod Consumption

The secret is referenced as an imagePullSecret to allow the pod to pull images from the private registry.

apiVersion: v1
kind: Pod
metadata:
  name: pod-using-private-image
spec:
  containers:
    - name: app
      image: my.registry.com/myapp:latest
  imagePullSecrets:
    - name: my-registry-secret

3. TLS Secret

  • Purpose: TLS secrets store SSL/TLS certificates and private keys in files to support HTTPS traffic.

  • Format: The secret stores two files, tls.crt (certificate) and tls.key (private key), which are essential for TLS.

Consumption:

  • Only as Volume: TLS secrets can only be consumed by mounting them as a volume in the pod.

3.1 TLS Secret

TLS secrets are used to store SSL/TLS certificates, which are necessary for enabling HTTPS.

Creation

  • Command Line:

      kubectl create secret tls my-tls-secret \
        --cert=path/to/tls.crt --key=path/to/tls.key
    
  • YAML:

      apiVersion: v1
      kind: Secret
      metadata:
        name: my-tls-secret
      type: kubernetes.io/tls
      data:
        tls.crt: <base64_encoded_certificate>
        tls.key: <base64_encoded_private_key>
    

Pod Consumption

Mount the TLS secret as a volume so that applications can use it for HTTPS.

apiVersion: v1
kind: Pod
metadata:
  name: pod-with-tls
spec:
  containers:
    - name: app
      image: nginx
      volumeMounts:
        - name: tls-volume
          mountPath: "/etc/tls"
          readOnly: true
  volumes:
    - name: tls-volume
      secret:
        secretName: my-tls-secret

4. Service Account Token Secret

When you create a Service Account, Kubernetes automatically generates a Service Account Token secret, which can be used to authenticate with the Kubernetes API.

Usage:

  • This token secret is not directly consumed like other secrets; instead, you assign the service account to the pod using the serviceAccountName field in the pod specification.

  • Service Account Token: Kubernetes automatically creates a service account token secret when you create a service account. Assign the service account to the pod, and Kubernetes will handle token authentication for the API.

4.1 Service Account Token Secret

A service account token secret is automatically generated for a service account and used for API access by pods.

Creation

  1. Create a Service Account:

     kubectl create serviceaccount my-service-account
    
  2. Inspect the Generated Secret: Kubernetes automatically generates a token secret associated with this service account.

Pod Consumption

Assign the service account to a pod to allow it to interact with the Kubernetes API securely.

apiVersion: v1
kind: Pod
metadata:
  name: pod-with-service-account
spec:
  serviceAccountName: my-service-account
  containers:
    - name: app
      image: myapi-client

Each of these secret types supports a specific use case, ensuring secure handling of sensitive information across Kubernetes workloads.


Above we mainly show the basic secret build-in types and some simple example to use these. Next we will give some explain for more details like the parameters, encryption.