От проверки кластера до прохождения сертификации регулятора
— что мы видим у клиентов и как это исправить
# Role: разрешаем только pods и deployments в namespace dev
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: dev
name: dev-team-role
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
---
# RoleBinding: привязываем роль к группе
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
namespace: dev
name: dev-team-binding
subjects:
- kind: Group
name: "dev-team"
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: dev-team-role
apiGroup: rbac.authorization.k8s.io apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
# enforce = блокирует поды, нарушающие политику
pod-security.kubernetes.io/enforce: "baseline"
pod-security.kubernetes.io/enforce-version: "latest"
# warn = предупреждает, но не блокирует (для тестирования restricted)
pod-security.kubernetes.io/warn: "restricted"
pod-security.kubernetes.io/warn-version: "latest"
# audit = пишет в лог (для мониторинга)
pod-security.kubernetes.io/audit: "restricted"
pod-security.kubernetes.io/audit-version: "latest" apiVersion: v1
kind: Pod
metadata:
name: secure-app
namespace: production
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
seccompProfile:
type: RuntimeDefault
containers:
- name: app
image: myregistry.kz/app:v1.2.3@sha256:abc123...
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
resources:
limits:
cpu: "500m"
memory: "256Mi"
requests:
cpu: "100m"
memory: "128Mi"
volumeMounts:
- name: tmp
mountPath: /tmp
volumes:
- name: tmp
emptyDir: {} # Шаг 1: запретить весь трафик в namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
namespace: production
spec:
podSelector: {} # применяется ко ВСЕМ подам
policyTypes:
- Ingress
- Egress
---
# Шаг 2: разрешить frontend → backend на порту 8080
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: production
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
---
# Шаг 3: разрешить backend → postgres на порту 5432
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-backend-to-db
namespace: production
spec:
podSelector:
matchLabels:
app: postgres
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: backend
ports:
- protocol: TCP
port: 5432 # ❌ ПЛОХО: секрет в переменной окружения — попадёт в логи и env dump
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
# ✅ ХОРОШО: секрет через volume — доступен только как файл
volumeMounts:
- name: db-creds
mountPath: /etc/secrets/db
readOnly: true
volumes:
- name: db-creds
secret:
secretName: db-credentials
defaultMode: 0400 # только чтение для владельца