рд╕рд░реНрд╡реЛрддреНрддрдо рдкреНрд░рдерд╛рдУрдВ рдФрд░ рдиреАрддрд┐рдпреЛрдВ рдХреЗ рд╡рд┐рд░реБрджреНрдз Kubernetes YAML рдХреЛ рдорд╛рдиреНрдп рдХрд░реЗрдВ

рдЯрд┐рдкреНрдкрдгреАред рдЕрдиреБрд╡рд╛рджред: K8s рдкрд░рд┐рд╡реЗрд╢реЛрдВ рдХреЗ рд▓рд┐рдП YAML рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреА рдмрдврд╝рддреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд╕рд╛рде, рдЙрдирдХреЗ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд╕рддреНрдпрд╛рдкрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдЕрдзрд┐рдХ рд╕реЗ рдЕрдзрд┐рдХ рдЬрд░реВрд░реА рд╣реЛ рдЧрдИ рд╣реИред рдЗрд╕ рд╕рдореАрдХреНрд╖рд╛ рдХреЗ рд▓реЗрдЦрдХ рдиреЗ рди рдХреЗрд╡рд▓ рдЗрд╕ рдХрд╛рд░реНрдп рдХреЗ рд▓рд┐рдП рдореМрдЬреВрджрд╛ рд╕рдорд╛рдзрд╛рдиреЛрдВ рдХрд╛ рдЪрдпрди рдХрд┐рдпрд╛, рдмрд▓реНрдХрд┐ рдпрд╣ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ рдкрд░рд┐рдирд┐рдпреЛрдЬрди рдХрд╛ рднреА рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдХрд┐ рд╡реЗ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВред рдпрд╣ рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЬрд╛рдирдХрд╛рд░реАрдкреВрд░реНрдг рд╕рд╛рдмрд┐рдд рд╣реБрдЖ рдЬреЛ рдЗрд╕ рд╡рд┐рд╖рдп рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВред

рд╕рд░реНрд╡реЛрддреНрддрдо рдкреНрд░рдерд╛рдУрдВ рдФрд░ рдиреАрддрд┐рдпреЛрдВ рдХреЗ рд╡рд┐рд░реБрджреНрдз Kubernetes YAML рдХреЛ рдорд╛рдиреНрдп рдХрд░реЗрдВ

TL, рдбреЙ: рдпрд╣ рдЖрд▓реЗрдЦ рд╕рд░реНрд╡реЛрддреНрддрдо рдкреНрд░рдерд╛рдУрдВ рдФрд░ рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЗ рд╡рд┐рд░реБрджреНрдз рдХреБрдмреЗрд░рдиреЗрдЯреНрд╕ YAML рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдорд╛рдиреНрдп рдФрд░ рдореВрд▓реНрдпрд╛рдВрдХрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЫрд╣ рд╕реНрдерд┐рд░ рдЙрдкрдХрд░рдгреЛрдВ рдХреА рддреБрд▓рдирд╛ рдХрд░рддрд╛ рд╣реИред

рдХреБрдмреЗрд░рдиреЗрдЯреНрд╕ рд╡рд░реНрдХрд▓реЛрдб рдХреЛ рдЖрдорддреМрд░ рдкрд░ YAML рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред YAML рдХреЗ рд╕рд╛рде рд╕рдорд╕реНрдпрд╛рдУрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдореИрдирд┐рдлрд╝реЗрд╕реНрдЯ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рдмреАрдЪ рдмрд╛рдзрд╛рдУрдВ рдпрд╛ рд╕рдВрдмрдВрдзреЛрдВ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдХрдард┐рдирд╛рдИ рд╣реИред

рдпрджрд┐ рд╣рдореЗрдВ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдХреНрд▓рд╕реНрдЯрд░ рдореЗрдВ рддреИрдирд╛рдд рд╕рднреА рдЫрд╡рд┐рдпрд╛рдВ рдПрдХ рд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рд░рдЬрд┐рд╕реНрдЯреНрд░реА рд╕реЗ рдЖрддреА рд╣реИрдВ рддреЛ рдХреНрдпрд╛ рд╣реЛрдЧрд╛?

рдореИрдВ рдЙрди рдкрд░рд┐рдирд┐рдпреЛрдЬрдирдУрдВ рдХреЛ рдХреНрд▓рд╕реНрдЯрд░ рдореЗрдВ рднреЗрдЬреЗ рдЬрд╛рдиреЗ рд╕реЗ рдХреИрд╕реЗ рд░реЛрдХ рд╕рдХрддрд╛ рд╣реВрдБ рдЬрд┐рдирдореЗрдВ PodDisruptionBudgets рдирд╣реАрдВ рд╣реИрдВ?

рд╕реНрдереИрддрд┐рдХ рдкрд░реАрдХреНрд╖рдг рдХрд╛ рдПрдХреАрдХрд░рдг рдЖрдкрдХреЛ рд╡рд┐рдХрд╛рд╕ рдЪрд░рдг рдореЗрдВ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдФрд░ рдиреАрддрд┐ рдЙрд▓реНрд▓рдВрдШрдиреЛрдВ рдХреА рдкрд╣рдЪрд╛рди рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдЗрд╕рд╕реЗ рдпрд╣ рдЧрд╛рд░рдВрдЯреА рдмрдврд╝ рдЬрд╛рддреА рд╣реИ рдХрд┐ рд╕рдВрд╕рд╛рдзрди рдкрд░рд┐рднрд╛рд╖рд╛рдПрдБ рд╕рд╣реА рдФрд░ рд╕реБрд░рдХреНрд╖рд┐рдд рд╣реИрдВ, рдФрд░ рдпрд╣ рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИ рдХрд┐ рдЙрддреНрдкрд╛рджрди рдХрд╛рд░реНрдпрднрд╛рд░ рд╕рд░реНрд╡реЛрддреНрддрдо рдкреНрд░рдерд╛рдУрдВ рдХрд╛ рдкрд╛рд▓рди рдХрд░реЗрдЧрд╛ред

рдХреБрдмреЗрд░рдиреЗрдЯреНрд╕ рд╕реНрдерд┐рд░ YAML рдлрд╝рд╛рдЗрд▓ рдирд┐рд░реАрдХреНрд╖рдг рдкрд╛рд░рд┐рд╕реНрдерд┐рддрд┐рдХреА рддрдВрддреНрд░ рдХреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╢реНрд░реЗрдгрд┐рдпреЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

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

рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рд╣рдо рдЫрд╣ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдЙрдкрдХрд░рдгреЛрдВ рдХрд╛ рд╡рд░реНрдгрди рдФрд░ рддреБрд▓рдирд╛ рдХрд░реЗрдВрдЧреЗ:

  1. рдХреБрдмреЗрд╡рд▓;
  2. рдХреНрдпреВрдм-рд╕реНрдХреЛрд░;
  3. рдХреЙрдиреНрдлрд┐рдЧ-рд▓рд┐рдВрдЯ;
  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 рдФрд░ рдЗрд╕ рд▓реЗрдЦ рдХреЗ рдЕрдиреНрдп рдШреЛрд╖рдгрд╛рдкрддреНрд░ рдпрд╣рд╛рдВ рдкрд╛рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдЧрд┐рдЯ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА.

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

kubectl apply -f hello-world.yaml

рдФрд░ рдЗрд╕рд▓рд┐рдП - рдХрд╛рд░реНрдп рдХреА рдЬрд╛рдБрдЪ рдХрд░реЗрдВ:

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

рдЕрдм рдЬрд╛рдУ http://localhost:8080 рдФрд░ рдкреБрд╖реНрдЯрд┐ рдХрд░реЗрдВ рдХрд┐ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реИред рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рдпрд╣ рд╕рд░реНрд╡реЛрддреНрддрдо рдкреНрд░рдерд╛рдУрдВ рдХрд╛ рдкрд╛рд▓рди рдХрд░рддрд╛ рд╣реИ? рдЪрд▓реЛ рдЬрд╛рдВрдЪрддреЗ рд╣реИрдВред

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

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

рд╕реНрдерд╛рдкрд╛рдирд╛ рдирд┐рд░реНрджреЗрд╢ рдХреНрдпреВрдмреЗрд╡рд▓ рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╡реЗрдмрд╕рд╛рдЗрдЯ рдкрд░ рдЙрдкрд▓рдмреНрдз рд╣реИрдВред

рдореВрд▓ рд▓реЗрдЦ рд▓рд┐рдЦрдиреЗ рдХреЗ рд╕рдордп, рд╕рдВрд╕реНрдХрд░рдг 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

рд╕рдВрд╕рд╛рдзрди рдХрд╛ рд╕рддреНрдпрд╛рдкрди рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИ.

рдПрдкреАрдЖрдИ рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рддреИрдирд╛рддреА 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-version:

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

рдХреГрдкрдпрд╛ рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП Major.Minor.Patch.

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

рд╡реНрдпрдХреНрддрд┐рдЧрдд YAML рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдХреНрдпреВрдмреЗрд╡рд▓ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛рдУрдВ рдФрд░ stdin рдХреЗ рд╕рд╛рде рднреА рдХрд╛рдо рдХрд░ рд╕рдХрддрд╛ рд╣реИред

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдХреНрдпреВрдмреЗрд╡рд▓ рдЖрд╕рд╛рдиреА рд╕реЗ рд╕реАрдЖрдИ рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдореЗрдВ рдПрдХреАрдХреГрдд рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред рдЬреЛ рд▓реЛрдЧ рдХреНрд▓рд╕реНрдЯрд░ рдореЗрдВ рдореИрдирд┐рдлрд╝реЗрд╕реНрдЯ рднреЗрдЬрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдЙрдиреНрд╣реЗрдВ рдпрд╣ рдЬрд╛рдирдХрд░ рдЦрд╝реБрд╢реА рд╣реЛрдЧреА рдХрд┐ рдХреНрдпреВрдмреЗрд╡рд▓ рддреАрди рдЖрдЙрдЯрдкреБрдЯ рд╕реНрд╡рд░реВрдкреЛрдВ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ:

  1. рд╕рд╛рджреЗ рдкрд╛рда;
  2. JSON;
  3. рдХреБрдЫ рднреА рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░реЗрдВ (рдЯреАрдПрдкреА)ред

рдФрд░ рд╡рд╛рдВрдЫрд┐рдд рдкреНрд░рдХрд╛рд░ рдХреЗ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХрд╛ рд╕рд╛рд░рд╛рдВрд╢ рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдЙрдЯрдкреБрдЯ рдХреЗ рдЖрдЧреЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рд▓рд┐рдП рдХрд┐рд╕реА рднреА рдкреНрд░рд╛рд░реВрдк рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

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

рдХреНрдпреВрдмреЗрд╡рд▓ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреА рдЬрд╛рдБрдЪ рдФрд░ рдореВрд▓реНрдпрд╛рдВрдХрди рдХреЗ рд▓рд┐рдП рдПрдХ рдорд╣рд╛рди рдЙрдкрдХрд░рдг рд╣реИ; рд╣рд╛рд▓рд╛рдБрдХрд┐, рдЗрд╕ рдмрд╛рдд рдкрд░ рдЬреЛрд░ рджрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдкрд░реАрдХреНрд╖рд╛ рдЙрддреНрддреАрд░реНрдг рдХрд░рдирд╛ рдпрд╣ рдЧрд╛рд░рдВрдЯреА рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИ рдХрд┐ рд╕рдВрд╕рд╛рдзрди рд╕рд░реНрд╡реЛрддреНрддрдо рдкреНрд░рдерд╛рдУрдВ рдХрд╛ рдЕрдиреБрдкрд╛рд▓рди рдХрд░рддрд╛ рд╣реИред

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЯреИрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ 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-score рд╕рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдЙрд▓реНрд▓рдВрдШрдиреЛрдВ рд╕рд╣рд┐рдд рдЬрд╛рдирдХрд╛рд░реА рдХреЛ рдорд╛рдирд╡-рдкрдардиреАрдп рд░реВрдк рдореЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИ рдЪреЗрддрд╛рд╡рдиреА ╨╕ рдЧрдВрднреАрд░, рдЬреЛ рд╡рд┐рдХрд╛рд╕ рдХреЗ рджреМрд░рд╛рди рдмрд╣реБрдд рдорджрдж рдХрд░рддрд╛ рд╣реИред

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

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

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╡рд┐рднрд┐рдиреНрди рдПрдкреАрдЖрдИ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ (рдХреНрдпреВрдмреЗрд╡рд▓ рдореЗрдВ) рдХреЗ рдЕрдиреБрдкрд╛рд▓рди рдХреЗ рд▓рд┐рдП рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдпрд╣ рдЬрд╛рдирдХрд╛рд░реА рдХреНрдпреВрдм-рд╕реНрдХреЛрд░ рдореЗрдВ рд╣реА рд╣рд╛рд░реНрдбрдХреЛрдб рдХреА рдЧрдИ рд╣реИ: рдЖрдк рдХреБрдмреЗрд░рдиреЗрдЯреНрд╕ рдХреЗ рдПрдХ рдЕрд▓рдЧ рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рдЪрдпрди рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрджрд┐ рдЖрдк рдЕрдкрдиреЗ рдХреНрд▓рд╕реНрдЯрд░ рдХреЛ рдЕрдкрдЧреНрд░реЗрдб рдХрд░рдиреЗ рдХрд╛ рдЗрд░рд╛рджрд╛ рд░рдЦрддреЗ рд╣реИрдВ рдпрд╛ рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ K8s рдХреЗ рд╡рд┐рднрд┐рдиреНрди рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рдХрдИ рдХреНрд▓рд╕реНрдЯрд░ рд╣реИрдВ рддреЛ рдпрд╣ рд╕реАрдорд╛ рдПрдХ рдмрдбрд╝реА рд╕рдорд╕реНрдпрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИред

рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рд╡рд╣рд╛рдБ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдПрдХ рдореБрджреНрджрд╛ рд╣реИ рдЗрд╕ рдЕрд╡рд╕рд░ рдХреЛ рд╕рд╛рдХрд╛рд░ рдХрд░рдиреЗ рдХреЗ рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЗ рд╕рд╛рдеред

рдХреНрдпреВрдм-рд╕реНрдХреЛрд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдпрд╣рд╛рдВ рдкрд╛рдИ рдЬрд╛ рд╕рдХрддреА рд╣реИ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рд╡реЗрдмрд╕рд╛рдЗрдЯ.

рдХреНрдпреВрдм-рд╕реНрдХреЛрд░ рдкрд░реАрдХреНрд╖рдг рд╕рд░реНрд╡реЛрддреНрддрдо рдкреНрд░рдерд╛рдУрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдорд╣рд╛рди рдЙрдкрдХрд░рдг рд╣реИрдВ, рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ рдЖрдкрдХреЛ рдкрд░реАрдХреНрд╖рдг рдореЗрдВ рдмрджрд▓рд╛рд╡ рдХрд░рдиреЗ рдпрд╛ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдирд┐рдпрдо рдЬреЛрдбрд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ? рдЕрдлрд╝рд╕реЛрд╕, рдРрд╕рд╛ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛.

рдХреНрдпреВрдм-рд╕реНрдХреЛрд░ рд╡рд┐рд╕реНрддрд╛рд░ рдпреЛрдЧреНрдп рдирд╣реАрдВ рд╣реИ: рдЖрдк рдЗрд╕рдореЗрдВ рдиреАрддрд┐рдпрд╛рдВ рдирд╣реАрдВ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рдпрд╛ рдЙрдиреНрд╣реЗрдВ рд╕рдорд╛рдпреЛрдЬрд┐рдд рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗред

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

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

рдХреЙрдиреНрдлрд┐рдЧ-рд▓рд┐рдВрдЯ YAML, JSON, рдЯреЗрд░рд╛рдлреЙрд░реНрдо, CSV рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдлрд╝рд╛рдЗрд▓реЛрдВ рдФрд░ рдХреБрдмреЗрд░рдиреЗрдЯреНрд╕ рдореИрдирд┐рдлрд╝реЗрд╕реНрдЯ рдХреЛ рдорд╛рдиреНрдп рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрдкрдХрд░рдг рд╣реИред

рдЖрдк рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрдВрд╕реНрдЯреЙрд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдирд┐рд░реНрджреЗрд╢ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рд╡реЗрдмрд╕рд╛рдЗрдЯ рдкрд░.

рдореВрд▓ рд▓реЗрдЦ рд▓рд┐рдЦреЗ рдЬрд╛рдиреЗ рддрдХ рд╡рд░реНрддрдорд╛рди рд░рд┐рд▓реАрдЬрд╝ 1.5.0 рд╣реИред

рдХреЙрдиреНрдлрд┐рдЧ-рд▓рд┐рдВрдЯ рдореЗрдВ рдХреБрдмреЗрд░рдиреЗрдЯреНрд╕ рдореИрдирд┐рдлрд╝реЗрд╕реНрдЯ рдХреЛ рдорд╛рдиреНрдп рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдкрд░реАрдХреНрд╖рдг рдирд╣реАрдВ рд╣реИрдВред

рдХреЛрдИ рднреА рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдЙрдЪрд┐рдд рдирд┐рдпрдо рдмрдирд╛рдиреЗ рд╣реЛрдВрдЧреЗред рд╡реЗ YAML рдлрд╝рд╛рдЗрд▓реЛрдВ рдореЗрдВ рд▓рд┐рдЦреЗ рдЧрдП рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ "рдирд┐рдпрдорд╕реЗрдЯ" рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ (рдирд┐рдпрдо-рд╕реЗрдЯ), рдФрд░ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рдВрд░рдЪрдирд╛ рд╣реИ:

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

(rule.yaml)

рдЖрдЗрдП рдЗрд╕рдХрд╛ рдЕрдзрд┐рдХ рдмрд╛рд░реАрдХреА рд╕реЗ рдЕрдзреНрдпрдпрди рдХрд░реЗрдВ:

  • рдХреНрд╖реЗрддреНрд░ type рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдХреЙрдиреНрдлрд┐рдЧ-рд▓рд┐рдВрдЯ рдХрд┐рд╕ рдкреНрд░рдХрд╛рд░ рдХреА рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдЧрд╛ред 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 - рд╢рд╛рдпрдж рдЕрд╕рдлрд▓рддрд╛, рдЪреЗрддрд╛рд╡рдиреА ╨╕ рдЧреИрд░_рдЕрдиреБрдкрд╛рд▓рдХ;
  • 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 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХреБрдмреЗрд░рдиреЗрдЯреНрд╕ YAML рдореИрдирд┐рдлрд╝реЗрд╕реНрдЯ рдХреЛ рдорд╛рдиреНрдп рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдкрд░реАрдХреНрд╖рдг рдмрдирд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред

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

4ред рддрд╛рдВрдмрд╛

рддрд╛рдВрдмрд╛ V2 рдХрд╕реНрдЯрдо рдкрд░реАрдХреНрд╖рдгреЛрдВ (рдХреЙрдиреНрдлрд┐рдЧ-рд▓рд┐рдВрдЯ рдХреЗ рд╕рдорд╛рди) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдореИрдирд┐рдлрд╝реЗрд╕реНрдЯ рдХреЛ рдорд╛рдиреНрдп рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд░реВрдкрд░реЗрдЦрд╛ рд╣реИред

рд╣рд╛рд▓рд╛рдБрдХрд┐, рдпрд╣ рдмрд╛рдж рд╡рд╛рд▓реЗ рд╕реЗ рдЕрд▓рдЧ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП YAML рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдмрдЬрд╛рдп рдкрд░реАрдХреНрд╖рдг рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рд▓рд┐рдЦреЗ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред рдХреЙрдкрд░ рдХрдИ рдмреБрдирд┐рдпрд╛рджреА рдЙрдкрдХрд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рдЖрдкрдХреЛ рдХреБрдмреЗрд░рдиреЗрдЯреНрд╕ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдкрдврд╝рдиреЗ рдФрд░ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреА рд░рд┐рдкреЛрд░реНрдЯ рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддрд╛ рд╣реИред

рдХреЙрдкрд░ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рдЪрд░рдг рдпрд╣рд╛рдВ рдкрд╛рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рджрд╕реНрддрд╛рд╡реЗрдЬ.

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 рдЕрдиреБрднрд╡ рд╡рд╛рд▓реЗ рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдкрд░рд┐рдЪрд┐рдд рддрдХрдиреАрдХ)ред

рдХреЙрдкрд░ рдХрд╛ рдореБрдЦреНрдп рд▓рд╛рдн рд╕реНрдкрд╖реНрдЯ рд╣реИ: рдЖрдкрдХреЛ рдХрд┐рд╕реА рд╡рд┐рд╢реЗрд╖ рднрд╛рд╖рд╛ рдореЗрдВ рдорд╣рд╛рд░рдд рд╣рд╛рд╕рд┐рд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ рдФрд░ рдЖрдк рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдкрд░реАрдХреНрд╖рдг, рдЬреИрд╕реЗ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдЗрдВрдЯрд░рдкреЛрд▓реЗрд╢рди, рдлрд╝рдВрдХреНрд╢рди рдЗрддреНрдпрд╛рджрд┐ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рднрд┐рдиреНрди рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдпрд╣ рднреА рдзреНрдпрд╛рди рджрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдХреЙрдкрд░ рдХрд╛ рд╡рд░реНрддрдорд╛рди рд╕рдВрд╕реНрдХрд░рдг рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЗрдВрдЬрди рдХреЗ ES5 рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, ES6 рдХреЗ рд╕рд╛рде рдирд╣реАрдВред

рд╡рд┐рд╡рд░рдг рдпрд╣рд╛рдВ рдЙрдкрд▓рдмреНрдз рд╣реИ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреА рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рд╡реЗрдмрд╕рд╛рдЗрдЯ.

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

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

рдХреЙрдиреНрдЯреЗрд╕реНрдЯ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдбреЗрдЯрд╛ рдХреЗ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдПрдХ рд░реВрдкрд░реЗрдЦрд╛ рд╣реИред рдХреБрдмреЗрд░рдиреЗрдЯреНрд╕ рдореЗрдирд┐рдлрд╝реЗрд╕реНрдЯ рдХреЗ рдкрд░реАрдХреНрд╖рдг/рд╕рддреНрдпрд╛рдкрди рдХреЗ рд▓рд┐рдП рднреА рдЙрдкрдпреБрдХреНрддред рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХрд╛ рд╡рд░реНрдгрди рдПрдХ рд╡рд┐рд╢реЗрд╖ рдХреНрд╡реЗрд░реА рднрд╛рд╖рд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рд░реЗрдЧреЛ.

рдЖрдк рдХреЙрдиреНрдЯреЗрд╕реНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрдВрд╕реНрдЯреЙрд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдирд┐рд░реНрджреЗрд╢рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╡реЗрдмрд╕рд╛рдЗрдЯ рдкрд░ рд╕реВрдЪреАрдмрджреНрдзред

рдореВрд▓ рд▓реЗрдЦ рд▓рд┐рдЦрдиреЗ рдХреЗ рд╕рдордп, рдЙрдкрд▓рдмреНрдз рдирд╡реАрдирддрдо рд╕рдВрд╕реНрдХрд░рдг 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.

рдиреАрддрд┐рдпреЛрдВ рдХреЛ рдбреАрдмрдЧ рдХрд░рдирд╛ рдЖрд╕рд╛рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЙрдиреНрдЯреЗрд╕реНрдЯ рдореЗрдВ рдПрдХ рдзреНрд╡рдЬ рд╣реЛрддрд╛ рд╣реИ --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

рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, DockerHub рдЕрднреА рддрдХ рд╕рдорд░реНрдерд┐рдд рдирд╣реАрдВ рд╣реИред рдЗрд╕рд▓рд┐рдП рдпрджрд┐ рдЖрдк рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рддреЛ рдЕрдкрдиреЗ рдЖрдк рдХреЛ рднрд╛рдЧреНрдпрд╢рд╛рд▓реА рд╕рдордЭреЗрдВ Azure рдХрдВрдЯреЗрдирд░ рд░рдЬрд┐рд╕реНрдЯреНрд░реА (рдПрд╕реАрдЖрд░) рдпрд╛ рдЖрдкрдХреА рдЕрдкрдиреА рд░рдЬрд┐рд╕реНрдЯреНрд░реАред

рд╡рд┐рд░реВрдкрдг рд╕рд╛рдХреНрд╖реНрдп рдкреНрд░рд╛рд░реВрдк рдХреЗ рд╕рдорд╛рди рд╣реИ рдкреЙрд▓рд┐рд╕реА рдПрдЬреЗрдВрдЯ рдкреИрдХреЗрдЬ рдЦреЛрд▓реЗрдВ (рдУрдкреАрдП), рдЬреЛ рдЖрдкрдХреЛ рдореМрдЬреВрджрд╛ рдУрдкреАрдП рдкреИрдХреЗрдЬреЛрдВ рд╕реЗ рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЙрдиреНрдЯреЗрд╕реНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред

рдЖрдк рдиреАрддрд┐ рд╕рд╛рдЭрд╛рдХрд░рдг рдФрд░ рдХреЙрдиреНрдЯреЗрд╕реНрдЯ рдХреА рдЕрдиреНрдп рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рди рд╕рдХрддреЗ рд╣реИрдВ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреА рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рд╡реЗрдмрд╕рд╛рдЗрдЯ.

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": [
    /* ╨┤╨╗╨╕╨╜╨╜╤Л╨╣ ╤Б╨┐╨╕╤Б╨╛╨║ */
  ]
}

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

рдХреНрдпреВрдм-рд╕реНрдХреЛрд░ рдХреА рддрд░рд╣, рдкреЛрд▓рд╛рд░рд┐рд╕ рдЙрди рдХреНрд╖реЗрддреНрд░реЛрдВ рдореЗрдВ рдореБрджреНрджреЛрдВ рдХреА рдкрд╣рдЪрд╛рди рдХрд░рддрд╛ рд╣реИ рдЬрд╣рд╛рдВ рдореЗрдирд┐рдлреЗрд╕реНрдЯ рд╕рд░реНрд╡реЛрддреНрддрдо рдкреНрд░рдерд╛рдУрдВ рдХреЛ рдкреВрд░рд╛ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ:

  • рдкреЙрдбреНрд╕ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рд╕реНрд╡рд╛рд╕реНрдереНрдп рдЬрд╛рдВрдЪ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИред
  • рдХрдВрдЯреЗрдирд░ рдЫрд╡рд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдЯреИрдЧ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдирд╣реАрдВ рд╣реИрдВ.
  • рдХрдВрдЯреЗрдирд░ рд░реВрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рдЪрд▓рддрд╛ рд╣реИред
  • рдореЗрдореЛрд░реА рдФрд░ рд╕реАрдкреАрдпреВ рдХреЗ рд▓рд┐рдП рдЕрдиреБрд░реЛрдз рдФрд░ рд╕реАрдорд╛рдПрдБ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдирд╣реАрдВ рд╣реИрдВред

рдкреНрд░рддреНрдпреЗрдХ рдкрд░реАрдХреНрд╖рдг рдХреЛ, рдЙрд╕рдХреЗ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдЧрдВрднреАрд░рддрд╛ рдХреА рдПрдХ рдбрд┐рдЧреНрд░реА рджреА рдЬрд╛рддреА рд╣реИ: рдЪреЗрддрд╛рд╡рдиреА рдпрд╛ рдЦрддрд░рд╛. рдЙрдкрд▓рдмреНрдз рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдиреЗ рдХреЗ рд▓рд┐рдП рдХреГрдкрдпрд╛ рджреЗрдЦреЗрдВ рдкреНрд░рд▓реЗрдЦрди.

рдпрджрд┐ рд╡рд┐рд╡рд░рдг рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рддреЛ рдЖрдк рдзреНрд╡рдЬ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ --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

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

рджреВрд╕рд░реА рдУрд░, рд░реЗрдЧреЛ рдпрд╛ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЬреИрд╕реА рдЕрдзрд┐рдХ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рднрд╛рд╖рд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдореЗрдВ рдЕрд╕рдорд░реНрдерддрд╛ рдЕрдзрд┐рдХ рдкрд░рд┐рд╖реНрдХреГрдд рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЛ рд░реЛрдХрдиреЗ рд╡рд╛рд▓рд╛ рдПрдХ рд╕реАрдорд┐рдд рдХрд╛рд░рдХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред

рдкреЛрд▓рд╛рд░рд┐рд╕ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдпрд╣рд╛рдВ рдЙрдкрд▓рдмреНрдз рд╣реИ рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╕реНрдерд▓.

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

рд╣рд╛рд▓рд╛рдБрдХрд┐ Kubernetes YAML рдлрд╝рд╛рдЗрд▓реЛрдВ рдХрд╛ рдирд┐рд░реАрдХреНрд╖рдг рдФрд░ рдореВрд▓реНрдпрд╛рдВрдХрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдИ рдЙрдкрдХрд░рдг рдЙрдкрд▓рдмреНрдз рд╣реИрдВ, рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдХреИрд╕реЗ рдбрд┐рдЬрд╝рд╛рдЗрди рдФрд░ рдХреНрд░рд┐рдпрд╛рдиреНрд╡рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдЗрд╕рдХреА рд╕реНрдкрд╖реНрдЯ рд╕рдордЭ рд╣реЛрдирд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ.

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рдЖрдк рдПрдХ рдкрд╛рдЗрдкрд▓рд╛рдЗрди рд╕реЗ рдЧреБрдЬрд░рдиреЗ рд╡рд╛рд▓реЗ рдХреБрдмреЗрд░рдиреЗрдЯреНрд╕ рдореИрдирд┐рдлрд╝реЗрд╕реНрдЯ рдХреЛ рд▓реЗрддреЗ рд╣реИрдВ, рддреЛ рдХреНрдпреВрдмреЗрд╡рд▓ рдРрд╕реА рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдореЗрдВ рдкрд╣рд▓рд╛ рдХрджрдо рд╣реЛ рд╕рдХрддрд╛ рд╣реИ. рдпрд╣ рдирд┐рдЧрд░рд╛рдиреА рдХрд░реЗрдЧрд╛ рдХрд┐ рдСрдмреНрдЬреЗрдХреНрдЯ рдкрд░рд┐рднрд╛рд╖рд╛рдПрдБ рдХреБрдмреЗрд░рдиреЗрдЯреНрд╕ рдПрдкреАрдЖрдИ рд╕реНрдХреАрдорд╛ рдХреЗ рдЕрдиреБрд░реВрдк рд╣реИрдВ рдпрд╛ рдирд╣реАрдВред

рдПрдХ рдмрд╛рд░ рдРрд╕реА рд╕рдореАрдХреНрд╖рд╛ рдкреВрд░реА рд╣реЛ рдЬрд╛рдиреЗ рдХреЗ рдмрд╛рдж, рдХреЛрдИ рдЕрдзрд┐рдХ рдкрд░рд┐рд╖реНрдХреГрдд рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреА рдУрд░ рдЖрдЧреЗ рдмрдврд╝ рд╕рдХрддрд╛ рд╣реИ, рдЬреИрд╕реЗ рдорд╛рдирдХ рд╕рд░реНрд╡реЛрддреНрддрдо рдкреНрд░рдерд╛рдУрдВ рдФрд░ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдиреАрддрд┐рдпреЛрдВ рдХрд╛ рдЕрдиреБрдкрд╛рд▓рдиред рдпрд╣реАрдВ рдкрд░ рдХреНрдпреВрдм-рд╕реНрдХреЛрд░ рдФрд░ рдкреЛрд▓рд╛рд░рд┐рд╕ рдХрд╛рдо рдЖрдПрдВрдЧреЗред

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

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

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

рдиреАрдЪреЗ рджреА рдЧрдИ рддрд╛рд▓рд┐рдХрд╛ рдкреНрд░рддреНрдпреЗрдХ рдЙрдкрдХрд░рдг рдХрд╛ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рд╡рд┐рд╡рд░рдг рдкреНрд░рджрд╛рди рдХрд░рддреА рд╣реИ:

рдЙрдкрдХрд░рдг
рднрд╛рдЧреНрдп
рд╕реАрдорд╛рдПрдВ
рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкрд░реАрдХреНрд╖рдг

рдХреБрдмреЗрд╡рд▓
рдПрдкреАрдЖрдИ рд╕реНрдХреАрдорд╛ рдХреЗ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд╡рд┐рд░реБрджреНрдз YAML рдореИрдирд┐рдлрд╝реЗрд╕реНрдЯ рдХреЛ рдорд╛рдиреНрдп рдХрд░рддрд╛ рд╣реИ
рд╕реАрдЖрд░рдбреА рдХреЗ рд╕рд╛рде рдХрд╛рдо рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛
рдирд╣реАрдВ

рдХреНрдпреВрдм-рд╕реНрдХреЛрд░
рд╕рд░реНрд╡реЛрддреНрддрдо рдкреНрд░рдерд╛рдУрдВ рдХреЗ рд╡рд┐рд░реБрджреНрдз YAML рдореЗрдирд┐рдлреЗрд╕реНрдЯреЛрдВ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рддрд╛ рд╣реИ
рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреА рдЬрд╛рдБрдЪ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЗ Kubernetes API рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рдЪрдпрди рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛
рдирд╣реАрдВ

рддрд╛рдВрдмрд╛
YAML рдореЗрдирд┐рдлреЗрд╕реНрдЯреЛрдВ рдХреЗ рд▓рд┐рдП рдХрд╕реНрдЯрдо рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдкрд░реАрдХреНрд╖рдг рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдкрд░реЗрдЦрд╛
рдХреЛрдИ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдкрд░реАрдХреНрд╖рдг рдирд╣реАрдВ. рдЦрд╝рд░рд╛рдм рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг
╨Ф╨░

config-lint
YAML рдореЗрдВ рдПрдореНрдмреЗрдбреЗрдб рдбреЛрдореЗрди-рд╡рд┐рд╢рд┐рд╖реНрдЯ рднрд╛рд╖рд╛ рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдкрд░реЗрдЦрд╛ред рд╡рд┐рднрд┐рдиреНрди рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдкреНрд░рд╛рд░реВрдкреЛрдВ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ (рдЬреИрд╕реЗ рдЯреЗрд░рд╛рдлреЙрд░реНрдо)
рдХреЛрдИ рддреИрдпрд╛рд░ рдкрд░реАрдХреНрд╖рдг рдирд╣реАрдВ рд╣реИрдВ. рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рджрд╛рд╡реЗ рдФрд░ рдХрд╛рд░реНрдп рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ
╨Ф╨░

рд╕рдВрдШрд░реНрд╖
рд░реЗрдЧреЛ (рдПрдХ рд╡рд┐рд╢реЗрд╖ рдХреНрд╡реЗрд░реА рднрд╛рд╖рд╛) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдкрд░реАрдХреНрд╖рдг рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд░реВрдкрд░реЗрдЦрд╛ред рдУрд╕реАрдЖрдИ рдмрдВрдбрд▓реЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдиреАрддрд┐рдпреЛрдВ рдХреЛ рд╕рд╛рдЭрд╛ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ
рдХреЛрдИ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдкрд░реАрдХреНрд╖рдг рдирд╣реАрдВ. рдореБрдЭреЗ рд░реЗрдЧреЛ рд╕реАрдЦрдирд╛ рд╣реИ. рдиреАрддрд┐рдпреЛрдВ рдХреЛ рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд░рддреЗ рд╕рдордп рдбреЙрдХрд░ рд╣рдм рд╕рдорд░реНрдерд┐рдд рдирд╣реАрдВ рд╣реИ
╨Ф╨░

рдкреЛрд▓рд░рд┐рд╕
рд╕рдореАрдХреНрд╖рд╛ YAML рдорд╛рдирдХ рд╕рд░реНрд╡реЛрддреНрддрдо рдкреНрд░рдерд╛рдУрдВ рдХреЗ рд╡рд┐рд░реБрджреНрдз рдкреНрд░рдХрдЯ рд╣реЛрддреА рд╣реИред рдЖрдкрдХреЛ JSON рд╕реНрдХреАрдорд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдкрд░реАрдХреНрд╖рдг рдмрдирд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ
JSON рд╕реНрдХреАрдорд╛ рдкрд░ рдЖрдзрд╛рд░рд┐рдд рдкрд░реАрдХреНрд╖рдг рдХреНрд╖рдорддрд╛рдПрдВ рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реЛ рд╕рдХрддреА рд╣реИрдВ
╨Ф╨░

рдХреНрдпреЛрдВрдХрд┐ рдпреЗ рдЙрдкрдХрд░рдг рдХреБрдмреЗрд░рдиреЗрдЯреНрд╕ рдХреНрд▓рд╕реНрдЯрд░ рддрдХ рдкрд╣реБрдВрдЪ рдкрд░ рдирд┐рд░реНрднрд░ рдирд╣реАрдВ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдЗрдиреНрд╣реЗрдВ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реИред рд╡реЗ рдЖрдкрдХреЛ рд╕реНрд░реЛрдд рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд░рдиреЗ рдФрд░ рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ рдкреБрд▓ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рд▓реЗрдЦрдХреЛрдВ рдХреЛ рддреНрд╡рд░рд┐рдд рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВред

рдЕрдиреБрд╡рд╛рджрдХ рд╕реЗ рдкреА.рдПрд╕

рд╣рдорд╛рд░реЗ рдмреНрд▓реЙрдЧ рдкрд░ рднреА рдкрдврд╝реЗрдВ:

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

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдЬреЛрдбрд╝реЗрдВ