рдЙрддреНрддрдо рдЕрднреНрдпрд╛рд╕ рд░ рдиреАрддрд┐рд╣рд░реВ рд╡рд┐рд░реБрджреНрдз Kubernetes YAML рдорд╛рдиреНрдп рдЧрд░реНрдиреБрд╣реЛрд╕реН

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

рдЙрддреНрддрдо рдЕрднреНрдпрд╛рд╕ рд░ рдиреАрддрд┐рд╣рд░реВ рд╡рд┐рд░реБрджреНрдз Kubernetes YAML рдорд╛рдиреНрдп рдЧрд░реНрдиреБрд╣реЛрд╕реН

TL; рдб: рдпрд╕ рд▓реЗрдЦрд▓реЗ рдЙрддреНрддрдо рдЕрднреНрдпрд╛рд╕ рд░ рдЖрд╡рд╢реНрдпрдХрддрд╛рд╣рд░реВ рд╡рд┐рд░реБрджреНрдз Kubernetes YAML рдлрд╛рдЗрд▓рд╣рд░реВ рдкреНрд░рдорд╛рдгреАрдХрд░рдг рд░ рдореВрд▓реНрдпрд╛рдЩреНрдХрди рдЧрд░реНрди рдЫрд╡рдЯрд╛ рд╕реНрдерд┐рд░ рдЙрдкрдХрд░рдгрд╣рд░реВ рддреБрд▓рдирд╛ рдЧрд░реНрджрдЫред

Kubernetes рд╡рд░реНрдХрд▓реЛрдбрд╣рд░реВ рд╕рд╛рдорд╛рдиреНрдпрддрдпрд╛ YAML рдХрд╛рдЧрдЬрд╛рддрд╣рд░реВрдХреЛ рд░реВрдкрдорд╛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдЧрд░рд┐рдиреНрдЫред YAML рд╕рдБрдЧ рд╕рдорд╕реНрдпрд╛рд╣рд░реВ рдордзреНрдпреЗ рдПрдЙрдЯрд╛ рднрдиреЗрдХреЛ рдмрд╛рдзрд╛рд╣рд░реВ рд╡рд╛ manifest рдлрд╛рдЗрд▓рд╣рд░реВ рдмреАрдЪрдХреЛ рд╕рдореНрдмрдиреНрдз рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЧрд░реНрди рдХрдард┐рдирд╛рдИ рд╣реЛред

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

рдХреНрд▓рд╕реНрдЯрд░рдорд╛ рдкрдард╛рдЙрдирдмрд╛рдЯ PodDisruptionBudgets рдирднрдПрдХрд╛ рдбрд┐рдкреНрд▓реЛрдпрдореЗрдиреНрдЯрд╣рд░реВрд▓рд╛рдИ рдо рдХрд╕рд░реА рд░реЛрдХреНрди рд╕рдХреНрдЫреБ?

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

Kubernetes рд╕реНрдерд┐рд░ YAML рдлрд╛рдЗрд▓ рдирд┐рд░реАрдХреНрд╖рдг рдЗрдХреЛрд╕рд┐рд╕реНрдЯрдорд▓рд╛рдИ рдирд┐рдореНрди рдХреЛрдЯрд┐рд╣рд░реВрдорд╛ рд╡рд┐рднрд╛рдЬрди рдЧрд░реНрди рд╕рдХрд┐рдиреНрдЫ:

  • 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 рднрдгреНрдбрд╛рд░рд╣рд░реВ.

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

kubectl apply -f hello-world.yaml

рд░ рддреНрдпрд╕реИрд▓реЗ - рдХрд╛рдо рдЬрд╛рдБрдЪ рдЧрд░реНрдиреБрд╣реЛрд╕реН:

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

рдЕрдм рдЬрд╛рдиреБрд╣реЛрд╕реН http://localhost:8080 рд░ рдкреБрд╖реНрдЯрд┐ рдЧрд░реНрдиреБрд╣реЛрд╕реН рдХрд┐ рдЕрдиреБрдкреНрд░рдпреЛрдЧрд▓реЗ рдХрд╛рдо рдЧрд░рд┐рд░рд╣реЗрдХреЛ рдЫред рддрд░ рдХреЗ рдпрд╕рд▓реЗ рдЙрддреНрддрдо рдЕрднреНрдпрд╛рд╕рд╣рд░реВ рдкрдЫреНрдпрд╛рдЙрдБрдЫ? рдЬрд╛рдБрдЪ рдЧрд░реМрдВред

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

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

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

рдореВрд▓ рд▓реЗрдЦ рд▓реЗрдЦреНрдиреЗ рд╕рдордпрдорд╛, рд╕рдВрд╕реНрдХрд░рдг 0.15.0 рдЙрдкрд▓рдмреНрдз рдерд┐рдпреЛред

рдПрдХ рдкрдЯрдХ рд╕реНрдерд╛рдкрдирд╛ рднрдПрдкрдЫрд┐, рдпрд╕рд▓рд╛рдИ рдорд╛рдерд┐рдХреЛ рдореНрдпрд╛рдирд┐рдлреЗрд╕реНрдЯ рдлрд┐рдб рдЧрд░реМрдВ:

$ kubeval base-valid.yaml
PASS - base-valid.yaml contains a valid Deployment (http-echo)
PASS - base-valid.yaml contains a valid Service (http-echo)

рдпрджрд┐ рд╕рдлрд▓ рднрдПрдорд╛, рдХреБрдмреЗрд╡рд▓ рдирд┐рдХрд╛рд╕ рдХреЛрдб реж рдХреЛ рд╕рд╛рде рдмрд╛рд╣рд┐рд░ рдирд┐рд╕реНрдХрдиреЗрдЫред рддрдкрд╛рдЗрдБ рдпрд╕рд▓рд╛рдИ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдЬрд╛рдБрдЪ рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ:

$ echo $?
0

рдЕрдм рдПрдХ рдлрд░рдХ manifest рд╕рдВрдЧ рдХреБрдмреЗрд╡рд▓ рдкреНрд░рдпрд╛рд╕ рдЧрд░реМрдВ:

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, рдкреЛрдбрдХреЛ рд▓реЗрдмрд▓рд╕рдБрдЧ рдореЗрд▓ рдЦрд╛рдиреЗ рдЪрдпрдирдХрд░реНрддрд╛ рд╕рдорд╛рд╡реЗрд╢ рдЧрд░реНрдиреБрдкрд░реНрдЫред рдорд╛рдерд┐рдХреЛ manifest рдорд╛ рдЪрдпрдирдХрд░реНрддрд╛ рд╕рдорд╛рд╡реЗрд╢ рдЫреИрди, рддреНрдпрд╕реИрд▓реЗ kubeval рд▓реЗ рддреНрд░реБрдЯрд┐ рд░рд┐рдкреЛрд░реНрдЯ рдЧрд░реНрдиреБрднрдпреЛ рд░ рдЧреИрд░-рд╢реВрдиреНрдп рдХреЛрдбрдХреЛ рд╕рд╛рде рдмрд╛рд╣рд┐рд░ рдирд┐рд╕реНрдХрдиреБрднрдпреЛред

рдореИрд▓реЗ рдЧрд░реЗ рднрдиреЗ рдХреЗ рд╣реЛрд▓рд╛ рднрдиреЗрд░ рд╕реЛрдЪрд┐рд░рд╣реЗрдХреЛ рдЫреБ kubectl apply -f рдпреЛ рдШреЛрд╖рдгрд╛ рдкрддреНрд░ рд╕рдВрдЧ?

рдЦреИрд░, рдкреНрд░рдпрд╛рд╕ рдЧрд░реМрдВ:

$ kubectl apply -f kubeval-invalid.yaml
error: error validating "kubeval-invalid.yaml": error validating data: ValidationError(Deployment.spec):
missing required field "selector" in io.k8s.api.apps.v1.DeploymentSpec; if you choose to ignore these errors,
turn validation off with --validate=false

рдХреБрдмреЗрд╡рд▓рд▓реЗ рдЪреЗрддрд╛рд╡рдиреА рджрд┐рдПрдХреЛ рдЧрд▓реНрддреА рдпрд╣реА рд╣реЛ ред рддрдкрд╛рдЗрдБ рдЪрдпрдирдХрд░реНрддрд╛ рдердкреЗрд░ рдпрд╕рд▓рд╛рдИ рдареАрдХ рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: http-echo
spec:
  replicas: 2
  selector:          # !!!
    matchLabels:     # !!!
      app: http-echo # !!!
  template:
    metadata:
      labels:
        app: http-echo
    spec:
      containers:
      - name: http-echo
        image: hashicorp/http-echo
        args: ["-text", "hello-world"]
        ports:
        - containerPort: 5678
---
apiVersion: v1
kind: Service
metadata:
  name: http-echo
spec:
  ports:
  - port: 5678
    protocol: TCP
    targetPort: 5678
  selector:
    app: http-echo

(base-valid.yaml)

рдХреБрдмреЗрд╡рд▓ рдЬрд╕реНрддрд╛ рдЙрдкрдХрд░рдгрд╣рд░реВрдХреЛ рдлрд╛рдЗрджрд╛ рдпреЛ рд╣реЛ рдХрд┐ рдпрд╕реНрддрд╛ рддреНрд░реБрдЯрд┐рд╣рд░реВ рдбрд┐рдкреНрд▓реЛрдЗрдореЗрдиреНрдЯ рдЪрдХреНрд░рдорд╛ рдЪрд╛рдБрдбреИ рд╕рдорд╛рддреНрди рд╕рдХрд┐рдиреНрдЫред

рдердк рд░реВрдкрдорд╛, рдпреА рдЬрд╛рдБрдЪрд╣рд░реВрд▓рд╛рдИ рдХреНрд▓рд╕реНрдЯрд░рдорд╛ рдкрд╣реБрдБрдЪ рдЖрд╡рд╢реНрдпрдХ рдкрд░реНрджреИрди; рддрд┐рдиреАрд╣рд░реВ рдЕрдлрд▓рд╛рдЗрди рдкреНрд░рджрд░реНрд╢рди рдЧрд░реНрди рд╕рдХрд┐рдиреНрдЫред

рдкреВрд░реНрд╡рдирд┐рд░реНрдзрд╛рд░рд┐рдд рд░реВрдкрдорд╛, kubeval рд▓реЗ рдирд╡реАрдирддрдо Kubernetes API рд╕реНрдХреАрдорд╛ рд╡рд┐рд░реБрджреНрдз рд╕реНрд░реЛрддрд╣рд░реВ рдЬрд╛рдБрдЪ рдЧрд░реНрджрдЫред рдЬреЗ рд╣реЛрд╕реН, рдзреЗрд░реИ рдЬрд╕реЛ рдХреЗрд╕рд╣рд░реВрдорд╛ рддрдкрд╛рдИрдВрд▓реЗ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ Kubernetes рд░рд┐рд▓реАрдЬ рд╡рд┐рд░реБрджреНрдз рдЬрд╛рдБрдЪ рдЧрд░реНрди рдЖрд╡рд╢реНрдпрдХ рдкрд░реНрджрдЫред рдпреЛ рдЭрдгреНрдбрд╛ рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдЧрд░реНрди рд╕рдХрд┐рдиреНрдЫ --kubernetes-version:

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

рдХреГрдкрдпрд╛ рдиреЛрдЯ рдЧрд░реНрдиреБрд╣реЛрд╕реН рдХрд┐ рд╕рдВрд╕реНрдХрд░рдг рдврд╛рдБрдЪрд╛рдорд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рд╣реБрдиреБрдкрд░реНрдЫ Major.Minor.Patch.

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

рд╡реНрдпрдХреНрддрд┐рдЧрдд YAML рдлрд╛рдИрд▓рд╣рд░реВрдХреЛ рдЕрддрд┐рд░рд┐рдХреНрдд, kubeval рд▓реЗ рдбрд╛рдЗрд░реЗрдХреНрдЯрд░реАрд╣рд░реВ рд░ stdin рд╕рдБрдЧ рдкрдирд┐ рдХрд╛рдо рдЧрд░реНрди рд╕рдХреНрдЫред

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

  1. рд╕рд╛рджрд╛ рдкрд╛рда;
  2. JSON;
  3. рдХреБрдиреИ рдкрдирд┐ рдкреНрд░реЛрдЯреЛрдХрд▓ (рдЯреНрдпрд╛рдк) рдкрд░реАрдХреНрд╖рдг рдЧрд░реНрдиреБрд╣реЛрд╕реНред

рд░ рдЗрдЪреНрдЫрд┐рдд рдкреНрд░рдХрд╛рд░рдХреЛ рдирддрд┐рдЬрд╛рд╣рд░реВрдХреЛ рд╕рд╛рд░рд╛рдВрд╢ рдЙрддреНрдкрдиреНрди рдЧрд░реНрди рдЖрдЙрдЯрдкреБрдЯрдХреЛ рдердк рдкрд╛рд░реНрд╕рд┐рдЩрдХреЛ рд▓рд╛рдЧрд┐ рдХреБрдиреИ рдкрдирд┐ рдврд╛рдБрдЪрд╛рд╣рд░реВ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрди рд╕рдХрд┐рдиреНрдЫред

рдХреБрдмреЗрд╡рд▓рдХреЛ рдПрдЙрдЯрд╛ рдХрдордЬреЛрд░реА рдпреЛ рд╣реЛ рдХрд┐ рдпрд╕рд▓реЗ рд╣рд╛рд▓ Custom Resource Definitions (CRDs) рдХреЛ рдЕрдиреБрдкрд╛рд▓рдирдХреЛ рдЬрд╛рдБрдЪ рдЧрд░реНрди рд╕рдХреНрджреИрдиред рдпрджреНрдпрдкрд┐, рдХреБрдмреЗрд╡рд▓ рдХрдиреНрдлрд┐рдЧрд░ рдЧрд░реНрди рд╕рдореНрднрд╡ рдЫ рддрд┐рдиреАрд╣рд░реВрд▓рд╛рдИ рдмреЗрд╡рд╛рд╕реНрддрд╛ рдЧрд░реНрдиреБрд╣реЛрд╕реН.

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

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

рддрд░ рдпрджрд┐ рддрдкрд╛рдЗрдБ YAML рдХреЛ рдореВрд▓реНрдпрд╛рдЩреНрдХрди рдЧрд░реНрди рд░ рдЯреНрдпрд╛рдЧ рдЬрд╕реНрддреИ рдЙрд▓реНрд▓рдЩреНрдШрдирд╣рд░реВ рдкрд╣рд┐рдЪрд╛рди рдЧрд░реНрди рдЪрд╛рд╣рдиреБрд╣реБрдиреНрдЫ рднрдиреЗ latest? рдореИрд▓реЗ рдЙрддреНрддрдо рдЕрднреНрдпрд╛рд╕рд╣рд░реВ рд╡рд┐рд░реБрджреНрдз YAML рдлрд╛рдЗрд▓ рдХрд╕рд░реА рдЬрд╛рдБрдЪ рдЧрд░реНрдиреЗ?

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

рдХреБрдмреЗ-рдЕрдЩреНрдХ YAML manifests рд▓рд╛рдИ рдкрд╛рд░реНрд╕ рдЧрд░реНрджрдЫ рд░ рдмрд┐рд▓реНрдЯ-рдЗрди рдкрд░реАрдХреНрд╖рдгрд╣рд░реВ рд╡рд┐рд░реБрджреНрдз рдореВрд▓реНрдпрд╛рдЩреНрдХрди рдЧрд░реНрджрдЫред рдпреА рдкрд░реАрдХреНрд╖рдгрд╣рд░реВ рд╕реБрд░рдХреНрд╖рд╛ рджрд┐рд╢рд╛рдирд┐рд░реНрджреЗрд╢рд╣рд░реВ рд░ рдЙрддреНрдХреГрд╖реНрдЯ рдЕрднреНрдпрд╛рд╕рд╣рд░реВрдХреЛ рдЖрдзрд╛рд░рдорд╛ рдЪрдпрди рдЧрд░рд┐рдиреНрдЫ, рдЬрд╕реНрддреИ:

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

рдкрд░реАрдХреНрд╖рдг рдирддрд┐рдЬрд╛рдХреЛ рдЖрдзрд╛рд░рдорд╛, рддреАрди рдирддрд┐рдЬрд╛ рджрд┐рдЗрдиреНрдЫ: OK, рдЪреЗрддрд╛рд╡рдиреА ╨╕ CRITICAL.

рддрдкрд╛рдЗрдБ рдХреБрдмреЗ-рд╕реНрдХреЛрд░ рдЕрдирд▓рд╛рдЗрди рдкреНрд░рдпрд╛рд╕ рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ рд╡рд╛ рдпрд╕рд▓рд╛рдИ рд╕реНрдерд╛рдиреАрдп рд░реВрдкрдорд╛ рд╕реНрдерд╛рдкрдирд╛ рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫред

рдореВрд▓ рд▓реЗрдЦ рд▓реЗрдЦреНрдиреЗ рд╕рдордпрдорд╛, рдХреБрдмреЗ-рд╕реНрдХреЛрд░рдХреЛ рдирд╡реАрдирддрдо рд╕рдВрд╕реНрдХрд░рдг 1.7.0 рдерд┐рдпреЛред

рд╣рд╛рдореНрд░реЛ manifest рдорд╛ рдпрд╕рд▓рд╛рдИ рдкреНрд░рдпрд╛рд╕ рдЧрд░реМрдВ base-valid.yaml:

$ kube-score score base-valid.yaml

apps/v1/Deployment http-echo
[CRITICAL] Container Image Tag
  ┬╖ http-echo -> Image with latest tag
      Using a fixed tag is recommended to avoid accidental upgrades
[CRITICAL] Pod NetworkPolicy
  ┬╖ The pod does not have a matching network policy
      Create a NetworkPolicy that targets this pod
[CRITICAL] Pod Probes
  ┬╖ Container is missing a readinessProbe
      A readinessProbe should be used to indicate when the service is ready to receive traffic.
      Without it, the Pod is risking to receive traffic before it has booted. It is also used during
      rollouts, and can prevent downtime if a new version of the application is failing.
      More information: https://github.com/zegl/kube-score/blob/master/README_PROBES.md
[CRITICAL] Container Security Context
  ┬╖ http-echo -> Container has no configured security context
      Set securityContext to run the container in a more secure context.
[CRITICAL] Container Resources
  ┬╖ http-echo -> CPU limit is not set
      Resource limits are recommended to avoid resource DDOS. Set resources.limits.cpu
  ┬╖ http-echo -> Memory limit is not set
      Resource limits are recommended to avoid resource DDOS. Set resources.limits.memory
  ┬╖ http-echo -> CPU request is not set
      Resource requests are recommended to make sure that the application can start and run without
      crashing. Set resources.requests.cpu
  ┬╖ http-echo -> Memory request is not set
      Resource requests are recommended to make sure that the application can start and run without crashing.
      Set resources.requests.memory
[CRITICAL] Deployment has PodDisruptionBudget
  ┬╖ No matching PodDisruptionBudget was found
      It is recommended to define a PodDisruptionBudget to avoid unexpected downtime during Kubernetes
      maintenance operations, such as when draining a node.
[WARNING] Deployment has host PodAntiAffinity
  ┬╖ Deployment does not have a host podAntiAffinity set
      It is recommended to set a podAntiAffinity that stops multiple pods from a deployment from
      being scheduled on the same node. This increases availability in case the node becomes unavailable.

YAML рд▓реЗ kubeval рдкрд░реАрдХреНрд╖рдгрд╣рд░реВ рдкрд╛рд╕ рдЧрд░реНрдЫ, рдЬрдмрдХрд┐ kube-рд╕реНрдХреЛрд░рд▓реЗ рдирд┐рдореНрди рддреНрд░реБрдЯрд┐рд╣рд░реВрд▓рд╛рдИ рд╕рдВрдХреЗрдд рдЧрд░реНрдЫ:

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

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

рдЯреЛрд▓реА kube-score рд╕рдмреИ рдкреНрд░рдХрд╛рд░рдХрд╛ рдЙрд▓реНрд▓рдЩреНрдШрдирд╣рд░реВ рд╕рд╣рд┐рдд рдорд╛рдирд╡-рдкрдардиреАрдп рдлрд╛рд░рдордорд╛ рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рджрд░реНрд╢рди рдЧрд░реНрджрдЫ рдЪреЗрддрд╛рд╡рдиреА ╨╕ CRITICAL, рдЬрд╕рд▓реЗ рд╡рд┐рдХрд╛рд╕рдХреЛ рдХреНрд░рдордорд╛ рдзреЗрд░реИ рдорджреНрджрдд рдЧрд░реНрджрдЫред

CI рдкрд╛рдЗрдкрд▓рд╛рдЗрди рднрд┐рддреНрд░ рдпреЛ рдЙрдкрдХрд░рдг рдкреНрд░рдпреЛрдЧ рдЧрд░реНрди рдЪрд╛рд╣рдиреЗрд╣рд░реВрд▓реЗ рдЭрдгреНрдбрд╛ рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдердк рд╕рдВрдХреБрдЪрд┐рдд рдЖрдЙрдЯрдкреБрдЯ рд╕рдХреНрд╖рдо рдЧрд░реНрди рд╕рдХреНрдЫрдиреН --output-format ci (рдпрд╕ рдЕрд╡рд╕реНрдерд╛рдорд╛, рдкрд░рд┐рдгрд╛рдордХреЛ рд╕рд╛рде рдкрд░реАрдХреНрд╖рдгрд╣рд░реВ рдкрдирд┐ рдкреНрд░рджрд░реНрд╢рд┐рдд рд╣реБрдиреНрдЫрдиреН OK):

$ kube-score score base-valid.yaml --output-format ci

[OK] http-echo apps/v1/Deployment
[OK] http-echo apps/v1/Deployment
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) CPU limit is not set
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) Memory limit is not set
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) CPU request is not set
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) Memory request is not set
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) Image with latest tag
[OK] http-echo apps/v1/Deployment
[CRITICAL] http-echo apps/v1/Deployment: The pod does not have a matching network policy
[CRITICAL] http-echo apps/v1/Deployment: Container is missing a readinessProbe
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) Container has no configured security context
[CRITICAL] http-echo apps/v1/Deployment: No matching PodDisruptionBudget was found
[WARNING] http-echo apps/v1/Deployment: Deployment does not have a host podAntiAffinity set
[OK] http-echo v1/Service
[OK] http-echo v1/Service
[OK] http-echo v1/Service
[OK] http-echo v1/Service

kubeval рдЬрд╕реНрддреИ, kube-рд╕реНрдХреЛрд░рд▓реЗ рдПрдХ рдЧреИрд░-рд╢реВрдиреНрдп рдирд┐рдХрд╛рд╕ рдХреЛрдб рдлрд░реНрдХрд╛рдЙрдБрдЫ рдЬрдм рддреНрдпрд╣рд╛рдБ рдПрдХ рдкрд░реАрдХреНрд╖рдг рдЕрд╕рдлрд▓ рд╣реБрдиреНрдЫред CRITICALред рддрдкрд╛рдИрдВ рдкрдирд┐ рдХреЛ рд▓рд╛рдЧреА рд╕рдорд╛рди рдкреНрд░рд╢реЛрдзрди рд╕рдХреНрд╖рдо рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ рдЪреЗрддрд╛рд╡рдиреА.

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

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

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

Kube-рд╕реНрдХреЛрд░ рдкрд░реАрдХреНрд╖рдгрд╣рд░реВ рдЙрддреНрддрдо рдЕрднреНрдпрд╛рд╕рд╣рд░реВ рд▓рд╛рдЧреВ рдЧрд░реНрдирдХреЛ рд▓рд╛рдЧрд┐ рдЙрддреНрдХреГрд╖реНрдЯ рдЙрдкрдХрд░рдг рд╣реЛ, рддрд░ рдпрджрд┐ рддрдкрд╛рдИрдВрд▓реЗ рдкрд░реАрдХреНрд╖рдгрдорд╛ рдкрд░рд┐рд╡рд░реНрддрдирд╣рд░реВ рдЧрд░реНрди рд╡рд╛ рдЖрдлреНрдиреИ рдирд┐рдпрдорд╣рд░реВ рдердкреНрди рдЖрд╡рд╢реНрдпрдХ рдЫ рднрдиреЗ рдХреЗ рд╣реБрдиреНрдЫ? рдЕрд╣реЛ, рдпреЛ рдЧрд░реНрди рд╕рдХрд┐рдБрджреИрдиред

рдХреБрдмреЗ-рд╕реНрдХреЛрд░ рдПрдХреНрд╕реНрдЯреЗрдиреНрд╕рд┐рдмрд▓ рдЫреИрди: рддрдкрд╛рдИрдВрд▓реЗ рдпрд╕рдорд╛ рдиреАрддрд┐рд╣рд░реВ рдердкреНрди рд╡рд╛ рд╕рдорд╛рдпреЛрдЬрди рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдиред

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

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

рдХрдиреНрдлрд┐рдЧ-рд▓рд┐рдиреНрдЯ YAML, JSON, Terraform, CSV рдХрдиреНрдлрд┐рдЧрд░реЗрд╕рди рдлрд╛рдЗрд▓рд╣рд░реВ рд░ Kubernetes manifests рдкреНрд░рдорд╛рдгреАрдХрд░рдг рдЧрд░реНрдиреЗ рдЙрдкрдХрд░рдг рд╣реЛред

рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рд╕реНрдерд╛рдкрдирд╛ рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ рдирд┐рд░реНрджреЗрд╢рдирд╣рд░реВ рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╡реЗрдмрд╕рд╛рдЗрдЯрдорд╛ред

рдореВрд▓ рд▓реЗрдЦ рд▓реЗрдЦреНрдиреЗ рд╕рдордпрдХреЛ рд░реВрдкрдорд╛ рд╣рд╛рд▓рдХреЛ рд░рд┐рд▓реАрдЬ 1.5.0 рд╣реЛред

рдХрдиреНрдлрд┐рдЧ-рд▓рд┐рдиреНрдЯрдорд╛ Kubernetes manifests рдХреЛ рдкреНрд░рдорд╛рдгреАрдХрд░рдгрдХреЛ рд▓рд╛рдЧрд┐ рдмрд┐рд▓реНрдЯ-рдЗрди рдкрд░реАрдХреНрд╖рдгрд╣рд░реВ рдЫреИрдирдиреНред

рдХреБрдиреИ рдкрдирд┐ рдкрд░реАрдХреНрд╖рдг рд╕рдЮреНрдЪрд╛рд▓рди рдЧрд░реНрди, рддрдкрд╛рдИрдВрд▓реЗ рдЙрдкрдпреБрдХреНрдд рдирд┐рдпрдорд╣рд░реВ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрди рдЖрд╡рд╢реНрдпрдХ рдЫред рддрд┐рдиреАрд╣рд░реВ 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 - рд╣реБрдирд╕рдХреНрдЫ FAILURE, рдЪреЗрддрд╛рд╡рдиреА ╨╕ 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"
  }
]

рдЪреЗрдХ рдЕрд╕рдлрд▓ рднрдпреЛред рдЕрдм рд╕рд╣реА рдЫрд╡рд┐ рднрдгреНрдбрд╛рд░рдХреЛ рд╕рд╛рде рдирд┐рдореНрди manifest рдЬрд╛рдБрдЪ рдЧрд░реМрдВ:

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)

рд╣рд╛рдореА рдорд╛рдерд┐рдХреЛ manifest рд╕рдВрдЧ рд╕рдорд╛рди рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рдЙрдБрдЫреМрдВред рдХреБрдиреИ рд╕рдорд╕реНрдпрд╛ рднреЗрдЯрд┐рдПрди:

$ config-lint -rules check_image_repo.yaml image-valid-mycompany.yaml
[]

рдХрдиреНрдлрд┐рдЧ-рд▓рд┐рдиреНрдЯ рдПрдХ рдЖрд╢рд╛рдЬрдирдХ рдврд╛рдБрдЪрд╛ рд╣реЛ рдЬрд╕рд▓реЗ рддрдкрд╛рдИрдВрд▓рд╛рдИ YAML DSL рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ Kubernetes YAML manifests рдкреНрд░рдорд╛рдгрд┐рдд рдЧрд░реНрди рдЖрдлреНрдиреИ рдкрд░реАрдХреНрд╖рдгрд╣рд░реВ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрди рдЕрдиреБрдорддрд┐ рджрд┐рдиреНрдЫред

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

рез. рдХрдкрд░

рдХрдкрд░ V2 рдЕрдиреБрдХреВрд▓рди рдкрд░реАрдХреНрд╖рдгрд╣рд░реВ (рдХрдиреНрдлрд┐рдЧ-рд▓рд┐рдиреНрдЯ рдЬрд╕реНрддреИ) рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдореНрдпрд╛рдирд┐рдлреЗрд╕реНрдЯрд╣рд░реВ рдорд╛рдиреНрдп рдЧрд░реНрдиреЗ рдврд╛рдБрдЪрд╛ рд╣реЛред

рдпрджреНрдпрдкрд┐, рдпреЛ рдкрдЫрд┐рд▓реНрд▓реЛ рднрдиреНрджрд╛ рдлрд░рдХ рдЫ рдХрд┐ рдпрд╕рд▓реЗ рдкрд░реАрдХреНрд╖рдгрд╣рд░реВ рд╡рд░реНрдгрди рдЧрд░реНрди YAML рдкреНрд░рдпреЛрдЧ рдЧрд░реНрджреИрдиред рдкрд░реАрдХреНрд╖рдгрд╣рд░реВ рд╕рдЯреНрдЯрд╛ рдЬрд╛рднрд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯрдорд╛ рд▓реЗрдЦреНрди рд╕рдХрд┐рдиреНрдЫред рдХрдкрд░рд▓реЗ рдзреЗрд░реИ рдЖрдзрд╛рд░рднреВрдд рдЙрдкрдХрд░рдгрд╣рд░реВрдХреЛ рд╕рд╛рде рдПрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдкреНрд░рджрд╛рди рдЧрд░реНрджрдЫ, рдЬрд╕рд▓реЗ рддрдкрд╛рдИрдВрд▓рд╛рдИ 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

рдпреЛ рд╕реНрдкрд╖реНрдЯ рдЫ рдХрд┐ рддрд╛рдорд╛рдХреЛ рдорджреНрджрддрд▓реЗ рддрдкрд╛рдИрд▓реЗ рдердк рдЬрдЯрд┐рд▓ рдкрд░реАрдХреНрд╖рдгрд╣рд░реВ рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ - рдЙрджрд╛рд╣рд░рдгрдХрд╛ рд▓рд╛рдЧрд┐, Ingress manifests рдорд╛ рдбреЛрдореЗрди рдирд╛рдорд╣рд░реВ рдЬрд╛рдБрдЪ рдЧрд░реНрдиреЗ рд╡рд╛ рд╡рд┐рд╢реЗрд╖рд╛рдзрд┐рдХрд╛рд░ рдкреНрд░рд╛рдкреНрдд рдореЛрдбрдорд╛ рдЪрд▓рд┐рд░рд╣реЗрдХреЛ рдкреЛрдбрд╣рд░реВ рдЕрд╕реНрд╡реАрдХрд╛рд░ рдЧрд░реНрдиреЗред

рдХрдкрд░рдорд╛ рдирд┐рд░реНрдорд┐рдд рд╡рд┐рднрд┐рдиреНрди рдЙрдкрдпреЛрдЧрд┐рддрд╛ рдкреНрд░рдХрд╛рд░реНрдпрд╣рд░реВ рдЫрдиреН:

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

рддрдкрд╛рдИрдВ рд╕рдмреИ рдЙрдкрд▓рдмреНрдз рд╕реЗрд╡рд╛ рдкреНрд░рдХрд╛рд░реНрдпрд╣рд░реВ рд╣реЗрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ рдпрд╣рд╛рдБ.

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

Copper рдХреЛ рдореБрдЦреНрдп рдлрд╛рдЗрджрд╛ рд╕реНрдкрд╖реНрдЯ рдЫ: рддрдкрд╛рдЗрдБрд▓рд╛рдИ рдПрдХ рд╡рд┐рд╢реЗрд╖ рднрд╛рд╖рд╛ рдорд╛рд╕реНрдЯрд░ рдЧрд░реНрди рдЖрд╡рд╢реНрдпрдХ рдЫреИрди рд░ рддрдкрд╛рдЗрдБ рддрдкрд╛рдЗрдБрдХреЛ рдЖрдлреНрдиреИ рдкрд░реАрдХреНрд╖рдгрд╣рд░реВ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрди рд╡рд┐рднрд┐рдиреНрди JavaScript рд╕реБрд╡рд┐рдзрд╛рд╣рд░реВ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ, рдЬрд╕реНрддреИ рд╕реНрдЯреНрд░рд┐рдЩ рдЗрдиреНрдЯрд░рдкреЛрд▓реЗрд╕рди, рдкреНрд░рдХрд╛рд░реНрдпрд╣рд░реВ, рдЖрджрд┐ред

рдпреЛ рдкрдирд┐ рдзреНрдпрд╛рди рджрд┐рдиреБрдкрд░реНрдЫ рдХрд┐ рдХрдкрд░рдХреЛ рд╣рд╛рд▓рдХреЛ рд╕рдВрд╕реНрдХрд░рдгрд▓реЗ рдЬрд╛рднрд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЗрдиреНрдЬрд┐рдирдХреЛ ES5 рд╕рдВрд╕реНрдХрд░рдгрд╕рдБрдЧ рдХрд╛рдо рдЧрд░реНрджрдЫ, ES6 рд╣реЛрдЗрдиред

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

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

5. рдкреНрд░рддрд┐рдпреЛрдЧрд┐рддрд╛

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

рддрдкрд╛рдИрдВ рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ confest рд╕реНрдерд╛рдкрдирд╛ рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ рдирд┐рд░реНрджреЗрд╢рдирд╣рд░реВрдкрд░рд┐рдпреЛрдЬрдирд╛ рд╡реЗрдмрд╕рд╛рдЗрдЯрдорд╛ рд╕реВрдЪреАрдмрджреНрдзред

рдореВрд▓ рд▓реЗрдЦ рд▓реЗрдЦреНрдиреЗ рд╕рдордпрдорд╛, рдирд╡реАрдирддрдо рд╕рдВрд╕реНрдХрд░рдг рдЙрдкрд▓рдмреНрдз рдерд┐рдпреЛ 0.18.2ред

config-lint рд░ copper рдЬрд╕реНрддреИ, confest рдХреБрдиреИ рдкрдирд┐ рдирд┐рд░реНрдорд┐рдд рдкрд░реАрдХреНрд╖рдг рдмрд┐рдирд╛ рдЖрдЙрдБрдЫред рдпрд╕рд▓рд╛рдИ рдкреНрд░рдпрд╛рд╕ рдЧрд░реМрдВ рд░ рд╣рд╛рдореНрд░реЛ рдЖрдлреНрдиреИ рдиреАрддрд┐ рд▓реЗрдЦреМрдВред рдЕрдШрд┐рд▓реНрд▓реЛ рдЙрджрд╛рд╣рд░рдгрд╣рд░реВрдорд╛ рдЬрд╕реНрддреИ, рд╣рд╛рдореА рдХрдиреНрдЯреЗрдирд░ рдЫрд╡рд┐рд╣рд░реВ рд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рд╕реНрд░реЛрддрдмрд╛рдЯ рд▓рд┐рдЗрдПрдХреЛ рд╣реЛ рдХрд┐ рднрдиреЗрд░ рдЬрд╛рдБрдЪ рдЧрд░реНрдиреЗрдЫреМрдВред

рдбрд╛рдЗрд░реЗрдХреНрдЯрд░реА рдмрдирд╛рдЙрдиреБрд╣реЛрд╕реН 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

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

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

рддрдкрд╛рдИрдВ рдиреАрддрд┐ рд╕рд╛рдЭреЗрджрд╛рд░реА рд░ confest рдХреЛ рдЕрдиреНрдп рд╕реБрд╡рд┐рдзрд╛рд╣рд░реВ рдмрд╛рд░реЗ рдердк рдЬрд╛рдиреНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╡реЗрдмрд╕рд╛рдЗрдЯ.

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

рдпрд╕ рд▓реЗрдЦрдорд╛ рдЫрд▓рдлрд▓ рдЧрд░рд┐рдиреЗ рдЕрдиреНрддрд┐рдо рдЙрдкрдХрд░рдг рд╣реЛ рдкреЛрд▓рд╛рд░рд┐рд╕. (рдЙрдирдХреЛ рдЧрдд рд╡рд░реНрд╖рдХреЛ рдШреЛрд╖рдгрд╛ рд╣рд╛рдореА рдкрд╣рд┐рд▓реЗ рдиреИ рдЕрдиреБрд╡рд╛рдж - рд▓рдЧрднрдЧред рдЕрдиреБрд╡рд╛рдж)

рдкреЛрд▓рд╛рд░рд┐рд╕ рдХреНрд▓рд╕реНрдЯрд░рдорд╛ рд╕реНрдерд╛рдкрд┐рдд рдЧрд░реНрди рд╕рдХрд┐рдиреНрдЫ рд╡рд╛ рдХрдорд╛рдВрдб рд▓рд╛рдЗрди рдореЛрдбрдорд╛ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрди рд╕рдХрд┐рдиреНрдЫред рддрдкрд╛рдИрд▓реЗ рдЕрдиреБрдорд╛рди рдЧрд░реНрдиреБ рднрдПрдХреЛ рд╣реБрдирд╕рдХреНрдЫ, рдпрд╕рд▓реЗ рддрдкрд╛рдИрд▓рд╛рдИ Kubernetes manifests рд▓рд╛рдИ рд╕реНрдерд┐рд░ рд░реВрдкрдорд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдЧрд░реНрди рдЕрдиреБрдорддрд┐ рджрд┐рдиреНрдЫред

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

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

рдХрдорд╛рдгреНрдб рд▓рд╛рдЗрди рдореЛрдбрдорд╛ рдкреЛрд▓рд╛рд░рд┐рд╕ рд╕реНрдерд╛рдкрдирд╛ рдЧрд░реНрди, рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдиреБрд╣реЛрд╕реН рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╡реЗрдмрд╕рд╛рдЗрдЯрдорд╛ рдирд┐рд░реНрджреЗрд╢рдирд╣рд░реВ.

рдореВрд▓ рд▓реЗрдЦ рд▓реЗрдЦреНрдиреЗ рд╕рдордпрдорд╛, рд╕рдВрд╕реНрдХрд░рдг 1.0.3 рдЙрдкрд▓рдмреНрдз рдЫред

рдПрдХ рдкрдЯрдХ рд╕реНрдерд╛рдкрдирд╛ рдкреВрд░рд╛ рднрдПрдкрдЫрд┐ рддрдкрд╛рдИрдВрд▓реЗ manifest рдорд╛ рдкреЛрд▓рд╛рд░рд┐рд╕ рдЪрд▓рд╛рдЙрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ 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 manifest рд╕рдБрдЧред

рд╣рд╛рдореНрд░реЛ рдШреЛрд╖рдгрд╛рдкрддреНрд░ рдкрд░реАрдХреНрд╖рдг рдЧрд░реМрдВ base-valid.yaml:

$ polaris audit --config custom_check.yaml --audit-path base-valid.yaml

рдЯреЛрд▓реА polaris audit рдорд╛рдерд┐ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЧрд░рд┐рдПрдХреЛ рдкреНрд░рдпреЛрдЧрдХрд░реНрддрд╛ рдкрд░реАрдХреНрд╖рдг рдорд╛рддреНрд░ рдЪрд▓реНрдпреЛ рд░ рдпреЛ рдЕрд╕рдлрд▓ рднрдпреЛред

рдпрджрд┐ рддрдкрд╛рдИрдВрд▓реЗ рдЫрд╡рд┐рд▓рд╛рдИ рдареАрдХ рдЧрд░реНрдиреБрднрдпреЛ рднрдиреЗ my-company.com/http-echo:1.0, рдкреЛрд▓рд╛рд░рд┐рд╕ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рдкреВрд░рд╛ рд╣реБрдиреЗрдЫред рдкрд░рд┐рд╡рд░реНрддрдирд╕рд╣рд┐рддрдХреЛ рдШреЛрд╖рдгрд╛рдкрддреНрд░ рдЖрдЗрд╕рдХреЗрдХреЛ рдЫ рднрдгреНрдбрд╛рд░рд╣рд░реВрддреНрдпрд╕реИрд▓реЗ рддрдкрд╛рдИрдВрд▓реЗ manifest рдорд╛ рдЕрдШрд┐рд▓реНрд▓реЛ рдЖрджреЗрд╢ рдЬрд╛рдБрдЪ рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ 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)

рдкреВрд░реНрдг рдХрдиреНрдлрд┐рдЧрд░реЗрд╕рди рдлрд╛рдЗрд▓рдХреЛ рдЙрджрд╛рд╣рд░рдг рдЙрдкрд▓рдмреНрдз рдЫ рдпрд╣рд╛рдБ.

manifest рдЬрд╛рдБрдЪ рдЧрд░реНрдиреБрд╣реЛрд╕реН base-valid.yamlрдмрд┐рд▓реНрдЯ-рдЗрди рд░ рдЕрдиреБрдХреВрд▓рди рдкрд░реАрдХреНрд╖рдгрд╣рд░реВ рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░, рддрдкрд╛рдЗрдБ рдЖрджреЗрд╢ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ:

$ polaris audit --config config_with_custom_check.yaml --audit-path base-valid.yaml

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

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

Polaris рдмрд╛рд░реЗ рдердк рдЬрд╛рдирдХрд╛рд░реА рдорд╛ рдЙрдкрд▓рдмреНрдз рдЫ рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╡реЗрдмрд╕рд╛рдЗрдЯ.

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

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

рдЙрджрд╛рд╣рд░рдгрдХрд╛ рд▓рд╛рдЧрд┐, рдпрджрд┐ рддрдкрд╛рдЗрдБ рдкрд╛рдЗрдкрд▓рд╛рдЗрдирдорд╛ рдЬрд╛рдиреЗ рдХреБрдмреЗрд░рдиреЗрдЯреНрд╕ рдореЗрдирд┐рдлреЗрд╕реНрдЯрд╣рд░реВ рд▓рд┐рдиреБрд╣реБрдиреНрдЫ рднрдиреЗ, рдХреБрдмреЗрд╡рд▓ рдпрд╕реНрддреЛ рдкрд╛рдЗрдкрд▓рд╛рдЗрдирдорд╛ рдкрд╣рд┐рд▓реЛ рдЪрд░рдг рд╣реБрди рд╕рдХреНрдЫредред рдпрд╕рд▓реЗ рд╡рд╕реНрддреБ рдкрд░рд┐рднрд╛рд╖рд╛рд╣рд░реВ Kubernetes API рд╕реНрдХреАрдорд╛ рдЕрдиреБрд░реВрдк рдЫрдиреН рдХрд┐ рдЫреИрдирдиреН рднрдиреЗрд░ рдирд┐рдЧрд░рд╛рдиреА рдЧрд░реНрдиреЗрдЫред

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

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

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

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

рддрд▓рдХреЛ рддрд╛рд▓рд┐рдХрд╛рд▓реЗ рдкреНрд░рддреНрдпреЗрдХ рдЙрдкрдХрд░рдгрдХреЛ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рд╡рд┐рд╡рд░рдг рдкреНрд░рджрд╛рди рдЧрд░реНрджрдЫ:

рдЙрдкрдХрд░рдг
рдЙрджреНрджреЗрд╢реНрдп
рдХрдореАрдХрдордЬреЛрд░реА
рдкреНрд░рдпреЛрдЧрдХрд░реНрддрд╛ рдкрд░реАрдХреНрд╖рдгрд╣рд░реВ

рдХреБрдмреЗрд╡рд▓
рдПрдкреАрдЖрдИ рд╕реНрдХреАрдорд╛ рдХреЛ рдПрдХ рд╡рд┐рд╢реЗрд╖ рд╕рдВрд╕реНрдХрд░рдг рд╡рд┐рд░реБрджреНрдз YAML рдкреНрд░рдХрдЯ рдкреНрд░рдорд╛рдгрд┐рдд рдЧрд░реНрджрдЫ
CRD рд╕рдБрдЧ рдХрд╛рдо рдЧрд░реНрди рд╕рдХрд┐рдБрджреИрди
рдХреБрдиреИ

kube-рд╕реНрдХреЛрд░
рд╡рд┐рд╢реНрд▓реЗрд╖рдг YAML рдЙрддреНрдХреГрд╖реНрдЯ рдЕрднреНрдпрд╛рд╕рд╣рд░реВ рд╡рд┐рд░реБрджреНрдз рдкреНрд░рдХрдЯ рд╣реБрдиреНрдЫ
рд╕реНрд░реЛрддрд╣рд░реВ рдЬрд╛рдБрдЪ рдЧрд░реНрди рддрдкрд╛рдИрдВрдХреЛ Kubernetes API рд╕рдВрд╕реНрдХрд░рдг рдЪрдпрди рдЧрд░реНрди рд╕рдХрд┐рдБрджреИрди
рдХреБрдиреИ

рддрд╛рдорд╛
YAML manifests рдХреЛ рд▓рд╛рдЧрд┐ рдЕрдиреБрдХреВрд▓рди JavaScript рдкрд░реАрдХреНрд╖рдгрд╣рд░реВ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрдирдХреЛ рд▓рд╛рдЧрд┐ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдврд╛рдБрдЪрд╛
рдмрд┐рд▓реНрдЯ-рдЗрди рдкрд░реАрдХреНрд╖рдгрд╣рд░реВ рдЫреИрдирдиреНред рдЦрд░рд╛рдм рдХрд╛рдЧрдЬрд╛рдд
рд╣реЛ

config-lint
YAML рдорд╛ рд╕рдореНрдорд┐рд▓рд┐рдд рдбреЛрдореЗрди-рд╡рд┐рд╢рд┐рд╖реНрдЯ рднрд╛рд╖рд╛рдорд╛ рдкрд░реАрдХреНрд╖рдгрд╣рд░реВ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрдирдХреЛ рд▓рд╛рдЧрд┐ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдврд╛рдБрдЪрд╛ред рд╡рд┐рднрд┐рдиреНрди рдХрдиреНрдлрд┐рдЧрд░реЗрд╕рди рдврд╛рдБрдЪрд╛рд╣рд░реВрд▓рд╛рдИ рд╕рдорд░реНрдерди рдЧрд░реНрджрдЫ (рдЬрд╕реНрддреИ Terraform)
рддреНрдпрд╣рд╛рдБ рдХреБрдиреИ рддрдпрд╛рд░ рдкрд░реАрдХреНрд╖рдгрд╣рд░реВ рдЫреИрдирдиреНред рдмрд┐рд▓реНрдЯ-рдЗрди рджрд╛рд╡реА рд░ рдХрд╛рд░реНрдпрд╣рд░реВ рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реБрди рд╕рдХреНрдЫ
рд╣реЛ

рдкреНрд░рддрд┐рд╕реНрдкрд░реНрдзрд╛
рд░реЗрдЧреЛ (рдПрдХ рд╡рд┐рд╢реЗрд╖ рдХреНрд╡реЗрд░реА рднрд╛рд╖рд╛) рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдЖрдлреНрдиреИ рдкрд░реАрдХреНрд╖рдгрд╣рд░реВ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрдиреЗ рдврд╛рдБрдЪрд╛ред OCI рдмрдиреНрдбрд▓рд╣рд░реВ рдорд╛рд░реНрдлрдд рдиреАрддрд┐рд╣рд░реВ рд╕рд╛рдЭреЗрджрд╛рд░реА рдЧрд░реНрди рдЕрдиреБрдорддрд┐ рджрд┐рдиреНрдЫ
рдмрд┐рд▓реНрдЯ-рдЗрди рдкрд░реАрдХреНрд╖рдгрд╣рд░реВ рдЫреИрдирдиреНред рдореИрд▓реЗ рд░реЗрдЧреЛ рд╕рд┐рдХреНрдиреБ рдкрд░реНрдЫред рдиреАрддрд┐рд╣рд░реВ рдкреНрд░рдХрд╛рд╢рд┐рдд рдЧрд░реНрджрд╛ рдбрдХрд░ рд╣рдм рд╕рдорд░реНрдерд┐рдд рдЫреИрди
рд╣реЛ

рдкреЛрд▓рд╛рд░рд┐рд╕
YAML рд▓реЗ рдорд╛рдирдХ рдЙрддреНрдХреГрд╖реНрдЯ рдЕрднреНрдпрд╛рд╕рд╣рд░реВ рд╡рд┐рд░реБрджреНрдз рдкреНрд░рдХрдЯ рдЧрд░реНрджрдЫ рд╕рдореАрдХреНрд╖рд╛ рдЧрд░реНрджрдЫред JSON рд╕реНрдХреАрдорд╛ рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рддрдкрд╛рдИрд▓рд╛рдИ рдЖрдлреНрдиреИ рдкрд░реАрдХреНрд╖рдгрд╣рд░реВ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрди рдЕрдиреБрдорддрд┐ рджрд┐рдиреНрдЫ
JSON рд╕реНрдХреАрдорд╛рдорд╛ рдЖрдзрд╛рд░рд┐рдд рдкрд░реАрдХреНрд╖рдг рдХреНрд╖рдорддрд╛рд╣рд░реВ рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реБрди рд╕рдХреНрдЫ
рд╣реЛ

рдХрд┐рдирднрдиреЗ рдпреА рдЙрдкрдХрд░рдгрд╣рд░реВ Kubernetes рдХреНрд▓рд╕реНрдЯрд░рдорд╛ рдкрд╣реБрдБрдЪрдорд╛ рднрд░ рдкрд░реНрджреИрдирдиреН, рддрд┐рдиреАрд╣рд░реВ рд╕реНрдерд╛рдкрдирд╛ рдЧрд░реНрди рд╕рдЬрд┐рд▓реЛ рдЫрдиреНред рддрд┐рдиреАрд╣рд░реВрд▓реЗ рддрдкрд╛рдИрдВрд▓рд╛рдИ рд╕реНрд░реЛрдд рдлрд╛рдЗрд▓рд╣рд░реВ рдлрд┐рд▓реНрдЯрд░ рдЧрд░реНрди рд░ рдкрд░рд┐рдпреЛрдЬрдирд╛рд╣рд░реВрдорд╛ рдкреБрд▓ рдЕрдиреБрд░реЛрдзрд╣рд░реВрдХреЛ рд▓реЗрдЦрдХрд╣рд░реВрд▓рд╛рдИ рджреНрд░реБрдд рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдкреНрд░рджрд╛рди рдЧрд░реНрди рдЕрдиреБрдорддрд┐ рджрд┐рдиреНрдЫред

рдЕрдиреБрд╡рд╛рджрдХрдмрд╛рдЯ PS

рд╣рд╛рдореНрд░реЛ рдмреНрд▓рдЧрдорд╛ рдкрдирд┐ рдкрдвреНрдиреБрд╣реЛрд╕реН:

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

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдердкреНрди