เคล็ดลับและคำแนะนำของ Kubernetes: เกี่ยวกับการพัฒนาท้องถิ่นและการนำเสนอทางไกล

เคล็ดลับและคำแนะนำของ Kubernetes: เกี่ยวกับการพัฒนาท้องถิ่นและการนำเสนอทางไกล

เราถูกถามมากขึ้นเกี่ยวกับการพัฒนาไมโครเซอร์วิสใน Kubernetes นักพัฒนา โดยเฉพาะภาษาที่แปล ต้องการแก้ไขโค้ดอย่างรวดเร็วใน IDE ที่พวกเขาชื่นชอบ และดูผลลัพธ์โดยไม่ต้องรอการสร้าง/ปรับใช้ เพียงแค่กด F5 และเมื่อพูดถึงแอปพลิเคชันขนาดใหญ่ การติดตั้งฐานข้อมูลและเว็บเซิร์ฟเวอร์ภายในเครื่อง (ใน Docker, VirtualBox...) ก็เพียงพอแล้ว จากนั้นจึงเพลิดเพลินกับการพัฒนาได้ทันที ด้วยการตัดเสาหินออกเป็นไมโครเซอร์วิสและการมาถึงของ Kubernetes โดยมีลักษณะของการพึ่งพาซึ่งกันและกัน ทุกสิ่งทุกอย่าง มันยากขึ้นนิดหน่อย. ยิ่งไมโครเซอร์วิสเหล่านี้มากเท่าไร ปัญหาก็จะยิ่งมากขึ้นเท่านั้น หากต้องการเพลิดเพลินกับการพัฒนาอีกครั้ง คุณต้องยกคอนเทนเนอร์ Docker มากกว่าหนึ่งหรือสองตัว และบางครั้งก็อาจมากกว่าหนึ่งโหล... โดยทั่วไปแล้ว ทั้งหมดนี้อาจใช้เวลาค่อนข้างมากเนื่องจากจำเป็นต้องได้รับการอัปเดตให้ทันสมัยอยู่เสมอ .

ในเวลาที่ต่างกัน เราได้ลองวิธีแก้ไขปัญหาที่แตกต่างกัน และฉันจะเริ่มต้นด้วยวิธีแก้ปัญหาที่สั่งสมมาหรือเพียงแค่ "ไม้ค้ำยัน"

1. ไม้ค้ำยัน

IDE ส่วนใหญ่มีความสามารถในการแก้ไขโค้ดได้โดยตรงบนเซิร์ฟเวอร์โดยใช้ FTP/SFTP เส้นทางนี้ชัดเจนมากและเราตัดสินใจใช้มันทันที สาระสำคัญของมันเดือดลงไปดังต่อไปนี้:

  1. ในพ็อดของสภาพแวดล้อมการพัฒนา (dev/review) จะมีการเปิดตัวคอนเทนเนอร์เพิ่มเติมพร้อมการเข้าถึง SSH และส่งต่อคีย์ SSH สาธารณะของนักพัฒนาที่จะกระทำ/ปรับใช้แอปพลิเคชัน
  2. ในระยะเริ่มต้น (ภายในคอนเทนเนอร์ prepare-app) โอนรหัสไปที่ emptyDirเพื่อเข้าถึงโค้ดจากคอนเทนเนอร์แอปพลิเคชันและเซิร์ฟเวอร์ SSH

เคล็ดลับและคำแนะนำของ Kubernetes: เกี่ยวกับการพัฒนาท้องถิ่นและการนำเสนอทางไกล

เพื่อให้เข้าใจการใช้งานทางเทคนิคของโครงร่างดังกล่าวได้ดีขึ้น ฉันจะจัดเตรียมส่วนย่อยของการกำหนดค่า 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 }}

สัมผัสสุดท้าย

หลังจากนั้นสิ่งที่เหลืออยู่คือการโอน ตัวแปร 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: นักพัฒนาที่เปิดตัวการปรับใช้สามารถเชื่อมต่อด้วยชื่อบริการ (วิธีให้สิทธิ์การเข้าถึงคลัสเตอร์อย่างปลอดภัย เราบอกไปแล้ว) จากเดสก์ท็อปของคุณผ่าน SFTP และแก้ไขโค้ดโดยไม่ต้องรอให้ส่งไปยังคลัสเตอร์

นี่เป็นวิธีแก้ปัญหาที่ทำงานได้อย่างสมบูรณ์ แต่จากมุมมองของการนำไปปฏิบัติก็มีข้อเสียที่ชัดเจน:

  • ความจำเป็นในการปรับแต่งแผนภูมิ Helm ซึ่งทำให้อ่านยากในอนาคต
  • สามารถใช้งานได้โดยบุคคลที่ใช้บริการเท่านั้น
  • คุณต้องจำไว้ว่าต้องซิงโครไนซ์มันกับไดเร็กทอรีในเครื่องด้วยโค้ดและคอมมิตมันกับ Git

2. การนำเสนอทางไกล

โครงการ ทางไกล เป็นที่รู้จักกันมานานแล้ว แต่อย่างที่พวกเขากล่าวว่า "ไม่ได้พยายามอย่างจริงจังในทางปฏิบัติ" อย่างไรก็ตาม ความต้องการได้ทำหน้าที่ของมันแล้ว และตอนนี้เรายินดีที่จะแบ่งปันประสบการณ์ของเรา ซึ่งอาจเป็นประโยชน์สำหรับผู้อ่านบล็อกของเรา โดยเฉพาะอย่างยิ่งเมื่อยังไม่มีเอกสารอื่นใดเกี่ยวกับ Telepresence บนฮับ

สรุปแล้วทุกอย่างกลับกลายเป็นว่าไม่น่ากลัวนัก เราได้วางการกระทำทั้งหมดที่ต้องมีการดำเนินการในส่วนของนักพัฒนาไว้ในไฟล์ข้อความแผนภูมิ 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 ก็มีชื่อเสียงที่สุดในบรรดาพวกเขา (โดยวิธีการนี้ยังมี นั่งร้าน จาก Google) ประสบการณ์การใช้งานของเรายังไม่ดีนัก แต่ก็ทำให้เรามีเหตุผลที่จะแนะนำให้ "เพื่อนร่วมงานในร้าน" ของเรา - ลองเลย!

PS

อื่นๆ จากซีรี่ส์เคล็ดลับและเทคนิคของ K8s:

ที่มา: will.com

เพิ่มความคิดเห็น