Прабач, OpenShift, мы недастаткова шанавалі цябе і прымалі як належнае
Гэты пост напісаны паколькі ў нашых супрацоўнікаў было даволі шмат гутарак з кліентамі аб распрацоўцы прыкладанняў на Kubernetes і аб спецыфіцы такой распрацоўкі на OpenShift.
Пачынаем мы звычайна з тэзы, што Kubernetes - гэта проста Kubernetes, а OpenShift - гэта ўжо Kubernetes-платформа, як Microsoft AKS або Amazon EKS. У кожнай з гэтых платформ ёсць свае плюсы, арыентаваныя на тую ці іншую мэтавую аўдыторыю. І пасля гэтага размова ўжо перацякае ў параўнанне моцных і слабых бакоў канкрэтных платформ.
Увогуле, мы думалі напісаць гэтую пасаду з высновай тыпу «Слухайце, ды без розніцы, дзе запускаць код, на OpenShift або на AKS, на EKS, на нейкім кастамным Kubernetes, ды на якім-заўгодна-Kubernetes (для сцісласці назавем яго КУК) – гэта рэальна проста, і там, і там».
Затым мы планавалі ўзяць найпросты "Hello World" і на яго прыкладзе паказаць, што агульнага і ў чым адрозненні паміж КУК і Red Hat OpenShift Container Platform (далей, OCP ці проста OpenShift).
Аднак па ходзе напісання гэтай пасады, мы зразумелі, што так даўно і моцна абвыклі выкарыстоўваць OpenShift, што проста не ўсведамляем, як ён вырас і ператварыўся ў узрушаючую платформу, якая стала значна больш, чым проста Kubernetes-дыстрыбутыў. Мы абвыклі ўспрымаць сталасць і прастату OpenShift як належнае, выпускаючы з-пад увагі яго пышнасць.
Увогуле, прыйшла сітавіна дзейнага раскаяння, і цяпер мы пакрокава параўнаем увод у лад свайго «Hello World» на КУК і на OpenShift, і зробім гэта максімальна аб'ектыўна (ну няўжо што выказваючы часам асабістае стаўленне да прадмета). Калі вам цікава асабліва суб'ектыўнае меркаванне па гэтым пытанні, тое яго можна прачытаць тут (EN). А ў гэтым пасце мы будзем прытрымлівацца фактаў і толькі фактаў.
кластары
Такім чынам, для нашага "Hello World" патрэбны кластары. Адразу скажам "не" усякім публічным аблокам, каб не плаціць за сервера, рэестры, сеткі, перадачу дадзеных і г.д. Адпаведна, мы выбіраем просты аднавузлавой кластар на Мінікубе (для КУК) і Кантэйнеры, гатовыя да кода (для кластара OpenShift). Абодва гэтых варыянты рэальна простыя ў ўстаноўцы, але запатрабуюць даволі шмат рэсурсаў на вашым ноўце.
Зборка на КУК-е
Такім чынам, паехалі.
Крок 1 – збіраем нашу кантэйнерную выяву
Пачнём я з таго, што разгорнем наш Hello World на minikube. Для гэтага спатрэбіцца:
1. Усталяваны Docker.
2. Усталяваны Git.
3. Усталяваны Maven (наогул-то ў гэтым праекце выкарыстоўваецца mvnw-бінарнік, так што можна абыйсціся і без гэтага).
Перш за ўсё трэба стварыць праект Quarkus. Не палохайцеся, калі ніколі не працавалі з сайтам Quarkus.io - гэта лёгка. Проста выбіраеце кампаненты, якія жадаеце выкарыстаць у праекце (RestEasy, Hibernate, Amazon SQS, Camel і т.д.), а далей Quarkus ужо сам, без якога-небудзь вашага ўдзелу, наладжвае архетып maven і выкладвае ўсё на github. Гэта значыць літаральна адзін клік мышшу - і гатова. За гэта мы і кахаем Quarkus.
Самы просты спосаб сабраць наш "Hello World" у кантэйнерны вобраз - выкарыстоўваць пашырэнні quarkus-maven для Docker'а, якія і праробяць усю неабходную працу. З з'яўленнем Quarkus гэта стала сапраўды лёгка і проста: дадаеце пашырэнне container-image-docker і можаце ствараць выявы камандамі maven.
І, нарэшце, выконваем зборку нашай выявы, выкарыстаючы Maven. У выніку наш зыходны код ператвараецца ў гатовую кантэйнерную выяву, які ўжо можна запускаць у асяроддзі выканання кантэйнераў.
Вось, уласна, і ўсё, зараз можна запускаць кантэйнер камандай docker run, падмапіўшы наш сэрвіс на порт 8080, каб да яго можна было звяртацца.
docker run -i — rm -p 8080:8080 gcolman/quarkus-hello-world
Пасля таго, як кантэйнерны інстанс запусціўся, застаецца толькі праверыць камандай curl, што наш сэрвіс працуе:
Такім чынам, усё працуе, і гэта было сапраўды лёгка і проста.
Крок 2 – адпраўляем наш кантэйнер у рэпазітар кантэйнерных вобразаў
Пакуль што створаны намі выява захоўваецца лакальна, у нашым лакальным кантэйнерным сховішчы. Калі мы хочам выкарыстоўваць гэтую выяву ў сваім асяроддзі КУК, тое яго трэба пакласці ў нейкі іншы рэпазітар. У Kubernetes няма такіх функцый, таму мы будзем выкарыстоўваць dockerhub. Таму што, па-першае, ён бясплатны, а па-другое, (амаль) усё так робяць.
Гэта таксама вельмі проста, і патрэбен тут толькі акаўнт на dockerhub.
Такім чынам, ставім dockerhub і адпраўляем туды нашу выяву.
Крок 3 - запускаем Kubernetes
Ёсць шмат спосабаў сабраць канфігурацыю kubernetes для запуску нашага Hello World, але мы будзем выкарыстоўваць найпросты з іх, ужо такія мы людзі…
Для пачатку запускаем кластар minikube:
minikube start
Крок 4 – разгортваем нашу кантэйнерную выяву
Цяпер трэба пераўтварыць наш код і кантэйнерны вобраз у канфігурацыі kubernetes. Інакш кажучы, нам патрэбен pod і deployment definition з указаннем на нашу кантэйнерную выяву на dockerhub. Адзін з самых простых спосабаў гэта зрабіць - запусціць каманду create deployment, паказаўшы на нашу выяву:
Гэтай каманднай мы сказалі нашай КУК стварыць deployment configuration, якая павінна змяшчаць спецыфікацыю pod'а для нашага кантэйнернага ладу. Гэтая каманда таксама прыменіць гэтую канфігурацыю да нашага кластара minikube, і створыць deployment, які запампуе наш кантэйнерны вобраз і запусціць pod у кластары.
Крок 5 – адчыняны доступ да нашага сэрвісу
Цяпер, калі ў нас ёсць разгорнуты кантэйнерны вобраз, пара падумаць, як сканфігураваць знешні доступ да гэтага Restful-сэрвісу, які, уласна, і запраграмаваны ў нашым кодзе.
Тут ёсьць шмат спосабаў. Напрыклад, можна выкарыстоўваць каманду expose, каб аўтаматычна ствараць адпаведныя Kubernetes-кампаненты, такія як services і endpoints. Уласна, так мы і зробім, выканаўшы каманду expose для нашага deployment-аб'екта:
Давайце на хвілінку спынімся на опцыі «-type» каманды expose.
Калі мы робім expose і ствараем кампаненты, неабходныя для запуску нашага сэрвісу, нам, сярод іншага, трэба, каб звонку можна было падключыцца да службы hello-quarkus, якая сядзіць усярэдзіне нашай праграмна-вызначанай сеткі. І параметр тып дазваляе нам стварыць і падключыць такія рэчы, як балансавальнікі нагрузкі, каб маршрутызаваць трафік у гэтую сетку.
Напрыклад, прапісаўшы type=LoadBalancer, мы аўтаматычна ініцыялізуем балансавальнік нагрузкі ў публічным воблаку, каб падлучацца да нашага кластара Kubernetes. Гэта, вядома, выдатна, але трэба разумець, што такая канфігурацыя будзе цвёрда прывязана да пэўнага публічнага воблака і яе будзе складаней пераносіць паміж Kubernetes-інстансам у розных асяроддзях.
У нашым прыкладзе type=NodePort, гэта значыць зварот да нашага сэрвісу ідзе па IP-адрасу вузла і нумару порта. Такі варыянт дазваляе не выкарыстоўваць ніякія публічныя аблокі, але патрабуе шэраг дадатковых крокаў. Па-першае, патрэбен свой балансавальнік нагрузкі, таму мы разгорнем у сваім кластары балансавальнік нагрузкі NGINX.
Крок 6 - ставім балансавальнік нагрузкі
У minikube ёсць шэраг платформенных функцый, якія палягчаюць стварэнне неабходных для доступу звонку кампанентаў, накшталт ingress-кантролераў. Minikube ідзе ў камплекце з ingress-кантролерам Nginx, і нам застаецца толькі ўключыць яго і наладзіць.
minikube addons enable ingress
Цяпер мы ўсяго адной камандай ствару ingress-кантролер Nginx, які будзе працаваць усярэдзіне нашага кластара minikube:
Цяпер нам трэба наладзіць ingress-кантролер Nginx, каб ён успрымаў запыты hello-quarkus.
І, нарэшце, нам трэба прымяніць гэтую канфігурацыю.
kubectl apply -f ingress.yml
Паколькі мы робім усё гэта на сваім кампе, то проста дадаем IP-адрас сваёй ноды ў файл /etc/ hosts, каб накіроўваць http-запыты да нашага minikube на балансавальнік нагрузкі NGINX.
192.168.99.100 hello-quarkus.info
Усё, зараз наш сэрвіс minikube даступны звонку праз ingress-кантролер Nginx.
Ну што, гэта было лёгка, так? Ці не вельмі?
Запуск на OpenShift (Code Ready Containers)
А зараз паглядзім, як гэта ўсё робіцца на Red Hat OpenShift Container Platform (OCP).
Як у выпадку з minikube, мы выбіраем схему з аднавузлавым кластарам OpenShift у форме Code Ready Containers (CRC). Раней гэта звалася minishift і грунтавалася на праекце OpenShift Origin, а зараз гэта CRC і пабудавана на Red Hat'аўскай OpenShift Container Platform.
Тут мы, прабачце, не можам стрымацца і не сказаць: OpenShift выдатны!
Першапачаткова мы думалі напісаць, што распрацоўка на OpenShift нічым не адрозніваецца ад распрацоўкі на Kubernetes. І па сутнасці так яно і ёсць. Але падчас напісання гэтай пасады мы ўспомнілі, колькі лішніх рухаў даводзіцца здзяйсняць, калі ў вас няма OpenShift, і таму ён, паўторымся, выдатны. Мы кахаем, калі ўсё робіцца лёгка, і тое, як лёгка ў параўнанні з minikube наш прыклад разгортваецца і запускаецца на OpenShift, уласна, і падштурхнула нас напісаць гэтую пасаду.
Давайце прабяжымся па працэсе і паглядзім, што нам спатрэбіцца зрабіць.
Такім чынам, у прыкладзе з minikube мы пачыналі з Docker… Стоп, нам больш не трэба, каб на машыне быў усталяваны Docker.
І лакальны git нам не патрэбен.
І Maven не патрэбен.
І не трэба рукамі ствараць кантэйнерны вобраз.
І не трэба шукаць які-небудзь рэпазітар кантэйнерных вобразаў.
І не трэба ўсталёўваць ingress-кантролер.
І канфігураваць ingress таксама не трэба.
Вы зразумелі, так? Каб разгарнуць і запусціць наша дадатак на OpenShift, не трэба нічога з вышэйпералічанага. А сам працэс выглядае наступным чынам.
Крок 1 - Запускаем свой кластар OpenShift
Мы выкарыстоўваем Code Ready Containers ад Red Hat, які ў сутнасці ёсць той жа Minikube, але толькі з паўнавартасным аднавузлавой кластарам Openshift.
crc start
Крок 2 - Выконваем зборку і разгортванне прыкладання ў кластары OpenShift
Менавіта на гэтым кроку прастата і выгода OpenShift выяўляюцца ва ўсёй красе. Як і ва ўсіх дыстрыбутывах Kubernetes, у нас ёсць шмат спосабаў запусціць прыкладанне ў кластары. І, як і ў выпадку КУК, мы спецыяльна выбіраем самы найпросты.
OpenShift заўсёды будаваўся як платформа для стварэння і запуску кантэйнерных дадаткаў. Зборка кантэйнераў заўсёды была неад'емнай часткай гэтай платформы, таму тут ёсць куча дадатковых Kubernetes-рэсурсаў для адпаведных задач.
Мы будзем выкарыстоўваць OpenShift'аўскі працэс Source 2 Image (S2I), у якога ёсць некалькі розных спосабаў для таго, каб узяць наш зыходнік (код або двайковыя файлы) і ператварыць яго ў кантэйнерны вобраз, які запускаецца ў кластары OpenShift.
Для гэтага нам спатрэбяцца дзве рэчы:
Наш зыходны код у рэпазітары git
Builder-выява, на падставе якога будзе выконвацца зборка.
Існуе мноства такіх выяў, якія суправаджаюцца як сіламі Red Hat, так і на ўзроўні супольнасці, і мы скарыстаемся выявай OpenJDK, ну паколькі я ж збіраю Java-прыкладанне.
Запусціць S2I-зборку можна, як і з графічнай кансолі OpenShift Developer, так і з каманднага радка. Мы скарыстаемся камандай new-app, паказаўшы ёй, дзе браць builder-выява і наш зыходны код.
Усё, наша дадатак створана. Пры гэтым працэс S2I выканаў наступныя рэчы:
Стварыў службовы build-pod для ўсякіх рэчаў, злучаных са зборкай прыкладання.
Стварыў канфіг OpenShift Build.
Запампаваў builder-выява ва ўнутраны docker-рэестр OpenShift.
Кланаваў «Hello World» у лакальны рэпазітар.
Убачыў, што там ёсць maven pom, і таму скампіляваў дадатак з дапамогай maven.
Стварыў новы кантэйнерны вобраз, які змяшчае скампіляванае Java-дадатак, і паклаў гэты вобраз ва ўнутраны рэестр кантэйнераў.
Стварыў Kubernetes Deployment са спецыфікацыямі pod'а, сервісу і г.д.
Запусціў deploy кантэйнернага ладу.
Выдаліў службовы build-pod.
У гэтым спісе шмат усяго, але галоўнае, што ўся зборка адбываецца выключна ўсярэдзіне OpenShift, унутраны Docker-рэестр знаходзіцца ўсярэдзіне OpenShift, а працэс зборкі стварае ўсе кампаненты Kubernetes і запускае іх у кластары.
Калі візуальна адсочваць запуск S2I у кансолі, то можна ўбачыць, як пры выкананні зборкі запускаецца build pod.
А зараз зірнем логі builder pod'а: па-першае, там відаць, як maven робіць сваю працу і спампоўвае залежнасці для зборкі нашага java-прыкладанні.
Пасля таго, як скончаная maven-зборка, запускаецца зборка кантэйнернай выявы, і затым гэтая сабраная выява адпраўляецца ва ўнутраны рэпазітар.
Усё, працэс зборкі завершаны. Цяпер пераканаемся, што ў кластары запусціліся pod'ы і сэрвісы нашага прыкладання.
oc get service
Вось і ўсё. І ўсяго адна каманда. Нам застаецца толькі зрабіць expose гэтага сэрвісу для доступу звонку.
Крок 3 – які робіцца expose сэрвісу для доступу звонку
Як і ў выпадку КУК, на платформе OpenShift нашаму «Hello World» таксама патрэбен роўтар, каб накіроўваць вонкавы трафік на сэрвіс усярэдзіне кластара. У OpenShift гэта робіць вельмі проста. Па-першае, у кластары па змаўчанні ўсталяваны кампанент маршрутызацыі HAProxy (яго можна памяняць на той жа NGINX). Па-другое, тут ёсць адмысловыя і дапушчальныя шырокія магчымасці налады рэсурсы, якія завуцца Routes і нагадваюць Ingress-аб'екты ў старым дабром Kubernetes (насамрэч OpenShift'аўкія Routes моцна паўплывалі на дызайн Ingress-аб'ектаў, якія зараз можна выкарыстоўваць і ў OpenShift) , Але для нашага «Hello World», ды і амаль ва ўсіх астатніх выпадках, нам хопіць стандартнага Route без дадатковай наладкі.
Каб стварыць для «Hello World» маршрутызаваны FQDN (так, у OpenShiift ёсць свой DNS для маршрутызацыі па імёнах сэрвісаў), мы проста выканаем expose для нашага сэрвісу:
oc expose service quarkus-hello-world
Калі паглядзець толькі што створаны Route, то тамака можна знайсці FQDN і іншыя звесткі па маршрутызацыі:
oc get route
І нарэшце, звяртаемся да нашага сэрвісу з браўзэра:
А вось зараз гэта было сапраўды лёгка!
Мы любім Kubernetes і ўсё, што дазваляе рабіць гэтая тэхналогія, а таксама мы любім прастату і лёгкасць. Kubernetes ствараўся, каб неверагодна спрасціць эксплуатацыю размеркаваных якія маштабуюцца кантэйнераў, але вось для ўводу ў лад прыкладанняў яго прастаты сёння ўжо нядосыць. І тут у гульню ўступае OpenShift, які ідзе ў нагу са часам і прапануе Kubernetes, арыентаваны ў першую чаргу на распрацоўніка. Была ўкладзена маса намаганняў, каб завастрыць платформу OpenShift менавіта пад распрацоўніка, у тым ліку стварэнне такіх інструментаў, як S2I, ODI, Developer Portal, OpenShift Operator Framework, інтэграцыя з IDE, Developer Catalogues, інтэграцыя з Helm, маніторынг і многія іншыя.
Спадзяемся, што гэты артыкул быў для вас цікавым і карысным. А знайсці дадатковыя рэсурсы, матэрыялы і іншыя карысныя для распрацоўкі на платформе OpenShift рэчы можна на партале Red Hat Developers.