ConfigMaps vs Secrets (big picture)
Both are ways to inject configuration into Pods without baking it into container images.
| Feature | ConfigMap | Secret |
|---|---|---|
| Purpose | Non-sensitive config | Sensitive data |
| Examples | URLs, feature flags, env names | Passwords, tokens, certs |
| Stored in etcd | Plaintext | Base64-encoded (not encrypted by default) |
| Size limit | ~1MB | ~1MB |
| Can be env vars | Yes | Yes |
| Can be mounted as files | Yes | Yes |
Let’s try it!
- Create new dotnet api
add configuration for configmap and secret in appsettings.json:
"AppConfig": {
"ServiceName": "My Awesome API"
},
"UserConfig":{
"SecretPassword": "User Secret"
},
In program.cs, let’s assign variables to the configurations
var serviceName = builder.Configuration["AppConfig:ServiceName"]; // Access the ConfigMap value
var userPassword = builder.Configuration["UserConfig:SecretPassword "]; // Access the Secret value
var app = builder.Build();
Create a controller to view the configs:
app.MapGet("/getconfigs", () =>
{
var response = new {
Version = "V1",
Service = serviceName,
Password = userPassword,
Machine = System.Environment.MachineName
};
Console.WriteLine(response);
return Results.Ok(response);
});
When you run the application, the resul should be:
$ curl http://localhost:5128/getconfigs
{"version":"V1","service":"My Awesome API","password":"User Secret","machine":"My-MacBook-Air"- Build and image for the application
Create a Docker file:
# Build stage
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY . .
RUN dotnet restore
RUN dotnet publish -c Release -o /app/publish
# Runtime stage
FROM mcr.microsoft.com/dotnet/aspnet:8.0
WORKDIR /app
COPY --from=build /app/publish .
EXPOSE 8080
ENTRYPOINT ["dotnet", "my-dotnet-api.dll"]
Build the image:
$ docker build --no-cache -t my-dotnet-api:latest . --no-cache- Create configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: dotnet-app-config
data:
# Example non-sensitive key-value pairs
SERVICE_NAME: "My Awesome API!!!"
- Create secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: dotnet-app-secret
type: Opaque
data:
# Base64 encoded: "s3cretP@ssw0rd"
PASSWORD: "czNyZXRQQHNzd2ByZA=="
- Create service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-dotnet-api-service
spec:
type: LoadBalancer
selector:
app: my-dotnet-api
ports:
- protocol: TCP
port: 80
targetPort: 8080
- Create deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-dotnet-api-deployment
spec:
replicas: 4
selector:
matchLabels:
app: my-dotnet-api
template:
metadata:
labels:
app: my-dotnet-api
spec:
containers:
- name: my-dotnet-api
image: my-dotnet-api:latest
imagePullPolicy: Always #Default: IfNotPresent
ports:
- containerPort: 8080
env:
# Get non-sensitive environment variables from the ConfigMap
- name: APPCONFIG__SERVICENAME # .NET Core configuration format
valueFrom:
configMapKeyRef:
name: dotnet-app-config
key: SERVICE_NAME
# Get sensitive environment variables from the Secret
- name: USERCONFIG__SECRETPASSWORD
valueFrom:
secretKeyRef:
name: dotnet-app-secret
key: PASSWORD
- Let’s test our work, apply our yaml files and see the result:
$ kubectl apply -f configmap.yaml
configmap/dotnet-app-config created
$ kubectl apply -f secret.yaml
secret/dotnet-app-secret created
$ kubectl apply -f service.yaml
service/my-dotnet-api-service created
$ kubectl apply -f deployment.yaml
deployment.apps/my-dotnet-api-deployment created
$ curl http://localhost/getconfigs
{"version":"V1","service":"My Awesome API!!!","password":"s3retP@ssw`rd","machine":"my-dotnet-api-deployment-7494d875f5-mmm42"} What if we have some changes in the Configmap? here’s what you can do:
We made some changes in the value for the SERVICE_NAME
configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: dotnet-app-config
data:
# Example non-sensitive key-value pairs
SERVICE_NAME: "My Awesome API Updated!"
We have 2 options to apply the changes:
- kubectl rollout restart deployment my-app
$ kubectl apply -f configmap.yaml
configmap/dotnet-app-config configured
$ kubectl rollout restart deployment my-dotnet-api-deployment
deployment.apps/my-dotnet-api-deployment restarted
$ curl http://localhost/getconfigs
{"version":"V1","service":"My Awesome API Updated!","password":"s3retP@ssw`rd","machine":"my-dotnet-api-deployment-54bb4888f4-mnfd8"} - Delete all pods: kubectl delete pod <pod-name>
(New Pods will pick up the updated ConfigMap)
Note: When you re-applied the configmap, the result says: configured, meaning the changes were applied, however, if there are no changes, the result will be: configmap/dotnet-app-config unchanged
To Clean Up:
kubectl delete deployment my-dotnet-api-deployment
kubectl delete service my-dotnet-api-service
kubectl delete secret dotnet-app-secret
kubectl delete configmap dotnet-app-config