ΠΠ°Π±Π΅Π»Π΅ΠΆΠΊΠ°. ΠΏΡΠ΅Π²ΠΎΠ΄: Π‘ Π½Π°ΡΠ°ΡΡΠ²Π°ΡΠΈΡ Π±ΡΠΎΠΉ YAML ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ Π·Π° K8s ΡΡΠ΅Π΄ΠΈ, Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΡΠ° ΠΎΡ ΡΡΡ Π½Π°ΡΠ° Π°Π²ΡΠΎΠΌΠ°ΡΠΈΠ·ΠΈΡΠ°Π½Π° ΠΏΡΠΎΠ²Π΅ΡΠΊΠ° ΡΡΠ°Π²Π° Π²ΡΠ΅ ΠΏΠΎ-ΡΠΏΠ΅ΡΠ½Π°. ΠΠ²ΡΠΎΡΡΡ Π½Π° ΡΠΎΠ·ΠΈ ΠΏΡΠ΅Π³Π»Π΅Π΄ Π½Π΅ ΡΠ°ΠΌΠΎ Π΅ ΠΈΠ·Π±ΡΠ°Π» ΡΡΡΠ΅ΡΡΠ²ΡΠ²Π°ΡΠΈ ΡΠ΅ΡΠ΅Π½ΠΈΡ Π·Π° ΡΠ°Π·ΠΈ Π·Π°Π΄Π°ΡΠ°, Π½ΠΎ Π΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π» ΠΈ Deployment ΠΊΠ°ΡΠΎ ΠΏΡΠΈΠΌΠ΅Ρ, Π·Π° Π΄Π° Π²ΠΈΠ΄ΠΈ ΠΊΠ°ΠΊ ΡΠ°Π±ΠΎΡΡΡ. ΠΠΊΠ°Π·Π° ΡΠ΅ ΠΌΠ½ΠΎΠ³ΠΎ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΠ²Π½ΠΎ Π·Π° ΡΠ΅Π·ΠΈ, ΠΊΠΎΠΈΡΠΎ ΡΠ΅ ΠΈΠ½ΡΠ΅ΡΠ΅ΡΡΠ²Π°Ρ ΠΎΡ ΡΠ°Π·ΠΈ ΡΠ΅ΠΌΠ°.
TL; DR: Π’Π°Π·ΠΈ ΡΡΠ°ΡΠΈΡ ΡΡΠ°Π²Π½ΡΠ²Π° ΡΠ΅ΡΡ ΡΡΠ°ΡΠΈΡΠ½ΠΈ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠ° Π·Π° Π²Π°Π»ΠΈΠ΄ΠΈΡΠ°Π½Π΅ ΠΈ ΠΎΡΠ΅Π½ΠΊΠ° Π½Π° Kubernetes YAML ΡΠ°ΠΉΠ»ΠΎΠ²Π΅ ΡΠΏΡΡΠΌΠΎ Π½Π°ΠΉ-Π΄ΠΎΠ±ΡΠΈΡΠ΅ ΠΏΡΠ°ΠΊΡΠΈΠΊΠΈ ΠΈ ΠΈΠ·ΠΈΡΠΊΠ²Π°Π½ΠΈΡ.
Π Π°Π±ΠΎΡΠ½ΠΈΡΠ΅ Π½Π°ΡΠΎΠ²Π°ΡΠ²Π°Π½ΠΈΡ Π½Π° Kubernetes ΠΎΠ±ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ΠΎ ΡΠ΅ Π΄Π΅ΡΠΈΠ½ΠΈΡΠ°Ρ ΠΏΠΎΠ΄ ΡΠΎΡΠΌΠ°ΡΠ° Π½Π° YAML Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠΈ. ΠΠ΄ΠΈΠ½ ΠΎΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠΈΡΠ΅ Ρ YAML Π΅ ΡΡΡΠ΄Π½ΠΎΡΡΡΠ° ΠΏΡΠΈ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ½Π΅ Π½Π° ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΡ ΠΈΠ»ΠΈ Π²ΡΡΠ·ΠΊΠΈ ΠΌΠ΅ΠΆΠ΄Ρ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠ½ΠΈΡΠ΅ ΡΠ°ΠΉΠ»ΠΎΠ²Π΅.
ΠΠ°ΠΊΠ²ΠΎ ΡΠ΅ ΡΡΠ°Π½Π΅, Π°ΠΊΠΎ ΡΡΡΠ±Π²Π° Π΄Π° ΡΠ΅ ΡΠ²Π΅ΡΠΈΠΌ, ΡΠ΅ Π²ΡΠΈΡΠΊΠΈ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ, ΡΠ°Π·ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈ Π² ΠΊΠ»ΡΡΡΠ΅ΡΠ°, ΠΈΠ΄Π²Π°Ρ ΠΎΡ Π΄ΠΎΠ²Π΅ΡΠ΅Π½ ΡΠ΅Π³ΠΈΡΡΡΡ?
ΠΠ°ΠΊ ΠΌΠΎΠ³Π° Π΄Π° ΠΏΡΠ΅Π΄ΠΎΡΠ²ΡΠ°ΡΡ ΠΈΠ·ΠΏΡΠ°ΡΠ°Π½Π΅ΡΠΎ Π½Π° ΡΠ°Π·ΠΏΠΎΠ»Π°Π³Π°Π½ΠΈΡ, ΠΊΠΎΠΈΡΠΎ Π½ΡΠΌΠ°Ρ PodDisruptionBudgets, ΠΊΡΠΌ ΠΊΠ»ΡΡΡΠ΅ΡΠ°?
ΠΠ½ΡΠ΅Π³ΡΠΈΡΠ°Π½Π΅ΡΠΎ Π½Π° ΡΡΠ°ΡΠΈΡΠ½ΠΎ ΡΠ΅ΡΡΠ²Π°Π½Π΅ Π²ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ²Π° Π΄Π° ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΡΠΈΡΠ°ΡΠ΅ Π³ΡΠ΅ΡΠΊΠΈ ΠΈ Π½Π°ΡΡΡΠ΅Π½ΠΈΡ Π½Π° ΠΏΡΠ°Π²ΠΈΠ»Π°ΡΠ° Π½Π° Π΅ΡΠ°ΠΏΠ° Π½Π° ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠ°. Π’ΠΎΠ²Π° ΡΠ²Π΅Π»ΠΈΡΠ°Π²Π° Π³Π°ΡΠ°Π½ΡΠΈΡΡΠ°, ΡΠ΅ Π΄Π΅ΡΠΈΠ½ΠΈΡΠΈΠΈΡΠ΅ Π½Π° ΡΠ΅ΡΡΡΡΠΈΡΠ΅ ΡΠ° ΠΏΡΠ°Π²ΠΈΠ»Π½ΠΈ ΠΈ ΡΠΈΠ³ΡΡΠ½ΠΈ ΠΈ ΠΏΡΠ°Π²ΠΈ ΠΏΠΎ-Π²Π΅ΡΠΎΡΡΠ½ΠΎ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΡΡΠ²Π΅Π½ΠΈΡΠ΅ Π½Π°ΡΠΎΠ²Π°ΡΠ²Π°Π½ΠΈΡ Π΄Π° ΡΠ»Π΅Π΄Π²Π°Ρ Π½Π°ΠΉ-Π΄ΠΎΠ±ΡΠΈΡΠ΅ ΠΏΡΠ°ΠΊΡΠΈΠΊΠΈ.
Π‘ΡΠ°ΡΠΈΡΠ½Π°ΡΠ° Π΅ΠΊΠΎΡΠΈΡΡΠ΅ΠΌΠ° Π·Π° ΠΏΡΠΎΠ²Π΅ΡΠΊΠ° Π½Π° YAML ΡΠ°ΠΉΠ»ΠΎΠ²Π΅ Π½Π° Kubernetes ΠΌΠΎΠΆΠ΅ Π΄Π° Π±ΡΠ΄Π΅ ΡΠ°Π·Π΄Π΅Π»Π΅Π½Π° Π½Π° ΡΠ»Π΅Π΄Π½ΠΈΡΠ΅ ΠΊΠ°ΡΠ΅Π³ΠΎΡΠΈΠΈ:
- API Π²Π°Π»ΠΈΠ΄Π°ΡΠΎΡΠΈ. ΠΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠΈΡΠ΅ Π² ΡΠ°Π·ΠΈ ΠΊΠ°ΡΠ΅Π³ΠΎΡΠΈΡ ΠΏΡΠΎΠ²Π΅ΡΡΠ²Π°Ρ YAML ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠ° ΡΠΏΡΡΠΌΠΎ ΠΈΠ·ΠΈΡΠΊΠ²Π°Π½ΠΈΡΡΠ° Π½Π° Kubernetes API ΡΡΡΠ²ΡΡΠ°.
- ΠΠΎΡΠΎΠ²ΠΈ ΡΠ΅ΡΡΠ΅ΡΠΈ. ΠΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠΈΡΠ΅ ΠΎΡ ΡΠ°Π·ΠΈ ΠΊΠ°ΡΠ΅Π³ΠΎΡΠΈΡ ΠΈΠ΄Π²Π°Ρ Ρ Π³ΠΎΡΠΎΠ²ΠΈ ΡΠ΅ΡΡΠΎΠ²Π΅ Π·Π° ΡΠΈΠ³ΡΡΠ½ΠΎΡΡ, ΡΡΠΎΡΠ²Π΅ΡΡΡΠ²ΠΈΠ΅ Ρ Π½Π°ΠΉ-Π΄ΠΎΠ±ΡΠΈΡΠ΅ ΠΏΡΠ°ΠΊΡΠΈΠΊΠΈ ΠΈ Π΄Ρ.
- ΠΠ΅ΡΡΠΎΠ½Π°Π»ΠΈΠ·ΠΈΡΠ°Π½ΠΈ Π²Π°Π»ΠΈΠ΄Π°ΡΠΎΡΠΈ. ΠΡΠ΅Π΄ΡΡΠ°Π²ΠΈΡΠ΅Π»ΠΈΡΠ΅ Π½Π° ΡΠ°Π·ΠΈ ΠΊΠ°ΡΠ΅Π³ΠΎΡΠΈΡ Π²ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ²Π°Ρ Π΄Π° ΡΡΠ·Π΄Π°Π²Π°ΡΠ΅ ΠΏΠ΅ΡΡΠΎΠ½Π°Π»ΠΈΠ·ΠΈΡΠ°Π½ΠΈ ΡΠ΅ΡΡΠΎΠ²Π΅ Π½Π° ΡΠ°Π·Π»ΠΈΡΠ½ΠΈ Π΅Π·ΠΈΡΠΈ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ Rego ΠΈ Javascript.
Π ΡΠ°Π·ΠΈ ΡΡΠ°ΡΠΈΡ ΡΠ΅ ΠΎΠΏΠΈΡΠ΅ΠΌ ΠΈ ΡΡΠ°Π²Π½ΠΈΠΌ ΡΠ΅ΡΡ ΡΠ°Π·Π»ΠΈΡΠ½ΠΈ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠ°:
- ΠΊΡΠ±Π΅Π²Π°Π»;
- kube-ΡΠ΅Π·ΡΠ»ΡΠ°Ρ;
- config-lint;
- ΠΌΠ΅Π΄;
- ΠΊΠΎΠ½ΠΊΡΡΡ;
- ΠΠΎΠ»Π°ΡΠΈΡ.
Π, Π΄Π° Π·Π°ΠΏΠΎΡΠ²Π°ΠΌΠ΅!
ΠΡΠΎΠ²Π΅ΡΠΊΠ° Π½Π° Π²Π½Π΅Π΄ΡΡΠ²Π°Π½ΠΈΡΡΠ°
ΠΡΠ΅Π΄ΠΈ Π΄Π° Π·Π°ΠΏΠΎΡΠ½Π΅ΠΌ Π΄Π° ΡΡΠ°Π²Π½ΡΠ²Π°ΠΌΠ΅ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠΈ, Π½Π΅ΠΊΠ° ΡΡΠ·Π΄Π°Π΄Π΅ΠΌ Π½ΡΠΊΠ°ΠΊΡΠ² ΡΠΎΠ½, Π²ΡΡΡ Ρ ΠΊΠΎΠΉΡΠΎ Π΄Π° Π³ΠΈ ΡΠ΅ΡΡΠ²Π°ΠΌΠ΅.
ΠΠ°Π½ΠΈΡΠ΅ΡΡΡΡ ΠΏΠΎ-Π΄ΠΎΠ»Ρ ΡΡΠ΄ΡΡΠΆΠ° ΡΠ΅Π΄ΠΈΡΠ° Π³ΡΠ΅ΡΠΊΠΈ ΠΈ Π½Π΅ΡΡΠΎΡΠ²Π΅ΡΡΡΠ²ΠΈΠ΅ Ρ Π½Π°ΠΉ-Π΄ΠΎΠ±ΡΠΈΡΠ΅ ΠΏΡΠ°ΠΊΡΠΈΠΊΠΈ: ΠΊΠΎΠ»ΠΊΠΎ ΠΎΡ ΡΡΡ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π½Π°ΠΌΠ΅ΡΠΈΡΠ΅?
apiVersion: apps/v1
kind: Deployment
metadata:
name: http-echo
spec:
replicas: 2
selector:
matchLabels:
app: http-echo
template:
metadata:
labels:
app: http-echo
spec:
containers:
- name: http-echo
image: hashicorp/http-echo
args: ["-text", "hello-world"]
ports:
- containerPort: 5678
---
apiVersion: v1
kind: Service
metadata:
name: http-echo
spec:
ports:
- port: 5678
protocol: TCP
targetPort: 5678
selector:
app: http-echo
(base-valid.yaml
)
Π©Π΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ ΡΠΎΠ·ΠΈ YAML, Π·Π° Π΄Π° ΡΡΠ°Π²Π½ΠΈΠΌ ΡΠ°Π·Π»ΠΈΡΠ½ΠΈ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠΈ.
ΠΠΎΡΠ½ΠΈΡΡ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡ
base-valid.yaml
ΠΈ Π΄ΡΡΠ³ΠΈ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠΈ ΠΎΡ ΡΠ°Π·ΠΈ ΡΡΠ°ΡΠΈΡ ΠΌΠΎΠ³Π°Ρ Π΄Π° Π±ΡΠ΄Π°Ρ Π½Π°ΠΌΠ΅ΡΠ΅Π½ΠΈ Π²Git Ρ ΡΠ°Π½ΠΈΠ»ΠΈΡΠ° .
ΠΠ°Π½ΠΈΡΠ΅ΡΡΡΡ ΠΎΠΏΠΈΡΠ²Π° ΡΠ΅Π± ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, ΡΠΈΡΡΠΎ ΠΎΡΠ½ΠΎΠ²Π½Π° Π·Π°Π΄Π°ΡΠ° Π΅ Π΄Π° ΠΎΡΠ³ΠΎΠ²ΠΎΡΠΈ ΡΡΡ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ βHello Worldβ Π½Π° ΠΏΠΎΡΡ 5678. Π’ΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° Π±ΡΠ΄Π΅ ΡΠ°Π·Π³ΡΡΠ½Π°ΡΠΎ ΡΡΡ ΡΠ»Π΅Π΄Π½Π°ΡΠ° ΠΊΠΎΠΌΠ°Π½Π΄Π°:
kubectl apply -f hello-world.yaml
Π ΡΠ°ΠΊΠ° - ΠΏΡΠΎΠ²Π΅ΡΠ΅ΡΠ΅ ΡΠ°Π±ΠΎΡΠ°ΡΠ°:
kubectl port-forward svc/http-echo 8080:5678
Π‘Π΅Π³Π° ΠΎΡΠΈΠ΄Π΅ΡΠ΅ Π½Π°
1. ΠΡΠ±Π΅Π²Π°Π»
Π ΡΡΡΡΠ΅ΡΠΎ
ΠΡΠΌ ΠΌΠΎΠΌΠ΅Π½ΡΠ° Π½Π° ΠΏΠΈΡΠ°Π½Π΅ Π½Π° ΠΎΡΠΈΠ³ΠΈΠ½Π°Π»Π½Π°ΡΠ° ΡΡΠ°ΡΠΈΡ Π±Π΅ΡΠ΅ Π½Π°Π»ΠΈΡΠ½Π° Π²Π΅ΡΡΠΈΡ 0.15.0.
ΠΠ΅Π΄Π½ΡΠΆ ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ°Π½, Π½Π΅ΠΊΠ° Π³ΠΎ Π·Π°Ρ ΡΠ°Π½ΠΈΠΌ Ρ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠ° ΠΏΠΎ-Π³ΠΎΡΠ΅:
$ kubeval base-valid.yaml
PASS - base-valid.yaml contains a valid Deployment (http-echo)
PASS - base-valid.yaml contains a valid Service (http-echo)
ΠΠΊΠΎ ΡΡΠΏΠ΅Π΅, kubeval ΡΠ΅ ΠΈΠ·Π»Π΅Π·Π΅ Ρ ΠΈΠ·Ρ ΠΎΠ΄Π΅Π½ ΠΊΠΎΠ΄ 0. ΠΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π³ΠΎ ΠΏΡΠΎΠ²Π΅ΡΠΈΡΠ΅ ΠΏΠΎ ΡΠ»Π΅Π΄Π½ΠΈΡ Π½Π°ΡΠΈΠ½:
$ echo $?
0
ΠΠ΅ΠΊΠ° ΡΠ΅Π³Π° ΠΎΠΏΠΈΡΠ°ΠΌΠ΅ kubeval Ρ ΡΠ°Π·Π»ΠΈΡΠ΅Π½ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡ:
apiVersion: apps/v1
kind: Deployment
metadata:
name: http-echo
spec:
replicas: 2
template:
metadata:
labels:
app: http-echo
spec:
containers:
- name: http-echo
image: hashicorp/http-echo
args: ["-text", "hello-world"]
ports:
- containerPort: 5678
---
apiVersion: v1
kind: Service
metadata:
name: http-echo
spec:
ports:
- port: 5678
protocol: TCP
targetPort: 5678
selector:
app: http-echo
(kubeval-invalid.yaml
)
ΠΠΎΠΆΠ΅ΡΠ΅ Π»ΠΈ Π΄Π° Π·Π°Π±Π΅Π»Π΅ΠΆΠΈΡΠ΅ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ° Ρ ΠΎΠΊΠΎ? ΠΠ° ΡΡΠ°ΡΡΠΈΡΠ°ΠΌΠ΅:
$ kubeval kubeval-invalid.yaml
WARN - kubeval-invalid.yaml contains an invalid Deployment (http-echo) - selector: selector is required
PASS - kubeval-invalid.yaml contains a valid Service (http-echo)
# ΠΏΡΠΎΠ²Π΅ΡΠΈΠΌ ΠΊΠΎΠ΄ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°
$ echo $?
1
Π Π΅ΡΡΡΡΡΡ Π½Π΅ ΡΠ΅ ΠΏΡΠΎΠ²Π΅ΡΡΠ²Π°.
ΠΠ½Π΅Π΄ΡΡΠ²Π°Π½ΠΈΡ Ρ ΠΏΠΎΠΌΠΎΡΡΠ° Π½Π° Π²Π΅ΡΡΠΈΡΡΠ° Π½Π° API apps/v1
, ΡΡΡΠ±Π²Π° Π΄Π° Π²ΠΊΠ»ΡΡΠ²Π° ΡΠ΅Π»Π΅ΠΊΡΠΎΡ, ΠΊΠΎΠΉΡΠΎ ΡΡΠΎΡΠ²Π΅ΡΡΡΠ²Π° Π½Π° Π΅ΡΠΈΠΊΠ΅ΡΠ° Π½Π° Π³ΡΡΠΏΠ°ΡΠ°. ΠΠ°Π½ΠΈΡΠ΅ΡΡΡΡ ΠΏΠΎ-Π³ΠΎΡΠ΅ Π½Π΅ Π²ΠΊΠ»ΡΡΠ²Π° ΡΠ΅Π»Π΅ΠΊΡΠΎΡΠ°, ΡΠ°ΠΊΠ° ΡΠ΅ kubeval ΡΡΠΎΠ±ΡΠΈ Π·Π° Π³ΡΠ΅ΡΠΊΠ° ΠΈ ΠΈΠ·Π»Π΅Π·Π΅ Ρ ΡΠ°Π·Π»ΠΈΡΠ΅Π½ ΠΎΡ Π½ΡΠ»Π° ΠΊΠΎΠ΄.
Π§ΡΠ΄Ρ ΡΠ΅ ΠΊΠ°ΠΊΠ²ΠΎ ΡΠ΅ ΡΡΠ°Π½Π΅, Π°ΠΊΠΎ Π³ΠΎ Π½Π°ΠΏΡΠ°Π²Ρ kubectl apply -f
Ρ ΡΠΎΠ·ΠΈ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡ?
Π, Π½Π΅ΠΊΠ° ΠΎΠΏΠΈΡΠ°ΠΌΠ΅:
$ kubectl apply -f kubeval-invalid.yaml
error: error validating "kubeval-invalid.yaml": error validating data: ValidationError(Deployment.spec):
missing required field "selector" in io.k8s.api.apps.v1.DeploymentSpec; if you choose to ignore these errors,
turn validation off with --validate=false
Π’ΠΎΠ²Π° Π΅ ΡΠΎΡΠ½ΠΎ Π³ΡΠ΅ΡΠΊΠ°ΡΠ°, Π·Π° ΠΊΠΎΡΡΠΎ kubeval ΠΏΡΠ΅Π΄ΡΠΏΡΠ΅Π΄ΠΈ. ΠΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π³ΠΎ ΠΏΠΎΠΏΡΠ°Π²ΠΈΡΠ΅, ΠΊΠ°ΡΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡΠ΅ ΡΠ΅Π»Π΅ΠΊΡΠΎΡ:
apiVersion: apps/v1
kind: Deployment
metadata:
name: http-echo
spec:
replicas: 2
selector: # !!!
matchLabels: # !!!
app: http-echo # !!!
template:
metadata:
labels:
app: http-echo
spec:
containers:
- name: http-echo
image: hashicorp/http-echo
args: ["-text", "hello-world"]
ports:
- containerPort: 5678
---
apiVersion: v1
kind: Service
metadata:
name: http-echo
spec:
ports:
- port: 5678
protocol: TCP
targetPort: 5678
selector:
app: http-echo
(base-valid.yaml
)
ΠΠΎΠ»Π·Π°ΡΠ° ΠΎΡ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠΈ ΠΊΠ°ΡΠΎ kubeval Π΅, ΡΠ΅ Π³ΡΠ΅ΡΠΊΠΈ ΠΊΠ°ΡΠΎ ΡΠ΅Π·ΠΈ ΠΌΠΎΠ³Π°Ρ Π΄Π° Π±ΡΠ΄Π°Ρ ΡΠ»ΠΎΠ²Π΅Π½ΠΈ Π² Π½Π°ΡΠ°Π»ΠΎΡΠΎ Π½Π° ΡΠΈΠΊΡΠ»Π° Π½Π° Π²Π½Π΅Π΄ΡΡΠ²Π°Π½Π΅.
ΠΡΠ²Π΅Π½ ΡΠΎΠ²Π° ΡΠ΅Π·ΠΈ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ Π½Π΅ ΠΈΠ·ΠΈΡΠΊΠ²Π°Ρ Π΄ΠΎΡΡΡΠΏ Π΄ΠΎ ΠΊΠ»ΡΡΡΠ΅ΡΠ°; ΡΠ΅ ΠΌΠΎΠ³Π°Ρ Π΄Π° ΡΠ΅ ΠΈΠ·Π²ΡΡΡΠ²Π°Ρ ΠΎΡΠ»Π°ΠΉΠ½.
ΠΠΎ ΠΏΠΎΠ΄ΡΠ°Π·Π±ΠΈΡΠ°Π½Π΅ kubeval ΠΏΡΠΎΠ²Π΅ΡΡΠ²Π° ΡΠ΅ΡΡΡΡΠΈΡΠ΅ ΡΠΏΡΡΠΌΠΎ Π½Π°ΠΉ-Π½ΠΎΠ²Π°ΡΠ° API ΡΡ
Π΅ΠΌΠ° Π½Π° Kubernetes. ΠΡΠΏΡΠ΅ΠΊΠΈ ΡΠΎΠ²Π°, Π² ΠΏΠΎΠ²Π΅ΡΠ΅ΡΠΎ ΡΠ»ΡΡΠ°ΠΈ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ Π½Π°Π»ΠΎΠΆΠΈ Π΄Π° ΠΏΡΠΎΠ²Π΅ΡΠΈΡΠ΅ ΡΠΏΡΡΠΌΠΎ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΠΎ ΠΈΠ·Π΄Π°Π½ΠΈΠ΅ Π½Π° Kubernetes. Π’ΠΎΠ²Π° ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΡΠ°Π½Π΅ Ρ ΠΏΠΎΠΌΠΎΡΡΠ° Π½Π° ΡΠ»Π°Π³Π° --kubernetes-version
:
$ kubeval --kubernetes-version 1.16.1 base-valid.yaml
ΠΠΎΠ»Ρ, ΠΈΠΌΠ°ΠΉΡΠ΅ ΠΏΡΠ΅Π΄Π²ΠΈΠ΄, ΡΠ΅ Π²Π΅ΡΡΠΈΡΡΠ° ΡΡΡΠ±Π²Π° Π΄Π° Π±ΡΠ΄Π΅ ΠΏΠΎΡΠΎΡΠ΅Π½Π° Π²ΡΠ² ΡΠΎΡΠΌΠ°ΡΠ° Major.Minor.Patch
.
ΠΠ° ΡΠΏΠΈΡΡΠΊ Ρ Π²Π΅ΡΡΠΈΠΈ, Π·Π° ΠΊΠΎΠΈΡΠΎ ΡΠ΅ ΠΏΠΎΠ΄Π΄ΡΡΠΆΠ° ΠΏΡΠΎΠ²Π΅ΡΠΊΠ°, Π²ΠΈΠΆΡΠ΅ --schema-location
.
Π Π΄ΠΎΠΏΡΠ»Π½Π΅Π½ΠΈΠ΅ ΠΊΡΠΌ ΠΎΡΠ΄Π΅Π»Π½ΠΈΡΠ΅ YAML ΡΠ°ΠΉΠ»ΠΎΠ²Π΅, kubeval ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ°Π±ΠΎΡΠΈ ΠΈ Ρ Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΠΈ ΠΈ stdin.
Π Π΄ΠΎΠΏΡΠ»Π½Π΅Π½ΠΈΠ΅, Kubeval Π»Π΅ΡΠ½ΠΎ ΡΠ΅ ΠΈΠ½ΡΠ΅Π³ΡΠΈΡΠ° Π² CI ΡΡΡΠ±ΠΎΠΏΡΠΎΠ²ΠΎΠ΄Π°. Π’Π΅Π·ΠΈ, ΠΊΠΎΠΈΡΠΎ ΠΆΠ΅Π»Π°ΡΡ Π΄Π° ΠΈΠ·ΠΏΡΠ»Π½ΡΡ ΡΠ΅ΡΡΠΎΠ²Π΅, ΠΏΡΠ΅Π΄ΠΈ Π΄Π° ΠΈΠ·ΠΏΡΠ°ΡΡΡ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠΈ ΠΊΡΠΌ ΠΊΠ»ΡΡΡΠ΅ΡΠ°, ΡΠ΅ ΡΠ΅ ΡΠ°Π΄Π²Π°Ρ Π΄Π° Π·Π½Π°ΡΡ, ΡΠ΅ kubeval ΠΏΠΎΠ΄Π΄ΡΡΠΆΠ° ΡΡΠΈ ΠΈΠ·Ρ ΠΎΠ΄Π½ΠΈ ΡΠΎΡΠΌΠ°ΡΠ°:
- ΠΠ±ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ ΡΠ΅ΠΊΡΡ;
- JSON;
- Test Anything Protocol (TAP).
ΠΡΠ΅ΠΊΠΈ ΠΎΡ ΡΠΎΡΠΌΠ°ΡΠΈΡΠ΅ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π·Π° ΠΏΠΎ-Π½Π°ΡΠ°ΡΡΡΠ½ΠΎ Π°Π½Π°Π»ΠΈΠ·ΠΈΡΠ°Π½Π΅ Π½Π° ΠΈΠ·Ρ ΠΎΠ΄Π°, Π·Π° Π΄Π° ΡΠ΅ Π³Π΅Π½Π΅ΡΠΈΡΠ° ΠΎΠ±ΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ Π½Π° ΡΠ΅Π·ΡΠ»ΡΠ°ΡΠΈΡΠ΅ ΠΎΡ ΠΆΠ΅Π»Π°Π½ΠΈΡ ΡΠΈΠΏ.
ΠΠ΄ΠΈΠ½ ΠΎΡ Π½Π΅Π΄ΠΎΡΡΠ°ΡΡΡΠΈΡΠ΅ Π½Π° kubeval Π΅, ΡΠ΅ Π² ΠΌΠΎΠΌΠ΅Π½ΡΠ° Π½Π΅ ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΏΡΠΎΠ²Π΅ΡΡΠ²Π° Π·Π° ΡΡΠΎΡΠ²Π΅ΡΡΡΠ²ΠΈΠ΅ Ρ ΠΏΠ΅ΡΡΠΎΠ½Π°Π»ΠΈΠ·ΠΈΡΠ°Π½ΠΈ Π΄Π΅ΡΠΈΠ½ΠΈΡΠΈΠΈ Π½Π° ΡΠ΅ΡΡΡΡΠΈ (CRD). ΠΡΠΏΡΠ΅ΠΊΠΈ ΡΠΎΠ²Π° Π΅ Π²ΡΠ·ΠΌΠΎΠΆΠ½ΠΎ Π΄Π° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠΈΡΠ°ΡΠ΅ kubeval
Kubeval Π΅ ΡΡΠ΄Π΅ΡΠ΅Π½ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½Ρ Π·Π° ΠΏΡΠΎΠ²Π΅ΡΠΊΠ° ΠΈ ΠΎΡΠ΅Π½ΠΊΠ° Π½Π° ΡΠ΅ΡΡΡΡΠΈ; Π’ΡΡΠ±Π²Π° ΠΎΠ±Π°ΡΠ΅ Π΄Π° ΡΠ΅ ΠΏΠΎΠ΄ΡΠ΅ΡΡΠ°Π΅, ΡΠ΅ ΠΏΡΠ΅ΠΌΠΈΠ½Π°Π²Π°Π½Π΅ΡΠΎ Π½Π° ΡΠ΅ΡΡΠ° Π½Π΅ Π³Π°ΡΠ°Π½ΡΠΈΡΠ°, ΡΠ΅ ΡΠ΅ΡΡΡΡΡΡ ΠΎΡΠ³ΠΎΠ²Π°ΡΡ Π½Π° Π½Π°ΠΉ-Π΄ΠΎΠ±ΡΠΈΡΠ΅ ΠΏΡΠ°ΠΊΡΠΈΠΊΠΈ.
ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ Ρ ΠΏΠΎΠΌΠΎΡΡΠ° Π½Π° Π΅ΡΠΈΠΊΠ΅ΡΠ° latest
Π² ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ Π½Π΅ ΡΠ»Π΅Π΄Π²Π° Π½Π°ΠΉ-Π΄ΠΎΠ±ΡΠΈΡΠ΅ ΠΏΡΠ°ΠΊΡΠΈΠΊΠΈ. Kubeval ΠΎΠ±Π°ΡΠ΅ Π½Π΅ ΡΡΠΈΡΠ° ΡΠΎΠ²Π° Π·Π° Π³ΡΠ΅ΡΠΊΠ° ΠΈ Π½Π΅ Ρ Π΄ΠΎΠΊΠ»Π°Π΄Π²Π°. Π’ΠΎΠ²Π° ΠΎΠ·Π½Π°ΡΠ°Π²Π°, ΡΠ΅ ΠΏΡΠΎΠ²Π΅ΡΠΊΠ°ΡΠ° Π½Π° ΡΠ°ΠΊΡΠ² YAML ΡΠ΅ Π·Π°Π²ΡΡΡΠΈ Π±Π΅Π· ΠΏΡΠ΅Π΄ΡΠΏΡΠ΅ΠΆΠ΄Π΅Π½ΠΈΡ.
ΠΠΎ ΠΊΠ°ΠΊΠ²ΠΎ ΡΠ΅ ΡΡΠ°Π½Π΅, Π°ΠΊΠΎ ΠΈΡΠΊΠ°ΡΠ΅ Π΄Π° ΠΎΡΠ΅Π½ΠΈΡΠ΅ YAML ΠΈ Π΄Π° ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΡΠΈΡΠ°ΡΠ΅ Π½Π°ΡΡΡΠ΅Π½ΠΈΡ ΠΊΠ°ΡΠΎ Π΅ΡΠΈΠΊΠ΅ΡΠ° latest
? ΠΠ°ΠΊ Π΄Π° ΠΏΡΠΎΠ²Π΅ΡΡ YAML ΡΠ°ΠΉΠ» ΡΠΏΡΡΠΌΠΎ Π½Π°ΠΉ-Π΄ΠΎΠ±ΡΠΈΡΠ΅ ΠΏΡΠ°ΠΊΡΠΈΠΊΠΈ?
2. ΠΡΠ±Π΅-ΡΠ΅Π·ΡΠ»ΡΠ°Ρ
- ΠΠ·ΠΏΡΠ»Π½Π΅Π½ΠΈΠ΅ Π½Π° ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠ° Π½Π΅ ΠΊΠ°ΡΠΎ root.
- ΠΠ°Π»ΠΈΡΠΈΠ΅ Π½Π° ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ Π½Π° Π·Π΄ΡΠ°Π²Π΅ΡΠΎ Π½Π° ΠΊΠ°ΠΏΡΡΠ»ΠΈΡΠ΅.
- ΠΠ°Π΄Π°Π²Π°Π½Π΅ Π½Π° Π·Π°ΡΠ²ΠΊΠΈ ΠΈ Π»ΠΈΠΌΠΈΡΠΈ Π·Π° ΡΠ΅ΡΡΡΡΠΈ.
ΠΡΠ· ΠΎΡΠ½ΠΎΠ²Π° Π½Π° ΡΠ΅Π·ΡΠ»ΡΠ°ΡΠΈΡΠ΅ ΠΎΡ ΡΠ΅ΡΡΠ° ΡΠ΅ Π΄Π°Π²Π°Ρ ΡΡΠΈ ΡΠ΅Π·ΡΠ»ΡΠ°ΡΠ°: OK, ΠΠ ΠΠΠ£ΠΠ ΠΠΠΠΠΠΠ ΠΈ ΠΠ ΠΠ’ΠΠ§ΠΠ.
ΠΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΈΠ·ΠΏΡΠΎΠ±Π²Π°ΡΠ΅ Kube-score ΠΎΠ½Π»Π°ΠΉΠ½ ΠΈΠ»ΠΈ Π΄Π° Π³ΠΎ ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ°ΡΠ΅ Π»ΠΎΠΊΠ°Π»Π½ΠΎ.
ΠΡΠΌ ΠΌΠΎΠΌΠ΅Π½ΡΠ° Π½Π° ΠΏΠΈΡΠ°Π½Π΅ Π½Π° ΠΎΡΠΈΠ³ΠΈΠ½Π°Π»Π½Π°ΡΠ° ΡΡΠ°ΡΠΈΡ Π½Π°ΠΉ-Π½ΠΎΠ²Π°ΡΠ° Π²Π΅ΡΡΠΈΡ Π½Π° kube-score Π±Π΅ΡΠ΅ 1.7.0.
ΠΠ΅ΠΊΠ° Π³ΠΎ ΠΈΠ·ΠΏΡΠΎΠ±Π²Π°ΠΌΠ΅ Π² Π½Π°ΡΠΈΡ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡ base-valid.yaml
:
$ kube-score score base-valid.yaml
apps/v1/Deployment http-echo
[CRITICAL] Container Image Tag
Β· http-echo -> Image with latest tag
Using a fixed tag is recommended to avoid accidental upgrades
[CRITICAL] Pod NetworkPolicy
Β· The pod does not have a matching network policy
Create a NetworkPolicy that targets this pod
[CRITICAL] Pod Probes
Β· Container is missing a readinessProbe
A readinessProbe should be used to indicate when the service is ready to receive traffic.
Without it, the Pod is risking to receive traffic before it has booted. It is also used during
rollouts, and can prevent downtime if a new version of the application is failing.
More information: https://github.com/zegl/kube-score/blob/master/README_PROBES.md
[CRITICAL] Container Security Context
Β· http-echo -> Container has no configured security context
Set securityContext to run the container in a more secure context.
[CRITICAL] Container Resources
Β· http-echo -> CPU limit is not set
Resource limits are recommended to avoid resource DDOS. Set resources.limits.cpu
Β· http-echo -> Memory limit is not set
Resource limits are recommended to avoid resource DDOS. Set resources.limits.memory
Β· http-echo -> CPU request is not set
Resource requests are recommended to make sure that the application can start and run without
crashing. Set resources.requests.cpu
Β· http-echo -> Memory request is not set
Resource requests are recommended to make sure that the application can start and run without crashing.
Set resources.requests.memory
[CRITICAL] Deployment has PodDisruptionBudget
Β· No matching PodDisruptionBudget was found
It is recommended to define a PodDisruptionBudget to avoid unexpected downtime during Kubernetes
maintenance operations, such as when draining a node.
[WARNING] Deployment has host PodAntiAffinity
Β· Deployment does not have a host podAntiAffinity set
It is recommended to set a podAntiAffinity that stops multiple pods from a deployment from
being scheduled on the same node. This increases availability in case the node becomes unavailable.
YAML ΠΏΡΠ΅ΠΌΠΈΠ½Π°Π²Π° kubeval ΡΠ΅ΡΡΠΎΠ²Π΅, Π΄ΠΎΠΊΠ°ΡΠΎ kube-score ΠΏΠΎΡΠΎΡΠ²Π° ΡΠ»Π΅Π΄Π½ΠΈΡΠ΅ Π½Π΅Π΄ΠΎΡΡΠ°ΡΡΡΠΈ:
- ΠΡΠΎΠ²Π΅ΡΠΊΠΈΡΠ΅ Π·Π° Π³ΠΎΡΠΎΠ²Π½ΠΎΡΡ Π½Π΅ ΡΠ° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠΈΡΠ°Π½ΠΈ.
- ΠΡΠΌΠ° Π·Π°ΡΠ²ΠΊΠΈ ΠΈΠ»ΠΈ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΡ Π·Π° CPU ΡΠ΅ΡΡΡΡΠΈ ΠΈ ΠΏΠ°ΠΌΠ΅Ρ.
- ΠΡΠ΄ΠΆΠ΅ΡΠΈΡΠ΅ Π·Π° ΠΏΡΠ΅ΠΊΡΡΠ²Π°Π½Π΅ Π½Π° ΠΊΠ°ΠΏΡΡΠ»ΠΈΡΠ΅ Π½Π΅ ΡΠ° ΠΏΠΎΡΠΎΡΠ΅Π½ΠΈ.
- ΠΡΠΌΠ° ΠΏΡΠ°Π²ΠΈΠ»Π° Π·Π° ΡΠ°Π·Π΄Π΅Π»ΡΠ½Π΅ (Π°Π½ΡΠΈ-Π°ΡΠΈΠ½ΠΈΡΠ΅Ρ) Π·Π° Π΄Π° ΡΠ²Π΅Π»ΠΈΡΠΈΡΠ΅ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»Π½ΠΎ Π½Π°Π»ΠΈΡΠ½ΠΎΡΡΡΠ°.
- ΠΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΡΡ ΡΠ°Π±ΠΎΡΠΈ ΠΊΠ°ΡΠΎ root.
Π’ΠΎΠ²Π° ΡΠ° Π²ΡΠΈΡΠΊΠΈ Π²Π°Π»ΠΈΠ΄Π½ΠΈ ΡΠΎΡΠΊΠΈ ΠΎΡΠ½ΠΎΡΠ½ΠΎ Π½Π΅Π΄ΠΎΡΡΠ°ΡΡΡΠΈΡΠ΅, ΠΊΠΎΠΈΡΠΎ ΡΡΡΠ±Π²Π° Π΄Π° Π±ΡΠ΄Π°Ρ ΡΠ΅ΡΠ΅Π½ΠΈ, Π·Π° Π΄Π° Π±ΡΠ΄Π΅ ΡΠ°Π·Π³ΡΡΡΠ°Π½Π΅ΡΠΎ ΠΏΠΎ-Π΅ΡΠ΅ΠΊΡΠΈΠ²Π½ΠΎ ΠΈ Π½Π°Π΄Π΅ΠΆΠ΄Π½ΠΎ.
ΠΡΠ±ΠΎΡ kube-score
ΠΏΠΎΠΊΠ°Π·Π²Π° ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ Π² ΡΠ΄ΠΎΠ±Π½Π° Π·Π° ΡΠ΅ΡΠ΅Π½Π΅ ΡΠΎΡΠΌΠ°, Π²ΠΊΠ»ΡΡΠΈΡΠ΅Π»Π½ΠΎ Π²ΡΠΈΡΠΊΠΈ Π½Π°ΡΡΡΠ΅Π½ΠΈΡ Π½Π° ΡΠΈΠΏΠ° ΠΠ ΠΠΠ£ΠΠ ΠΠΠΠΠΠΠ ΠΈ ΠΠ ΠΠ’ΠΠ§ΠΠ, ΠΊΠΎΠ΅ΡΠΎ ΠΏΠΎΠΌΠ°Π³Π° ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎ Π²ΡΠ΅ΠΌΠ΅ Π½Π° ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠ°ΡΠ°.
Π’Π΅Π·ΠΈ, ΠΊΠΎΠΈΡΠΎ ΠΆΠ΅Π»Π°ΡΡ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ ΡΠΎΠ·ΠΈ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½Ρ Π² ΡΠ°ΠΌΠΊΠΈΡΠ΅ Π½Π° CI ΡΡΡΠ±ΠΎΠΏΡΠΎΠ²ΠΎΠ΄Π°, ΠΌΠΎΠ³Π°Ρ Π΄Π° Π°ΠΊΡΠΈΠ²ΠΈΡΠ°Ρ ΠΏΠΎ-ΠΊΠΎΠΌΠΏΡΠ΅ΡΠΈΡΠ°Π½ ΠΈΠ·Ρ
ΠΎΠ΄ Ρ ΠΏΠΎΠΌΠΎΡΡΠ° Π½Π° ΡΠ»Π°Π³Π° --output-format ci
(Π² ΡΠΎΠ·ΠΈ ΡΠ»ΡΡΠ°ΠΉ ΡΠ΅ ΠΏΠΎΠΊΠ°Π·Π²Π°Ρ ΠΈ ΡΠ΅ΡΡΠΎΠ²Π΅ Ρ ΡΠ΅Π·ΡΠ»ΡΠ°ΡΠ° OK):
$ kube-score score base-valid.yaml --output-format ci
[OK] http-echo apps/v1/Deployment
[OK] http-echo apps/v1/Deployment
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) CPU limit is not set
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) Memory limit is not set
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) CPU request is not set
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) Memory request is not set
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) Image with latest tag
[OK] http-echo apps/v1/Deployment
[CRITICAL] http-echo apps/v1/Deployment: The pod does not have a matching network policy
[CRITICAL] http-echo apps/v1/Deployment: Container is missing a readinessProbe
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) Container has no configured security context
[CRITICAL] http-echo apps/v1/Deployment: No matching PodDisruptionBudget was found
[WARNING] http-echo apps/v1/Deployment: Deployment does not have a host podAntiAffinity set
[OK] http-echo v1/Service
[OK] http-echo v1/Service
[OK] http-echo v1/Service
[OK] http-echo v1/Service
ΠΠΎΠ΄ΠΎΠ±Π½ΠΎ Π½Π° kubeval, kube-score Π²ΡΡΡΠ° Π½Π΅Π½ΡΠ»Π΅Π² ΠΈΠ·Ρ ΠΎΠ΄Π΅Π½ ΠΊΠΎΠ΄, ΠΊΠΎΠ³Π°ΡΠΎ ΠΈΠΌΠ° ΡΠ΅ΡΡ, ΠΊΠΎΠΉΡΠΎ Π΅ Π½Π΅ΡΡΠΏΠ΅ΡΠ΅Π½ ΠΠ ΠΠ’ΠΠ§ΠΠ. ΠΠΎΠΆΠ΅ΡΠ΅ ΡΡΡΠΎ Π΄Π° Π°ΠΊΡΠΈΠ²ΠΈΡΠ°ΡΠ΅ ΠΏΠΎΠ΄ΠΎΠ±Π½Π° ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ° Π·Π° ΠΠ ΠΠΠ£ΠΠ ΠΠΠΠΠΠΠ.
ΠΡΠ²Π΅Π½ ΡΠΎΠ²Π° Π΅ Π²ΡΠ·ΠΌΠΎΠΆΠ½ΠΎ Π΄Π° ΡΠ΅ ΠΏΡΠΎΠ²Π΅ΡΡΠ²Π°Ρ ΡΠ΅ΡΡΡΡΠΈΡΠ΅ Π·Π° ΡΡΠΎΡΠ²Π΅ΡΡΡΠ²ΠΈΠ΅ Ρ ΡΠ°Π·Π»ΠΈΡΠ½ΠΈ Π²Π΅ΡΡΠΈΠΈ Π½Π° API (ΠΊΠ°ΠΊΡΠΎ Π² kubeval). Π’Π°Π·ΠΈ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ ΠΎΠ±Π°ΡΠ΅ Π΅ ΡΠ²ΡΡΠ΄ΠΎ ΠΊΠΎΠ΄ΠΈΡΠ°Π½Π° Π² ΡΠ°ΠΌΠΈΡ kube-score: Π½Π΅ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΈΠ·Π±Π΅ΡΠ΅ΡΠ΅ ΡΠ°Π·Π»ΠΈΡΠ½Π° Π²Π΅ΡΡΠΈΡ Π½Π° Kubernetes. Π’ΠΎΠ²Π° ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅ Π΄Π° Π±ΡΠ΄Π΅ Π³ΠΎΠ»ΡΠΌ ΠΏΡΠΎΠ±Π»Π΅ΠΌ, Π°ΠΊΠΎ Π²ΡΠ·Π½Π°ΠΌΠ΅ΡΡΠ²Π°ΡΠ΅ Π΄Π° Π½Π°Π΄ΡΡΡΠΎΠΈΡΠ΅ ΡΠ²ΠΎΡ ΠΊΠ»ΡΡΡΠ΅Ρ ΠΈΠ»ΠΈ Π°ΠΊΠΎ ΠΈΠΌΠ°ΡΠ΅ Π½ΡΠΊΠΎΠ»ΠΊΠΎ ΠΊΠ»ΡΡΡΠ΅ΡΠ° Ρ ΡΠ°Π·Π»ΠΈΡΠ½ΠΈ Π²Π΅ΡΡΠΈΠΈ Π½Π° K8s.
ΠΠΎΠ»Ρ, ΠΈΠΌΠ°ΠΉΡΠ΅ ΠΏΡΠ΅Π΄Π²ΠΈΠ΄, ΡΠ΅
Π²Π΅ΡΠ΅ ΠΈΠΌΠ° ΠΏΡΠΎΠ±Π»Π΅ΠΌ Ρ ΠΏΡΠ΅Π΄Π»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π·Π° ΡΠ΅Π°Π»ΠΈΠ·ΠΈΡΠ°Π½Π΅ Π½Π° ΡΠ°Π·ΠΈ Π²ΡΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ.
ΠΠΎΠ²Π΅ΡΠ΅ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ Π·Π° kube-score ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π½Π°ΠΌΠ΅ΡΠΈΡΠ΅ Π½Π°
Kube-score ΡΠ΅ΡΡΠΎΠ²Π΅ΡΠ΅ ΡΠ° ΡΡΠ΄Π΅ΡΠ΅Π½ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½Ρ Π·Π° Π²Π½Π΅Π΄ΡΡΠ²Π°Π½Π΅ Π½Π° Π½Π°ΠΉ-Π΄ΠΎΠ±ΡΠΈ ΠΏΡΠ°ΠΊΡΠΈΠΊΠΈ, Π½ΠΎ ΠΊΠ°ΠΊΠ²ΠΎ ΡΠ΅ ΡΡΠ°Π½Π΅, Π°ΠΊΠΎ ΡΡΡΠ±Π²Π° Π΄Π° Π½Π°ΠΏΡΠ°Π²ΠΈΡΠ΅ ΠΏΡΠΎΠΌΠ΅Π½ΠΈ Π² ΡΠ΅ΡΡΠ° ΠΈΠ»ΠΈ Π΄Π° Π΄ΠΎΠ±Π°Π²ΠΈΡΠ΅ ΡΠ²ΠΎΠΈ ΡΠΎΠ±ΡΡΠ²Π΅Π½ΠΈ ΠΏΡΠ°Π²ΠΈΠ»Π°? Π£Π²ΠΈ, ΡΠΎΠ²Π° Π½Π΅ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΡΠ°Π½Π΅.
Kube-score Π½Π΅ Π΅ ΡΠ°Π·ΡΠΈΡΡΠ΅ΠΌ: Π½Π΅ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π΄ΠΎΠ±Π°Π²ΡΡΠ΅ ΠΏΠΎΠ»ΠΈΡΠΈΠΊΠΈ ΠΊΡΠΌ Π½Π΅Π³ΠΎ ΠΈΠ»ΠΈ Π΄Π° Π³ΠΈ ΠΊΠΎΡΠΈΠ³ΠΈΡΠ°ΡΠ΅.
ΠΠΊΠΎ ΡΡΡΠ±Π²Π° Π΄Π° Π½Π°ΠΏΠΈΡΠ΅ΡΠ΅ ΠΏΠ΅ΡΡΠΎΠ½Π°Π»ΠΈΠ·ΠΈΡΠ°Π½ΠΈ ΡΠ΅ΡΡΠΎΠ²Π΅, Π·Π° Π΄Π° ΠΏΡΠΎΠ²Π΅ΡΠΈΡΠ΅ ΡΡΠΎΡΠ²Π΅ΡΡΡΠ²ΠΈΠ΅ΡΠΎ Ρ ΡΠΈΡΠΌΠ΅Π½ΠΈΡΠ΅ ΠΏΠΎΠ»ΠΈΡΠΈΠΊΠΈ, ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΡΠ΅ Π΅Π΄ΠΈΠ½ ΠΎΡ ΡΠ»Π΅Π΄Π½ΠΈΡΠ΅ ΡΠ΅ΡΠΈΡΠΈ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠ°: config-lint, copper, conftest ΠΈΠ»ΠΈ polaris.
3.Config-lint
Config-lint Π΅ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½Ρ Π·Π° Π²Π°Π»ΠΈΠ΄ΠΈΡΠ°Π½Π΅ Π½Π° YAML, JSON, Terraform, CSV ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΎΠ½Π½ΠΈ ΡΠ°ΠΉΠ»ΠΎΠ²Π΅ ΠΈ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠΈ Π½Π° Kubernetes.
ΠΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π³ΠΎ ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ°ΡΠ΅ Ρ ΠΏΠΎΠΌΠΎΡΡΠ° Π½Π°
Π’Π΅ΠΊΡΡΠ°ΡΠ° Π²Π΅ΡΡΠΈΡ ΠΊΡΠΌ ΠΌΠΎΠΌΠ΅Π½ΡΠ° Π½Π° ΠΏΠΈΡΠ°Π½Π΅ Π½Π° ΠΎΡΠΈΠ³ΠΈΠ½Π°Π»Π½Π°ΡΠ° ΡΡΠ°ΡΠΈΡ Π΅ 1.5.0.
Config-lint Π½ΡΠΌΠ° Π²Π³ΡΠ°Π΄Π΅Π½ΠΈ ΡΠ΅ΡΡΠΎΠ²Π΅ Π·Π° Π²Π°Π»ΠΈΠ΄ΠΈΡΠ°Π½Π΅ Π½Π° ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠΈΡΠ΅ Π½Π° Kubernetes.
ΠΠ° Π΄Π° ΠΏΡΠΎΠ²Π΅ΠΆΠ΄Π°ΡΠ΅ ΡΠ΅ΡΡΠΎΠ²Π΅, ΡΡΡΠ±Π²Π° Π΄Π° ΡΡΠ·Π΄Π°Π΄Π΅ΡΠ΅ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ΡΡΠΈ ΠΏΡΠ°Π²ΠΈΠ»Π°. Π’Π΅ ΡΠ° Π½Π°ΠΏΠΈΡΠ°Π½ΠΈ Π² YAML ΡΠ°ΠΉΠ»ΠΎΠ²Π΅, Π½Π°ΡΠ΅ΡΠ΅Π½ΠΈ "rulesets" (Π½Π°Π±ΠΎΡΠΈ ΠΎΡ ΠΏΡΠ°Π²ΠΈΠ»Π°)ΠΈ ΠΈΠΌΠ°Ρ ΡΠ»Π΅Π΄Π½Π°ΡΠ° ΡΡΡΡΠΊΡΡΡΠ°:
version: 1
description: Rules for Kubernetes spec files
type: Kubernetes
files:
- "*.yaml"
rules:
# ΡΠΏΠΈΡΠΎΠΊ ΠΏΡΠ°Π²ΠΈΠ»
(rule.yaml
)
ΠΠ΅ΠΊΠ° Π³ΠΎ ΠΏΡΠΎΡΡΠΈΠΌ ΠΏΠΎ-ΠΎΡΠ±Π»ΠΈΠ·ΠΎ:
- ΠΠ±Π»Π°ΡΡ
type
ΡΠΊΠ°Π·Π²Π° ΠΊΠ°ΠΊΡΠ² ΡΠΈΠΏ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° config-lint. ΠΠ° ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠΈΡΠ΅ Π½Π° K8s ΡΠΎΠ²Π° Π΅ Π²ΠΈΠ½Π°Π³ΠΈKubernetes
. - Π ΠΎΠ±Π»Π°ΡΡΡΠ°
files
Π Π΄ΠΎΠΏΡΠ»Π½Π΅Π½ΠΈΠ΅ ΠΊΡΠΌ ΡΠ°ΠΌΠΈΡΠ΅ ΡΠ°ΠΉΠ»ΠΎΠ²Π΅ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΏΠΎΡΠΎΡΠΈΡΠ΅ Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΡ. - ΠΠ±Π»Π°ΡΡ
rules
ΠΏΡΠ΅Π΄Π½Π°Π·Π½Π°ΡΠ΅Π½ Π·Π° Π½Π°ΡΡΡΠΎΠΉΠΊΠ° Π½Π° ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΡΠΊΠΈ ΡΠ΅ΡΡΠΎΠ²Π΅.
ΠΠ° ΠΏΡΠΈΠ΅ΠΌΠ΅ΠΌ, ΡΠ΅ ΠΈΡΠΊΠ°ΡΠ΅ Π΄Π° ΡΡΠ΅ ΡΠΈΠ³ΡΡΠ½ΠΈ, ΡΠ΅ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡΡΠ° Π² Deployment Π²ΠΈΠ½Π°Π³ΠΈ ΡΠ΅ ΠΈΠ·ΡΠ΅Π³Π»ΡΡ ΠΎΡ Π½Π°Π΄Π΅ΠΆΠ΄Π½ΠΎ Ρ
ΡΠ°Π½ΠΈΠ»ΠΈΡΠ΅ ΠΊΠ°ΡΠΎ my-company.com/myapp:1.0
. ΠΡΠ°Π²ΠΈΠ»ΠΎ Π·Π° config-lint, ΠΊΠΎΠ΅ΡΠΎ ΠΈΠ·Π²ΡΡΡΠ²Π° ΡΠ°ΠΊΠ°Π²Π° ΠΏΡΠΎΠ²Π΅ΡΠΊΠ°, ΡΠ΅ ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π° ΡΠ°ΠΊΠ°:
- id: MY_DEPLOYMENT_IMAGE_TAG
severity: FAILURE
message: Deployment must use a valid image tag
resource: Deployment
assertions:
- every:
key: spec.template.spec.containers
expressions:
- key: image
op: starts-with
value: "my-company.com/"
(rule-trusted-repo.yaml
)
ΠΡΡΠΊΠΎ ΠΏΡΠ°Π²ΠΈΠ»ΠΎ ΡΡΡΠ±Π²Π° Π΄Π° ΠΈΠΌΠ° ΡΠ»Π΅Π΄Π½ΠΈΡΠ΅ Π°ΡΡΠΈΠ±ΡΡΠΈ:
id
β ΡΠ½ΠΈΠΊΠ°Π»Π΅Π½ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ Π½Π° ΠΏΡΠ°Π²ΠΈΠ»ΠΎΡΠΎ;severity
- ΠΠΎΠΆΠ΅ Π±ΠΈ ΠΠΠ£Π‘ΠΠΠ₯, ΠΠ ΠΠΠ£ΠΠ ΠΠΠΠΠΠΠ ΠΈ NON_COMPLIANT;message
β Π°ΠΊΠΎ ΠΏΡΠ°Π²ΠΈΠ»ΠΎΡΠΎ Π΅ Π½Π°ΡΡΡΠ΅Π½ΠΎ, ΡΠ΅ ΠΏΠΎΠΊΠ°Π·Π²Π° ΡΡΠ΄ΡΡΠΆΠ°Π½ΠΈΠ΅ΡΠΎ Π½Π° ΡΠΎΠ·ΠΈ ΡΠ΅Π΄;resource
β Π²ΠΈΠ΄Π° Π½Π° ΡΠ΅ΡΡΡΡΠ°, Π·Π° ΠΊΠΎΠΉΡΠΎ ΡΠ΅ ΠΏΡΠΈΠ»Π°Π³Π° ΡΠΎΠ²Π° ΠΏΡΠ°Π²ΠΈΠ»ΠΎ;assertions
β ΡΠΏΠΈΡΡΠΊ Ρ ΡΡΠ»ΠΎΠ²ΠΈΡ, ΠΊΠΎΠΈΡΠΎ ΡΠ΅ Π±ΡΠ΄Π°Ρ ΠΎΡΠ΅Π½Π΅Π½ΠΈ Π²ΡΠ² Π²ΡΡΠ·ΠΊΠ° Ρ ΡΠΎΠ·ΠΈ ΡΠ΅ΡΡΡΡ.
Π Π³ΠΎΡΠ½ΠΎΡΠΎ ΠΏΡΠ°Π²ΠΈΠ»ΠΎ assertion
Π½Π°ΡΠΈΡΠ° every
key: spec.templates.spec.containers
) ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΡΠ΅ Π½Π°Π΄Π΅ΠΆΠ΄Π½ΠΈ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ (Ρ.Π΅. ΠΊΠ°ΡΠΎ Π·Π°ΠΏΠΎΡΠ½Π΅ΡΠ΅ Ρ my-company.com/
).
ΠΡΠ»Π½ΠΈΡΡ Π½Π°Π±ΠΎΡ ΠΎΡ ΠΏΡΠ°Π²ΠΈΠ»Π° ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π° ΡΠ°ΠΊΠ°:
version: 1
description: Rules for Kubernetes spec files
type: Kubernetes
files:
- "*.yaml"
rules:
- id: DEPLOYMENT_IMAGE_REPOSITORY # !!!
severity: FAILURE
message: Deployment must use a valid image repository
resource: Deployment
assertions:
- every:
key: spec.template.spec.containers
expressions:
- key: image
op: starts-with
value: "my-company.com/"
(ruleset.yaml
)
ΠΠ° Π΄Π° ΠΈΠ·ΠΏΡΠΎΠ±Π²Π°ΡΠ΅ ΡΠ΅ΡΡΠ°, Π½Π΅ΠΊΠ° Π³ΠΎ Π·Π°ΠΏΠ°Π·ΠΈΠΌ ΠΊΠ°ΡΠΎ check_image_repo.yaml
. ΠΠ΅ΠΊΠ° Π½Π°ΠΏΡΠ°Π²ΠΈΠΌ ΠΏΡΠΎΠ²Π΅ΡΠΊΠ° Π½Π° ΡΠ°ΠΉΠ»Π° base-valid.yaml
:
$ config-lint -rules check_image_repo.yaml base-valid.yaml
[
{
"AssertionMessage": "Every expression fails: And expression fails: image does not start with my-company.com/",
"Category": "",
"CreatedAt": "2020-06-04T01:29:25Z",
"Filename": "test-data/base-valid.yaml",
"LineNumber": 0,
"ResourceID": "http-echo",
"ResourceType": "Deployment",
"RuleID": "DEPLOYMENT_IMAGE_REPOSITORY",
"RuleMessage": "Deployment must use a valid image repository",
"Status": "FAILURE"
}
]
ΠΡΠΎΠ²Π΅ΡΠΊΠ°ΡΠ° Π΅ Π½Π΅ΡΡΠΏΠ΅ΡΠ½Π°. Π‘Π΅Π³Π° Π½Π΅ΠΊΠ° ΠΏΡΠΎΠ²Π΅ΡΠΈΠΌ ΡΠ»Π΅Π΄Π½ΠΈΡ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡ Ρ ΠΏΡΠ°Π²ΠΈΠ»Π½ΠΎΡΠΎ Ρ ΡΠ°Π½ΠΈΠ»ΠΈΡΠ΅ Π½Π° ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ:
apiVersion: apps/v1
kind: Deployment
metadata:
name: http-echo
spec:
replicas: 2
selector:
matchLabels:
app: http-echo
template:
metadata:
labels:
app: http-echo
spec:
containers:
- name: http-echo
image: my-company.com/http-echo:1.0 # !!!
args: ["-text", "hello-world"]
ports:
- containerPort: 5678
(image-valid-mycompany.yaml
)
ΠΡΠΎΠ²Π΅ΠΆΠ΄Π°ΠΌΠ΅ ΡΡΡΠΈΡ ΡΠ΅ΡΡ Ρ Π³ΠΎΡΠ½ΠΈΡ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡ. ΠΡΠΌΠ° Π½Π°ΠΌΠ΅ΡΠ΅Π½ΠΈ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠΈ:
$ config-lint -rules check_image_repo.yaml image-valid-mycompany.yaml
[]
Config-lint Π΅ ΠΎΠ±Π΅ΡΠ°Π²Π°ΡΠ° ΡΠ°ΠΌΠΊΠ°, ΠΊΠΎΡΡΠΎ Π²ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ²Π° Π΄Π° ΡΡΠ·Π΄Π°Π²Π°ΡΠ΅ ΡΠ²ΠΎΠΈ ΡΠΎΠ±ΡΡΠ²Π΅Π½ΠΈ ΡΠ΅ΡΡΠΎΠ²Π΅ Π·Π° Π²Π°Π»ΠΈΠ΄ΠΈΡΠ°Π½Π΅ Π½Π° Kubernetes YAML ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠΈ Ρ ΠΏΠΎΠΌΠΎΡΡΠ° Π½Π° YAML DSL.
ΠΠΎ ΠΊΠ°ΠΊΠ²ΠΎ ΡΠ΅ ΡΡΠ°Π½Π΅, Π°ΠΊΠΎ ΠΈΠΌΠ°ΡΠ΅ Π½ΡΠΆΠ΄Π° ΠΎΡ ΠΏΠΎ-ΡΠ»ΠΎΠΆΠ½Π° Π»ΠΎΠ³ΠΈΠΊΠ° ΠΈ ΡΠ΅ΡΡΠΎΠ²Π΅? YAML Π½Π΅ Π΅ Π»ΠΈ ΡΠ²ΡΡΠ΄Π΅ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ Π·Π° ΡΠΎΠ²Π°? ΠΠ°ΠΊΠ²ΠΎ ΡΠ΅ ΡΡΠ°Π½Π΅, Π°ΠΊΠΎ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΡΡΠ·Π΄Π°Π²Π°ΡΠ΅ ΡΠ΅ΡΡΠΎΠ²Π΅ Π½Π° ΠΏΡΠ»Π΅Π½ Π΅Π·ΠΈΠΊ Π·Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ°Π½Π΅?
4. ΠΠ΅Π΄
ΠΡΠΏΡΠ΅ΠΊΠΈ ΡΠΎΠ²Π°, ΡΠΎΠΉ ΡΠ΅ ΡΠ°Π·Π»ΠΈΡΠ°Π²Π° ΠΎΡ ΠΏΠΎΡΠ»Π΅Π΄Π½ΠΈΡ ΠΏΠΎ ΡΠΎΠ²Π°, ΡΠ΅ Π½Π΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° YAML Π·Π° ΠΎΠΏΠΈΡΠ²Π°Π½Π΅ Π½Π° ΡΠ΅ΡΡΠΎΠ²Π΅. ΠΠΌΠ΅ΡΡΠΎ ΡΠΎΠ²Π° ΡΠ΅ΡΡΠΎΠ²Π΅ΡΠ΅ ΠΌΠΎΠ³Π°Ρ Π΄Π° Π±ΡΠ΄Π°Ρ Π½Π°ΠΏΠΈΡΠ°Π½ΠΈ Π½Π° JavaScript. Copper ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Ρ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° Ρ Π½ΡΠΊΠΎΠ»ΠΊΠΎ ΠΎΡΠ½ΠΎΠ²Π½ΠΈ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠ°, ΠΊΠΎΠΈΡΠΎ Π²ΠΈ ΠΏΠΎΠΌΠ°Π³Π°Ρ Π΄Π° ΡΠ΅ΡΠ΅ΡΠ΅ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ Π·Π° ΠΎΠ±Π΅ΠΊΡΠΈΡΠ΅ Π½Π° Kubernetes ΠΈ Π΄Π° ΡΡΠΎΠ±ΡΠ°Π²Π°ΡΠ΅ Π·Π° Π³ΡΠ΅ΡΠΊΠΈ.
Π‘ΡΡΠΏΠΊΠΈΡΠ΅ Π·Π° ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ°Π½Π΅ Π½Π° Copper ΠΌΠΎΠ³Π°Ρ Π΄Π° Π±ΡΠ΄Π°Ρ Π½Π°ΠΌΠ΅ΡΠ΅Π½ΠΈ Π²
2.0.1 Π΅ Π½Π°ΠΉ-Π½ΠΎΠ²Π°ΡΠ° Π²Π΅ΡΡΠΈΡ Π½Π° ΡΠ°Π·ΠΈ ΠΏΠΎΠΌΠΎΡΠ½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° ΠΊΡΠΌ ΠΌΠΎΠΌΠ΅Π½ΡΠ° Π½Π° ΠΏΠΈΡΠ°Π½Π΅ Π½Π° ΠΎΡΠΈΠ³ΠΈΠ½Π°Π»Π½Π°ΡΠ° ΡΡΠ°ΡΠΈΡ.
ΠΠΎΠ΄ΠΎΠ±Π½ΠΎ Π½Π° config-lint, Copper Π½ΡΠΌΠ° Π²Π³ΡΠ°Π΄Π΅Π½ΠΈ ΡΠ΅ΡΡΠΎΠ²Π΅. ΠΠ° Π½Π°ΠΏΠΈΡΠ΅ΠΌ Π΅Π΄Π½ΠΎ. ΠΠ΅ΠΊΠ° ΠΏΡΠΎΠ²Π΅ΡΠΈ Π΄Π°Π»ΠΈ Π²Π½Π΅Π΄ΡΡΠ²Π°Π½ΠΈΡΡΠ° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ Π½Π° ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠΈ ΠΈΠ·ΠΊΠ»ΡΡΠΈΡΠ΅Π»Π½ΠΎ ΠΎΡ Π½Π°Π΄Π΅ΠΆΠ΄Π½ΠΈ Ρ
ΡΠ°Π½ΠΈΠ»ΠΈΡΠ° ΠΊΠ°ΡΠΎ my-company.com
.
Π‘ΡΠ·Π΄Π°ΠΉΡΠ΅ ΡΠ°ΠΉΠ» check_image_repo.js
ΡΡΡ ΡΠ»Π΅Π΄Π½ΠΎΡΠΎ ΡΡΠ΄ΡΡΠΆΠ°Π½ΠΈΠ΅:
$$.forEach(function($){
if ($.kind === 'Deployment') {
$.spec.template.spec.containers.forEach(function(container) {
var image = new DockerImage(container.image);
if (image.registry.lastIndexOf('my-company.com/') != 0) {
errors.add_error('no_company_repo',"Image " + $.metadata.name + " is not from my-company.com repo", 1)
}
});
}
});
Π‘Π΅Π³Π° Π΄Π° ΡΠ΅ΡΡΠ²Π°ΠΌΠ΅ Π½Π°ΡΠΈΡ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡ base-valid.yaml
, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΡΠ΅ ΠΊΠΎΠΌΠ°Π½Π΄Π°ΡΠ° copper validate
:
$ copper validate --in=base-valid.yaml --validator=check_image_tag.js
Check no_company_repo failed with severity 1 due to Image http-echo is not from my-company.com repo
Validation failed
Π―ΡΠ½ΠΎ Π΅, ΡΠ΅ Ρ ΠΏΠΎΠΌΠΎΡΡΠ° Π½Π° ΠΌΠ΅Π΄ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΈΠ·Π²ΡΡΡΠ²Π°ΡΠ΅ ΠΏΠΎ-ΡΠ»ΠΎΠΆΠ½ΠΈ ΡΠ΅ΡΡΠΎΠ²Π΅ - Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ ΠΏΡΠΎΠ²Π΅ΡΠΊΠ° Π½Π° ΠΈΠΌΠ΅Π½Π°ΡΠ° Π½Π° Π΄ΠΎΠΌΠ΅ΠΉΠ½ΠΈ Π² ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠΈΡΠ΅ Π½Π° Ingress ΠΈΠ»ΠΈ ΠΎΡΡ Π²ΡΡΠ»ΡΠ½Π΅ Π½Π° ΠΏΠΎΠ΄ΠΎΠ²Π΅, ΡΠ°Π±ΠΎΡΠ΅ΡΠΈ Π² ΠΏΡΠΈΠ²ΠΈΠ»Π΅Π³ΠΈΡΠΎΠ²Π°Π½ ΡΠ΅ΠΆΠΈΠΌ.
ΠΠ΅Π΄ΡΠ° ΠΈΠΌΠ° ΡΠ°Π·Π»ΠΈΡΠ½ΠΈ ΠΏΠΎΠ»Π΅Π·Π½ΠΈ ΡΡΠ½ΠΊΡΠΈΠΈ, Π²Π³ΡΠ°Π΄Π΅Π½ΠΈ Π² Π½Π΅Ρ:
DockerImage
ΡΠ΅ΡΠ΅ ΠΏΠΎΡΠΎΡΠ΅Π½ΠΈΡ Π²Ρ ΠΎΠ΄Π΅Π½ ΡΠ°ΠΉΠ» ΠΈ ΡΡΠ·Π΄Π°Π²Π° ΠΎΠ±Π΅ΠΊΡ ΡΡΡ ΡΠ»Π΅Π΄Π½ΠΈΡΠ΅ Π°ΡΡΠΈΠ±ΡΡΠΈ:name
- ΠΈΠΌΠ΅ Π½Π° ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ΡΠΎ,tag
- Π΅ΡΠΈΠΊΠ΅Ρ Π½Π° ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ΡΠΎ,registry
- ΡΠ΅Π³ΠΈΡΡΡΡ Π½Π° ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡΡΠ°,registry_url
- ΠΏΡΠΎΡΠΎΠΊΠΎΠ» (https://
) ΠΈ ΡΠ΅Π³ΠΈΡΡΡΡ Π½Π° ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡΡΠ°,fqin
β ΠΏΡΠ»Π½ΠΎ ΠΌΠ΅ΡΡΠΎΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π½Π° ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ΡΠΎ.
- Π€ΡΠ½ΠΊΡΠΈΡ
findByName
ΠΏΠΎΠΌΠ°Π³Π° Π·Π° Π½Π°ΠΌΠΈΡΠ°Π½Π΅ Π½Π° ΡΠ΅ΡΡΡΡ ΠΏΠΎ Π΄Π°Π΄Π΅Π½ ΡΠΈΠΏ (kind
) ΠΈ ΠΈΠΌΠ΅ (name
) ΠΎΡ Π²Ρ ΠΎΠ΄Π½ΠΈΡ ΡΠ°ΠΉΠ». - Π€ΡΠ½ΠΊΡΠΈΡ
findByLabels
ΠΏΠΎΠΌΠ°Π³Π° Π΄Π° ΡΠ΅ Π½Π°ΠΌΠ΅ΡΠΈ ΡΠ΅ΡΡΡΡ ΠΏΠΎ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ ΡΠΈΠΏ (kind
) ΠΈ Π΅ΡΠΈΠΊΠ΅ΡΠΈ (labels
).
ΠΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π²ΠΈΠ΄ΠΈΡΠ΅ Π²ΡΠΈΡΠΊΠΈ Π½Π°Π»ΠΈΡΠ½ΠΈ ΡΠ΅ΡΠ²ΠΈΠ·Π½ΠΈ ΡΡΠ½ΠΊΡΠΈΠΈ
ΠΠΎ ΠΏΠΎΠ΄ΡΠ°Π·Π±ΠΈΡΠ°Π½Π΅ ΡΠΎΠΉ Π·Π°ΡΠ΅ΠΆΠ΄Π° ΡΠ΅Π»ΠΈΡ Π²Ρ
ΠΎΠ΄Π΅Π½ YAML ΡΠ°ΠΉΠ» Π² ΠΏΡΠΎΠΌΠ΅Π½Π»ΠΈΠ²Π° $$
ΠΈ Π³ΠΎ ΠΏΡΠ°Π²ΠΈ Π΄ΠΎΡΡΡΠΏΠ΅Π½ Π·Π° ΡΠΊΡΠΈΠΏΡΠΎΠ²Π΅ (ΠΏΠΎΠ·Π½Π°ΡΠ° ΡΠ΅Ρ
Π½ΠΈΠΊΠ° Π·Π° ΡΠ΅Π·ΠΈ Ρ ΠΎΠΏΠΈΡ Π² jQuery).
ΠΡΠ½ΠΎΠ²Π½ΠΎΡΠΎ ΠΏΡΠ΅Π΄ΠΈΠΌΡΡΠ²ΠΎ Π½Π° Copper Π΅ ΠΎΡΠ΅Π²ΠΈΠ΄Π½ΠΎ: Π½Π΅ Π΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ Π΄Π° Π²Π»Π°Π΄Π΅Π΅ΡΠ΅ ΡΠΏΠ΅ΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΠ°Π½ Π΅Π·ΠΈΠΊ ΠΈ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΡΠ΅ ΡΠ°Π·Π»ΠΈΡΠ½ΠΈ ΡΡΠ½ΠΊΡΠΈΠΈ Π½Π° JavaScript, Π·Π° Π΄Π° ΡΡΠ·Π΄Π°Π²Π°ΡΠ΅ ΡΠ²ΠΎΠΈ ΡΠΎΠ±ΡΡΠ²Π΅Π½ΠΈ ΡΠ΅ΡΡΠΎΠ²Π΅, ΠΊΠ°ΡΠΎ ΠΈΠ½ΡΠ΅ΡΠΏΠΎΠ»Π°ΡΠΈΡ Π½Π° Π½ΠΈΠ·ΠΎΠ²Π΅, ΡΡΠ½ΠΊΡΠΈΠΈ ΠΈ Ρ.Π½.
Π’ΡΡΠ±Π²Π° ΡΡΡΠΎ Π΄Π° ΡΠ΅ ΠΎΡΠ±Π΅Π»Π΅ΠΆΠΈ, ΡΠ΅ ΡΠ΅ΠΊΡΡΠ°ΡΠ° Π²Π΅ΡΡΠΈΡ Π½Π° Copper ΡΠ°Π±ΠΎΡΠΈ Ρ Π²Π΅ΡΡΠΈΡΡΠ° ES5 Π½Π° Π΄Π²ΠΈΠ³Π°ΡΠ΅Π»Ρ Π½Π° JavaScript, Π° Π½Π΅ Ρ ES6.
ΠΠΎΠ΄ΡΠΎΠ±Π½ΠΎΡΡΠΈ ΡΠ° Π½Π°Π»ΠΈΡΠ½ΠΈ Π½Π°
ΠΠΊΠΎ ΠΎΠ±Π°ΡΠ΅ Π½Π°ΠΈΡΡΠΈΠ½Π° Π½Π΅ Ρ Π°ΡΠ΅ΡΠ²Π°ΡΠ΅ JavaScript ΠΈ ΠΏΡΠ΅Π΄ΠΏΠΎΡΠΈΡΠ°ΡΠ΅ Π΅Π·ΠΈΠΊ, ΡΠΏΠ΅ΡΠΈΠ°Π»Π½ΠΎ ΡΡΠ·Π΄Π°Π΄Π΅Π½ Π·Π° ΡΡΠ·Π΄Π°Π²Π°Π½Π΅ Π½Π° Π·Π°ΡΠ²ΠΊΠΈ ΠΈ ΠΎΠΏΠΈΡΠ²Π°Π½Π΅ Π½Π° ΠΏΠΎΠ»ΠΈΡΠΈΠΊΠΈ, ΡΡΡΠ±Π²Π° Π΄Π° ΠΎΠ±ΡΡΠ½Π΅ΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° conftest.
5. ΠΠΎΠ½ΠΊΡΡΡ
Conftest Π΅ ΡΠ°ΠΌΠΊΠ° Π·Π° ΡΠ΅ΡΡΠ²Π°Π½Π΅ Π½Π° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΎΠ½Π½ΠΈ Π΄Π°Π½Π½ΠΈ. Π‘ΡΡΠΎ ΡΠ°ΠΊΠ° ΠΏΠΎΠ΄Ρ
ΠΎΠ΄ΡΡ Π·Π° ΡΠ΅ΡΡΠ²Π°Π½Π΅/ΠΏΡΠΎΠ²Π΅ΡΠΊΠ° Π½Π° Kubernetes ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠΈ. Π’Π΅ΡΡΠΎΠ²Π΅ΡΠ΅ ΡΠ° ΠΎΠΏΠΈΡΠ°Π½ΠΈ Ρ ΠΏΠΎΠΌΠΎΡΡΠ° Π½Π° ΡΠΏΠ΅ΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΠ°Π½ Π΅Π·ΠΈΠΊ Π·Π° Π·Π°ΡΠ²ΠΊΠΈ
ΠΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ°ΡΠ΅ conftest, ΠΊΠ°ΡΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΡΠ΅
ΠΡΠΌ ΠΌΠΎΠΌΠ΅Π½ΡΠ° Π½Π° ΠΏΠΈΡΠ°Π½Π΅ Π½Π° ΠΎΡΠΈΠ³ΠΈΠ½Π°Π»Π½Π°ΡΠ° ΡΡΠ°ΡΠΈΡ ΠΏΠΎΡΠ»Π΅Π΄Π½Π°ΡΠ° Π½Π°Π»ΠΈΡΠ½Π° Π²Π΅ΡΡΠΈΡ Π±Π΅ΡΠ΅ 0.18.2.
ΠΠΎΠ΄ΠΎΠ±Π½ΠΎ Π½Π° config-lint ΠΈ copper, conftest ΠΈΠ΄Π²Π° Π±Π΅Π· Π½ΠΈΠΊΠ°ΠΊΠ²ΠΈ Π²Π³ΡΠ°Π΄Π΅Π½ΠΈ ΡΠ΅ΡΡΠΎΠ²Π΅. ΠΠ΅ΠΊΠ° Π΄Π° Π³ΠΎ ΠΈΠ·ΠΏΡΠΎΠ±Π²Π°ΠΌΠ΅ ΠΈ Π΄Π° Π½Π°ΠΏΠΈΡΠ΅ΠΌ Π½Π°ΡΠ°ΡΠ° ΡΠΎΠ±ΡΡΠ²Π΅Π½Π° ΠΏΠΎΠ»ΠΈΡΠΈΠΊΠ°. ΠΠ°ΠΊΡΠΎ Π² ΠΏΡΠ΅Π΄ΠΈΡΠ½ΠΈΡΠ΅ ΠΏΡΠΈΠΌΠ΅ΡΠΈ, ΡΠ΅ ΠΏΡΠΎΠ²Π΅ΡΠΈΠΌ Π΄Π°Π»ΠΈ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡΡΠ° Π½Π° ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠ° ΡΠ° Π²Π·Π΅ΡΠΈ ΠΎΡ Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ ΠΈΠ·ΡΠΎΡΠ½ΠΈΠΊ.
Π‘ΡΠ·Π΄Π°ΠΉΡΠ΅ Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΡ conftest-checks
, Π° Π² Π½Π΅Π³ΠΎ ΠΈΠΌΠ° ΡΠ°ΠΉΠ» Ρ ΠΈΠΌΠ΅ check_image_registry.rego
ΡΡΡ ΡΠ»Π΅Π΄Π½ΠΎΡΠΎ ΡΡΠ΄ΡΡΠΆΠ°Π½ΠΈΠ΅:
package main
deny[msg] {
input.kind == "Deployment"
image := input.spec.template.spec.containers[_].image
not startswith(image, "my-company.com/")
msg := sprintf("image '%v' doesn't come from my-company.com repository", [image])
}
Π‘Π΅Π³Π° Π½Π΅ΠΊΠ° ΡΠ΅ΡΡΠ²Π°ΠΌΠ΅ base-valid.yaml
ΠΏΡΠ΅Π· conftest
:
$ conftest test --policy ./conftest-checks base-valid.yaml
FAIL - base-valid.yaml - image 'hashicorp/http-echo' doesn't come from my-company.com repository
1 tests, 1 passed, 0 warnings, 1 failure
Π’Π΅ΡΡΡΡ ΠΎΡΠ°ΠΊΠ²Π°Π½ΠΎ ΡΠ΅ ΠΏΡΠΎΠ²Π°Π»ΠΈ, Π·Π°ΡΠΎΡΠΎ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡΡΠ° ΠΈΠ΄Π²Π°Ρ ΠΎΡ Π½Π΅Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ ΠΈΠ·ΡΠΎΡΠ½ΠΈΠΊ.
ΠΡΠ² ΡΠ°ΠΉΠ»Π° Rego Π΄Π΅ΡΠΈΠ½ΠΈΡΠ°ΠΌΠ΅ Π±Π»ΠΎΠΊΠ° deny
. ΠΡΡΠΈΠ½Π°ΡΠ° ΠΌΡ ΡΠ΅ ΡΡΠΈΡΠ° Π·Π° Π½Π°ΡΡΡΠ΅Π½ΠΈΠ΅. ΠΠΊΠΎ Π±Π»ΠΎΠΊΠΎΠ²Π΅ deny
Π½ΡΠΊΠΎΠ»ΠΊΠΎ, conftest Π³ΠΈ ΠΏΡΠΎΠ²Π΅ΡΡΠ²Π° Π½Π΅Π·Π°Π²ΠΈΡΠΈΠΌΠΎ Π΅Π΄ΠΈΠ½ ΠΎΡ Π΄ΡΡΠ³ ΠΈ ΠΈΡΡΠΈΠ½Π½ΠΎΡΡΡΠ° Π½Π° Π²ΡΠ΅ΠΊΠΈ ΠΎΡ Π±Π»ΠΎΠΊΠΎΠ²Π΅ΡΠ΅ ΡΠ΅ ΡΡΠ΅ΡΠΈΡΠ° ΠΊΠ°ΡΠΎ Π½Π°ΡΡΡΠ΅Π½ΠΈΠ΅.
Π Π΄ΠΎΠΏΡΠ»Π½Π΅Π½ΠΈΠ΅ ΠΊΡΠΌ ΠΈΠ·Ρ
ΠΎΠ΄Π° ΠΏΠΎ ΠΏΠΎΠ΄ΡΠ°Π·Π±ΠΈΡΠ°Π½Π΅, conftest ΠΏΠΎΠ΄Π΄ΡΡΠΆΠ° JSON, TAP ΠΈ ΡΠ°Π±Π»ΠΈΡΠ΅Π½ ΡΠΎΡΠΌΠ°Ρ - ΠΈΠ·ΠΊΠ»ΡΡΠΈΡΠ΅Π»Π½ΠΎ ΠΏΠΎΠ»Π΅Π·Π½Π° ΡΡΠ½ΠΊΡΠΈΡ, Π°ΠΊΠΎ ΡΡΡΠ±Π²Π° Π΄Π° Π²Π³ΡΠ°Π΄ΠΈΡΠ΅ ΠΎΡΡΠ΅ΡΠΈ Π² ΡΡΡΠ΅ΡΡΠ²ΡΠ²Π°Ρ CI ΠΊΠ°Π½Π°Π». ΠΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π·Π°Π΄Π°Π΄Π΅ΡΠ΅ ΠΆΠ΅Π»Π°Π½ΠΈΡ ΡΠΎΡΠΌΠ°Ρ Ρ ΠΏΠΎΠΌΠΎΡΡΠ° Π½Π° ΡΠ»Π°Π³Π° --output
.
ΠΠ° Π΄Π° ΡΠ»Π΅ΡΠ½ΠΈ ΠΎΡΡΡΡΠ°Π½ΡΠ²Π°Π½Π΅ΡΠΎ Π½Π° Π³ΡΠ΅ΡΠΊΠΈ Π² ΠΏΠΎΠ»ΠΈΡΠΈΠΊΠΈΡΠ΅, conftest ΠΈΠΌΠ° ΡΠ»Π°Π³ --trace
. Π’ΠΎΠΉ ΠΈΠ·Π²Π΅ΠΆΠ΄Π° ΡΠ»Π΅Π΄Π° Π·Π° ΡΠΎΠ²Π° ΠΊΠ°ΠΊ conftest Π°Π½Π°Π»ΠΈΠ·ΠΈΡΠ° ΠΏΠΎΡΠΎΡΠ΅Π½ΠΈΡΠ΅ ΡΠ°ΠΉΠ»ΠΎΠ²Π΅ Ρ ΠΏΡΠ°Π²ΠΈΠ»Π°.
ΠΠΎΠ»ΠΈΡΠΈΠΊΠΈΡΠ΅ Π½Π° ΠΊΠΎΠ½ΠΊΡΡΡΠ° ΠΌΠΎΠ³Π°Ρ Π΄Π° Π±ΡΠ΄Π°Ρ ΠΏΡΠ±Π»ΠΈΠΊΡΠ²Π°Π½ΠΈ ΠΈ ΡΠΏΠΎΠ΄Π΅Π»ΡΠ½ΠΈ Π² ΡΠ΅Π³ΠΈΡΡΡΠΈΡΠ΅ Π½Π° OCI (Open Container Initiative) ΠΊΠ°ΡΠΎ Π°ΡΡΠ΅ΡΠ°ΠΊΡΠΈ.
ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ push
ΠΈ pull
Π²ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ²Π°Ρ Π΄Π° ΠΏΡΠ±Π»ΠΈΠΊΡΠ²Π°ΡΠ΅ Π°ΡΡΠ΅ΡΠ°ΠΊΡ ΠΈΠ»ΠΈ Π΄Π° ΠΈΠ·Π²Π»Π΅ΡΠ΅ΡΠ΅ ΡΡΡΠ΅ΡΡΠ²ΡΠ²Π°Ρ Π°ΡΡΠ΅ΡΠ°ΠΊΡ ΠΎΡ ΠΎΡΠ΄Π°Π»Π΅ΡΠ΅Π½ ΡΠ΅Π³ΠΈΡΡΡΡ. ΠΠ΅ΠΊΠ° ΠΎΠΏΠΈΡΠ°ΠΌΠ΅ Π΄Π° ΠΏΡΠ±Π»ΠΈΠΊΡΠ²Π°ΠΌΠ΅ ΠΏΠΎΠ»ΠΈΡΠΈΠΊΠ°ΡΠ°, ΠΊΠΎΡΡΠΎ ΡΡΠ·Π΄Π°Π΄ΠΎΡ
ΠΌΠ΅, Π² Π»ΠΎΠΊΠ°Π»Π½ΠΈΡ ΡΠ΅Π³ΠΈΡΡΡΡ Π½Π° Docker, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ conftest push
.
Π‘ΡΠ°ΡΡΠΈΡΠ°ΠΉΡΠ΅ Π²Π°ΡΠΈΡ Π»ΠΎΠΊΠ°Π»Π΅Π½ ΡΠ΅Π³ΠΈΡΡΡΡ Π½Π° Docker:
$ docker run -it --rm -p 5000:5000 registry
Π Π΄ΡΡΠ³ ΡΠ΅ΡΠΌΠΈΠ½Π°Π» ΠΎΡΠΈΠ΄Π΅ΡΠ΅ Π² Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΡΡΠ°, ΠΊΠΎΡΡΠΎ ΡΡΠ΅ ΡΡΠ·Π΄Π°Π»ΠΈ ΠΏΠΎ-ΡΠ°Π½ΠΎ conftest-checks
ΠΈ ΠΈΠ·ΠΏΡΠ»Π½Π΅ΡΠ΅ ΡΠ»Π΅Π΄Π½Π°ΡΠ° ΠΊΠΎΠΌΠ°Π½Π΄Π°:
$ conftest push 127.0.0.1:5000/amitsaha/opa-bundle-example:latest
ΠΠΊΠΎ ΠΊΠΎΠΌΠ°Π½Π΄Π°ΡΠ° Π΅ Π±ΠΈΠ»Π° ΡΡΠΏΠ΅ΡΠ½Π°, ΡΠ΅ Π²ΠΈΠ΄ΠΈΡΠ΅ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ ΠΊΠ°ΡΠΎ ΡΠΎΠ²Π°:
2020/06/10 14:25:43 pushed bundle with digest: sha256:e9765f201364c1a8a182ca637bc88201db3417bacc091e7ef8211f6c2fd2609c
Π‘Π΅Π³Π° ΡΡΠ·Π΄Π°ΠΉΡΠ΅ Π²ΡΠ΅ΠΌΠ΅Π½Π½Π° Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΡ ΠΈ ΠΈΠ·ΠΏΡΠ»Π½Π΅ΡΠ΅ ΠΊΠΎΠΌΠ°Π½Π΄Π°ΡΠ° Π² Π½Π΅Ρ conftest pull
. Π’ΠΎΠΉ ΡΠ΅ ΠΈΠ·ΡΠ΅Π³Π»ΠΈ ΠΏΠ°ΠΊΠ΅ΡΠ°, ΡΡΠ·Π΄Π°Π΄Π΅Π½ ΠΎΡ ΠΏΡΠ΅Π΄ΠΈΡΠ½Π°ΡΠ° ΠΊΠΎΠΌΠ°Π½Π΄Π°:
$ cd $(mktemp -d)
$ conftest pull 127.0.0.1:5000/amitsaha/opa-bundle-example:latest
ΠΡΠ² Π²ΡΠ΅ΠΌΠ΅Π½Π½Π°ΡΠ° Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΡ ΡΠ΅ ΡΠ΅ ΠΏΠΎΡΠ²ΠΈ ΠΏΠΎΠ΄Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΡ policy
ΡΡΠ΄ΡΡΠΆΠ°Ρ Π½Π°ΡΠΈΡ ΡΠ°ΠΉΠ» Ρ ΠΏΡΠ°Π²ΠΈΠ»Π°:
$ tree
.
βββ policy
βββ check_image_registry.rego
Π’Π΅ΡΡΠΎΠ²Π΅ΡΠ΅ ΠΌΠΎΠ³Π°Ρ Π΄Π° ΡΠ΅ ΠΈΠ·ΠΏΡΠ»Π½ΡΠ²Π°Ρ Π΄ΠΈΡΠ΅ΠΊΡΠ½ΠΎ ΠΎΡ Ρ ΡΠ°Π½ΠΈΠ»ΠΈΡΠ΅ΡΠΎ:
$ conftest test --update 127.0.0.1:5000/amitsaha/opa-bundle-example:latest base-valid.yaml
..
FAIL - base-valid.yaml - image 'hashicorp/http-echo' doesn't come from my-company.com repository
2 tests, 1 passed, 0 warnings, 1 failure
ΠΠ° ΡΡΠΆΠ°Π»Π΅Π½ΠΈΠ΅, DockerHub Π²ΡΠ΅ ΠΎΡΠ΅ Π½Π΅ ΡΠ΅ ΠΏΠΎΠ΄Π΄ΡΡΠΆΠ°. Π’Π°ΠΊΠ° ΡΠ΅ ΡΡΠΈΡΠ°ΠΉΡΠ΅ ΡΠ΅ Π·Π° ΠΊΡΡΠΌΠ΅ΡΠ»ΠΈΡ, Π°ΠΊΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΡΠ΅
Π€ΠΎΡΠΌΠ°ΡΡΡ Π½Π° Π°ΡΡΠ΅ΡΠ°ΠΊΡΠ° Π΅ ΡΡΡΠΈΡΡ ΠΊΠ°ΡΠΎ
ΠΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π½Π°ΡΡΠΈΡΠ΅ ΠΏΠΎΠ²Π΅ΡΠ΅ Π·Π° ΡΠΏΠΎΠ΄Π΅Π»ΡΠ½Π΅ΡΠΎ Π½Π° ΠΏΠΎΠ»ΠΈΡΠΈΠΊΠΈ ΠΈ Π΄ΡΡΠ³ΠΈ ΡΡΠ½ΠΊΡΠΈΠΈ Π½Π° confest Π½Π°
6. ΠΠΎΠ»ΡΡΠ½Π°ΡΠ° Π·Π²Π΅Π·Π΄Π°
ΠΠΎΡΠ»Π΅Π΄Π½ΠΈΡΡ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½Ρ, ΠΊΠΎΠΉΡΠΎ ΡΠ΅ Π±ΡΠ΄Π΅ ΠΎΠ±ΡΡΠ΄Π΅Π½ Π² ΡΠ°Π·ΠΈ ΡΡΠ°ΡΠΈΡ, Π΅
Polaris ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ° Π² ΠΊΠ»ΡΡΡΠ΅Ρ ΠΈΠ»ΠΈ Π΄Π° ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π² ΡΠ΅ΠΆΠΈΠΌ Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄Π΅Π½ ΡΠ΅Π΄. ΠΠ°ΠΊΡΠΎ ΠΌΠΎΠΆΠ΅ Π±ΠΈ ΡΠ΅ Π΄ΠΎΡΠ΅ΡΠ°ΡΠ΅, ΡΠΎΠ²Π° Π²ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ²Π° Π΄Π° Π°Π½Π°Π»ΠΈΠ·ΠΈΡΠ°ΡΠ΅ ΡΡΠ°ΡΠΈΡΠ½ΠΎ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠΈΡΠ΅ Π½Π° Kubernetes.
ΠΠΎΠ³Π°ΡΠΎ ΡΠ΅ ΠΈΠ·ΠΏΡΠ»Π½ΡΠ²Π° Π² ΡΠ΅ΠΆΠΈΠΌ Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄Π΅Π½ ΡΠ΅Π΄, ΡΠ° Π½Π°Π»ΠΈΡΠ½ΠΈ Π²Π³ΡΠ°Π΄Π΅Π½ΠΈ ΡΠ΅ΡΡΠΎΠ²Π΅, ΠΎΠ±Ρ Π²Π°ΡΠ°ΡΠΈ ΠΎΠ±Π»Π°ΡΡΠΈ ΠΊΠ°ΡΠΎ ΡΠΈΠ³ΡΡΠ½ΠΎΡΡ ΠΈ Π½Π°ΠΉ-Π΄ΠΎΠ±ΡΠΈ ΠΏΡΠ°ΠΊΡΠΈΠΊΠΈ (ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎ Π½Π° kube-score). ΠΡΠ²Π΅Π½ ΡΠΎΠ²Π° ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΡΡΠ·Π΄Π°Π΄Π΅ΡΠ΅ ΡΠ²ΠΎΠΈ ΡΠΎΠ±ΡΡΠ²Π΅Π½ΠΈ ΡΠ΅ΡΡΠΎΠ²Π΅ (ΠΊΠ°ΠΊΡΠΎ Π² config-lint, copper ΠΈ conftest).
Π‘ Π΄ΡΡΠ³ΠΈ Π΄ΡΠΌΠΈ, Polaris ΡΡΡΠ΅ΡΠ°Π²Π° ΠΏΡΠ΅Π΄ΠΈΠΌΡΡΠ²Π°ΡΠ° Π½Π° Π΄Π²Π΅ΡΠ΅ ΠΊΠ°ΡΠ΅Π³ΠΎΡΠΈΠΈ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠΈ: Ρ Π²Π³ΡΠ°Π΄Π΅Π½ΠΈ ΠΈ ΠΏΠ΅ΡΡΠΎΠ½Π°Π»ΠΈΠ·ΠΈΡΠ°Π½ΠΈ ΡΠ΅ΡΡΠΎΠ²Π΅.
ΠΠ° Π΄Π° ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ°ΡΠ΅ Polaris Π² ΡΠ΅ΠΆΠΈΠΌ Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄Π΅Π½ ΡΠ΅Π΄, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΡΠ΅
ΠΡΠΌ ΠΌΠΎΠΌΠ΅Π½ΡΠ° Π½Π° ΠΏΠΈΡΠ°Π½Π΅ Π½Π° ΠΎΡΠΈΠ³ΠΈΠ½Π°Π»Π½Π°ΡΠ° ΡΡΠ°ΡΠΈΡ Π΅ Π½Π°Π»ΠΈΡΠ½Π° Π²Π΅ΡΡΠΈΡ 1.0.3.
Π‘Π»Π΅Π΄ ΠΊΠ°ΡΠΎ ΠΈΠ½ΡΡΠ°Π»Π°ΡΠΈΡΡΠ° ΠΏΡΠΈΠΊΠ»ΡΡΠΈ, ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΡΡΠ°ΡΡΠΈΡΠ°ΡΠ΅ polaris Π½Π° ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠ° base-valid.yaml
ΡΡΡ ΡΠ»Π΅Π΄Π½Π°ΡΠ° ΠΊΠΎΠΌΠ°Π½Π΄Π°:
$ polaris audit --audit-path base-valid.yaml
Π’ΠΎΠΉ ΡΠ΅ ΠΈΠ·Π²Π΅Π΄Π΅ Π½ΠΈΠ· Π²ΡΠ² ΡΠΎΡΠΌΠ°Ρ JSON Ρ ΠΏΠΎΠ΄ΡΠΎΠ±Π½ΠΎ ΠΎΠΏΠΈΡΠ°Π½ΠΈΠ΅ Π½Π° ΠΈΠ·Π²ΡΡΡΠ΅Π½ΠΈΡΠ΅ ΡΠ΅ΡΡΠΎΠ²Π΅ ΠΈ ΡΠ΅Π·ΡΠ»ΡΠ°ΡΠΈΡΠ΅ ΠΎΡ ΡΡΡ . Π Π΅Π·ΡΠ»ΡΠ°ΡΡΡ ΡΠ΅ ΠΈΠΌΠ° ΡΠ»Π΅Π΄Π½Π°ΡΠ° ΡΡΡΡΠΊΡΡΡΠ°:
{
"PolarisOutputVersion": "1.0",
"AuditTime": "0001-01-01T00:00:00Z",
"SourceType": "Path",
"SourceName": "test-data/base-valid.yaml",
"DisplayName": "test-data/base-valid.yaml",
"ClusterInfo": {
"Version": "unknown",
"Nodes": 0,
"Pods": 2,
"Namespaces": 0,
"Controllers": 2
},
"Results": [
/* Π΄Π»ΠΈΠ½Π½ΡΠΉ ΡΠΏΠΈΡΠΎΠΊ */
]
}
ΠΠ°Π»ΠΈΡΠ΅Π½ ΠΏΡΠ»Π΅Π½ ΠΈΠ·Ρ
ΠΎΠ΄
ΠΠΎΠ΄ΠΎΠ±Π½ΠΎ Π½Π° kube-score, Polaris ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΡΠΈΡΠ° ΠΏΡΠΎΠ±Π»Π΅ΠΌΠΈ Π² ΠΎΠ±Π»Π°ΡΡΠΈ, ΠΊΡΠ΄Π΅ΡΠΎ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΡΡ Π½Π΅ ΠΎΡΠ³ΠΎΠ²Π°ΡΡ Π½Π° Π½Π°ΠΉ-Π΄ΠΎΠ±ΡΠΈΡΠ΅ ΠΏΡΠ°ΠΊΡΠΈΠΊΠΈ:
- ΠΡΠΌΠ° Π·Π΄ΡΠ°Π²Π½ΠΈ ΠΏΡΠ΅Π³Π»Π΅Π΄ΠΈ Π·Π° ΠΏΠΎΠ΄Ρ.
- Π’Π°Π³ΠΎΠ²Π΅ Π·Π° ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ Π½Π° ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠΈ Π½Π΅ ΡΠ° ΠΏΠΎΡΠΎΡΠ΅Π½ΠΈ.
- ΠΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΡΡ ΡΠ°Π±ΠΎΡΠΈ ΠΊΠ°ΡΠΎ root.
- ΠΠ°ΡΠ²ΠΊΠΈ ΠΈ Π»ΠΈΠΌΠΈΡΠΈ Π·Π° ΠΏΠ°ΠΌΠ΅Ρ ΠΈ ΠΏΡΠΎΡΠ΅ΡΠΎΡ Π½Π΅ ΡΠ° ΠΏΠΎΡΠΎΡΠ΅Π½ΠΈ.
ΠΠ° Π²ΡΠ΅ΠΊΠΈ ΡΠ΅ΡΡ, Π² Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ ΠΎΡ Π½Π΅Π³ΠΎΠ²ΠΈΡΠ΅ ΡΠ΅Π·ΡΠ»ΡΠ°ΡΠΈ, ΡΠ΅ ΠΎΠΏΡΠ΅Π΄Π΅Π»Ρ ΡΡΠ΅ΠΏΠ΅Π½ Π½Π° ΠΊΡΠΈΡΠΈΡΠ½ΠΎΡΡ: ΠΏΡΠ΅Π΄ΡΠΏΡΠ΅ΠΆΠ΄Π΅Π½ΠΈΠ΅ ΠΈΠ»ΠΈ ΠΎΠΏΠ°ΡΠ½ΠΎΡΡ. ΠΠ° Π΄Π° Π½Π°ΡΡΠΈΡΠ΅ ΠΏΠΎΠ²Π΅ΡΠ΅ Π·Π° Π½Π°Π»ΠΈΡΠ½ΠΈΡΠ΅ Π²Π³ΡΠ°Π΄Π΅Π½ΠΈ ΡΠ΅ΡΡΠΎΠ²Π΅, Π²ΠΈΠΆΡΠ΅
ΠΠΊΠΎ Π½Π΅ ΡΠ° Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΈ ΠΏΠΎΠ΄ΡΠΎΠ±Π½ΠΎΡΡΠΈ, ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΏΠΎΡΠΎΡΠΈΡΠ΅ ΡΠ»Π°Π³Π° --format score
. Π ΡΠΎΠ·ΠΈ ΡΠ»ΡΡΠ°ΠΉ Polaris ΡΠ΅ ΠΈΠ·Π²Π΅Π΄Π΅ ΡΠΈΡΠ»ΠΎ Π² Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½Π° ΠΎΡ 1 Π΄ΠΎ 100 β ΡΠ΅Π·ΡΠ»ΡΠ°Ρ (Ρ.Π΅. ΠΎΡΠ΅Π½ΠΊΠ°):
$ polaris audit --audit-path test-data/base-valid.yaml --format score
68
ΠΠΎΠ»ΠΊΠΎΡΠΎ ΠΏΠΎ-Π±Π»ΠΈΠ·ΠΎ Π΅ ΡΠ΅Π·ΡΠ»ΡΠ°ΡΡΡ Π΄ΠΎ 100, ΡΠΎΠ»ΠΊΠΎΠ²Π° ΠΏΠΎ-Π²ΠΈΡΠΎΠΊΠ° Π΅ ΡΡΠ΅ΠΏΠ΅Π½ΡΠ° Π½Π° ΡΡΠ³Π»Π°ΡΠΈΠ΅. ΠΠΊΠΎ ΠΏΡΠΎΠ²Π΅ΡΠΈΡΠ΅ ΠΈΠ·Ρ
ΠΎΠ΄Π½ΠΈΡ ΠΊΠΎΠ΄ Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄Π°ΡΠ° polaris audit
, ΡΠ΅ ΠΎΠΊΠ°Π·Π²Π°, ΡΠ΅ Π΅ ΡΠ°Π²Π½ΠΎ Π½Π° 0.
Π‘ΠΈΠ»Π° polaris audit
ΠΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΏΡΠ΅ΠΊΡΠ°ΡΠΈΡΠ΅ ΡΠ°Π±ΠΎΡΠ°ΡΠ° Ρ Π½Π΅Π½ΡΠ»Π΅Π² ΠΊΠΎΠ΄, ΠΊΠ°ΡΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΡΠ΅ Π΄Π²Π° ΡΠ»Π°Π³Π°:
- ΡΠ»Π°Π³
--set-exit-code-below-score
ΠΏΡΠΈΠ΅ΠΌΠ° ΠΊΠ°ΡΠΎ Π°ΡΠ³ΡΠΌΠ΅Π½Ρ ΠΏΡΠ°Π³ΠΎΠ²Π° ΡΡΠΎΠΉΠ½ΠΎΡΡ Π² Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½Π° 1-100. Π ΡΠΎΠ·ΠΈ ΡΠ»ΡΡΠ°ΠΉ ΠΊΠΎΠΌΠ°Π½Π΄Π°ΡΠ° ΡΠ΅ ΠΈΠ·Π»Π΅Π·Π΅ Ρ ΠΊΠΎΠ΄ Π·Π° ΠΈΠ·Ρ ΠΎΠ΄ 4, Π°ΠΊΠΎ ΡΠ΅Π·ΡΠ»ΡΠ°ΡΡΡ Π΅ ΠΏΠΎΠ΄ ΠΏΡΠ°Π³Π°. Π’ΠΎΠ²Π° Π΅ ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ, ΠΊΠΎΠ³Π°ΡΠΎ ΠΈΠΌΠ°ΡΠ΅ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π° ΠΏΡΠ°Π³ΠΎΠ²Π° ΡΡΠΎΠΉΠ½ΠΎΡΡ (Π΄Π° ΡΠ΅ΡΠ΅ΠΌ 75) ΠΈ ΡΡΡΠ±Π²Π° Π΄Π° ΠΏΠΎΠ»ΡΡΠΈΡΠ΅ ΠΏΡΠ΅Π΄ΡΠΏΡΠ΅ΠΆΠ΄Π΅Π½ΠΈΠ΅, Π°ΠΊΠΎ ΡΠ΅Π·ΡΠ»ΡΠ°ΡΡΡ ΠΏΠ°Π΄Π½Π΅ ΠΏΠΎΠ΄ Π½Π΅Π³ΠΎ. - ΡΠ»Π°Π³
--set-exit-code-on-danger
ΡΠ΅ Π΄ΠΎΠ²Π΅Π΄Π΅ Π΄ΠΎ Π½Π΅ΡΡΠΏΠ΅Ρ Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄Π°ΡΠ° Ρ ΠΊΠΎΠ΄ 3, Π°ΠΊΠΎ Π΅Π΄ΠΈΠ½ ΠΎΡ ΡΠ΅ΡΡΠΎΠ²Π΅ΡΠ΅ Π·Π° ΠΎΠΏΠ°ΡΠ½ΠΎΡΡ Π΅ Π½Π΅ΡΡΠΏΠ΅ΡΠ΅Π½.
Π‘Π΅Π³Π° Π½Π΅ΠΊΠ° ΡΠ΅ ΠΎΠΏΠΈΡΠ°ΠΌΠ΅ Π΄Π° ΡΡΠ·Π΄Π°Π΄Π΅ΠΌ ΠΏΠ΅ΡΡΠΎΠ½Π°Π»ΠΈΠ·ΠΈΡΠ°Π½ ΡΠ΅ΡΡ, ΠΊΠΎΠΉΡΠΎ ΠΏΡΠΎΠ²Π΅ΡΡΠ²Π° Π΄Π°Π»ΠΈ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ΡΠΎ Π΅ Π²Π·Π΅ΡΠΎ ΠΎΡ Π½Π°Π΄Π΅ΠΆΠ΄Π½ΠΎ Ρ ΡΠ°Π½ΠΈΠ»ΠΈΡΠ΅. ΠΠ΅ΡΡΠΎΠ½Π°Π»ΠΈΠ·ΠΈΡΠ°Π½ΠΈΡΠ΅ ΡΠ΅ΡΡΠΎΠ²Π΅ ΡΠ° ΠΏΠΎΡΠΎΡΠ΅Π½ΠΈ Π²ΡΠ² ΡΠΎΡΠΌΠ°Ρ YAML, Π° ΡΠ°ΠΌΠΈΡΡ ΡΠ΅ΡΡ Π΅ ΠΎΠΏΠΈΡΠ°Π½ Ρ ΠΏΠΎΠΌΠΎΡΡΠ° Π½Π° JSON ΡΡ Π΅ΠΌΠ°.
Π‘Π»Π΅Π΄Π½ΠΈΡΡ YAML ΠΊΠΎΠ΄ΠΎΠ² ΡΡΠ°Π³ΠΌΠ΅Π½Ρ ΠΎΠΏΠΈΡΠ²Π° Π½ΠΎΠ² ΡΠ΅ΡΡ, ΠΈΠ·Π²ΠΈΠΊΠ°Π½ checkImageRepo
:
checkImageRepo:
successMessage: Image registry is valid
failureMessage: Image registry is not valid
category: Images
target: Container
schema:
'$schema': http://json-schema.org/draft-07/schema
type: object
properties:
image:
type: string
pattern: ^my-company.com/.+$
ΠΠ΅ΠΊΠ° Π³ΠΎ ΡΠ°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΠΏΠΎ-ΠΎΡΠ±Π»ΠΈΠ·ΠΎ:
successMessage
β ΡΠΎΠ·ΠΈ ΡΠ΅Π΄ ΡΠ΅ Π±ΡΠ΄Π΅ ΠΎΡΠΏΠ΅ΡΠ°ΡΠ°Π½, Π°ΠΊΠΎ ΡΠ΅ΡΡΡΡ Π·Π°Π²ΡΡΡΠΈ ΡΡΠΏΠ΅ΡΠ½ΠΎ;failureMessage
β ΡΠΎΠ²Π° ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ ΡΠ΅ ΡΠ΅ ΠΏΠΎΠΊΠ°ΠΆΠ΅ Π² ΡΠ»ΡΡΠ°ΠΉ Π½Π° ΠΏΠΎΠ²ΡΠ΅Π΄Π°;category
β ΠΏΠΎΡΠΎΡΠ²Π° Π΅Π΄Π½Π° ΠΎΡ ΠΊΠ°ΡΠ΅Π³ΠΎΡΠΈΠΈΡΠ΅:Images
,Health Checks
,Security
,Networking
ΠΈResources
;target
--- ΠΎΠΏΡΠ΅Π΄Π΅Π»Ρ ΠΊΠ°ΠΊΡΠ² ΡΠΈΠΏ ΠΎΠ±Π΅ΠΊΡ (spec
) ΡΠ΅ ΠΏΡΠΈΠ»Π°Π³Π° ΡΠ΅ΡΡ. ΠΡΠ·ΠΌΠΎΠΆΠ½ΠΈ ΡΡΠΎΠΉΠ½ΠΎΡΡΠΈ:Container
,Pod
ΠΈΠ»ΠΈController
;- Π‘Π°ΠΌΠΈΡΡ ΡΠ΅ΡΡ Π΅ ΠΏΠΎΡΠΎΡΠ΅Π½ Π² ΠΎΠ±Π΅ΠΊΡΠ°
schema
ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ JSON ΡΡ Π΅ΠΌΠ°. ΠΠ»ΡΡΠΎΠ²Π°ΡΠ° Π΄ΡΠΌΠ° Π² ΡΠΎΠ·ΠΈ ΡΠ΅ΡΡ Π΅pattern
ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° ΡΠ΅ Π·Π° ΡΡΠ°Π²Π½ΡΠ²Π°Π½Π΅ Π½Π° ΠΈΠ·ΡΠΎΡΠ½ΠΈΠΊΠ° Π½Π° ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ Ρ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΈΡ.
ΠΠ° Π΄Π° ΠΈΠ·ΠΏΡΠ»Π½ΠΈΡΠ΅ Π³ΠΎΡΠ½ΠΈΡ ΡΠ΅ΡΡ, ΡΡΡΠ±Π²Π° Π΄Π° ΡΡΠ·Π΄Π°Π΄Π΅ΡΠ΅ ΡΠ»Π΅Π΄Π½Π°ΡΠ° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ Π½Π° Polaris:
checks:
checkImageRepo: danger
customChecks:
checkImageRepo:
successMessage: Image registry is valid
failureMessage: Image registry is not valid
category: Images
target: Container
schema:
'$schema': http://json-schema.org/draft-07/schema
type: object
properties:
image:
type: string
pattern: ^my-company.com/.+$
(polaris-conf.yaml
)
ΠΠ΅ΠΊΠ° Π°Π½Π°Π»ΠΈΠ·ΠΈΡΠ°ΠΌΠ΅ ΡΠ°ΠΉΠ»Π°:
- Π ΠΎΠ±Π»Π°ΡΡΡΠ°
checks
ΠΏΡΠ΅Π΄ΠΏΠΈΡΠ²Π°Ρ ΡΠ΅ ΡΠ΅ΡΡΠΎΠ²Π΅ ΠΈ ΡΡΡ Π½ΠΎΡΠΎ Π½ΠΈΠ²ΠΎ Π½Π° ΠΊΡΠΈΡΠΈΡΠ½ΠΎΡΡ. Π’ΡΠΉ ΠΊΠ°ΡΠΎ Π΅ ΠΆΠ΅Π»Π°ΡΠ΅Π»Π½ΠΎ Π΄Π° ΠΏΠΎΠ»ΡΡΠΈΡΠ΅ ΠΏΡΠ΅Π΄ΡΠΏΡΠ΅ΠΆΠ΄Π΅Π½ΠΈΠ΅, ΠΊΠΎΠ³Π°ΡΠΎ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ Π΅ Π²Π·Π΅ΡΠΎ ΠΎΡ Π½Π΅Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ ΠΈΠ·ΡΠΎΡΠ½ΠΈΠΊ, Π½ΠΈΠ΅ Π·Π°Π΄Π°Π²Π°ΠΌΠ΅ Π½ΠΈΠ²ΠΎΡΠΎ ΡΡΠΊdanger
. - Π‘Π°ΠΌΠΈΡΡ ΡΠ΅ΡΡ
checkImageRepo
ΡΠ»Π΅Π΄ ΡΠΎΠ²Π° ΡΠ΅Π³ΠΈΡΡΡΠΈΡΠ°Π½ Π² ΠΎΠ±Π΅ΠΊΡΠ°customChecks
.
ΠΠ°ΠΏΠ°Π·Π΅ΡΠ΅ ΡΠ°ΠΉΠ»Π° ΠΊΠ°ΡΠΎ custom_check.yaml
. Π‘Π΅Π³Π° ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π±ΡΠ³Π°ΡΠ΅ polaris audit
Ρ YAML ΠΌΠ°Π½ΠΈΡΠ΅ΡΡ, ΠΊΠΎΠΉΡΠΎ ΠΈΠ·ΠΈΡΠΊΠ²Π° ΠΏΡΠΎΠ²Π΅ΡΠΊΠ°.
ΠΠ΅ΠΊΠ° ΡΠ΅ΡΡΠ²Π°ΠΌΠ΅ Π½Π°ΡΠΈΡ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡ base-valid.yaml
:
$ polaris audit --config custom_check.yaml --audit-path base-valid.yaml
ΠΡΠ±ΠΎΡ polaris audit
ΠΈΠ·ΠΏΡΠ»Π½ΠΈ ΡΠ°ΠΌΠΎ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΡΠΊΠΈΡ ΡΠ΅ΡΡ, ΠΏΠΎΡΠΎΡΠ΅Π½ ΠΏΠΎ-Π³ΠΎΡΠ΅, ΠΈ Π½Π΅ ΡΡΠΏΡ.
ΠΠΊΠΎ ΠΊΠΎΡΠΈΠ³ΠΈΡΠ°ΡΠ΅ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ΡΠΎ ΠΊΡΠΌ my-company.com/http-echo:1.0
, Polaris ΡΠ΅ Π·Π°Π²ΡΡΡΠΈ ΡΡΠΏΠ΅ΡΠ½ΠΎ. ΠΠ°Π½ΠΈΡΠ΅ΡΡΡΡ Ρ ΠΏΡΠΎΠΌΠ΅Π½ΠΈΡΠ΅ Π²Π΅ΡΠ΅ Π΅ Π² ΡΠΈΠ»Π° image-valid-mycompany.yaml
.
Π‘Π΅Π³Π° Π²ΡΠ·Π½ΠΈΠΊΠ²Π° Π²ΡΠΏΡΠΎΡΡΡ: ΠΊΠ°ΠΊ Π΄Π° ΡΡΠ°ΡΡΠΈΡΠ°ΡΠ΅ Π²Π³ΡΠ°Π΄Π΅Π½ΠΈ ΡΠ΅ΡΡΠΎΠ²Π΅ Π·Π°Π΅Π΄Π½ΠΎ Ρ ΠΏΠ΅ΡΡΠΎΠ½Π°Π»ΠΈΠ·ΠΈΡΠ°Π½ΠΈ? ΠΠ΅ΡΠ½ΠΎ! ΠΡΠΎΡΡΠΎ ΡΡΡΠ±Π²Π° Π΄Π° Π΄ΠΎΠ±Π°Π²ΠΈΡΠ΅ Π²Π³ΡΠ°Π΄Π΅Π½ΠΈΡΠ΅ ΡΠ΅ΡΡΠΎΠ²ΠΈ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΈ ΠΊΡΠΌ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΎΠ½Π½ΠΈΡ ΡΠ°ΠΉΠ». Π ΡΠ΅Π·ΡΠ»ΡΠ°Ρ Π½Π° ΡΠΎΠ²Π° ΡΠ΅ ΠΏΡΠΈΠ΅ΠΌΠ΅ ΡΠ»Π΅Π΄Π½Π°ΡΠ° ΡΠΎΡΠΌΠ°:
checks:
cpuRequestsMissing: warning
cpuLimitsMissing: warning
# Other inbuilt checks..
# ..
# custom checks
checkImageRepo: danger # !!!
customChecks:
checkImageRepo: # !!!
successMessage: Image registry is valid
failureMessage: Image registry is not valid
category: Images
target: Container
schema:
'$schema': http://json-schema.org/draft-07/schema
type: object
properties:
image:
type: string
pattern: ^my-company.com/.+$
(config_with_custom_check.yaml
)
ΠΠ°Π»ΠΈΡΠ΅Π½ Π΅ ΠΏΡΠΈΠΌΠ΅Ρ Π·Π° ΠΏΡΠ»Π΅Π½ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΎΠ½Π΅Π½ ΡΠ°ΠΉΠ»
ΠΡΠΎΠ²Π΅ΡΠ΅ΡΠ΅ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠ° base-valid.yaml
ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ Π²Π³ΡΠ°Π΄Π΅Π½ΠΈ ΠΈ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΡΠΊΠΈ ΡΠ΅ΡΡΠΎΠ²Π΅, ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΡΠ΅ ΠΊΠΎΠΌΠ°Π½Π΄Π°ΡΠ°:
$ polaris audit --config config_with_custom_check.yaml --audit-path base-valid.yaml
Polaris Π΄ΠΎΠΏΡΠ»Π²Π° Π²Π³ΡΠ°Π΄Π΅Π½ΠΈΡΠ΅ ΡΠ΅ΡΡΠΎΠ²Π΅ Ρ ΠΏΠ΅ΡΡΠΎΠ½Π°Π»ΠΈΠ·ΠΈΡΠ°Π½ΠΈ, ΠΊΠ°ΡΠΎ ΠΏΠΎ ΡΠΎΠ·ΠΈ Π½Π°ΡΠΈΠ½ ΡΡΡΠ΅ΡΠ°Π²Π° Π½Π°ΠΉ-Π΄ΠΎΠ±ΡΠΎΡΠΎ ΠΎΡ Π΄Π²Π°ΡΠ° ΡΠ²ΡΡΠ°.
ΠΡ Π΄ΡΡΠ³Π° ΡΡΡΠ°Π½Π°, Π½Π΅Π²ΡΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡΠ° Π΄Π° ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ ΠΏΠΎ-ΠΌΠΎΡΠ½ΠΈ Π΅Π·ΠΈΡΠΈ ΠΊΠ°ΡΠΎ Rego ΠΈΠ»ΠΈ JavaScript ΠΌΠΎΠΆΠ΅ Π΄Π° Π±ΡΠ΄Π΅ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ°Π²Π°Ρ ΡΠ°ΠΊΡΠΎΡ, ΠΏΡΠ΅Π΄ΠΎΡΠ²ΡΠ°ΡΡΠ²Π°Ρ ΡΡΠ·Π΄Π°Π²Π°Π½Π΅ΡΠΎ Π½Π° ΠΏΠΎ-ΡΠ»ΠΎΠΆΠ½ΠΈ ΡΠ΅ΡΡΠΎΠ²Π΅.
ΠΠΎΠ²Π΅ΡΠ΅ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ Π·Π° Polaris ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π½Π°ΠΌΠ΅ΡΠΈΡΠ΅ Π½Π°
ΠΠ±ΠΎΠ±ΡΠ΅Π½ΠΈΠ΅
ΠΡΠΏΡΠ΅ΠΊΠΈ ΡΠ΅ ΠΈΠΌΠ° ΠΌΠ½ΠΎΠ³ΠΎ Π½Π°Π»ΠΈΡΠ½ΠΈ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠΈ Π·Π° ΠΏΡΠΎΠ²Π΅ΡΠΊΠ° ΠΈ ΠΎΡΠ΅Π½ΠΊΠ° Π½Π° Kubernetes YAML ΡΠ°ΠΉΠ»ΠΎΠ²Π΅, Π²Π°ΠΆΠ½ΠΎ Π΅ Π΄Π° ΠΈΠΌΠ°ΡΠ΅ ΡΡΠ½ΠΎ ΡΠ°Π·Π±ΠΈΡΠ°Π½Π΅ Π·Π° ΡΠΎΠ²Π° ΠΊΠ°ΠΊ ΡΠ΅ Π±ΡΠ΄Π°Ρ ΠΏΡΠΎΠ΅ΠΊΡΠΈΡΠ°Π½ΠΈ ΠΈ ΠΈΠ·ΠΏΡΠ»Π½Π΅Π½ΠΈ ΡΠ΅ΡΡΠΎΠ²Π΅ΡΠ΅.
ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Π°ΠΊΠΎ Π²Π·Π΅ΠΌΠ΅ΡΠ΅ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠΈΡΠ΅ Π½Π° Kubernetes, ΠΏΡΠ΅ΠΌΠΈΠ½Π°Π²Π°ΡΠΈ ΠΏΡΠ΅Π· ΡΡΡΠ±ΠΎΠΏΡΠΎΠ²ΠΎΠ΄, kubeval ΠΌΠΎΠΆΠ΅ Π΄Π° Π±ΡΠ΄Π΅ ΠΏΡΡΠ²Π°ΡΠ° ΡΡΡΠΏΠΊΠ° Π² ΡΠ°ΠΊΡΠ² ΡΡΡΠ±ΠΎΠΏΡΠΎΠ²ΠΎΠ΄. Π©Π΅ ΡΠ»Π΅Π΄ΠΈ Π΄Π°Π»ΠΈ Π΄Π΅ΡΠΈΠ½ΠΈΡΠΈΠΈΡΠ΅ Π½Π° ΠΎΠ±Π΅ΠΊΡΠΈ ΡΡΠΎΡΠ²Π΅ΡΡΡΠ²Π°Ρ Π½Π° ΡΡ Π΅ΠΌΠ°ΡΠ° Π½Π° Kubernetes API.
Π‘Π»Π΅Π΄ ΠΊΠ°ΡΠΎ ΡΠ°ΠΊΡΠ² ΠΏΡΠ΅Π³Π»Π΅Π΄ ΠΏΡΠΈΠΊΠ»ΡΡΠΈ, ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ ΠΏΡΠ΅ΠΌΠΈΠ½Π΅ ΠΊΡΠΌ ΠΏΠΎ-ΡΠ»ΠΎΠΆΠ½ΠΈ ΡΠ΅ΡΡΠΎΠ²Π΅, ΠΊΠ°ΡΠΎ ΡΡΠΎΡΠ²Π΅ΡΡΡΠ²ΠΈΠ΅ ΡΡΡ ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΠΈΡΠ΅ Π½Π°ΠΉ-Π΄ΠΎΠ±ΡΠΈ ΠΏΡΠ°ΠΊΡΠΈΠΊΠΈ ΠΈ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΠΈ ΠΏΠΎΠ»ΠΈΡΠΈΠΊΠΈ. Π’ΠΎΠ²Π° Π΅ ΠΌΡΡΡΠΎΡΠΎ, ΠΊΡΠ΄Π΅ΡΠΎ kube-score ΠΈ Polaris Π±ΠΈΡ Π° Π±ΠΈΠ»ΠΈ ΠΏΠΎΠ»Π΅Π·Π½ΠΈ.
ΠΠ° ΡΠ΅Π·ΠΈ, ΠΊΠΎΠΈΡΠΎ ΠΈΠΌΠ°Ρ ΡΠ»ΠΎΠΆΠ½ΠΈ ΠΈΠ·ΠΈΡΠΊΠ²Π°Π½ΠΈΡ ΠΈ ΡΡΡΠ±Π²Π° Π΄Π° ΠΏΠ΅ΡΡΠΎΠ½Π°Π»ΠΈΠ·ΠΈΡΠ°Ρ ΡΠ΅ΡΡΠΎΠ²Π΅ΡΠ΅ Π² Π΄Π΅ΡΠ°ΠΉΠ»ΠΈ, ΠΌΠ΅Π΄, config-lint ΠΈ conftest Π±ΠΈΡ Π° Π±ΠΈΠ»ΠΈ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ΡΡΠΈ.
Conftest ΠΈ config-lint ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ YAML Π·Π° Π΄Π΅ΡΠΈΠ½ΠΈΡΠ°Π½Π΅ Π½Π° ΠΏΠ΅ΡΡΠΎΠ½Π°Π»ΠΈΠ·ΠΈΡΠ°Π½ΠΈ ΡΠ΅ΡΡΠΎΠ²Π΅, Π° copper Π²ΠΈ Π΄Π°Π²Π° Π΄ΠΎΡΡΡΠΏ Π΄ΠΎ ΠΏΡΠ»Π΅Π½ Π΅Π·ΠΈΠΊ Π·Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ°Π½Π΅, ΠΊΠΎΠ΅ΡΠΎ Π³ΠΎ ΠΏΡΠ°Π²ΠΈ Π΄ΠΎΡΡΠ° ΠΏΡΠΈΠ²Π»Π΅ΠΊΠ°ΡΠ΅Π»Π΅Π½ ΠΈΠ·Π±ΠΎΡ.
ΠΡ Π΄ΡΡΠ³Π° ΡΡΡΠ°Π½Π°, ΡΡΡΡΠ²Π° Π»ΠΈ ΡΠΈ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΡΠ΅ Π΅Π΄ΠΈΠ½ ΠΎΡ ΡΠ΅Π·ΠΈ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠΈ ΠΈ ΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»Π½ΠΎ Π΄Π° ΡΡΠ·Π΄Π°Π²Π°ΡΠ΅ Π²ΡΠΈΡΠΊΠΈ ΡΠ΅ΡΡΠΎΠ²Π΅ ΡΡΡΠ½ΠΎ ΠΈΠ»ΠΈ Π΄Π° ΠΏΡΠ΅Π΄ΠΏΠΎΡΠ΅ΡΠ΅ΡΠ΅ Polaris ΠΈ Π΄Π° Π΄ΠΎΠ±Π°Π²ΠΈΡΠ΅ ΡΠ°ΠΌΠΎ ΡΠΎΠ²Π°, ΠΊΠΎΠ΅ΡΠΎ Π΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΠΊΡΠΌ Π½Π΅Π³ΠΎ? ΠΡΠΌΠ° ΡΡΠ΅Π½ ΠΎΡΠ³ΠΎΠ²ΠΎΡ Π½Π° ΡΠΎΠ·ΠΈ Π²ΡΠΏΡΠΎΡ.
Π’Π°Π±Π»ΠΈΡΠ°ΡΠ° ΠΏΠΎ-Π΄ΠΎΠ»Ρ ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Ρ ΠΊΡΠ°ΡΠΊΠΎ ΠΎΠΏΠΈΡΠ°Π½ΠΈΠ΅ Π½Π° Π²ΡΠ΅ΠΊΠΈ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½Ρ:
ΠΠ½ΡΡΡΡΠΌΠ΅Π½Ρ
ΡΡΠ΄Π±Π°
ΠΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΡ
ΠΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΡΠΊΠΈ ΡΠ΅ΡΡΠΎΠ²Π΅
ΠΊΡΠ±Π΅Π²Π°Π»
ΠΠ°Π»ΠΈΠ΄ΠΈΡΠ° YAML ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠΈΡΠ΅ ΡΠΏΡΡΠΌΠΎ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½Π° Π²Π΅ΡΡΠΈΡ Π½Π° API ΡΡ
Π΅ΠΌΠ°ΡΠ°
ΠΠ΅ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ°Π±ΠΎΡΠΈ Ρ CRD
ΠΠ΅
kube-ΡΠ΅Π·ΡΠ»ΡΠ°Ρ
ΠΠ½Π°Π»ΠΈΠ·ΠΈΡΠ° YAML ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠΈΡΠ΅ ΡΠΏΡΡΠΌΠΎ Π½Π°ΠΉ-Π΄ΠΎΠ±ΡΠΈΡΠ΅ ΠΏΡΠ°ΠΊΡΠΈΠΊΠΈ
ΠΠ΅ ΠΌΠΎΠ³Π° Π΄Π° ΠΈΠ·Π±Π΅ΡΠ° Π²Π°ΡΠ°ΡΠ° Π²Π΅ΡΡΠΈΡ Π½Π° Kubernetes API Π·Π° ΠΏΡΠΎΠ²Π΅ΡΠΊΠ° Π½Π° ΡΠ΅ΡΡΡΡΠΈΡΠ΅
ΠΠ΅
ΠΌΠ΅Π΄
ΠΠ±ΡΠ° ΡΠ°ΠΌΠΊΠ° Π·Π° ΡΡΠ·Π΄Π°Π²Π°Π½Π΅ Π½Π° ΠΏΠ΅ΡΡΠΎΠ½Π°Π»ΠΈΠ·ΠΈΡΠ°Π½ΠΈ JavaScript ΡΠ΅ΡΡΠΎΠ²Π΅ Π·Π° YAML ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠΈ
ΠΡΠΌΠ° Π²Π³ΡΠ°Π΄Π΅Π½ΠΈ ΡΠ΅ΡΡΠΎΠ²Π΅. ΠΠΎΡΠ° Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡ
ΠΠ°
config-lint
ΠΠ±ΡΠ° ΡΠ°ΠΌΠΊΠ° Π·Π° ΡΡΠ·Π΄Π°Π²Π°Π½Π΅ Π½Π° ΡΠ΅ΡΡΠΎΠ²Π΅ Π½Π° ΡΠΏΠ΅ΡΠΈΡΠΈΡΠ΅Π½ Π·Π° Π΄ΠΎΠΌΠ΅ΠΉΠ½ Π΅Π·ΠΈΠΊ, Π²Π³ΡΠ°Π΄Π΅Π½ Π² YAML. ΠΠΎΠ΄Π΄ΡΡΠΆΠ° ΡΠ°Π·Π»ΠΈΡΠ½ΠΈ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΎΠ½Π½ΠΈ ΡΠΎΡΠΌΠ°ΡΠΈ (Π½Π°ΠΏΡ. Terraform)
ΠΡΠΌΠ° Π³ΠΎΡΠΎΠ²ΠΈ ΡΠ΅ΡΡΠΎΠ²Π΅. ΠΠ³ΡΠ°Π΄Π΅Π½ΠΈΡΠ΅ ΡΠ²ΡΡΠ΄Π΅Π½ΠΈΡ ΠΈ ΡΡΠ½ΠΊΡΠΈΠΈ ΠΌΠΎΠΆΠ΅ Π΄Π° Π½Π΅ ΡΠ° Π΄ΠΎΡΡΠ°ΡΡΡΠ½ΠΈ
ΠΠ°
ΠΊΠΎΠ½ΠΊΡΡΡ
Π Π°ΠΌΠΊΠ° Π·Π° ΡΡΠ·Π΄Π°Π²Π°Π½Π΅ Π½Π° Π²Π°ΡΠΈ ΡΠΎΠ±ΡΡΠ²Π΅Π½ΠΈ ΡΠ΅ΡΡΠΎΠ²Π΅ Ρ ΠΏΠΎΠΌΠΎΡΡΠ° Π½Π° Rego (ΡΠΏΠ΅ΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΠ°Π½ Π΅Π·ΠΈΠΊ Π·Π° Π·Π°ΡΠ²ΠΊΠΈ). ΠΠΎΠ·Π²ΠΎΠ»ΡΠ²Π° ΡΠΏΠΎΠ΄Π΅Π»ΡΠ½Π΅ Π½Π° ΠΏΠΎΠ»ΠΈΡΠΈΠΊΠΈ ΡΡΠ΅Π· OCI ΠΏΠ°ΠΊΠ΅ΡΠΈ
ΠΡΠΌΠ° Π²Π³ΡΠ°Π΄Π΅Π½ΠΈ ΡΠ΅ΡΡΠΎΠ²Π΅. Π’ΡΡΠ±Π²Π° Π΄Π° Π½Π°ΡΡΠ° Rego. Docker Hub Π½Π΅ ΡΠ΅ ΠΏΠΎΠ΄Π΄ΡΡΠΆΠ° ΠΏΡΠΈ ΠΏΡΠ±Π»ΠΈΠΊΡΠ²Π°Π½Π΅ Π½Π° ΠΏΡΠ°Π²ΠΈΠ»Π°
ΠΠ°
ΠΠΎΠ»ΡΡΠ½Π°ΡΠ° Π·Π²Π΅Π·Π΄Π°
ΠΡΠ΅Π³Π»Π΅ΠΆΠ΄Π° YAML ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠΈΡΠ΅ ΡΠΏΡΡΠΌΠΎ ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΠΈΡΠ΅ Π½Π°ΠΉ-Π΄ΠΎΠ±ΡΠΈ ΠΏΡΠ°ΠΊΡΠΈΠΊΠΈ. ΠΠΎΠ·Π²ΠΎΠ»ΡΠ²Π° Π²ΠΈ Π΄Π° ΡΡΠ·Π΄Π°Π²Π°ΡΠ΅ ΡΠ²ΠΎΠΈ ΡΠΎΠ±ΡΡΠ²Π΅Π½ΠΈ ΡΠ΅ΡΡΠΎΠ²Π΅ Ρ ΠΏΠΎΠΌΠΎΡΡΠ° Π½Π° JSON Schema
ΠΡΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠΈΡΠ΅ Π·Π° ΡΠ΅ΡΡΠ²Π°Π½Π΅ Π½Π° Π±Π°Π·Π°ΡΠ° Π½Π° JSON ΡΡ
Π΅ΠΌΠ° ΠΌΠΎΠΆΠ΅ Π΄Π° Π½Π΅ ΡΠ° Π΄ΠΎΡΡΠ°ΡΡΡΠ½ΠΈ
ΠΠ°
Π’ΡΠΉ ΠΊΠ°ΡΠΎ ΡΠ΅Π·ΠΈ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠΈ Π½Π΅ ΡΠ°Π·ΡΠΈΡΠ°Ρ Π½Π° Π΄ΠΎΡΡΡΠΏ Π΄ΠΎ ΠΊΠ»ΡΡΡΠ΅ΡΠ° Kubernetes, ΡΠ΅ ΡΠ° Π»Π΅ΡΠ½ΠΈ Π·Π° ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ°Π½Π΅. Π’Π΅ Π²ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ²Π°Ρ Π΄Π° ΡΠΈΠ»ΡΡΠΈΡΠ°ΡΠ΅ ΠΈΠ·Ρ ΠΎΠ΄Π½ΠΈΡΠ΅ ΡΠ°ΠΉΠ»ΠΎΠ²Π΅ ΠΈ Π΄Π° ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²ΡΡΠ΅ Π±ΡΡΠ·Π° ΠΎΠ±ΡΠ°ΡΠ½Π° Π²ΡΡΠ·ΠΊΠ° Π½Π° Π°Π²ΡΠΎΡΠΈΡΠ΅ Π½Π° Π·Π°ΡΠ²ΠΊΠΈ Π·Π° ΠΈΠ·ΡΠ΅Π³Π»ΡΠ½Π΅ Π² ΠΏΡΠΎΠ΅ΠΊΡΠΈ.
PS ΠΎΡ ΠΏΡΠ΅Π²ΠΎΠ΄Π°ΡΠ°
ΠΡΠΎΡΠ΅ΡΠ΅ΡΠ΅ ΡΡΡΠΎ Π² Π½Π°ΡΠΈΡ Π±Π»ΠΎΠ³:
- Β«
Polaris Π΅ Π²ΡΠ²Π΅Π΄Π΅Π½, Π·Π° Π΄Π° ΠΏΠΎΠ΄Π΄ΡΡΠΆΠ° ΠΊΠ»ΡΡΡΠ΅ΡΠΈΡΠ΅ Π½Π° Kubernetes Π·Π΄ΡΠ°Π²ΠΈ Β»; - Β«
Vim Ρ YAML ΠΏΠΎΠ΄Π΄ΡΡΠΆΠΊΠ° Π·Π° Kubernetes Β»; - Β«
7-ΡΠ΅ Π½Π°ΠΉ-Π΄ΠΎΠ±ΡΠΈ ΠΏΡΠ°ΠΊΡΠΈΠΊΠΈ Π·Π° ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠΈ Π½Π° Google ".
ΠΠ·ΡΠΎΡΠ½ΠΈΠΊ: www.habr.com