Sahkan Kubernetes YAML terhadap amalan dan dasar terbaik

Catatan. terjemah: Dengan peningkatan bilangan konfigurasi YAML untuk persekitaran K8, keperluan untuk pengesahan automatik mereka menjadi semakin mendesak. Pengarang ulasan ini bukan sahaja memilih penyelesaian sedia ada untuk tugas ini, tetapi juga menggunakan Deployment sebagai contoh untuk melihat cara penyelesaian tersebut berfungsi. Ia ternyata sangat bermaklumat bagi mereka yang berminat dengan topik ini.

Sahkan Kubernetes YAML terhadap amalan dan dasar terbaik

TL; DR: Artikel ini membandingkan enam alat statik untuk mengesahkan dan menilai fail YAML Kubernetes berbanding amalan dan keperluan terbaik.

Beban kerja Kubernetes biasanya ditakrifkan dalam bentuk dokumen YAML. Salah satu masalah dengan YAML ialah kesukaran untuk menentukan kekangan atau hubungan antara fail manifes.

Bagaimana jika kita perlu memastikan bahawa semua imej yang digunakan ke kluster datang daripada pendaftaran yang dipercayai?

Bagaimanakah saya boleh menghalang Deployment yang tidak mempunyai PodDisruptionBudgets daripada dihantar ke kluster?

Penyepaduan ujian statik membolehkan anda mengenal pasti ralat dan pelanggaran dasar pada peringkat pembangunan. Ini meningkatkan jaminan bahawa takrifan sumber adalah betul dan selamat, dan menjadikannya lebih berkemungkinan bahawa beban kerja pengeluaran akan mengikut amalan terbaik.

Ekosistem pemeriksaan fail YAML statik Kubernetes boleh dibahagikan kepada kategori berikut:

  • Pengesah API. Alat dalam kategori ini menyemak manifes YAML terhadap keperluan pelayan API Kubernetes.
  • Penguji sedia. Alat daripada kategori ini disertakan dengan ujian sedia untuk keselamatan, pematuhan terhadap amalan terbaik, dsb.
  • Pengesah tersuai. Wakil kategori ini membolehkan anda membuat ujian tersuai dalam pelbagai bahasa, contohnya, Rego dan Javascript.

Dalam artikel ini kami akan menerangkan dan membandingkan enam alat yang berbeza:

  1. kubeval;
  2. kube-skor;
  3. config-lint;
  4. tembaga;
  5. pertandingan;
  6. polaris.

Baiklah, mari kita mulakan!

Menyemak Kerahan

Sebelum kita mula membandingkan alatan, mari kita cipta beberapa latar belakang untuk mengujinya.

Manifesto di bawah mengandungi beberapa ralat dan ketidakpatuhan terhadap amalan terbaik: berapa banyak daripadanya yang boleh anda temui?

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)

Kami akan menggunakan YAML ini untuk membandingkan alat yang berbeza.

Manifesto di atas base-valid.yaml dan manifesto lain daripada artikel ini boleh didapati di Repositori Git.

Manifes menerangkan aplikasi web yang tugas utamanya adalah untuk membalas dengan mesej "Hello World" ke port 5678. Ia boleh digunakan dengan arahan berikut:

kubectl apply -f hello-world.yaml

Dan sebagainya - semak kerja:

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

Sekarang pergi ke http://localhost:8080 dan sahkan bahawa aplikasi itu berfungsi. Tetapi adakah ia mengikut amalan terbaik? Jom semak.

1. Kubeval

Di tengah-tengah kubeval Ideanya ialah sebarang interaksi dengan Kubernetes berlaku melalui API RESTnya. Dengan kata lain, anda boleh menggunakan skema API untuk menyemak sama ada YAML yang diberikan mematuhinya. Mari kita lihat contoh.

arahan pemasangan kubeval boleh didapati di laman web projek.

Pada masa menulis artikel asal, versi 0.15.0 telah tersedia.

Setelah dipasang, mari kita suapkan manifes di atas:

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

Jika berjaya, kubeval akan keluar dengan kod keluar 0. Anda boleh menyemaknya seperti berikut:

$ echo $?
0

Sekarang mari cuba kubeval dengan manifes yang berbeza:

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)

Bolehkah anda melihat masalah dengan mata? Mari kita lancarkan:

$ 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

Sumber tidak disahkan.

Penggunaan menggunakan versi API apps/v1, mesti menyertakan pemilih yang sepadan dengan label pod. Manifes di atas tidak termasuk pemilih, jadi kubeval melaporkan ralat dan keluar dengan kod bukan sifar.

Saya tertanya-tanya apa yang akan berlaku jika saya berbuat demikian kubectl apply -f dengan manifesto ini?

Nah, mari cuba:

$ 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

Inilah ralat yang kubeval beri amaran. Anda boleh membetulkannya dengan menambahkan pemilih:

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)

Faedah alatan seperti kubeval ialah ralat seperti ini boleh ditangkap pada awal kitaran penggunaan.

Selain itu, semakan ini tidak memerlukan akses kepada kluster; ia boleh dilakukan di luar talian.

Secara lalai, kubeval menyemak sumber terhadap skema API Kubernetes terkini. Walau bagaimanapun, dalam kebanyakan kes anda mungkin perlu menyemak keluaran Kubernetes tertentu. Ini boleh dilakukan menggunakan bendera --kubernetes-version:

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

Sila ambil perhatian bahawa versi mesti dinyatakan dalam format Major.Minor.Patch.

Untuk senarai versi yang pengesahan disokong, sila rujuk Skema JSON pada GitHub, yang kubeval gunakan untuk pengesahan. Jika anda perlu menjalankan kubeval luar talian, muat turun skema dan nyatakan lokasi setempatnya menggunakan bendera --schema-location.

Selain fail YAML individu, kubeval juga boleh berfungsi dengan direktori dan stdin.

Di samping itu, Kubeval mudah disepadukan ke dalam saluran paip CI. Mereka yang ingin menjalankan ujian sebelum menghantar manifes kepada kluster akan gembira mengetahui bahawa kubeval menyokong tiga format output:

  1. Teks kosong;
  2. JSON;
  3. Uji Anything Protocol (TAP).

Dan mana-mana format boleh digunakan untuk menghuraikan output selanjutnya untuk menjana ringkasan hasil jenis yang dikehendaki.

Salah satu kelemahan kubeval ialah ia pada masa ini tidak boleh menyemak pematuhan dengan Definisi Sumber Tersuai (CRD). Walau bagaimanapun, adalah mungkin untuk mengkonfigurasi kubeval abaikan mereka.

Kubeval ialah alat yang hebat untuk menyemak dan menilai sumber; Walau bagaimanapun, perlu ditekankan bahawa lulus ujian tidak menjamin bahawa sumber itu mematuhi amalan terbaik.

Contohnya, menggunakan tag latest dalam bekas tidak mengikut amalan terbaik. Walau bagaimanapun, kubeval tidak menganggap ini sebagai ralat dan tidak melaporkannya. Iaitu, pengesahan YAML tersebut akan selesai tanpa amaran.

Tetapi bagaimana jika anda ingin menilai YAML dan mengenal pasti pelanggaran seperti teg latest? Bagaimanakah cara saya menyemak fail YAML terhadap amalan terbaik?

2. Kube-skor

Kube-skor menghuraikan manifes YAML dan menilainya terhadap ujian terbina dalam. Ujian ini dipilih berdasarkan garis panduan keselamatan dan amalan terbaik, seperti:

  • Menjalankan bekas bukan sebagai akar.
  • Ketersediaan pemeriksaan kesihatan pod.
  • Menetapkan permintaan dan had untuk sumber.

Berdasarkan keputusan ujian, tiga keputusan diberikan: OK, BERKHATAN : ΠΈ KRITIKAL.

Anda boleh mencuba Kube-skor dalam talian atau memasangnya secara tempatan.

Pada masa menulis artikel asal, versi terkini kube-score ialah 1.7.0.

Mari cuba pada manifes kami 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 lulus ujian kubeval, manakala skor kube menunjukkan kelemahan berikut:

  • Semakan kesediaan tidak dikonfigurasikan.
  • Tiada permintaan atau had untuk sumber dan memori CPU.
  • Belanjawan gangguan pod tidak dinyatakan.
  • Tiada peraturan pemisahan (anti-afiniti) untuk memaksimumkan ketersediaan.
  • Bekas berfungsi sebagai akar.

Ini semua adalah perkara yang sah tentang kekurangan yang perlu ditangani untuk menjadikan Deployment lebih cekap dan boleh dipercayai.

Pasukan kube-score memaparkan maklumat dalam bentuk yang boleh dibaca manusia termasuk semua jenis pelanggaran BERKHATAN : ΠΈ KRITIKAL, yang banyak membantu semasa pembangunan.

Mereka yang ingin menggunakan alat ini dalam saluran paip CI boleh mendayakan lebih banyak output termampat menggunakan bendera --output-format ci (dalam kes ini, ujian dengan hasilnya juga dipaparkan 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

Sama seperti kubeval, kube-score mengembalikan kod keluar bukan sifar apabila terdapat ujian yang gagal KRITIKAL. Anda juga boleh mendayakan pemprosesan serupa untuk BERKHATAN :.

Di samping itu, adalah mungkin untuk menyemak sumber untuk pematuhan dengan versi API yang berbeza (seperti dalam kubeval). Walau bagaimanapun, maklumat ini dikodkan dalam kube-skor itu sendiri: anda tidak boleh memilih versi Kubernetes yang berbeza. Had ini boleh menjadi masalah besar jika anda berhasrat untuk meningkatkan kluster anda atau jika anda mempunyai berbilang kluster dengan versi K8 yang berbeza.

Sila ambil perhatian bahawa sudah ada isu dengan cadangan untuk merealisasikan peluang ini.

Maklumat lanjut tentang skor kube boleh didapati di laman web rasmi.

Ujian skor Kube ialah alat yang hebat untuk melaksanakan amalan terbaik, tetapi bagaimana jika anda perlu membuat perubahan pada ujian atau menambah peraturan anda sendiri? Malangnya, ini tidak boleh dilakukan.

Skor Kube tidak boleh dilanjutkan: anda tidak boleh menambah dasar padanya atau melaraskannya.

Jika anda perlu menulis ujian tersuai untuk mengesahkan pematuhan dengan dasar syarikat, anda boleh menggunakan salah satu daripada empat alatan berikut: config-lint, copper, conftest atau polaris.

3.Config-lint

Config-lint ialah alat untuk mengesahkan fail konfigurasi YAML, JSON, Terraform, CSV dan manifes Kubernetes.

Anda boleh memasangnya menggunakan arahan di laman web projek.

Keluaran semasa pada masa penulisan artikel asal ialah 1.5.0.

Config-lint tidak mempunyai ujian terbina dalam untuk mengesahkan manifes Kubernetes.

Untuk menjalankan sebarang ujian, anda perlu membuat peraturan yang sesuai. Ia ditulis dalam fail YAML yang dipanggil "peraturan" (peraturan), dan mempunyai struktur berikut:

version: 1
description: Rules for Kubernetes spec files
type: Kubernetes
files:
  - "*.yaml"
rules:
   # список ΠΏΡ€Π°Π²ΠΈΠ»

(rule.yaml)

Mari kita kaji dengan lebih teliti:

  • Bidang type menentukan jenis konfigurasi config-lint yang akan digunakan. Untuk manifes K8 ini adalah sentiasa Kubernetes.
  • Dalam bidang files Sebagai tambahan kepada fail itu sendiri, anda boleh menentukan direktori.
  • Bidang rules bertujuan untuk menetapkan ujian pengguna.

Katakan anda ingin memastikan bahawa imej dalam Deployment sentiasa dimuat turun daripada repositori yang dipercayai seperti my-company.com/myapp:1.0. Peraturan config-lint yang melakukan semakan sedemikian akan kelihatan seperti ini:

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

Setiap peraturan mesti mempunyai atribut berikut:

  • id β€” pengecam unik peraturan;
  • severity - Mungkin KEGAGALAN, BERKHATAN : ΠΈ TIDAK_COMPLIANT;
  • message β€” jika peraturan dilanggar, kandungan baris ini dipaparkan;
  • resource β€” jenis sumber yang peraturan ini terpakai;
  • assertions β€” senarai syarat yang akan dinilai berhubung dengan sumber ini.

Dalam peraturan di atas assertion dipanggil every menyemak bahawa semua bekas berada dalam Deployment (key: spec.templates.spec.containers) gunakan imej yang dipercayai (iaitu bermula dengan my-company.com/).

Set peraturan lengkap kelihatan seperti ini:

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)

Untuk mencuba ujian, mari simpan sebagai check_image_repo.yaml. Mari kita jalankan semakan pada fail 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"
  }
]

Cek gagal. Sekarang mari kita lihat manifes berikut dengan repositori imej yang betul:

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)

Kami menjalankan ujian yang sama dengan manifes di atas. Tiada masalah ditemui:

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

Config-lint ialah rangka kerja yang menjanjikan yang membolehkan anda membuat ujian anda sendiri untuk mengesahkan manifes YAML Kubernetes menggunakan YAML DSL.

Tetapi bagaimana jika anda memerlukan logik dan ujian yang lebih kompleks? Bukankah YAML terlalu terhad untuk ini? Bagaimana jika anda boleh membuat ujian dalam bahasa pengaturcaraan penuh?

4. Tembaga

Kuprum V2 ialah rangka kerja untuk mengesahkan manifes menggunakan ujian tersuai (serupa dengan config-lint).

Walau bagaimanapun, ia berbeza daripada yang terakhir kerana ia tidak menggunakan YAML untuk menerangkan ujian. Ujian boleh ditulis dalam JavaScript sebaliknya. Tembaga menyediakan perpustakaan dengan beberapa alat asas, yang membantu anda membaca maklumat tentang objek Kubernetes dan melaporkan ralat.

Langkah-langkah untuk memasang Copper boleh didapati dalam dokumentasi rasmi.

2.0.1 ialah keluaran terkini utiliti ini pada masa penulisan artikel asal.

Seperti config-lint, Copper tidak mempunyai ujian terbina dalam. Jom tulis satu. Biarkan ia menyemak bahawa penempatan menggunakan imej bekas secara eksklusif daripada repositori yang dipercayai seperti my-company.com.

Buat fail check_image_repo.js dengan kandungan berikut:

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

Sekarang untuk menguji manifes kami base-valid.yaml, gunakan arahan 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

Adalah jelas bahawa dengan bantuan tembaga anda boleh melakukan ujian yang lebih kompleks - contohnya, menyemak nama domain dalam Manifes Ingress atau menolak pod berjalan dalam mod istimewa.

Tembaga mempunyai pelbagai fungsi utiliti terbina di dalamnya:

  • DockerImage membaca fail input yang ditentukan dan mencipta objek dengan atribut berikut:
    • name - nama imej,
    • tag - tag imej,
    • registry - pendaftaran imej,
    • registry_url - protokol (https://) dan pendaftaran imej,
    • fqin β€” lokasi penuh imej.
  • Fungsi findByName membantu mencari sumber mengikut jenis tertentu (kind) dan nama (name) daripada fail input.
  • Fungsi findByLabels membantu mencari sumber mengikut jenis tertentu (kind) dan label (labels).

Anda boleh melihat semua fungsi perkhidmatan yang tersedia di sini.

Secara lalai ia memuatkan keseluruhan fail YAML input ke dalam pembolehubah $$ dan menjadikannya tersedia untuk skrip (teknik biasa bagi mereka yang mempunyai pengalaman jQuery).

Kelebihan utama Copper adalah jelas: anda tidak perlu menguasai bahasa khusus dan anda boleh menggunakan pelbagai ciri JavaScript untuk membuat ujian anda sendiri, seperti interpolasi rentetan, fungsi, dsb.

Perlu diingatkan juga bahawa versi semasa Copper berfungsi dengan versi ES5 enjin JavaScript, bukan ES6.

Butiran boleh didapati di laman web rasmi projek.

Walau bagaimanapun, jika anda tidak begitu menyukai JavaScript dan lebih suka bahasa yang direka khusus untuk membuat pertanyaan dan menerangkan dasar, anda harus memberi perhatian kepada pertandingan.

5.Pertandingan

Conftest ialah rangka kerja untuk menguji data konfigurasi. Juga sesuai untuk menguji/mengesahkan manifes Kubernetes. Ujian diterangkan menggunakan bahasa pertanyaan khusus Rego.

Anda boleh memasang conftest menggunakan arahandisenaraikan di laman web projek.

Pada masa menulis artikel asal, versi terkini yang tersedia ialah 0.18.2.

Sama seperti config-lint dan copper, conftest datang tanpa sebarang ujian terbina dalam. Mari cuba dan tulis dasar kita sendiri. Seperti dalam contoh sebelumnya, kami akan menyemak sama ada imej bekas diambil daripada sumber yang boleh dipercayai.

Buat direktori conftest-checks, dan di dalamnya terdapat fail bernama check_image_registry.rego dengan kandungan berikut:

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

Sekarang mari kita uji base-valid.yaml melalui 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

Ujian itu diramalkan gagal kerana imej datang daripada sumber yang tidak dipercayai.

Dalam fail Rego kami mentakrifkan blok deny. Kebenarannya dianggap sebagai pelanggaran. Jika blok deny beberapa, conftest memeriksa mereka secara bebas antara satu sama lain, dan kebenaran mana-mana blok dianggap sebagai pelanggaran.

Sebagai tambahan kepada output lalai, conftest menyokong format JSON, TAP dan jadual - ciri yang sangat berguna jika anda perlu membenamkan laporan ke dalam saluran paip CI sedia ada. Anda boleh menetapkan format yang dikehendaki menggunakan bendera --output.

Untuk memudahkan anda menyahpepijat dasar, conftest mempunyai bendera --trace. Ia mengeluarkan jejak cara conftest menghuraikan fail dasar yang ditentukan.

Dasar peraduan boleh diterbitkan dan dikongsi dalam pendaftaran OCI (Open Container Initiative) sebagai artifak.

Pasukan push ΠΈ pull membolehkan anda menerbitkan artifak atau mendapatkan semula artifak sedia ada daripada pendaftaran jauh. Mari cuba terbitkan dasar yang kami buat ke pendaftaran Docker tempatan menggunakan conftest push.

Mulakan pendaftaran Docker tempatan anda:

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

Dalam terminal lain, pergi ke direktori yang anda buat sebelum ini conftest-checks dan jalankan arahan berikut:

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

Jika arahan itu berjaya, anda akan melihat mesej seperti ini:

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

Sekarang buat direktori sementara dan jalankan arahan di dalamnya conftest pull. Ia akan memuat turun pakej yang dibuat oleh arahan sebelumnya:

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

Subdirektori akan muncul dalam direktori sementara policymengandungi fail dasar kami:

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

Ujian boleh dijalankan terus dari repositori:

$ 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

Malangnya, DockerHub belum lagi disokong. Jadi anggap diri anda bertuah jika anda menggunakan Pendaftaran Kontena Azure (ACR) atau pendaftaran anda sendiri.

Format artifak adalah sama seperti Buka pakej Ejen Polisi (OPA), yang membolehkan anda menggunakan conftest untuk menjalankan ujian daripada pakej OPA sedia ada.

Anda boleh mengetahui lebih lanjut tentang perkongsian dasar dan ciri kontest lain di laman web rasmi projek.

6. Polaris

Alat terakhir yang akan dibincangkan dalam artikel ini ialah Polaris. (Pengumuman tahun lepas beliau kami sudah diterjemahkan - lebih kurang terjemahan)

Polaris boleh dipasang dalam kelompok atau digunakan dalam mod baris arahan. Seperti yang mungkin anda duga, ini membolehkan anda menganalisis manifes Kubernetes secara statik.

Apabila berjalan dalam mod baris arahan, ujian terbina dalam tersedia meliputi kawasan seperti keselamatan dan amalan terbaik (serupa dengan kube-score). Di samping itu, anda boleh membuat ujian anda sendiri (seperti dalam config-lint, copper dan conftest).

Dengan kata lain, Polaris menggabungkan faedah kedua-dua kategori alat: dengan ujian terbina dalam dan tersuai.

Untuk memasang Polaris dalam mod baris arahan, gunakan arahan di laman web projek.

Pada masa menulis artikel asal, versi 1.0.3 tersedia.

Setelah pemasangan selesai, anda boleh menjalankan polaris pada manifes base-valid.yaml dengan arahan berikut:

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

Ia akan mengeluarkan rentetan dalam format JSON dengan penerangan terperinci tentang ujian yang dilakukan dan keputusannya. Output akan mempunyai struktur berikut:

{
  "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": [
    /* Π΄Π»ΠΈΠ½Π½Ρ‹ΠΉ список */
  ]
}

Keluaran penuh tersedia di sini.

Seperti skor kube, Polaris mengenal pasti isu dalam kawasan yang manifes tidak memenuhi amalan terbaik:

  • Tiada pemeriksaan kesihatan untuk pod.
  • Teg untuk imej bekas tidak dinyatakan.
  • Bekas berfungsi sebagai akar.
  • Permintaan dan had untuk memori dan CPU tidak dinyatakan.

Setiap ujian, bergantung pada keputusannya, diberikan tahap kritikal: amaran atau bahaya. Untuk mengetahui lebih lanjut tentang ujian terbina dalam yang tersedia, sila rujuk dokumentasi.

Jika butiran tidak diperlukan, anda boleh menentukan bendera --format score. Dalam kes ini, Polaris akan mengeluarkan nombor antara 1 hingga 100 βˆ’ Perincian (iaitu penilaian):

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

Semakin hampir skor adalah 100, semakin tinggi tahap persetujuan. Jika anda menyemak kod keluar arahan polaris audit, ternyata ia sama dengan 0.

Paksa polaris audit Anda boleh menamatkan kerja dengan kod bukan sifar menggunakan dua bendera:

  • Π€Π»Π°Π³ --set-exit-code-below-score mengambil sebagai hujah nilai ambang dalam julat 1-100. Dalam kes ini, arahan akan keluar dengan kod keluar 4 jika skor berada di bawah ambang. Ini sangat berguna apabila anda mempunyai nilai ambang tertentu (katakan 75) dan anda perlu menerima makluman jika markah berada di bawah.
  • Π€Π»Π°Π³ --set-exit-code-on-danger akan menyebabkan arahan gagal dengan kod 3 jika salah satu ujian bahaya gagal.

Sekarang mari cuba buat ujian tersuai yang menyemak sama ada imej diambil daripada repositori yang dipercayai. Ujian tersuai ditentukan dalam format YAML dan ujian itu sendiri diterangkan menggunakan Skema JSON.

Coretan kod YAML berikut menerangkan ujian baharu yang dipanggil 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/.+$

Mari kita lihat dengan lebih dekat:

  • successMessage β€” baris ini akan dicetak jika ujian berjaya diselesaikan;
  • failureMessage β€” mesej ini akan ditunjukkan sekiranya berlaku kegagalan;
  • category β€” menunjukkan salah satu kategori: Images, Health Checks, Security, Networking ΠΈ Resources;
  • target--- menentukan jenis objek (spec) ujian digunakan. Nilai yang mungkin: Container, Pod atau Controller;
  • Ujian itu sendiri dinyatakan dalam objek schema menggunakan skema JSON. Kata kunci dalam ujian ini ialah pattern digunakan untuk membandingkan sumber imej dengan yang diperlukan.

Untuk menjalankan ujian di atas, anda perlu mencipta konfigurasi Polaris berikut:

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)

Mari kita menghuraikan fail:

  • Dalam bidang checks ujian dan tahap kritikalnya ditetapkan. Memandangkan adalah wajar untuk menerima amaran apabila imej diambil daripada sumber yang tidak dipercayai, kami menetapkan tahap di sini danger.
  • Ujian itu sendiri checkImageRepo kemudian didaftarkan dalam objek customChecks.

Simpan fail sebagai custom_check.yaml. Sekarang anda boleh berlari polaris audit dengan manifes YAML yang memerlukan pengesahan.

Mari kita uji manifesto kita base-valid.yaml:

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

Pasukan polaris audit menjalankan hanya ujian pengguna yang dinyatakan di atas dan ia gagal.

Jika anda membetulkan imej itu my-company.com/http-echo:1.0, Polaris akan selesai dengan jayanya. Manifesto dengan perubahan sudah masuk repositorisupaya anda boleh menyemak arahan sebelumnya pada manifes image-valid-mycompany.yaml.

Sekarang timbul persoalan: bagaimana untuk menjalankan ujian terbina dalam bersama-sama dengan ujian tersuai? Dengan mudah! Anda hanya perlu menambah pengecam ujian terbina dalam pada fail konfigurasi. Akibatnya, ia akan mengambil bentuk berikut:

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)

Contoh fail konfigurasi lengkap tersedia di sini.

Semak manifes base-valid.yamlmenggunakan ujian terbina dalam dan tersuai, anda boleh menggunakan arahan:

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

Polaris melengkapkan ujian terbina dalam dengan ujian tersuai, dengan itu menggabungkan yang terbaik dari kedua-dua dunia.

Sebaliknya, ketidakupayaan untuk menggunakan bahasa yang lebih berkuasa seperti Rego atau JavaScript boleh menjadi faktor pengehad yang menghalang penciptaan ujian yang lebih canggih.

Maklumat lanjut mengenai Polaris boleh didapati di laman web projek.

Ringkasan

Walaupun terdapat banyak alat yang tersedia untuk memeriksa dan menilai fail YAML Kubernetes, adalah penting untuk mempunyai pemahaman yang jelas tentang cara ujian akan direka bentuk dan dilaksanakan.

Sebagai contoh, jika anda mengambil manifes Kubernetes melalui saluran paip, kubeval boleh menjadi langkah pertama dalam saluran paip sedemikian. Ia akan memantau sama ada definisi objek mematuhi skema API Kubernetes.

Setelah semakan sedemikian selesai, seseorang boleh beralih kepada ujian yang lebih canggih, seperti pematuhan terhadap amalan terbaik standard dan dasar khusus. Di sinilah kube-score dan Polaris akan berguna.

Bagi mereka yang mempunyai keperluan yang kompleks dan perlu menyesuaikan ujian secara terperinci, tembaga, config-lint dan conftest akan sesuai.

Conftest dan config-lint menggunakan YAML untuk mentakrifkan ujian tersuai, dan tembaga memberikan anda akses kepada bahasa pengaturcaraan penuh, menjadikannya pilihan yang cukup menarik.

Sebaliknya, adakah patut menggunakan salah satu alat ini dan, oleh itu, membuat semua ujian secara manual, atau lebih suka Polaris dan menambah hanya apa yang diperlukan padanya? Tiada jawapan yang jelas untuk soalan ini.

Jadual di bawah memberikan penerangan ringkas bagi setiap alat:

Alat
Tujuan
Kecacatan
Ujian pengguna

kubeval
Mengesahkan manifes YAML terhadap versi khusus skema API
Tidak boleh bekerja dengan CRD
Tiada

kube-skor
Menganalisis manifes YAML terhadap amalan terbaik
Tidak dapat memilih versi API Kubernetes anda untuk menyemak sumber
Tiada

tembaga
Rangka kerja umum untuk membuat ujian JavaScript tersuai untuk manifes YAML
Tiada ujian terbina dalam. Dokumentasi yang lemah
Ya

config-lint
Rangka kerja umum untuk membuat ujian dalam bahasa khusus domain yang dibenamkan dalam YAML. Menyokong pelbagai format konfigurasi (cth. Terraform)
Tiada ujian siap sedia. Penegasan dan fungsi terbina dalam mungkin tidak mencukupi
Ya

kontest
Rangka kerja untuk membuat ujian anda sendiri menggunakan Rego (bahasa pertanyaan khusus). Membenarkan perkongsian dasar melalui himpunan OCI
Tiada ujian terbina dalam. Saya perlu belajar Rego. Docker Hub tidak disokong semasa menerbitkan dasar
Ya

Polaris
Ulasan YAML nyata terhadap amalan terbaik standard. Membolehkan anda membuat ujian anda sendiri menggunakan Skema JSON
Keupayaan ujian berdasarkan Skema JSON mungkin tidak mencukupi
Ya

Oleh kerana alat ini tidak bergantung pada akses kepada gugusan Kubernetes, alat ini mudah dipasang. Mereka membenarkan anda menapis fail sumber dan memberikan maklum balas pantas kepada pengarang permintaan tarik dalam projek.

PS daripada penterjemah

Baca juga di blog kami:

Sumber: www.habr.com

Tambah komen