Қолданбаны 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 контейнерінде пайда болады. Бірақ бір подводтағы екі контейнер болған жағдайда, 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. Аппараттық құралдар мен ресурстар рұқсат етсе, пайдалануға болады cephfs статикалық қажеттіліктер үшін бірдей қолжетімді каталогты ұйымдастыру. Ресми құжаттама SSD дискілерін, кем дегенде үш еселік репликацияны және кластер түйіндері арасындағы тұрақты «қалың» қосылымды ұсынады.
  2. Неғұрлым талап етілетін опция NFS серверін ұйымдастыру болады. Дегенмен, сіз веб-сервердің сұрауларды өңдеуге жауап беру уақытының ықтимал ұлғаюын ескеруіңіз керек және ақауларға төзімділік көп нәрсені қажет етеді. Сәтсіздіктің салдары апатты: таудың жоғалуы аспанға асқынған LA жүктемесінің қысымымен кластерді өлімге әкеледі.

Басқа нәрселермен қатар, тұрақты жадты құрудың барлық опциялары қажет болады фондық тазалау белгілі бір уақыт аралығында жинақталған ескірген файлдар жиынтығы. РНР бар контейнерлердің алдына қоюға болады DaemonSet шектеулі уақыт ішінде активтердің көшірмелерін сақтайтын nginx кэштеуден. Бұл әрекетті пайдалану арқылы оңай конфигурациялауға болады proxy_cache күнмен немесе гигабайттық дискілік кеңістіктегі сақтау тереңдігімен.

Бұл әдісті жоғарыда аталған таратылған файлдық жүйелермен біріктіру қиялдың үлкен өрісін қамтамасыз етеді, тек оны жүзеге асыратын және қолдайтындардың бюджетімен және техникалық әлеуетімен шектеледі. Тәжірибеге сүйенсек, жүйе неғұрлым қарапайым болса, соғұрлым тұрақты жұмыс істейді деп айта аламыз. Мұндай қабаттарды қосқанда, инфрақұрылымды ұстау әлдеқайда қиын болады, сонымен бірге диагностикаға және кез келген ақауларды қалпына келтіруге кететін уақыт артады.

Ұсыныс

Ұсынылған сақтау нұсқаларын іске асыру сізге негізсіз болып көрінсе (күрделі, қымбат ...), онда жағдайды екінші жағынан қарастырған жөн. Атап айтқанда, жоба архитектурасын қазу және кодтағы мәселені шешіңіз, кескіндегі кейбір статикалық деректер құрылымына байланысты, мазмұнның бір мәнді анықтамасы немесе кескінді құрастыру сатысында «жылыту» және/немесе активтерді алдын ала құрастыру процедурасы. Осылайша, біз барлық орталар мен іске қосылған қолданбаның көшірмелері үшін мүлдем болжамды әрекетті және бірдей файлдар жинағын аламыз.

Егер біз Yii шеңберімен нақты мысалға оралсақ және оның құрылымын зерттемесек (бұл мақаланың мақсаты емес), екі танымал тәсілді атап өту жеткілікті:

  1. Активтерді болжамды орынға орналастыру үшін кескін құру процесін өзгертіңіз. Бұл кеңейтімдер сияқты ұсынылған/енгізілген yii2-статикалық-активтер.
  2. Актив каталогтары үшін арнайы хэштерді анықтаңыз, мысалы: бұл презентация (No35 слайдтан бастап). Айтпақшы, есеп авторы сайып келгенде (және себепсіз емес!) құрастыру серверіне активтерді жинағаннан кейін оларды орталық жадқа (S3 сияқты) жүктеп салуға кеңес береді, оның алдында CDN орналасады.

Жүктеулер

Қолданбаны Kubernetes кластеріне көшіру кезінде міндетті түрде пайда болатын тағы бір жағдай файлдық жүйеде пайдаланушы файлдарын сақтау болып табылады. Мысалы, бізде қайтадан жүктеп салу пішіні арқылы файлдарды қабылдайтын, жұмыс кезінде олармен бірдеңе жасайтын және оларды кері жіберетін PHP қолданбасы бар.

Kubernetes-те бұл файлдарды орналастыру керек орын қолданбаның барлық көшірмелері үшін ортақ болуы керек. Қолданбаның күрделілігіне және осы файлдардың тұрақтылығын ұйымдастыру қажеттілігіне байланысты жоғарыда аталған ортақ құрылғы опциялары осындай орын болуы мүмкін, бірақ біз көріп отырғанымыздай, олардың кемшіліктері бар.

Ұсыныс

Бір шешім S3-үйлесімді жадты пайдалану (тіпті бұл minio сияқты өзін-өзі басқаратын санат болса да). S3 жүйесіне ауысу үшін өзгерістер қажет болады код деңгейінде, және мазмұнның алдыңғы жағында қалай жеткізілетінін біз қазірдің өзінде білдік жазды.

Пайдаланушы сеанстары

Пайдаланушы сеанстарын сақтауды ұйымдастыруды бөлек атап өткен жөн. Көбінесе бұл дискідегі файлдар, олар Кубернетес контекстінде егер оның сұрауы басқа контейнерде аяқталса, пайдаланушының тұрақты авторизация сұрауларына әкеледі.

Мәселе қосу арқылы ішінара шешіледі stickySessions кіруде (мүмкіндікке барлық танымал кіріс контроллерлерінде қолдау көрсетіледі - қосымша мәліметтер алу үшін қараңыз біздің шолу)пайдаланушыны қолданба арқылы белгілі бір подкастқа байланыстыру үшін:

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

пікір қалдыру