Аппликешныг Kubernetes руу шилжүүлэх үед локал файлууд

Аппликешныг Kubernetes руу шилжүүлэх үед локал файлууд

Kubernetes-ийг ашиглан CI/CD процессыг бүтээхдээ заримдаа шинэ дэд бүтцийн шаардлага болон түүнд шилжүүлж буй програмын хооронд үл нийцэх асуудал үүсдэг. Ялангуяа програм бүтээх үе шатанд үүнийг авах нь чухал юм один ашиглах зураг всех төслийн орчин ба кластерууд. Энэ зарчим зөвийн үндэс суурь болдог Google-ийн дагуу савны менежмент (энэ талаар нэгээс олон удаа ярьж байна болон манай техникийн хэлтэс).

Гэсэн хэдий ч, сайтын код нь цаашид ашиглахад хязгаарлалт тавьдаг бэлэн хүрээ ашигладаг тохиолдолд та хэнийг ч харахгүй. "Хэвийн орчинд" үүнийг шийдвэрлэхэд хялбар байдаг ч Кубернетес дэх энэ зан байдал, ялангуяа та анх удаа тулгарсан үед асуудал үүсгэж болно. Зохион бүтээгч оюун ухаан нь анх харахад ойлгомжтой эсвэл бүр сайн мэт санагдах дэд бүтцийн шийдлүүдийг гаргаж чаддаг ч... ихэнх нөхцөл байдал ийм байж болох бөгөөд хийх ёстой гэдгийг санах нь чухал. архитектурын хувьд шийднэ.

Бид кластер ажиллуулахад таагүй үр дагаварт хүргэж болзошгүй файлуудыг хадгалах түгээмэл шийдлүүдэд дүн шинжилгээ хийж, илүү зөв замыг зааж өгөх болно.

Статик хадгалалт

Дүрслэхийн тулд зураг, загвар болон бусад зүйлийг авахын тулд ямар нэгэн статик генератор ашигладаг вэб програмыг авч үзье. Жишээлбэл, Yii PHP фреймворк нь өвөрмөц лавлах нэрийг үүсгэдэг үндсэн хөрөнгийн менежертэй. Үүний дагуу гаралт нь бие биетэйгээ огтлолцохгүй байгаа статик сайтын замуудын багц юм (энэ нь хэд хэдэн шалтгааны улмаас хийгдсэн - жишээлбэл, олон бүрэлдэхүүн хэсэг ижил нөөцийг ашиглах үед давхардлыг арилгахын тулд). Тиймээс, таныг вэб нөөцийн модульд анх удаа нэвтрэх үед статик файлууд (үнэндээ ихэвчлэн симбол холбоосууд байдаг, гэхдээ дараа нь илүү ихийг хэлнэ) энэ байршуулалтад өвөрмөц нийтлэг үндсэн лавлахаар үүсгэгддэг:

  • webroot/assets/2072c2df/css/…
  • webroot/assets/2072c2df/images/…
  • webroot/assets/2072c2df/js/…

Энэ нь кластерын хувьд юу гэсэн үг вэ?

Хамгийн энгийн жишээ

PHP-ийн өмнө статик өгөгдөл түгээх, энгийн хүсэлтийг боловсруулахын тулд nginx бичигдсэн нийтлэг тохиолдлыг авч үзье. Хамгийн хялбар арга - байрлуулалт хоёр савтай:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: site
spec:
  selector:
    matchLabels:
      component: backend
  template:
    metadata:
      labels:
        component: backend
    spec:
      volumes:
        - name: nginx-config
          configMap:
            name: nginx-configmap
      containers:
      - name: php
        image: own-image-with-php-backend:v1.0
        command: ["/usr/local/sbin/php-fpm","-F"]
        workingDir: /var/www
      - name: nginx
        image: nginx:1.16.0
        command: ["/usr/sbin/nginx", "-g", "daemon off;"]
        volumeMounts:
        - name: nginx-config
          mountPath: /etc/nginx/conf.d/default.conf
          subPath: nginx.conf

Хялбаршуулсан хэлбэрээр nginx тохиргоо нь дараах байдалтай байна.

apiVersion: v1
kind: ConfigMap
metadata:
  name: "nginx-configmap"
data:
  nginx.conf: |
    server {
        listen 80;
        server_name _;
        charset utf-8;
        root  /var/www;

        access_log /dev/stdout;
        error_log /dev/stderr;

        location / {
            index index.php;
            try_files $uri $uri/ /index.php?$args;
        }

        location ~ .php$ {
            fastcgi_pass 127.0.0.1:9000;
            fastcgi_index index.php;
            include fastcgi_params;
        }
    }

Таныг анх сайт руу ороход PHP контейнерт хөрөнгө гарч ирнэ. Гэхдээ нэг pod дотор хоёр контейнер байгаа тохиолдолд nginx эдгээр статик файлуудын талаар юу ч мэдэхгүй бөгөөд (тохиргооны дагуу) тэдэнд өгөх ёстой. Үүний үр дүнд үйлчлүүлэгч CSS болон JS файлуудын бүх хүсэлтэд 404 алдааг харах болно. Эндээс хамгийн энгийн шийдэл бол контейнерт зориулсан нийтлэг лавлах зохион байгуулах явдал юм. Анхдагч сонголт - ерөнхий emptyDir:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: site
spec:
  selector:
    matchLabels:
      component: backend
  template:
    metadata:
      labels:
        component: backend
    spec:
      volumes:
        - name: assets
          emptyDir: {}
        - name: nginx-config
          configMap:
            name: nginx-configmap
      containers:
      - name: php
        image: own-image-with-php-backend:v1.0
        command: ["/usr/local/sbin/php-fpm","-F"]
        workingDir: /var/www
        volumeMounts:
        - name: assets
          mountPath: /var/www/assets
      - name: nginx
        image: nginx:1.16.0
        command: ["/usr/sbin/nginx", "-g", "daemon off;"]
        volumeMounts:
        - name: assets
          mountPath: /var/www/assets
        - name: nginx-config
          mountPath: /etc/nginx/conf.d/default.conf
          subPath: nginx.conf

Одоо саванд үүсгэгдсэн статик файлууд нь nginx-ээр зөв үйлчилдэг. Гэхдээ энэ бол анхдагч шийдэл гэдгийг сануулъя, энэ нь хамгийн тохиромжтой зүйлээс хол, доор авч үзэх өөрийн гэсэн нюанс, дутагдалтай гэсэн үг юм.

Илүү дэвшилтэт хадгалах сан

Хэрэглэгч тухайн сайтад зочилж, контейнерт байгаа хэв маягтай хуудсыг ачаалж, энэ хуудсыг уншиж байх үед бид контейнерийг дахин байршуулсан нөхцөл байдлыг төсөөлөөд үз дээ. Хөрөнгийн каталог хоосон болсон тул шинээр үүсгэж эхлэхийн тулд PHP-д хүсэлт гаргах шаардлагатай байна. Гэсэн хэдий ч үүний дараа ч гэсэн хуучин статикийн холбоосууд нь хамааралгүй байх бөгөөд энэ нь статикийг харуулахад алдаа гаргахад хүргэдэг.

Нэмж дурдахад, бидэнд илүү их эсвэл бага ачаалалтай төсөл байгаа бөгөөд энэ нь програмын нэг хуулбар хангалтгүй гэсэн үг юм.

  • Үүнийг томруулж үзье байрлуулалт хоёр хүртэлх хуулбар.
  • Сайт руу анх нэвтрэх үед хөрөнгийг нэг хуулбараар үүсгэсэн.
  • Хэзээ нэгэн цагт (ачаалал тэнцвэржүүлэх зорилгоор) нэвтрэх хүсэлтийг хоёр дахь хуулбар руу илгээхээр шийдсэн бөгөөд эдгээр хөрөнгө хараахан байхгүй байсан. Эсвэл бид ашигладаг учраас тэд байхгүй болсон байж магадгүй юм RollingUpdate бөгөөд одоогоор бид байршуулалт хийж байна.

Ерөнхийдөө үр дүн нь дахин алдаа юм.

Хуучин хөрөнгөө алдахгүйн тулд та өөрчилж болно emptyDir тухай hostPath, кластерийн зангилаанд статикийг физик байдлаар нэмэх. Энэ арга нь муу, учир нь бид үүнийг хийх ёстой тодорхой кластерийн зангилаатай холбох Таны програм, учир нь - бусад зангилаа руу шилжих тохиолдолд лавлахад шаардлагатай файлууд байхгүй болно. Эсвэл зангилааны хооронд ямар нэгэн суурь лавлах синхрончлол шаардлагатай.

Ямар шийдлүүд байна вэ?

  1. Хэрэв техник хангамж, нөөц боломж зөвшөөрвөл та ашиглаж болно cepfs статик хэрэгцээнд адилхан хүртээмжтэй лавлах зохион байгуулах. Албан ёсны баримт бичиг нь SSD хөтчүүд, дор хаяж XNUMX дахин хуулбарлах, кластерийн зангилааны хооронд тогтвортой "зузаан" холболт хийхийг зөвлөж байна.
  2. Шаардлага багатай сонголт бол NFS серверийг зохион байгуулах явдал юм. Гэсэн хэдий ч, дараа нь вэб серверийн хүсэлтийг боловсруулахад хариу өгөх хугацаа нэмэгдэж болзошгүйг анхаарч үзэх хэрэгтэй бөгөөд алдааг тэсвэрлэх чадвар нь хүссэн зүйлээ орхих болно. Бүтэлгүйтлийн үр дагавар нь гамшгийн үр дагавар юм: уулын алдагдал нь тэнгэрт гүйж буй LA ачааллын даралтын дор кластерийг үхэлд хүргэдэг.

Бусад зүйлсийн дотор байнгын хадгалалт үүсгэх бүх сонголтууд шаардлагатай болно дэвсгэр цэвэрлэх тодорхой хугацаанд хуримтлагдсан хуучирсан файлуудын багц. PHP-тэй савны өмнө та тавьж болно DaemonSet Хязгаарлагдмал хугацаанд хөрөнгийн хуулбарыг хадгалах nginx-ийг кэшлэхээс. Энэ зан үйлийг ашиглан тохируулахад хялбар байдаг proxy_cache хадгалах гүн нь хоногоор буюу гигабайт дискний зайтай.

Энэ аргыг дээр дурдсан тархсан файлын системтэй хослуулах нь зөвхөн хэрэгжүүлэх, дэмжих хүмүүсийн төсөв, техникийн боломжоор хязгаарлагдах төсөөллийн асар том талбарыг бий болгодог. Туршлагаас харахад систем нь энгийн байх тусмаа илүү тогтвортой ажилладаг гэж хэлж болно. Ийм давхаргыг нэмэхэд дэд бүтцийг арчлахад илүү хэцүү болж, үүнтэй зэрэгцэн аливаа эвдрэлийг оношлох, сэргээхэд зарцуулагдах хугацаа нэмэгддэг.

Зөвлөмж

Санал болгож буй хадгалах хувилбаруудыг хэрэгжүүлэх нь танд үндэслэлгүй мэт санагдаж байвал (төвөгтэй, үнэтэй ...) нөхцөл байдлыг нөгөө талаас нь харах нь зүйтэй. Тухайлбал, төслийн архитектур болон Код дээрх асуудлыг засах, зураг дээрх зарим статик өгөгдлийн бүтэцтэй холбоотой, дүрсийг угсрах үе шатанд "дулаацах" ба/эсвэл хөрөнгийг урьдчилан эмхэтгэх агуулгын эсвэл процедурын хоёрдмол утгагүй тодорхойлолт. Ингэснээр бид бүх орчин болон ажиллаж байгаа програмын хуулбарт зориулсан бүрэн урьдчилан таамаглахуйц зан байдал, ижил файлуудын багцыг авах болно.

Хэрэв бид Yii хүрээтэй тодорхой жишээ рүү буцаж очоод түүний бүтцийг судлахгүй бол (энэ нь нийтлэлийн зорилго биш) хоёр түгээмэл хандлагыг тэмдэглэхэд хангалттай.

  1. Хөрөнгийг урьдчилан таамаглах боломжтой газар байрлуулахын тулд зураг бүтээх процессыг өөрчил. гэх мэт өргөтгөлүүдэд үүнийг санал болгосон/хэрэгжүүлсэн yii2-статик-хөрөнгө.
  2. Хөрөнгийн лавлахуудад зориулсан тусгай хэшийг тодорхойлох, жишээ нь. энэ танилцуулга (35-р слайдаас эхлэн). Дашрамд хэлэхэд, тайлангийн зохиогч эцсийн эцэст (шалтгаангүй биш!) хөрөнгийг бүтээх сервер дээр угсарсны дараа тэдгээрийг төвлөрсөн хадгалах сан руу (S3 гэх мэт) байршуулахыг зөвлөж байна.

Татаж авсан зүйлс

Аппликешныг Kubernetes кластер руу шилжүүлэх үед гарч ирэх өөр нэг тохиолдол бол хэрэглэгчийн файлуудыг файлын системд хадгалах явдал юм. Жишээлбэл, бид дахин файлуудыг байршуулах маягтаар хүлээн авч, ажиллах явцад тэдэнтэй ямар нэг зүйл хийж, буцааж илгээдэг PHP програмтай болсон.

Kubernetes-д эдгээр файлуудыг байрлуулах байршил нь програмын бүх хуулбарт нийтлэг байх ёстой. Хэрэглээний нарийн төвөгтэй байдал, эдгээр файлуудын тогтвортой байдлыг зохион байгуулах хэрэгцээ шаардлагаас хамааран дээр дурдсан хуваалцсан төхөөрөмжийн сонголтууд нь ийм газар байж болох ч бидний харж байгаагаар тэдгээр нь сул талуудтай байдаг.

Зөвлөмж

Нэг шийдэл S3-тэй нийцтэй хадгалах санг ашиглах (хэдийгээр энэ нь minio гэх мэт өөрөө зохион байгуулдаг ангилал байсан ч). S3 руу шилжихэд өөрчлөлт оруулах шаардлагатай кодын түвшинд, мөн контентыг нүүрэн талдаа хэрхэн хүргэх талаар бид аль хэдийн мэдсэн бичсэн.

Хэрэглэгчийн сессүүд

Хэрэглэгчийн сессийг хадгалах зохион байгуулалтыг тусад нь тэмдэглэх нь зүйтэй. Ихэнхдээ эдгээр нь дискэн дээрх файлууд бөгөөд Kubernetes-ийн хүрээнд хэрэглэгчийн хүсэлт өөр саванд дуусвал хэрэглэгчийн байнгын зөвшөөрлийн хүсэлтэд хүргэдэг.

Асуудлыг асаах замаар хэсэгчлэн шийддэг stickySessions нэвтрэх дээр (энэ функцийг бүх алдартай оролт хянагчдад дэмждэг - дэлгэрэнгүй мэдээллийг үзнэ үү бидний тойм)Хэрэглэгчийг програмын тусламжтайгаар тодорхой pod руу холбохын тулд:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: nginx-test
  annotations:
    nginx.ingress.kubernetes.io/affinity: "cookie"
    nginx.ingress.kubernetes.io/session-cookie-name: "route"
    nginx.ingress.kubernetes.io/session-cookie-expires: "172800"
    nginx.ingress.kubernetes.io/session-cookie-max-age: "172800"

spec:
  rules:
  - host: stickyingress.example.com
    http:
      paths:
      - backend:
          serviceName: http-svc
          servicePort: 80
        path: /

Гэхдээ энэ нь дахин дахин байршуулахтай холбоотой асуудлыг арилгахгүй.

Зөвлөмж

Илүү зөв арга бол програмыг шилжүүлэх явдал юм сессүүдийг memcached, Redis болон үүнтэй төстэй шийдлүүдэд хадгалах - ерөнхийдөө файлын сонголтоос бүрэн татгалз.

дүгнэлт

Текстэд хэлэлцсэн дэд бүтцийн шийдлүүдийг зөвхөн түр зуурын "таяг" хэлбэрээр ашиглах нь зүйтэй (энэ нь англи хэл дээр түр зуурын шийдэл гэж илүү сайхан сонсогддог). Эдгээр нь програмыг Kubernetes руу шилжүүлэх эхний үе шатанд хамааралтай байж болох ч үндэслэх ёсгүй.

Санал болгож буй ерөнхий зам бол олон хүнд аль хэдийн сайн мэддэг зүйлийн дагуу програмын архитектурын өөрчлөлтийг ашиглахын тулд тэдгээрийг арилгах явдал юм. 12 хүчин зүйлийн програм. Гэсэн хэдий ч энэ нь - өргөдлийг харьяалалгүй хэлбэрт оруулах нь кодыг өөрчлөх шаардлагатай гэсэн үг бөгөөд энд бизнесийн чадвар/шаардлага, сонгосон замыг хэрэгжүүлэх, хадгалах хэтийн төлөв хоорондын тэнцвэрийг олох нь чухал юм. .

PS

Мөн манай блог дээрээс уншина уу:

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх