Faili za ndani wakati wa kuhamisha programu hadi Kubernetes

Faili za ndani wakati wa kuhamisha programu hadi Kubernetes

Wakati wa kujenga mchakato wa CI / CD kwa kutumia Kubernetes, wakati mwingine tatizo linatokea la kutokubaliana kati ya mahitaji ya miundombinu mpya na maombi kuhamishiwa kwake. Hasa, katika hatua ya kujenga maombi ni muhimu kupata moja picha ambayo itatumika katika Kila mazingira ya mradi na makundi. Kanuni hii ni msingi sahihi kulingana na Google usimamizi wa chombo (zaidi ya mara moja kuhusu hili alizungumza na idara yetu ya kiufundi).

Hata hivyo, hutaona mtu yeyote katika hali ambapo msimbo wa tovuti hutumia mfumo uliofanywa tayari, matumizi ambayo huweka vikwazo kwa matumizi yake zaidi. Na wakati katika "mazingira ya kawaida" hii ni rahisi kukabiliana nayo, katika Kubernetes tabia hii inaweza kuwa tatizo, hasa unapokutana nayo kwa mara ya kwanza. Ingawa akili ya uvumbuzi inaweza kuja na suluhisho za miundombinu ambazo zinaonekana wazi au hata nzuri kwa mtazamo wa kwanza ... ni muhimu kukumbuka kuwa hali nyingi zinaweza na lazima. kutatuliwa kwa usanifu.

Wacha tuangalie suluhisho maarufu za kuhifadhi faili ambazo zinaweza kusababisha athari mbaya wakati wa kufanya kazi na nguzo, na pia onyesha njia sahihi zaidi.

Hifadhi tuli

Kwa mfano, fikiria programu ya wavuti inayotumia aina fulani ya jenereta tuli kupata seti ya picha, mitindo na vitu vingine. Kwa mfano, mfumo wa Yii PHP una kidhibiti cha kipengee kilichojengwa ndani ambacho hutoa majina ya saraka ya kipekee. Ipasavyo, matokeo ni seti ya njia za tovuti tuli ambayo ni wazi haiingiliani na kila mmoja (hii ilifanyika kwa sababu kadhaa - kwa mfano, kuondoa nakala wakati vifaa vingi vinatumia rasilimali sawa). Kwa hivyo, nje ya kisanduku, mara ya kwanza unapofikia moduli ya rasilimali ya wavuti, faili tuli (kwa kweli, mara nyingi hulinganishwa, lakini zaidi juu ya hiyo baadaye) huundwa na kuwekwa na saraka ya mizizi ya kawaida ya kipekee kwa upelekaji huu:

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

Hii ina maana gani katika suala la nguzo?

Mfano rahisi zaidi

Wacha tuchukue kesi ya kawaida, wakati PHP inatanguliwa na nginx kusambaza data tuli na kushughulikia maombi rahisi. Njia rahisi zaidi - Kuhamishwa na vyombo viwili:

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

Katika fomu iliyorahisishwa, usanidi wa nginx hupungua hadi yafuatayo:

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;
        }
    }

Unapofikia tovuti kwa mara ya kwanza, mali huonekana kwenye kontena la PHP. Lakini katika kesi ya vyombo viwili ndani ya pod moja, nginx haijui chochote kuhusu faili hizi za tuli, ambazo (kulingana na usanidi) zinapaswa kutolewa kwao. Kwa hivyo, mteja ataona hitilafu ya 404 kwa maombi yote kwa faili za CSS na JS. Suluhisho rahisi zaidi hapa litakuwa kupanga saraka ya kawaida ya vyombo. Chaguo la kwanza - la jumla 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

Sasa faili tuli zinazozalishwa kwenye chombo zinahudumiwa na nginx kwa usahihi. Lakini napenda kukukumbusha kwamba hii ni suluhisho la primitive, ambayo ina maana ni mbali na bora na ina nuances yake mwenyewe na mapungufu, ambayo yanajadiliwa hapa chini.

Hifadhi ya hali ya juu zaidi

Sasa fikiria hali ambapo mtumiaji alitembelea tovuti, akapakia ukurasa na mitindo iliyopo kwenye chombo, na alipokuwa akisoma ukurasa huu, tuliweka tena chombo. Katalogi ya mali imekuwa tupu na ombi kwa PHP linahitajika ili kuanza kutoa mpya. Hata hivyo, hata baada ya hili, viungo vya statics vya zamani vitakuwa visivyofaa, ambayo itasababisha makosa katika kuonyesha statics.

Kwa kuongezea, tuna uwezekano mkubwa wa kuwa na mradi uliopakiwa zaidi au chini, ambayo inamaanisha kuwa nakala moja ya programu haitatosha:

  • Hebu tuiongeze Kuhamishwa hadi nakala mbili.
  • Wakati tovuti ilifikiwa kwa mara ya kwanza, vipengee viliundwa katika nakala moja.
  • Wakati fulani, ingress iliamua (kwa madhumuni ya kusawazisha mzigo) kutuma ombi kwa nakala ya pili, na mali hizi hazikuwepo bado. Au labda hawapo tena kwa sababu tunatumia RollingUpdate na kwa sasa tunafanya deployment.

Kwa ujumla, matokeo ni makosa tena.

Ili kuepuka kupoteza mali ya zamani, unaweza kubadilisha emptyDir juu ya hostPath, ikiongeza tuli kimwili kwa nodi ya nguzo. Njia hii ni mbaya kwa sababu kwa kweli lazima funga kwa nodi maalum ya nguzo maombi yako, kwa sababu - katika kesi ya kuhamia nodes nyingine - saraka haitakuwa na faili muhimu. Au aina fulani ya maingiliano ya saraka ya mandharinyuma kati ya nodi inahitajika.

Masuluhisho ni yapi?

  1. Ikiwa vifaa na rasilimali zinaruhusu, unaweza kutumia cephfs kupanga saraka inayoweza kufikiwa kwa usawa kwa mahitaji tuli. Nyaraka rasmi inapendekeza viendeshi vya SSD, angalau kurudia mara tatu na muunganisho thabiti wa "nene" kati ya nodi za nguzo.
  2. Chaguo lisilohitaji sana litakuwa kupanga seva ya NFS. Walakini, basi unahitaji kuzingatia ongezeko linalowezekana la wakati wa kujibu kwa maombi ya usindikaji na seva ya wavuti, na uvumilivu wa makosa utaacha kuhitajika. Matokeo ya kutofaulu ni janga: upotezaji wa mlima huharibu nguzo hadi kifo chini ya shinikizo la mzigo LA unaokimbilia angani.

Miongoni mwa mambo mengine, chaguzi zote za kuunda hifadhi ya kudumu zitahitaji kusafisha background seti zilizopitwa na wakati za faili zilizokusanywa kwa muda fulani. Mbele ya vyombo na PHP unaweza kuweka DaemonSet kutoka kwa caching nginx, ambayo itahifadhi nakala za mali kwa muda mfupi. Tabia hii inaweza kusanidiwa kwa urahisi kwa kutumia proxy_cache na kina cha kuhifadhi kwa siku au gigabytes ya nafasi ya diski.

Kuchanganya njia hii na mifumo ya faili iliyosambazwa iliyotajwa hapo juu hutoa uwanja mkubwa wa mawazo, mdogo tu na bajeti na uwezo wa kiufundi wa wale ambao watatekeleza na kuunga mkono. Kutokana na uzoefu, tunaweza kusema kwamba mfumo rahisi, ni imara zaidi hufanya kazi. Wakati tabaka hizo zinaongezwa, inakuwa vigumu zaidi kudumisha miundombinu, na wakati huo huo wakati unaotumiwa katika kuchunguza na kurejesha kutokana na kushindwa yoyote huongezeka.

Mapendekezo

Ikiwa utekelezaji wa chaguzi zilizopendekezwa za uhifadhi pia unaonekana kuwa hauna haki kwako (ngumu, ghali ...), basi ni thamani ya kuangalia hali hiyo kutoka upande mwingine. Yaani, kuchimba katika usanifu wa mradi na kurekebisha tatizo katika kanuni, inayohusishwa na muundo fulani wa data tuli kwenye picha, ufafanuzi usio na utata wa yaliyomo au utaratibu wa "kupasha joto" na/au vipengee vilivyojumuishwa awali katika hatua ya kuunganisha picha. Kwa njia hii tunapata tabia inayotabirika kabisa na seti sawa ya faili kwa mazingira yote na nakala za programu inayoendesha.

Ikiwa tunarudi kwenye mfano maalum na mfumo wa Yii na hatuzingatii muundo wake (ambayo sio madhumuni ya kifungu), inatosha kutaja njia mbili maarufu:

  1. Badilisha mchakato wa kuunda picha ili kuweka mali katika eneo linaloweza kutabirika. Hii inapendekezwa/kutekelezwa katika viendelezi kama yii2-tuli-mali.
  2. Bainisha heshi maalum za saraka za mali, kama ilivyojadiliwa katika k.m. uwasilishaji huu (kuanzia slaidi Na. 35). Kwa njia, mwandishi wa ripoti hatimaye (na si bila sababu!) Anashauri kwamba baada ya kukusanya mali kwenye seva ya kujenga, pakia kwenye hifadhi ya kati (kama S3), mbele ya mahali ambapo CDN.

Faili zinazoweza kupakuliwa

Kesi nyingine ambayo hakika itatumika wakati wa kuhamishia programu kwenye nguzo ya Kubernetes ni kuhifadhi faili za watumiaji kwenye mfumo wa faili. Kwa mfano, tuna tena programu ya PHP ambayo inakubali faili kupitia fomu ya kupakia, hufanya kitu nazo wakati wa operesheni, na kuzituma tena.

Katika Kubernetes, mahali ambapo faili hizi zinapaswa kuwekwa panapaswa kuwa sawa kwa nakala zote za programu. Kulingana na ugumu wa programu na hitaji la kupanga uendelevu wa faili hizi, chaguzi za kifaa zilizoshirikiwa zilizotajwa hapo juu zinaweza kuwa mahali kama hiyo, lakini, kama tunavyoona, zina shida zao.

Mapendekezo

Suluhisho moja ni kwa kutumia hifadhi inayoendana na S3 (hata kama ni aina fulani ya kategoria inayojiendesha kama minio). Kubadilisha hadi S3 kutahitaji mabadiliko katika kiwango cha kanuni, na jinsi yaliyomo yatawasilishwa kwenye sehemu ya mbele, tayari tunayo писали.

Vipindi vya watumiaji

Kwa kando, inafaa kuzingatia shirika la uhifadhi wa vikao vya watumiaji. Mara nyingi hizi pia ni faili kwenye diski, ambayo katika muktadha wa Kubernetes itasababisha maombi ya idhini ya mara kwa mara kutoka kwa mtumiaji ikiwa ombi lake linaisha kwenye chombo kingine.

Tatizo linatatuliwa kwa sehemu kwa kuwasha stickySessions kwenye ingress (kipengele hiki kinasaidiwa katika vidhibiti vyote vya ingress - kwa maelezo zaidi, ona ukaguzi wetu)kumfunga mtumiaji kwa ganda maalum na programu:

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: /

Lakini hii haitaondoa matatizo na kupelekwa mara kwa mara.

Mapendekezo

Njia sahihi zaidi itakuwa kuhamisha programu hadi kuhifadhi vikao katika memcached, Redis na ufumbuzi sawa - kwa ujumla, acha kabisa chaguzi za faili.

Hitimisho

Suluhisho za miundombinu zilizojadiliwa katika maandishi zinastahili kutumika tu katika muundo wa "magongo" ya muda (ambayo yanasikika nzuri zaidi kwa Kiingereza kama njia ya kufanya kazi). Zinaweza kuwa muhimu katika hatua za kwanza za kuhamisha programu hadi Kubernetes, lakini hazipaswi kukita mizizi.

Njia iliyopendekezwa ya jumla ni kuwaondoa kwa niaba ya urekebishaji wa usanifu wa programu kulingana na kile ambacho tayari kinajulikana kwa wengi. Programu ya 12-Factor. Hata hivyo, hii - kuleta maombi kwa fomu isiyo na uraia - bila shaka ina maana kwamba mabadiliko katika kanuni yatahitajika, na hapa ni muhimu kupata usawa kati ya uwezo / mahitaji ya biashara na matarajio ya kutekeleza na kudumisha njia iliyochaguliwa. .

PS

Soma pia kwenye blogi yetu:

Chanzo: mapenzi.com

Kuongeza maoni