ΠΡΠΈΠΌ. ΠΏΠ΅ΡΠ΅Π².: Π‘ ΡΠΎΡΡΠΎΠΌ ΡΠΈΡΠ»Π° YAML-ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΉ Π΄Π»Ρ K8s-ΠΎΠΊΡΡΠΆΠ΅Π½ΠΈΠΉ Π²ΡΡ Π±ΠΎΠ»Π΅Π΅ Π°ΠΊΡΡΠ°Π»ΡΠ½ΠΎΠΉ ΡΡΠ°Π½ΠΎΠ²ΠΈΡΡΡ ΠΏΠΎΡΡΠ΅Π±Π½ΠΎΡΡΡ Π² ΠΈΡ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΠ·ΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠΉ ΠΏΡΠΎΠ²Π΅ΡΠΊΠ΅. ΠΠ²ΡΠΎΡ ΡΡΠΎΠ³ΠΎ ΠΎΠ±Π·ΠΎΡΠ° Π½Π΅ ΠΏΡΠΎΡΡΠΎ ΠΎΡΠΎΠ±ΡΠ°Π» ΡΡΡΠ΅ΡΡΠ²ΡΡΡΠΈΠ΅ ΡΠ΅ΡΠ΅Π½ΠΈΡ Π΄Π»Ρ ΡΡΠΎΠΉ Π·Π°Π΄Π°ΡΠΈ, Π½ΠΎ ΠΈ Π½Π° ΠΏΡΠΈΠΌΠ΅ΡΠ΅ Deployment’Π° ΠΏΠΎΡΠΌΠΎΡΡΠ΅Π», ΠΊΠ°ΠΊ ΠΎΠ½ΠΈ ΡΠ°Π±ΠΎΡΠ°ΡΡ. ΠΠΎΠ»ΡΡΠΈΠ»ΠΎΡΡ Π²Π΅ΡΡΠΌΠ° ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΠ²Π½ΠΎ Π΄Π»Ρ ΡΠ΅Ρ , ΠΊΠΎΠΌΡ ΡΡΠ° ΡΠ΅ΠΌΠ° ΠΈΠ½ΡΠ΅ΡΠ΅ΡΠ½Π°.
TL;DR: Π ΡΡΠ°ΡΡΠ΅ ΡΡΠ°Π²Π½ΠΈΠ²Π°ΡΡΡΡ ΡΠ΅ΡΡΡ ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΡ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠΎΠ² ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ ΠΈ ΠΎΡΠ΅Π½ΠΊΠΈ YAML-ΡΠ°ΠΉΠ»ΠΎΠ² Kubernetes Π½Π° ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΠΈΠ΅ Π»ΡΡΡΠΈΠΌ ΠΏΡΠ°ΠΊΡΠΈΠΊΠ°ΠΌ ΠΈ ΡΡΠ΅Π±ΠΎΠ²Π°Π½ΠΈΡΠΌ.
Π Π°Π±ΠΎΡΠΈΠ΅ Π½Π°Π³ΡΡΠ·ΠΊΠΈ Kubernetes, ΠΊΠ°ΠΊ ΠΏΡΠ°Π²ΠΈΠ»ΠΎ, ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΡΡΡΡ Π² ΡΠΎΡΠΌΠ΅ YAML-Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠΎΠ². ΠΠ΄Π½Π° ΠΈΠ· ΠΏΡΠΎΠ±Π»Π΅ΠΌ Ρ YAML’ΠΎΠΌ β ΡΠ»ΠΎΠΆΠ½ΠΎΡΡΡ Π·Π°Π΄Π°Π½ΠΈΡ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΠΉ ΠΈΠ»ΠΈ Π²Π·Π°ΠΈΠΌΠΎΠΎΡΠ½ΠΎΡΠ΅Π½ΠΈΠΉ ΠΌΠ΅ΠΆΠ΄Ρ ΡΠ°ΠΉΠ»Π°ΠΌΠΈ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠΎΠ².
Π§ΡΠΎ, Π΅ΡΠ»ΠΈ Π½Π°ΠΌ Π½Π°Π΄ΠΎ ΡΠ΄ΠΎΡΡΠΎΠ²Π΅ΡΠΈΡΡΡΡ, ΡΡΠΎ Π²ΡΠ΅ ΠΎΠ±ΡΠ°Π·Ρ, ΡΠ°Π·Π²Π΅ΡΡΡΠ²Π°Π΅ΠΌΡΠ΅ Π² ΠΊΠ»Π°ΡΡΠ΅ΡΠ΅, Π±Π΅ΡΡΡΡΡ ΠΈΠ· Π΄ΠΎΠ²Π΅ΡΠ΅Π½Π½ΠΎΠ³ΠΎ ΡΠ΅Π΅ΡΡΡΠ°?
ΠΠ°ΠΊ ΠΏΡΠ΅Π΄ΠΎΡΠ²ΡΠ°ΡΠΈΡΡ ΠΎΡΠΏΡΠ°Π²ΠΊΡ Π² ΠΊΠ»Π°ΡΡΠ΅Ρ Deployment’ΠΎΠ², Π΄Π»Ρ ΠΊΠΎΡΠΎΡΡΡ Π½Π΅ Π·Π°Π΄Π°Π½Ρ PodDisruptionBudgets?
ΠΠ½ΡΠ΅Π³ΡΠ°ΡΠΈΡ ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠ³ΠΎ ΡΠ΅ΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Π²ΡΡΠ²Π»ΡΡΡ ΠΎΡΠΈΠ±ΠΊΠΈ ΠΈ Π½Π°ΡΡΡΠ΅Π½ΠΈΡ ΠΏΠΎΠ»ΠΈΡΠΈΠΊ Π΅ΡΠ΅ Π½Π° ΡΡΠ°Π΄ΠΈΠΈ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠΈ. Π’Π΅ΠΌ ΡΠ°ΠΌΡΠΌ ΠΏΠΎΠ²ΡΡΠ°ΡΡΡΡ Π³Π°ΡΠ°Π½ΡΠΈΠΈ ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΠΎΡΡΠΈ ΠΈ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΠΈ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΠΉ ΡΠ΅ΡΡΡΡΠΎΠ² ΠΈ ΠΏΠΎΠ²ΡΡΠ°Π΅ΡΡΡ Π²Π΅ΡΠΎΡΡΠ½ΠΎΡΡΡ ΡΠΎΠ³ΠΎ, ΡΡΠΎ production-Π½Π°Π³ΡΡΠ·ΠΊΠΈ Π±ΡΠ΄ΡΡ ΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΡ Π»ΡΡΡΠΈΠΌ ΠΏΡΠ°ΠΊΡΠΈΠΊΠ°ΠΌ.
ΠΠΊΠΎΡΠΈΡΡΠ΅ΠΌΡ ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠΉ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ YAML-ΡΠ°ΠΉΠ»ΠΎΠ² Kubernetes ΠΌΠΎΠΆΠ½ΠΎ ΡΠ°Π·Π΄Π΅Π»ΠΈΡΡ Π½Π° ΡΠ»Π΅Π΄ΡΡΡΠΈΠ΅ ΠΊΠ°ΡΠ΅Π³ΠΎΡΠΈΠΈ:
- API-Π²Π°Π»ΠΈΠ΄Π°ΡΠΎΡΡ. ΠΠ½ΡΡΡΡΠΌΠ΅Π½ΡΡ Π² ΡΡΠΎΠΉ ΠΊΠ°ΡΠ΅Π³ΠΎΡΠΈΠΈ ΠΏΡΠΎΠ²Π΅ΡΡΡΡ YAML-ΠΌΠ°Π½ΠΈΡΠ΅ΡΡ Π½Π° ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΠΈΠ΅ ΡΡΠ΅Π±ΠΎΠ²Π°Π½ΠΈΡΠΌ API-ΡΠ΅ΡΠ²Π΅ΡΠ° Kubernetes.
- ΠΠΎΡΠΎΠ²ΡΠ΅ ΡΠ΅ΡΡΠ΅ΡΡ. ΠΠ½ΡΡΡΡΠΌΠ΅Π½ΡΡ ΠΈΠ· Π΄Π°Π½Π½ΠΎΠΉ ΠΊΠ°ΡΠ΅Π³ΠΎΡΠΈΠΈ ΠΈΠ΄ΡΡ Ρ Π³ΠΎΡΠΎΠ²ΡΠΌΠΈ ΡΠ΅ΡΡΠ°ΠΌΠΈ Π½Π° Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΡ, ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΠΈΠ΅ Π»ΡΡΡΠΈΠΌ ΠΏΡΠ°ΠΊΡΠΈΠΊΠ°ΠΌ ΠΈ Ρ.ΠΏ.
- ΠΠ°ΡΡΠΎΠΌΠ½ΡΠ΅ Π²Π°Π»ΠΈΠ΄Π°ΡΠΎΡΡ. ΠΡΠ΅Π΄ΡΡΠ°Π²ΠΈΡΠ΅Π»ΠΈ ΡΡΠΎΠΉ ΠΊΠ°ΡΠ΅Π³ΠΎΡΠΈΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡΡ ΡΠΎΠ·Π΄Π°Π²Π°ΡΡ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΡΠΊΠΈΠ΅ ΡΠ΅ΡΡΡ Π½Π° ΡΠ°Π·Π»ΠΈΡΠ½ΡΡ ΡΠ·ΡΠΊΠ°Ρ , Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, Π½Π° Rego ΠΈ Javascript.
Π ΡΡΠΎΠΉ ΡΡΠ°ΡΡΠ΅ ΠΌΡ ΠΎΠΏΠΈΡΠ΅ΠΌ ΠΈ ΡΡΠ°Π²Π½ΠΈΠΌ ΡΠ΅ΡΡΡ ΡΠ°Π·Π»ΠΈΡΠ½ΡΡ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠΎΠ²:
- kubeval;
- kube-score;
- config-lint;
- copper;
- conftest;
- Polaris.
Π§ΡΠΎ ΠΆ, Π΄Π°Π²Π°ΠΉΡΠ΅ ΠΏΡΠΈΡΡΡΠΏΠΈΠΌ!
ΠΡΠΎΠ²Π΅ΡΠΊΠ° Deployment’ΠΎΠ²
ΠΡΠ΅ΠΆΠ΄Π΅ ΡΠ΅ΠΌ ΠΏΡΠΈΡΡΡΠΏΠΈΡΡ ΠΊ ΡΡΠ°Π²Π½Π΅Π½ΠΈΡ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠΎΠ², Π΄Π°Π²Π°ΠΉΡΠ΅ ΡΠΎΠ·Π΄Π°Π΄ΠΈΠΌ Π½Π΅ΠΊΠΎΡΠΎΡΡΡ ΠΎΡΠ½ΠΎΠ²Ρ, Π½Π° ΠΊΠΎΡΠΎΡΠΎΠΉ Π±ΡΠ΄Π΅ΠΌ ΠΈΡ ΡΠ΅ΡΡΠΈΡΠΎΠ²Π°ΡΡ.
ΠΡΠΈΠ²Π΅Π΄Π΅Π½Π½ΡΠΉ Π½ΠΈΠΆΠ΅ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡ ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ ΡΡΠ΄ ΠΎΡΠΈΠ±ΠΎΠΊ ΠΈ Π½Π΅ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΠΈΠΉ Π»ΡΡΡΠΈΠΌ ΠΏΡΠ°ΠΊΡΠΈΠΊΠ°ΠΌ: ΡΠΊΠΎΠ»ΡΠΊΠΎ ΠΈΠ· Π½ΠΈΡ Π²Ρ ΡΠΌΠΎΠΆΠ΅ΡΠ΅ Π½Π°ΠΉΡΠΈ?
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. Kubeval
Π ΠΎΡΠ½ΠΎΠ²Π΅
ΠΠ° ΠΌΠΎΠΌΠ΅Π½Ρ Π½Π°ΠΏΠΈΡΠ°Π½ΠΈΡ ΠΎΡΠΈΠ³ΠΈΠ½Π°Π»ΡΠ½ΠΎΠΉ ΡΡΠ°ΡΡΠΈ Π±ΡΠ»Π° Π΄ΠΎΡΡΡΠΏΠ½Π° Π²Π΅ΡΡΠΈΡ 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 Π·Π°Π²Π΅ΡΡΠΈΡ ΡΠ°Π±ΠΎΡΡ Ρ exit-ΠΊΠΎΠ΄ΠΎΠΌ 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
Π Π΅ΡΡΡΡ Π½Π΅ ΠΏΡΠΎΡ ΠΎΠ΄ΠΈΡ ΠΏΡΠΎΠ²Π΅ΡΠΊΡ.
Deployment’Ρ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΠΈΠ΅ Π²Π΅ΡΡΠΈΡ API apps/v1
, Π΄ΠΎΠ»ΠΆΠ½Ρ Π²ΠΊΠ»ΡΡΠ°ΡΡ ΡΠ΅Π»Π΅ΠΊΡΠΎΡ, ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠΉ ΠΌΠ΅ΡΠΊΠ΅ pod’Π°. ΠΠ°Π½ΠΈΡΠ΅ΡΡ Π²ΡΡΠ΅ Π½Π΅ Π²ΠΊΠ»ΡΡΠ°Π΅Ρ ΡΠ΅Π»Π΅ΠΊΡΠΎΡ, ΠΏΠΎΡΡΠΎΠΌΡ 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 ΠΏΡΠΎΠ²Π΅ΡΡΠ΅Ρ ΡΠ΅ΡΡΡΡΡ Π½Π° ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΠΈΠ΅ ΡΠ°ΠΌΠΎΠΉ ΠΏΠΎΡΠ»Π΅Π΄Π½Π΅ΠΉ ΡΡ
Π΅ΠΌΠ΅ Kubernetes API. ΠΠ΄Π½Π°ΠΊΠΎ Π² Π±ΠΎΠ»ΡΡΠΈΠ½ΡΡΠ²Π΅ ΡΠ»ΡΡΠ°Π΅Π² Π²Π°ΠΌ ΠΌΠΎΠΆΠ΅Ρ ΠΏΠΎΡΡΠ΅Π±ΠΎΠ²Π°ΡΡΡΡ ΠΏΡΠΎΠ²Π΅ΡΡΠΈ ΠΏΡΠΎΠ²Π΅ΡΠΊΡ Π½Π° ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΠΈΠ΅ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΠΎΠΌΡ ΡΠ΅Π»ΠΈΠ·Ρ 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 β Π² Π½Π°ΡΡΠΎΡΡΠ΅Π΅ Π²ΡΠ΅ΠΌΡ ΠΎΠ½ Π½Π΅ ΡΠΌΠ΅Π΅Ρ ΠΏΡΠΎΠ²Π΅ΡΡΡΡ Π½Π° ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΠΈΠ΅ Custom Resource Definitions (CRDs). ΠΠ΄Π½Π°ΠΊΠΎ ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΡΡΡΠΎΠΈΡΡ kubeval
Kubeval β ΠΎΡΠ»ΠΈΡΠ½ΡΠΉ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½Ρ Π΄Π»Ρ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ ΠΈ ΠΎΡΠ΅Π½ΠΊΠΈ ΡΠ΅ΡΡΡΡΠΎΠ²; ΠΏΡΠ°Π²Π΄Π°, ΡΠ»Π΅Π΄ΡΠ΅Ρ ΠΏΠΎΠ΄ΡΠ΅ΡΠΊΠ½ΡΡΡ, ΡΡΠΎ ΡΡΠΏΠ΅ΡΠ½ΠΎΠ΅ ΠΏΡΠΎΡ ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ ΡΠ΅ΡΡΠ° Π½Π΅ Π³Π°ΡΠ°Π½ΡΠΈΡΡΠ΅Ρ, ΡΡΠΎ ΡΠ΅ΡΡΡΡ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΠ΅Ρ Π»ΡΡΡΠΈΠΌ ΠΏΡΠ°ΠΊΡΠΈΠΊΠ°ΠΌ.
ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ ΡΠ΅Π³Π° latest
Π² ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠ΅ Π½Π΅ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΠ΅Ρ Π»ΡΡΡΠΈΠΌ ΠΏΡΠ°ΠΊΡΠΈΠΊΠ°ΠΌ. ΠΠ΄Π½Π°ΠΊΠΎ kubeval Π½Π΅ ΡΡΠΈΡΠ°Π΅Ρ ΡΡΠΎ ΠΎΡΠΈΠ±ΠΊΠΎΠΉ ΠΈ Π½Π΅ ΡΠΎΠΎΠ±ΡΠ°Π΅Ρ ΠΎ Π½Π΅ΠΉ. Π’ΠΎ Π΅ΡΡΡ ΠΏΡΠΎΠ²Π΅ΡΠΊΠ° ΡΠ°ΠΊΠΎΠ³ΠΎ YAML Π·Π°Π²Π΅ΡΡΠΈΡΡΡ Π±Π΅Π· ΠΏΡΠ΅Π΄ΡΠΏΡΠ΅ΠΆΠ΄Π΅Π½ΠΈΠΉ.
ΠΠΎ ΡΡΠΎ, Π΅ΡΠ»ΠΈ Π½ΡΠΆΠ½ΠΎ ΠΎΡΠ΅Π½ΠΈΡΡ YAML ΠΈ Π²ΡΡΠ²ΠΈΡΡ Π½Π°ΡΡΡΠ΅Π½ΠΈΡ Π²ΡΠΎΠ΄Π΅ ΡΠ΅Π³Π° latest
? ΠΠ°ΠΊ ΠΏΡΠΎΠ²Π΅ΡΠΈΡΡ YAML-ΡΠ°ΠΉΠ» Π½Π° ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΠΈΠ΅ Π»ΡΡΡΠΈΠΌ ΠΏΡΠ°ΠΊΡΠΈΠΊΠ°ΠΌ?
2. Kube-score
- ΠΠ°ΠΏΡΡΠΊ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠ° Π½Π΅ ΠΏΠΎΠ΄ root’ΠΎΠΌ.
- ΠΠ°Π»ΠΈΡΠΈΠ΅ ΠΏΡΠΎΠ²Π΅ΡΠΎΠΊ Π·Π΄ΠΎΡΠΎΠ²ΡΡ pod’ΠΎΠ².
- ΠΠ°Π΄Π°Π½ΠΈΠ΅ request’ΠΎΠ² ΠΈ limit’ΠΎΠ² ΡΠ΅ΡΡΡΡΠΎΠ².
ΠΠΎ ΠΈΡΠΎΠ³Π°ΠΌ ΡΠ΅ΡΡΠ° Π²ΡΠ΄Π°Π΅ΡΡΡ ΡΡΠΈ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ°: OK, WARNING ΠΈ CRITICAL.
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 ΡΠΊΠ°Π·ΡΠ²Π°Π΅Ρ Π½Π° ΡΠ»Π΅Π΄ΡΡΡΠΈΠ΅ Π½Π΅Π΄ΠΎΡΡΠ°ΡΠΊΠΈ:
- ΠΠ΅ Π½Π°ΡΡΡΠΎΠ΅Π½Ρ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ Π³ΠΎΡΠΎΠ²Π½ΠΎΡΡΠΈ.
- ΠΡΡΡΡΡΡΠ²ΡΡΡ request’Ρ ΠΈ limit’Ρ Π½Π° ΡΠ΅ΡΡΡΡΡ CPU ΠΈ ΠΏΠ°ΠΌΡΡΡ.
- ΠΠ΅ Π·Π°Π΄Π°Π½Ρ Pod disruption budgets.
- ΠΡΡΡΡΡΡΠ²ΡΡΡ ΠΏΡΠ°Π²ΠΈΠ»Π° ΡΠ°Π·Π΄Π΅Π»ΡΠ½ΠΎΠ³ΠΎ ΡΡΡΠ΅ΡΡΠ²ΠΎΠ²Π°Π½ΠΈΡ (anti-affinity) Π΄Π»Ρ ΠΌΠ°ΠΊΡΠΈΠΌΠΈΠ·Π°ΡΠΈΠΈ Π΄ΠΎΡΡΡΠΏΠ½ΠΎΡΡΠΈ.
- ΠΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ ΠΏΠΎΠ΄ root’ΠΎΠΌ.
ΠΡΡ ΡΡΠΎ β ΡΠ΅Π·ΠΎΠ½Π½ΡΠ΅ Π·Π°ΠΌΠ΅ΡΠ°Π½ΠΈΡ ΠΎ Π½Π΅Π΄ΠΎΡΡΠ°ΡΠΊΠ°Ρ , ΠΊΠΎΡΠΎΡΡΠ΅ ΡΠ»Π΅Π΄ΡΠ΅Ρ ΡΡΡΡΠ°Π½ΠΈΡΡ, ΡΡΠΎΠ±Ρ Deployment ΡΡΠ°Π» Π±ΠΎΠ»Π΅Π΅ ΡΡΡΠ΅ΠΊΡΠΈΠ²Π½ΡΠΌ ΠΈ Π½Π°Π΄Π΅ΠΆΠ½ΡΠΌ.
ΠΠΎΠΌΠ°Π½Π΄Π° kube-score
Π²ΡΠ²ΠΎΠ΄ΠΈΡ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ Π² ΡΠ΄ΠΎΠ±ΠΎΡΠΈΡΠ°Π΅ΠΌΠΎΠΉ ΡΠΎΡΠΌΠ΅ Ρ Π²ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ΠΌ Π²ΡΠ΅Ρ
Π½Π°ΡΡΡΠ΅Π½ΠΈΠΉ ΡΠΈΠΏΠ° WARNING ΠΈ CRITICAL, ΡΡΠΎ ΠΎΡΠ΅Π½Ρ ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ Π²ΠΎ Π²ΡΠ΅ΠΌΡ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠΈ.
ΠΠ΅Π»Π°ΡΡΠΈΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΡΠΎΡ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½Ρ Π² ΡΠ°ΠΌΠΊΠ°Ρ
ΠΏΠ°ΠΉΠΏΠ»Π°ΠΉΠ½Π° 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 Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ Π½Π΅Π½ΡΠ»Π΅Π²ΠΎΠΉ ΠΊΠΎΠ΄ Π²ΡΡ ΠΎΠ΄Π° ΠΏΡΠΈ Π½Π°Π»ΠΈΡΠΈΠΈ ΡΠ΅ΡΡΠ°, Π·Π°Π²Π΅ΡΡΠΈΠ²ΡΠ΅Π³ΠΎΡΡ ΠΎΡΠΈΠ±ΠΊΠΎΠΉ CRITICAL. Π’Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ½ΠΎ Π²ΠΊΠ»ΡΡΠΈΡΡ ΠΏΠΎΠ΄ΠΎΠ±Π½ΡΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΡ ΠΈ Π΄Π»Ρ WARNING.
ΠΡΠΎΠΌΠ΅ ΡΠΎΠ³ΠΎ, ΠΈΠΌΠ΅Π΅ΡΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ ΡΠ΅ΡΡΡΡΠΎΠ² Π½Π° ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΠΈΠ΅ ΡΠ°Π·Π»ΠΈΡΠ½ΡΠΌ Π²Π΅ΡΡΠΈΡΠΌ API (ΠΊΠ°ΠΊ ΠΈ Π² kubeval). ΠΠ΄Π½Π°ΠΊΠΎ ΡΡΠ° ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ Π·Π°’hardcode’Π½Π° Π² ΡΠ°ΠΌΠΎΠΌ kube-score: Π²ΡΠ±ΡΠ°ΡΡ Π΄ΡΡΠ³ΡΡ Π²Π΅ΡΡΠΈΡ Kubernetes Π½Π΅Π»ΡΠ·Ρ. ΠΠΎΠ΄ΠΎΠ±Π½ΠΎΠ΅ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ ΡΡΠ°ΡΡ Π±ΠΎΠ»ΡΡΠΎΠΉ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠΎΠΉ, Π΅ΡΠ»ΠΈ Π²Ρ Π½Π°ΠΌΠ΅ΡΠ΅Π½Ρ ΠΎΠ±Π½ΠΎΠ²ΠΈΡΡ ΠΊΠ»Π°ΡΡΠ΅Ρ ΠΈΠ»ΠΈ Ρ Π²Π°Ρ Π΅ΡΡΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΠΊΠ»Π°ΡΡΠ΅ΡΠΎΠ² Ρ ΡΠ°Π·Π»ΠΈΡΠ½ΡΠΌΠΈ Π²Π΅ΡΡΠΈΡΠΌΠΈ K8s.
ΠΠ±ΡΠ°ΡΠΈΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, ΡΡΠΎ
ΡΠΆΠ΅ Π΅ΡΡΡ issue Ρ ΠΏΡΠ΅Π΄Π»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΠΌ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°ΡΡ ΡΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ.
ΠΠΎΠ΄ΡΠΎΠ±Π½Π΅Π΅ ΠΎ 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
β ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ FAILURE, WARNING ΠΈ NON_COMPLIANT;message
β ΠΏΡΠΈ Π½Π°ΡΡΡΠ΅Π½ΠΈΠΈ ΠΏΡΠ°Π²ΠΈΠ»Π° ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ°Π΅ΡΡΡ ΡΠΎΠ΄Π΅ΡΠΆΠΈΠΌΠΎΠ΅ ΡΡΠΎΠΉ ΡΡΡΠΎΠΊΠΈ;resource
β ΡΠΈΠΏ ΡΠ΅ΡΡΡΡΠ°, ΠΊ ΠΊΠΎΡΠΎΡΠΎΠΌΡ ΠΏΡΠΈΠΌΠ΅Π½ΡΠ΅ΡΡΡ ΡΡΠΎ ΠΏΡΠ°Π²ΠΈΠ»ΠΎ;assertions
β ΡΠΏΠΈΡΠΎΠΊ ΡΡΠ»ΠΎΠ²ΠΈΠΉ, ΠΊΠΎΡΠΎΡΡΠ΅ Π±ΡΠ΄ΡΡ ΠΎΡΠ΅Π½ΠΈΠ²Π°ΡΡΡΡ Π² ΠΎΡΠ½ΠΎΡΠ΅Π½ΠΈΠΈ Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΡΠ΅ΡΡΡΡΠ°.
Π ΠΏΡΠ°Π²ΠΈΠ»Π΅ Π²ΡΡΠ΅ assertion
ΠΏΠΎΠ΄ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ΠΌ every
key: spec.templates.spec.containers
) ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡ Π΄ΠΎΠ²Π΅ΡΠ΅Π½Π½ΡΠ΅ ΠΎΠ±ΡΠ°Π·Ρ (Ρ.Π΅., Π½Π°ΡΠΈΠ½Π°ΡΡΠΈΠ΅ΡΡ Ρ my-company.com/
).
ΠΠΎΠ»Π½ΡΠΉ ruleset Π²ΡΠ³Π»ΡΠ΄ΠΈΡ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ:
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 β ΠΏΠ΅ΡΡΠΏΠ΅ΠΊΡΠΈΠ²Π½ΡΠΉ ΡΡΠ΅ΠΉΠΌΠ²ΠΎΡΠΊ, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡΡΠΈΠΉ ΡΠΎΠ·Π΄Π°Π²Π°ΡΡ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΠ΅ ΡΠ΅ΡΡΡ Π΄Π»Ρ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ YAML-ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠΎΠ² Kubernetes Ρ ΠΏΠΎΠΌΠΎΡΡΡ YAML DSL.
ΠΠΎ ΡΡΠΎ Π΄Π΅Π»Π°ΡΡ, Π΅ΡΠ»ΠΈ ΡΡΠ΅Π±ΡΠ΅ΡΡΡ Π±ΠΎΠ»Π΅Π΅ ΡΠ»ΠΎΠΆΠ½Π°Ρ Π»ΠΎΠ³ΠΈΠΊΠ° ΠΈ ΡΠ΅ΡΡΡ? Π Π°Π·Π²Π΅ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠΈ YAML Π½Π΅ ΡΠ»ΠΈΡΠΊΠΎΠΌ ΠΌΠ°Π»Ρ Π΄Π»Ρ ΡΡΠΎΠ³ΠΎ? Π§ΡΠΎ, Π΅ΡΠ»ΠΈ ΠΌΠΎΠΆΠ½ΠΎ Π±ΡΠ»ΠΎ Π±Ρ ΡΠΎΠ·Π΄Π°Π²Π°ΡΡ ΡΠ΅ΡΡΡ Π½Π° ΠΏΠΎΠ»Π½ΠΎΡΠ΅Π½Π½ΠΎΠΌ ΡΠ·ΡΠΊΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΡ?
4. Copper
ΠΠ΄Π½Π°ΠΊΠΎ ΠΎΡ ΠΏΠΎΡΠ»Π΅Π΄Π½Π΅Π³ΠΎ ΠΎΠ½ ΠΎΡΠ»ΠΈΡΠ°Π΅ΡΡΡ ΡΠ΅ΠΌ, ΡΡΠΎ Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ YAML Π΄Π»Ρ ΠΎΠΏΠΈΡΠ°Π½ΠΈΡ ΡΠ΅ΡΡΠΎΠ². ΠΠΌΠ΅ΡΡΠΎ ΡΡΠΎΠ³ΠΎ ΡΠ΅ΡΡΡ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°Π²Π°ΡΡ Π½Π° JavaScript. Copper ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΠ΅Ρ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΡ Ρ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΠΌΠΈ Π±Π°Π·ΠΎΠ²ΡΠΌΠΈ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠ°ΠΌΠΈ, ΠΏΠΎΠΌΠΎΠ³Π°ΡΡΠΈΠΌΠΈ ΡΡΠΈΡΡΠ²Π°ΡΡ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ ΠΎΠ± ΠΎΠ±ΡΠ΅ΠΊΡΠ°Ρ Kubernetes ΠΈ ΡΠΎΠΎΠ±ΡΠ°ΡΡ ΠΎΠ± ΠΎΡΠΈΠ±ΠΊΠ°Ρ .
ΠΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎΡΡΡ ΡΠ°Π³ΠΎΠ² Π΄Π»Ρ ΡΡΡΠ°Π½ΠΎΠ²ΠΊΠΈ Copper ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΉΡΠΈ Π²
2.0.1 β ΡΠ°ΠΌΡΠΉ ΡΠ²Π΅ΠΆΠΈΠΉ ΡΠ΅Π»ΠΈΠ· ΡΡΠΎΠΉ ΡΡΠΈΠ»ΠΈΡΡ Π½Π° ΠΌΠΎΠΌΠ΅Π½Ρ Π½Π°ΠΏΠΈΡΠ°Π½ΠΈΡ ΠΎΡΠΈΠ³ΠΈΠ½Π°Π»ΡΠ½ΠΎΠΉ ΡΡΠ°ΡΡΠΈ.
ΠΠ°ΠΊ ΠΈ config-lint, Copper Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ Π²ΡΡΡΠΎΠ΅Π½Π½ΡΡ
ΡΠ΅ΡΡΠΎΠ². ΠΠ°Π²Π°ΠΉΡΠ΅ Π½Π°ΠΏΠΈΡΠ΅ΠΌ ΠΎΠ΄ΠΈΠ½. ΠΡΡΡΡ ΠΎΠ½ ΠΏΡΠΎΠ²Π΅ΡΡΠ΅Ρ, ΡΡΠΎ deployment’Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠ½ΡΠ΅ ΠΎΠ±ΡΠ°Π·Ρ ΠΈΡΠΊΠ»ΡΡΠΈΡΠ΅Π»ΡΠ½ΠΎ ΠΈΠ· Π΄ΠΎΠ²Π΅ΡΠ΅Π½Π½ΡΡ
ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠ΅Π² Π²ΡΠΎΠ΄Π΅ 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
ΠΠΎΠ½ΡΡΠ½ΠΎ, ΡΡΠΎ Ρ ΠΏΠΎΠΌΠΎΡΡΡ copper ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡΠΎΠ²ΠΎΠ΄ΠΈΡΡ Π±ΠΎΠ»Π΅Π΅ ΡΠ»ΠΎΠΆΠ½ΡΠ΅ ΡΠ΅ΡΡΡ β Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, ΠΏΡΠΎΠ²Π΅ΡΡΡΡ Π΄ΠΎΠΌΠ΅Π½Π½ΡΠ΅ ΠΈΠΌΠ΅Π½Π° Π² ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠ°Ρ Ingress ΠΈΠ»ΠΈ ΠΎΡΠ²Π΅ΡΠ³Π°ΡΡ pod’Ρ, ΡΠ°Π±ΠΎΡΠ°ΡΡΠΈΠ΅ Π² ΠΏΡΠΈΠ²ΠΈΠ»Π΅Π³ΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠΌ ΡΠ΅ΠΆΠΈΠΌΠ΅.
Π Copper Π²ΡΡΡΠΎΠ΅Π½Ρ ΡΠ°Π·Π»ΠΈΡΠ½ΡΠ΅ ΡΠ»ΡΠΆΠ΅Π±Π½ΡΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ:
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
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 ΠΏΠ°ΡΡΠΈΡ ΡΠΊΠ°Π·Π°Π½Π½ΡΠ΅ ΡΠ°ΠΉΠ»Ρ ΠΏΠΎΠ»ΠΈΡΠΈΠΊ.
ΠΠΎΠ»ΠΈΡΠΈΠΊΠΈ 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 ΠΏΠΎΠΊΠ° Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅ΡΡΡ. ΠΠΎΡΡΠΎΠΌΡ ΡΡΠΈΡΠ°ΠΉΡΠ΅, ΡΡΠΎ Π²Π°ΠΌ ΠΏΠΎΠ²Π΅Π·Π»ΠΎ, Π΅ΡΠ»ΠΈ Π²Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΠ΅
Π€ΠΎΡΠΌΠ°Ρ Π°ΡΡΠ΅ΡΠ°ΠΊΡΠΎΠ² β ΡΠ°ΠΊΠΎΠΉ ΠΆΠ΅, ΠΊΠ°ΠΊ Ρ
ΠΠΎΠ»ΡΡΠ΅ ΠΎ ΡΠΎΠ²ΠΌΠ΅ΡΡΠ½ΠΎΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ ΠΏΠΎΠ»ΠΈΡΠΈΠΊ ΠΈ Π΄ΡΡΠ³ΠΈΡ
ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎΡΡΡΡ
conftest ΠΌΠΎΠΆΠ½ΠΎ ΡΠ·Π½Π°ΡΡ Π½Π°
6. Polaris
ΠΠΎΡΠ»Π΅Π΄Π½ΠΈΠΉ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½Ρ, ΠΎ ΠΊΠΎΡΠΎΡΠΎΠΌ ΠΏΠΎΠΉΠ΄Π΅Ρ ΡΠ΅ΡΡ Π² ΡΡΠΎΠΉ ΡΡΠ°ΡΡΠ΅, β ΡΡΠΎ
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 Π²ΡΡΠ²Π»ΡΠ΅Ρ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ Π² ΡΠ΅Ρ ΠΎΠ±Π»Π°ΡΡΡΡ , Π² ΠΊΠΎΡΠΎΡΡΡ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡ Π½Π΅ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΠ΅Ρ Π»ΡΡΡΠΈΠΌ ΠΏΡΠ°ΠΊΡΠΈΠΊΠ°ΠΌ:
- ΠΡΡΡΡΡΡΠ²ΡΡΡ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ Π·Π΄ΠΎΡΠΎΠ²ΡΡ pod’ΠΎΠ².
- ΠΠ΅ ΡΠΊΠ°Π·Π°Π½Ρ ΡΠ΅Π³ΠΈ Π΄Π»Ρ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠ½ΡΡ ΠΎΠ±ΡΠ°Π·ΠΎΠ².
- ΠΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ ΠΏΠΎΠ΄ root’ΠΎΠΌ.
- ΠΠ΅ ΡΠΊΠ°Π·Π°Π½Ρ request’Ρ ΠΈ limit’Ρ Π΄Π»Ρ ΠΏΠ°ΠΌΡΡΠΈ ΠΈ CPU.
ΠΠ°ΠΆΠ΄ΠΎΠΌΡ ΡΠ΅ΡΡΡ Π² Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ ΠΎΡ Π΅Π³ΠΎ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠΎΠ² ΠΏΡΠΈΡΠ²Π°ΠΈΠ²Π°Π΅ΡΡΡ ΡΡΠ΅ΠΏΠ΅Π½Ρ ΠΊΡΠΈΡΠΈΡΠ½ΠΎΡΡΠΈ: warning ΠΈΠ»ΠΈ danger. Π§ΡΠΎΠ±Ρ ΡΠ·Π½Π°ΡΡ Π±ΠΎΠ»ΡΡΠ΅ ΠΎΠ± ΠΈΠΌΠ΅ΡΡΠΈΡ
ΡΡ Π²ΡΡΡΠΎΠ΅Π½Π½ΡΡ
ΡΠ΅ΡΡΠ°Ρ
, ΠΎΠ±ΡΠ°ΡΠΈΡΠ΅ΡΡ ΠΊ
ΠΡΠ»ΠΈ ΠΏΠΎΠ΄ΡΠΎΠ±Π½ΠΎΡΡΠΈ Π½Π΅ Π½ΡΠΆΠ½Ρ, ΠΌΠΎΠΆΠ½ΠΎ ΡΠΊΠ°Π·Π°ΡΡ ΡΠ»Π°Π³ --format score
. Π ΡΡΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ Polaris Π²ΡΠ²Π΅Π΄Π΅Ρ ΡΠΈΡΠ»ΠΎ Π² Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½Π΅ ΠΎΡ 1 Π΄ΠΎ 100 β score (Ρ.Π΅. ΠΎΡΠ΅Π½ΠΊΡ):
$ polaris audit --audit-path test-data/base-valid.yaml --format score
68
Π§Π΅ΠΌ ΠΎΡΠ΅Π½ΠΊΠ° Π±Π»ΠΈΠΆΠ΅ ΠΊ 100, ΡΠ΅ΠΌ Π²ΡΡΠ΅ ΡΡΠ΅ΠΏΠ΅Π½Ρ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΠΈΡ. ΠΡΠ»ΠΈ ΠΏΡΠΎΠ²Π΅ΡΠΈΡΡ exit-ΠΊΠΎΠ΄ ΠΊΠΎΠΌΠ°Π½Π΄Ρ polaris audit
, ΠΎΠΊΠ°ΠΆΠ΅ΡΡΡ, ΡΡΠΎ ΠΎΠ½ ΡΠ°Π²Π΅Π½ 0.
ΠΠ°ΡΡΠ°Π²ΠΈΡΡ polaris audit
Π·Π°Π²Π΅ΡΡΠ°ΡΡ ΡΠ°Π±ΠΎΡΡ Ρ Π½Π΅Π½ΡΠ»Π΅Π²ΡΠΌ ΠΊΠΎΠ΄ΠΎΠΌ ΠΌΠΎΠΆΠ½ΠΎ Ρ ΠΏΠΎΠΌΠΎΡΡΡ Π΄Π²ΡΡ
ΡΠ»Π°Π³ΠΎΠ²:
- Π€Π»Π°Π³
--set-exit-code-below-score
ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠ° ΠΏΠΎΡΠΎΠ³ΠΎΠ²ΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Π² Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½Π΅ 1-100. Π ΡΡΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ ΠΊΠΎΠΌΠ°Π½Π΄Π° Π·Π°Π²Π΅ΡΡΠΈΡΡΡ Ρ exit-ΠΊΠΎΠ΄ΠΎΠΌ 4, Π΅ΡΠ»ΠΈ ΠΎΡΠ΅Π½ΠΊΠ° ΠΎΠΊΠ°ΠΆΠ΅ΡΡΡ Π½ΠΈΠΆΠ΅ ΠΏΠΎΡΠΎΠ³ΠΎΠ²ΠΎΠΉ. ΠΡΠΎ ΠΎΡΠ΅Π½Ρ ΡΠ΄ΠΎΠ±Π½ΠΎ, ΠΊΠΎΠ³Π΄Π° Ρ Π²Π°Ρ Π΅ΡΡΡ Π½Π΅ΠΊΠΎΠ΅ ΠΏΠΎΡΠΎΠ³ΠΎΠ²ΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ (ΡΠΊΠ°ΠΆΠ΅ΠΌ, 75), ΠΈ Π²Π°ΠΌ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΠΎΠ»ΡΡΠΈΡΡ alert, Π΅ΡΠ»ΠΈ ΠΎΡΠ΅Π½ΠΊΠ° ΠΎΠΏΡΡΡΠΈΡΡΡ Π½ΠΈΠΆΠ΅. - Π€Π»Π°Π³
--set-exit-code-on-danger
ΠΏΡΠΈΠ²Π΅Π΄Π΅Ρ ΠΊ ΡΠΎΠΌΡ, ΡΡΠΎ ΠΊΠΎΠΌΠ°Π½Π΄Π° Π·Π°Π²Π΅ΡΡΠΈΡΡΡ Ρ ΠΊΠΎΠ΄ΠΎΠΌ 3, Π΅ΡΠ»ΠΈ ΠΎΠ΄ΠΈΠ½ ΠΈΠ· danger-ΡΠ΅ΡΡΠΎΠ² Π·Π°Π²Π΅ΡΡΠΈΡΡΡ Π½Π΅ΡΠ΄Π°ΡΠ½ΠΎ.
Π’Π΅ΠΏΠ΅ΡΡ Π΄Π°Π²Π°ΠΉΡΠ΅ ΠΏΠΎΠΏΡΠΎΠ±ΡΠ΅ΠΌ ΡΠΎΠ·Π΄Π°ΡΡ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΡΠΊΠΈΠΉ ΡΠ΅ΡΡ, ΠΏΡΠΎΠ²Π΅ΡΡΡΡΠΈΠΉ, Π±Π΅ΡΠ΅ΡΡΡ Π»ΠΈ ΠΎΠ±ΡΠ°Π· ΠΈΠ· Π΄ΠΎΠ²Π΅ΡΠ΅Π½Π½ΠΎΠ³ΠΎ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΡ. ΠΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΡΠΊΠΈΠ΅ ΡΠ΅ΡΡΡ Π·Π°Π΄Π°ΡΡΡΡ Π² ΡΠΎΡΠΌΠ°ΡΠ΅ YAML, Π° ΡΠ°ΠΌ ΡΠ΅ΡΡ ΠΎΠΏΠΈΡΡΠ²Π°Π΅ΡΡΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ JSON Schema.
Π‘Π»Π΅Π΄ΡΡΡΠΈΠΉ ΡΡΠ°Π³ΠΌΠ΅Π½Ρ 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 schema. Π Π΄Π°Π½Π½ΠΎΠΌ ΡΠ΅ΡΡΠ΅ ΠΊΠ»ΡΡΠ΅Π²ΠΎΠ΅ ΡΠ»ΠΎΠ²ΠΎ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 Π΄ΠΎΡΡΡΠΏΠ½Π° Π½Π°
Π Π΅Π·ΡΠΌΠ΅
Π₯ΠΎΡΡ ΡΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²ΠΎ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠΎΠ² Π΄Π»Ρ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ ΠΈ ΠΎΡΠ΅Π½ΠΊΠΈ YAML-ΡΠ°ΠΉΠ»ΠΎΠ² Kubernetes, Π²Π°ΠΆΠ½ΠΎ ΠΈΠΌΠ΅ΡΡ ΡΠ΅ΡΠΊΠΎΠ΅ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ ΠΎ ΡΠΎΠΌ, ΠΊΠ°ΠΊ ΡΠ΅ΡΡΡ Π±ΡΠ΄ΡΡ ΠΏΡΠΎΠ΅ΠΊΡΠΈΡΠΎΠ²Π°ΡΡΡΡ ΠΈ Π²ΡΠΏΠΎΠ»Π½ΡΡΡΡΡ.
ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Π΅ΡΠ»ΠΈ Π²Π·ΡΡΡ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΡ Kubernetes, ΠΏΡΠΎΡ ΠΎΠ΄ΡΡΠΈΠ΅ ΡΠ΅ΡΠ΅Π· ΠΏΠ°ΠΉΠΏΠ»Π°ΠΉΠ½, kubeval ΠΌΠΎΠ³ Π±Ρ ΡΡΠ°ΡΡ ΠΏΠ΅ΡΠ²ΡΠΌ ΡΠ°Π³ΠΎΠΌ Π² ΡΠ°ΠΊΠΎΠΌ ΠΏΠ°ΠΉΠΏΠ»Π°ΠΉΠ½Π΅. ΠΠ½ Π±Ρ ΡΠ»Π΅Π΄ΠΈΠ» Π·Π° ΡΠ΅ΠΌ, ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡ Π»ΠΈ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² ΡΡ Π΅ΠΌΠ΅ API Kubernetes.
ΠΠΎΡΠ»Π΅ Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΡ ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎΠΉ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ ΠΌΠΎΠΆΠ½ΠΎ Π±ΡΠ»ΠΎ Π±Ρ ΠΏΠ΅ΡΠ΅ΠΉΡΠΈ ΠΊ Π±ΠΎΠ»Π΅Π΅ ΠΈΠ·ΠΎΡΡΠ΅Π½Π½ΡΠΌ ΡΠ΅ΡΡΠ°ΠΌ, ΡΠ°ΠΊΠΈΠΌ ΠΊΠ°ΠΊ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΠΈΠ΅ ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΡΠΌ Π»ΡΡΡΠΈΠΌ ΠΏΡΠ°ΠΊΡΠΈΠΊΠ°ΠΌ ΠΈ ΠΎΡΠΎΠ±ΡΠΌ ΠΏΠΎΠ»ΠΈΡΠΈΠΊΠ°ΠΌ. Π Π·Π΄Π΅ΡΡ Π±Ρ ΠΏΡΠΈΠ³ΠΎΠ΄ΠΈΠ»ΠΈΡΡ kube-score ΠΈ Polaris.
Π’Π΅ΠΌ, Ρ ΠΊΠΎΠ³ΠΎ ΡΠ»ΠΎΠΆΠ½ΡΠ΅ ΡΡΠ΅Π±ΠΎΠ²Π°Π½ΠΈΡ ΠΈ Π΅ΡΡΡ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΡ Π΄Π΅ΡΠ°Π»ΡΠ½ΠΎ Π½Π°ΡΡΡΠ°ΠΈΠ²Π°ΡΡ ΡΠ΅ΡΡΡ, ΠΏΠΎΠ΄ΠΎΡΠ»ΠΈ Π±Ρ copper, config-lint ΠΈ conftest.
Conftest ΠΈ config-lint ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡ YAML Π΄Π»Ρ Π·Π°Π΄Π°Π½ΠΈΡ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΡΠΊΠΈΡ ΡΠ΅ΡΡΠΎΠ², Π° copper Π΄Π°Π΅Ρ Π΄ΠΎΡΡΡΠΏ ΠΊ ΠΏΠΎΠ»Π½ΠΎΡΠ΅Π½Π½ΠΎΠΌΡ ΡΠ·ΡΠΊΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΡ, ΡΡΠΎ Π΄Π΅Π»Π°Π΅Ρ Π΅Π³ΠΎ Π΄ΠΎΠ²ΠΎΠ»ΡΠ½ΠΎ ΠΏΡΠΈΠ²Π»Π΅ΠΊΠ°ΡΠ΅Π»ΡΠ½ΡΠΌ Π²ΡΠ±ΠΎΡΠΎΠΌ.
Π‘ Π΄ΡΡΠ³ΠΎΠΉ ΡΡΠΎΡΠΎΠ½Ρ, ΡΡΠΎΠΈΡ Π»ΠΈ Π²ΠΎΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ ΠΎΠ΄Π½ΠΈΠΌ ΠΈΠ· ΡΡΠΈΡ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠΎΠ² ΠΈ, ΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎ, ΡΠΎΠ·Π΄Π°Π²Π°ΡΡ Π²ΡΠ΅ ΡΠ΅ΡΡΡ Π²ΡΡΡΠ½ΡΡ, ΠΈΠ»ΠΈ ΠΏΡΠ΅Π΄ΠΏΠΎΡΠ΅ΡΡΡ Polaris, ΠΈ Π΄ΠΎΠΏΠΈΡΠ°ΡΡ Π² Π½Π΅Π³ΠΎ ΡΠΎΠ»ΡΠΊΠΎ ΡΠΎ, ΡΡΠΎ Π½ΡΠΆΠ½ΠΎ? ΠΠ΄Π½ΠΎΠ·Π½Π°ΡΠ½ΠΎΠ³ΠΎ ΠΎΡΠ²Π΅ΡΠ° Π½Π° ΡΡΠΎΡ Π²ΠΎΠΏΡΠΎΡ Π½Π΅Ρ.
Π’Π°Π±Π»ΠΈΡΠ° Π½ΠΈΠΆΠ΅ ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ ΠΊΡΠ°ΡΠΊΠΎΠ΅ ΠΎΠΏΠΈΡΠ°Π½ΠΈΠ΅ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠ°:
ΠΠ½ΡΡΡΡΠΌΠ΅Π½Ρ
ΠΡΠ΅Π΄Π½Π°Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅
ΠΠ΅Π΄ΠΎΡΡΠ°ΡΠΊΠΈ
ΠΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΡΠΊΠΈΠ΅ ΡΠ΅ΡΡΡ
kubeval
ΠΡΠΎΠ²Π΅ΡΡΠ΅Ρ YAML-ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΡ Π½Π° ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΠΈΠ΅ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠΉ Π²Π΅ΡΡΠΈΠΈ ΡΡ
Π΅ΠΌΡ API
ΠΠ΅ ΡΠΌΠ΅Π΅Ρ ΡΠ°Π±ΠΎΡΠ°ΡΡ Ρ CRD
ΠΠ΅Ρ
kube-score
ΠΠ½Π°Π»ΠΈΠ·ΠΈΡΡΠ΅Ρ ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΡ YAML Π½Π° ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΠΈΠ΅ Π»ΡΡΡΠΈΠΌ ΠΏΡΠ°ΠΊΡΠΈΠΊΠ°ΠΌ
ΠΠ΅Π»ΡΠ·Ρ Π²ΡΠ±ΡΠ°ΡΡ ΡΠ²ΠΎΡ Π²Π΅ΡΡΠΈΡ API Kubernetes Π΄Π»Ρ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ ΡΠ΅ΡΡΡΡΠΎΠ²
ΠΠ΅Ρ
copper
ΠΠ±ΡΠΈΠΉ ΡΡΠ΅ΠΉΠΌΡΠΎΡΠΊ Π΄Π»Ρ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΡ
JavaScript-ΡΠ΅ΡΡΠΎΠ² Π΄Π»Ρ YAML-ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠΎΠ²
ΠΠ΅Ρ Π²ΡΡΡΠΎΠ΅Π½Π½ΡΡ
ΡΠ΅ΡΡΠΎΠ². Π‘ΠΊΡΠ΄Π½Π°Ρ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡ
ΠΠ°
config-lint
ΠΠ±ΡΠΈΠΉ ΡΡΠ΅ΠΉΠΌΠ²ΠΎΡΠΊ Π΄Π»Ρ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΡΠ΅ΡΡΠΎΠ² Π½Π° ΠΏΡΠ΅Π΄ΠΌΠ΅ΡΠ½ΠΎ-ΠΎΡΠΈΠ΅Π½ΡΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠΌ ΡΠ·ΡΠΊΠ΅, Π²ΡΡΡΠΎΠ΅Π½Π½ΠΎΠΌ Π² YAML. ΠΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅Ρ ΡΠ°Π·Π»ΠΈΡΠ½ΡΠ΅ ΡΠΎΡΠΌΠ°ΡΡ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΉ (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, Terraform)
ΠΠ΅Ρ Π³ΠΎΡΠΎΠ²ΡΡ
ΡΠ΅ΡΡΠΎΠ². ΠΡΡΡΠΎΠ΅Π½Π½ΡΡ
assertions ΠΈ ΡΡΠ½ΠΊΡΠΈΠΉ ΠΌΠΎΠΆΠ΅Ρ ΠΎΠΊΠ°Π·Π°ΡΡΡΡ Π½Π΅Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ
ΠΠ°
conftest
Π€ΡΠ΅ΠΉΠΌΠ²ΠΎΡΠΊ Π΄Π»Ρ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΡ
ΡΠ΅ΡΡΠΎΠ² Π½Π° Rego (ΡΠΏΠ΅ΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠΌ ΡΠ·ΡΠΊΠ΅ Π·Π°ΠΏΡΠΎΡΠΎΠ²). ΠΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Π΄Π΅Π»ΠΈΡΡΡΡ ΠΏΠΎΠ»ΠΈΡΠΈΠΊΠ°ΠΌΠΈ ΡΠ΅ΡΠ΅Π· OCI bundles
ΠΠ΅Ρ Π²ΡΡΡΠΎΠ΅Π½Π½ΡΡ
ΡΠ΅ΡΡΠΎΠ². ΠΡΠΈΡ
ΠΎΠ΄ΠΈΡΡΡ ΠΈΠ·ΡΡΠ°ΡΡ Rego. Docker Hub Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅ΡΡΡ ΠΏΡΠΈ ΠΏΡΠ±Π»ΠΈΠΊΠ°ΡΠΈΠΈ ΠΏΠΎΠ»ΠΈΡΠΈΠΊ
ΠΠ°
Polaris
ΠΠ½Π°Π»ΠΈΠ·ΠΈΡΡΠ΅Ρ YAML-ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΡ Π½Π° ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΠΈΠ΅ ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΡΠΌ Π»ΡΡΡΠΈΠΌ ΠΏΡΠ°ΠΊΡΠΈΠΊΠ°ΠΌ. ΠΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΡΠΎΠ·Π΄Π°Π²Π°ΡΡ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΠ΅ ΡΠ΅ΡΡΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ JSON Schema
ΠΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠ΅ΠΉ ΡΠ΅ΡΡΠΎΠ², ΠΎΡΠ½ΠΎΠ²Π°Π½Π½ΡΡ
Π½Π° JSON Schema, ΠΌΠΎΠΆΠ΅Ρ Π½Π΅ Ρ
Π²Π°ΡΠΈΡΡ
ΠΠ°
ΠΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΡΡΠΈ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΡ Π½Π΅ Π·Π°Π²ΠΈΡΡΡ ΠΎΡ Π΄ΠΎΡΡΡΠΏΠ° Π² ΠΊΠ»Π°ΡΡΠ΅Ρ Kubernetes, ΠΈΡ Π»Π΅Π³ΠΊΠΎ ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°ΡΡ. ΠΠ½ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡΡ ΡΠΈΠ»ΡΡΡΠΎΠ²Π°ΡΡ ΠΈΡΡ ΠΎΠ΄Π½ΡΠ΅ ΡΠ°ΠΉΠ»Ρ ΠΈ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠΈΠ²Π°ΡΡ Π±ΡΡΡΡΡΡ ΠΎΠ±ΡΠ°ΡΠ½ΡΡ ΡΠ²ΡΠ·Ρ Π°Π²ΡΠΎΡΠ°ΠΌ pull request’ΠΎΠ² Π² ΠΏΡΠΎΠ΅ΠΊΡΠ°Ρ .
P.S. ΠΎΡ ΠΏΠ΅ΡΠ΅Π²ΠΎΠ΄ΡΠΈΠΊΠ°
Π§ΠΈΡΠ°ΠΉΡΠ΅ ΡΠ°ΠΊΠΆΠ΅ Π² Π½Π°ΡΠ΅ΠΌ Π±Π»ΠΎΠ³Π΅:
- Β«
ΠΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½ Polaris Π΄Π»Ρ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠ°Π½ΠΈΡ ΠΊΠ»Π°ΡΡΠ΅ΡΠΎΠ² Kubernetes Π² Π·Π΄ΠΎΡΠΎΠ²ΠΎΠΌ ΡΠΎΡΡΠΎΡΠ½ΠΈΠΈ Β»; - Β«
Vim Ρ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠΎΠΉ YAML Π΄Π»Ρ Kubernetes Β»; - Β«
7 Π»ΡΡΡΠΈΡ ΠΏΡΠ°ΠΊΡΠΈΠΊ ΠΏΠΎ ΡΠΊΡΠΏΠ»ΡΠ°ΡΠ°ΡΠΈΠΈ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠΎΠ² ΠΏΠΎ Π²Π΅ΡΡΠΈΠΈ Google Β».
ΠΡΡΠΎΡΠ½ΠΈΠΊ: habr.com