
Kami semakin banyak ditanya tentang pengembangan layanan-layanan microsoft di Kubernetes. Pengembang, terutama bahasa yang ditafsirkan, ingin segera memperbaiki kode di IDE favorit mereka dan tanpa menunggu build / penyebaran untuk melihat hasilnya - hanya dengan menekan F5. Dan ketika datang ke aplikasi monolitik, itu sudah cukup untuk meningkatkan basis data dan server web (di Docker, VirtualBox ...), setelah itu - segera menikmati pengembangannya. Dengan menggergaji monolit ke dalam layanan mikro dan munculnya Kubernetes, dengan munculnya ketergantungan satu sama lain, segalanya
menjadi sedikit lebih rumit . Semakin banyak dari layanan microser ini, semakin banyak masalah. Untuk menikmati pengembangan lagi, Anda perlu mengumpulkan lebih dari satu atau dua kontainer Docker, dan kadang-kadang bahkan lebih dari selusin ... Secara umum, semua ini bisa memakan banyak waktu, karena itu juga harus terus diperbarui.
Pada waktu yang berbeda, kami mencoba berbagai solusi untuk masalah tersebut. Dan saya akan mulai dengan solusi yang terakumulasi atau hanya "kruk".
1. Kruk
Sebagian besar IDE memiliki kemampuan untuk mengedit kode secara langsung di server menggunakan FTP / SFTP. Cara ini sangat jelas dan kami segera memutuskan untuk menggunakannya. Esensinya adalah sebagai berikut:
- Di pod untuk lingkungan pengembangan (dev / review), wadah tambahan diluncurkan dengan akses melalui SSH dan meneruskan kunci SSH publik pengembang yang akan melakukan / menyebarkan aplikasi.
- Pada tahap init (dalam wadah
prepare-app
) kami mentransfer kode ke emptyDir
untuk memiliki akses ke kode dari wadah dengan aplikasi dan server SSH.

Untuk pemahaman yang lebih baik tentang implementasi teknis dari skema semacam itu, saya akan memberikan fragmen dari konfigurasi YAML yang terlibat di Kubernetes.
Konfigurasi
1.1. values.yaml
ssh_pub_key: vasya.pupkin: <ssh public key in base64>
Di sini
vasya.pupkin
adalah nilai variabel
${GITLAB_USER_LOGIN}
.
1.2. deployment.yaml
... {{ if eq .Values.global.debug "yes" }} volumes: - name: ssh-pub-key secret: defaultMode: 0600 secretName: {{ .Chart.Name }}-ssh-pub-key - name: app-data emptyDir: {} initContainers: - name: prepare-app {{ tuple "backend" . | include "werf_container_image" | indent 8 }} volumeMounts: - name: app-data mountPath: /app-data command: ["bash", "-c", "cp -ar /app/* /app-data/" ] {{ end }} containers: {{ if eq .Values.global.debug "yes" }} - name: ssh image: corbinu/ssh-server volumeMounts: - name: ssh-pub-key readOnly: true mountPath: /root/.ssh/authorized_keys subPath: authorized_keys - name: app-data mountPath: /app ports: - name: ssh containerPort: 22 protocol: TCP {{ end }} - name: backend volumeMounts: {{ if eq .Values.global.debug "yes" }} - name: app-data mountPath: /app {{ end }} command: ["/usr/sbin/php-fpm7.2", "--fpm-config", "/etc/php/7.2/php-fpm.conf", "-F"] ...
1.3. secret.yaml
{{ if eq .Values.global.debug "yes" }} apiVersion: v1 kind: Secret metadata: name: {{ .Chart.Name }}-ssh-pub-key type: Opaque data: authorized_keys: "{{ first (pluck .Values.global.username .Values.ssh_pub_key) }}" {{ end }}
Sentuhan terakhir
Setelah itu, tetap hanya meneruskan
variabel yang diperlukan ke gitlab-ci.yml :
dev: stage: deploy script: - type multiwerf && source <(multiwerf use 1.0 beta) - type werf && source <(werf ci-env gitlab --tagging-strategy tag-or-branch --verbose) - werf deploy --namespace ${CI_PROJECT_NAME}-stage --set "global.env=stage" --set "global.git_rev=${CI_COMMIT_SHA}" --set "global.debug=yes" --set "global.username=${GITLAB_USER_LOGIN}" tags: - build
Voila: pengembang yang meluncurkan penyebaran dapat terhubung menggunakan nama layanan (
kami sudah memberi tahu Anda cara mengeluarkan akses ke gugus dengan aman) dari desktop Anda melalui SFTP dan mengedit kode tanpa menunggu kode dikirimkan ke gugus.
Ini adalah solusi yang sepenuhnya berfungsi, tetapi dari sudut pandang implementasi memiliki kelemahan yang jelas:
- kebutuhan untuk memperbaiki grafik Helm, yang semakin mempersulit pembacaannya;
- Hanya orang yang telah menggunakan layanan yang dapat menggunakannya;
- Anda harus ingat untuk menyinkronkannya dengan direktori lokal dengan kode dan komit di Git.
2. Telepresence
Proyek
Telepresence telah dikenal selama beberapa waktu, tetapi dengan serius mencobanya dalam praktik dengan kami, seperti yang mereka katakan, "tidak mencapai tangan kami". Namun, permintaan telah melakukan tugasnya dan sekarang kami senang untuk berbagi pengalaman yang mungkin berguna bagi pembaca blog kami - terutama karena masih belum ada bahan lain tentang Telepresence di hub.
Singkatnya, itu tidak menakutkan. Semua tindakan yang membutuhkan eksekusi oleh pengembang, kami menempatkannya di file teks dari Helm-chart, yang disebut
NOTES.txt
. Jadi, setelah penyebaran layanan di Kubernetes, pengembang melihat instruksi untuk memulai lingkungan dev lokal di log pekerjaan GitLab:
!!! , Kubernetes !!! * * * VPN * * kubectl ( https://kubernetes.io/docs/tasks/tools/install-kubectl/ ) * * config- kubectl ( ~/.kube/config) * * telepresence ( https://www.telepresence.io/reference/install ) * * Docker * * reporter https://gitlab.site.com/group/app * * registry / GitLab ( ): ######################################################################### docker login registry.site.com ######################################################################### * ######################################################################### telepresence --namespace {{ .Values.global.env }} --swap-deployment {{ .Chart.Name }}:backend --mount=/tmp/app --docker-run -v `pwd`:/app -v /tmp/app/var/run/secrets:/var/run/secrets -ti registry.site.com/group/app/backend:v8 #########################################################################
Kami tidak akan memikirkan langkah-langkah yang dijelaskan dalam manual ini ... kecuali untuk yang terakhir. Apa yang terjadi selama peluncuran Telepresence?
Bekerja dengan Telepresence
Saat mulai (dengan perintah terakhir yang ditentukan dalam instruksi di atas) kami menetapkan:
- namespace (namespace) di mana layanan Microsoft diluncurkan;
- nama-nama penyebaran dan wadah yang ingin kami tembus.
Argumen yang tersisa bersifat opsional. Jika layanan kami berinteraksi dengan Kubernetes API dan
ServiceAccount dibuat untuk itu, kami perlu memasang sertifikat / token di desktop kami. Untuk melakukan ini, gunakan opsi
--mount=true
(atau
--mount=/dst_path
), yang akan me-mount root (/) dari wadah di Kubernetes ke desktop kita. Setelah itu, kita bisa (tergantung pada OS dan cara aplikasi diluncurkan) menggunakan "kunci" dari cluster.
Pertama, pertimbangkan opsi peluncuran aplikasi yang paling serbaguna - dalam wadah Docker. Untuk melakukan ini, gunakan
--docker-run
dan
--docker-run
direktori dengan kode di wadah:
-v `pwd`:/app
Harap dicatat bahwa ini menyiratkan mulai dari direktori dengan proyek. Kode aplikasi akan dipasang di direktori
/app
dalam wadah.
Berikutnya:
-v /tmp/app/var/run/secrets:/var/run/secrets
- untuk memasang direktori dengan sertifikat / token ke dalam wadah.
Opsi ini akhirnya diikuti oleh gambar di mana aplikasi akan diluncurkan.
NB : Saat membuat gambar, Anda harus menentukan
CMD
atau
ENTRYPOINT
!
Sebenarnya apa yang akan terjadi selanjutnya?
- Di Kubernetes, untuk Penempatan yang ditentukan, jumlah replika akan diubah menjadi 0. Sebagai gantinya, Penempatan baru akan diluncurkan - dengan wadah
backend
diganti. - Di desktop, 2 wadah akan mulai: yang pertama - dengan Telepresence (ini akan mem-proxy permintaan dari / ke Kubernetes), yang kedua - dengan aplikasi yang sedang dikembangkan.
- Jika exec'nutsya dalam wadah dengan aplikasi, maka kita akan memiliki akses ke semua variabel ENV yang disahkan oleh Helm selama penyebaran, serta semua layanan tersedia. Yang tersisa hanyalah mengedit kode di IDE favorit Anda dan menikmati hasilnya.
- Di akhir pekerjaan, cukup tutup terminal tempat Telepresence berjalan (akhiri sesi menggunakan Ctrl + C), wadah Docker akan berhenti di desktop, dan semuanya akan kembali ke keadaan semula di Kubernetes. Yang tersisa hanyalah melakukan komitmen, mengeluarkan MR dan meneruskannya untuk meninjau / menggabungkan / ... (tergantung pada alur kerja Anda).
Jika kami tidak ingin menjalankan aplikasi dalam wadah Docker - misalnya, kami mengembangkannya bukan dalam PHP, tetapi dalam Go, dan masih mengumpulkannya secara lokal - meluncurkan Telepresence akan lebih mudah:
telepresence --namespace {{ .Values.global.env }} --swap-deployment {{ .Chart.Name }}:backend --mount=true
Jika aplikasi mengakses Kubernetes API, Anda harus memasang
direktori dengan kunci . Untuk Linux, ada utilitas
proot :
proot -b $TELEPRESENCE_ROOT/var/run/secrets/:/var/run/secrets bash
Setelah memulai Telepresence tanpa opsi
--docker-run
, semua variabel lingkungan akan tersedia di terminal saat ini, jadi Anda perlu memulai aplikasi di dalamnya.
NB : Saat menggunakan, misalnya, PHP, Anda harus ingat untuk menonaktifkan berbagai op_cache, apc, dan akselerator lain untuk pengembangan - jika tidak mengedit kode tidak akan menghasilkan hasil yang diinginkan.
Ringkasan
Pengembangan lokal dengan Kubernetes adalah masalah yang kebutuhan solusinya tumbuh sebanding dengan penyebaran platform ini. Setelah menerima permintaan yang relevan dari pengembang (dari pelanggan kami), kami mulai menyelesaikannya dengan cara pertama yang tersedia, yang, bagaimanapun, tidak membuktikan diri mereka dari jarak jauh. Untungnya, ini menjadi jelas tidak hanya sekarang dan tidak hanya bagi kita, oleh karena itu sarana yang lebih cocok telah muncul di dunia, dan Telepresence adalah yang paling terkenal di antara mereka (omong-omong, masih ada
perancah dari Google). Pengalaman kami dalam penggunaannya tidak terlalu bagus, tetapi sudah memberikan alasan untuk merekomendasikan "kolega" - coba saja!
PS
Lainnya dari siklus tips & trik K8: