เราถูกถามมากขึ้นเกี่ยวกับการพัฒนาไมโครเซอร์วิสใน Kubernetes นักพัฒนา โดยเฉพาะภาษาที่แปล ต้องการแก้ไขโค้ดอย่างรวดเร็วใน IDE ที่พวกเขาชื่นชอบ และดูผลลัพธ์โดยไม่ต้องรอการสร้าง/ปรับใช้ เพียงแค่กด F5 และเมื่อพูดถึงแอปพลิเคชันขนาดใหญ่ การติดตั้งฐานข้อมูลและเว็บเซิร์ฟเวอร์ภายในเครื่อง (ใน Docker, VirtualBox...) ก็เพียงพอแล้ว จากนั้นจึงเพลิดเพลินกับการพัฒนาได้ทันที ด้วยการตัดเสาหินออกเป็นไมโครเซอร์วิสและการมาถึงของ Kubernetes โดยมีลักษณะของการพึ่งพาซึ่งกันและกัน ทุกสิ่งทุกอย่าง
ในเวลาที่ต่างกัน เราได้ลองวิธีแก้ไขปัญหาที่แตกต่างกัน และฉันจะเริ่มต้นด้วยวิธีแก้ปัญหาที่สั่งสมมาหรือเพียงแค่ "ไม้ค้ำยัน"
1. ไม้ค้ำยัน
IDE ส่วนใหญ่มีความสามารถในการแก้ไขโค้ดได้โดยตรงบนเซิร์ฟเวอร์โดยใช้ FTP/SFTP เส้นทางนี้ชัดเจนมากและเราตัดสินใจใช้มันทันที สาระสำคัญของมันเดือดลงไปดังต่อไปนี้:
- ในพ็อดของสภาพแวดล้อมการพัฒนา (dev/review) จะมีการเปิดตัวคอนเทนเนอร์เพิ่มเติมพร้อมการเข้าถึง SSH และส่งต่อคีย์ SSH สาธารณะของนักพัฒนาที่จะกระทำ/ปรับใช้แอปพลิเคชัน
- ในระยะเริ่มต้น (ภายในคอนเทนเนอร์
prepare-app
) โอนรหัสไปที่emptyDir
เพื่อเข้าถึงโค้ดจากคอนเทนเนอร์แอปพลิเคชันและเซิร์ฟเวอร์ SSH
เพื่อให้เข้าใจการใช้งานทางเทคนิคของโครงร่างดังกล่าวได้ดีขึ้น ฉันจะจัดเตรียมส่วนย่อยของการกำหนดค่า YAML ที่เกี่ยวข้องใน Kubernetes
การกำหนดค่า
1.1. ค่านิยม.yaml
ssh_pub_key:
vasya.pupkin: <ssh public key in base64>
ที่นี่ vasya.pupkin
คือค่าของตัวแปร ${GITLAB_USER_LOGIN}
.
1.2. การปรับใช้.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 }}
สัมผัสสุดท้าย
หลังจากนั้นสิ่งที่เหลืออยู่คือการโอน
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: นักพัฒนาที่เปิดตัวการปรับใช้สามารถเชื่อมต่อด้วยชื่อบริการ (วิธีให้สิทธิ์การเข้าถึงคลัสเตอร์อย่างปลอดภัย
นี่เป็นวิธีแก้ปัญหาที่ทำงานได้อย่างสมบูรณ์ แต่จากมุมมองของการนำไปปฏิบัติก็มีข้อเสียที่ชัดเจน:
- ความจำเป็นในการปรับแต่งแผนภูมิ Helm ซึ่งทำให้อ่านยากในอนาคต
- สามารถใช้งานได้โดยบุคคลที่ใช้บริการเท่านั้น
- คุณต้องจำไว้ว่าต้องซิงโครไนซ์มันกับไดเร็กทอรีในเครื่องด้วยโค้ดและคอมมิตมันกับ Git
2. การนำเสนอทางไกล
โครงการ
สรุปแล้วทุกอย่างกลับกลายเป็นว่าไม่น่ากลัวนัก เราได้วางการกระทำทั้งหมดที่ต้องมีการดำเนินการในส่วนของนักพัฒนาไว้ในไฟล์ข้อความแผนภูมิ Helm ที่เรียกว่า NOTES.txt
. ดังนั้น หลังจากปรับใช้บริการกับ Kubernetes แล้ว นักพัฒนาจะเห็นคำแนะนำในการเปิดใช้สภาพแวดล้อม dev ภายในเครื่องในบันทึกงาน 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
#########################################################################
เราจะไม่ลงรายละเอียดเกี่ยวกับขั้นตอนที่อธิบายไว้ในคำแนะนำนี้... ยกเว้นขั้นตอนสุดท้าย จะเกิดอะไรขึ้นระหว่างการเปิดตัว Telepresence?
การทำงานกับ Telepresence
เมื่อเริ่มต้น (โดยใช้คำสั่งสุดท้ายที่ระบุในคำแนะนำด้านบน) เราตั้งค่า:
- เนมสเปซที่ไมโครเซอร์วิสกำลังทำงานอยู่
- ชื่อของการปรับใช้และคอนเทนเนอร์ที่เราต้องการเจาะเข้าไป
อาร์กิวเมนต์ที่เหลือเป็นทางเลือก หากบริการของเราโต้ตอบกับและสำหรับ Kubernetes API --mount=true
(หรือ --mount=/dst_path
) ซึ่งจะเมานต์รูท (/) จากคอนเทนเนอร์ Kubernetes ไปยังเดสก์ท็อปของเรา หลังจากนี้ เราสามารถใช้ "คีย์" จากคลัสเตอร์ได้ (ขึ้นอยู่กับระบบปฏิบัติการและวิธีการเปิดใช้งานแอปพลิเคชัน)
ก่อนอื่นเรามาดูตัวเลือกที่เป็นสากลที่สุดสำหรับการรันแอปพลิเคชัน - ในคอนเทนเนอร์ Docker ในการทำเช่นนี้เราจะใช้กุญแจ --docker-run
และเมานต์ไดเร็กทอรีด้วยโค้ดลงในคอนเทนเนอร์: -v `pwd`:/app
โปรดทราบว่าการดำเนินการนี้จะถือว่าทำงานจากไดเรกทอรีโครงการ รหัสแอปพลิเคชันจะถูกเมานต์ในไดเร็กทอรี /app
ในภาชนะ
ถัดไป: -v /tmp/app/var/run/secrets:/var/run/secrets
— เพื่อเมานต์ไดเร็กทอรีด้วยใบรับรอง/โทเค็นลงในคอนเทนเนอร์
ในที่สุดตัวเลือกนี้จะตามมาด้วยรูปภาพที่แอปพลิเคชันจะทำงาน NB: เมื่อสร้างภาพต้องระบุ CMD
หรือ ENTRYPOINT
!
จะเกิดอะไรขึ้นต่อไป?
- ใน Kubernetes สำหรับการปรับใช้ที่ระบุ จำนวนเรพลิกาจะเปลี่ยนเป็น 0 แต่จะมีการเปิดใช้การปรับใช้ใหม่แทน - พร้อมด้วยคอนเทนเนอร์ทดแทน
backend
. - คอนเทนเนอร์ 2 รายการจะเปิดตัวบนเดสก์ท็อป: คอนเทนเนอร์แรกมี Telepresence (จะเป็นคำขอพร็อกซีจาก/ไปยัง Kubernetes) คอนเทนเนอร์ที่สองมีการพัฒนาแอปพลิเคชัน
- หากเราดำเนินการลงในคอนเทนเนอร์ด้วยแอปพลิเคชัน ตัวแปร ENV ทั้งหมดที่ Helm ถ่ายโอนระหว่างการปรับใช้งานจะพร้อมใช้งานสำหรับเรา และบริการทั้งหมดก็จะพร้อมใช้งานเช่นกัน สิ่งที่เหลืออยู่คือการแก้ไขโค้ดใน IDE ที่คุณชื่นชอบและเพลิดเพลินกับผลลัพธ์
- ในตอนท้ายของงาน คุณเพียงแค่ต้องปิดเทอร์มินัลที่ Telepresence กำลังทำงานอยู่ (ยุติเซสชันด้วย Ctrl+C) - คอนเทนเนอร์ Docker จะหยุดบนเดสก์ท็อป และใน Kubernetes ทุกอย่างจะกลับสู่สถานะเริ่มต้น สิ่งที่เหลืออยู่คือการดำเนินการ ออก MR และโอนไปตรวจสอบ/รวม/... (ขึ้นอยู่กับขั้นตอนการทำงานของคุณ)
หากเราไม่ต้องการรันแอปพลิเคชันในคอนเทนเนอร์ Docker - ตัวอย่างเช่น เราไม่ได้พัฒนาใน PHP แต่พัฒนาใน Go และยังคงสร้างมันขึ้นมาในเครื่อง - การเปิดตัว Telepresence จะยิ่งง่ายกว่า:
telepresence --namespace {{ .Values.global.env }} --swap-deployment {{ .Chart.Name }}:backend --mount=true
หากแอปพลิเคชันเข้าถึง Kubernetes API คุณจะต้องต่อเชื่อมไดเร็กทอรีคีย์ (https://www.telepresence.io/howto/volumes) มียูทิลิตี้สำหรับ Linux
proot -b $TELEPRESENCE_ROOT/var/run/secrets/:/var/run/secrets bash
หลังจากเปิดตัว Telepresence โดยไม่มีตัวเลือก --docker-run
ตัวแปรสภาพแวดล้อมทั้งหมดจะพร้อมใช้งานในเทอร์มินัลปัจจุบัน ดังนั้นจึงต้องเปิดแอปพลิเคชันในเทอร์มินัลนั้น
NB: เมื่อใช้เช่น PHP คุณต้องจำไว้ว่าให้ปิดการใช้งาน op_cache, apc และตัวเร่งความเร็วอื่น ๆ เพื่อการพัฒนา - มิฉะนั้นการแก้ไขโค้ดจะไม่นำไปสู่ผลลัพธ์ที่ต้องการ
ผลของการ
การพัฒนาในท้องถิ่นด้วย Kubernetes เป็นปัญหาที่โซลูชันมีการเติบโตตามสัดส่วนของการแพร่กระจายของแพลตฟอร์มนี้ เมื่อได้รับการร้องขอที่เกี่ยวข้องจากนักพัฒนา (จากลูกค้าของเรา) เราจึงเริ่มแก้ไขปัญหาด้วยวิธีแรกที่มีอยู่ ซึ่งไม่ได้พิสูจน์ตัวเองในระยะยาว โชคดีที่สิ่งนี้ชัดเจนไม่เพียงแต่ตอนนี้และไม่เพียงแต่สำหรับเราเท่านั้น ดังนั้นวิธีการที่เหมาะสมกว่าจึงปรากฏแล้วในโลกนี้ และ Telepresence ก็มีชื่อเสียงที่สุดในบรรดาพวกเขา (โดยวิธีการนี้ยังมี
PS
อื่นๆ จากซีรี่ส์เคล็ดลับและเทคนิคของ K8s:
- «
เคล็ดลับและลูกเล่น Kubernetes: หน้าข้อผิดพลาดที่กำหนดเองใน NGINX Ingress "; - «
การถ่ายโอนทรัพยากรที่ทำงานในคลัสเตอร์ไปยังการจัดการ Helm 2 "; - «
เกี่ยวกับการจัดสรรโหนดและโหลดบนเว็บแอปพลิเคชัน "; - «
เข้าถึงไซต์ dev "; - «
การเร่งความเร็วบูตสแตรปสำหรับฐานข้อมูลขนาดใหญ่ '
ที่มา: will.com