Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Cara kami menggunakan kerja Kubernetes untuk menskalakan OpenSSF Scorecard

Cara kami menggunakan kerja Kubernetes untuk menskalakan OpenSSF Scorecard

WBOY
WBOYasal
2024-08-09 10:20:521119semak imbas

How we use Kubernetes jobs to scale OpenSSF Scorecard

Kami baru-baru ini mengeluarkan penyepaduan dengan OpenSSF Scorecard pada platform OpenSauced. OpenSSF Scorecard ialah antara muka baris arahan Go yang berkuasa yang boleh digunakan oleh sesiapa sahaja untuk mula memahami postur keselamatan projek dan kebergantungan mereka. Ia menjalankan beberapa semakan untuk aliran kerja berbahaya, amalan terbaik CICD, jika projek masih dikekalkan, dan banyak lagi. Ini membolehkan pembina perisian dan pengguna memahami gambaran keseluruhan keselamatan mereka, menyimpulkan sama ada sesuatu projek selamat digunakan dan tempat penambahbaikan kepada amalan keselamatan perlu dibuat.

Tetapi salah satu matlamat kami dengan menyepadukan Kad Skor OpenSSF ke dalam platform OpenSauced adalah untuk menyediakan ini kepada ekosistem sumber terbuka yang lebih luas secara amnya. Jika ia adalah repositori di GitHub, kami mahu dapat memaparkan skor untuknya. Ini bermakna meningkatkan skala CLI Kad Skor untuk menyasarkan hampir mana-mana repositori di GitHub. Lebih mudah diucapkan daripada dilakukan!

Dalam catatan blog ini, mari kita lihat cara kami melakukannya menggunakan Kubernetes dan keputusan teknikal yang kami buat dengan melaksanakan penyepaduan ini.

Kami tahu bahawa kami perlu membina perkhidmatan mikro jenis cron yang kerap mengemas kini skor merentas pelbagai repositori: persoalan sebenar ialah bagaimana kami akan melakukannya. Tidak masuk akal untuk menjalankan kad skor CLI ad-hoc: platform boleh terlalu mudah terharu dan kami mahu dapat melakukan analisis yang lebih mendalam pada skor merentas ekosistem sumber terbuka, walaupun halaman repo OpenSauced belum dilawati baru-baru ini. Pada mulanya, kami melihat menggunakan perpustakaan Scorecard Go sebagai kod bergantung langsung dan menjalankan semakan kad skor dalam satu perkhidmatan mikro monolitik. Kami juga mempertimbangkan untuk menggunakan kerja tanpa pelayan untuk menjalankan satu bekas kad skor yang akan mengembalikan hasil untuk repositori individu.

Pendekatan yang akhirnya kami gunakan, yang menggabungkan kesederhanaan, fleksibiliti dan kuasa, ialah menggunakan Kubernetes Jobs pada skala, semuanya diuruskan oleh perkhidmatan mikro pengawal Kubernetes "penjadual". Daripada membina penyepaduan kod yang lebih mendalam dengan kad skor, menjalankan satu daripada Kubernetes Jobs memberi kami manfaat yang sama menggunakan pendekatan tanpa pelayan, tetapi dengan kos yang lebih rendah kerana kami menguruskan semuanya secara langsung pada kelompok Kubernetes kami. Pekerjaan juga menawarkan banyak fleksibiliti dalam cara ia dijalankan: mereka boleh mempunyai tamat masa yang panjang dan berpanjangan, mereka boleh menggunakan cakera, dan seperti mana-mana paradigma Kubernetes lain, mereka boleh mempunyai berbilang pod melakukan tugasan yang berbeza.

Mari kita pecahkan komponen individu sistem ini dan lihat cara ia berfungsi secara mendalam:

Bahagian pertama dan terbesar sistem ini ialah "penjadual kad skor-k8s"; perkhidmatan mikro seperti pengawal Kubernetes yang memulakan kerja baharu dalam kelompok. Walaupun perkhidmatan mikro ini mengikut banyak prinsip, corak dan kaedah yang digunakan semasa membina pengawal atau pengendali Kubernetes tradisional, ia tidak mengawasi atau memutasi sumber tersuai pada gugusan. Fungsinya adalah untuk memulakan Kubernetes Jobs yang menjalankan Scorecard CLI dan mengumpulkan hasil kerja yang telah siap.

Mari kita lihat dahulu pada gelung kawalan utama dalam kod Go. Perkhidmatan mikro ini menggunakan perpustakaan Kubernetes Client-Go untuk antara muka terus dengan kluster yang sedang dijalankan oleh perkhidmatan mikro: ini sering dirujuk sebagai konfigurasi dan klien pada kelompok. Dalam kod, selepas bootstrap klien pada kelompok, kami meninjau repositori dalam pangkalan data kami yang perlu dikemas kini. Setelah beberapa repo ditemui, kami memulakan kerja Kubernetes pada "benang" pekerja individu yang akan menunggu setiap kerja selesai.

// buffered channel, sort of like semaphores, for threaded working
sem := make(chan bool, numConcurrentJobs)

// continuous control loop
for {
    // blocks on getting semaphore off buffered channel
    sem <- true

    go func() {
        // release the hold on the channel for this Go routine when done
        defer func() {
            <-sem
        }()

        // grab repo needing update, start scorecard Kubernetes Job on-cluster,
        // wait for results, etc. etc.

        // sleep the configured amount of time to relieve backpressure
        time.Sleep(backoff)
    }()
}

Kaedah "gelung kawalan tak terhingga" ini, dengan saluran penimbal, ialah cara biasa dalam Pergi untuk melakukan sesuatu secara berterusan tetapi hanya menggunakan bilangan utas yang dikonfigurasikan. Bilangan fungsi Go serentak yang berjalan pada satu-satu masa bergantung pada nilai yang dikonfigurasikan pembolehubah "numConcurrentJobs". Ini menyediakan saluran penimbal untuk bertindak sebagai kumpulan pekerja atau semaphore yang menandakan bilangan fungsi Go serentak yang berjalan pada satu-satu masa tertentu. Memandangkan saluran penimbal ialah sumber kongsi yang boleh digunakan dan diperiksa oleh semua utas, saya selalunya suka menganggap ini sebagai semafor: sumber, sama seperti mutex, yang berbilang utas boleh cuba dikunci dan diakses. Dalam persekitaran pengeluaran kami, kami telah menskalakan bilangan urutan dalam penjadual ini semuanya berjalan serentak. Memandangkan penjadual sebenar tidak begitu berat dari segi pengiraan dan hanya akan memulakan kerja dan menunggu keputusan akhirnya muncul, kami boleh menolak sampul surat tentang perkara yang boleh diuruskan oleh penjadual ini. Kami juga mempunyai sistem backoff terbina dalam yang cuba meredakan tekanan apabila diperlukan: sistem ini akan menambah nilai "undur" yang dikonfigurasikan jika terdapat ralat atau jika tiada repo ditemui untuk mengira skor. Ini memastikan kami tidak terus menyelar pangkalan data kami dengan pertanyaan dan penjadual kad skor itu sendiri boleh kekal dalam keadaan "menunggu", tidak menggunakan sumber pengiraan yang berharga pada gugusan.

Dalam gelung kawalan, kami melakukan beberapa perkara: pertama, kami menanyakan pangkalan data kami untuk repositori yang memerlukan kad skornya dikemas kini. Ini ialah pertanyaan pangkalan data mudah yang berdasarkan beberapa metadata cap waktu yang kami perhatikan dan mempunyai indeks. Setelah jumlah masa yang dikonfigurasikan berlalu sejak skor terakhir dikira untuk repo, ia akan menggelembung untuk dipecahkan oleh Tugas Kubernetes yang menjalankan CLI Kad Skor.

Seterusnya, setelah kami mempunyai repo untuk mendapatkan markah, kami memulakan Kerja Kubernetes menggunakan imej "gcr.io/openssf/scorecard". Bootstrap kerja ini dalam kod Go menggunakan Client-Go kelihatan sangat serupa dengan penampilannya dengan yaml, hanya menggunakan pelbagai perpustakaan dan apis yang tersedia melalui import "k8s.io" dan melakukannya secara pemprograman:

// defines the Kubernetes Job and its spec
job := &batchv1.Job{
    // structs and details for the actual Job
    // including metav1.ObjectMeta and batchv1.JobSpec
}

// create the actual Job on cluster
// using the in-cluster config and client
return s.clientset.BatchV1().Jobs(ScorecardNamespace).Create(ctx, job, metav1.CreateOptions{})

Selepas kerja dibuat, kami menunggu ia menandakan kerja itu telah selesai atau ralat. Sama seperti kubectl, Client-Go menawarkan cara yang berguna untuk "menonton" sumber dan memerhati keadaan mereka apabila ia berubah:

// watch selector for the job name on cluster
watch, err := s.clientset.BatchV1().Jobs(ScorecardNamespace).Watch(ctx, metav1.ListOptions{
    FieldSelector: "metadata.name=" + jobName,
})

// continuously pop off the watch results channel for job status
for event := range watch.ResultChan() {
        // wait for job success, error, or other states
}

Akhir sekali, sebaik sahaja kami berjaya menyiapkan kerja, kami boleh mengambil keputusan daripada log pod Job yang akan mempunyai hasil json sebenar daripada CLI kad skor! Sebaik sahaja kami mendapat keputusan tersebut, kami boleh menaikkan semula skor ke dalam pangkalan data dan mengubah sebarang metadata yang diperlukan untuk memberi isyarat kepada perkhidmatan mikro kami yang lain atau OpenSauced API bahawa terdapat skor baharu!

Seperti yang dinyatakan sebelum ini, scorecard-k8s-scheduler boleh menjalankan sebarang bilangan kerja serentak: dalam tetapan pengeluaran kami, kami mempunyai sejumlah besar kerja yang dijalankan serentak, semuanya diuruskan oleh perkhidmatan mikro ini. Tujuannya adalah untuk dapat mengemas kini skor setiap 2 minggu merentas semua repositori di GitHub. Dengan skala seperti ini, kami berharap dapat memberikan alatan dan cerapan yang berkuasa kepada mana-mana penyelenggara atau pengguna sumber terbuka!

Perkhidmatan mikro "penjadual" akhirnya menjadi sebahagian kecil daripada keseluruhan sistem ini: sesiapa yang biasa dengan pengawal Kubernetes tahu bahawa terdapat bahagian tambahan infrastruktur Kubernetes yang diperlukan untuk menjadikan sistem berfungsi. Dalam kes kami, kami memerlukan beberapa kawalan akses berasaskan peranan (RBAC) untuk membolehkan perkhidmatan mikro kami mencipta Pekerjaan pada kelompok.

Pertama, kami memerlukan akaun perkhidmatan: ini ialah akaun yang akan digunakan oleh penjadual dan mempunyai kawalan akses yang terikat kepadanya:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: scorecard-sa
  namespace: scorecard-ns

Kami meletakkan akaun perkhidmatan ini dalam ruang nama "scorecard-ns" kami di mana semua ini dijalankan.

Seterusnya, kita perlu mempunyai peranan dan pengikatan peranan untuk akaun perkhidmatan. Ini termasuk kawalan akses sebenar (termasuk dapat membuat Pekerjaan, melihat log pod, dll.)

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: scorecard-scheduler-role
  namespace: scorecard-ns
rules:
- apiGroups: ["batch"]
  resources: ["jobs"]
  verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
- apiGroups: [""]
  resources: ["pods", "pods/log"]
  verbs: ["get", "list", "watch"]

—

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: scorecard-scheduler-role-binding
  namespace: scorecard-ns
subjects:
- kind: ServiceAccount
  name: scorecard-sa
  namespace: scorecard-ns
roleRef:
  kind: Role
  name: scorecard-scheduler-role
  apiGroup: rbac.authorization.k8s.io

Anda mungkin bertanya kepada diri sendiri "Mengapa saya perlu memberikan akses akaun perkhidmatan ini untuk mendapatkan pod dan log pod? Bukankah itu lanjutan kawalan akses yang berlebihan?” Ingat! Pekerjaan mempunyai pod dan untuk mendapatkan log pod yang mempunyai hasil sebenar CLI kad skor, kita mesti boleh menyenaraikan pod daripada kerja dan kemudian membaca lognya!

Bahagian kedua ini, "RoleBinding", ialah tempat kami sebenarnya melampirkan Peranan pada akaun perkhidmatan. Akaun perkhidmatan ini kemudiannya boleh digunakan apabila memulakan kerja baharu pada gugusan.

Terima kasih kepada Alex Ellis dan pengawal tugas yang sangat baik: ini adalah inspirasi dan rujukan yang besar untuk menggunakan Client-Go with Jobs dengan betul!

Kekal bijak semua!

Atas ialah kandungan terperinci Cara kami menggunakan kerja Kubernetes untuk menskalakan OpenSSF Scorecard. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn