Kubernetes YAML рд╕рд░реНрд╡реЛрддреНрддрдо рдкрджреНрдзрддреА рдЖрдгрд┐ рдзреЛрд░рдгрд╛рдВрд╡рд┐рд░реБрджреНрдз рдкреНрд░рдорд╛рдгрд┐рдд рдХрд░рд╛

рдиреЛрдВрдж. рдЕрдиреБрд╡рд╛рдж: K8s рд╡рд╛рддрд╛рд╡рд░рдгрд╛рд╕рд╛рдареА YAML рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рдирдЪреНрдпрд╛ рд╡рд╛рдврддреНрдпрд╛ рд╕рдВрдЦреНрдпреЗрд╕рд╣, рддреНрдпрд╛рдВрдЪреНрдпрд╛ рд╕реНрд╡рдпрдВрдЪрд▓рд┐рдд рдкрдбрддрд╛рд│рдгреАрдЪреА рдЧрд░рдЬ рдЕрдзрд┐рдХрд╛рдзрд┐рдХ рдирд┐рдХрдб рд╣реЛрдд рдЖрд╣реЗ. рдпрд╛ рдкреБрдирд░рд╛рд╡рд▓реЛрдХрдирд╛рдЪреНрдпрд╛ рд▓реЗрдЦрдХрд╛рдиреЗ рдпрд╛ рдХрд╛рд░реНрдпрд╛рд╕рд╛рдареА рдХреЗрд╡рд│ рд╡рд┐рджреНрдпрдорд╛рди рдЙрдкрд╛рдп рдирд┐рд╡рдбрд▓реЗ рдирд╛рд╣реАрдд рддрд░ рддреЗ рдХрд╕реЗ рдХрд╛рд░реНрдп рдХрд░рддрд╛рдд рд╣реЗ рдкрд╛рд╣рдгреНрдпрд╛рд╕рд╛рдареА рдЙрджрд╛рд╣рд░рдг рдореНрд╣рдгреВрди рдЙрдкрдпреЛрдЬрди рджреЗрдЦреАрд▓ рд╡рд╛рдкрд░рд▓реЗ. рдЬреНрдпрд╛рдВрдирд╛ рдпрд╛ рд╡рд┐рд╖рдпрд╛рдд рд░рд╕ рдЖрд╣реЗ рддреНрдпрд╛рдВрдЪреНрдпрд╛рд╕рд╛рдареА рд╣реЗ рдЦреВрдк рдорд╛рд╣рд┐рддреАрдкреВрд░реНрдг рдард░рд▓реЗ.

Kubernetes YAML рд╕рд░реНрд╡реЛрддреНрддрдо рдкрджреНрдзрддреА рдЖрдгрд┐ рдзреЛрд░рдгрд╛рдВрд╡рд┐рд░реБрджреНрдз рдкреНрд░рдорд╛рдгрд┐рдд рдХрд░рд╛

TL; рдбреЙ: рд╣рд╛ рд▓реЗрдЦ рд╕рд░реНрд╡реЛрддреНрддрдо рдкрджреНрдзрддреА рдЖрдгрд┐ рдЖрд╡рд╢реНрдпрдХрддрд╛рдВрдиреБрд╕рд╛рд░ Kubernetes YAML рдлрд╛рдЗрд▓реНрд╕рдЪреЗ рдкреНрд░рдорд╛рдгреАрдХрд░рдг рдЖрдгрд┐ рдореВрд▓реНрдпрдорд╛рдкрди рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рд╕рд╣рд╛ рд╕реНрдерд┐рд░ рд╕рд╛рдзрдирд╛рдВрдЪреА рддреБрд▓рдирд╛ рдХрд░рддреЛ.

Kubernetes рд╡рд░реНрдХрд▓реЛрдбреНрд╕ рд╕рд╛рдорд╛рдиреНрдпрдд: YAML рджрд╕реНрддрдРрд╡рдЬрд╛рдВрдЪреНрдпрд╛ рд╕реНрд╡рд░реВрдкрд╛рдд рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХреЗрд▓реЗ рдЬрд╛рддрд╛рдд. YAML рдордзреАрд▓ рд╕рдорд╕реНрдпрд╛рдВрдкреИрдХреА рдПрдХ рдореНрд╣рдгрдЬреЗ рдореЕрдирд┐рдлреЗрд╕реНрдЯ рдлрд╛рдЗрд▓реНрд╕рдордзреАрд▓ рдорд░реНрдпрд╛рджрд╛ рдХрд┐рдВрд╡рд╛ рд╕рдВрдмрдВрдз рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдгреНрдпрд╛рдд рдЕрдбрдЪрдг.

рдХреНрд▓рд╕реНрдЯрд░рдордзреНрдпреЗ рдЙрдкрдпреЛрдЬрд┐рдд рдХреЗрд▓реЗрд▓реНрдпрд╛ рд╕рд░реНрд╡ рдкреНрд░рддрд┐рдорд╛ рд╡рд┐рд╢реНрд╡рд╛рд╕рд╛рд░реНрд╣ рд░реЗрдЬрд┐рд╕реНрдЯреНрд░реАрдордзреВрди рдЖрд▓реНрдпрд╛рдЪреА рдЦрд╛рддреНрд░реА рдХрд░рд╛рдпрдЪреА рдЕрд╕рд▓реНрдпрд╛рд╕ рдХрд╛рдп?

PodDisruptionBudgets рдирд╕рд▓реЗрд▓реНрдпрд╛ рдЙрдкрдпреЛрдЬрдирд╛рдВрдирд╛ рдореА рдХреНрд▓рд╕реНрдЯрд░рд▓рд╛ рдкрд╛рдард╡рдгреНрдпрд╛рдкрд╛рд╕реВрди рдХрд╕реЗ рд░реЛрдЦреВ рд╢рдХрддреЛ?

рд╕реНрдерд┐рд░ рдЪрд╛рдЪрдгреАрдЪреЗ рдПрдХрддреНрд░реАрдХрд░рдг рддреБрдореНрд╣рд╛рд▓рд╛ рд╡рд┐рдХрд╛рд╕рд╛рдЪреНрдпрд╛ рдЯрдкреНрдкреНрдпрд╛рд╡рд░ рддреНрд░реБрдЯреА рдЖрдгрд┐ рдзреЛрд░рдгрд╛рдВрдЪреЗ рдЙрд▓реНрд▓рдВрдШрди рдУрд│рдЦрдгреНрдпрд╛рд╕ рдЕрдиреБрдорддреА рджреЗрддреЗ. рд╣реЗ рд╕рдВрд╕рд╛рдзрди рд╡реНрдпрд╛рдЦреНрдпрд╛ рдпреЛрдЧреНрдп рдЖрдгрд┐ рд╕реБрд░рдХреНрд╖рд┐рдд рдЕрд╕рд▓реНрдпрд╛рдЪреА рд╣рдореА рд╡рд╛рдврд╡рддреЗ рдЖрдгрд┐ рдЙрддреНрдкрд╛рджрди рд╡рд░реНрдХрд▓реЛрдб рд╕рд░реНрд╡реЛрддреНрддрдо рдкрджреНрдзрддреАрдВрдЪреЗ рдкрд╛рд▓рди рдХрд░рддреАрд▓ рдЕрд╢реА рдЕрдзрд┐рдХ рд╢рдХреНрдпрддрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рддреЗ.

Kubernetes рд╕реНрдерд┐рд░ YAML рдлрд╛рдЗрд▓ рддрдкрд╛рд╕рдгреА рдЗрдХреЛрд╕рд┐рд╕реНрдЯрдо рдЦрд╛рд▓реАрд▓ рд╢реНрд░реЗрдгреАрдВрдордзреНрдпреЗ рд╡рд┐рднрд╛рдЧрд▓реА рдЬрд╛рдК рд╢рдХрддреЗ:

  • API рдкреНрд░рдорд╛рдгреАрдХрд░рдгрдХрд░реНрддреЗ. рдпрд╛ рд╡рд░реНрдЧрд╛рддреАрд▓ рд╕рд╛рдзрдиреЗ рдХреБрдмрд░реНрдиреЗрдЯреНрд╕ API рд╕рд░реНрд╡реНрд╣рд░рдЪреНрдпрд╛ рдЖрд╡рд╢реНрдпрдХрддрд╛рдВрдиреБрд╕рд╛рд░ YAML рдореЕрдирд┐рдлреЗрд╕реНрдЯ рддрдкрд╛рд╕рддрд╛рдд.
  • рддрдпрд╛рд░ рдкрд░реАрдХреНрд╖рдХ. рдпрд╛ рд╢реНрд░реЗрдгреАрддреАрд▓ рд╕рд╛рдзрдиреЗ рд╕реБрд░рдХреНрд╖рд┐рддрддреЗрд╕рд╛рдареА, рд╕рд░реНрд╡реЛрддреНрддрдо рдкрджреНрдзрддреАрдВрдЪреЗ рдкрд╛рд▓рди рдЗрддреНрдпрд╛рджреАрдВрд╕рд╛рдареА рддрдпрд╛рд░ рдХреЗрд▓реЗрд▓реНрдпрд╛ рдЪрд╛рдЪрдгреНрдпрд╛рдВрд╕рд╣ рдпреЗрддрд╛рдд.
  • рд╕рд╛рдиреБрдХреВрд▓ рд╕рддреНрдпрд╛рдкрдирдХрд░реНрддреЗ. рдпрд╛ рд╢реНрд░реЗрдгреАрдЪреЗ рдкреНрд░рддрд┐рдирд┐рдзреА рддреБрдореНрд╣рд╛рд▓рд╛ рд╡рд┐рд╡рд┐рдз рднрд╛рд╖рд╛рдВрдордзреНрдпреЗ рд╕рд╛рдиреБрдХреВрд▓ рдЪрд╛рдЪрдгреНрдпрд╛ рддрдпрд╛рд░ рдХрд░рдгреНрдпрд╛рдЪреА рдкрд░рд╡рд╛рдирдЧреА рджреЗрддрд╛рдд, рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рд░реЗрдЧреЛ рдЖрдгрд┐ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ.

рдпрд╛ рд▓реЗрдЦрд╛рдд рдЖрдореНрд╣реА рд╕рд╣рд╛ рд╡реЗрдЧрд╡реЗрдЧрд│реНрдпрд╛ рд╕рд╛рдзрдирд╛рдВрдЪреЗ рд╡рд░реНрдгрди рдЖрдгрд┐ рддреБрд▓рдирд╛ рдХрд░реВ:

  1. рдХреБрдмреЗрд╡рд▓;
  2. kube-рд╕реНрдХреЛрдЕрд░;
  3. config-lint;
  4. рддрд╛рдВрдмреЗ;
  5. рд╕реНрдкрд░реНрдзрд╛
  6. рдкреЛрд▓рд╛рд░рд┐рд╕.

рдмрд░рдВ, рдЪрд▓рд╛ рд╕реБрд░реБрд╡рд╛рдд рдХрд░реВрдпрд╛!

рдЙрдкрдпреЛрдЬрди рддрдкрд╛рд╕рдд рдЖрд╣реЗ

рдЖрдкрдг рд╕рд╛рдзрдирд╛рдВрдЪреА рддреБрд▓рдирд╛ рд╕реБрд░реВ рдХрд░рдгреНрдпрд╛рдкреВрд░реНрд╡реА, рддреНрдпрд╛рдВрдЪреА рдЪрд╛рдЪрдгреА рдШреЗрдгреНрдпрд╛рд╕рд╛рдареА рдХрд╛рд╣реА рдкрд╛рд░реНрд╢реНрд╡рднреВрдореА рддрдпрд╛рд░ рдХрд░реВрдпрд╛.

рдЦрд╛рд▓реАрд▓ рдШреЛрд╖рдгрд╛рдкрддреНрд░рд╛рдордзреНрдпреЗ рдЕрдиреЗрдХ рддреНрд░реБрдЯреА рдЖрдгрд┐ рд╕рд░реНрд╡реЛрддреНрддрдо рдкрджреНрдзрддреАрдВрдЪреЗ рдкрд╛рд▓рди рди рдХрд░рдгреЗ рд╕рдорд╛рд╡рд┐рд╖реНрдЯ рдЖрд╣реЗ: рддреНрдпрд╛рдкреИрдХреА рдХрд┐рддреА рддреБрдореНрд╣рд╛рд▓рд╛ рд╕рд╛рдкрдбрддреАрд▓?

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 рднрд╛рдВрдбрд╛рд░.

рдореЕрдирд┐рдлреЗрд╕реНрдЯ рдПрдХрд╛ рд╡реЗрдм рдНрдкреНрд▓рд┐рдХреЗрд╢рдирдЪреЗ рд╡рд░реНрдгрди рдХрд░рддреЛ рдЬреНрдпрд╛рдЪреЗ рдореБрдЦреНрдп рдХрд╛рд░реНрдп рдкреЛрд░реНрдЯ 5678 рд╡рд░ "рд╣реЕрд▓реЛ рд╡рд░реНрд▓реНрдб" рд╕рдВрджреЗрд╢рд╛рд╕рд╣ рдкреНрд░рддрд┐рд╕рд╛рдж рджреЗрдгреЗ рдЖрд╣реЗ. рддреЗ рдЦрд╛рд▓реАрд▓ рдЖрджреЗрд╢рд╛рд╕рд╣ рддреИрдирд╛рдд рдХреЗрд▓реЗ рдЬрд╛рдК рд╢рдХрддреЗ:

kubectl apply -f hello-world.yaml

рдЖрдгрд┐ рдореНрд╣рдгреВрди - рдХрд╛рдо рддрдкрд╛рд╕рд╛:

kubectl port-forward svc/http-echo 8080:5678

рдЖрддрд╛ рдЬрд╛ http://localhost:8080 рдЖрдгрд┐ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдХрд╛рд░реНрдп рдХрд░рдд рдЕрд╕рд▓реНрдпрд╛рдЪреА рдкреБрд╖реНрдЯреА рдХрд░рд╛. рдкрдг рддреЗ рд╕рд░реНрд╡реЛрддреНрддрдо рдкрджреНрдзрддреАрдВрдЪреЗ рдкрд╛рд▓рди рдХрд░рддреЗ рдХрд╛? рдЪрд▓рд╛ рддрдкрд╛рд╕реВрдпрд╛.

1. рдХреБрдмреЗрд╡рд▓

рдЪреНрдпрд╛ рд╣реГрджрдпрд╛рдд рдХреБрдмреЗрд╡рд▓ рдХрд▓реНрдкрдирд╛ рдЕрд╢реА рдЖрд╣реЗ рдХреА рдХреБрдмрд░реНрдиреЗрдЯреНрд╕рд╢реА рдХреЛрдгрддрд╛рд╣реА рд╕рдВрд╡рд╛рдж рддреНрдпрд╛рдЪреНрдпрд╛ REST API рджреНрд╡рд╛рд░реЗ рд╣реЛрддреЛ. рджреБрд╕-рдпрд╛ рд╢рдмреНрджрд╛рдд, рджрд┐рд▓реЗрд▓реНрдпрд╛ YAML рддреНрдпрд╛рдЪреНрдпрд╛рд╢реА рд╕реБрд╕рдВрдЧрдд рдЖрд╣реЗ рдХреА рдирд╛рд╣реА рд╣реЗ рддрдкрд╛рд╕рдгреНрдпрд╛рд╕рд╛рдареА рддреБрдореНрд╣реА API рд╕реНрдХреАрдорд╛ рд╡рд╛рдкрд░реВ рд╢рдХрддрд╛. рдПрдХ рдЙрджрд╛рд╣рд░рдг рдкрд╛рд╣реВ.

рд╕реНрдерд╛рдкрдирд╛ рд╕реВрдЪрдирд╛ 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)

рдпрд╢рд╕реНрд╡реА рдЭрд╛рд▓реНрдпрд╛рд╕, рдХреБрдмреЗрд╡рд▓ рдПрдХреНрдЭрд┐рдЯ рдХреЛрдб 0 рд╕рд╣ рдмрд╛рд╣реЗрд░ рдкрдбреЗрд▓. рддреБрдореНрд╣реА рддреЗ рдЦрд╛рд▓реАрд▓рдкреНрд░рдорд╛рдгреЗ рддрдкрд╛рд╕реВ рд╢рдХрддрд╛:

$ echo $?
0

рдЖрддрд╛ рд╡реЗрдЧрд│реНрдпрд╛ рдореЕрдирд┐рдлреЗрд╕реНрдЯрд╕рд╣ рдХреБрдмреЗрд╡рд▓ рд╡рд╛рдкрд░реВрди рдкрд╛рд╣реВ:

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, рдкреЙрдбрдЪреНрдпрд╛ рд▓реЗрдмрд▓рд╢реА рдЬреБрд│рдгрд╛рд░рд╛ рдирд┐рд╡рдбрдХ рд╕рдорд╛рд╡рд┐рд╖реНрдЯ рдХрд░рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ. рд╡рд░реАрд▓ рдореЕрдирд┐рдлреЗрд╕реНрдЯрдордзреНрдпреЗ рдирд┐рд╡рдбрдХрд░реНрддреНрдпрд╛рдЪрд╛ рд╕рдорд╛рд╡реЗрд╢ рдирд╛рд╣реА, рддреНрдпрд╛рдореБрд│реЗ рдХреБрдмреЗрд╡рд╛рд▓рдиреЗ рддреНрд░реБрдЯреА рдиреЛрдВрджрд╡рд▓реА рдЖрдгрд┐ рд╢реВрдиреНрдп рдирд╕рд▓реЗрд▓реНрдпрд╛ рдХреЛрдбрд╕рд╣ рдмрд╛рд╣реЗрд░ рдкрдбрд▓реЛ.

рдорд▓рд╛ рдЖрд╢реНрдЪрд░реНрдп рд╡рд╛рдЯрддреЗ рдХреА рдореА рдХреЗрд▓реЗ рддрд░ рдХрд╛рдп рд╣реЛрдИрд▓ 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

рдиреЗрдордХреА рд╣реАрдЪ рдЪреВрдХ рдЖрд╣реЗ рдЬреНрдпрд╛рдмрджреНрджрд▓ рдХреБрдмреЗрд╡рд╛рд▓ рдпрд╛рдВрдиреА рдЗрд╢рд╛рд░рд╛ рджрд┐рд▓рд╛ рд╣реЛрддрд╛. рддреБрдореНрд╣реА рд╕рд┐рд▓реЗрдХреНрдЯрд░ рдЬреЛрдбреВрди рдпрд╛рдЪреЗ рдирд┐рд░рд╛рдХрд░рдг рдХрд░реВ рд╢рдХрддрд╛:

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)

рдХреБрдмреЗрд╡рд▓ рд╕рд╛рд░рдЦреНрдпрд╛ рд╕рд╛рдзрдирд╛рдВрдЪрд╛ рдлрд╛рдпрджрд╛ рдЕрд╕рд╛ рдЖрд╣реЗ рдХреА рдпрд╛рд╕рд╛рд░рдЦреНрдпрд╛ рддреНрд░реБрдЯреА рдЙрдкрдпреЛрдЬрди рдЪрдХреНрд░рд╛рдд рд▓рд╡рдХрд░ рдкрдХрдбрд▓реНрдпрд╛ рдЬрд╛рдК рд╢рдХрддрд╛рдд.

рдпрд╛рд╡реНрдпрддрд┐рд░рд┐рдХреНрдд, рдпрд╛ рддрдкрд╛рд╕рдгреНрдпрд╛рдВрдирд╛ рдХреНрд▓рд╕реНрдЯрд░рдордзреНрдпреЗ рдкреНрд░рд╡реЗрд╢ рдЖрд╡рд╢реНрдпрдХ рдирд╛рд╣реА; рддреЗ рдСрдлрд▓рд╛рдЗрди рдХреЗрд▓реЗ рдЬрд╛рдК рд╢рдХрддрд╛рдд.

рдбреАрдлреЙрд▓реНрдЯрдиреБрд╕рд╛рд░, рдХреБрдмреЗрд╡рд▓ рдирд╡реАрдирддрдо Kubernetes API рд╕реНрдХреАрдорд╛ рд╡рд┐рд░реБрджреНрдз рд╕рдВрд╕рд╛рдзрдиреЗ рддрдкрд╛рд╕рддреЗ. рддрдерд╛рдкрд┐, рдмрд░реНтАНрдпрд╛рдЪ рдкреНрд░рдХрд░рдгрд╛рдВрдордзреНрдпреЗ рдЖрдкрд▓реНрдпрд╛рд▓рд╛ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХреБрдмрд░реНрдиреЗрдЯреНрд╕ рд░рд┐рд▓реАрдЭ рд╡рд┐рд░реВрджреНрдз рддрдкрд╛рд╕рдгреНрдпрд╛рдЪреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдЕрд╕реВ рд╢рдХрддреЗ. рд╣реЗ рдзреНрд╡рдЬ рд╡рд╛рдкрд░реВрди рдХреЗрд▓реЗ рдЬрд╛рдК рд╢рдХрддреЗ --kubernetes-version:

$ kubeval --kubernetes-version 1.16.1 base-valid.yaml

рдХреГрдкрдпрд╛ рд▓рдХреНрд╖рд╛рдд рдареЗрд╡рд╛ рдХреА рдЖрд╡реГрддреНрддреА рдлреЙрд░рдореЕрдЯрдордзреНрдпреЗ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ Major.Minor.Patch.

рдЖрд╡реГрддреНрддреНрдпрд╛рдВрдЪреНрдпрд╛ рд╕реВрдЪреАрд╕рд╛рдареА рдЬреНрдпрд╛рд╕рд╛рдареА рд╕рддреНрдпрд╛рдкрди рд╕рдорд░реНрдерд┐рдд рдЖрд╣реЗ, рдХреГрдкрдпрд╛ рдкрд╣рд╛ GitHub рд╡рд░ JSON рд╕реНрдХреАрдорд╛, рдЬреЗ рдХреБрдмреЗрд╡рд╛рд▓ рдкреНрд░рдорд╛рдгреАрдХрд░рдгрд╛рд╕рд╛рдареА рд╡рд╛рдкрд░рддрд╛рдд. рддреБрдореНрд╣рд╛рд▓рд╛ рдХреБрдмреЗрд╡рд▓ рдСрдлрд▓рд╛рдЗрди рдЪрд╛рд▓рд╡рд╛рдпрдЪреЗ рдЕрд╕рд▓реНрдпрд╛рд╕, рд╕реНрдХреАрдорд╛ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рд╛ рдЖрдгрд┐ рдзреНрд╡рдЬ рд╡рд╛рдкрд░реВрди рддреНрдпрд╛рдВрдЪреЗ рд╕реНрдерд╛рдирд┐рдХ рд╕реНрдерд╛рди рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рд╛ --schema-location.

рд╡реИрдпрдХреНрддрд┐рдХ YAML рдлрд╛рдЗрд▓реНрд╕ рд╡реНрдпрддрд┐рд░рд┐рдХреНрдд, kubeval рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдЖрдгрд┐ stdin рд╕рд╣ рджреЗрдЦреАрд▓ рдХрд╛рд░реНрдп рдХрд░реВ рд╢рдХрддреЗ.

рдпрд╛рд╡реНрдпрддрд┐рд░рд┐рдХреНрдд, рдХреБрдмреЗрд╡рд▓ рд╕рд╣рдЬрдкрдгреЗ рд╕реАрдЖрдп рдкрд╛рдЗрдкрд▓рд╛рдЗрдирдордзреНрдпреЗ рд╕рдорд╛рдХрд▓рд┐рдд рд╣реЛрддреЗ. рдХреНрд▓рд╕реНрдЯрд░рд▓рд╛ рдореЕрдирд┐рдлреЗрд╕реНрдЯ рдкрд╛рдард╡рдгреНрдпрд╛рдкреВрд░реНрд╡реА рдЪрд╛рдЪрдгреНрдпрд╛ рдЪрд╛рд▓рд╡рдгреНрдпрд╛рдЪреА рдЗрдЪреНрдЫрд╛ рдЕрд╕рд▓реЗрд▓реНрдпрд╛рдВрдирд╛ рд╣реЗ рдЬрд╛рдгреВрди рдЖрдирдВрдж рд╣реЛрдИрд▓ рдХреА рдХреБрдмреЗрд╡рд▓ рддреАрди рдЖрдЙрдЯрдкреБрдЯ рдлреЙрд░рдореЕрдЯрд▓рд╛ рд╕рдкреЛрд░реНрдЯ рдХрд░рддреЛ:

  1. рд╕рд╛рдзрд╛ рдордЬрдХреВрд░;
  2. JSON;
  3. рдПрдиреАрдерд┐рдВрдЧ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ (рдЯреЕрдк) рдЪрд╛рдЪрдгреА рдХрд░рд╛.

рдЖрдгрд┐ рдЗрдЪреНрдЫрд┐рдд рдкреНрд░рдХрд╛рд░рд╛рдЪреНрдпрд╛ рдкрд░рд┐рдгрд╛рдорд╛рдВрдЪрд╛ рд╕рд╛рд░рд╛рдВрд╢ рддрдпрд╛рд░ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдЖрдЙрдЯрдкреБрдЯрдЪреНрдпрд╛ рдкреБрдвреАрд▓ рд╡рд┐рд╢реНрд▓реЗрд╖рдгрд╛рд╕рд╛рдареА рдХреЛрдгрддреЗрд╣реА рд╕реНрд╡рд░реВрдк рд╡рд╛рдкрд░рд▓реЗ рдЬрд╛рдК рд╢рдХрддреЗ.

рдХреБрдмреЗрд╡рд▓рдЪреНрдпрд╛ рддреНрд░реБрдЯреАрдВрдкреИрдХреА рдПрдХ рдореНрд╣рдгрдЬреЗ рддреЗ рд╕рдзреНрдпрд╛ рдХрд╕реНрдЯрдо рд░рд┐рд╕реЛрд░реНрд╕ рдбреЗрдлрд┐рдирд┐рд╢рди (CRDs) рдЪреЗ рдЕрдиреБрдкрд╛рд▓рди рддрдкрд╛рд╕реВ рд╢рдХрдд рдирд╛рд╣реА. рддрдерд╛рдкрд┐, рдХреБрдмреЗрд╡рд▓ рдХреЙрдиреНрдлрд┐рдЧрд░ рдХрд░рдгреЗ рд╢рдХреНрдп рдЖрд╣реЗ рддреНрдпрд╛рдВрдЪреНрдпрд╛рдХрдбреЗ рджреБрд░реНрд▓рдХреНрд╖ рдХрд░рд╛.

рдХреБрдмреЗрд╡рд▓ рд╣реЗ рд╕рдВрд╕рд╛рдзрдиреЗ рддрдкрд╛рд╕рдгреНрдпрд╛рд╕рд╛рдареА рдЖрдгрд┐ рдореВрд▓реНрдпрдорд╛рдкрди рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдПрдХ рдЙрддреНрддрдо рд╕рд╛рдзрди рдЖрд╣реЗ; рддрдерд╛рдкрд┐, рдпрд╛рд╡рд░ рдЬреЛрд░ рджрд┐рд▓рд╛ рдкрд╛рд╣рд┐рдЬреЗ рдХреА рдЪрд╛рдЪрдгреА рдЙрддреНрддреАрд░реНрдг рдХреЗрд▓реНрдпрд╛рдиреЗ рд╕рдВрд╕рд╛рдзрди рд╕рд░реНрд╡реЛрддреНрддрдо рдкрджреНрдзрддреАрдВрдЪреЗ рдкрд╛рд▓рди рдХрд░рддреЗ рдпрд╛рдЪреА рд╣рдореА рджреЗрдд тАЛтАЛрдирд╛рд╣реА.

рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдЯреЕрдЧ рд╡рд╛рдкрд░рдгреЗ latest рдХрдВрдЯреЗрдирд░рдордзреНрдпреЗ рд╕рд░реНрд╡реЛрддреНрддрдо рдкрджреНрдзрддреАрдВрдЪреЗ рдкрд╛рд▓рди рдХрд░рдд рдирд╛рд╣реА. рдорд╛рддреНрд░, рдХреБрдмреЗрд╡рд╛рд▓ рдпрд╛рд▓рд╛ рддреНрд░реБрдЯреА рдорд╛рдирдд рдирд╛рд╣реАрдд рдЖрдгрд┐ рддрдХреНрд░рд╛рд░ рдХрд░рдд рдирд╛рд╣реАрдд. рдореНрд╣рдгрдЬреЗрдЪ, рдЕрд╢рд╛ YAML рдЪреЗ рд╕рддреНрдпрд╛рдкрди рдЪреЗрддрд╛рд╡рдгреАрд╢рд┐рд╡рд╛рдп рдкреВрд░реНрдг рд╣реЛрдИрд▓.

рдкрдг рддреБрдореНрд╣рд╛рд▓рд╛ YAML рдЪреЗ рдореВрд▓реНрдпрдорд╛рдкрди рдХрд░рд╛рдпрдЪреЗ рдЕрд╕реЗрд▓ рдЖрдгрд┐ рдЯреЕрдЧрд╕рд╛рд░рдЦреЗ рдЙрд▓реНрд▓рдВрдШрди рдУрд│рдЦрд╛рдпрдЪреЗ рдЕрд╕реЗрд▓ рддрд░? latest? рд╕рд░реНрд╡реЛрддреНрддрдо рдкрджреНрдзрддреАрдВрд╡рд┐рд░реБрджреНрдз рдореА YAML рдлрд╛рдЗрд▓ рдХрд╢реА рддрдкрд╛рд╕реВ?

2. рдХреБрдмреЗ-рд╕реНрдХреЛрдЕрд░

рдХреБрдмреЗ-рд╕реНрдХреЛрдЕрд░ YAML рдореЕрдирд┐рдлреЗрд╕реНрдЯ рдкрд╛рд░реНрд╕ рдХрд░рддреЗ рдЖрдгрд┐ рдЕрдВрдЧрднреВрдд рдЪрд╛рдЪрдгреНрдпрд╛рдВрд╡рд┐рд░реВрджреНрдз рддреНрдпрд╛рдВрдЪреЗ рдореВрд▓реНрдпрд╛рдВрдХрди рдХрд░рддреЗ. рдпрд╛ рдЪрд╛рдЪрдгреНрдпрд╛ рд╕реБрд░рдХреНрд╖рд╛ рдорд╛рд░реНрдЧрджрд░реНрд╢рдХ рддрддреНрддреНрд╡реЗ рдЖрдгрд┐ рд╕рд░реНрд╡реЛрддреНрддрдо рдкрджреНрдзрддреАрдВрд╡рд░ рдЖрдзрд╛рд░рд┐рдд рдирд┐рд╡рдбрд▓реНрдпрд╛ рдЬрд╛рддрд╛рдд, рдЬрд╕реЗ рдХреА:

  • рд░реВрдЯ рдореНрд╣рдгреВрди рдирд╛рд╣реА рдХрдВрдЯреЗрдирд░ рдЪрд╛рд▓рд╡рдгреЗ.
  • рдкреЙрдб рдЖрд░реЛрдЧреНрдп рддрдкрд╛рд╕рдгреАрдЪреА рдЙрдкрд▓рдмреНрдзрддрд╛.
  • рд╕рдВрд╕рд╛рдзрдирд╛рдВрд╕рд╛рдареА рд╡рд┐рдирдВрддреНрдпрд╛ рдЖрдгрд┐ рдорд░реНрдпрд╛рджрд╛ рд╕реЗрдЯ рдХрд░рдгреЗ.

рдЪрд╛рдЪрдгреА рдкрд░рд┐рдгрд╛рдорд╛рдВрд╡рд░ рдЖрдзрд╛рд░рд┐рдд, рддреАрди рдкрд░рд┐рдгрд╛рдо рджрд┐рд▓реЗ рдЬрд╛рддрд╛рдд: OK, рдЪреЗрддрд╛рд╡рдгреА ╨╕ рдЧрдВрднреАрд░.

рддреБрдореНрд╣реА рдХреБрдмреЗ-рд╕реНрдХреЛрдЕрд░ рдСрдирд▓рд╛рдЗрди рд╡рд╛рдкрд░реВрди рдкрд╛рд╣реВ рд╢рдХрддрд╛ рдХрд┐рдВрд╡рд╛ рд╕реНрдерд╛рдирд┐рдХ рдкрд╛рддрд│реАрд╡рд░ рд╕реНрдерд╛рдкрд┐рдд рдХрд░реВ рд╢рдХрддрд╛.

рдореВрд│ рд▓реЗрдЦ рд▓рд┐рд╣рд┐рдгреНрдпрд╛рдЪреНрдпрд╛ рд╡реЗрд│реА, рдХреБрдмреЗ-рд╕реНрдХреЛрдЕрд░рдЪреА рдирд╡реАрдирддрдо рдЖрд╡реГрддреНрддреА 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 рдХреБрдмреЗрд╡рд▓ рдЪрд╛рдЪрдгреНрдпрд╛ рдЙрддреНрддреАрд░реНрдг рдХрд░рддреЗ, рддрд░ kube-рд╕реНрдХреЛрдЕрд░ рдЦрд╛рд▓реАрд▓ рддреНрд░реБрдЯреАрдВрдХрдбреЗ рдирд┐рд░реНрджреЗрд╢ рдХрд░рддреЗ:

  • рддрдпрд╛рд░реА рддрдкрд╛рд╕рдгреА рдХреЙрдиреНрдлрд┐рдЧрд░ рдХреЗрд▓реЗрд▓реА рдирд╛рд╣реА.
  • CPU рд╕рдВрд╕рд╛рдзрдиреЗ рдЖрдгрд┐ рдореЗрдорд░реАрд╕рд╛рдареА рдХреЛрдгрддреНрдпрд╛рд╣реА рд╡рд┐рдирдВрддреНрдпрд╛ рдХрд┐рдВрд╡рд╛ рдорд░реНрдпрд╛рджрд╛ рдирд╛рд╣реАрдд.
  • рдкреЙрдб рд╡реНрдпрддреНрдпрдп рдЕрдВрджрд╛рдЬрдкрддреНрд░рдХ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХреЗрд▓реЗрд▓реЗ рдирд╛рд╣реАрдд.
  • рд╡реЗрдЧрд│реЗ рдХрд░рдгреНрдпрд╛рдЪреЗ рдХреЛрдгрддреЗрд╣реА рдирд┐рдпрдо рдирд╛рд╣реАрдд (рд╡рд┐рд░реЛрдзрдХ) рдЙрдкрд▓рдмреНрдзрддрд╛ рд╡рд╛рдврд╡рдгреНрдпрд╛рд╕рд╛рдареА.
  • рдХрдВрдЯреЗрдирд░ рд░реВрдЯ рдореНрд╣рдгреВрди рдЪрд╛рд▓рддреЗ.

рдЙрдкрдпреЛрдЬрди рдЕрдзрд┐рдХ рдХрд╛рд░реНрдпрдХреНрд╖рдо рдЖрдгрд┐ рд╡рд┐рд╢реНрд╡рд╛рд╕рд╛рд░реНрд╣ рдмрдирд╡рдгреНрдпрд╛рд╕рд╛рдареА рдпрд╛ рд╕рд░реНрд╡ рддреНрд░реБрдЯреАрдВрдмрджреНрджрд▓ рд╡реИрдз рдореБрджреНрджреЗ рдЖрд╣реЗрдд рдЬреНрдпрд╛рдХрдбреЗ рд▓рдХреНрд╖ рджреЗрдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ.

рд╕рдВрдШ 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

рдХреБрдмреЗрд╡рд▓ рдкреНрд░рдорд╛рдгреЗрдЪ, рдХреБрдмреЗ-рд╕реНрдХреЛрдЕрд░ рдПрдХ рдиреЙрди-рдЭрд┐рд░реЛ рдПрдХреНрдЭрд┐рдЯ рдХреЛрдб рдкрд░рдд рдХрд░рддреЛ рдЬреЗрд╡реНрд╣рд╛ рдПрдЦрд╛рджреА рдЪрд╛рдЪрдгреА рдЕрдкрдпрд╢реА рдард░рддреЗ рдЧрдВрднреАрд░. рдЖрдкрдг рдпрд╛рд╕рд╛рдареА рд╕рдорд╛рди рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╕рдХреНрд╖рдо рджреЗрдЦреАрд▓ рдХрд░реВ рд╢рдХрддрд╛ рдЪреЗрддрд╛рд╡рдгреА.

рдпрд╛рд╡реНрдпрддрд┐рд░рд┐рдХреНрдд, рд╡реЗрдЧрд╡реЗрдЧрд│реНрдпрд╛ API рдЖрд╡реГрддреНрддреНрдпрд╛рдВрд╕рд╣ (рдХреБрдмреЗрд╡рд▓ рдкреНрд░рдорд╛рдгреЗ) рдЕрдиреБрдкрд╛рд▓рдирд╛рд╕рд╛рдареА рд╕рдВрд╕рд╛рдзрдиреЗ рддрдкрд╛рд╕рдгреЗ рд╢рдХреНрдп рдЖрд╣реЗ. рддрдерд╛рдкрд┐, рд╣реА рдорд╛рд╣рд┐рддреА kube-рд╕реНрдХреЛрдЕрд░рдордзреНрдпреЗрдЪ рд╣рд╛рд░реНрдбрдХреЛрдб рдХреЗрд▓реЗрд▓реА рдЖрд╣реЗ: рддреБрдореНрд╣реА Kubernetes рдЪреА рд╡реЗрдЧрд│реА рдЖрд╡реГрддреНрддреА рдирд┐рд╡рдбреВ рд╢рдХрдд рдирд╛рд╣реА. рддреБрдордЪрд╛ рдХреНрд▓рд╕реНрдЯрд░ рдЕрдкрдЧреНрд░реЗрдб рдХрд░рд╛рдпрдЪрд╛ рдЕрд╕реЗрд▓ рдХрд┐рдВрд╡рд╛ рддреБрдордЪреНрдпрд╛рдХрдбреЗ K8 рдЪреНрдпрд╛ рд╡реЗрдЧрд╡реЗрдЧрд│реНрдпрд╛ рдЖрд╡реГрддреНрддреНрдпрд╛рдВрд╕рд╣ рдЕрдиреЗрдХ рдХреНрд▓рд╕реНрдЯрд░реНрд╕ рдЕрд╕рддреАрд▓ рддрд░ рд╣реА рдорд░реНрдпрд╛рджрд╛ рдореЛрдареА рд╕рдорд╕реНрдпрд╛ рдЕрд╕реВ рд╢рдХрддреЗ.

рд▓рдХреНрд╖рд╛рдд рдареЗрд╡рд╛ рдХреА рдЖрдзреАрдЪ рдПрдХ рд╕рдорд╕реНрдпрд╛ рдЖрд╣реЗ рдпрд╛ рд╕рдВрдзреАрдЪреА рдЬрд╛рдгреАрд╡ рдХрд░реВрди рджреЗрдгреНрдпрд╛рд╕рд╛рдареА рдкреНрд░рд╕реНрддрд╛рд╡рд╛рд╕рд╣.

рдХреБрдмреЗ-рд╕реНрдХреЛрдЕрд░рдмрджреНрджрд▓ рдЕрдзрд┐рдХ рдорд╛рд╣рд┐рддреА рдпреЗрдереЗ рдЖрдврд│реВ рд╢рдХрддреЗ рдЕрдзрд┐рдХреГрдд рд╡реЗрдмрд╕рд╛рдЗрдЯ.

рдХреБрдмреЗ-рд╕реНрдХреЛрдЕрд░ рдЪрд╛рдЪрдгреНрдпрд╛ рд╕рд░реНрд╡реЛрддреНрддрдо рдкрджреНрдзрддреА рд▓рд╛рдЧреВ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдПрдХ рдЙрддреНрддрдо рд╕рд╛рдзрди рдЖрд╣реЗ, рдкрд░рдВрддреБ рддреБрдореНрд╣рд╛рд▓рд╛ рдЪрд╛рдЪрдгреАрдордзреНрдпреЗ рдмрджрд▓ рдХрд░рдгреЗ рдХрд┐рдВрд╡рд╛ рддреБрдордЪреЗ рд╕реНрд╡рддрдГрдЪреЗ рдирд┐рдпрдо рдЬреЛрдбрдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЕрд╕рд▓реНрдпрд╛рд╕ рдХрд╛рдп? рдЕрд░реЗрд░реЗ, рд╣реЗ рдХрд░рддрд╛ рдпреЗрдд рдирд╛рд╣реА.

рдХреБрдмреЗ-рд╕реНрдХреЛрдЕрд░ рдПрдХреНрд╕реНрдЯреЗрдВрд╕рд┐рдмрд▓ рдирд╛рд╣реА: рддреБрдореНрд╣реА рддреНрдпрд╛рдд рдкреЙрд▓рд┐рд╕реА рдЬреЛрдбреВ рд╢рдХрдд рдирд╛рд╣реА рдХрд┐рдВрд╡рд╛ рд╕рдорд╛рдпреЛрдЬрд┐рдд рдХрд░реВ рд╢рдХрдд рдирд╛рд╣реА.

рдХрдВрдкрдиреАрдЪреНрдпрд╛ рдзреЛрд░рдгрд╛рдВрдЪреЗ рдЕрдиреБрдкрд╛рд▓рди рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рддреБрдореНрд╣рд╛рд▓рд╛ рд╕рд╛рдиреБрдХреВрд▓ рдЪрд╛рдЪрдгреНрдпрд╛ рд▓рд┐рд╣рд┐рдгреНрдпрд╛рдЪреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдЕрд╕рд▓реНрдпрд╛рд╕, рддреБрдореНрд╣реА рдЦрд╛рд▓реАрд▓ рдЪрд╛рд░ рд╕рд╛рдзрдирд╛рдВрдкреИрдХреА рдПрдХ рд╡рд╛рдкрд░реВ рд╢рдХрддрд╛: рдХреЙрдиреНрдлрд┐рдЧ-рд▓рд┐рдВрдЯ, рдХреЙрдкрд░, рдХреЙрдиреНрдлреЗрд╕реНрдЯ рдХрд┐рдВрд╡рд╛ рдкреЛрд▓рд╛рд░рд┐рд╕.

3.рдХреЙрдиреНрдлрд┐рдЧ-рд▓рд┐рдВрдЯ

рдХреЙрдиреНрдлрд┐рдЧ-рд▓рд┐рдВрдЯ рд╣реЗ YAML, JSON, Terraform, CSV рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рди рдлрд╛рдЗрд▓реНрд╕ рдЖрдгрд┐ Kubernetes рдореЕрдирд┐рдлреЗрд╕реНрдЯрдЪреЗ рдкреНрд░рдорд╛рдгреАрдХрд░рдг рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдПрдХ рд╕рд╛рдзрди рдЖрд╣реЗ.

рд╡рд╛рдкрд░реВрди рд╕реНрдерд╛рдкрд┐рдд рдХрд░реВ рд╢рдХрддрд╛ рд╕реВрдЪрдирд╛ рдкреНрд░рдХрд▓реНрдк рд╡реЗрдмрд╕рд╛рдЗрдЯрд╡рд░.

рдореВрд│ рд▓реЗрдЦ рд▓рд┐рд╣рд┐рдгреНрдпрд╛рдЪреНрдпрд╛ рд╡реЗрд│реЗрдиреБрд╕рд╛рд░ рд╡рд░реНрддрдорд╛рди рдкреНрд░рдХрд╛рд╢рди 1.5.0 рдЖрд╣реЗ.

Config-lint рдордзреНрдпреЗ Kubernetes manifests рдкреНрд░рдорд╛рдгрд┐рдд рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдЕрдВрдЧрднреВрдд рдЪрд╛рдЪрдгреНрдпрд╛ рдирд╛рд╣реАрдд.

рдХреЛрдгрддреНрдпрд╛рд╣реА рдЪрд╛рдЪрдгреНрдпрд╛ рдЖрдпреЛрдЬрд┐рдд рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА, рдЖрдкрд▓реНрдпрд╛рд▓рд╛ рдпреЛрдЧреНрдп рдирд┐рдпрдо рддрдпрд╛рд░ рдХрд░рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ. рддреЗ "рдирд┐рдпрдорд╕реЗрдЯ" рдирд╛рд╡рд╛рдЪреНрдпрд╛ YAML рдлрд╛рдпрд▓реАрдВрдордзреНрдпреЗ рд▓рд┐рд╣рд┐рд▓реЗрд▓реЗ рдЖрд╣реЗрдд (рдирд┐рдпрдорд╕рдВрдЪ), рдЖрдгрд┐ рдЦрд╛рд▓реАрд▓ рд░рдЪрдирд╛ рдЖрд╣реЗ:

version: 1
description: Rules for Kubernetes spec files
type: Kubernetes
files:
  - "*.yaml"
rules:
   # ╤Б╨┐╨╕╤Б╨╛╨║ ╨┐╤А╨░╨▓╨╕╨╗

(rule.yaml)

рдЪрд▓рд╛ рдпрд╛рдЪрд╛ рдЕрдзрд┐рдХ рдмрд╛рд░рдХрд╛рдИрдиреЗ рдЕрднреНрдпрд╛рд╕ рдХрд░реВрдпрд╛:

  • рдлреАрд▓реНрдб type config-lint рдХреЛрдгрддреНрдпрд╛ рдкреНрд░рдХрд╛рд░рдЪреЗ рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рди рд╡рд╛рдкрд░реЗрд▓ рддреЗ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддреЗ. K8s рд╕рд╛рдареА рд╣реЗ рдкреНрд░рдХрдЯ рд╣реЛрддреЗ рдиреЗрд╣рдореА Kubernetes.
  • рдХреНрд╖реЗрддреНрд░рд╛рдд files рдлрд╛рдпрд▓реАрдВрд╡реНрдпрддрд┐рд░рд┐рдХреНрдд, рдЖрдкрдг рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░реВ рд╢рдХрддрд╛.
  • рдлреАрд▓реНрдб rules рд╡рд╛рдкрд░рдХрд░реНрддрд╛ рдЪрд╛рдЪрдгреНрдпрд╛ рд╕реЗрдЯ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рд╣реЗрддреВ.

рд╕рдордЬрд╛ рддреБрдореНрд╣рд╛рд▓рд╛ рдЦрд╛рддреНрд░реА рдХрд░рд╛рдпрдЪреА рдЖрд╣реЗ рдХреА рдбрд┐рдкреНрд▓реЙрдпрдореЗрдВрдЯрдордзреАрд▓ рдкреНрд░рддрд┐рдорд╛ рдиреЗрд╣рдореА рд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рднрд╛рдВрдбрд╛рд░рд╛рддреВрди рдбрд╛рдЙрдирд▓реЛрдб рдХреЗрд▓реНрдпрд╛ рдЬрд╛рддрд╛рдд рдЬрд╕реЗ рдХреА my-company.com/myapp:1.0. рдЕрд╢реА рддрдкрд╛рд╕рдгреА рдХрд░рдгрд╛рд░рд╛ рдХреЙрдиреНрдлрд┐рдЧ-рд▓рд┐рдВрдЯ рдирд┐рдпрдо рдЕрд╕реЗ рджрд┐рд╕реЗрд▓:

- 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
[]

рдХреЙрдиреНрдлрд┐рдЧ-рд▓рд┐рдВрдЯ рд╣реЗ рдПрдХ рдЖрд╢рд╛рджрд╛рдпрдХ рдлреНрд░реЗрдорд╡рд░реНрдХ рдЖрд╣реЗ рдЬреЗ рддреБрдореНрд╣рд╛рд▓рд╛ YAML DSL рд╡рд╛рдкрд░реВрди Kubernetes YAML рдореЕрдирд┐рдлреЗрд╕реНрдЯ рдкреНрд░рдорд╛рдгрд┐рдд рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рддреБрдордЪреНрдпрд╛ рд╕реНрд╡рддрдГрдЪреНрдпрд╛ рдЪрд╛рдЪрдгреНрдпрд╛ рддрдпрд╛рд░ рдХрд░рдгреНрдпрд╛рд╕ рдЕрдиреБрдорддреА рджреЗрддреЗ.

рдкрд░рдВрддреБ рдЖрдкрд▓реНрдпрд╛рд▓рд╛ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рддрд░реНрдХрд╢рд╛рд╕реНрддреНрд░ рдЖрдгрд┐ рдЪрд╛рдЪрдгреНрдпрд╛рдВрдЪреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдЕрд╕рд▓реНрдпрд╛рд╕ рдХрд╛рдп? YAML рдЗрддрдХреЗрдЪ рдорд░реНрдпрд╛рджрд┐рдд рдирд╛рд╣реА рдХрд╛? рддреБрдореНрд╣реА рдкреВрд░реНрдг рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖реЗрдд рдЪрд╛рдЪрдгреНрдпрд╛ рддрдпрд╛рд░ рдХрд░реВ рд╢рдХрдд рдЕрд╕рд╛рд▓ рддрд░?

4. рддрд╛рдВрдмреЗ

рддрд╛рдВрдмреЗ V2 рд╕рд╛рдиреБрдХреВрд▓ рдЪрд╛рдЪрдгреНрдпрд╛ (рдХреЙрдиреНрдлрд┐рдЧ-рд▓рд┐рдВрдЯ рдкреНрд░рдорд╛рдгреЗ) рд╡рд╛рдкрд░реВрди рдореЕрдирд┐рдлреЗрд╕реНрдЯ рдкреНрд░рдорд╛рдгрд┐рдд рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдлреНрд░реЗрдорд╡рд░реНрдХ рдЖрд╣реЗ.

рддрдерд╛рдкрд┐, рддреЗ рдЪрд╛рдЪрдгреНрдпрд╛рдВрдЪреЗ рд╡рд░реНрдгрди рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА YAML рд╡рд╛рдкрд░рдд рдирд╕рд▓реНрдпрд╛рдореБрд│реЗ рдирдВрддрд░рдЪреНрдпрд╛рдкреЗрдХреНрд╖рд╛ рд╡реЗрдЧрд│реЗ рдЖрд╣реЗ. рддреНрдпрд╛рдРрд╡рдЬреА рдЪрд╛рдЪрдгреНрдпрд╛ JavaScript рдордзреНрдпреЗ рд▓рд┐рд╣рд┐рд▓реНрдпрд╛ рдЬрд╛рдК рд╢рдХрддрд╛рдд. рдХреЙрдкрд░ рдЕрдиреЗрдХ рдореВрд▓рднреВрдд рд╕рд╛рдзрдирд╛рдВрд╕рд╣ рд▓рд╛рдпрдмреНрд░рд░реА рдкреНрд░рджрд╛рди рдХрд░рддреЗ, рдЬреЗ рддреБрдореНрд╣рд╛рд▓рд╛ Kubernetes рд╡рд╕реНрддреВрдВрдмрджреНрджрд▓ рдорд╛рд╣рд┐рддреА рд╡рд╛рдЪрдгреНрдпрд╛рдд рдЖрдгрд┐ рддреНрд░реБрдЯреАрдВрдЪреА рддрдХреНрд░рд╛рд░ рдХрд░рдгреНрдпрд╛рд╕ рдорджрдд рдХрд░рддрд╛рдд.

рдХреЙрдкрд░ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдгреНрдпрд╛рдЪреНрдпрд╛ рдЪрд░рдгрд╛рдВрдордзреНрдпреЗ рдЖрдврд│реВ рд╢рдХрддреЗ рдЕрдзрд┐рдХреГрдд рджрд╕реНрддрдРрд╡рдЬреАрдХрд░рдг.

2.0.1 рд╣реЗ рдореВрд│ рд▓реЗрдЦ рд▓рд┐рд╣рд┐рдгреНрдпрд╛рдЪреНрдпрд╛ рд╡реЗрд│реА рдпрд╛ рдЙрдкрдпреБрдХреНрддрддреЗрдЪреЗ рдирд╡реАрдирддрдо рдкреНрд░рдХрд╛рд╢рди рдЖрд╣реЗ.

рдХреЙрдиреНрдлрд┐рдЧ-рд▓рд┐рдВрдЯ рдкреНрд░рдорд╛рдгреЗ, рдХреЙрдкрд░рдордзреНрдпреЗ рдЕрдВрдЧрднреВрдд рдЪрд╛рдЪрдгреНрдпрд╛ рдирд╛рд╣реАрдд. рдЪрд▓рд╛ рдПрдХ рд▓рд┐рд╣реВрдпрд╛. рдбрд┐рдкреНрд▓реЙрдпрдореЗрдВрдЯреНрд╕ рдХреЗрд╡рд│ рд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рд░рд┐рдкреЙрдЭрд┐рдЯрд░реАрдЬрдордзреВрди рдХрдВрдЯреЗрдирд░ рдкреНрд░рддрд┐рдорд╛ рд╡рд╛рдкрд░рддрд╛рдд рд╣реЗ рддрдкрд╛рд╕реВ рджреНрдпрд╛ 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

рд╣реЗ рд╕реНрдкрд╖реНрдЯ рдЖрд╣реЗ рдХреА рддрд╛рдВрдмреНрдпрд╛рдЪреНрдпрд╛ рдорджрддреАрдиреЗ рдЖрдкрдг рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рдЪрд╛рдЪрдгреНрдпрд╛ рдХрд░реВ рд╢рдХрддрд╛ - рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдЗрдВрдЧреНрд░реЗрд╕ рдореЕрдирд┐рдлреЗрд╕реНрдЯрдордзреНрдпреЗ рдбреЛрдореЗрди рдирд╛рд╡реЗ рддрдкрд╛рд╕рдгреЗ рдХрд┐рдВрд╡рд╛ рд╡рд┐рд╢реЗрд╖рд╛рдзрд┐рдХрд╛рд░ рдореЛрдбрдордзреНрдпреЗ рдЪрд╛рд▓рдгрд╛рд░реЗ рдкреЙрдб рдирд╛рдХрд╛рд░рдгреЗ.

рдХреЙрдкрд░рдордзреНрдпреЗ рд╡рд┐рд╡рд┐рдз рдЙрдкрдпреБрдХреНрддрддрд╛ рдХрд╛рд░реНрдпреЗ рдЕрдВрдЧрднреВрдд рдЖрд╣реЗрдд:

  • DockerImage рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЗрдирдкреБрдЯ рдлрд╛рдЗрд▓ рд╡рд╛рдЪрддреЗ рдЖрдгрд┐ рдЦрд╛рд▓реАрд▓ рдЧреБрдгрдзрд░реНрдорд╛рдВрд╕рд╣ рдПрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рддрдпрд╛рд░ рдХрд░рддреЗ:
    • name - рдкреНрд░рддрд┐рдореЗрдЪреЗ рдирд╛рд╡,
    • tag - рдкреНрд░рддрд┐рдорд╛ рдЯреЕрдЧ,
    • registry - рдкреНрд░рддрд┐рдорд╛ рдиреЛрдВрджрдгреА,
    • registry_url - рдкреНрд░реЛрдЯреЛрдХреЙрд▓ (https://) рдЖрдгрд┐ рдкреНрд░рддрд┐рдорд╛ рдиреЛрдВрджрдгреА,
    • fqin - рдкреНрд░рддрд┐рдореЗрдЪреЗ рд╕рдВрдкреВрд░реНрдг рд╕реНрдерд╛рди.
  • рдХрд╛рд░реНрдп findByName рджрд┐рд▓реЗрд▓реНрдпрд╛ рдкреНрд░рдХрд╛рд░рд╛рдиреБрд╕рд╛рд░ рд╕рдВрд╕рд╛рдзрди рд╢реЛрдзрдгреНрдпрд╛рдд рдорджрдд рдХрд░рддреЗ (kind) рдЖрдгрд┐ рдирд╛рд╡ (name) рдЗрдирдкреБрдЯ рдлрд╛рдЗрд▓рдордзреВрди.
  • рдХрд╛рд░реНрдп findByLabels рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдкреНрд░рдХрд╛рд░рд╛рджреНрд╡рд╛рд░реЗ рд╕рдВрд╕рд╛рдзрди рд╢реЛрдзрдгреНрдпрд╛рдд рдорджрдд рдХрд░рддреЗ (kind) рдЖрдгрд┐ рд▓реЗрдмрд▓реЗ (labels).

рддреБрдореНрд╣реА рд╕рд░реНрд╡ рдЙрдкрд▓рдмреНрдз рд╕реЗрд╡рд╛ рдХрд╛рд░реНрдпреЗ рдкрд╛рд╣реВ рд╢рдХрддрд╛ рдпреЗрдереЗ.

рдбреАрдлреЙрд▓реНрдЯрдиреБрд╕рд╛рд░ рддреЗ рд╕рдВрдкреВрд░реНрдг рдЗрдирдкреБрдЯ YAML рдлрд╛рдЗрд▓ рд╡реНрд╣реЗрд░рд┐рдПрдмрд▓рдордзреНрдпреЗ рд▓реЛрдб рдХрд░рддреЗ $$ рдЖрдгрд┐ рддреЗ рд╕реНрдХреНрд░рд┐рдкреНрдЯрд┐рдВрдЧрд╕рд╛рдареА рдЙрдкрд▓рдмреНрдз рдХрд░реВрди рджреЗрддреЗ (jQuery рдЕрдиреБрднрд╡ рдЕрд╕рд▓реЗрд▓реНрдпрд╛рдВрд╕рд╛рдареА рдПрдХ рдкрд░рд┐рдЪрд┐рдд рддрдВрддреНрд░).

рдХреЙрдкрд░рдЪрд╛ рдореБрдЦреНрдп рдлрд╛рдпрджрд╛ рд╕реНрдкрд╖реНрдЯ рдЖрд╣реЗ: рддреБрдореНрд╣рд╛рд▓рд╛ рд╡рд┐рд╢рд┐рд╖реНрдЯ рднрд╛рд╖реЗрд╡рд░ рдкреНрд░рднреБрддреНрд╡ рдорд┐рд│рд╡рдгреНрдпрд╛рдЪреА рдЧрд░рдЬ рдирд╛рд╣реА рдЖрдгрд┐ рддреБрдореНрд╣реА рддреБрдордЪреНрдпрд╛ рд╕реНрд╡рддрдГрдЪреНрдпрд╛ рдЪрд╛рдЪрдгреНрдпрд╛ рддрдпрд╛рд░ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рд╡рд┐рд╡рд┐рдз JavaScript рд╡реИрд╢рд┐рд╖реНрдЯреНрдпреЗ рд╡рд╛рдкрд░реВ рд╢рдХрддрд╛, рдЬрд╕реЗ рдХреА рд╕реНрдЯреНрд░рд┐рдВрдЧ рдЗрдВрдЯрд░рдкреЛрд▓реЗрд╢рди, рдлрдВрдХреНрд╢рдиреНрд╕ рдЗ.

рд╣реЗ рджреЗрдЦреАрд▓ рд▓рдХреНрд╖рд╛рдд рдШреНрдпрд╛рд╡реЗ рдХреА рдХреЙрдкрд░рдЪреА рд╡рд░реНрддрдорд╛рди рдЖрд╡реГрддреНрддреА JavaScript рдЗрдВрдЬрд┐рдирдЪреНрдпрд╛ ES5 рдЖрд╡реГрддреНрддреАрд╕рд╣ рдХрд╛рд░реНрдп рдХрд░рддреЗ, ES6 рдирд╛рд╣реА.

рдпреЗрдереЗ рддрдкрд╢реАрд▓ рдЙрдкрд▓рдмреНрдз рдЖрд╣реЗрдд рдЕрдзрд┐рдХреГрдд рдкреНрд░рдХрд▓реНрдк рд╡реЗрдмрд╕рд╛рдЗрдЯ.

рддрдерд╛рдкрд┐, рдЬрд░ рддреБрдореНрд╣рд╛рд▓рд╛ рдЦрд░реЛрдЦрд░ JavaScript рдЖрд╡рдбрдд рдирд╕реЗрд▓ рдЖрдгрд┐ рд╡рд┐рд╢реЗрд╖рдд: рдХреНрд╡реЗрд░реА рддрдпрд╛рд░ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдЖрдгрд┐ рдзреЛрд░рдгрд╛рдВрдЪреЗ рд╡рд░реНрдгрди рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдбрд┐рдЭрд╛рдЗрди рдХреЗрд▓реЗрд▓реА рднрд╛рд╖рд╛ рдкрд╕рдВрдд рдХрд░рдд рдЕрд╕рд╛рд▓, рддрд░ рддреБрдореНрд╣реА рдХреЙрдиреНрдЯреЗрд╕реНрдЯрдХрдбреЗ рд▓рдХреНрд╖ рджрд┐рд▓реЗ рдкрд╛рд╣рд┐рдЬреЗ.

5.рдХреЙрдиреНрдлреЗрд╕реНрдЯ

рдХреЙрдиреНрдлрдЯреЗрд╕реНрдЯ рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рди рдбреЗрдЯрд╛рдЪреНрдпрд╛ рдЪрд╛рдЪрдгреАрд╕рд╛рдареА рдПрдХ рдлреНрд░реЗрдорд╡рд░реНрдХ рдЖрд╣реЗ. Kubernetes рдореЕрдирд┐рдлреЗрд╕реНрдЯрдЪреА рдЪрд╛рдЪрдгреА/рдкрдбрддрд╛рд│рдгреА рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рджреЗрдЦреАрд▓ рдпреЛрдЧреНрдп. рд╡рд┐рд╢реЗрд╖ рдХреНрд╡реЗрд░реА рднрд╛рд╖рд╛ рд╡рд╛рдкрд░реВрди рдЪрд╛рдЪрдгреНрдпрд╛рдВрдЪреЗ рд╡рд░реНрдгрди рдХреЗрд▓реЗ рдЬрд╛рддреЗ рд░реЗрдЧреЛ.

рдЖрдкрдг рд╡рд╛рдкрд░реВрди conftest рд╕реНрдерд╛рдкрд┐рдд рдХрд░реВ рд╢рдХрддрд╛ рд╕реВрдЪрдирд╛рдкреНрд░рдХрд▓реНрдк рд╡реЗрдмрд╕рд╛рдЗрдЯрд╡рд░ рд╕реВрдЪреАрдмрджреНрдз.

рдореВрд│ рд▓реЗрдЦ рд▓рд┐рд╣рд┐рдгреНрдпрд╛рдЪреНрдпрд╛ рд╡реЗрд│реА, рдирд╡реАрдирддрдо рдЖрд╡реГрддреНрддреА 0.18.2 рдЙрдкрд▓рдмреНрдз рд╣реЛрддреА.

рдХреЙрдиреНрдлрд┐рдЧ-рд▓рд┐рдВрдЯ рдЖрдгрд┐ рдХреЙрдкрд░ рдкреНрд░рдорд╛рдгреЗрдЪ, рдХреЙрдиреНрдлреЗрд╕реНрдЯ рдХреЛрдгрддреНрдпрд╛рд╣реА рдЕрдВрдЧрднреВрдд рдЪрд╛рдЪрдгреНрдпрд╛рдВрд╢рд┐рд╡рд╛рдп рдпреЗрддреЗ. рдЪрд▓рд╛ рддреЗ рд╡рд╛рдкрд░реВрди рдкрд╛рд╣реВ рдЖрдгрд┐ рд╕реНрд╡рддрдГрдЪреЗ рдзреЛрд░рдг рд▓рд┐рд╣реВ. рдорд╛рдЧреАрд▓ рдЙрджрд╛рд╣рд░рдгрд╛рдВрдкреНрд░рдорд╛рдгреЗ, рдЖрдореНрд╣реА рдХрдВрдЯреЗрдирд░ рдкреНрд░рддрд┐рдорд╛ рд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рд╕реНрддреНрд░реЛрддрд╛рдХрдбреВрди рдШреЗрддрд▓реНрдпрд╛ рдЖрд╣реЗрдд рдХреА рдирд╛рд╣реА рддреЗ рддрдкрд╛рд╕реВ.

рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рддрдпрд╛рд░ рдХрд░рд╛ 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

рдЪрд╛рдЪрдгреА рдЕрдпрд╢рд╕реНрд╡реА рдард░рд▓реА рдХрд╛рд░рдг рдкреНрд░рддрд┐рдорд╛ рдЕрд╡рд┐рд╢реНрд╡рд╛рд╕реВ рд╕реНрддреНрд░реЛрддрд╛рдХрдбреВрди рдЖрд▓реНрдпрд╛ рдЖрд╣реЗрдд.

рд░реЗрдЧреЛ рдлрд╛рдЗрд▓рдордзреНрдпреЗ рдЖрдореНрд╣реА рдмреНрд▓реЙрдХ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЛ deny. рддреНрдпрд╛рдЪреЗ рд╕рддреНрдп рдЙрд▓реНрд▓рдВрдШрди рдорд╛рдирд▓реЗ рдЬрд╛рддреЗ. рдЕрд╡рд░реЛрдз рдЕрд╕рд▓реНрдпрд╛рд╕ deny рдЕрдиреЗрдХ, рдХреЙрдиреНрдЯреЗрд╕реНрдЯ рддреНрдпрд╛рдВрдирд╛ рдПрдХрдореЗрдХрд╛рдВрдкрд╛рд╕реВрди рд╕реНрд╡рддрдВрддреНрд░рдкрдгреЗ рддрдкрд╛рд╕рддрд╛рдд рдЖрдгрд┐ рдХреЛрдгрддреНрдпрд╛рд╣реА рдмреНрд▓реЙрдХрдЪреЗ рд╕рддреНрдп рдЙрд▓реНрд▓рдВрдШрди рдорд╛рдирд▓реЗ рдЬрд╛рддреЗ.

рдбреАрдлреЙрд▓реНрдЯ рдЖрдЙрдЯрдкреБрдЯ рд╡реНрдпрддрд┐рд░рд┐рдХреНрдд, рдХреЙрдиреНрдлрдЯреЗрд╕реНрдЯ JSON, TAP рдЖрдгрд┐ рдЯреЗрдмрд▓ рдлреЙрд░рдореЕрдЯрд▓рд╛ рд╕рдкреЛрд░реНрдЯ рдХрд░рддреЗ - рдЬрд░ рддреБрдореНрд╣рд╛рд▓рд╛ рд╡рд┐рджреНрдпрдорд╛рди CI рдкрд╛рдЗрдкрд▓рд╛рдЗрдирдордзреНрдпреЗ рд░рд┐рдкреЛрд░реНрдЯ рдПрдореНрдмреЗрдб рдХрд░рд╛рдпрдЪрд╛ рдЕрд╕реЗрд▓ рддрд░ рдПрдХ рдЕрддреНрдпрдВрдд рдЙрдкрдпреБрдХреНрдд рд╡реИрд╢рд┐рд╖реНрдЯреНрдп. рдЖрдкрдг рдзреНрд╡рдЬ рд╡рд╛рдкрд░реВрди рдЗрдЪреНрдЫрд┐рдд рд╕реНрд╡рд░реВрдк рд╕реЗрдЯ рдХрд░реВ рд╢рдХрддрд╛ --output.

рдзреЛрд░рдгреЗ рдбреАрдмрдЧ рдХрд░рдгреЗ рд╕реЛрдкреЗ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА, confest рд▓рд╛ рдзреНрд╡рдЬ рдЖрд╣реЗ --trace. рдХреЙрдиреНрдЯреЗрд╕реНрдЯ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдкреЙрд▓рд┐рд╕реА рдлрд╛рдЗрд▓реНрд╕рдЪреЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд╕реЗ рдХрд░рддреЗ рдпрд╛рдЪрд╛ рдЯреНрд░реЗрд╕ рдЖрдЙрдЯрдкреБрдЯ рдХрд░рддреЗ.

рд╕реНрдкрд░реНрдзрд╛ рдзреЛрд░рдгреЗ рдкреНрд░рдХрд╛рд╢рд┐рдд рдХреЗрд▓реА рдЬрд╛рдК рд╢рдХрддрд╛рдд рдЖрдгрд┐ OCI (рдУрдкрди рдХрдВрдЯреЗрдирд░ рдЗрдирд┐рд╢рд┐рдПрдЯрд┐рд╡реНрд╣) рдиреЛрдВрджрдгреАрдордзреНрдпреЗ рдХрд▓рд╛рдХреГрддреА рдореНрд╣рдгреВрди рд╕рд╛рдорд╛рдпрд┐рдХ рдХреЗрд▓реА рдЬрд╛рдК рд╢рдХрддрд╛рдд.

рдЯреАрдореНрд╕ push ╨╕ pull рддреБрдореНрд╣рд╛рд▓рд╛ рдЖрд░реНрдЯрд┐рдлреЕрдХреНрдЯ рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд░рдгреНрдпрд╛рд╕ рдХрд┐рдВрд╡рд╛ рд░рд┐рдореЛрдЯ рд░реЗрдЬрд┐рд╕реНрдЯреНрд░реАрдордзреВрди рд╡рд┐рджреНрдпрдорд╛рди рдЖрд░реНрдЯрд┐рдлреЕрдХреНрдЯ рдкреБрдирд░реНрдкреНрд░рд╛рдкреНрдд рдХрд░рдгреНрдпрд╛рдЪреА рдЕрдиреБрдорддреА рджреЗрддреЗ. рдЖрдореНрд╣реА рд╕реНрдерд╛рдирд┐рдХ рдбреЙрдХрд░ рд░реЗрдЬрд┐рд╕реНрдЯреНрд░реА рд╡рд╛рдкрд░реВрди рддрдпрд╛рд░ рдХреЗрд▓реЗрд▓реЗ рдзреЛрд░рдг рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд░рдгреНрдпрд╛рдЪрд╛ рдкреНрд░рдпрддреНрди рдХрд░реВрдпрд╛ conftest push.

рддреБрдордЪреА рд╕реНрдерд╛рдирд┐рдХ рдбреЙрдХрд░ рд░реЗрдЬрд┐рд╕реНрдЯреНрд░реА рд╕реБрд░реВ рдХрд░рд╛:

$ 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

рджреБрд░реНрджреИрд╡рд╛рдиреЗ, рдбреЙрдХрд░рд╣рдм рдЕрджреНрдпрд╛рдк рд╕рдорд░реНрдерд┐рдд рдирд╛рд╣реА. рддреНрдпрд╛рдореБрд│реЗ рддреБрдореНрд╣реА рд╡рд╛рдкрд░рдд рдЕрд╕рд╛рд▓ рддрд░ рд╕реНрд╡рддрдГрд▓рд╛ рднрд╛рдЧреНрдпрд╡рд╛рди рд╕рдордЬрд╛ Azure рдХрдВрдЯреЗрдирд░ рдиреЛрдВрджрдгреА (ACR) рдХрд┐рдВрд╡рд╛ рддреБрдордЪреА рд╕реНрд╡рддрдГрдЪреА рдиреЛрдВрджрдгреА.

рдЖрд░реНрдЯрд┐рдлреЕрдХреНрдЯ рдлреЙрд░рдореЕрдЯ рд╕рд╛рд░рдЦреЗрдЪ рдЖрд╣реЗ рдкреЙрд▓рд┐рд╕реА рдПрдЬрдВрдЯ рдкреЕрдХреЗрдЬ рдЙрдШрдбрд╛ (OPA), рдЬреЗ рддреБрдореНрд╣рд╛рд▓рд╛ рд╡рд┐рджреНрдпрдорд╛рди OPA рдкреЕрдХреЗрдЬреЗрд╕рдордзреВрди рдЪрд╛рдЪрдгреНрдпрд╛ рдЪрд╛рд▓рд╡рдгреНрдпрд╛рд╕рд╛рдареА рдХреЙрдиреНрдЯреЗрд╕реНрдЯ рд╡рд╛рдкрд░рдгреНрдпрд╛рдЪреА рдкрд░рд╡рд╛рдирдЧреА рджреЗрддреЗ.

рддреБрдореНрд╣реА рдпреЗрдереЗ рдкреЙрд▓рд┐рд╕реА рд╢реЗрдЕрд░рд┐рдВрдЧ рдЖрдгрд┐ рдХреЙрдиреНрдЯреЗрд╕реНрдЯрдЪреНрдпрд╛ рдЗрддрд░ рд╡реИрд╢рд┐рд╖реНрдЯреНрдпрд╛рдВрдмрджреНрджрд▓ рдЕрдзрд┐рдХ рдЬрд╛рдгреВрди рдШреЗрдК рд╢рдХрддрд╛ рдЕрдзрд┐рдХреГрдд рдкреНрд░рдХрд▓реНрдк рд╡реЗрдмрд╕рд╛рдЗрдЯ.

6. рдкреЛрд▓рд╛рд░рд┐рд╕

рдпрд╛ рд▓реЗрдЦрд╛рдд рдЪрд░реНрдЪрд╛ рдХреЗрд▓реА рдЬрд╛рдИрд▓ рдХреА рд╢реЗрд╡рдЯрдЪреЗ рд╕рд╛рдзрди рдЖрд╣реЗ рдкреЛрд▓рд╛рд░рд┐рд╕. (рддреНрдпрд╛рдЪреА рдЧреЗрд▓реНрдпрд╛ рд╡рд░реНрд╖реАрдЪреА рдШреЛрд╖рдгрд╛ рдЖрдореНрд╣реА рдЖрдзреАрдЪ рдЕрдиреБрд╡рд╛рджрд┐рдд - рдЕрдВрджрд╛рдЬреЗ рднрд╛рд╖рд╛рдВрддрд░)

рдкреЛрд▓рд╛рд░рд┐рд╕ рдХреНрд▓рд╕реНрдЯрд░рдордзреНрдпреЗ рд╕реНрдерд╛рдкрд┐рдд рдХреЗрд▓реЗ рдЬрд╛рдК рд╢рдХрддреЗ рдХрд┐рдВрд╡рд╛ рдХрдорд╛рдВрдб рд▓рд╛рдЗрди рдореЛрдбрдордзреНрдпреЗ рд╡рд╛рдкрд░рд▓реЗ рдЬрд╛рдК рд╢рдХрддреЗ. рдЬрд╕реЗ рддреБрдореНрд╣реА рдЕрдВрджрд╛рдЬ рд▓рд╛рд╡рд▓рд╛ рдЕрд╕реЗрд▓, рддреЛ рддреБрдореНрд╣рд╛рд▓рд╛ рдХреБрдмрд░реНрдиреЗрдЯреНрд╕ рдореЕрдирд┐рдлреЗрд╕реНрдЯрдЪреЗ рд╕реНрдерд┐рд░ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рдгреНрдпрд╛рд╕ рдЕрдиреБрдорддреА рджреЗрддреЛ.

рдХрдорд╛рдВрдб рд▓рд╛рдЗрди рдореЛрдбрдордзреНрдпреЗ рдЪрд╛рд▓рдд рдЕрд╕рддрд╛рдирд╛, рдмрд┐рд▓реНрдЯ-рдЗрди рдЪрд╛рдЪрдгреНрдпрд╛ рд╕реБрд░рдХреНрд╖рд┐рддрддрд╛ рдЖрдгрд┐ рд╕рд░реНрд╡реЛрддреНрддрдо рдкрджреНрдзрддреА (рдХреБрдмреЗ-рд╕реНрдХреЛрдЕрд░ рдкреНрд░рдорд╛рдгреЗ) рдпрд╛рд╕рд╛рд░рдЦреНрдпрд╛ рдХреНрд╖реЗрддреНрд░рд╛рдВрдирд╛ рдХрд╡реНрд╣рд░ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдЙрдкрд▓рдмреНрдз рдЕрд╕рддрд╛рдд. рдпрд╛рд╡реНрдпрддрд┐рд░рд┐рдХреНрдд, рддреБрдореНрд╣реА рддреБрдордЪреНрдпрд╛ рд╕реНрд╡рддрдГрдЪреНрдпрд╛ рдЪрд╛рдЪрдгреНрдпрд╛ рддрдпрд╛рд░ рдХрд░реВ рд╢рдХрддрд╛ (рдХреЙрдиреНрдлрд┐рдЧ-рд▓рд┐рдВрдЯ, рдХреЙрдкрд░ рдЖрдгрд┐ рдХреЙрдиреНрдлреЗрд╕реНрдЯ рдкреНрд░рдорд╛рдгреЗ).

рджреБрд╕рд▒реНрдпрд╛ рд╢рдмреНрджрд╛рдВрдд, рдкреЛрд▓рд╛рд░рд┐рд╕ рджреЛрдиреНрд╣реА рд╢реНрд░реЗрдгреАрдВрдЪреНрдпрд╛ рд╕рд╛рдзрдирд╛рдВрдЪреЗ рдлрд╛рдпрджреЗ рдПрдХрддреНрд░ рдХрд░рддреЗ: рдЕрдВрдЧрднреВрдд рдЖрдгрд┐ рд╕рд╛рдиреБрдХреВрд▓ рдЪрд╛рдЪрдгреНрдпрд╛рдВрд╕рд╣.

рдХрдорд╛рдВрдб рд▓рд╛рдЗрди рдореЛрдбрдордзреНрдпреЗ рдкреЛрд▓рд╛рд░рд┐рд╕ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА, рд╡рд╛рдкрд░рд╛ рдкреНрд░рдХрд▓реНрдк рд╡реЗрдмрд╕рд╛рдЗрдЯрд╡рд░ рд╕реВрдЪрдирд╛.

рдореВрд│ рд▓реЗрдЦ рд▓рд┐рд╣рд┐рдгреНрдпрд╛рдЪреНрдпрд╛ рд╡реЗрд│реА, рдЖрд╡реГрддреНрддреА 1.0.3 рдЙрдкрд▓рдмреНрдз рдЖрд╣реЗ.

рдПрдХрджрд╛ рдЗрдВрд╕реНрдЯреЙрд▓реЗрд╢рди рдкреВрд░реНрдг рдЭрд╛рд▓реНрдпрд╛рд╡рд░ рддреБрдореНрд╣реА рдореЕрдирд┐рдлреЗрд╕реНрдЯрд╡рд░ рдкреЛрд▓рд╛рд░рд┐рд╕ рдЪрд╛рд▓рд╡реВ рд╢рдХрддрд╛ 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": [
    /* ╨┤╨╗╨╕╨╜╨╜╤Л╨╣ ╤Б╨┐╨╕╤Б╨╛╨║ */
  ]
}

рдкреВрд░реНрдг рдЖрдЙрдЯрдкреБрдЯ рдЙрдкрд▓рдмреНрдз рдпреЗрдереЗ.

рдХреНрдпреВрдмреЗ-рд╕реНрдХреЛрдЕрд░ рдкреНрд░рдорд╛рдгреЗ, рдкреЛрд▓рд╛рд░рд┐рд╕ рдЕрд╢рд╛ рдХреНрд╖реЗрддреНрд░рд╛рддреАрд▓ рд╕рдорд╕реНрдпрд╛ рдУрд│рдЦрддреЛ рдЬреЗрдереЗ рдореЕрдирд┐рдлреЗрд╕реНрдЯ рд╕рд░реНрд╡реЛрддреНрддрдо рдкрджреНрдзрддреА рдкреВрд░реНрдг рдХрд░рдд рдирд╛рд╣реА:

  • рд╢реЗрдВрдЧрд╛рдВрдЪреА рдЖрд░реЛрдЧреНрдп рддрдкрд╛рд╕рдгреА рд╣реЛрдд рдирд╛рд╣реА.
  • рдХрдВрдЯреЗрдирд░ рдкреНрд░рддрд┐рдорд╛рдВрд╕рд╛рдареА рдЯреЕрдЧ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХреЗрд▓реЗрд▓реЗ рдирд╛рд╣реАрдд.
  • рдХрдВрдЯреЗрдирд░ рд░реВрдЯ рдореНрд╣рдгреВрди рдЪрд╛рд▓рддреЗ.
  • рдореЗрдорд░реА рдЖрдгрд┐ CPU рд╕рд╛рдареА рд╡рд┐рдирдВрддреНрдпрд╛ рдЖрдгрд┐ рдорд░реНрдпрд╛рджрд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдирд╛рд╣реАрдд.

рдкреНрд░рддреНрдпреЗрдХ рдЪрд╛рдЪрдгреА, рддреНрдпрд╛рдЪреНрдпрд╛ рдкрд░рд┐рдгрд╛рдорд╛рдВрд╡рд░ рдЕрд╡рд▓рдВрдмреВрди, рдЧрдВрднреАрд░рддреЗрдЪреА рдбрд┐рдЧреНрд░реА рдирд┐рдпреБрдХреНрдд рдХреЗрд▓реА рдЬрд╛рддреЗ: рдЪреЗрддрд╛рд╡рдгреА рдХрд┐рдВрд╡рд╛ рдзреЛрдХрд╛. рдЙрдкрд▓рдмреНрдз рдЕрдВрдЧрднреВрдд рдЪрд╛рдЪрдгреНрдпрд╛рдВрдмрджреНрджрд▓ рдЕрдзрд┐рдХ рдЬрд╛рдгреВрди рдШреЗрдгреНрдпрд╛рд╕рд╛рдареА, рдХреГрдкрдпрд╛ рдкрд╣рд╛ рджрд╕реНрддрдРрд╡рдЬреАрдХрд░рдг.

рддрдкрд╢реАрд▓ рдЖрд╡рд╢реНрдпрдХ рдирд╕рд▓реНрдпрд╛рд╕, рдЖрдкрдг рдзреНрд╡рдЬ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░реВ рд╢рдХрддрд╛ --format score. рдпрд╛ рдкреНрд░рдХрд░рдгрд╛рдд, рдкреЛрд▓рд╛рд░рд┐рд╕ 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 рдЖрд╡рд╢реНрдпрдХ рдЕрд╕рд▓реЗрд▓реНрдпрд╛ рдкреНрд░рддрд┐рдорд╛ рд╕реНрддреНрд░реЛрддрд╛рд╢реА рддреБрд▓рдирд╛ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рд╡рд╛рдкрд░рд▓реЗ рдЬрд╛рддреЗ.

рд╡рд░реАрд▓ рдЪрд╛рдЪрдгреА рдЪрд╛рд▓рд╡рдгреНрдпрд╛рд╕рд╛рдареА, рддреБрдореНрд╣рд╛рд▓рд╛ рдЦрд╛рд▓реАрд▓ рдкреЛрд▓рд╛рд░рд┐рд╕ рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рди рддрдпрд╛рд░ рдХрд░рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ:

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, рдкреЛрд▓рд╛рд░рд┐рд╕ рдпрд╢рд╕реНрд╡реАрд░рд┐рддреНрдпрд╛ рдкреВрд░реНрдг рд╣реЛрдИрд▓. рдмрджрд▓рд╛рдВрд╕рд╣ рдЬрд╛рд╣реАрд░рдирд╛рдорд╛ рдЖрдзреАрдЪ рдЖрдд рдЖрд╣реЗ рднрд╛рдВрдбрд╛рд░рддреНрдпрд╛рдореБрд│реЗ рддреБрдореНрд╣реА рдореЕрдирд┐рдлреЗрд╕реНрдЯрд╡рд░ рдорд╛рдЧреАрд▓ рдХрдорд╛рдВрдб рддрдкрд╛рд╕реВ рд╢рдХрддрд╛ 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

рдкреЛрд▓рд╛рд░рд┐рд╕ рд╕рд╛рдиреБрдХреВрд▓ рдЪрд╛рдЪрдгреНрдпрд╛рдВрд╕рд╣ рдЕрдВрдЧрднреВрдд рдЪрд╛рдЪрдгреНрдпрд╛рдВрдЪреА рдкреВрд░реНрддрддрд╛ рдХрд░рддреЗ, рдЬреНрдпрд╛рдореБрд│реЗ рджреЛрдиреНрд╣реА рдЬрдЧрд╛рддреАрд▓ рд╕рд░реНрд╡реЛрддреНрддрдо рдЧреЛрд╖реНрдЯреА рдПрдХрддреНрд░ рд╣реЛрддрд╛рдд.

рджреБрд╕рд░реАрдХрдбреЗ, Rego рдХрд┐рдВрд╡рд╛ JavaScript рд╕рд╛рд░рдЦреНрдпрд╛ рдЕрдзрд┐рдХ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рднрд╛рд╖рд╛ рд╡рд╛рдкрд░рдгреНрдпрд╛рд╕ рдЕрд╕рдорд░реНрдерддрд╛ рдЕрдзрд┐рдХ рдЕрддреНрдпрд╛рдзреБрдирд┐рдХ рдЪрд╛рдЪрдгреНрдпрд╛ рддрдпрд╛рд░ рдХрд░рдгреНрдпрд╛рд╕ рдкреНрд░рддрд┐рдмрдВрдз рдХрд░рдгрд╛рд░рд╛ рдПрдХ рдорд░реНрдпрд╛рджрд┐рдд рдШрдЯрдХ рдЕрд╕реВ рд╢рдХрддреЛ.

рдкреЛрд▓рд╛рд░рд┐рд╕ рдмрджреНрджрд▓ рдЕрдзрд┐рдХ рдорд╛рд╣рд┐рддреА рдпреЗрдереЗ рдЙрдкрд▓рдмреНрдз рдЖрд╣реЗ рдкреНрд░рдХрд▓реНрдк рд╡реЗрдмрд╕рд╛рдЗрдЯ.

рд╕рд╛рд░рд╛рдВрд╢

Kubernetes YAML рдлрд╛рдЗрд▓реНрд╕рдЪреА рддрдкрд╛рд╕рдгреА рдЖрдгрд┐ рдореВрд▓реНрдпрдорд╛рдкрди рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдЕрдиреЗрдХ рд╕рд╛рдзрдиреЗ рдЙрдкрд▓рдмреНрдз рдЕрд╕рддрд╛рдирд╛, рдЪрд╛рдЪрдгреНрдпрд╛рдВрдЪреА рд░рдЪрдирд╛ рдЖрдгрд┐ рдЕрдВрдорд▓рдмрдЬрд╛рд╡рдгреА рдХрд╢реА рдХреЗрд▓реА рдЬрд╛рдИрд▓ рдпрд╛рдЪреА рд╕реНрдкрд╖реНрдЯ рд╕рдордЬ рдЕрд╕рдгреЗ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ рдЖрд╣реЗ.

рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдЬрд░ рддреБрдореНрд╣реА рдкрд╛рдЗрдкрд▓рд╛рдЗрдирдордзреВрди рдЬрд╛рдгрд╛рд░реЗ рдХреБрдмреЗрд░рдиреЗрдЯреНрд╕ рдореЕрдирд┐рдлреЗрд╕реНрдЯ рдШреЗрддрд▓реЗ рддрд░ рдХреБрдмреЗрд╡рд▓ рд╣реА рдЕрд╢рд╛ рдкрд╛рдЗрдкрд▓рд╛рдЗрдирдЪреА рдкрд╣рд┐рд▓реА рдкрд╛рдпрд░реА рдЕрд╕реВ рд╢рдХрддреЗ.. рдСрдмреНрдЬреЗрдХреНрдЯ рд╡реНрдпрд╛рдЦреНрдпрд╛ Kubernetes API рд╕реНрдХреАрдорд╛рд╢реА рд╕реБрд╕рдВрдЧрдд рдЖрд╣реЗ рдХреА рдирд╛рд╣реА рдпрд╛рд╡рд░ рддреЗ рдирд┐рд░реАрдХреНрд╖рдг рдХрд░реЗрд▓.

рдПрдХрджрд╛ рдЕрд╕реЗ рдкреБрдирд░рд╛рд╡рд▓реЛрдХрди рдкреВрд░реНрдг рдЭрд╛рд▓реНрдпрд╛рдирдВрддрд░, рдПрдЦрд╛рджреА рд╡реНрдпрдХреНрддреА рдЕрдзрд┐рдХ рдЕрддреНрдпрд╛рдзреБрдирд┐рдХ рдЪрд╛рдЪрдгреНрдпрд╛рдВрдХрдбреЗ рдЬрд╛рдК рд╢рдХрддреЗ, рдЬрд╕реЗ рдХреА рдорд╛рдирдХ рд╕рд░реНрд╡реЛрддреНрддрдо рдкрджреНрдзрддреА рдЖрдгрд┐ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдзреЛрд░рдгрд╛рдВрдЪреЗ рдкрд╛рд▓рди. рдЗрдереЗрдЪ рдХреБрдмреЗ-рд╕реНрдХреЛрдЕрд░ рдЖрдгрд┐ рдкреЛрд▓рд╛рд░рд┐рд╕ рдЙрдкрдпреЛрдЧреА рдкрдбрддреАрд▓.

рдЬреНрдпрд╛рдВрдирд╛ рдЬрдЯрд┐рд▓ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдЖрд╣реЗрдд рдЖрдгрд┐ рддрдкрд╢реАрд▓рд╡рд╛рд░ рдЪрд╛рдЪрдгреНрдпрд╛ рд╕рд╛рдиреБрдХреВрд▓рд┐рдд рдХрд░рдгреНрдпрд╛рдЪреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдЖрд╣реЗ рддреНрдпрд╛рдВрдЪреНрдпрд╛рд╕рд╛рдареА, рддрд╛рдВрдмреЗ, рдХреЙрдиреНрдлрд┐рдЧ-рд▓рд┐рдВрдЯ рдЖрдгрд┐ рдХреЙрдиреНрдлреЗрд╕реНрдЯ рдпреЛрдЧреНрдп рдЕрд╕рддреАрд▓..

рдХреЙрдиреНрдлрдЯреЗрд╕реНрдЯ рдЖрдгрд┐ рдХреЙрдиреНрдлрд┐рдЧ-рд▓рд┐рдВрдЯ рд╕рд╛рдиреБрдХреВрд▓ рдЪрд╛рдЪрдгреНрдпрд╛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА YAML рд╡рд╛рдкрд░рддрд╛рдд рдЖрдгрд┐ рдХреЙрдкрд░ рддреБрдореНрд╣рд╛рд▓рд╛ рд╕рдВрдкреВрд░реНрдг рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖реЗрдд рдкреНрд░рд╡реЗрд╢ рджреЗрддреЗ, рдЬреНрдпрд╛рдореБрд│реЗ рддреА рдПрдХ рдЖрдХрд░реНрд╖рдХ рдирд┐рд╡рдб рдмрдирддреЗ.

рджреБрд╕рд░реАрдХрдбреЗ, рдпрд╛рдкреИрдХреА рдПрдХ рд╕рд╛рдзрди рд╡рд╛рдкрд░рдгреЗ рдЖрдгрд┐ рдореНрд╣рдгреВрди, рд╕рд░реНрд╡ рдЪрд╛рдЪрдгреНрдпрд╛ рд╡реНрдпрдХреНрддрд┐рдЪрд▓рд┐рддрдкрдгреЗ рддрдпрд╛рд░ рдХрд░рдгреЗ рдХрд┐рдВрд╡рд╛ рдкреЛрд▓рд╛рд░рд┐рд╕рд▓рд╛ рдкреНрд░рд╛рдзрд╛рдиреНрдп рджреЗрдгреЗ рдЖрдгрд┐ рддреНрдпрд╛рдд рдЖрд╡рд╢реНрдпрдХ рддреЗрдЪ рдЬреЛрдбрдгреЗ рдпреЛрдЧреНрдп рдЖрд╣реЗ рдХрд╛? рдпрд╛ рдкреНрд░рд╢реНрдирд╛рдЪреЗ рдХреЛрдгрддреЗрд╣реА рд╕реНрдкрд╖реНрдЯ рдЙрддреНрддрд░ рдирд╛рд╣реА.

рдЦрд╛рд▓реАрд▓ рд╕рд╛рд░рдгреА рдкреНрд░рддреНрдпреЗрдХ рд╕рд╛рдзрдирд╛рдЪреЗ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рд╡рд░реНрдгрди рдкреНрд░рджрд╛рди рдХрд░рддреЗ:

рдЙрдкрдХрд░рдгреЗ
рдЧрдВрддрд╡реНрдп
рдЙрдгреАрд╡рд╛
рд╡рд╛рдкрд░рдХрд░реНрддрд╛ рдЪрд╛рдЪрдгреНрдпрд╛

рдХреБрдмреЗрд╡рд▓
API рд╕реНрдХреАрдорд╛рдЪреНрдпрд╛ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЖрд╡реГрддреНрддреАрд╡рд░ YAML рдореЕрдирд┐рдлреЗрд╕реНрдЯрдЪреЗ рдкреНрд░рдорд╛рдгреАрдХрд░рдг рдХрд░рддреЗ
CRD рд╕рд╣ рдХрд╛рдо рдХрд░реВ рд╢рдХрдд рдирд╛рд╣реА
рдХреЛрдгрддреНрдпрд╛рд╣реА

kube-рд╕реНрдХреЛрдЕрд░
рд╕рд░реНрд╡реЛрддреНрддрдо рдкрджреНрдзрддреАрдВрд╡рд┐рд░реБрджреНрдз YAML рдкреНрд░рдХрдЯрддреЗрдЪреЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рддреЗ
рд╕рдВрд╕рд╛рдзрдиреЗ рддрдкрд╛рд╕рдгреНрдпрд╛рд╕рд╛рдареА рддреБрдордЪреА Kubernetes API рдЖрд╡реГрддреНрддреА рдирд┐рд╡рдбреВ рд╢рдХрдд рдирд╛рд╣реА
рдХреЛрдгрддреНрдпрд╛рд╣реА

рддрд╛рдВрдмреЗ
YAML рдореЕрдирд┐рдлреЗрд╕реНрдЯрд╕рд╛рдареА рд╕рд╛рдиреБрдХреВрд▓ JavaScript рдЪрд╛рдЪрдгреНрдпрд╛ рддрдпрд╛рд░ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдлреНрд░реЗрдорд╡рд░реНрдХ
рдЕрдВрдЧрднреВрдд рдЪрд╛рдЪрдгреНрдпрд╛ рдирд╛рд╣реАрдд. рдЦрд░рд╛рдм рджрд╕реНрддрдРрд╡рдЬреАрдХрд░рдг
рд╣реЛрдп

config-lint
YAML рдордзреНрдпреЗ рдПрдореНрдмреЗрдб рдХреЗрд▓реЗрд▓реНрдпрд╛ рдбреЛрдореЗрди-рд╡рд┐рд╢рд┐рд╖реНрдЯ рднрд╛рд╖реЗрдордзреНрдпреЗ рдЪрд╛рдЪрдгреНрдпрд╛ рддрдпрд╛рд░ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдлреНрд░реЗрдорд╡рд░реНрдХ. рд╡рд┐рд╡рд┐рдз рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рди рдлреЙрд░рдореЕрдЯрд▓рд╛ рд╕рдкреЛрд░реНрдЯ рдХрд░рддреЗ (рдЙрджрд╛. рдЯреЗрд░рд╛рдлреЙрд░реНрдо)
рдХреЛрдгрддреНрдпрд╛рд╣реА рд░реЗрдбреАрдореЗрдб рдЪрд╛рдЪрдгреНрдпрд╛ рдирд╛рд╣реАрдд. рдЕрдВрдЧрднреВрдд рд╡рд┐рдзрд╛рдиреЗ рдЖрдгрд┐ рдХрд╛рд░реНрдпреЗ рдкреБрд░реЗрд╢реА рдирд╕рддреАрд▓
рд╣реЛрдп

рд╕реНрдкрд░реНрдзрд╛
рд░реЗрдЧреЛ (рдПрдХ рд╡рд┐рд╢реЗрд╖ рдХреНрд╡реЗрд░реА рднрд╛рд╖рд╛) рд╡рд╛рдкрд░реВрди рддреБрдордЪреНрдпрд╛ рд╕реНрд╡рддрдГрдЪреНрдпрд╛ рдЪрд╛рдЪрдгреНрдпрд╛ рддрдпрд╛рд░ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдлреНрд░реЗрдорд╡рд░реНрдХ. OCI рдмрдВрдбрд▓рджреНрд╡рд╛рд░реЗ рдкреЙрд▓рд┐рд╕реА рд╢реЗрдЕрд░ рдХрд░рдгреНрдпрд╛рдЪреА рдЕрдиреБрдорддреА рджреЗрддреЗ
рдЕрдВрдЧрднреВрдд рдЪрд╛рдЪрдгреНрдпрд╛ рдирд╛рд╣реАрдд. рдорд▓рд╛ рд░реЗрдЧреЛ рд╢рд┐рдХрд╛рдпрдЪреЗ рдЖрд╣реЗ. рдзреЛрд░рдгреЗ рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд░рддрд╛рдирд╛ рдбреЙрдХрд░ рд╣рдм рд╕рдорд░реНрдерд┐рдд рдирд╛рд╣реА
рд╣реЛрдп

рдкреЛрд▓рд╛рд░рд┐рд╕
рдкреБрдирд░рд╛рд╡рд▓реЛрдХрдиреЗ YAML рдорд╛рдирдХ рд╕рд░реНрд╡реЛрддреНрддрдо рдкрджреНрдзрддреАрдВрд╡рд┐рд░реБрджреНрдз рдкреНрд░рдХрдЯ рд╣реЛрддрд╛рдд. рддреБрдореНрд╣рд╛рд▓рд╛ JSON рд╕реНрдХреАрдорд╛ рд╡рд╛рдкрд░реВрди рддреБрдордЪреНрдпрд╛ рд╕реНрд╡рддрдГрдЪреНрдпрд╛ рдЪрд╛рдЪрдгреНрдпрд╛ рддрдпрд╛рд░ рдХрд░рдгреНрдпрд╛рдЪреА рдЕрдиреБрдорддреА рджреЗрддреЗ
JSON рд╕реНрдХреАрдорд╛рд╡рд░ рдЖрдзрд╛рд░рд┐рдд рдЪрд╛рдЪрдгреА рдХреНрд╖рдорддрд╛ рдкреБрд░реЗрд╢реА рдирд╕реВ рд╢рдХрддрд╛рдд
рд╣реЛрдп

рд╣реА рд╕рд╛рдзрдиреЗ рдХреБрдмрд░реНрдиреЗрдЯреНрд╕ рдХреНрд▓рд╕реНрдЯрд░рдЪреНрдпрд╛ рдкреНрд░рд╡реЗрд╢рд╛рд╡рд░ рдЕрд╡рд▓рдВрдмреВрди рдирд╕рд▓реНрдпрд╛рдореБрд│реЗ, рддреЗ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдгреЗ рд╕реЛрдкреЗ рдЖрд╣реЗ. рддреЗ рддреБрдореНрд╣рд╛рд▓рд╛ рд╕реНрддреНрд░реЛрдд рдлрд╛рдпрд▓реА рдлрд┐рд▓реНрдЯрд░ рдХрд░рдгреНрдпрд╛рдЪреА рдЖрдгрд┐ рдкреНрд░рдХрд▓реНрдкрд╛рдВрдордзреАрд▓ рдкреБрд▓ рд╡рд┐рдирдВрддреНрдпрд╛ рд▓реЗрдЦрдХрд╛рдВрдирд╛ рджреНрд░реБрдд рдЕрднрд┐рдкреНрд░рд╛рдп рдкреНрд░рджрд╛рди рдХрд░рдгреНрдпрд╛рдЪреА рдкрд░рд╡рд╛рдирдЧреА рджреЗрддрд╛рдд.

рдЕрдиреБрд╡рд╛рджрдХрд╛рдХрдбреВрди рдкреБрдирд╢реНрдЪ

рдЖрдордЪреНрдпрд╛ рдмреНрд▓реЙрдЧрд╡рд░ рджреЗрдЦреАрд▓ рд╡рд╛рдЪрд╛:

рд╕реНрддреНрд░реЛрдд: www.habr.com

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдЬреЛрдбрд╛