OpenShift-də Müasir Tətbiqlər, 3-cü Hissə: İnkişaf Mühiti və OpenShift Boru Kəmərləri kimi OpenShift

Bu blogdakı hər kəsə salam! Bu, Red Hat OpenShift-də müasir veb proqramları necə yerləşdirməyi sizə göstərdiyimiz seriyanın üçüncü yazısıdır.

OpenShift-də Müasir Tətbiqlər, 3-cü Hissə: İnkişaf Mühiti və OpenShift Boru Kəmərləri kimi OpenShift

Əvvəlki iki yazıda biz müasir veb proqramları bir neçə addımda necə yerləşdirməyi və istehsalın yerləşdirilməsi üçün zəncirlənmiş quruluşlardan istifadə edərək NGINX kimi əvvəlcədən qurulmuş HTTP server təsviri ilə birlikdə yeni S2I təsvirindən necə istifadə etməyi əhatə etdik.

Bu gün biz OpenShift platformasında tətbiqiniz üçün inkişaf serverini necə işlətəcəyinizi və onu yerli fayl sistemi ilə necə sinxronlaşdıracağınızı göstərəcəyik, həmçinin OpenShift Boru Kəmərlərinin nə olduğu və onların əlaqəli montajlara alternativ olaraq necə istifadə oluna biləcəyi haqqında danışacağıq.

OpenShift bir inkişaf mühiti kimi

inkişaf iş axını

Artıq qeyd edildiyi kimi ilk yazı, müasir veb proqramlar üçün tipik inkişaf prosesi sadəcə olaraq yerli fayllardakı dəyişiklikləri izləyən "inkişaf serveridir". Onlar baş verdikdə, proqramın qurulması işə salınır və sonra o, brauzerə yenilənir.

Əksər müasir çərçivələrdə belə bir "inkişaf serveri" müvafiq əmr xətti alətlərinə quraşdırılmışdır.

Yerli nümunə

Əvvəlcə yerli proqramların işlədilməsi vəziyyətində bunun necə işlədiyini görək. Nümunə olaraq bir tətbiqi götürək. Reaksiya əvvəlki məqalələrdən, baxmayaraq ki, demək olar ki, eyni iş axını anlayışları bütün digər müasir çərçivələrə aiddir.
Beləliklə, React nümunəmizdə "inkişaf serverini" işə salmaq üçün aşağıdakı əmri yazacağıq:

$ npm run start

Sonra terminal pəncərəsində belə bir şey görəcəyik:

OpenShift-də Müasir Tətbiqlər, 3-cü Hissə: İnkişaf Mühiti və OpenShift Boru Kəmərləri kimi OpenShift

Və tətbiqimiz standart brauzerdə açılacaq:

OpenShift-də Müasir Tətbiqlər, 3-cü Hissə: İnkişaf Mühiti və OpenShift Boru Kəmərləri kimi OpenShift

İndi faylda dəyişiklik etsək, proqram brauzerdə yenilənməlidir.

Tamam, yerli rejimdə inkişafla hər şey aydındır, amma OpenShift-də eyni şeyə necə nail olmaq olar?

OpenShift-də inkişaf serveri

Əgər xatırlayırsınızsa əvvəlki yazı, biz S2I təsvirinin sözdə işləmə mərhələsini (çalışdırma mərhələsi) təhlil etdik və gördük ki, standart olaraq veb tətbiqimiz xidmət modulu tərəfindən xidmət göstərir.

Ancaq daha yaxından baxsanız skripti işlədin həmin misaldan sonra o, öz əmrinizi icra etməyə imkan verən $NPM_RUN mühit dəyişəninə malikdir.

Məsələn, tətbiqimizi yerləşdirmək üçün nodeshift modulundan istifadə edə bilərik:

$ npx nodeshift --deploy.env NPM_RUN="yarn start" --dockerImage=nodeshift/ubi8-s2i-web-app

Qeyd: Yuxarıdakı nümunə ümumi fikri göstərmək üçün qısaldılmışdır.

Burada biz NPM_RUN mühit dəyişənini yerləşdirməmizə əlavə etdik, bu, OpenShift podumuzun içərisində React inkişaf serverini işə salan iplik işə salma əmrini işə salmaq üçün icra müddətini bildirir.

Çalışan bir podun jurnalına baxsanız, belə bir şey olacaq:

OpenShift-də Müasir Tətbiqlər, 3-cü Hissə: İnkişaf Mühiti və OpenShift Boru Kəmərləri kimi OpenShift

Təbii ki, bütün bunlar yerli kodu kodla sinxronizasiya edə bilməyincə heç bir şey olmayacaq, bu da dəyişikliklər üçün idarə olunur, lakin uzaq serverdə yaşayır.

Uzaqdan və yerli kodun sinxronizasiyası

Xoşbəxtlikdən, nodeshift asanlıqla sinxronizasiyaya kömək edə bilər və dəyişiklikləri izləmək üçün watch əmrindən istifadə edə bilərsiniz.

Tətbiqimiz üçün inkişaf serverini yerləşdirmək əmrini yerinə yetirdikdən sonra bu əmrdən təhlükəsiz istifadə edə bilərik:

$ npx nodeshift watch

Nəticədə, bir az əvvəl yaratdığımız işləyən pod ilə əlaqə qurulacaq, yerli fayllarımızın uzaq klasterlə sinxronizasiyası aktivləşdiriləcək və yerli sistemimizdəki fayllar dəyişikliklərə görə izlənilməyə başlayacaq.

Buna görə də, əgər indi src/App.js faylını yeniləsək, sistem bu dəyişikliklərə reaksiya verəcək, onları uzaq klasterə köçürəcək və inkişaf serverini işə salacaq, bu da brauzerdə tətbiqimizi yeniləyəcək.

Şəkli tamamlamaq üçün gəlin bu əmrlərin bütövlükdə necə göründüyünü göstərək:

$ npx nodeshift --strictSSL=false --dockerImage=nodeshift/ubi8-s2i-web-app --build.env YARN_ENABLED=true --expose --deploy.env NPM_RUN="yarn start" --deploy.port 3000

$ npx nodeshift watch --strictSSL=false

Saat əmri oc rsync əmrinin üstündəki abstraksiyadır, bunun necə işlədiyi haqqında daha çox öyrənə bilərsiniz burada.

Bu, React üçün bir nümunə idi, lakin eyni üsul digər çərçivələrlə də istifadə oluna bilər, sadəcə NPM_RUN mühit dəyişənini lazım olduqda təyin edin.

Openshift boru kəmərləri

OpenShift-də Müasir Tətbiqlər, 3-cü Hissə: İnkişaf Mühiti və OpenShift Boru Kəmərləri kimi OpenShift

Sonra, OpenShift Pipelines kimi bir alət və onun zəncirlənmiş quruluşlara alternativ olaraq necə istifadə oluna biləcəyi haqqında danışacağıq.

OpenShift Pipelines nədir

OpenShift Pipelines, Tekton istifadə edən boru kəmərləri üçün bulud əsaslı CI/CD davamlı inteqrasiya və çatdırılma sistemidir. Tekton açıq mənbəli, çevik Kubernetes yerli CI/CD çərçivəsidir və əsas təbəqədən mücərrədləşmə yolu ilə çoxsaylı platformalarda (Kubernetes, serversiz, virtual maşınlar və s.) yerləşdirməni avtomatlaşdırır.

Bu məqaləni başa düşmək Boru Kəmərləri haqqında müəyyən bilik tələb edir, ona görə də əvvəlcə oxumağınızı məsləhət görürük rəsmi dərslik.

İş mühitinin qurulması

Bu məqalədəki nümunələrlə oynamaq üçün əvvəlcə iş mühiti qurmalısınız:

  1. OpenShift 4 klasterini quraşdırın və konfiqurasiya edin.Nümunələrimiz bunun üçün CodeReady Konteynerlərindən (CRD) istifadə edir, quraşdırma təlimatları burada tapıla bilər. burada.
  2. Klaster hazır olduqdan sonra onun üzərinə Boru Kəməri Operatorunu quraşdırmalısınız. Qorxma, bu asandır, quraşdırma təlimatları burada.
  3. Download Tekton CLI (tkn) burada.
  4. Daha sonra yerləşdiriləcək proqram yaratmaq üçün Create-react-app komanda xətti alətini işə salın (bu sadə proqramdır Reaksiya).
  5. (Könüllü) Npm quraşdırma və sonra npm start ilə nümunə proqramı yerli olaraq işə salmaq üçün deponu klonlayın.

Tətbiq anbarında həmçinin tətbiqi yerləşdirmək üçün istifadə olunan Kubernetes/OpenShift YAML-ləri ehtiva edən k8s qovluğu olacaq. Burada yaradacağımız Tapşırıqlar, ClusterTasks, Resurslar və Boru Kəmərləri olacaq. depolar.

Başlanır

Nümunəmiz üçün ilk addım OpenShift klasterində yeni layihə yaratmaqdır. Gəlin bu layihəni webapp-pipeline adlandıraq və onu aşağıdakı komanda ilə yaradaq:

$ oc new-project webapp-pipeline

Daha sonra bu layihə adı kodda görünəcək, ona görə də onu başqa adlandırmaq qərarına gəlsəniz, nümunələrdən kodu müvafiq olaraq redaktə etməyi unutmayın. Bu nöqtədən başlayaraq, yuxarıdan aşağıya deyil, aşağıdan yuxarıya doğru gedəcəyik: yəni əvvəlcə konveyerin bütün komponentlərini, sonra isə özünü yaradacağıq.

Beləliklə, ilk növbədə…

Tapşırıqlar

Gəlin bir neçə tapşırıq (tapşırıq) yaradaq, bu da proqramın boru kəmərimizdə yerləşdirilməsinə kömək edəcək. İlk tapşırıq, application_manifests_task, tətbiqimizin k8s qovluğunda yerləşən həmin Kubernetes resurslarının (xidmət, yerləşdirmə və marşrut) YAML tətbiqinə cavabdehdir. İkinci tapşırıq - update_deployment_task - artıq yerləşdirilmiş təsviri bizim boru kəmərimiz tərəfindən yaradılan görüntüyə yeniləmək üçün cavabdehdir.

Hələ çox aydın deyilsə, narahat olmayın. Əslində, bu vəzifələr kommunal xidmətlər kimi bir şeydir və biz onlara bir az sonra daha ətraflı girəcəyik. Hələlik gəlin onları yaradaq:

$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/tasks/update_deployment_task.yaml
$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/tasks/apply_manifests_task.yaml

Sonra, tkn CLI əmrindən istifadə edərək, tapşırıqların yaradıldığını yoxlayın:

$ tkn task ls

NAME                AGE
apply-manifests     1 minute ago
update-deployment   1 minute ago

Qeyd: Bunlar cari layihəniz üçün yerli tapşırıqlardır.

Klaster tapşırıqları

Klaster tapşırıqları əsasən sadəcə tapşırıqlarla eynidir. Yəni, müəyyən bir tapşırıq işə salındıqda bu və ya digər şəkildə birləşdirilən addımların təkrar istifadə edilə bilən toplusudur. Fərq ondadır ki, klaster tapşırığı klaster daxilində hər yerdə mövcuddur. Boru Kəməri Operatoru əlavə edildikdə avtomatik olaraq yaradılan klaster tapşırıqlarının siyahısını görmək üçün yenidən tkn CLI əmrindən istifadə edin:

$ tkn clustertask ls

NAME                       AGE
buildah                    1 day ago
buildah-v0-10-0            1 day ago
jib-maven                  1 day ago
kn                         1 day ago
maven                      1 day ago
openshift-client           1 day ago
openshift-client-v0-10-0   1 day ago
s2i                        1 day ago
s2i-go                     1 day ago
s2i-go-v0-10-0             1 day ago
s2i-java-11                1 day ago
s2i-java-11-v0-10-0        1 day ago
s2i-java-8                 1 day ago
s2i-java-8-v0-10-0         1 day ago
s2i-nodejs                 1 day ago
s2i-nodejs-v0-10-0         1 day ago
s2i-perl                   1 day ago
s2i-perl-v0-10-0           1 day ago
s2i-php                    1 day ago
s2i-php-v0-10-0            1 day ago
s2i-python-3               1 day ago
s2i-python-3-v0-10-0       1 day ago
s2i-ruby                   1 day ago
s2i-ruby-v0-10-0           1 day ago
s2i-v0-10-0                1 day ago

İndi iki klaster tapşırığı yaradaq. Birincisi S2I şəklini yaradacaq və onu daxili OpenShift reyestrinə göndərəcək; ikincisi, artıq məzmun olaraq qurduğumuz tətbiqdən istifadə edərək NGINX əsaslı imicimizi yaratmaqdır.

Şəkil yaradın və göndərin

İlk tapşırığı yaratarkən, əlaqəli məclislər haqqında əvvəlki məqalədə etdiyimizi təkrarlayacağıq. Yada salaq ki, biz tətbiqimizi "yaratmaq" üçün S2I təsvirindən (ubi8-s2i-web-app) istifadə etdik və daxili OpenShift reyestrində saxlanılan bir şəkil ilə başa çatdıq. İndi biz bu S2I veb tətbiqi şəklini tətbiqimiz üçün DockerFile yaratmaq üçün istifadə edəcəyik və sonra Buildah-dan istifadə edərək nəticədə yaranan təsviri daxili OpenShift reyestrinə köçürəcəyik, çünki siz NodeShift-dən istifadə edərək proqramlarınızı yerləşdirdiyiniz zaman OpenShift məhz bunu edir.

Bütün bunları biz haradan bilirik, soruşursan? From rəsmi Node.js-in rəsmi versiyası, biz sadəcə onu köçürdük və özümüz üçün bitirdik.

Beləliklə, indi biz s2i-web-app klaster tapşırığını yaradırıq:

$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/clustertasks/s2i-web-app-task.yaml

Biz bunu ətraflı təhlil etməyəcəyik, ancaq OUTPUT_DIR parametri üzərində dayanacağıq:

params:
      - name: OUTPUT_DIR
        description: The location of the build output directory
        default: build

Varsayılan olaraq, bu parametr React-in qurulmuş məzmunu yerləşdirdiyi yerdir. Digər çərçivələr müxtəlif yollardan istifadə edir, məsələn, Ember-də dist. İlk klaster tapşırığımızın nəticəsi topladığımız HTML, JavaScript və CSS-dən ibarət bir şəkil olacaq.

Biz NGINX əsasında bir şəkil qururuq

İkinci klaster tapşırığımıza gəlincə, o, artıq qurduğumuz tətbiqin məzmunundan istifadə edərək bizim üçün NGINX əsaslı görüntü yaratmalıdır. Əslində, bu, zəncirlənmiş quruluşlara baxdığımız əvvəlki bölmənin hissəsidir.

Bunu etmək üçün, biz - bir az yuxarıda olduğu kimi - webapp-build-runtime klaster tapşırığını yaradacağıq:

$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/clustertasks/webapp-build-runtime-task.yaml

Bu klaster tapşırıqlarının koduna baxsanız, onda görə bilərsiniz ki, bizim işlədiyimiz Git repozitoriyası və ya yaratdığımız şəkillərin adları göstərilməyib. Biz yalnız Git-ə tam olaraq nəyi ötürəcəyimizi və ya son şəkli çıxarmaq istədiyimiz bəzi təsviri müəyyənləşdiririk. Buna görə də bu qruplaşdırılmış tapşırıqlar digər proqramlarla işləyərkən təkrar istifadə edilə bilər.

Və sonra zərifliklə növbəti nöqtəyə keçirik ...

Resurslar

Beləliklə, bayaq dediyimiz kimi, klaster tapşırıqları mümkün qədər ümumi olmalıdır, biz girişdə (Git deposu) və çıxışda (son şəkillər) istifadə olunacaq resurslar yaratmalıyıq. Bizə lazım olan ilk resurs tətbiqimizin yerləşdiyi Git-dir, buna bənzər bir şey:

# This resource is the location of the git repo with the web application source
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
  name: web-application-repo
spec:
  type: git
  params:
    - name: url
      value: https://github.com/nodeshift-starters/react-pipeline-example
    - name: revision
      value: master

Burada PipelineResource git tiplidir. Params bölməsindəki url açarı müəyyən bir depoya işarə edir və master filialını təyin edir (bu isteğe bağlıdır, lakin biz onu tamlıq üçün yazırıq).

İndi s2i-web-app tapşırığının nəticələrinin saxlanacağı şəkil üçün bir resurs yaratmalıyıq, bu aşağıdakı kimi edilir:

# This resource is the result of running "npm run build",  the resulting built files will be located in /opt/app-root/output
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
  name: built-web-application-image
spec:
  type: image
  params:
    - name: url
      value: image-registry.openshift-image-registry.svc:5000/webapp-pipeline/built-web-application:latest

Burada PipelineResource şəkil tiplidir və url parametrinin dəyəri daxili OpenShift Şəkil Reyestrinə, xüsusən də webapp-pipeline ad məkanındakı birinə işarə edir. Fərqli ad məkanından istifadə edirsinizsə, bu parametri dəyişməyi unutmayın.

Və nəhayət, bizə lazım olan son resurs da şəkil tipli olacaq və bu, yerləşdirmə zamanı istifadə olunacaq son NGINX şəkli olacaq:

# This resource is the image that will be just the static html, css, js files being run with nginx
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
  name: runtime-web-application-image
spec:
  type: image
  params:
    - name: url
      value: image-registry.openshift-image-registry.svc:5000/webapp-pipeline/runtime-web-application:latest

Yenə də qeyd edək ki, bu resurs şəkli webapp-pipeline ad məkanında daxili OpenShift reyestrində saxlayır.

Bütün bu resursları bir anda yaratmaq üçün yaratmaq əmrindən istifadə edirik:

$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/resources/resource.yaml

Resursların yaradıldığından əmin olmaq üçün bunu edə bilərsiniz:

$ tkn resource ls

boru kəməri

İndi bütün lazımi komponentlərə sahib olduğumuzdan, aşağıdakı əmrlə yaradaraq onlardan bir boru kəməri yığacağıq:

$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/pipelines/build-and-deploy-react.yaml

Ancaq bu əmri yerinə yetirməzdən əvvəl bu komponentlərə nəzər salaq. Birincisi adıdır:

apiVersion: tekton.dev/v1alpha1
kind: Pipeline
metadata:
  name: build-and-deploy-react

Sonra, spesifikasiya bölməsində əvvəllər yaratdığımız resursların göstəricisini görürük:

spec:
  resources:
    - name: web-application-repo
      type: git
    - name: built-web-application-image
      type: image
    - name: runtime-web-application-image
      type: image

Daha sonra boru kəmərimizin işləməsi üçün tapşırıqlar yaradırıq. Əvvəla, o, artıq yaratdığımız s2i-web-app tapşırığını yerinə yetirməlidir:

tasks:
    - name: build-web-application
      taskRef:
        name: s2i-web-app
        kind: ClusterTask

Bu tapşırıq giriş (gir resurs) və çıxış (daxili veb tətbiqi-şəkil resursu) parametrlərini qəbul edir. Öz-özünə imzalanmış sertifikatlardan istifadə etdiyimiz üçün TLS-ni yoxlamaması üçün ona xüsusi parametr də veririk:

resources:
        inputs:
          - name: source
            resource: web-application-repo
        outputs:
          - name: image
            resource: built-web-application-image
      params:
        - name: TLSVERIFY
          value: "false"

Növbəti tapşırıq demək olar ki, eynidir, yalnız bizim artıq yaratdığımız webapp-build-runtime klaster tapşırığı burada çağırılır:

name: build-runtime-image
    taskRef:
      name: webapp-build-runtime
      kind: ClusterTask

Əvvəlki tapşırıqda olduğu kimi, biz bir resursdan keçirik, amma indi o, qurulmuş veb-tətbiq-imagedir (əvvəlki tapşırığımızın nəticəsi). Və nəticə olaraq, yenidən görüntünü təyin etdik. Bu tapşırıq əvvəlkindən sonra yerinə yetirilməli olduğundan runAfter sahəsini əlavə edirik:

resources:
        inputs:
          - name: image
            resource: built-web-application-image
        outputs:
          - name: image
            resource: runtime-web-application-image
        params:
        - name: TLSVERIFY
          value: "false"
      runAfter:
        - build-web-application

Növbəti iki tapşırıq veb tətbiqimizin k8s kataloqunda yaşayan xidmət, marşrut və yerləşdirmə YAML fayllarının tətbiqi və yeni şəkillər yaradıldıqda bu yerləşdirmənin yenilənməsi üçün cavabdehdir. Məqalənin əvvəlində bu iki klaster vəzifəsini təyin etdik.

Boru kəmərinin işə salınması

Beləliklə, boru kəmərimizin bütün hissələri yaradılmışdır və biz onu aşağıdakı əmrlə başlayacağıq:

$ tkn pipeline start build-and-deploy-react

Bu nöqtədə, komanda xətti interaktiv şəkildə istifadə olunur və onun hər bir sorğusuna cavab olaraq müvafiq resurslar seçilməlidir: git resursu üçün web-application-repo, sonra ilk şəkil resursu üçün inşa-veb-application- seçin. şəkil, və nəhayət, ikinci şəkil resursu üçün – runtime-web-application-image:

? Choose the git resource to use for web-application-repo: web-application-repo (https://github.com/nodeshift-starters/react-pipeline-example)
? Choose the image resource to use for built-web-application-image: built-web-application-image (image-registry.openshift-image-registry.svc:5000/webapp-pipeline/built-web-
application:latest)
? Choose the image resource to use for runtime-web-application-image: runtime-web-application-image (image-registry.openshift-image-registry.svc:5000/webapp-pipeline/runtim
e-web-application:latest)
Pipelinerun started: build-and-deploy-react-run-4xwsr

İndi aşağıdakı əmrlə boru kəmərinin vəziyyətini yoxlayın:

$ tkn pipeline logs -f

Boru kəməri işə salındıqdan və proqram yerləşdirildikdən sonra dərc edilmiş marşrutu aşağıdakı əmrlə sorğulayın:

$ oc get route react-pipeline-example --template='http://{{.spec.host}}'

Daha çox görünürlük üçün bölmədə veb konsolunun Developer rejimində boru kəmərimizə baxa bilərsiniz. Boru kəmərləriŞəkildə göstərildiyi kimi. 1.

OpenShift-də Müasir Tətbiqlər, 3-cü Hissə: İnkişaf Mühiti və OpenShift Boru Kəmərləri kimi OpenShift

Şəkil 1. Aparılan boru kəmərlərinə ümumi baxış.

Çalışan boru kəmərinə kliklədikdə Şəkil 2-də göstərildiyi kimi əlavə təfərrüatlar göstərilir.

OpenShift-də Müasir Tətbiqlər, 3-cü Hissə: İnkişaf Mühiti və OpenShift Boru Kəmərləri kimi OpenShift

düyü. 2. Konveyer haqqında əlavə məlumat.

Ətraflı təfərrüatlardan sonra görünüşdə çalışan proqramları görə bilərsiniz Topoloji, Fig.3-də göstərildiyi kimi.

OpenShift-də Müasir Tətbiqlər, 3-cü Hissə: İnkişaf Mühiti və OpenShift Boru Kəmərləri kimi OpenShift

Şək 3. Çalışan pod.

İşarənin yuxarı sağ küncündəki dairənin üzərinə klikləməklə, Şəkil 4-də göstərildiyi kimi tətbiqimiz açılır.

OpenShift-də Müasir Tətbiqlər, 3-cü Hissə: İnkişaf Mühiti və OpenShift Boru Kəmərləri kimi OpenShift

düyü. 4. İşləyən React proqramı.

Nəticə

Beləliklə, biz OpenShift-də tətbiqiniz üçün inkişaf serverini necə işə salmağı və onu yerli fayl sistemi ilə sinxronizasiya etməyi göstərdik. Biz həmçinin OpenShift Pipelines istifadə edərək zəncirlənmiş quruluş şablonunu necə simulyasiya etməyə baxdıq. Bu məqalədəki bütün nümunə kodları tapa bilərsiniz burada.

Əlavə Resurslar

Qarşıdan gələn vebinarların elanları

Red Hat OpenShift Konteyner Platforması və Kubernetes-dən istifadənin yerli təcrübəsi haqqında bir sıra cümə vebinarlarına başlayırıq:

Mənbə: www.habr.com

Добавить комментарий