Secret
1.1 About Secret
Some sensitive information such as database username and password is needed in the application startup process. If it is not safe to store directly in the container image, K8S provides the scheme of Secret.
Secret stores data in ciphertext, avoiding storing sensitive information directly in configuration files.
Secret is mount ed to Pod in the form of Volume. Containers can use sensitive data in Secret in the form of files or environment variables.
1.2 Create and view Secret
Suppose we want to create a Secret that contains the following information:
(1) User name: Edison
(2) Password: EDC123456*
There are four ways to create Secret:
(1) By - literal:
kubectl create secret generic mysecret --from-literal=username=Edison --from-literal=password=EDC123456*
PS: Each -- from-literal corresponds to an information entry
(2) Through -- from-file:
echo -n Edison > ./username echo -n EDC123456* > ./password kubectl create secret generic mysecret --from-file=./username --from-file=./password
PS: Each file content corresponds to an information entry
(3) Through -- from-env-file:
cat << EOF > env.txt username=Edison password=EDC123456* EOF kubectl create secret generic mysecret --from-env-file=env.txt
PS: Each row of Key=Value in the file env.txt corresponds to an information entry
(4) Create through YAML configuration file: (Recommendation)
Since sensitive data in the configuration file must be encoded by base64, it is necessary to obtain Base64 encoded values:
The following is the content of the YAML file:
apiVersion: v1 kind: Secret metadata: name: edc-secret data: username: RWRpc29u password: RURDMTIzNDU2Kg==
Create Secret through kubectl application:
After the creation is successful, verify and check out the Secret:
kubectl get secret edc-secret // View the existing secret kubectl describe secret edc-secret // View Key entries kubectl edit secret edc-secret // View the Value of the entry
Value is decoded with base64, as shown below, consistent with expectations:
1.3 Use Secret in Pod
There are two ways to use Secret in Pod in K8S, one is Volume mode, the other is environment variable mode.
(1) Volume approach
Here we show an example of how to use Secret through Volume. First, we define a Pod:
apiVersion: v1 kind: Pod metadata: name: secret-demo spec: containers: - name: secret-demo-pod image: busybox args: - /bin/sh - -c - sleep 10; touch /tmp/healthy; sleep 30000 volumeMounts: - name: foo mountPath: "/etc/foo" readOnly: true volumes: - name: foo secret: secretName: edc-secret
The Pod uses the newly defined secret (edc-secret), and then volumeMounts defines the directory where the path from foo mount to container is / etc/foo, and specifies read-write permission as read-only.
After the creation of kubectl application, we try to read secret in the container to verify it, as shown in the following figure:
As you can see, K8S creates a file for each sensitive data, and its Value is stored in plaintext.
Of course, you can also customize the directory where the data is stored, as shown in the following configuration:
apiVersion: v1 kind: Pod metadata: name: secret-demo spec: containers: - name: secret-demo-pod image: busybox args: - /bin/sh - -c - sleep 10; touch /tmp/healthy; sleep 30000 volumeMounts: - name: foo mountPath: "/etc/foo" readOnly: true volumes: - name: foo secret: secretName: edc-secret items: - key: username path: /edc-group/username - key: password path: /edc-group/password
At this point, the secret will be stored in / etc/foo/edc-group/username and / etc/foo/edc-group/password directories.
(2) Dynamic update
One of the advantages of using Secret in Volume mode is that it supports dynamic updates. For example, we will update Secret and re-apply it to K8S:
apiVersion: v1 kind: Secret metadata: name: edc-secret data: username: RWRpc29u password: YWJjZGVmZyo= // For abcdefg*
After the kubectl application is re-applied, wait for a period of time and then enter the container again to verify:
It has been changed to abcdefg*, which meets expectations.
(2) Ways of Environmental Variables
Using Secret through Volume seems a bit cumbersome, and the container has to read data through files. K8S provides another way, that is, the environment variable way.
The following example is to modify the configuration file:
apiVersion: v1 kind: Pod metadata: name: secret-demo spec: containers: - name: secret-demo-pod image: busybox args: - /bin/sh - -c - sleep 10; touch /tmp/healthy; sleep 30000 env: - name: EDC_SECRET_USERNAME valueFrom: secretKeyRef: name: edc-secret key: username - name: EDC_SECRET_PASSWORD valueFrom: secretKeyRef: name: edc-secret key: password
After the application of kubectl application, enter the container to verify:
As you can see, you can easily get Value from environment variables.
_ PS: Note that although it is convenient to read Secret through environment variables, it can not support dynamic update of Secret!
Configmap
2.1 On Configmap
The Secret mentioned above can store confidential data for Pod, while Configmap can be used for some non-confidential sensitive data, such as configuration information for some applications.
Configmap was created and used in a very similar way to Secret, except that the data was stored in plaintext (but I don't think Secret's ciphertext is ciphertext, it's simply encoding).
2.2 Create Configmap
Like Secret, it can be created by -- from-literal, -- from-file and -- from-env-file, so let's skip and go straight to our most commonly used yaml configuration file.
apiVersion: v1 kind: ConfigMap metadata: name: service-configmap data: LogLevel: Error LogFile: service-timestamp.log AllowedHosts: edc.com
2.3 Use Configmap
Like Secret, Configmap can also be used through Volume or environment variables.
(1) Volume approach
apiVersion: v1 kind: Pod metadata: name: configmap-demo spec: containers: - name: configmap-demo-pod image: busybox args: - /bin/sh - -c - sleep 10; touch /tmp/healthy; sleep 30000 volumeMounts: - name: foo mountPath: "/etc/foo" readOnly: true volumes: - name: foo configMap: name: service-configmap
(2) Ways of Environmental Variables
apiVersion: v1 kind: Pod metadata: name: secret-demo spec: containers: - name: secret-demo-pod image: busybox args: - /bin/sh - -c - sleep 10; touch /tmp/healthy; sleep 30000 env: - name: SERVICE_LOG_LEVEL valueFrom: configMapKeyRef: name: service-configmap key: LogLevel - name: SERVICE_LOG_FILE valueFrom: configMapKeyRef: name: service-configmap key: LogFile - name: SERVICE_ALLOWED_HOSTS valueFrom: configMapKeyRef: name: service-configmap key: AllowedHosts
2.4 Best Practices
In most cases, the best practices recommended are:
(1) Create ConfigMap with YAML configuration=> easy to reuse and version management
(2) Read ConfigMap by Volume=> to facilitate configuration of dynamic updates
Next, we create a Configmap whose YAML content is as follows:
apiVersion: v1 kind: ConfigMap metadata: name: service-configmap data: appsettings.json: | LogHandler: NLogHandler LogLevel: Error LogFile: %hostname-%timestamp.log
Note here that don't forget: the following | symbol, and then create & view Configmap:
If you want to use this Configmap in Pod, you can configure it in YAML as follows:
apiVersion: v1 kind: Pod metadata: name: configmap-demo spec: containers: - name: configmap-demo-pod image: busybox args: - /bin/sh - -c - sleep 10; touch /tmp/healthy; sleep 30000 volumeMounts: - name: configmap mountPath: "/etc/configmap" volumes: - name: configmap configMap: name: service-configmap items: - key: appsettings.json path: appsettings.json
Here we mount Volume into the container's / etc/configmap directory. Let's verify that:
At this point, we will update configmap as follows:
apiVersion: v1 kind: ConfigMap metadata: name: service-configmap data: appsettings.json: | Logging: LogLevel: Default: "Error" AllowedHosts: "*"
Update configmap through kubectl application, and then go to pod to verify whether the update is dynamic:
As you can see, it has been updated dynamically and meets expectations!
2.5 ASP.NET Core appSettings
Our configurations in ASP.NET Core are written in the appSettings.json file. How can we convert appSettings.json to ConfigMap? Saint It has been summarized as follows:< NET Core uses the correct posture of K8S Configmap > Interested readers can refer to this article.
Summary
This article explores how to manage configuration in K8S. Secret can be used if ciphertext configuration is required, and ConfigMap can be used if general application configuration is required. Although Secret and ConfigMap both define several definitions, we generally use YAML configuration creation and Volume mode to read, because Volume mode can support dynamic updates. Finally, by sharing an article of St. Jay, I introduce how to use Configmap under ASP.NET Core. I hope it will be helpful to you!