Съжалявам, OpenShift, не те оценявахме достатъчно и те приемахме за даденост

Този пост е написан, защото нашите служители проведоха доста разговори с клиенти относно разработката на приложения в Kubernetes и особеностите на подобна разработка в OpenShift.

Съжалявам, 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“ са ни нужни клъстери. Веднага казваме „не“ на всякакви публични облаци, за да не плащаме за сървъри, регистри, мрежи, предаване на данни и т.н. Следователно избираме прост еднодисков клъстер на Minikube (за КУК) и Code Ready Containers (за клъстера OpenShift). И двата варианта са наистина лесни за инсталиране, но ще изискват доста ресурси на вашия лаптоп.

Съжалявам, OpenShift, не те оценявахме достатъчно и те приемахме за даденост

Сглобяване на КУК

И така, да започваме.

Стъпка 1 – сглобяваме нашия контейнерен образ

Нека започнем с разполагането на нашия „Hello World“ на minikube. За това са необходими:

  1. 1. Инсталиран Docker.
  2. 2. Инсталиран Git.
  3. 3. Инсталиран Maven (в действителност, в този проект се използва mvnw бинарен файл, така че можете да се справите и без това).
  4. 4. Всъщност, самият изходен код, т.е. клонирането на репозитория github.com/gcolman/quarkus-hello-world.git

На първо място, трябва да създадете Quarkus проект. Не се притеснявайте, ако никога не сте работили с уебсайта Quarkus.io – това е лесно. Просто избирате компонентите, които искате да използвате в проекта (RestEasy, Hibernate, Amazon SQS, Camel и т.н.), а след това Quarkus сам, без ваше участие, настройва архетипа на maven и всичко публикува в github. Тоест, буквално един клик с мишката – и готово. Заради това обичаме Quarkus.

Съжалявам, OpenShift, не те оценявахме достатъчно и те приемахме за даденост

Най-простият начин да съберете нашето „Hello World“ в контейнерен образ е да използвате разширението quarkus-maven за Docker, което ще свърши цялата необходима работа. С появата на Quarkus това стана наистина лесно и просто: добавяте разширението container-image-docker и можете да създавате образи с maven команди.

./mvnw quarkus:add-extension -Dextensions="container-image-docker"

И, накрая, извършваме изграждането на нашия образ, използвайки Maven. В резултат на това, нашият изходен код се превръща в готов контейнерен образ, който вече може да бъде стартиран в среда за изпълнение на контейнери.

Съжалявам, OpenShift, не те оценявахме достатъчно и те приемахме за даденост

./mvnw -X clean package -Dquarkus.container-image.build=true

Ето, всъщност и всичко, сега можете да стартирате контейнера с командата docker run, картографирайки нашия сервис на порт 8080, за да бъде достъпен.

docker run -i --rm -p 8080:8080 gcolman/quarkus-hello-world

Съжалявам, OpenShift, не те оценявахме достатъчно и те приемахме за даденост

След като контейнерният инстанс стартира, остава само да проверите с командата curl, че нашият сервис работи:

Съжалявам, OpenShift, не те оценявахме достатъчно и те приемахме за даденост

И така, всичко работи и наистина беше лесно и просто.

Стъпка 2 – изпращаме нашия контейнер в репозитория на контейнерни образи

Досега, създаденият от нас образ се съхранява локално, в нашето локално хранилище за контейнери. Ако искаме да използваме този образ в своята среда KUB, трябва да го поставим в някой друг репозиторий. В Kubernetes няма такива функции, затова ще използваме dockerhub. Защото, от една страна, той е безплатен, а от друга страна, (почти) всички така правят.

Това също е много просто, и тук само е нужен акаунт в dockerhub.

И така, изтегляме dockerhub и изпращаме там нашия образ.

Съжалявам, OpenShift, не те оценявахме достатъчно и те приемахме за даденост

Стъпка 3 – стартиране на Kubernetes

Има много начини за събиране на конфигурация за kubernetes за стартиране на нашето „Hello World“, но ще използваме най-простия от тях, ние сме такива хора...

Първо, стартирайте кластера minikube:

minikube start

Стъпка 4 – разгръщаме нашия контейнерен образ

Сега трябва да преобразуваме нашия код и контейнерния образ в конфигурации на kubernetes. С други думи, нуждаем се от pod и deployment определение, което указва нашия контейнерен образ на dockerhub. Един от най-простите начин да направим това е да стартираме командата create deployment, като посочим нашия образ:

Съжалявам, OpenShift, не те оценявахме достатъчно и те приемахме за даденост

kubectl create deployment hello-quarkus — image =gcolman/quarkus-hello-world:1.0.0-SNAPSHOT

С тази команда казваме на нашия K8s да създаде конфигурация на deployment, която трябва да съдържа спецификация на pod-a за нашия контейнерен образ. Тази команда също така ще приложи тази конфигурация към нашия миникуб кластер и ще създаде deployment, който ще изтегли нашия контейнерен образ и ще стартира pod в клъстера.

Стъпка 5 – отваряме достъп до нашата услуга

Сега, когато имаме разгръщан контейнерен образ, е време да помислим как да конфигурираме външния достъп до този Restful-сервис, който всъщност е програмиран в нашия код.

Има много начина да го направим. Например, можем да използваме командата expose, за да създадем автоматично съответните компоненти на Kubernetes, като services и endpoints. Всъщност, така и ще направим, изпълнявайки командата expose за нашия deployment обект:

kubectl expose deployment hello-quarkus — type=NodePort — port=8080

Нека за момент спрем на опцията „— 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-controller-69ccf5d9d8-j5gs9 1/1 Текущ 1 33m

Стъпка 7 - Настройване на ingress

Сега трябва да настроим ingress контролера Nginx, за да обработва заявките hello-quarkus.

Съжалявам, OpenShift, не те оценявахме достатъчно и те приемахме за даденост

Съжалявам, OpenShift, не те оценявахме достатъчно и те приемахме за даденост

И накрая, трябва да приложим тази конфигурация.

Съжалявам, OpenShift, не те оценявахме достатъчно и те приемахме за даденост

kubectl apply -f ingress.yml

Съжалявам, OpenShift, не те оценявахме достатъчно и те приемахме за даденост

Тъй като правим всичко това на нашия компютър, просто добавяме IP адреса на нашия възел в файла /etc/hosts, така че http заявките да бъдат насочвани към нашия minikube на балансировача на натоварването NGINX.

192.168.99.100 hello-quarkus.info

Готово, сега нашият minikube услуга е достъпна отвън чрез ingress контролера Nginx.

Съжалявам, OpenShift, не те оценявахме достатъчно и те приемахме за даденост

Ами, това не беше ли лесно, нали? Или не толкова?

Съжалявам, OpenShift, не те оценявахме достатъчно и те приемахме за даденост

Стартиране на OpenShift (Code Ready Containers)

А сега да видим как става това на Red Hat OpenShift Container Platform (OCP).

Както в случая с minikube, избираме схема с едновъзлов кластер OpenShift под формата на Code Ready Containers (CRC). По-рано това бе наричано minishift и се основаваше на проекта OpenShift Origin, а сега е CRC и е построен на OpenShift Container Platform на Red Hat.

Тук, извинете, не можем да се сдържим да не кажем: „OpenShift е страхотен!“

Първоначално мислехме да напишем, че разработката на OpenShift няма особености в сравнение с разработката на Kubernetes. И всъщност, така е. Но в процеса на написването на този пост си припомнихме колко много излишни стъпки се налага да правите, когато нямате OpenShift, и затова той, можем да повторим, е страхотен. Обичаме, когато всичко се прави лесно, а начинът, по който нашият пример се разгръща и стартира на OpenShift в сравнение с minikube, ни подтикна да напишем този пост.

Нека да се запознаем с процеса и да видим какво ще ни е необходимо.

И така, в примера с 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-образа и нашия изходен код.

Съжалявам, OpenShift, не те оценявахме достатъчно и те приемахме за даденост

oc new-app registry.access.redhat.com/ubi8/openjdk-11:latest~https://github.com/gcolman/quarkus-hello-world.git

Всичко, приложението ни е създадено. При това процесът 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.

Съжалявам, OpenShift, не те оценявахме достатъчно и те приемахме за даденост

А сега да погледнем логовете на builder pod: първо, там се вижда как maven върши своята работа и изтегля зависимости за изграждането на нашето java приложение.

Съжалявам, OpenShift, не те оценявахме достатъчно и те приемахме за даденост

След като maven изграждането приключи, стартира изграждането на контейнерния образ и след това този събран образ се изпраща във вътрешния репозиторий.

Съжалявам, OpenShift, не те оценявахме достатъчно и те приемахме за даденост

Всичко, процесът на изграждане е завършен. Сега нека се уверим, че в кластера са стартирани pod-овете и услугите на нашето приложение.

oc get service

Съжалявам, OpenShift, не те оценявахме достатъчно и те приемахме за даденост

Ето всичко. И само една команда. Остава само да направим expose на тази услуга за достъп от външни източници.

Стъпка 3 – правим expose на услугата за достъп от външно

Както и в случая с КУК, на платформата OpenShift нашето 'Hello World' също се нуждае от рутер, за да насочи външния трафик към услугата в кластера. В OpenShift това се прави много лесно. Първо, в кластера по подразбиране е инсталиран компонент за маршрутизиране HAProxy (може да бъде сменен с NGINX). На второ място, тук има специални ресурси, предлагащи широки възможности за конфигурация, наречени Routes, които напомнят на Ingress обекти в добрия стар Kubernetes (всъщност OpenShift-овите Routes оказаха голямо влияние върху дизайна на Ingress обектите, които сега могат да се използват и в OpenShift), но за нашето 'Hello World', както и почти във всичките останали случаи, стандартен Route без допълнителна конфигурация е напълно достатъчен.

За да създадем маршрутизируем FQDN за 'Hello World' (да, в OpenShift има собствен DNS за маршрутизация по имена на услуги), просто ще изпълним expose за нашата услуга:

Съжалявам, OpenShift, не те оценявахме достатъчно и те приемахме за даденост

oc expose service quarkus-hello-world

Ако погледнете току-що създадения Route, можете да намерите FQDN и друга информация за маршрутизация:

oc get route

Съжалявам, OpenShift, не те оценявахме достатъчно и те приемахме за даденост

И накрая, ще се свържем с нашата услуга от браузъра:

Съжалявам, OpenShift, не те оценявахме достатъчно и те приемахме за даденост

А сега това наистина беше лесно!

Ние обичаме Kubernetes и всичко, което тази технология позволява, а също така обичаме простота и лекота. Kubernetes беше създаден, за да опрости експлоатацията на разпределени масштабируеми контейнери, но за внедряване на приложения, простотата му вече не е достатъчна. Тук на помощ идва OpenShift, който върви с времето и предлага Kubernetes, фокусиран главно върху разработчиците. Вложени са много усилия, за да се адаптира платформата OpenShift именно за разработчиците, включително създаването на инструменти като S2I, ODI, Developer Portal, OpenShift Operator Framework, интеграция с IDE, Developer Catalogues, интеграция с Helm, мониторинг и много други.

Надяваме се, че тази статия беше интересна и полезна за вас. Допълнителни ресурси, материали и други полезни неща за разработка на платформата OpenShift можете да намерите на портала Red Hat Developers.

Източник: habr.com

Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри 🔥 Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри | ProHoster