Kubernetes YAML-ро бо таҷрибаҳо ва сиёсатҳои беҳтарин тасдиқ кунед

Шарҳ. тарҷума.: Бо афзоиши шумораи конфигуратсияҳои YAML барои муҳитҳои K8s, зарурати санҷиши автоматии онҳо ҳарчи бештар фаврӣ мешавад. Муаллифи ин барраси на танҳо ҳалли мавҷударо барои ин вазифа интихоб кардааст, балки барои дидани он ки чӣ тавр кор мекунанд, Deployment-ро ҳамчун намуна истифода кардааст. Он барои онҳое, ки ба ин мавзӯъ таваҷҷӯҳ доранд, хеле муфид буд.

Kubernetes YAML-ро бо таҷрибаҳо ва сиёсатҳои беҳтарин тасдиқ кунед

ХИБ; DR: Ин мақола шаш асбоби статикиро барои тасдиқ ва арзёбии файлҳои Kubernetes YAML бо таҷрибаҳо ва талаботҳои беҳтарин муқоиса мекунад.

Сарбории кории Kubernetes одатан дар шакли ҳуҷҷатҳои YAML муайян карда мешавад. Яке аз мушкилот бо YAML ин душвории муайян кардани маҳдудиятҳо ё муносибатҳо байни файлҳои манифест мебошад.

Чӣ бояд кард, агар мо бояд боварӣ ҳосил кунем, ки ҳамаи тасвирҳои дар кластер ҷойгиршуда аз феҳристи боэътимод омадаанд?

Чӣ тавр ман метавонам аз фиристодани ҷойгиркунии PodDisruptionBudgets ба кластер пешгирӣ кунам?

Интегратсияи санҷиши статикӣ ба шумо имкон медиҳад, ки хатогиҳо ва вайронкунии сиёсатро дар марҳилаи таҳия муайян кунед. Ин кафолати дуруст ва бехатар будани таърифҳои захираҳоро зиёд мекунад ва эҳтимоли зиёд дорад, ки сарбории истеҳсолӣ ба таҷрибаи беҳтарин пайравӣ кунад.

Экосистемаи санҷиши файли статикии YAML-и Kubernetes метавонад ба категорияҳои зерин тақсим карда шавад:

  • Санҷишҳои API. Асбобҳо дар ин категория манифести YAML-ро бо талаботи сервери Kubernetes API тафтиш мекунанд.
  • Санҷишҳои омода. Асбобҳои ин категория бо санҷишҳои омода барои амният, мувофиқат ба таҷрибаҳои беҳтарин ва ғайра оварда мешаванд.
  • Валидаторҳои фармоишӣ. Намояндагони ин категория ба шумо имкон медиҳанд, ки санҷишҳои фармоиширо бо забонҳои гуногун эҷод кунед, масалан, Rego ва Javascript.

Дар ин мақола мо шаш асбоби гуногунро тавсиф ва муқоиса хоҳем кард:

  1. кубевал;
  2. холҳои кубӣ;
  3. config-lint;
  4. мис;
  5. мусобиқа;
  6. Қутбӣ.

Хуб, биёед оғоз кунем!

Санҷиши ҷойгиркунӣ

Пеш аз он ки мо ба муқоисаи асбобҳо шурӯъ кунем, биёед заминаеро эҷод кунем, ки дар он онҳоро озмоиш кунем.

Манифести зер як қатор хатогиҳо ва риоя накардани таҷрибаҳои беҳтаринро дар бар мегирад: шумо чандтои онҳоро ёфта метавонед?

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

(base-valid.yaml)

Мо ин YAML-ро барои муқоисаи асбобҳои гуногун истифода хоҳем кард.

Манифести боло base-valid.yaml ва дигар манифестҳои ин мақоларо метавон дар Анбори Git.

Манифест веб-барномаи вебро тавсиф мекунад, ки вазифаи асосии он посух додан бо паёми "Салом Ҷаҳон" ба порти 5678 мебошад. Он метавонад бо фармони зерин ҷойгир карда шавад:

kubectl apply -f hello-world.yaml

Ва ҳамин тавр - корро тафтиш кунед:

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

Акнун ба http://localhost:8080 ва тасдиқ кунед, ки барнома кор мекунад. Аммо оё он ба таҷрибаҳои беҳтарин пайравӣ мекунад? Биёед тафтиш кунем.

1. Кубевал

Дар асл кубевал Идеяи он аст, ки ҳама гуна ҳамкорӣ бо Kubernetes тавассути REST API-и он сурат мегирад. Ба ибораи дигар, шумо метавонед схемаи API-ро истифода баред, то тафтиш кунед, ки оё YAML-и додашуда ба он мувофиқат мекунад. Биёед як мисолро дида бароем.

Дастурҳо оид ба насб kubeval дар вебсайти лоиҳа дастрасанд.

Ҳангоми навиштани мақолаи аслӣ версияи 0.15.0 дастрас буд.

Пас аз насб, биёед онро ба манифести дар боло овардашуда гузорем:

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

Агар муваффақ бошад, kubeval бо рамзи баромади 0 мебарояд. Шумо метавонед онро ба таври зерин тафтиш кунед:

$ echo $?
0

Акнун биёед kubeval-ро бо манифести дигар санҷем:

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

(kubeval-invalid.yaml)

Оё шумо метавонед мушкилотро бо чашм муайян кунед? Биёед оғоз кунем:

$ kubeval kubeval-invalid.yaml
WARN - kubeval-invalid.yaml contains an invalid Deployment (http-echo) - selector: selector is required
PASS - kubeval-invalid.yaml contains a valid Service (http-echo)

# проверим код возврата
$ echo $?
1

Манбаъ тасдиқ карда намешавад.

Ҷойгиркунӣ бо истифода аз версияи API apps/v1, бояд селектореро дар бар гирад, ки ба тамғаи pod мувофиқат кунад. Манифести боло селекторро дар бар намегирад, аз ин рӯ kubeval дар бораи хато хабар дод ва бо рамзи ғайри сифр баромад.

Ман ҳайронам, ки агар кунам, чӣ мешавад kubectl apply -f бо ин манифест?

Хуб, биёед кӯшиш кунем:

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

Ин маҳз хатоест, ки кубевал дар бораи он огоҳ карда буд. Шумо метавонед онро тавассути илова кардани селектор ислоҳ кунед:

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

(base-valid.yaml)

Бартарии асбобҳо ба монанди kubeval дар он аст, ки хатогиҳои ба ин монандро дар давраи ҷойгиркунӣ барвақт ошкор кардан мумкин аст.

Илова бар ин, ин санҷишҳо дастрасӣ ба кластерро талаб намекунанд; онҳо метавонанд офлайн анҷом дода шаванд.

Бо нобаёнӣ, kubeval захираҳоро бар зидди схемаи охирини API Kubernetes тафтиш мекунад. Аммо, дар аксари ҳолатҳо ба шумо лозим меояд, ки бар зидди версияи мушаххаси Kubernetes тафтиш кунед. Инро бо истифода аз парчам кардан мумкин аст --kubernetes-version:

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

Лутфан қайд кунед, ки версия бояд дар формат нишон дода шавад Major.Minor.Patch.

Барои рӯйхати версияҳое, ки тасдиқи онҳо дастгирӣ мешавад, лутфан ба ин муроҷиат кунед Схемаи JSON дар GitHub, ки kubeval барои тасдиқ истифода мебарад. Агар ба шумо лозим аст, ки kubeval-ро офлайн иҷро кунед, схемаҳоро зеркашӣ кунед ва ҷойгиршавии маҳаллии онҳоро бо истифода аз парчам муайян кунед --schema-location.

Илова ба файлҳои инфиродии YAML, kubeval инчунин метавонад бо директорияҳо ва stdin кор кунад.

Илова бар ин, Кубевал ба осонӣ ба лӯлаи CI пайваст мешавад. Онҳое, ки мехоҳанд пеш аз фиристодани манифестҳо ба кластер санҷиш гузаронанд, аз он хушнуданд, ки kubeval се формати баромадро дастгирӣ мекунад:

  1. Матни оддӣ;
  2. JSON;
  3. Протоколи ҳама чизро санҷед (TAP).

Ва ҳама гуна форматҳоро барои таҳлили минбаъдаи натиҷаҳо барои тавлиди хулосаи натиҷаҳои намуди дилхоҳ истифода бурдан мумкин аст.

Яке аз нуқсонҳои kubeval дар он аст, ки он дар айни замон мувофиқатро бо таърифҳои фармоишии захираҳо (CRDs) тафтиш карда наметавонад. Бо вуҷуди ин, мумкин аст, ки kubeval-ро танзим кунед ба онҳо эътибор надиҳед.

Кубевал воситаи олиҷаноб барои тафтиш ва арзёбии захираҳо мебошад; Бо вуҷуди ин, бояд қайд кард, ки супоридани санҷиш кафолат намедиҳад, ки захира ба таҷрибаи пешқадам мувофиқат мекунад.

Масалан, бо истифода аз тег latest дар зарф ба тачрибаи пешкадам риоя намекунад. Аммо, kubeval инро хато намешуморад ва хабар намедиҳад. Яъне, тафтиши чунин YAML бе огоҳӣ анҷом меёбад.

Аммо чӣ мешавад, агар шумо хоҳед, ки YAML-ро арзёбӣ кунед ва вайронкуниҳоро ба монанди тег муайян кунед latest? Чӣ тавр ман метавонам файли YAML-ро бо таҷрибаҳои беҳтарин тафтиш кунам?

2. Кубе-хол

Кубе-хол манифестҳои YAML-ро таҳлил мекунад ва онҳоро бар зидди санҷишҳои дарунсохт арзёбӣ мекунад. Ин озмоишҳо дар асоси дастурҳои амниятӣ ва таҷрибаҳои беҳтарин интихоб карда мешаванд, ба монанди:

  • Кор кардани контейнер на ҳамчун реша.
  • Мавҷудияти санҷишҳои саломатӣ.
  • Муқаррар кардани дархостҳо ва маҳдудиятҳо барои захираҳо.

Дар асоси натиҷаҳои санҷиш, се натиҷа дода мешавад: OK, ҲУШДОР и КРИТСИЯ.

Шумо метавонед Kube-score-ро онлайн санҷед ё онро ба таври маҳаллӣ насб кунед.

Ҳангоми навиштани мақолаи аслӣ, версияи охирини kube-score 1.7.0 буд.

Биёед онро дар манифести худ санҷем base-valid.yaml:

$ kube-score score base-valid.yaml

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

YAML аз санҷишҳои kubeval мегузарад, дар ҳоле ки kube-хол ба камбудиҳои зерин ишора мекунад:

  • Санҷишҳои омодагӣ танзим карда нашудаанд.
  • Барои захираҳои CPU ва хотира ягон дархост ё маҳдудият вуҷуд надорад.
  • Буҷетҳои вайронкунии Pod муайян карда нашудаанд.
  • Қоидаҳои ҷудошавӣ вуҷуд надоранд (зидди ҳамбастагӣ) ба ҳадди аксар расонидани дастрасии.
  • Контейнер ҳамчун реша кор мекунад.

Ин ҳама нуктаҳои дуруст дар бораи камбудиҳо мебошанд, ки бояд барои самараноктар ва боэътимодтар кардани Ҷойгиркунӣ бартараф карда шаванд.

гурӯҳ kube-score маълумотро дар шакли барои одамон хондан, аз ҷумла ҳама намуди вайронкуниҳо нишон медиҳад ҲУШДОР и КРИТСИЯ, ки дар рафти инкишоф ёрии калон мерасонад.

Онҳое, ки мехоҳанд ин асбобро дар лӯлаи CI истифода баранд, метавонанд бо истифода аз парчам баромади бештар фишурдашударо фаъол созанд --output-format ci (дар ин ҳолат, санҷишҳо бо натиҷа низ нишон дода мешаванд OK):

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

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

Монанди kubeval, kube-score рамзи баромади ғайрисифрро бармегардонад, вақте ки санҷиш ноком мешавад КРИТСИЯ. Шумо инчунин метавонед коркарди шабеҳро барои ҲУШДОР.

Илова бар ин, имконпазир аст, ки захираҳоро барои мувофиқат бо версияҳои гуногуни API тафтиш кунед (ба монанди дар kubeval). Аммо, ин маълумот дар худи kube-score сахт рамзгузорӣ шудааст: шумо наметавонед версияи дигари Kubernetes-ро интихоб кунед. Агар шумо кластери худро навсозӣ карданӣ бошед ё агар шумо кластерҳои сершумор бо версияҳои гуногуни K8 дошта бошед, ин маҳдудият метавонад як мушкили бузург бошад.

дар назар гиред, ки аллакай як масъала вуҷуд дорад бо таклифи ба амал баровардани ин имконият.

Маълумоти бештарро дар бораи kube-score метавонед дар ин ҷо пайдо кунед сомонаи расмӣ.

Санҷишҳои Kube-score воситаи олӣ барои татбиқи таҷрибаҳои беҳтарин мебошанд, аммо агар ба шумо лозим аст, ки ба санҷиш тағирот ворид кунед ё қоидаҳои худро илова кунед-чӣ? Афсус, ки ин корро кардан мумкин нест.

Kube-score васеъшаванда нест: шумо наметавонед ба он сиёсат илова кунед ё онҳоро танзим кунед.

Агар ба шумо лозим аст, ки санҷишҳои фармоишӣ нависед, то мувофиқат бо сиёсатҳои ширкатро тафтиш кунед, шумо метавонед яке аз чаҳор абзори зеринро истифода баред: config-lint, copper, confest ё polaris.

3. Config-lint

Config-lint абзорест барои тасдиқи файлҳои конфигуратсияи YAML, JSON, Terraform, CSV ва манифестҳои Kubernetes.

Шумо метавонед онро бо истифода аз насб кунед дастурҳо дар вебсайти лоиҳа.

Нашри кунунӣ аз замони навиштани мақолаи аслӣ 1.5.0 аст.

Config-lint санҷишҳои дарунсохт барои тасдиқи манифестҳои Kubernetes надорад.

Барои гузаронидани ҳама гуна санҷишҳо, шумо бояд қоидаҳои мувофиқро эҷод кунед. Онҳо дар файлҳои YAML бо номи "қоидаҳо" навишта шудаанд (қоидаҳо), ва дорои сохтори зерин:

version: 1
description: Rules for Kubernetes spec files
type: Kubernetes
files:
  - "*.yaml"
rules:
   # список правил

(rule.yaml)

Биёед онро муфассалтар омӯзем:

  • соҳа type муайян мекунад, ки кадом намуди конфигуратсияи config-lint истифода мешавад. Барои K8s ин зуҳур аст ҳамеша Kubernetes.
  • Дар соҳаи files Илова ба худи файлҳо, шумо метавонед директорияро муайян кунед.
  • соҳа rules барои танзими санҷишҳои корбар пешбинӣ шудааст.

Фарз мекунем, ки шумо мехоҳед боварӣ ҳосил кунед, ки тасвирҳо дар Deployment ҳамеша аз анбори боэътимоди монанди зеркашишуда зеркашӣ карда мешаванд. my-company.com/myapp:1.0. Қоидаи config-lint, ки чунин санҷишро иҷро мекунад, чунин хоҳад буд:

- id: MY_DEPLOYMENT_IMAGE_TAG
  severity: FAILURE
  message: Deployment must use a valid image tag
  resource: Deployment
  assertions:
    - every:
        key: spec.template.spec.containers
        expressions:
          - key: image
            op: starts-with
            value: "my-company.com/"

(rule-trusted-repo.yaml)

Ҳар як қоида бояд хусусиятҳои зеринро дошта бошад:

  • id — идентификатори ягонаи коида;
  • severity - Мумкин ки Нокомӣ, ҲУШДОР и НО_МУВОФАТ;
  • 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
[]

Config-lint як чаҳорчӯбаи ояндадорест, ки ба шумо имкон медиҳад санҷишҳои шахсии худро барои тасдиқи манифестҳои Kubernetes YAML бо истифода аз YAML DSL эҷод кунед.

Аммо чӣ мешавад, агар ба шумо мантиқ ва санҷишҳои мураккабтар лозим бошад? Оё YAML барои ин хеле маҳдуд нест? Чӣ мешавад, агар шумо метавонед санҷишҳоро бо забони пурраи барномасозӣ эҷод кунед?

4. мис

Мис V2 чаҳорчӯбаи тасдиқи манифестҳо бо истифода аз санҷишҳои фармоишӣ (монанд ба config-lint) мебошад.

Аммо, он аз охирин бо он фарқ мекунад, ки он YAML-ро барои тавсифи санҷишҳо истифода намебарад. Ба ҷои ин, санҷишҳоро бо JavaScript навиштан мумкин аст. Copper китобхонаро бо якчанд асбобҳои асосӣ таъмин мекунад, ки ба шумо дар хондани маълумот дар бораи объектҳои Kubernetes ва гузориш дар бораи хатогиҳо кӯмак мекунад.

Қадамҳои насби мисро дар ин ҷо пайдо кардан мумкин аст ҳуҷҷатҳои расмӣ.

2.0.1 версияи охирини ин утилита дар вақти навиштани мақолаи аслӣ мебошад.

Мисли config-lint, Copper санҷишҳои дарунсохт надорад. Биёед якто нависед. Бигзор он тафтиш кунад, ки ҷойгиркунӣ тасвирҳои контейнерро танҳо аз анбори боэътимоди монанди 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 ё рад кардани pods, ки дар реҷаи имтиёзнок кор мекунанд.

Мис дорои вазифаҳои гуногуни коммуналӣ мебошад, ки дар он сохта шудаанд:

  • DockerImage файли вуруди муайяншударо мехонад ва объектеро бо атрибутҳои зерин месозад:
    • name - номи тасвир,
    • tag - теги тасвир,
    • registry - феҳристи тасвирҳо,
    • registry_url - протокол (https://) ва феҳристи тасвирҳо,
    • fqin — ҷойгиршавии пурраи тасвир.
  • функсия findByName барои дарёфти манбаъ аз рӯи намуди додашуда кӯмак мекунад (kind) ва ном (name) аз файли воридотӣ.
  • функсия findByLabels барои дарёфти манбаъ аз рӯи намуди муайян кӯмак мекунад (kind) ва тамғакоғазҳо (labels).

Шумо метавонед ҳамаи функсияҳои хидматрасонии дастрасро бинед дар ин ҷо.

Бо нобаёнӣ он тамоми файли вуруди YAML-ро ба тағирёбанда бор мекунад $$ ва онро барои скрипт дастрас мекунад (як техникаи шинос барои онҳое, ки таҷрибаи jQuery доранд).

Бартарии асосии Мис аён аст: ба шумо забони махсусро азхуд кардан лозим нест ва шумо метавонед барои сохтани санҷишҳои худ аз хусусиятҳои гуногуни JavaScript истифода баред, ба монанди интерполясияи сатр, функсияҳо ва ғайра.

Инчунин бояд қайд кард, ки версияи кунунии Copper бо версияи ES5 муҳаррики JavaScript кор мекунад, на ES6.

Тафсилот дар сомонаи расмии лоиҳа.

Аммо, агар шумо воқеан JavaScript-ро дӯст надоред ва забонеро, ки махсус барои эҷоди дархостҳо ва тавсифи сиёсатҳо пешбинӣ шудааст, афзалтар донед, шумо бояд ба confest диққат диҳед.

5. Озмун

Confest чаҳорчӯбаи санҷиши маълумоти конфигуратсия мебошад. Инчунин барои санҷиш/тасдиқи манифестҳои Kubernetes мувофиқ аст. Санҷишҳо бо истифода аз забони махсуси дархост тавсиф карда мешаванд Рего.

Шумо метавонед бо истифода аз 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

Санҷиши пешгӯӣ ноком шуд, зеро тасвирҳо аз манбаи боваринок омадаанд.

Дар файли Rego мо блокро муайян мекунем deny. Ҳақиқати он вайронкунӣ ҳисобида мешавад. Агар блокхо deny якчанд, confest онҳоро новобаста аз якдигар месанҷад ва ҳақиқати ягон блок ҳамчун вайронкунӣ баррасӣ карда мешавад.

Илова ба баромади пешфарз, confest JSON, TAP ва формати ҷадвалро дастгирӣ мекунад - як хусусияти хеле муфид, агар ба шумо лозим аст, ки гузоришҳоро ба лӯлаи мавҷудаи CI ворид кунед. Шумо метавонед формати дилхоҳро бо истифода аз парчам муқаррар кунед --output.

Барои осон кардани ислоҳи сиёсатҳо, confest дорои парчам аст --trace. Он нишон медиҳад, ки чӣ тавр confest файлҳои сиёсати муайяншударо таҳлил мекунад.

Сиёсати озмунро метавон ҳамчун артефакт дар реестри OCI (Open Container Initiative) нашр ва мубодила кард.

Фармонҳо push и pull ба шумо имкон медиҳад, ки артефактро нашр кунед ё артефакти мавҷударо аз феҳристи дурдаст дарёфт кунед. Биёед кӯшиш кунем, ки сиёсатеро, ки мо дар феҳристи маҳаллии Docker сохтаем, интишор кунем conftest push.

Феҳристи маҳаллии Docker-и худро оғоз кунед:

$ docker run -it --rm -p 5000:5000 registry

Дар терминали дигар ба директорияе, ки қаблан сохта будед, равед conftest-checks ва фармони зеринро иҷро кунед:

$ conftest push 127.0.0.1:5000/amitsaha/opa-bundle-example:latest

Агар фармон муваффақ бошад, шумо паёми зеринро хоҳед дид:

2020/06/10 14:25:43 pushed bundle with digest: sha256:e9765f201364c1a8a182ca637bc88201db3417bacc091e7ef8211f6c2fd2609c

Акнун директорияи муваққатӣ эҷод кунед ва фармонро дар он иҷро кунед conftest pull. Он бастаеро, ки бо фармони қаблӣ сохта шудааст, зеркашӣ мекунад:

$ cd $(mktemp -d)
$ conftest pull 127.0.0.1:5000/amitsaha/opa-bundle-example:latest

Дар директорияи муваққатӣ зеркаталог пайдо мешавад policyдорои файли сиёсати мо:

$ tree
.
└── policy
  └── check_image_registry.rego

Санҷишҳоро мустақиман аз анбор иҷро кардан мумкин аст:

$ conftest test --update 127.0.0.1:5000/amitsaha/opa-bundle-example:latest base-valid.yaml
..
FAIL - base-valid.yaml - image 'hashicorp/http-echo' doesn't come from my-company.com repository
2 tests, 1 passed, 0 warnings, 1 failure

Мутаассифона, DockerHub ҳанӯз дастгирӣ намешавад. Пас, агар шумо истифода баред, худро хушбахт ҳисоб кунед Феҳристи контейнерҳои Azure (ACR) ё феҳристи шахсии шумо.

Формати артефакт ҳамон аст Бастаҳои Агенти Policy Open (OPA), ки ба шумо имкон медиҳад, ки confest-ро барои гузаронидани санҷишҳо аз бастаҳои мавҷудаи OPA истифода баред.

Шумо метавонед дар бораи мубодилаи сиёсат ва дигар хусусиятҳои конфест маълумоти бештар гиред сомонаи расмии лоиҳа.

6. Қутбӣ

Воситаи охирине, ки дар ин мақола муҳокима хоҳад шуд Polaris. (Эълони соли гузаштаи ӯ мо аллакай тарҷума шудааст - тахминан. тарҷума)

Polaris-ро дар кластер насб кардан ё дар реҷаи сатри фармон истифода бурдан мумкин аст. Тавре ки шумо тахмин кардаед, он ба шумо имкон медиҳад, ки манифестҳои Kubernetes-ро статикӣ таҳлил кунед.

Ҳангоми кор дар реҷаи сатри фармон, санҷишҳои дарунсохт мавҷуданд, ки соҳаҳоро ба монанди амният ва таҷрибаҳои беҳтарин (монанд ба kube-score) фаро мегиранд. Илова бар ин, шумо метавонед озмоишҳои худро эҷод кунед (ба мисли config-lint, copper ва confest).

Ба ибораи дигар, Polaris бартариҳои ҳарду категорияи асбобҳоро муттаҳид мекунад: бо санҷишҳои дарунсохт ва фармоишӣ.

Барои насб кардани Polaris дар ҳолати сатри фармон, истифода баред дастурҳо дар вебсайти лоиҳа.

Ҳангоми навиштани мақолаи аслӣ версияи 1.0.3 дастрас аст.

Пас аз ба итмом расидани насб шумо метавонед polaris -ро дар манифест иҷро кунед base-valid.yaml бо фармони зерин:

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

Он сатрро дар формати JSON бо тавсифи муфассали санҷишҳои гузаронидашуда ва натиҷаҳои онҳо мебарорад. Натиҷа дорои сохтори зерин хоҳад буд:

{
  "PolarisOutputVersion": "1.0",
  "AuditTime": "0001-01-01T00:00:00Z",
  "SourceType": "Path",
  "SourceName": "test-data/base-valid.yaml",
  "DisplayName": "test-data/base-valid.yaml",
  "ClusterInfo": {
    "Version": "unknown",
    "Nodes": 0,
    "Pods": 2,
    "Namespaces": 0,
    "Controllers": 2
  },
  "Results": [
    /* длинный список */
  ]
}

Натиҷаи пурра дастрас аст дар ин ҷо.

Мисли kube-score, Polaris мушкилотро дар соҳаҳое муайян мекунад, ки манифест ба таҷрибаҳои беҳтарин мувофиқат намекунад:

  • Санҷишҳои саломатӣ барои гулҳо вуҷуд надоранд.
  • Тегҳо барои тасвирҳои контейнер муайян карда нашудаанд.
  • Контейнер ҳамчун реша кор мекунад.
  • Дархостҳо ва маҳдудиятҳо барои хотира ва CPU муайян карда нашудаанд.

Ҳар як санҷиш, вобаста ба натиҷаҳои он, дараҷаи интиқодӣ дода мешавад: огоҳӣ ё Хатар. Барои гирифтани маълумоти бештар дар бораи санҷишҳои дарунсохт, лутфан ба ин муроҷиат кунед хуччатхо.

Агар тафсилот лозим набошад, шумо метавонед парчамро муайян кунед --format score. Дар ин ҳолат, Polaris рақами аз 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 Schema тавсиф карда мешавад.

Парчами коди YAML-и зерин санҷиши наверо тавсиф мекунад, ки номида мешавад checkImageRepo:

checkImageRepo:
  successMessage: Image registry is valid
  failureMessage: Image registry is not valid
  category: Images
  target: Container
  schema:
    '$schema': http://json-schema.org/draft-07/schema
    type: object
    properties:
      image:
        type: string
        pattern: ^my-company.com/.+$

Биёед ба он муфассалтар назар андозем:

  • successMessage — агар имтихон бомуваффакият анчом ёбад, ин сатр чоп карда мешавад;
  • failureMessage — ин хабар дар сурати нокомй нишон дода мешавад;
  • category — яке аз категорияхоро нишон медихад: Images, Health Checks, Security, Networking и Resources;
  • target--- кадом намуди объектро муайян мекунад (spec) санҷиш татбиқ карда мешавад. Арзишҳои имконпазир: Container, Pod ё Controller;
  • Худи санҷиш дар объект нишон дода шудааст schema бо истифода аз схемаи JSON. Калимаи калидӣ дар ин санҷиш аст pattern барои муқоисаи манбаи тасвир бо манбаи зарурӣ истифода мешавад.

Барои иҷро кардани санҷиши дар боло зикршуда, шумо бояд конфигуратсияи зерини Polaris -ро эҷод кунед:

checks:
  checkImageRepo: danger
customChecks:
  checkImageRepo:
    successMessage: Image registry is valid
    failureMessage: Image registry is not valid
    category: Images
    target: Container
    schema:
      '$schema': http://json-schema.org/draft-07/schema
      type: object
      properties:
        image:
          type: string
          pattern: ^my-company.com/.+$

(polaris-conf.yaml)

Биёед файлро таҳлил кунем:

  • Дар соҳаи checks санчишхо ва дарачаи танкидии онхо мукаррар карда шудаанд. Азбаски гирифтани огоҳӣ ҳангоми гирифтани тасвир аз манбаи боваринок матлуб аст, мо сатҳро дар ин ҷо муқаррар мекунем danger.
  • Худи озмоиш checkImageRepo баъд дар объект кайд карда мешавад customChecks.

Файлро ҳамчун захира кунед custom_check.yaml. Акнун шумо метавонед давед polaris audit бо манифести YAML, ки тафтишро талаб мекунад.

Биёед манифести худро санҷида base-valid.yaml:

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

гурӯҳ polaris audit танҳо санҷиши корбареро, ки дар боло зикр шудааст, иҷро кард ва он ноком шуд.

Агар шумо тасвирро ислоҳ кунед my-company.com/http-echo:1.0, Polaris бомуваффақият мебарояд. Манифест бо тағирот аллакай дар анборҳоПас шумо метавонед фармони қаблиро дар манифест тафтиш кунед image-valid-mycompany.yaml.

Акнун савол ба миён меояд: чӣ гуна санҷишҳои дарунсохтро якҷоя бо санҷишҳои фармоишӣ иҷро кардан мумкин аст? Ба осонӣ! Ба шумо танҳо лозим аст, ки идентификаторҳои дарунсохтро ба файли конфигуратсия илова кунед. Дар натиҷа, он шакли зеринро мегирад:

checks:
  cpuRequestsMissing: warning
  cpuLimitsMissing: warning
  # Other inbuilt checks..
  # ..
  # custom checks
  checkImageRepo: danger # !!!
customChecks:
  checkImageRepo:        # !!!
    successMessage: Image registry is valid
    failureMessage: Image registry is not valid
    category: Images
    target: Container
    schema:
      '$schema': http://json-schema.org/draft-07/schema
      type: object
      properties:
        image:
          type: string
          pattern: ^my-company.com/.+$

(config_with_custom_check.yaml)

Намунаи файли конфигуратсияи мукаммал мавҷуд аст дар ин ҷо.

Манифестро тафтиш кунед base-valid.yamlбо истифода аз санҷишҳои дарунсохт ва фармоишӣ, шумо метавонед фармонро истифода баред:

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

Polaris санҷишҳои дарунсохтро бо санҷишҳои фармоишӣ пурра мекунад ва ба ин васила беҳтарини ҳарду ҷаҳонро муттаҳид мекунад.

Аз тарафи дигар, имконнопазирии истифодаи забонҳои пурқувват ба монанди Rego ё JavaScript метавонад омили маҳдудкунандае бошад, ки эҷоди санҷишҳои мураккабтарро пешгирӣ кунад.

Маълумоти бештар дар бораи Polaris дастрас аст сомона.

Натиҷа

Гарчанде ки асбобҳои зиёде барои тафтиш ва арзёбии файлҳои Kubernetes YAML мавҷуданд, муҳим аст, ки фаҳмиши равшани он, ки санҷишҳо чӣ гуна тарҳрезӣ ва иҷро карда мешаванд.

Барои мисол, агар шумо манифести Кубернетесро гиред, ки аз қубур мегузарад, kubeval метавонад қадами аввалин дар чунин қубур бошад. Он назорат мекунад, ки оё таърифҳои объект ба схемаи Kubernetes API мувофиқат мекунанд.

Пас аз ба итмом расидани чунин барраси, метавон ба санҷишҳои мураккабтар, аз қабили мувофиқат бо таҷрибаҳои беҳтарини стандартӣ ва сиёсатҳои мушаххас гузарад. Дар ин ҷо kube-score ва Polaris муфид хоҳанд буд.

Барои онҳое, ки талаботи мураккаб доранд ва бояд санҷишҳоро ба таври муфассал танзим кунанд, мис, config-lint ва confest мувофиқанд.

Confest ва config-lint YAML-ро барои муайян кардани санҷишҳои фармоишӣ истифода мебаранд ва мис ба шумо ба забони пурраи барномасозӣ дастрасӣ медиҳад, ки онро интихоби хеле ҷолиб месозад.

Аз тарафи дигар, оё меарзад, ки яке аз ин асбобҳоро истифода барад ва аз ин рӯ, ҳама санҷишҳоро дастӣ эҷод кунед ё Polaris-ро афзал донед ва танҳо он чизеро, ки ба он лозим аст, илова кунед? Ба ин савол ҷавоби равшане нест.

Дар ҷадвали зер тавсифи мухтасари ҳар як асбоб оварда шудааст:

Tool
Мақсад
Нобудӣ
Санҷишҳои корбар

кубевал
YAML-ро бар зидди версияи мушаххаси схемаи API тасдиқ мекунад
Бо CRD кор кардан мумкин нест
нест

кубе-хол
Таҳлилҳои YAML-ро бар зидди таҷрибаҳои беҳтарин таҳлил мекунад
Барои тафтиши захираҳо версияи API-и Kubernetes-и худро интихоб карда наметавонед
нест

мис
Чаҳорчӯбаи умумӣ барои эҷоди санҷишҳои фармоишии JavaScript барои манифестҳои YAML
Ҳеҷ гуна санҷишҳои дарунсохт. Ҳуҷҷатҳои бад
он

config-lint
Чаҳорчӯбаи умумӣ барои эҷоди тестҳо дар забони мушаххаси домен, ки дар YAML ворид карда шудааст. Форматҳои гуногуни конфигуратсияро дастгирӣ мекунад (масалан, Terraform)
Санҷишҳои тайёр вуҷуд надоранд. Тасдиқҳо ва функсияҳои дарунсохт кофӣ нестанд
он

мусобика
Чаҳорчӯба барои сохтани санҷишҳои шахсии худ бо истифода аз Rego (забони махсуси дархост). Ба мубодилаи сиёсатҳо тавассути бастаҳои OCI иҷозат медиҳад
Ҳеҷ гуна санҷишҳои дарунсохт. Ман бояд Регоро омӯзам. Ҳангоми нашри сиёсатҳо Docker Hub дастгирӣ намешавад
он

Polaris
Баррасиҳои YAML дар муқоиса бо таҷрибаҳои беҳтарини стандартӣ зоҳир мешавад. Ба шумо имкон медиҳад, ки бо истифода аз JSON Schema санҷишҳои шахсии худро эҷод кунед
Имкониятҳои санҷишӣ дар асоси JSON Schema шояд кофӣ набошанд
он

Азбаски ин асбобҳо ба дастрасӣ ба кластери Kubernetes такя намекунанд, насб кардани онҳо осон аст. Онҳо ба шумо имкон медиҳанд, ки файлҳои манбаъро филтр кунед ва ба муаллифони дархостҳои ҷалб дар лоиҳаҳо зуд фикру мулоҳиза гузоред.

PS аз тарҷумон

Инчунин дар блоги мо хонед:

Манбаъ: will.com

Илова Эзоҳ