Валидация Kubernetes YAML Π½Π° соотвСтствиС Π»ΡƒΡ‡ΡˆΠΈΠΌ ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ°ΠΌ ΠΈ ΠΏΠΎΠ»ΠΈΡ‚ΠΈΠΊΠ°ΠΌ

ΠŸΡ€ΠΈΠΌ. ΠΏΠ΅Ρ€Π΅Π².: Π‘ ростом числа YAML-ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΉ для K8s-ΠΎΠΊΡ€ΡƒΠΆΠ΅Π½ΠΈΠΉ всё Π±ΠΎΠ»Π΅Π΅ Π°ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½ΠΎΠΉ становится ΠΏΠΎΡ‚Ρ€Π΅Π±Π½ΠΎΡΡ‚ΡŒ Π² ΠΈΡ… Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠΉ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ΅. Автор этого ΠΎΠ±Π·ΠΎΡ€Π° Π½Π΅ просто ΠΎΡ‚ΠΎΠ±Ρ€Π°Π» ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ для этой Π·Π°Π΄Π°Ρ‡ΠΈ, Π½ΠΎ ΠΈ Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ Deployment’Π° посмотрСл, ΠΊΠ°ΠΊ ΠΎΠ½ΠΈ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚. ΠŸΠΎΠ»ΡƒΡ‡ΠΈΠ»ΠΎΡΡŒ вСсьма ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΈΠ²Π½ΠΎ для Ρ‚Π΅Ρ…, ΠΊΠΎΠΌΡƒ эта Ρ‚Π΅ΠΌΠ° интСрСсна.

Валидация Kubernetes YAML Π½Π° соотвСтствиС Π»ΡƒΡ‡ΡˆΠΈΠΌ ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ°ΠΌ ΠΈ ΠΏΠΎΠ»ΠΈΡ‚ΠΈΠΊΠ°ΠΌ

TL;DR: Π’ ΡΡ‚Π°Ρ‚ΡŒΠ΅ ΡΡ€Π°Π²Π½ΠΈΠ²Π°ΡŽΡ‚ΡΡ ΡˆΠ΅ΡΡ‚ΡŒ статичСских инструмСнтов ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ΠΈ ΠΎΡ†Π΅Π½ΠΊΠΈ YAML-Ρ„Π°ΠΉΠ»ΠΎΠ² Kubernetes Π½Π° соотвСтствиС Π»ΡƒΡ‡ΡˆΠΈΠΌ ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ°ΠΌ ΠΈ трСбованиям.

Π Π°Π±ΠΎΡ‡ΠΈΠ΅ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Kubernetes, ΠΊΠ°ΠΊ ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ, ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‚ΡΡ Π² Ρ„ΠΎΡ€ΠΌΠ΅ YAML-Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ². Одна ΠΈΠ· ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ с YAML’ΠΎΠΌ β€” ΡΠ»ΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ задания ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠΉ ΠΈΠ»ΠΈ Π²Π·Π°ΠΈΠΌΠΎΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΠΉ ΠΌΠ΅ΠΆΠ΄Ρƒ Ρ„Π°ΠΉΠ»Π°ΠΌΠΈ манифСстов.

Π§Ρ‚ΠΎ, Ссли Π½Π°ΠΌ Π½Π°Π΄ΠΎ ΡƒΠ΄ΠΎΡΡ‚ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒΡΡ, Ρ‡Ρ‚ΠΎ всС ΠΎΠ±Ρ€Π°Π·Ρ‹, Ρ€Π°Π·Π²Π΅Ρ€Ρ‚Ρ‹Π²Π°Π΅ΠΌΡ‹Π΅ Π² кластСрС, бСрутся ΠΈΠ· Π΄ΠΎΠ²Π΅Ρ€Π΅Π½Π½ΠΎΠ³ΠΎ рССстра?

Как ΠΏΡ€Π΅Π΄ΠΎΡ‚Π²Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΡƒ Π² кластСр Deployment’ΠΎΠ², для ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π½Π΅ Π·Π°Π΄Π°Π½Ρ‹ PodDisruptionBudgets?

Π˜Π½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΡ статичСского тСстирования позволяСт Π²Ρ‹ΡΠ²Π»ΡΡ‚ΡŒ ошибки ΠΈ Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΡ ΠΏΠΎΠ»ΠΈΡ‚ΠΈΠΊ Π΅Ρ‰Π΅ Π½Π° стадии Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ. Π’Π΅ΠΌ самым ΠΏΠΎΠ²Ρ‹ΡˆΠ°ΡŽΡ‚ΡΡ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΠΈ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΡΡ‚ΠΈ ΠΈ бСзопасности ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΉ рСсурсов ΠΈ ΠΏΠΎΠ²Ρ‹ΡˆΠ°Π΅Ρ‚ΡΡ Π²Π΅Ρ€ΠΎΡΡ‚Π½ΠΎΡΡ‚ΡŒ Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ production-Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Π±ΡƒΠ΄ΡƒΡ‚ ΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚ΡŒ Π»ΡƒΡ‡ΡˆΠΈΠΌ ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ°ΠΌ.

ЭкосистСму статичСской ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ YAML-Ρ„Π°ΠΉΠ»ΠΎΠ² Kubernetes ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π°Π·Π΄Π΅Π»ΠΈΡ‚ΡŒ Π½Π° ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΈ:

  • API-Π²Π°Π»ΠΈΠ΄Π°Ρ‚ΠΎΡ€Ρ‹. Π˜Π½ΡΡ‚Ρ€ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ Π² этой ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΈ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡŽΡ‚ YAML-манифСст Π½Π° соотвСтствиС трСбованиям API-сСрвСра Kubernetes.
  • Π“ΠΎΡ‚ΠΎΠ²Ρ‹Π΅ тСстСры. Π˜Π½ΡΡ‚Ρ€ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ ΠΈΠ· Π΄Π°Π½Π½ΠΎΠΉ ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΈ ΠΈΠ΄ΡƒΡ‚ с Π³ΠΎΡ‚ΠΎΠ²Ρ‹ΠΌΠΈ тСстами Π½Π° Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡ‚ΡŒ, соотвСтствиС Π»ΡƒΡ‡ΡˆΠΈΠΌ ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ°ΠΌ ΠΈ Ρ‚.ΠΏ.
  • ΠšΠ°ΡΡ‚ΠΎΠΌΠ½Ρ‹Π΅ Π²Π°Π»ΠΈΠ΄Π°Ρ‚ΠΎΡ€Ρ‹. ΠŸΡ€Π΅Π΄ΡΡ‚Π°Π²ΠΈΡ‚Π΅Π»ΠΈ этой ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠ΅ тСсты Π½Π° Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… языках, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π½Π° Rego ΠΈ Javascript.

Π’ этой ΡΡ‚Π°Ρ‚ΡŒΠ΅ ΠΌΡ‹ опишСм ΠΈ сравним ΡˆΠ΅ΡΡ‚ΡŒ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… инструмСнтов:

  1. kubeval;
  2. kube-score;
  3. config-lint;
  4. copper;
  5. conftest;
  6. 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

Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΏΠ΅Ρ€Π΅ΠΉΠ΄ΠΈΡ‚Π΅ Π½Π° http://localhost:8080 ΠΈ ΠΏΠΎΠ΄Ρ‚Π²Π΅Ρ€Π΄ΠΈΡ‚Π΅, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚. Но слСдуСт Π»ΠΈ ΠΎΠ½ΠΎ Π»ΡƒΡ‡ΡˆΠΈΠΌ ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ°ΠΌ? Π”Π°Π²Π°ΠΉΡ‚Π΅ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΠΌ.

1. Kubeval

Π’ основС kubeval Π»Π΅ΠΆΠΈΡ‚ идСя ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ любоС взаимодСйствиС с Kubernetes происходит Ρ‡Π΅Ρ€Π΅Π· Π΅Π³ΠΎ REST API. Π”Ρ€ΡƒΠ³ΠΈΠΌΠΈ словами, ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ схСму API для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Ρ‚ΠΎΠ³ΠΎ, соотвСтствуСт Π»ΠΈ Π΅ΠΉ Π΄Π°Π½Π½Ρ‹ΠΉ YAML. Π”Π°Π²Π°ΠΉΡ‚Π΅ рассмотрим ΠΏΡ€ΠΈΠΌΠ΅Ρ€.

Π˜Π½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΠΈ ΠΏΠΎ установкС 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.

Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ список вСрсий, для ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… поддСрТиваСтся ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ°, ΠΎΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ΡΡŒ ΠΊ JSON-схСмС Π½Π° GitHub, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ kubeval ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ для Π²Π°Π»ΠΈΠ΄Π°Ρ†ΠΈΠΈ. Если Π½ΡƒΠΆΠ½ΠΎ Π·Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ kubeval ΠΎΡ„Ρ„Π»Π°ΠΉΠ½, скачайтС схСмы ΠΈ ΡƒΠΊΠ°ΠΆΠΈΡ‚Π΅ ΠΈΡ… локальноС мСстополоТСниС с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„Π»Π°Π³Π° --schema-location.

ΠšΡ€ΠΎΠΌΠ΅ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Ρ… YAML-Ρ„Π°ΠΉΠ»ΠΎΠ², kubeval Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с дирСкториями ΠΈ stdin.

ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, Kubeval Π»Π΅Π³ΠΊΠΎ интСгрируСтся Π² ΠΏΠ°ΠΉΠΏΠ»Π°ΠΉΠ½ CI. Π–Π΅Π»Π°ΡŽΡ‰ΠΈΠ΅ ΠΏΡ€ΠΎΠ²ΠΎΠ΄ΠΈΡ‚ΡŒ тСсты ΠΏΠ΅Ρ€Π΅Π΄ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΎΠΉ манифСстов Π² кластСр Π±ΡƒΠ΄ΡƒΡ‚ Ρ€Π°Π΄Ρ‹ ΡƒΠ·Π½Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ kubeval ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ Ρ‚Ρ€ΠΈ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π° Π²Ρ‹Π²ΠΎΠ΄Π°:

  1. ΠžΠ±Ρ‹Ρ‡Π½Ρ‹ΠΉ тСкст;
  2. JSON;
  3. Test Anything Protocol (TAP).

И любой ΠΈΠ· Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΎΠ² ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ для дальнСйшСго парсинга Π²Ρ‹Π²ΠΎΠ΄Π°, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρ„ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ сводку Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ² ΠΆΠ΅Π»Π°Π΅ΠΌΠΎΠ³ΠΎ Π²ΠΈΠ΄Π°.

Один ΠΈΠ· нСдостатков kubeval β€” Π² настоящСС врСмя ΠΎΠ½ Π½Π΅ ΡƒΠΌΠ΅Π΅Ρ‚ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡ‚ΡŒ Π½Π° соотвСтствиС Custom Resource Definitions (CRDs). Однако ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ kubeval ΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΡ….

Kubeval β€” ΠΎΡ‚Π»ΠΈΡ‡Π½Ρ‹ΠΉ инструмСнт для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ΠΈ ΠΎΡ†Π΅Π½ΠΊΠΈ рСсурсов; ΠΏΡ€Π°Π²Π΄Π°, слСдуСт ΠΏΠΎΠ΄Ρ‡Π΅Ρ€ΠΊΠ½ΡƒΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠ΅ ΠΏΡ€ΠΎΡ…ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ тСста Π½Π΅ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚, Ρ‡Ρ‚ΠΎ рСсурс соотвСтствуСт Π»ΡƒΡ‡ΡˆΠΈΠΌ ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ°ΠΌ.

НапримСр, использованиС Ρ‚Π΅Π³Π° latest Π² ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π΅ Π½Π΅ соотвСтствуСт Π»ΡƒΡ‡ΡˆΠΈΠΌ ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ°ΠΌ. Однако kubeval Π½Π΅ считаСт это ошибкой ΠΈ Π½Π΅ сообщаСт ΠΎ Π½Π΅ΠΉ. Π’ΠΎ Π΅ΡΡ‚ΡŒ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Ρ‚Π°ΠΊΠΎΠ³ΠΎ YAML Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡΡ Π±Π΅Π· ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠΉ.

Но Ρ‡Ρ‚ΠΎ, Ссли Π½ΡƒΠΆΠ½ΠΎ ΠΎΡ†Π΅Π½ΠΈΡ‚ΡŒ YAML ΠΈ Π²Ρ‹ΡΠ²ΠΈΡ‚ΡŒ Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΡ Π²Ρ€ΠΎΠ΄Π΅ Ρ‚Π΅Π³Π° latest? Как ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ YAML-Ρ„Π°ΠΉΠ» Π½Π° соотвСтствиС Π»ΡƒΡ‡ΡˆΠΈΠΌ ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ°ΠΌ?

2. Kube-score

Kube-score Π°Π½Π°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅Ρ‚ манифСсты YAML ΠΈ ΠΎΡ†Π΅Π½ΠΈΠ²Π°Π΅Ρ‚ ΠΈΡ… ΠΏΠΎ встроСнным тСстам. Π­Ρ‚ΠΈ тСсты Π²Ρ‹Π±ΠΈΡ€Π°ΡŽΡ‚ΡΡ Π½Π° основС Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΠΉ ΠΏΠΎ бСзопасности ΠΈ Π»ΡƒΡ‡ΡˆΠΈΡ… ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€:

  • Запуск ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π° Π½Π΅ ΠΏΠΎΠ΄ 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 провСряСт, Ρ‡Ρ‚ΠΎ всС ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Ρ‹ Π² Deployment’Π΅ (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

Copper V2 β€” это Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊ для Π²Π°Π»ΠΈΠ΄Π°Ρ†ΠΈΠΈ манифСстов с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΡ… тСстов (Π°Π½Π°Π»ΠΎΠ³ config-lint).

Однако ΠΎΡ‚ послСднСго ΠΎΠ½ отличаСтся Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ 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. ВСсты ΠΎΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‚ΡΡ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ спСциализированного языка запросов Rego.

Π£ΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ 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 ΠΏΠΎΠΊΠ° Π½Π΅ поддСрТиваСтся. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ считайтС, Ρ‡Ρ‚ΠΎ Π²Π°ΠΌ ΠΏΠΎΠ²Π΅Π·Π»ΠΎ, Ссли Π²Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ Azure Container Registry (ACR) ΠΈΠ»ΠΈ свой собствСнный рССстр.

Π€ΠΎΡ€ΠΌΠ°Ρ‚ Π°Ρ€Ρ‚Π΅Ρ„Π°ΠΊΡ‚ΠΎΠ² β€” Ρ‚Π°ΠΊΠΎΠΉ ΠΆΠ΅, ΠΊΠ°ΠΊ Ρƒ ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ² Open Policy Agent (OPA), Ρ‡Ρ‚ΠΎ позволяСт ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ conftest для запуска тСстов ΠΈΠ· ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ² OPA.

Π‘ΠΎΠ»ΡŒΡˆΠ΅ ΠΎ совмСстном использовании ΠΏΠΎΠ»ΠΈΡ‚ΠΈΠΊ ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΡ… особСнностях conftest ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠ·Π½Π°Ρ‚ΡŒ Π½Π° ΠΎΡ„ΠΈΡ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠΌ сайтС ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°.

6. Polaris

ПослСдний инструмСнт, ΠΎ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΠΏΠΎΠΉΠ΄Π΅Ρ‚ Ρ€Π΅Ρ‡ΡŒ Π² этой ΡΡ‚Π°Ρ‚ΡŒΠ΅, β€” это 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. ΠΎΡ‚ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄Ρ‡ΠΈΠΊΠ°

Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ Ρ‚Π°ΠΊΠΆΠ΅ Π² нашСм Π±Π»ΠΎΠ³Π΅:

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com