Skip to main content

Configmap, Secret va Configuration Management

Mundarija

  1. Configuration Management Asoslari
  2. ConfigMap
  3. Secret
  4. Environment Variables
  5. Immutable ConfigMaps va Secrets
  6. External Secrets
  7. Best Practices

Configuration Management Asoslari

Muammo

Zamonaviy ilovalar ko'p muhitlarda ishlaydi:

  • Development
  • Testing
  • Staging
  • Production

Har bir muhitda turli configuration:

  • Database URLs
  • API endpoints
  • Feature flags
  • Credentials
  • Environment-specific settings

Anti-pattern: Configuration'ni code ichiga hardcode qilish ❌

12-Factor App Principles

III. Config:

"Store config in the environment"

Configuration code'dan ajratilishi kerak:

  • ✅ Environment variables
  • ✅ Config files
  • ✅ External config servers
  • ❌ Hardcoded values

Kubernetes Yechimi

Kubernetes ikkita asosiy resource beradi:

  1. ConfigMap: Non-sensitive configuration
  2. Secret: Sensitive data (passwords, tokens, keys)

Ajratish sabablari:

  • Code va config alohida
  • Bir xil image turli muhitlarda
  • Configuration versioning
  • Runtime'da o'zgartirish

ConfigMap

Ta'rif

ConfigMap - bu key-value juftliklari yoki konfiguratsiya fayllarini saqlash uchun Kubernetes obyekti.

Foydalanish holatlari:

  • Application configuration
  • Command-line arguments
  • Environment variables
  • Configuration files

ConfigMap Yaratish

1. Literal Values

Kubectl orqali:

kubectl create configmap app-config \
--from-literal=database_url=postgres://db:5432/mydb \
--from-literal=log_level=info \
--from-literal=max_connections=100

YAML:

apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: default
data:
database_url: postgres://db:5432/mydb
log_level: info
max_connections: "100"

Eslatma: Barcha qiymatlar string bo'lishi kerak!

2. From File

File yaratish:

cat > app.properties << EOF
server.port=8080
server.host=0.0.0.0
logging.level=INFO
feature.newUI=true
EOF

ConfigMap yaratish:

kubectl create configmap app-config --from-file=app.properties

YAML:

apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
app.properties: |
server.port=8080
server.host=0.0.0.0
logging.level=INFO
feature.newUI=true

3. From Directory

Directory structure:

config/
├── app.properties
├── database.conf
└── logging.xml

ConfigMap yaratish:

kubectl create configmap app-config --from-file=config/

Result:

apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
app.properties: |
server.port=8080
...
database.conf: |
host=db.example.com
...
logging.xml: |
<configuration>
...

4. From Env File

Env file:

cat > database.env << EOF
DB_HOST=postgres.example.com
DB_PORT=5432
DB_NAME=myapp
DB_USER=admin
EOF

ConfigMap yaratish:

kubectl create configmap db-config --from-env-file=database.env

YAML:

apiVersion: v1
kind: ConfigMap
metadata:
name: db-config
data:
DB_HOST: postgres.example.com
DB_PORT: "5432"
DB_NAME: myapp
DB_USER: admin

ConfigMap Ishlatish

1. Environment Variables Sifatida

Barcha key'lar:

apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: myapp:1.0
envFrom:
- configMapRef:
name: app-config

Pod ichida:

echo $database_url
echo $log_level
echo $max_connections

Alohida key'lar:

apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: myapp:1.0
env:
- name: DATABASE_URL
valueFrom:
configMapKeyRef:
name: app-config
key: database_url
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: app-config
key: log_level

Prefix bilan:

spec:
containers:
- name: app
image: myapp:1.0
envFrom:
- configMapRef:
name: app-config
prefix: APP_

Pod ichida:

echo $APP_database_url
echo $APP_log_level

2. Volume Sifatida

Barcha key'lar:

apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: myapp:1.0
volumeMounts:
- name: config
mountPath: /etc/config
volumes:
- name: config
configMap:
name: app-config

File'lar:

/etc/config/database_url
/etc/config/log_level
/etc/config/max_connections

Specific key'lar:

volumes:
- name: config
configMap:
name: app-config
items:
- key: database_url
path: db.conf
- key: log_level
path: logging.conf

File'lar:

/etc/config/db.conf
/etc/config/logging.conf

Permissions:

volumes:
- name: config
configMap:
name: app-config
defaultMode: 0644

3. Command Arguments

apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: myapp:1.0
command: ["/bin/myapp"]
args:
- "--port=$(SERVER_PORT)"
- "--host=$(SERVER_HOST)"
env:
- name: SERVER_PORT
valueFrom:
configMapKeyRef:
name: app-config
key: server.port
- name: SERVER_HOST
valueFrom:
configMapKeyRef:
name: app-config
key: server.host

ConfigMap Yangilash

Edit:

kubectl edit configmap app-config

Apply:

# app-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
database_url: postgres://new-db:5432/mydb # Yangilandi
log_level: debug # Yangilandi
max_connections: "200" # Yangilandi
kubectl apply -f app-config.yaml

Patch:

kubectl patch configmap app-config -p '{"data":{"log_level":"debug"}}'

ConfigMap Update Propagation

Volume mount:

  • Automatic update (bir necha soniyadan keyin)
  • Symbolic link orqali
  • Pod restart kerak emas

Environment variables:

  • ❌ Avtomatik yangilanmaydi
  • Pod restart kerak

Misol:

ConfigMap:

data:
config.json: |
{
"version": "1.0"
}

Pod (volume):

volumeMounts:
- name: config
mountPath: /etc/config

ConfigMap yangilash:

data:
config.json: |
{
"version": "2.0"
}

Natija:

  • File /etc/config/config.json avtomatik yangilanadi
  • Application'ni reload qilish kerak (signal, inotify, polling)

ConfigMap Binary Data

Binary file'lar uchun binaryData:

apiVersion: v1
kind: ConfigMap
metadata:
name: binary-config
binaryData:
image.png: iVBORw0KGgoAAAANSUhEUgAA... # base64
data:
text.txt: Hello World

Yaratish:

kubectl create configmap binary-config \
--from-file=image.png \
--from-literal=text.txt="Hello World"

Secret

Ta'rif

Secret - bu parol, token, key kabi sensitive ma'lumotlarni saqlash uchun Kubernetes obyekti.

Secret vs ConfigMap:

ConfigMapSecret
Non-sensitive dataSensitive data
Plain textBase64 encoded
Visible in describeHidden in describe
No size limit1MB limit

⚠️ Muhim: Secret'lar base64 encoded, lekin ENCRYPT qilinmagan!

Secret Turlari

Kubernetes bir nechta built-in secret type'larini qo'llab-quvvatlaydi:

1. Opaque (default)

Generic secret, istalgan data.

apiVersion: v1
kind: Secret
metadata:
name: my-secret
type: Opaque
data:
username: YWRtaW4= # admin (base64)
password: cGFzc3dvcmQxMjM= # password123 (base64)

2. kubernetes.io/service-account-token

ServiceAccount uchun token.

apiVersion: v1
kind: Secret
metadata:
name: sa-token
annotations:
kubernetes.io/service-account.name: my-sa
type: kubernetes.io/service-account-token

3. kubernetes.io/dockerconfigjson

Docker registry authentication.

apiVersion: v1
kind: Secret
metadata:
name: docker-secret
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: eyJhdXRocyI6eyJodHRwczovL2luZGV4LmRvY2tlci5pby92MS8iOnsidXNlcm5hbWUiOiJ1c2VyIiwicGFzc3dvcmQiOiJwYXNzIiwiZW1haWwiOiJ1c2VyQGV4YW1wbGUuY29tIiwiYXV0aCI6ImRYTmxjanB3WVhOeiJ9fX0=

4. kubernetes.io/basic-auth

Basic authentication.

apiVersion: v1
kind: Secret
metadata:
name: basic-auth
type: kubernetes.io/basic-auth
data:
username: YWRtaW4=
password: cGFzc3dvcmQ=

5. kubernetes.io/ssh-auth

SSH authentication.

apiVersion: v1
kind: Secret
metadata:
name: ssh-key
type: kubernetes.io/ssh-auth
data:
ssh-privatekey: LS0tLS1CRUdJTi...

6. kubernetes.io/tls

TLS certificate va private key.

apiVersion: v1
kind: Secret
metadata:
name: tls-secret
type: kubernetes.io/tls
data:
tls.crt: LS0tLS1CRUdJTi...
tls.key: LS0tLS1CRUdJTi...

Secret Yaratish

1. Kubectl Generic

kubectl create secret generic db-secret \
--from-literal=username=admin \
--from-literal=password=secret123

2. From File

echo -n 'admin' > username.txt
echo -n 'secret123' > password.txt

kubectl create secret generic db-secret \
--from-file=username=username.txt \
--from-file=password=password.txt

3. YAML (manual base64)

Base64 encode:

echo -n 'admin' | base64
# YWRtaW4=

echo -n 'secret123' | base64
# c2VjcmV0MTIz

YAML:

apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
data:
username: YWRtaW4=
password: c2VjcmV0MTIz

4. YAML (stringData)

Soddaroq usul:

apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
stringData:
username: admin
password: secret123

Kubernetes avtomatik base64'ga encode qiladi.

5. Docker Registry Secret

kubectl create secret docker-registry regcred \
--docker-server=https://index.docker.io/v1/ \
--docker-username=myuser \
--docker-password=mypassword \
--docker-email=myemail@example.com

6. TLS Secret

kubectl create secret tls tls-secret \
--cert=path/to/tls.crt \
--key=path/to/tls.key

Secret Ishlatish

1. Environment Variables

Barcha key'lar:

apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: myapp:1.0
envFrom:
- secretRef:
name: db-secret

Alohida key'lar:

apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: myapp:1.0
env:
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: db-secret
key: username
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: password

2. Volume

apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: myapp:1.0
volumeMounts:
- name: secret
mountPath: /etc/secret
readOnly: true
volumes:
- name: secret
secret:
secretName: db-secret

File'lar:

/etc/secret/username  (decoded: admin)
/etc/secret/password (decoded: secret123)

Specific keys:

volumes:
- name: secret
secret:
secretName: db-secret
items:
- key: username
path: db-username
- key: password
path: db-password

Permissions:

volumes:
- name: secret
secret:
secretName: db-secret
defaultMode: 0400 # Read-only

3. ImagePullSecrets

Private registry'dan image pull qilish:

apiVersion: v1
kind: Pod
metadata:
name: private-pod
spec:
imagePullSecrets:
- name: regcred
containers:
- name: app
image: private-registry.com/myapp:1.0

Secret Ko'rish

List:

kubectl get secrets

Describe (value hidden):

kubectl describe secret db-secret

Output:

Name:         db-secret
Namespace: default
Labels: <none>
Annotations: <none>

Type: Opaque

Data
====
password: 9 bytes
username: 5 bytes

Get value (base64):

kubectl get secret db-secret -o yaml

Decode:

kubectl get secret db-secret -o jsonpath='{.data.password}' | base64 -d

Secret Encryption at Rest

Default holatda Secret'lar etcd'da encrypt qilinmaydi!

Encryption Configuration:

apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
- aescbc:
keys:
- name: key1
secret: <32-byte base64 encoded string>
- identity: {}

API Server flag:

--encryption-provider-config=/etc/kubernetes/encryption-config.yaml

Encrypt existing secrets:

kubectl get secrets --all-namespaces -o json | kubectl replace -f -

Environment Variables

Pod Environment

1. Static Values

spec:
containers:
- name: app
image: myapp:1.0
env:
- name: ENVIRONMENT
value: "production"
- name: LOG_LEVEL
value: "info"

2. Field References

Pod metadata'dan qiymatlar:

env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName

3. Resource References

Container resource limits/requests:

env:
- name: CPU_REQUEST
valueFrom:
resourceFieldRef:
containerName: app
resource: requests.cpu
- name: MEMORY_LIMIT
valueFrom:
resourceFieldRef:
containerName: app
resource: limits.memory

4. ConfigMap va Secret

Yuqorida ko'rsatilgan.

Environment Variable Expansion

env:
- name: SERVICE_URL
value: "http://$(SERVICE_HOST):$(SERVICE_PORT)"
- name: SERVICE_HOST
value: "api.example.com"
- name: SERVICE_PORT
value: "8080"

Result:

SERVICE_URL=http://api.example.com:8080

Immutable ConfigMaps va Secrets

Muammo

ConfigMap/Secret o'zgartirilsa:

  • Pods'larga inconsistent data
  • Race conditions
  • Update propagation issues

Yechim: Immutable

Immutable ConfigMap:

apiVersion: v1
kind: ConfigMap
metadata:
name: app-config-v1
data:
database_url: postgres://db:5432/mydb
immutable: true

Immutable Secret:

apiVersion: v1
kind: Secret
metadata:
name: db-secret-v1
type: Opaque
data:
password: c2VjcmV0MTIz
immutable: true

Afzalliklar

  1. Consistency: O'zgarmas data
  2. Performance: kube-apiserver load kamayadi
  3. Safety: Accidental changes oldini olish

Versioning Pattern

Version-based naming:

app-config-v1
app-config-v2
db-secret-v1
db-secret-v2

Deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
template:
spec:
containers:
- name: app
envFrom:
- configMapRef:
name: app-config-v2 # Version o'zgartirildi
- secretRef:
name: db-secret-v2 # Version o'zgartirildi

Rolling update:

  1. Yangi ConfigMap/Secret yarating (v3)
  2. Deployment'ni yangilang (app-config-v3)
  3. Rolling update avtomatik
  4. Eski version'larni o'chiring

External Secrets

Muammo

Kubernetes Secret'lar:

  • etcd'da saqlanadi
  • Git'da saqlash xavfli
  • Centralized secret management yo'q

Yechim: External Secret Operator

External Secret Manager'lar:

  1. AWS Secrets Manager
  2. Azure Key Vault
  3. Google Secret Manager
  4. HashiCorp Vault
  5. Doppler

External Secrets Operator

Architecture:

External Secret → Operator → Cloud Secret Manager

Kubernetes Secret

ExternalSecret CRD:

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: db-secret
spec:
refreshInterval: 1h
secretStoreRef:
name: aws-secrets-manager
kind: SecretStore
target:
name: db-secret
creationPolicy: Owner
data:
- secretKey: username
remoteRef:
key: prod/db/username
- secretKey: password
remoteRef:
key: prod/db/password

SecretStore:

apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
name: aws-secrets-manager
spec:
provider:
aws:
service: SecretsManager
region: us-east-1
auth:
jwt:
serviceAccountRef:
name: external-secrets

Natija:

  • db-secret Kubernetes Secret avtomatik yaratiladi
  • AWS Secrets Manager'dan sync qilinadi
  • 1 soatda bir yangilanadi

Sealed Secrets

Muammo: Git'da Secret'larni qanday saqlash?

Yechim: Sealed Secrets (Bitnami)

Architecture:

Secret → kubeseal → SealedSecret (encrypted)

Git repository

kubectl apply

Controller decrypt

Kubernetes Secret

SealedSecret yaratish:

kubectl create secret generic mysecret \
--from-literal=password=secret123 \
--dry-run=client -o yaml | \
kubeseal -o yaml > mysealedsecret.yaml

mysealedsecret.yaml:

apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: mysecret
spec:
encryptedData:
password: AgBQHW8... # Encrypted

Apply:

kubectl apply -f mysealedsecret.yaml

Controller decrypt qiladi va mysecret Secret yaratadi.


Best Practices

1. ConfigMap Best Practices

Naming Convention

<app>-<env>-config
myapp-prod-config
myapp-dev-config

Versioning

myapp-config-v1
myapp-config-v2

Namespace Organization

# Development
kubectl create configmap app-config -n development

# Production
kubectl create configmap app-config -n production

Size Limit

  • ConfigMap: 1MB limit
  • Ko'p data bo'lsa, volume/storage ishlatish

Hot Reload

Application'da config reload:

  • File watcher (inotify)
  • Signal handling (SIGHUP)
  • Polling

2. Secret Best Practices

Encryption at Rest

Doim enable qiling!

Access Control

RBAC:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "list"]
resourceNames: ["db-secret"] # Specific secret

External Secret Management

Production'da:

  • AWS Secrets Manager
  • HashiCorp Vault
  • Azure Key Vault

Avoid Environment Variables

Secret'larni environment variable sifatida emas, volume sifatida ishlatish yaxshiroq:

  • /proc/<pid>/environ orqali ko'rinmaydi
  • Logs'ga tushmaydi

Rotation

Secret'larni muntazam o'zgartirish:

  • Automated rotation
  • Zero-downtime rotation

3. General Best Practices

Separation of Concerns

app-config  → Application settings
db-config → Database configuration
api-config → API endpoints

Documentation

ConfigMap/Secret'larda annotation:

metadata:
annotations:
description: "Database configuration for production"
owner: "platform-team"
version: "2.0"

Testing

Test muhitda:

# Create test configmap
kubectl create configmap test-config \
--from-literal=env=test \
-n testing

# Test pod
kubectl run test-pod \
--image=busybox \
--restart=Never \
-n testing \
--env="CONFIG_ENV=$(kubectl get cm test-config -o jsonpath='{.data.env}')"

Monitoring

ConfigMap/Secret o'zgarishlarini monitor qiling:

  • Audit logs
  • GitOps (ArgoCD, Flux)
  • Version control

Xulosa

Configuration Management Kubernetes'da juda muhim:

ConfigMap: Non-sensitive configuration ✅ Secret: Sensitive data (passwords, tokens) ✅ Environment Variables: Runtime configuration ✅ Immutable: Consistency va performance ✅ External Secrets: Centralized secret management ✅ Best Practices: Security, versioning, monitoring