Configmap, Secret va Configuration Management
Mundarija
- Configuration Management Asoslari
- ConfigMap
- Secret
- Environment Variables
- Immutable ConfigMaps va Secrets
- External Secrets
- 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:
- ConfigMap: Non-sensitive configuration
- 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.jsonavtomatik 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:
| ConfigMap | Secret |
|---|---|
| Non-sensitive data | Sensitive data |
| Plain text | Base64 encoded |
| Visible in describe | Hidden in describe |
| No size limit | 1MB 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
- Consistency: O'zgarmas data
- Performance: kube-apiserver load kamayadi
- 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:
- Yangi ConfigMap/Secret yarating (v3)
- Deployment'ni yangilang (app-config-v3)
- Rolling update avtomatik
- 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:
- AWS Secrets Manager
- Azure Key Vault
- Google Secret Manager
- HashiCorp Vault
- 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-secretKubernetes 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>/environorqali 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