Validasi Kubernetes YAML berdasarkan praktik dan kebijakan terbaik

Catatan. terjemahan: Dengan semakin banyaknya konfigurasi YAML untuk lingkungan K8, kebutuhan akan verifikasi otomatisnya menjadi semakin mendesak. Penulis ulasan ini tidak hanya memilih solusi yang ada untuk tugas ini, namun juga menggunakan Deployment sebagai contoh untuk melihat cara kerjanya. Ternyata sangat informatif bagi mereka yang tertarik dengan topik ini.

Validasi Kubernetes YAML berdasarkan praktik dan kebijakan terbaik

TL; DR: Artikel ini membandingkan enam alat statis untuk memvalidasi dan mengevaluasi file YAML Kubernetes terhadap praktik dan persyaratan terbaik.

Beban kerja Kubernetes biasanya ditentukan dalam bentuk dokumen YAML. Salah satu masalah YAML adalah sulitnya menentukan batasan atau hubungan antar file manifes.

Bagaimana jika kita perlu memastikan bahwa semua gambar yang disebarkan ke cluster berasal dari registri tepercaya?

Bagaimana cara mencegah Deployment yang tidak memiliki PodDisruptionBudgets dikirim ke cluster?

Integrasi pengujian statis memungkinkan Anda mengidentifikasi kesalahan dan pelanggaran kebijakan pada tahap pengembangan. Hal ini meningkatkan jaminan bahwa definisi sumber daya sudah benar dan aman, serta memperbesar kemungkinan beban kerja produksi akan mengikuti praktik terbaik.

Ekosistem pemeriksaan file YAML statis Kubernetes dapat dibagi ke dalam kategori berikut:

  • Validator API. Alat dalam kategori ini memeriksa manifes YAML terhadap persyaratan server API Kubernetes.
  • Penguji siap. Alat dari kategori ini dilengkapi dengan pengujian siap pakai untuk keamanan, kepatuhan terhadap praktik terbaik, dll.
  • Validator khusus. Perwakilan dari kategori ini memungkinkan Anda membuat pengujian khusus dalam berbagai bahasa, misalnya Rego dan Javascript.

Pada artikel ini kami akan menjelaskan dan membandingkan enam alat berbeda:

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

Baiklah, mari kita mulai!

Memeriksa Penerapan

Sebelum kita mulai membandingkan alat, mari buat beberapa latar belakang untuk mengujinya.

Manifesto di bawah ini berisi sejumlah kesalahan dan ketidakpatuhan terhadap praktik terbaik: berapa banyak kesalahan yang dapat Anda temukan?

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 berbeda.

Manifesto di atas base-valid.yaml dan manifesto lain dari artikel ini dapat ditemukan di Repositori Git.

Manifes menjelaskan aplikasi web yang tugas utamanya adalah merespons dengan pesan β€œHalo Dunia” ke port 5678. Ini dapat diterapkan dengan perintah berikut:

kubectl apply -f hello-world.yaml

Jadi - periksa pekerjaannya:

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

Sekarang pergi ke http://localhost:8080 dan konfirmasikan bahwa aplikasi berfungsi. Namun apakah ini mengikuti praktik terbaik? Mari kita periksa.

1. Kubeval

Di jantung kubeval Idenya adalah setiap interaksi dengan Kubernetes terjadi melalui REST API-nya. Dengan kata lain, Anda dapat menggunakan skema API untuk memeriksa apakah YAML tertentu mematuhinya. Mari kita lihat sebuah contoh.

Instruksi instalasi kubeval tersedia di situs proyek.

Pada saat artikel asli ditulis, versi 0.15.0 telah tersedia.

Setelah terinstal, mari kita berikan 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 berhasil, kubeval akan keluar dengan kode keluar 0. Anda dapat memeriksanya sebagai berikut:

$ echo $?
0

Sekarang mari kita coba kubeval dengan manifes yang berbeda:

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)

Bisakah Anda melihat masalahnya secara langsung? Mari kita luncurkan:

$ 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 daya tidak diverifikasi.

Penerapan menggunakan versi API apps/v1, harus menyertakan pemilih yang cocok dengan label pod. Manifes di atas tidak menyertakan pemilih, jadi kubeval melaporkan kesalahan dan keluar dengan kode bukan nol.

Aku ingin tahu apa yang akan terjadi jika aku melakukannya kubectl apply -f dengan manifesto ini?

Baiklah, mari kita coba:

$ 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

Ini adalah kesalahan yang diperingatkan oleh kubeval. Anda dapat memperbaikinya 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)

Manfaat alat seperti kubeval adalah kesalahan seperti ini dapat diketahui pada awal siklus penerapan.

Selain itu, pemeriksaan ini tidak memerlukan akses ke cluster; pemeriksaan ini dapat dilakukan secara offline.

Secara default, kubeval memeriksa sumber daya berdasarkan skema API Kubernetes terbaru. Namun, dalam sebagian besar kasus, Anda mungkin perlu memeriksa rilis Kubernetes tertentu. Hal ini dapat dilakukan dengan menggunakan bendera --kubernetes-version:

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

Harap dicatat bahwa versi harus ditentukan dalam format Major.Minor.Patch.

Untuk daftar versi yang verifikasinya didukung, silakan lihat Skema JSON di GitHub, yang digunakan kubeval untuk validasi. Jika Anda perlu menjalankan kubeval secara offline, unduh skemanya dan tentukan lokasi lokalnya menggunakan flag --schema-location.

Selain file YAML individual, kubeval juga dapat bekerja dengan direktori dan stdin.

Selain itu, Kubeval dengan mudah berintegrasi ke dalam pipeline CI. Mereka yang ingin menjalankan pengujian sebelum mengirimkan manifes ke cluster akan senang mengetahui bahwa kubeval mendukung tiga format output:

  1. Teks biasa;
  2. json;
  3. Uji Protokol Apa Pun (TAP).

Dan format apa pun dapat digunakan untuk penguraian keluaran lebih lanjut guna menghasilkan ringkasan hasil jenis yang diinginkan.

Salah satu kelemahan kubeval adalah saat ini kubeval tidak dapat memeriksa kepatuhan terhadap Definisi Sumber Daya Kustom (CRD). Namun, kubeval dapat dikonfigurasi abaikan mereka.

Kubeval adalah alat yang hebat untuk memeriksa dan mengevaluasi sumber daya; Namun, perlu ditekankan bahwa lulus tes tidak menjamin bahwa sumber daya tersebut mematuhi praktik terbaik.

Misalnya saja dengan menggunakan tag latest dalam wadah tidak mengikuti praktik terbaik. Namun, kubeval tidak menganggap ini sebagai kesalahan dan tidak melaporkannya. Artinya, verifikasi YAML tersebut akan selesai tanpa peringatan.

Namun bagaimana jika Anda ingin mengevaluasi YAML dan mengidentifikasi pelanggaran seperti tag latest? Bagaimana cara memeriksa file YAML berdasarkan praktik terbaik?

2. Skor Kube

Skor Kube mem-parsing manifes YAML dan mengevaluasinya berdasarkan pengujian bawaan. Pengujian ini dipilih berdasarkan pedoman keamanan dan praktik terbaik, seperti:

  • Menjalankan container bukan sebagai root.
  • Ketersediaan pemeriksaan kesehatan pod.
  • Menetapkan permintaan dan batasan sumber daya.

Berdasarkan hasil pengujian, diberikan tiga hasil: OK, PERINGATAN ΠΈ KRITIS.

Anda dapat mencoba Kube-score online atau menginstalnya secara lokal.

Pada saat artikel asli ditulis, versi terbaru kube-score adalah 1.7.0.

Mari kita mencobanya di 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 pengujian kubeval, sementara kube-score menunjukkan kelemahan berikut:

  • Pemeriksaan kesiapan tidak dikonfigurasi.
  • Tidak ada permintaan atau batasan untuk sumber daya CPU dan memori.
  • Anggaran gangguan pod tidak ditentukan.
  • Tidak ada aturan pemisahan (anti-afinitas) untuk memaksimalkan ketersediaan.
  • Wadah berjalan sebagai root.

Ini semua adalah poin valid tentang kekurangan yang perlu diatasi agar Deployment lebih efisien dan andal.

Tim kube-score menampilkan informasi dalam bentuk yang dapat dibaca manusia termasuk semua jenis pelanggaran PERINGATAN ΠΈ KRITIS, yang banyak membantu selama pengembangan.

Mereka yang ingin menggunakan alat ini dalam pipeline CI dapat mengaktifkan output yang lebih terkompresi menggunakan flag --output-format ci (dalam hal ini, tes dengan hasilnya juga ditampilkan 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

Mirip dengan kubeval, kube-score mengembalikan kode keluar yang bukan nol ketika ada pengujian yang gagal KRITIS. Anda juga dapat mengaktifkan pemrosesan serupa untuk PERINGATAN.

Selain itu, dimungkinkan untuk memeriksa kepatuhan sumber daya dengan versi API yang berbeda (seperti di kubeval). Namun, informasi ini dikodekan dalam kube-score itu sendiri: Anda tidak dapat memilih versi Kubernetes yang lain. Keterbatasan ini bisa menjadi masalah besar jika Anda ingin mengupgrade klaster Anda atau jika Anda memiliki beberapa klaster dengan versi K8 yang berbeda.

Harap dicatat bahwa sudah ada masalah dengan proposal untuk mewujudkan peluang ini.

Informasi lebih lanjut tentang kube-score dapat ditemukan di situs resmi.

Pengujian Kube-score adalah alat yang hebat untuk menerapkan praktik terbaik, namun bagaimana jika Anda perlu melakukan perubahan pada pengujian atau menambahkan aturan Anda sendiri? Sayangnya, hal ini tidak dapat dilakukan.

Skor Kube tidak dapat diperluas: Anda tidak dapat menambahkan atau menyesuaikan kebijakan ke dalamnya.

Jika Anda perlu menulis pengujian khusus untuk memverifikasi kepatuhan terhadap kebijakan perusahaan, Anda dapat menggunakan salah satu dari empat alat berikut: config-lint, copper, conftest, atau polaris.

3.Config-lint

Config-lint adalah alat untuk memvalidasi file konfigurasi YAML, JSON, Terraform, CSV, dan manifes Kubernetes.

Anda dapat menginstalnya menggunakan instruksi di situs web proyek.

Rilis saat ini pada saat artikel asli ditulis adalah 1.5.0.

Config-lint tidak memiliki pengujian bawaan untuk memvalidasi manifes Kubernetes.

Untuk melakukan tes apa pun, Anda perlu membuat aturan yang sesuai. Mereka ditulis dalam file YAML yang disebut "rulesets" (aturan), dan memiliki struktur berikut:

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

(rule.yaml)

Mari kita pelajari lebih dekat:

  • Lapangan type menentukan jenis konfigurasi apa yang akan digunakan config-lint. Untuk manifes K8, inilah yang terjadi selalu Kubernetes.
  • Di lapangan files Selain file itu sendiri, Anda dapat menentukan direktori.
  • Lapangan rules dimaksudkan untuk mengatur tes pengguna.

Katakanlah Anda ingin memastikan bahwa gambar di Deployment selalu diunduh dari repositori tepercaya seperti my-company.com/myapp:1.0. Aturan config-lint yang melakukan pemeriksaan seperti itu akan terlihat 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 aturan harus memiliki atribut berikut:

  • id β€” pengenal unik dari aturan tersebut;
  • severity - mungkin KEGAGALAN, PERINGATAN ΠΈ TIDAK_KOMPLAIN;
  • message β€” jika suatu aturan dilanggar, konten baris ini akan ditampilkan;
  • resource β€” jenis sumber daya yang menerapkan aturan ini;
  • assertions β€” daftar kondisi yang akan dievaluasi sehubungan dengan sumber daya ini.

Dalam aturan di atas assertion bernama every memeriksa apakah semua kontainer berada dalam Deployment (key: spec.templates.spec.containers) gunakan gambar tepercaya (yaitu dimulai dengan my-company.com/).

Aturan lengkapnya terlihat 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 mencoba tes ini, simpan saja sebagai check_image_repo.yaml. Mari kita jalankan pemeriksaan pada file tersebut 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"
  }
]

Pemeriksaan gagal. Sekarang mari kita periksa manifes berikut dengan repositori gambar yang benar:

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 pengujian yang sama dengan manifes di atas. Tidak ada masalah yang ditemukan:

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

Config-lint adalah kerangka kerja menjanjikan yang memungkinkan Anda membuat pengujian sendiri untuk memvalidasi manifes YAML Kubernetes menggunakan YAML DSL.

Namun bagaimana jika Anda memerlukan logika dan pengujian yang lebih kompleks? Bukankah YAML terlalu terbatas untuk ini? Bagaimana jika Anda bisa membuat tes dalam bahasa pemrograman lengkap?

4. Tembaga

Tembaga V2 adalah kerangka kerja untuk memvalidasi manifes menggunakan pengujian khusus (mirip dengan config-lint).

Namun, ini berbeda dari yang terakhir karena tidak menggunakan YAML untuk menjelaskan pengujian. Tes dapat ditulis dalam JavaScript. Copper menyediakan perpustakaan dengan beberapa alat dasar, yang membantu Anda membaca informasi tentang objek Kubernetes dan melaporkan kesalahan.

Langkah-langkah pemasangan Tembaga dapat dilihat di dokumentasi resmi.

2.0.1 adalah rilis terbaru dari utilitas ini pada saat artikel asli ditulis.

Seperti config-lint, Copper tidak memiliki pengujian bawaan. Ayo tulis satu. Biarkan ia memeriksa bahwa penerapan menggunakan gambar kontainer secara eksklusif dari repositori tepercaya seperti my-company.com.

Buat berkas check_image_repo.js dengan konten sebagai 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 perintah 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

Jelas bahwa dengan bantuan tembaga Anda dapat melakukan pengujian yang lebih kompleks - misalnya, memeriksa nama domain di manifes Ingress atau menolak pod yang berjalan dalam mode istimewa.

Tembaga memiliki berbagai fungsi utilitas yang tertanam di dalamnya:

  • DockerImage membaca file input yang ditentukan dan membuat objek dengan atribut berikut:
    • name - nama gambar,
    • tag - label gambar,
    • registry - registri gambar,
    • registry_url - protokol (https://) dan registri gambar,
    • fqin β€” lokasi lengkap gambar.
  • Fungsi findByName membantu menemukan sumber daya berdasarkan jenis tertentu (kind) dan nama (name) dari file masukan.
  • Fungsi findByLabels membantu menemukan sumber daya berdasarkan tipe tertentu (kind) dan label (labels).

Anda dapat melihat semua fungsi layanan yang tersedia di sini.

Secara default, ini memuat seluruh file input YAML ke dalam variabel $$ dan membuatnya tersedia untuk pembuatan skrip (teknik yang familiar bagi mereka yang memiliki pengalaman jQuery).

Keuntungan utama Copper jelas: Anda tidak perlu menguasai bahasa khusus dan Anda dapat menggunakan berbagai fitur JavaScript untuk membuat pengujian Anda sendiri, seperti interpolasi string, fungsi, dll.

Perlu juga dicatat bahwa versi Copper saat ini berfungsi dengan mesin JavaScript versi ES5, bukan ES6.

Detail tersedia di situs resmi proyek.

Namun, jika Anda tidak terlalu menyukai JavaScript dan lebih memilih bahasa yang dirancang khusus untuk membuat kueri dan menjelaskan kebijakan, Anda harus memperhatikan conftest.

5.Konftest

Conftest adalah kerangka kerja untuk menguji data konfigurasi. Juga cocok untuk menguji/memverifikasi manifes Kubernetes. Pengujian dijelaskan menggunakan bahasa kueri khusus Rego.

Anda dapat menginstal Conftest menggunakan instruksiterdaftar di situs web proyek.

Pada saat artikel asli ditulis, versi terbaru yang tersedia adalah 0.18.2.

Mirip dengan config-lint dan copper, conftest hadir tanpa pengujian bawaan apa pun. Mari kita mencobanya dan menulis kebijakan kita sendiri. Seperti pada contoh sebelumnya, kami akan memeriksa apakah gambar container diambil dari sumber yang dapat dipercaya.

Buat direktori conftest-checks, dan di dalamnya ada file bernama check_image_registry.rego dengan konten sebagai 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

Pengujian tersebut diperkirakan gagal karena gambar tersebut berasal dari sumber yang tidak tepercaya.

Di file Rego kami mendefinisikan blok deny. Kebenarannya dianggap sebagai pelanggaran. Jika menghalangi deny beberapa, conftest memeriksanya secara independen satu sama lain, dan kebenaran dari setiap blok dianggap sebagai pelanggaran.

Selain keluaran default, conftest mendukung JSON, TAP, dan format tabel - fitur yang sangat berguna jika Anda perlu menyematkan laporan ke dalam saluran CI yang ada. Anda dapat mengatur format yang diinginkan menggunakan bendera --output.

Untuk mempermudah men-debug kebijakan, conftest memiliki sebuah tanda --trace. Ini menghasilkan jejak bagaimana conftest mem-parsing file kebijakan yang ditentukan.

Kebijakan kontes dapat dipublikasikan dan dibagikan di registri OCI (Open Container Initiative) sebagai artefak.

Tim push ΠΈ pull memungkinkan Anda menerbitkan artefak atau mengambil artefak yang ada dari registri jarak jauh. Mari kita coba mempublikasikan kebijakan yang kita buat ke registri Docker lokal menggunakan conftest push.

Mulai registri Docker lokal Anda:

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

Di terminal lain, buka direktori yang Anda buat sebelumnya conftest-checks dan jalankan perintah berikut:

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

Jika perintah berhasil, Anda akan melihat pesan seperti ini:

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

Sekarang buat direktori sementara dan jalankan perintah di dalamnya conftest pull. Ini akan mengunduh paket yang dibuat oleh perintah sebelumnya:

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

Subdirektori akan muncul di direktori sementara policyberisi file kebijakan kami:

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

Pengujian dapat dijalankan langsung 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

Sayangnya, DockerHub belum didukung. Jadi anggaplah diri Anda beruntung jika menggunakannya Registri Kontainer Azure (ACR) atau registri Anda sendiri.

Format artefak sama dengan Buka paket Agen Kebijakan (OPA), yang memungkinkan Anda menggunakan conftest untuk menjalankan pengujian dari paket OPA yang ada.

Anda dapat mempelajari lebih lanjut tentang pembagian kebijakan dan fitur konflik lainnya di situs resmi proyek.

6. Polaris

Alat terakhir yang akan dibahas dalam artikel ini adalah Polaris. (Pengumumannya tahun lalu kami sudah diterjemahkan - kira-kira. terjemahan)

Polaris dapat diinstal dalam cluster atau digunakan dalam mode baris perintah. Seperti yang sudah Anda duga, ini memungkinkan Anda menganalisis manifes Kubernetes secara statis.

Saat dijalankan dalam mode baris perintah, pengujian bawaan tersedia yang mencakup bidang-bidang seperti keamanan dan praktik terbaik (mirip dengan kube-score). Selain itu, Anda dapat membuat pengujian sendiri (seperti pada config-lint, copper, dan conftest).

Dengan kata lain, Polaris menggabungkan keunggulan kedua kategori alat: dengan pengujian bawaan dan pengujian khusus.

Untuk menginstal Polaris dalam mode baris perintah, gunakan instruksi di situs web proyek.

Pada saat artikel asli ditulis, versi 1.0.3 telah tersedia.

Setelah instalasi selesai Anda dapat menjalankan polaris di manifes base-valid.yaml dengan perintah berikut:

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

Ini akan menampilkan string dalam format JSON dengan penjelasan rinci tentang tes yang dilakukan dan hasilnya. Outputnya akan memiliki 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 kube-score, Polaris mengidentifikasi masalah di area yang manifesnya tidak memenuhi praktik terbaik:

  • Tidak ada pemeriksaan kesehatan untuk pod.
  • Tag untuk gambar kontainer tidak ditentukan.
  • Wadah berjalan sebagai root.
  • Permintaan dan batasan untuk memori dan CPU tidak ditentukan.

Setiap pengujian, bergantung pada hasilnya, diberikan tingkat kekritisan: peringatan ΠΈΠ»ΠΈ bahaya. Untuk mempelajari lebih lanjut tentang tes bawaan yang tersedia, silakan merujuk ke dokumentasi.

Jika detailnya tidak diperlukan, Anda dapat menentukan tandanya --format score. Dalam hal ini, Polaris akan mengeluarkan angka mulai dari 1 hingga 100 βˆ’ skor (yaitu penilaian):

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

Semakin mendekati angka 100, maka semakin tinggi tingkat persetujuannya. Jika Anda memeriksa kode keluar dari perintah polaris audit, ternyata sama dengan 0.

Membuat polaris audit Anda dapat menghentikan pekerjaan dengan kode bukan nol menggunakan dua tanda:

  • Bendera --set-exit-code-below-score mengambil sebagai argumen nilai ambang batas dalam kisaran 1-100. Dalam hal ini, perintah akan keluar dengan kode keluar 4 jika skornya di bawah ambang batas. Ini sangat berguna ketika Anda memiliki nilai ambang batas tertentu (misalnya 75) dan Anda perlu menerima peringatan jika skornya turun.
  • Bendera --set-exit-code-on-danger akan menyebabkan perintah gagal dengan kode 3 jika salah satu tes bahaya gagal.

Sekarang mari kita coba membuat pengujian khusus yang memeriksa apakah gambar diambil dari repositori tepercaya. Pengujian khusus ditentukan dalam format YAML, dan pengujian itu sendiri dijelaskan menggunakan Skema JSON.

Cuplikan kode YAML berikut menjelaskan pengujian baru yang disebut 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 lebih dekat:

  • successMessage β€” baris ini akan dicetak jika tes berhasil diselesaikan;
  • failureMessage β€” pesan ini akan ditampilkan jika terjadi kegagalan;
  • category β€” menunjukkan salah satu kategori: Images, Health Checks, Security, Networking ΠΈ Resources;
  • target--- menentukan jenis objek apa (spec) tes diterapkan. Nilai yang mungkin: Container, Pod ΠΈΠ»ΠΈ Controller;
  • Tes itu sendiri ditentukan dalam objek schema menggunakan skema JSON. Kata kunci dalam tes ini adalah pattern digunakan untuk membandingkan sumber gambar dengan yang diperlukan.

Untuk menjalankan pengujian di atas, Anda perlu membuat 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 parsing filenya:

  • Di lapangan checks tes dan tingkat kekritisannya ditentukan. Karena diinginkan untuk menerima peringatan ketika gambar diambil dari sumber yang tidak tepercaya, kami menetapkan levelnya di sini danger.
  • Tes itu sendiri checkImageRepo kemudian didaftarkan pada objek tersebut customChecks.

Simpan file sebagai custom_check.yaml. Sekarang kamu bisa lari polaris audit dengan manifes YAML yang memerlukan verifikasi.

Mari kita uji manifesto kita base-valid.yaml:

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

Tim polaris audit hanya menjalankan tes pengguna yang ditentukan di atas dan gagal.

Jika Anda memperbaiki gambar menjadi my-company.com/http-echo:1.0, Polaris akan berhasil keluar. Manifesto perubahan sudah ada repositorisehingga Anda dapat memeriksa perintah sebelumnya di manifes image-valid-mycompany.yaml.

Sekarang muncul pertanyaan: bagaimana cara menjalankan pengujian bawaan bersama dengan pengujian khusus? Mudah! Anda hanya perlu menambahkan pengidentifikasi pengujian bawaan ke file konfigurasi. Hasilnya akan berbentuk sebagai 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 file konfigurasi lengkap tersedia di sini.

Periksa manifes base-valid.yamlmenggunakan pengujian bawaan dan khusus, Anda dapat menggunakan perintah:

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

Polaris melengkapi pengujian bawaan dengan pengujian khusus, sehingga menggabungkan yang terbaik dari kedua dunia.

Di sisi lain, ketidakmampuan untuk menggunakan bahasa yang lebih canggih seperti Rego atau JavaScript dapat menjadi faktor pembatas yang mencegah pembuatan pengujian yang lebih canggih.

Informasi lebih lanjut tentang Polaris tersedia di situs web proyek.

Ringkasan

Meskipun ada banyak alat yang tersedia untuk memeriksa dan mengevaluasi file YAML Kubernetes, penting untuk memiliki pemahaman yang jelas tentang bagaimana pengujian akan dirancang dan dilaksanakan.

Misalnya, jika Anda mengambil manifes Kubernetes melalui pipeline, kubeval bisa menjadi langkah pertama dalam pipeline tersebut. Ini akan memantau apakah definisi objek sesuai dengan skema API Kubernetes.

Setelah peninjauan tersebut selesai, kita dapat melanjutkan ke pengujian yang lebih canggih, seperti kepatuhan terhadap standar praktik terbaik dan kebijakan spesifik. Di sinilah kube-score dan Polaris akan berguna.

Bagi mereka yang memiliki persyaratan kompleks dan perlu menyesuaikan pengujian secara detail, tembaga, config-lint, dan conftest akan cocok.

Conftest dan config-lint menggunakan YAML untuk menentukan pengujian khusus, dan tembaga memberi Anda akses ke bahasa pemrograman lengkap, menjadikannya pilihan yang cukup menarik.

Di sisi lain, apakah layak menggunakan salah satu alat ini dan, oleh karena itu, membuat semua pengujian secara manual, atau lebih memilih Polaris dan hanya menambahkan apa yang diperlukan ke dalamnya? Tidak ada jawaban yang jelas untuk pertanyaan ini.

Tabel di bawah ini memberikan penjelasan singkat tentang masing-masing alat:

Alat
Tujuan
Kekurangan:
Tes pengguna

kubeval
Memvalidasi manifes YAML terhadap versi skema API tertentu
Tidak dapat bekerja dengan CRD
Tidak

skor-kube
Menganalisis manifes YAML berdasarkan praktik terbaik
Tidak dapat memilih versi API Kubernetes untuk memeriksa sumber daya
Tidak

tembaga
Kerangka kerja umum untuk membuat pengujian JavaScript khusus untuk manifes YAML
Tidak ada tes bawaan. Dokumentasi yang buruk
Ya

config-lint
Kerangka kerja umum untuk membuat pengujian dalam bahasa khusus domain yang tertanam di YAML. Mendukung berbagai format konfigurasi (misalnya Terraform)
Tidak ada tes yang siap pakai. Pernyataan dan fungsi bawaan mungkin tidak cukup
Ya

konflik
Kerangka kerja untuk membuat pengujian Anda sendiri menggunakan Rego (bahasa kueri khusus). Memungkinkan berbagi kebijakan melalui paket OCI
Tidak ada tes bawaan. Saya harus belajar Rego. Docker Hub tidak didukung saat menerbitkan kebijakan
Ya

Polaris
Ulasan YAML bermanifestasi berdasarkan praktik terbaik standar. Memungkinkan Anda membuat pengujian sendiri menggunakan Skema JSON
Kemampuan pengujian berdasarkan Skema JSON mungkin tidak cukup
Ya

Karena alat ini tidak bergantung pada akses ke cluster Kubernetes, alat ini mudah dipasang. Mereka memungkinkan Anda memfilter file sumber dan memberikan umpan balik cepat kepada pembuat permintaan tarik dalam proyek.

PS dari penerjemah

Baca juga di blog kami:

Sumber: www.habr.com

Tambah komentar