Production security best practices
Когда первичная защита (SecurityContext + RBAC + PSA) на месте, начинается работа над глубиной обороны: что делать с images, как хранить secrets вне etcd, как изолировать трафик NetworkPolicies, как настраивать audit log. На CKAD это уровень знания концепций — экзамен не требует настроить Falco или Vault, но ожидает что вы понимаете, в каком слое работает каждая практика и почему. В production это превращается в чеклист security review.
Trivy и Docker Scout: сканеры CVE для образов
Image security
containers:
- name: app
# 1. Pin digest — не tag
image: registry.example.com/app@sha256:e8c4ab3fb1e2...
# ИЛИ хотя бы immutable tag
# image: registry.example.com/app:1.4.2-2026-04-15
image: nginx без tag — это nginx:latest, который завтра может быть чем-то совсем другим. Никогда не используйте latest в production — это блокирует rollback (нет конкретной версии для отката) и делает поведение не reproducible.
Pod hardening: must-have checklist
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 2000
seccompProfile:
type: RuntimeDefault
containers:
- name: app
image: registry.example.com/app@sha256:...
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: [ALL]
add: [NET_BIND_SERVICE]
resources:
requests:
memory: 64Mi
cpu: 100m
limits:
memory: 256Mi
cpu: 500m
volumeMounts:
- name: tmp
mountPath: /tmp
volumes:
- name: tmp
emptyDir: {}
Минимальный hardening:
- runAsNonRoot + runAsUser явный — нельзя бежать под root.
- allowPrivilegeEscalation: false — no_new_privs.
- readOnlyRootFilesystem: true + emptyDir для tmp — нельзя писать в
/. - capabilities drop ALL + явный add для нужных.
- seccompProfile RuntimeDefault — стандартный seccomp filter блокирует опасные syscalls.
- resources requests + limits — защита от resource exhaustion.
Secrets management
K8s Secret — это base64-encoded payload в etcd. Это не encryption. Кто получил доступ к etcd backup, получил все Secrets кластера.
Default K8s Secret в etcd — это лишь base64, не шифрование. Любой с read доступом к etcd (или его backup) видит все Secrets кластера в plaintext. Encryption at rest на kube-apiserver — must-have для production. KMS-based — best-practice.
Network security
Default-deny NetworkPolicy в каждом namespace — фундамент zero-trust:
# 1. Default-deny всё (ingress + egress)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
namespace: production
spec:
podSelector: {}
policyTypes: [Ingress, Egress]
---
# 2. Allow DNS (нужен почти всем)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns
namespace: production
spec:
podSelector: {}
policyTypes: [Egress]
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- port: 53
protocol: UDP
- port: 53
protocol: TCP
---
# 3. Specific allow rules для каждого приложения
Для зашифрованного service-to-service:
- mTLS через service mesh: Istio, Linkerd. Automatic certificate rotation, identity-based authorization, traffic encryption — без изменения кода приложений.
- SPIFFE / SPIRE identities — стандарт для workload identity, leveraged by Istio/Linkerd.
Least privilege RBAC
Принцип: каждый Pod / SA получает только нужные permissions:
# Plохо: дать app-sa cluster-admin для удобства
# Хорошо: точечная Role
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: app-permissions
namespace: production
rules:
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["app-config"] # ТОЛЬКО этот ConfigMap
verbs: ["get", "watch"]
Audit logging
kube-apiserver может логировать каждый API-запрос в audit log. Это критично для:
- Incident response — кто что сделал и когда.
- Compliance (SOC 2, ISO 27001, HIPAA) — proof что доступ контролируется.
- Detection of malicious activity — например, неожиданные
get secretsпод compromised SA.
# Пример audit policy на kube-apiserver
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
# Логировать всё что касается Secrets — RequestResponse (полный payload)
- level: RequestResponse
resources:
- group: ""
resources: ["secrets"]
# Логировать RBAC изменения
- level: RequestResponse
resources:
- group: "rbac.authorization.k8s.io"
resources: ["*"]
# Минимальный лог для всего остального — Metadata only
- level: Metadata
Apiserver запускается с флагами --audit-policy-file=... и --audit-log-path=.... Audit logs обычно отправляют в SIEM (Splunk, Elastic) для корреляции.
На CKAD: знать что audit policy существует и конфигурируется на kube-apiserver. Самим написать policy не требуется — это работа cluster-admin. На задачах вас могут попросить найти audit log при наличии — обычно в /var/log/audit/audit.log на control plane node.
Supply chain: SLSA уровни
SLSA (Supply chain Levels for Software Artifacts, v1.0 release — 2023) — фреймворк для оценки security supply chain. С v1.0 уровни организованы по трекам (Build, Source) и привязаны к конкретному треку. Самый используемый — Build Track:
- Build L1 — build process documented, есть provenance.
- Build L2 — provenance подписан, build server tamper-resistant.
- Build L3 — build platform изолирована, hosted/managed, provenance non-forgeable.
(SLSA 1.0 убрал «Build L4» из активных уровней — пункт hermetic/reproducible builds перенесён в advisory.)
В K8s контексте: подписанные images (cosign), provenance (in-toto attestations), build на hosted CI с trusted builders (GitHub Actions OIDC + sigstore). На CKAD концепции хватит.