Gunakan aplikasi merentas berbilang kluster Kubernetes dengan Helm

Cara Dailymotion menggunakan Kubernetes: Penerapan Aplikasi

Kami di Dailymotion mula menggunakan Kubernetes dalam pengeluaran 3 tahun lalu. Tetapi menggunakan aplikasi merentas berbilang kluster adalah menyeronokkan, jadi sejak beberapa tahun kebelakangan ini kami telah cuba menambah baik alatan dan aliran kerja kami.

Di mana ia bermula

Di sini kami akan membincangkan cara kami menggunakan aplikasi kami merentas berbilang kluster Kubernetes di seluruh dunia.

Untuk menggunakan berbilang objek Kubernetes serentak, kami menggunakan Helm, dan semua carta kami disimpan dalam satu repositori git. Untuk menggunakan timbunan aplikasi penuh daripada beberapa perkhidmatan, kami menggunakan carta ringkasan yang dipanggil. Pada asasnya, ini ialah carta yang mengisytiharkan kebergantungan dan membolehkan anda memulakan API dan perkhidmatannya dengan satu arahan.

Kami juga menulis skrip Python kecil di atas Helm untuk melakukan semakan, mencipta carta, menambah rahsia dan menggunakan aplikasi. Semua tugas ini dilakukan pada platform CI pusat menggunakan imej docker.

Mari kita ke intinya.

Catatan. Semasa anda membaca ini, calon keluaran pertama untuk Helm 3 telah pun diumumkan. Versi utama mengandungi pelbagai penambahbaikan untuk menangani beberapa isu yang kami hadapi pada masa lalu.

Aliran kerja pembangunan carta

Kami menggunakan percabangan untuk aplikasi, dan kami memutuskan untuk menggunakan pendekatan yang sama pada carta.

  • Cawangan dev digunakan untuk mencipta carta yang akan diuji pada kelompok pembangunan.
  • Apabila permintaan tarik dikemukakan kepada master, mereka didaftar masuk pementasan.
  • Akhir sekali, kami membuat permintaan tarik untuk melakukan perubahan pada cawangan prod dan mengaplikasikannya dalam pengeluaran.

Setiap persekitaran mempunyai repositori peribadi sendiri yang menyimpan carta kami, dan kami gunakan Muzium Chart dengan API yang sangat berguna. Dengan cara ini kami memastikan pengasingan ketat antara persekitaran dan ujian dunia sebenar carta sebelum menggunakannya dalam pengeluaran.

Repositori carta dalam persekitaran yang berbeza

Perlu diingat bahawa apabila pembangun menolak cawangan dev, versi carta mereka ditolak secara automatik ke dev Chartmuseum. Oleh itu, semua pembangun menggunakan repositori dev yang sama, dan anda perlu menentukan versi carta anda dengan teliti supaya tidak menggunakan perubahan orang lain secara tidak sengaja.

Selain itu, skrip Python kecil kami mengesahkan objek Kubernetes terhadap spesifikasi OpenAPI Kubernetes yang digunakan Kubeval, sebelum menerbitkannya di Chartmusem.

Penerangan umum aliran kerja pembangunan carta

  1. Menyediakan tugas saluran paip mengikut spesifikasi gazr.io untuk kawalan kualiti (lint, unit-test).
  2. Menolak imej docker dengan alat Python yang menggunakan aplikasi kami.
  3. Menyediakan persekitaran mengikut nama cawangan.
  4. Mengesahkan fail yaml Kubernetes menggunakan Kubeval.
  5. Meningkatkan versi carta dan carta induknya secara automatik (carta yang bergantung pada carta yang diubah).
  6. Menyerahkan carta kepada Chartmuseum yang sepadan dengan persekitarannya

Menguruskan perbezaan merentas kelompok

Persekutuan Kluster

Ada masa kita guna persekutuan kluster Kubernetes, di mana objek Kubernetes boleh diisytiharkan daripada satu titik akhir API. Tetapi masalah timbul. Sebagai contoh, beberapa objek Kubernetes tidak dapat dibuat dalam titik akhir persekutuan, menjadikannya sukar untuk mengekalkan objek bersekutu dan objek lain untuk kelompok individu.

Untuk menyelesaikan masalah, kami mula menguruskan kluster secara bebas, yang sangat memudahkan proses (kami menggunakan versi pertama persekutuan; sesuatu mungkin telah berubah pada yang kedua).

Platform teragih geo

Platform kami kini diedarkan di 6 wilayah - 3 secara tempatan dan 3 dalam awan.


Agihan Teragih

Nilai Helm Global

4 nilai Helm global membolehkan anda mengenal pasti perbezaan antara kelompok. Semua carta kami mempunyai nilai minimum lalai.

global:
  cloud: True
  env: staging
  region: us-central1
  clusterName: staging-us-central1

Nilai global

Nilai ini membantu menentukan konteks untuk aplikasi kami dan digunakan untuk pelbagai tujuan: pemantauan, pengesanan, pengelogan, membuat panggilan luaran, penskalaan, dll.

  • "cloud": Kami mempunyai platform Kubernetes hibrid. Sebagai contoh, API kami digunakan dalam zon GCP dan di pusat data kami.
  • "env": Sesetengah nilai mungkin berubah untuk persekitaran bukan pengeluaran. Contohnya, definisi sumber dan konfigurasi penskalaan automatik.
  • "rantau": Maklumat ini membantu menentukan lokasi kluster dan boleh digunakan untuk menentukan titik akhir berdekatan untuk perkhidmatan luaran.
  • "clusterName": jika dan bila kita mahu menentukan nilai untuk kelompok individu.

Berikut ialah contoh khusus:

{{/* Returns Horizontal Pod Autoscaler replicas for GraphQL*/}}
{{- define "graphql.hpaReplicas" -}}
{{- if eq .Values.global.env "prod" }}
{{- if eq .Values.global.region "europe-west1" }}
minReplicas: 40
{{- else }}
minReplicas: 150
{{- end }}
maxReplicas: 1400
{{- else }}
minReplicas: 4
maxReplicas: 20
{{- end }}
{{- end -}}

Contoh templat helm

Logik ini ditakrifkan dalam templat pembantu untuk mengelakkan Kubernetes YAML berantakan.

Pengumuman Permohonan

Alat penggunaan kami adalah berdasarkan berbilang fail YAML. Di bawah ialah contoh cara kami mengisytiharkan perkhidmatan dan topologi penskalaannya (bilangan replika) dalam kelompok.

releases:
  - foo.world

foo.world:                # Release name
  services:               # List of dailymotion's apps/projects
    foobar:
      chart_name: foo-foobar
      repo: [email protected]:dailymotion/foobar
      contexts:
        prod-europe-west1:
          deployments:
            - name: foo-bar-baz
              replicas: 18
            - name: another-deployment
              replicas: 3

Definisi Perkhidmatan

Ini ialah garis besar semua langkah yang mentakrifkan aliran kerja penggunaan kami. Langkah terakhir menggunakan aplikasi kepada berbilang kelompok pekerja secara serentak.


Langkah-langkah Penggunaan Jenkins

Bagaimana pula dengan rahsia?

Mengenai keselamatan, kami menjejaki semua rahsia dari tempat yang berbeza dan menyimpannya dalam peti besi yang unik Bilik Kebal di Paris.

Alat penempatan kami mengekstrak nilai rahsia daripada Vault dan, apabila tiba masanya, masukkannya ke dalam Helm.

Untuk melakukan ini, kami menentukan pemetaan antara rahsia dalam Vault dan rahsia yang diperlukan oleh aplikasi kami:

secrets:                                                                                                                                                                                                        
     - secret_id: "stack1-app1-password"                                                                                                                                                                                  
       contexts:                                                                                                                                                                                                   
         - name: "default"                                                                                                                                                                                         
           vaultPath: "/kv/dev/stack1/app1/test"                                                                                                                                                               
           vaultKey: "password"                                                                                                                                                                                    
         - name: "cluster1"                                                                                                                                                                           
           vaultPath: "/kv/dev/stack1/app1/test"                                                                                                                                                               
           vaultKey: "password"

  • Kami telah menentukan peraturan am untuk dipatuhi semasa merakam rahsia dalam Vault.
  • Jika rahsia itu berlaku kepada konteks atau kelompok tertentu, anda perlu menambah entri tertentu. (Di sini cluster1 konteks mempunyai nilai sendiri untuk kata laluan stack-app1 rahsia).
  • Jika tidak nilai digunakan secara lalai.
  • Untuk setiap item dalam senarai ini dalam Rahsia Kubernetes pasangan nilai kunci dimasukkan. Oleh itu, templat rahsia dalam carta kami adalah sangat mudah.

apiVersion: v1
data:
{{- range $key,$value := .Values.secrets }}
  {{ $key }}: {{ $value | b64enc | quote }}
{{ end }}
kind: Secret
metadata:
  name: "{{ .Chart.Name }}"
  labels:
    chartVersion: "{{ .Chart.Version }}"
    tillerVersion: "{{ .Capabilities.TillerVersion.SemVer }}"
type: Opaque

Masalah dan batasan

Bekerja dengan berbilang repositori

Kini kami memisahkan pembangunan carta dan aplikasi. Ini bermakna bahawa pembangun perlu bekerja dalam dua repositori git: satu untuk aplikasi, dan satu untuk menentukan penggunaannya kepada Kubernetes. 2 repositori git bermakna 2 aliran kerja, dan mudah untuk orang baru keliru.

Mengurus carta umum adalah menyusahkan

Seperti yang telah kami katakan, carta generik sangat berguna untuk mengenal pasti kebergantungan dan menggunakan berbilang aplikasi dengan cepat. Tetapi kita gunakan --reuse-valuesuntuk mengelak daripada melepasi semua nilai setiap kali kami menggunakan aplikasi yang merupakan sebahagian daripada carta umum ini.

Dalam aliran kerja penghantaran berterusan, kami hanya mempunyai dua nilai yang sentiasa berubah: bilangan replika dan teg imej (versi). Nilai lain yang lebih stabil diubah secara manual, dan ini agak sukar. Selain itu, satu kesilapan dalam menggunakan carta umum boleh membawa kepada kegagalan yang serius, seperti yang telah kita lihat daripada pengalaman kita sendiri.

Mengemas kini berbilang fail konfigurasi

Apabila pembangun menambah aplikasi baharu, dia perlu menukar beberapa fail: pengisytiharan aplikasi, senarai rahsia, menambah aplikasi sebagai pergantungan jika ia disertakan dalam carta umum.

Keizinan Jenkins terlalu dipanjangkan dalam Bilik Kebal

Sekarang kita ada satu AppRole, yang membaca semua rahsia dari Vault.

Proses rollback tidak automatik

Untuk melancarkan semula, anda perlu menjalankan arahan pada beberapa kelompok, dan ini penuh dengan ralat. Kami melakukan operasi ini secara manual untuk memastikan bahawa ID versi yang betul ditentukan.

Kami bergerak ke arah GitOps

Matlamat kami

Kami mahu mengembalikan carta ke repositori aplikasi yang digunakannya.

Aliran kerja akan sama seperti untuk pembangunan. Sebagai contoh, apabila cawangan ditolak untuk menguasai, penempatan akan dicetuskan secara automatik. Perbezaan utama antara pendekatan ini dan aliran kerja semasa ialah itu semuanya akan diuruskan dalam git (aplikasi itu sendiri dan cara ia digunakan dalam Kubernetes).

Terdapat beberapa kelebihan:

  • banyak lebih jelas untuk pemaju. Lebih mudah untuk mempelajari cara menggunakan perubahan dalam carta setempat.
  • Definisi penggunaan perkhidmatan boleh ditentukan tempat yang sama dengan kod perkhidmatan.
  • Menguruskan penyingkiran carta umum. Perkhidmatan ini akan mempunyai keluaran Helm sendiri. Ini akan membolehkan anda menguruskan kitaran hayat aplikasi (putar balik, naik taraf) pada tahap terkecil, supaya tidak menjejaskan perkhidmatan lain.
  • Faedah git untuk pengurusan carta: buat asal perubahan, log audit, dll. Jika anda perlu membuat asal perubahan pada carta, anda boleh melakukan ini menggunakan git. Pengerahan bermula secara automatik.
  • Anda mungkin mempertimbangkan untuk meningkatkan aliran kerja pembangunan anda dengan alatan seperti Skaffold, yang mana pembangun boleh menguji perubahan dalam konteks yang hampir dengan pengeluaran.

Penghijrahan dua langkah

Pembangun kami telah menggunakan aliran kerja ini selama 2 tahun sekarang, jadi kami mahu penghijrahan itu tidak menyakitkan yang mungkin. Oleh itu, kami memutuskan untuk menambah langkah perantaraan dalam perjalanan ke matlamat.
Peringkat pertama adalah mudah:

  • Kami menyimpan struktur yang serupa untuk menyediakan penggunaan aplikasi, tetapi dalam satu objek yang dipanggil DailymotionRelease.

apiVersion: "v1"
kind: "DailymotionRelease"
metadata:
  name: "app1.ns1"
  environment: "dev"
  branch: "mybranch"
spec:
  slack_channel: "#admin"
  chart_name: "app1"
  scaling:
    - context: "dev-us-central1-0"
      replicas:
        - name: "hermes"
          count: 2
    - context: "dev-europe-west1-0"
      replicas:
        - name: "app1-deploy"
          count: 2
  secrets:
    - secret_id: "app1"
      contexts:
        - name: "default"
          vaultPath: "/kv/dev/ns1/app1/test"
          vaultKey: "password"
        - name: "dev-europe-west1-0"
          vaultPath: "/kv/dev/ns1/app1/test"
          vaultKey: "password"

  • 1 keluaran bagi setiap aplikasi (tanpa carta umum).
  • Carta dalam repositori git aplikasi.

Kami telah berbincang dengan semua pembangun, jadi proses migrasi telah pun bermula. Peringkat pertama masih dikawal menggunakan platform CI. Saya akan menulis catatan lain tidak lama lagi tentang fasa dua: cara kami beralih ke aliran kerja GitOps dengan Fluks. Saya akan memberitahu anda cara kami menyediakan segala-galanya dan kesukaran yang kami hadapi (berbilang repositori, rahsia, dll.). Ikuti berita.

Di sini kami telah cuba menerangkan kemajuan kami dalam aliran kerja penggunaan aplikasi sejak beberapa tahun lalu, yang membawa kepada pemikiran tentang pendekatan GitOps. Kami belum mencapai matlamat dan akan melaporkan hasilnya, tetapi kini kami yakin bahawa kami telah melakukan perkara yang betul apabila kami memutuskan untuk memudahkan segala-galanya dan membawanya lebih dekat dengan tabiat pemaju.

Sumber: www.habr.com

Tambah komen