E hōʻoia i ka Kubernetes YAML e pili ana i nā hana a me nā kulekele maikaʻi loa

Nānā. unuhi.: Me ka ulu nui o nā hoʻonohonoho YAML no nā kaiapuni K8, ʻoi aku ka wikiwiki o ka pono o kā lākou hōʻoia ʻokoʻa. ʻAʻole i koho wale ka mea kākau o kēia loiloi i nā hoʻonā i loaʻa no kēia hana, akā ua hoʻohana pū kekahi i ka Deployment ma ke ʻano he laʻana e ʻike ai pehea lākou e hana ai. Ua lilo ia i mea ʻike nui no ka poʻe hoihoi i kēia kumuhana.

E hōʻoia i ka Kubernetes YAML e pili ana i nā hana a me nā kulekele maikaʻi loa

Aku; DR: Hoʻohālikelike kēia ʻatikala i ʻeono mau mea hana paʻa e hōʻoia a loiloi i nā faila Kubernetes YAML e pili ana i nā hana maikaʻi loa a me nā koi.

Ua wehewehe pinepine ʻia nā hana hana Kubernetes ma ke ʻano o nā palapala YAML. ʻO kekahi o nā pilikia me YAML ka paʻakikī o ka wehewehe ʻana i nā kaohi a i ʻole nā ​​pilina ma waena o nā faila hōʻike.

He aha inā pono mākou e hōʻoia i nā kiʻi āpau i kau ʻia i ka pūʻulu e hele mai mai kahi papa inoa hilinaʻi?

Pehea e hiki ai iaʻu ke pale aku i nā Deployments ʻaʻohe PodDisruptionBudgets mai ka hoʻouna ʻana i ka pūʻulu?

ʻO ka hoʻohui ʻana o ka hoʻāʻo static e ʻae iā ʻoe e ʻike i nā hewa a me nā hewa kulekele i ka pae hoʻomohala. Hoʻonui kēia i ka ʻoiaʻiʻo he pololei a paʻa ka wehewehe ʻana i nā kumuwaiwai, a ʻoi aku ka maikaʻi o ka hana ʻana i nā hana maikaʻi loa.

Hiki ke hoʻokaʻawale ʻia ke kaiaola kaiaola static file YAML Kubernetes i nā ʻāpana penei:

  • Nā mea hōʻoia API. E nānā nā mea hana ma kēia māhele i ka hōʻike YAML e kūʻē i nā koi o ke kikowaena API Kubernetes.
  • Mākaukau nā mea hōʻike. Hele mai nā mea hana mai kēia māhele me nā hoʻokolohua mākaukau no ka palekana, ka hoʻokō ʻana i nā hana maikaʻi loa, etc.
  • Nā mea hōʻoia maʻamau. ʻAe nā ʻelele o kēia ʻāpana iā ʻoe e hana i nā hoʻokolohua maʻamau i nā ʻōlelo like ʻole, no ka laʻana, Rego a me Javascript.

Ma kēia ʻatikala e wehewehe a hoʻohālikelike mākou i ʻeono mau mea hana like ʻole:

  1. kubeval;
  2. kube-helu;
  3. config-lint;
  4. keleawe;
  5. paio;
  6. polaris.

ʻAe, e hoʻomaka kākou!

Ke nānā ʻana i nā hoʻolālā

Ma mua o ka hoʻomaka ʻana i ka hoʻohālikelike ʻana i nā mea hana, e hana kāua i kahi kāʻei e hoʻāʻo ai iā lākou.

Aia i loko o ka manifesto ma lalo kekahi mau hewa a me ka hoʻokō ʻole ʻana i nā hana maikaʻi loa: ʻehia ka nui o lākou e ʻike ai?

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)

E hoʻohana mākou i kēia YAML e hoʻohālikelike i nā mea hana like ʻole.

ʻO ka manifesto ma luna base-valid.yaml a me nā hōʻike ʻē aʻe mai kēia ʻatikala hiki ke loaʻa ma Nā waihona waihona Git.

Hōʻike ka hōʻike i kahi palapala noi pūnaewele nona ka hana nui e pane me kahi memo "Hello World" i ka port 5678. Hiki ke kau ʻia me kēia kauoha:

kubectl apply -f hello-world.yaml

A pēlā - e nānā i ka hana:

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

I kēia manawa e hele i http://localhost:8080 a hōʻoia i ka hana ʻana o ka noi. Akā, hahai anei ia i nā hana maikaʻi loa? E nānā kāua.

1. Kubeval

Ma ka puuwai o kubeval ʻO ka manaʻo ʻo ia ka pili ʻana me Kubernetes ma o kāna REST API. I nā huaʻōlelo ʻē aʻe, hiki iā ʻoe ke hoʻohana i kahi schema API e nānā ai inā pili ka YAML iā ia. E nānā kākou i kekahi laʻana.

Nā kuhikuhi hoʻonohonoho Loaʻa ka kubeval ma ka pūnaewele papahana.

I ka manawa e kākau ai i ka ʻatikala kumu, loaʻa ka mana 0.15.0.

Ke hoʻokomo ʻia, e hānai iā ia i ka hōʻike ma luna:

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

Inā kūleʻa, e puka ka kubeval me ka code exit 0. Hiki iā ʻoe ke nānā iā ia penei:

$ echo $?
0

E ho'āʻo kākou i ke kubeval me kahi hōʻike ʻokoʻa:

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)

Hiki iā ʻoe ke ʻike i ka pilikia ma ka maka? E hoʻomaka kākou:

$ 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

ʻAʻole hōʻoia ʻia ka punawai.

Ka hoʻohana ʻana i ka mana API apps/v1, pono e hoʻokomo i kahi mea koho i kūpono i ka lepili o ka pod. ʻAʻole i hoʻokomo ʻia ka mea koho ma ka hōʻike ma luna, no laila ua hōʻike ʻo kubeval i kahi hewa a puka i waho me kahi code zero-zero.

Manaʻo wau he aha ka hopena inā hana wau kubectl apply -f me kēia manifesto?

ʻAe, e hoʻāʻo kāua:

$ 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

ʻO kēia ka hewa i ʻōlelo ʻia e kubeval. Hiki iā ʻoe ke hoʻoponopono iā ia ma ka hoʻohui ʻana i kahi mea koho:

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)

ʻO ka pōmaikaʻi o nā mea hana e like me kubeval ʻo ia ka hiki ke hopu ʻia nā hewa e like me kēia i ka wā mua o ke kaʻina hoʻonohonoho.

Eia kekahi, ʻaʻole pono kēia mau loiloi i ke komo ʻana i ka pūʻulu; hiki ke hana ma waho.

Ma ka paʻamau, nānā ʻo kubeval i nā kumuwaiwai kūʻē i ka schema Kubernetes API hou loa. Eia naʻe, i ka hapanui o nā hihia, pono paha ʻoe e nānā i kahi hoʻokuʻu Kubernetes kikoʻī. Hiki ke hana i kēia me ka hoʻohana ʻana i ka hae --kubernetes-version:

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

E ʻoluʻolu e hoʻomaopopo pono ʻia ka mana ma ke ʻano Major.Minor.Patch.

No ka papa inoa o nā mana i kākoʻo ʻia ka hōʻoia, e ʻoluʻolu e nānā i JSON schema ma GitHub, i hoʻohana ʻia e kubeval no ka hōʻoia ʻana. Inā pono ʻoe e holo i ka kubeval offline, hoʻoiho i nā schemas a kuhikuhi i ko lākou wahi kūloko me ka hoʻohana ʻana i ka hae --schema-location.

Ma kahi o nā faila YAML pākahi, hiki i ke kubeval ke hana pū me nā papa kuhikuhi a me stdin.

Eia kekahi, hoʻohui maʻalahi ʻo Kubeval i ka pipeline CI. E hauʻoli ka poʻe e makemake ana e hoʻāʻo ma mua o ka hoʻouna ʻana i nā hōʻike i ka hui ʻike e kākoʻo ana ʻo kubeval i ʻekolu ʻano puka:

  1. He kikokikona maʻalahi;
  2. JSON;
  3. E ho'āʻo i nā mea āpau (TAP).

A hiki ke hoʻohana ʻia kekahi o nā ʻano no ka hoʻopau hou ʻana i ka hopena e hana i kahi hōʻuluʻulu o nā hopena o ke ʻano makemake.

ʻO kekahi o nā hemahema o kubeval ʻo ia ʻaʻole hiki iā ia ke nānā i ka hoʻokō ʻana me Custom Resource Definitions (CRDs). Eia naʻe, hiki ke hoʻonohonoho i ka kubeval haʻalele iā lākou.

He mea hana maikaʻi ʻo Kubeval no ka nānā ʻana a me ka loiloi ʻana i nā kumuwaiwai; Eia nō naʻe, pono e hoʻokūpaʻa ʻia ʻaʻole e hōʻoiaʻiʻo ʻia ka hoʻokō ʻana i ka hoʻāʻo ʻana e hoʻokō ka kumuwaiwai i nā hana maikaʻi loa.

No ka laʻana, me ka hoʻohana ʻana i ka tag latest i loko o kahi ipu ʻaʻole hahai i nā hana maikaʻi loa. Eia naʻe, ʻaʻole manaʻo ʻo kubeval he hewa kēia a ʻaʻole hōʻike. ʻO ia hoʻi, e hoʻopau ʻia ka hōʻoia ʻana o ia YAML me ka ʻole o nā ʻōlelo aʻo.

Akā pehea inā makemake ʻoe e loiloi iā YAML a ʻike i nā hewa e like me ka tag latest? Pehea wau e nānā ai i kahi faila YAML e pili ana i nā hana maikaʻi loa?

2. Kube-helu

Kube-helu parses YAML hōʻike a loiloi iā lākou e kūʻē i nā hoʻokolohua i kūkulu ʻia. Ua koho ʻia kēia mau hoʻokolohua ma muli o nā alakaʻi palekana a me nā hana maikaʻi loa, e like me:

  • Ka holo ʻana i ka ipu ʻaʻole ma ke kumu.
  • Loaʻa i nā nānā olakino pod.
  • Hoʻonohonoho i nā noi a me nā palena no nā kumuwaiwai.

Ma muli o nā hopena hoʻokolohua, hāʻawi ʻia ʻekolu mau hopena: OK, Aʻo и NO KA KULA.

Hiki iā ʻoe ke hoʻāʻo iā Kube-score ma ka pūnaewele a i ʻole e hoʻokomo iā ia ma ka ʻāina.

I ka manawa e kākau ai i ka ʻatikala kumu, ʻo ka mana hou o kube-score ʻo 1.7.0.

E hoao kakou ma ko kakou hoike 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.

Hoʻopau ʻo YAML i nā hoʻokolohua kubeval, aʻo ka kube-score e kuhikuhi ana i kēia mau hemahema:

  • ʻAʻole i hoʻonohonoho ʻia nā loiloi mākaukau.
  • ʻAʻohe noi a palena ʻole no nā kumuwaiwai CPU a me ka hoʻomanaʻo.
  • ʻAʻole i kuhikuhi ʻia nā kumukūʻai hoʻopōʻino pod.
  • ʻAʻohe kānāwai kaʻawale (kūʻē i ka pilina) e hoʻonui i ka loaʻa.
  • Holo ka ipu i ke kumu.

ʻO kēia nā manaʻo kūpono e pili ana i nā hemahema e pono e hoʻoponopono ʻia i mea e ʻoi aku ka maikaʻi a me ka hilinaʻi o Deployment.

hui kube-score hōʻike i ka ʻike ma ke ʻano hiki ke heluhelu ʻia e ke kanaka me nā ʻano hewa āpau Aʻo и NO KA KULA, he mea kōkua nui i ka wā hoʻomohala.

ʻO ka poʻe e makemake ana e hoʻohana i kēia mea hana i loko o ka pipeline CI hiki ke hoʻohana i ka hoʻopuka paʻa ʻoi aku me ka hoʻohana ʻana i ka hae --output-format ci (i kēia hihia, hōʻike pū ʻia nā hoʻokolohua me ka hopena 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

E like me kubeval, hoʻihoʻi ka kube-score i kahi code puka ʻole ʻole inā loaʻa kahi hoʻāʻo i hāʻule. NO KA KULA. Hiki iā ʻoe ke ʻae i ka hana like no Aʻo.

Eia hou, hiki ke nānā i nā kumuwaiwai no ka hoʻokō ʻana i nā mana API like ʻole (e like me ka kubeval). Eia naʻe, paʻakikī kēia ʻike i ka kube-score ponoʻī: ʻaʻole hiki iā ʻoe ke koho i kahi mana ʻokoʻa o Kubernetes. Hiki i kēia palena ke lilo i pilikia nui inā makemake ʻoe e hoʻomaikaʻi i kāu puʻupuʻu a i ʻole he mau puʻupuʻu me nā ʻano like ʻole o nā K8.

kahakaha i aia kekahi pilikia me ka manaʻo e hoʻokō i kēia manawa kūpono.

Hiki ke loaʻa ka ʻike hou aku e pili ana i ka kube-score ma kahua pūnaewele.

He mea hana maikaʻi nā hoʻokolohua Kube-score no ka hoʻokō ʻana i nā hana maikaʻi loa, akā pehea inā pono ʻoe e hoʻololi i ka hoʻāʻo a hoʻohui i kāu mau lula ponoʻī? Auwe, ʻaʻole hiki ke hana i kēia.

ʻAʻole hiki ke hoʻonui ʻia ka helu Kube: ʻaʻole hiki iā ʻoe ke hoʻohui i nā kulekele iā ia a hoʻololi paha.

Inā pono ʻoe e kākau i nā hoʻokolohua maʻamau e hōʻoia i ka hoʻokō ʻana i nā kulekele ʻoihana, hiki iā ʻoe ke hoʻohana i kekahi o kēia mau mea hana ʻehā: config-lint, copper, conftest, a i ʻole polaris.

3.Config-lint

ʻO Config-lint kahi mea hana no ka hōʻoia ʻana iā YAML, JSON, Terraform, nā faila hoʻonohonoho CSV a me nā hōʻike Kubernetes.

Hiki iā ʻoe ke hoʻouka me ka hoʻohana ʻana kuhikuhi ma ka pūnaewele papahana.

ʻO ka hoʻokuʻu ʻana i kēia manawa e like me ka manawa i kākau ai i ka ʻatikala kumu ʻo 1.5.0.

ʻAʻohe o Config-lint i nā hoʻāʻo i kūkulu ʻia no ka hōʻoia ʻana i nā hōʻike Kubernetes.

No ka hana ʻana i nā hoʻokolohua, pono ʻoe e hana i nā lula kūpono. Ua kākau ʻia lākou ma nā faila YAML i kapa ʻia "rulesets" (nā lula), a loaʻa ke ʻano penei:

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

(rule.yaml)

E aʻo pono kākou:

  • kahua type kuhikuhi i ke ʻano o ka hoʻonohonoho config-lint e hoʻohana ai. No nā K8s hōʻike kēia i nā manawa a pau Kubernetes.
  • Ma kahua files Ma waho aʻe o nā faila ponoʻī, hiki iā ʻoe ke kuhikuhi i kahi papa kuhikuhi.
  • kahua rules i manaʻo ʻia no ka hoʻonohonoho ʻana i nā hoʻokolohua mea hoʻohana.

E ʻōlelo mākou makemake ʻoe e hōʻoia e hoʻoiho mau ʻia nā kiʻi ma Deployment mai kahi waihona hilinaʻi e like me my-company.com/myapp:1.0. ʻO kahi lula config-lint e hana ana i kahi loiloi e like me kēia:

- 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)

Pono nā ʻano o kēlā me kēia lula:

  • id - mea hōʻike kū hoʻokahi o ka lula;
  • severity - Malia paha HOLE, Aʻo и NON_COMPLIANT;
  • message - inā i uhaki ʻia kahi lula, hōʻike ʻia nā mea o kēia laina;
  • resource - ke ʻano o nā kumuwaiwai e pili ai kēia lula;
  • assertions - he papa inoa o nā kūlana e loiloi ʻia e pili ana i kēia kumuwaiwai.

Ma ka rula maluna assertion malalo o ka inoa every hōʻoia aia nā pahu a pau i ka Deployment (key: spec.templates.spec.containers) hoʻohana i nā kiʻi hilinaʻi (ʻo ia hoʻi my-company.com/).

Penei ka lula piha:

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)

No ka hoʻāʻo ʻana i ka hoʻāʻo, e mālama iā ia ma ke ʻano check_image_repo.yaml. E holo kāua i kahi hōʻoia ma ka faila 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"
  }
]

Ua hāʻule ka māka. I kēia manawa, e nānā kākou i kēia hōʻike me ka waihona kiʻi kūpono:

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)

Holo mākou i ka hoʻāʻo like me ka hōʻike ma luna. ʻAʻohe pilikia i loaʻa:

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

ʻO Config-lint kahi papa hana hoʻohiki e hiki ai iā ʻoe ke hana i kāu mau hoʻāʻo ponoʻī e hōʻoia i nā hōʻike Kubernetes YAML me ka hoʻohana ʻana i ka YAML DSL.

Akā, pehea inā makemake ʻoe i nā loiloi paʻakikī a me nā hoʻāʻo? ʻAʻole i kaupalena ʻia ʻo YAML no kēia? He aha inā hiki iā ʻoe ke hana i nā hoʻokolohua ma kahi ʻōlelo hoʻolālā piha?

4. Keleawe

Ke keleawe V2 he ʻano hana no ka hōʻoia ʻana i nā hōʻike me ka hoʻohana ʻana i nā hoʻokolohua maʻamau (e like me config-lint).

Eia naʻe, ʻokoʻa ia mai ka mea hope ʻaʻole ia e hoʻohana iā YAML e wehewehe i nā hoʻokolohua. Hiki ke kākau ʻia nā hoʻāʻo ma JavaScript. Hāʻawi ʻo Copper i kahi waihona me nā mea hana maʻamau, kōkua iā ʻoe e heluhelu i ka ʻike e pili ana i nā mea Kubernetes a hōʻike i nā hewa.

Hiki ke loaʻa nā ʻanuʻu no ka hoʻokomo ʻana i ka Copper ma palapala kūhelu.

ʻO 2.0.1 ka hoʻokuʻu hou loa o kēia pono i ka manawa e kākau ai i ka ʻatikala kumu.

E like me config-lint, ʻaʻohe o Copper i nā hoʻokolohua i kūkulu ʻia. E kākau kāua i hoʻokahi. E nānā i ka hoʻohana ʻana i nā kiʻi pahu pahu wale nō mai nā waihona hilinaʻi like my-company.com.

Hana i kahi faila check_image_repo.js me keia mau mea:

$$.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)
            }
        });
    }
});

I kēia manawa e hoʻāʻo i kā mākou hōʻike base-valid.yaml, hoʻohana i ke kauoha 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

Ua maopopo me ke kōkua o ke keleawe hiki iā ʻoe ke hana i nā hoʻokolohua ʻoi aku ka paʻakikī - no ka laʻana, ke nānā ʻana i nā inoa domain ma Ingress hōʻike a hōʻole paha i nā pods e holo ana ma ke ʻano hiʻona.

Loaʻa i ka Copper nā hana pono like ʻole i kūkulu ʻia i loko:

  • DockerImage Heluhelu i ka faila hoʻokomo i kuhikuhi ʻia a hana i kahi mea me kēia mau ʻano:
    • name - inoa o ke kiʻi,
    • tag - hōʻailona kiʻi,
    • registry - kākau inoa kiʻi,
    • registry_url - protocol (https://) a me ke kākau inoa kiʻi,
    • fqin - kahi piha o ke kiʻi.
  • kuleana pili i findByName kōkua i ka ʻimi ʻana i kahi kumuwaiwai e kekahi ʻano i hāʻawi ʻia (kind) a me ka inoa (name) mai ka waihona hoʻokomo.
  • kuleana pili i findByLabels kōkua i ka ʻimi ʻana i kahi kumuwaiwai ma kahi ʻano kikoʻī (kind) a me nā lepili (labels).

Hiki iā ʻoe ke nānā i nā hana lawelawe āpau i loaʻa maanei.

Ma ka maʻamau, hoʻouka ia i ka faila YAML komo i loko o kahi loli $$ a hoʻolako iā ia no ka kākau ʻana (he ʻenehana maʻamau no ka poʻe me ka ʻike jQuery).

ʻIke ʻia ka pono nui o Copper: ʻaʻole pono ʻoe e aʻo i kahi ʻōlelo kūikawā a hiki iā ʻoe ke hoʻohana i nā hiʻohiʻona JavaScript e hana i kāu mau hoʻāʻo ponoʻī, e like me ke string interpolation, functions, etc.

Pono e hoʻomaopopo ʻia e hana ana ka mana o Copper i kēia manawa me ka mana ES5 o ka mīkini JavaScript, ʻaʻole ES6.

Loaʻa nā kikoʻī ma kahua kahua papahana kūhelu.

Eia naʻe, inā ʻaʻole ʻoe makemake i ka JavaScript a makemake ʻoe i kahi ʻōlelo i hoʻolālā ʻia no ka hoʻokumu ʻana i nā nīnau a wehewehe i nā kulekele, pono ʻoe e hoʻolohe i ka hakakā.

5. Hoʻopaʻapaʻa

ʻO Conftest kahi hoʻolālā no ka hoʻāʻo ʻana i ka ʻikepili hoʻonohonoho. He kūpono no ka hoʻāʻo ʻana/hōʻoia i nā hōʻike Kubernetes. Hōʻike ʻia nā hoʻokolohua me ka hoʻohana ʻana i kahi ʻōlelo nīnau nīnau kūikawā Rego.

Hiki iā ʻoe ke hoʻouka i ka conftest me ka hoʻohana ʻana kuhikuhihelu ʻia ma ka pūnaewele papahana.

I ka manawa e kākau ai i ka ʻatikala kumu, ʻo ka mana hou loa i loaʻa ʻo 0.18.2.

E like me ka config-lint a me ke keleawe, hele mai ka conftest me ka ʻole o nā hoʻāʻo i kūkulu ʻia. E hoʻāʻo kākou a kākau i kā kākou kulekele ponoʻī. E like me nā hiʻohiʻona mua, e nānā mākou inā lawe ʻia nā kiʻi pahu mai kahi kumu hilinaʻi.

E hana i papa kuhikuhi conftest-checks, a i loko o laila he faila i kapa ʻia check_image_registry.rego me keia mau mea:

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])
}

I kēia manawa e hoʻāʻo kāua 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

ʻAʻole hiki ke hoʻāʻo ʻia no ka mea i hele mai nā kiʻi mai kahi kumu hilinaʻi ʻole.

Ma ka faila Rego, wehewehe mākou i ka poloka deny. Ua manaʻo ʻia kona ʻoiaʻiʻo he uhaki. Ina poloka deny ʻO kekahi, e nānā kūʻokoʻa ka contest iā lākou mai kekahi i kekahi, a ua mālama ʻia ka ʻoiaʻiʻo o kekahi o nā poloka ma ke ʻano he uhaki.

Ma waho aʻe o ka hoʻopuka paʻamau, kākoʻo ka conftest iā JSON, TAP a me ke ʻano papa - he hiʻohiʻona maikaʻi loa inā pono ʻoe e hoʻokomo i nā hōʻike i loko o kahi pipeline CI. Hiki iā ʻoe ke hoʻonohonoho i ke ʻano makemake me ka hoʻohana ʻana i ka hae --output.

I mea e maʻalahi ai ka debug i nā kulekele, he hae ko conftest --trace. Hoʻopuka ia i kahi ʻano o ka hoʻopaʻa ʻana o ka conftest i nā faila kulekele i kuhikuhi ʻia.

Hiki ke paʻi ʻia nā kulekele hoʻokūkū a kaʻana like i loko o nā papa inoa OCI (Open Container Initiative) ma ke ʻano he mea kiʻi.

Nā Pūʻulu push и pull e ʻae iā ʻoe e hoʻopuka i kahi kiʻi kiʻi a i ʻole e kiʻi i kahi mea i loaʻa mai kahi papa inoa mamao. E ho'āʻo mākou e hoʻopuka i ke kulekele a mākou i hana ai i ka hoʻopaʻa inoa Docker kūloko me ka hoʻohana ʻana conftest push.

E hoʻomaka i kāu papa inoa Docker kūloko:

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

Ma kahi pahu ʻē aʻe, e hele i ka papa kuhikuhi āu i hana ai ma mua conftest-checks a holo i kēia kauoha:

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

Inā kūleʻa ke kauoha, e ʻike ʻoe i kahi memo e like me kēia:

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

E hana i kahi papa kuhikuhi no ka manawa pōkole a holo i ke kauoha i loko conftest pull. E hoʻoiho i ka pōʻai i hana ʻia e ke kauoha mua:

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

E hōʻike ʻia kahi papa kuhikuhi ma ka papa kuhikuhi manawa policyi loko o kā mākou waihona kulekele:

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

Hiki ke holo pololei nā hoʻokolohua mai ka waihona:

$ 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

ʻO ka mea pōʻino, ʻaʻole i kākoʻo ʻia ʻo DockerHub. No laila e noʻonoʻo iā ʻoe iho he laki inā hoʻohana ʻoe Kakau inoa pahu Azure (ACR) a i ʻole kāu kau inoa ponoʻī.

ʻO ke ʻano kiʻi kiʻi like me E wehe i nā pūʻolo ʻAgent Policy (OPA), hiki iā ʻoe ke hoʻohana i ka conftest e holo i nā hoʻokolohua mai nā pūʻolo OPA i loaʻa.

Hiki iā ʻoe ke aʻo hou aʻe e pili ana i ka māhele kulekele a me nā hiʻohiʻona ʻē aʻe o ka hakakā ma kahua kahua papahana kūhelu.

6. Polaris

ʻO ka mea hana hope e kūkākūkā ʻia ma kēia ʻatikala Polaris. (ʻO kāna hoʻolaha o ka makahiki hope iā mākou ua unuhiia - kokoke. unuhi)

Hiki ke hoʻokomo ʻia ʻo Polaris i kahi hui a hoʻohana ʻia i ke ʻano laina kauoha. E like me kāu i manaʻo ai, hiki iā ʻoe ke nānā i nā hōʻike Kubernetes.

Ke holo nei ma ke ʻano laina kauoha, loaʻa nā hoʻāʻo i kūkulu ʻia e uhi ana i nā wahi e like me ka palekana a me nā hana maikaʻi loa (e like me ka kube-score). Eia hou, hiki iā ʻoe ke hana i kāu mau hoʻāʻo ponoʻī (e like me ka config-lint, copper and conftest).

I nā huaʻōlelo ʻē aʻe, hoʻohui ʻo Polaris i nā pono o nā ʻāpana ʻelua o nā mea hana: me nā hoʻokolohua i kūkulu ʻia a maʻamau.

No ka hoʻouka ʻana iā Polaris ma ke ʻano laina kauoha, e hoʻohana nā kuhikuhi ma ka pūnaewele papahana.

I ka manawa e kākau ai i ka ʻatikala kumu, loaʻa ka mana 1.0.3.

Ke pau ka hoʻokomo ʻana hiki iā ʻoe ke holo i ka polaris ma ka hōʻike base-valid.yaml me keia kauoha:

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

E hoʻopuka ia i kahi kaula i ka format JSON me ka wehewehe kikoʻī o nā hoʻokolohua i hana ʻia a me kā lākou hopena. E loaʻa i ka huahana ke ʻano penei:

{
  "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": [
    /* длинный список */
  ]
}

Loaʻa nā huahana piha maanei.

E like me ka kube-score, ua ʻike ʻo Polaris i nā pilikia ma nā wahi i kū ʻole ai ka hōʻike i nā hana maikaʻi loa:

  • ʻAʻohe nānā olakino no nā pods.
  • ʻAʻole i kuhikuhi ʻia nā lepili no nā kiʻi pahu.
  • Holo ka ipu i ke kumu.
  • ʻAʻole i kuhikuhi ʻia nā noi a me nā palena no ka hoʻomanaʻo a me ka CPU.

ʻO kēlā me kēia ho'āʻo, ma muli o kāna mau hopena, ua hāʻawi ʻia i kahi degere koʻikoʻi: ke ao ai ole ia, weliweli. No ka ʻike hou aku e pili ana i nā hoʻāʻo i kūkulu ʻia, e ʻoluʻolu e nānā palapala.

Inā ʻaʻole pono nā kikoʻī, hiki iā ʻoe ke kuhikuhi i ka hae --format score. I kēia hihia, e hoʻopuka ʻo Polaris i kahi helu mai ka 1 a hiki i ka 100 − manual (ʻo ia hoʻi ka loiloi):

$ polaris audit --audit-path test-data/base-valid.yaml --format score
68

ʻOi aku ka pili o ka helu i 100, ʻoi aku ka kiʻekiʻe o ke kiʻekiʻe o ka ʻaelike. Inā ʻoe e nānā i ke code puka o ke kauoha polaris audit, ua like ia me 0.

Ka ikaika polaris audit Hiki iā ʻoe ke hoʻopau i ka hana me ka code non-zero me ka hoʻohana ʻana i nā hae ʻelua:

  • Ho'āka --set-exit-code-below-score lawe ʻia ma ke ʻano he hoʻopaʻapaʻa i ka waiwai paepae ma ka laulā 1-100. I kēia hihia, e haʻalele ke kauoha me ka code exit 4 inā aia ka helu ma lalo o ka paepae. He mea maikaʻi loa kēia inā loaʻa iā ʻoe kahi waiwai paepae (e ʻōlelo ʻo 75) a pono ʻoe e loaʻa i kahi mākaʻikaʻi inā hele ka helu ma lalo.
  • Ho'āka --set-exit-code-on-danger e hāʻule ke kauoha me ke code 3 inā hāʻule kekahi o nā hoʻokolohua pilikia.

I kēia manawa e hoʻāʻo mākou e hana i kahi hoʻokolohua maʻamau e nānā inā lawe ʻia ke kiʻi mai kahi waihona hilinaʻi. Hōʻike ʻia nā hoʻāʻo maʻamau i ka format YAML, a ua wehewehe ʻia ka hoʻāʻo ponoʻī me ka JSON Schema.

Hōʻike ka YAML code snippet i kahi hōʻike hou i kapa ʻia 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/.+$

E nānā pono kākou iā ia:

  • successMessage - e paʻi ʻia kēia laina inā pau ka hoʻāʻo ʻana;
  • failureMessage - e hōʻike ʻia kēia memo i ka wā o ka hāʻule;
  • category - hōʻike i kekahi o nā ʻano: Images, Health Checks, Security, Networking и Resources;
  • target--- hoʻoholo i ke ʻano o ka mea (spec) hoʻohana ʻia ka hoʻāʻo. Nā waiwai kūpono: Container, Pod ai ole ia, Controller;
  • Hōʻike ʻia ka hoʻāʻo ponoʻī i ka mea schema me ka hoʻohana ʻana i ka schema JSON. ʻO ka huaʻōlelo koʻikoʻi ma kēia hoʻokolohua pattern hoʻohana ʻia e hoʻohālikelike i ke kumu kiʻi me ka mea i makemake ʻia.

No ka holo ʻana i ka hoʻāʻo ma luna, pono ʻoe e hana i ka hoʻonohonoho Polaris aʻe:

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)

E wehe kākou i ka faila:

  • Ma kahua checks kau ʻia nā hoʻokolohua a me ko lākou pae koʻikoʻi. No ka mea makemake ʻia e loaʻa kahi ʻōlelo aʻo i ka wā i lawe ʻia ai kahi kiʻi mai kahi kumu hilinaʻi ʻole, hoʻonoho mākou i ka pae ma aneʻi danger.
  • ʻO ka hoʻāʻo ponoʻī checkImageRepo a laila hoʻopaʻa inoa i ka mea customChecks.

E mālama i ka faila e like me custom_check.yaml. I kēia manawa hiki iā ʻoe ke holo polaris audit me kahi hōʻike YAML e pono ai ka hōʻoia.

E ho'āʻo kākou i kā mākou manifesto base-valid.yaml:

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

hui polaris audit holo wale i ka ho'āʻo mea hoʻohana i ʻōlelo ʻia ma luna a ua hāʻule.

Inā hoʻoponopono ʻoe i ke kiʻi i my-company.com/http-echo:1.0, E hoʻopau pono ʻo Polaris. Aia ka manifesto me nā hoʻololi hale waihonano laila hiki iā ʻoe ke nānā i ke kauoha mua ma ka hōʻike image-valid-mycompany.yaml.

Ke kū nei ka nīnau: pehea e holo ai i nā hoʻokolohua i kūkulu ʻia me nā mea maʻamau? Maʻalahi! Pono ʻoe e hoʻohui i nā mea hōʻike hōʻike i kūkulu ʻia i ka faila hoʻonohonoho. ʻO ka hopena, e lawe ʻia kēia ʻano:

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)

Loaʻa kahi laʻana o kahi faila hoʻonohonoho piha maanei.

Hōʻike hōʻike base-valid.yamlme ka hoʻohana ʻana i nā hoʻokolohua i kūkulu ʻia a maʻamau, hiki iā ʻoe ke hoʻohana i ke kauoha:

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

Hoʻopiha ʻo Polaris i nā hoʻokolohua i kūkulu ʻia me nā mea maʻamau, a laila e hoʻohui i ka maikaʻi o nā ao ʻelua.

Ma ka ʻaoʻao ʻē aʻe, ʻo ka hiki ʻole ke hoʻohana i nā ʻōlelo ʻoi aku ka ikaika e like me Rego a i ʻole JavaScript hiki ke lilo i mea palena e pale ai i ka hana ʻana i nā hoʻokolohua ʻoi aku ka maʻalahi.

Loaʻa ka ʻike hou aku e pili ana iā Polaris ma pūnaewele papahana.

Hōʻuluʻulu

ʻOiai he nui nā mea hana e nānā a loiloi i nā faila Kubernetes YAML, he mea nui ka ʻike maopopo i ke ʻano o ka hoʻolālā ʻana a me ka hana ʻana o nā hoʻokolohua.

No kekahi laʻana, inā ʻoe e lawe i nā hōʻike Kubernetes e hele ana ma kahi pipeline, hiki i ka kubeval ke hana mua i ka pipeline.. E nānā ʻo ia i ka hoʻohālikelike ʻana o nā mea i ka Kubernetes API schema.

Ke hoʻopau ʻia kēlā loiloi, hiki i kekahi ke neʻe i nā hoʻokolohua ʻoi aku ka maʻalahi, e like me ka hoʻokō ʻana i nā hana maikaʻi maʻamau a me nā kulekele kikoʻī. ʻO kēia kahi e hiki mai ai ka kube-score a me Polaris.

No ka poʻe i loaʻa nā koi paʻakikī a pono e hana i nā hoʻokolohua kikoʻī, kūpono ke keleawe, config-lint a me ka conftest..

Hoʻohana ʻo Conftest a me config-lint i ka YAML e wehewehe i nā hoʻokolohua maʻamau, a hāʻawi ke keleawe iā ʻoe i ke komo ʻana i kahi ʻōlelo hoʻonohonoho piha, e lilo ia i koho nani.

Ma ka ʻaoʻao ʻē aʻe, pono paha e hoʻohana i kekahi o kēia mau mea hana a, no laila, hana lima i nā hoʻokolohua āpau, a makemake paha iā Polaris a hoʻohui wale i nā mea e pono ai? ʻAʻohe pane maopopo i kēia nīnau.

Hāʻawi ka papa ma lalo i kahi wehewehe pōkole o kēlā me kēia mea hana:

Nā mea hana
ʻO ke kumu
hewa
Nā ho'āʻo mea hoʻohana

kubeval
Hōʻoia i nā hōʻike YAML e kūʻē i kahi mana kikoʻī o ka schema API
ʻAʻole hiki ke hana me CRD
No

kube-helu
Nānā i nā hōʻike YAML e kūʻē i nā hana maikaʻi loa
ʻAʻole hiki ke koho i kāu mana Kubernetes API e nānā i nā kumuwaiwai
No

keleawe
He hoʻolālā maʻamau no ka hana ʻana i nā hoʻokolohua JavaScript maʻamau no nā hōʻike YAML
ʻAʻohe hoʻokolohua i kūkulu ʻia. ʻAʻohe palapala
ia

config-lint
He kaʻina hana maʻamau no ka hana ʻana i nā hoʻokolohua ma kahi ʻōlelo kikoʻī kikowaena i hoʻokomo ʻia ma YAML. Kākoʻo i nā ʻano hoʻonohonoho like ʻole (e laʻa me Terraform)
ʻAʻohe hoʻokolohua mākaukau. ʻAʻole lawa paha nā ʻōlelo a me nā hana i kūkulu ʻia
ia

paio
He kahua no ka hana ʻana i kāu mau hoʻāʻo ponoʻī me ka hoʻohana ʻana iā Rego (he ʻōlelo nīnau nīnau kūikawā). ʻAe ʻia ke kaʻana like ʻana o nā kulekele ma o nā pūʻulu OCI
ʻAʻohe hoʻokolohua i kūkulu ʻia. Pono wau e aʻo iā Rego. ʻAʻole kākoʻo ʻia ʻo Docker Hub i ka wā e paʻi ana i nā kulekele
ia

Polaris
Hōʻike nā loiloi YAML e kūʻē i nā hana maikaʻi loa. Hiki iā ʻoe ke hana i kāu hoʻāʻo ponoʻī me ka hoʻohana ʻana i ka JSON Schema
ʻAʻole lawa nā mana hoʻāʻo e pili ana i ka JSON Schema
ia

No ka mea ʻaʻole hilinaʻi kēia mau mea hana i ke komo ʻana i ka hui Kubernetes, maʻalahi lākou e hoʻokomo. Hāʻawi lākou iā ʻoe e kānana i nā faila kumu a hāʻawi i nā pane wikiwiki i nā mea kākau o nā noi huki i nā papahana.

PS mai ka unuhi

E heluhelu pū ma kā mākou blog:

Source: www.habr.com

Pākuʻi i ka manaʻo hoʻopuka