Подготовка на приложението за Istio

Подготовка на приложението за Istio

Istio — това е удобен инструмент за свързване, защита и мониторинг на разпределени приложения. В Istio се използват различни технологии за мащабно стартиране на софтуер и управление на него, включително контейнери за опаковане на кода на приложението и зависимостите за разпределение и Kubernetes — за управление на тези контейнери. Затова, за да работите с Istio, трябва да разберете как работи приложение с няколко услуги, базирани на тези технологии. без Istio. Ако тези инструменти и концепции вече са ви познати, смело пропуснете това ръководство и преминете направо към раздела. Инсталиране на Istio на Google Kubernetes Engine (GKE) или инсталиране на разширение Istio на GKE.

Това е ръководство стъпка по стъпка, в което ще разгледаме целия процес от изходен код до контейнер на GKE, така че да получите основно разбиране за тези технологии с примери. Също така ще видите как Istio използва възможностите на тези технологии. Предполага се, че не знаете нищо за контейнери, Kubernetes, service mesh или Istio.

Задачи

В това ръководство ще изпълните следните задачи:

  1. Изучаване на простото приложение hello world с няколко услуги.
  2. Стартиране на приложението от изходен код.
  3. Опаковане на приложението в контейнери.
  4. Създаване на Kubernetes клъстър.
  5. Разгръщане на контейнери в клъстъра.

Преди да започнете

Следвайте инструкциите, за да активирате Kubernetes Engine API:

  1. Отидете на страницата на Kubernetes Engine в конзолата на Google Cloud Platform.
  2. Създайте или изберете проект.
  3. Изчакайте, докато API и свързаните услуги се активират. Това може да отнеме няколко минути.
  4. Уверете се, че за проекта Google Cloud Platform е настроено фактуриране. Научете как да активирате фактуриране.

В това ръководство можете да използвате Cloud Shell, който подготвя виртуална машина g1-small в Google Compute Engine с Linux на базата на Debian, или компютър с Linux или macOS.

Вариант А: използване на Cloud Shell

Предимства от използването на Cloud Shell:

  • Средите за разработка на Python 2 и Python 3 (включително virtualenv) са напълно конфигурирани.
  • Командни инструменти gcloud, docker, git и kubectl, които ще използваме, вече са инсталирани.
  • Имате на разположение няколко текстови редактора:
    1. Редактор на код, който се отваря с иконата на редактиране в горната част на прозореца Cloud Shell.
    2. Emacs, Vim или Nano, които се отварят от командния ред в Cloud Shell.

За да използвате Cloud Shell:

  1. Отидете в конзолата на GCP.
  2. Натиснете бутона Активирайте Cloud Shell (Активирайте Cloud Shell) в горната част на прозореца на конзолата GCP.

Подготовка на приложението за Istio

В долната част на конзолата GCP в нов прозорец ще се отвори сесия на Cloud Shell с команден ред.

Подготовка на приложението за Istio

Опция Б: използване на инструменти от командния ред локално

Ако работите на компютър с Linux или macOS, трябва да настроите и инсталирате следните компоненти:

  1. Настройте среда за разработка Python 3 и Python 2.

  2. Инсталирайте Cloud SDK с инструмента за команден ред gcloud.

  3. Инсталирайте kubectl — инструмент за команден ред за работа с Kubernetes.

    gcloud components install kubectl

  4. Инсталирайте Docker Community Edition (CE). Ще използвате инструмента за команден ред docker, за да създавате контейнерни образи за примерното приложение.

  5. Инсталирайте инструмента за контрол на версиите Git, за да получите примерното приложение от GitHub.

Изтегляне на примера с код

  1. Изтеглете изходния код helloserver:

    git clone https://github.com/GoogleCloudPlatform/istio-samples

  2. Преминете в директорията на примера с код:

    cd istio-samples/sample-apps/helloserver

Изучаване на приложението с множество услуги

Примерното приложение е написано на Python и се състои от два компонента, които взаимодействат чрез REST:

  • server: прост сървър с една крайна точка GET, /, който извежда "hello world" на конзолата.
  • loadgen: скрипт, който изпраща трафик на server, с настраиваем брой запитвания в секунда.

Подготовка на приложението за Istio

Стартиране на приложението от изходния код

За да изучите примерното приложение, стартирайте го в Cloud Shell или на компютъра си.
1) В директорията istio-samples/sample-apps/helloserver стартирайте server:

python3 server/server.py

При стартиране server се показва следното:

INFO:root:Стартиране на сървъра...

2) Отворете друг прозорец на терминала, за да изпращате запитвания към server. Ако използвате Cloud Shell, натиснете иконата за добавяне, за да отворите друга сесия.
3) Изпратете запитване към server:

curl http://localhost:8080

сървърът отговаря:

Hello World!

4) От директорията, където сте изтеглили примера с код, преминете в директорията, която съдържа loadgen:

cd YOUR_WORKING_DIRECTORY/istio-samples/sample-apps/helloserver/loadgen

5) Създайте следните променливи на средата:

export SERVER_ADDR=http://localhost:8080
export REQUESTS_PER_SECOND=5

6) Стартирайте virtualenv:

virtualenv --python python3 env

7) Активирайте виртуалната среда:

source env/bin/activate

8) Инсталирайте зависимостите за loadgen:

pip3 install -r requirements.txt

9) Стартирайте loadgen:

python3 loadgen.py

При стартиране loadgen извежда приблизително следното съобщение:

Стартиране на loadgen: 2019-05-20 10:44:12.448415
5 запитвания завършени към http://localhost:8080

В друг прозорец на терминала server извежда приблизително следните съобщения на конзолата:

127.0.0.1 - - [21/Jun/2019 14:22:01] "GET / HTTP/1.1" 200 -
INFO:root:GET запитване,
Път: /
Заглавия:
Хост: localhost:8080
User-Agent: python-requests/2.22.0
Accept-Encoding: gzip, deflate
Accept: */*

От гледна точка на мрежата, всичко приложение работи на един хост (локален компютър или виртуална машина Cloud Shell). Затова можете да използвате localhost, за да изпращате заявки към server.
10) За да спрете loadgen и server, въведете Ctrl-c във всяко терминално прозорец.
11) В терминалното прозорец loadgen деактивирайте виртуалната среда:

deactivate

Опаковане на приложението в контейнери

За да стартирате приложението на GKE, трябва да опаковате примерното приложение — server и loadgen — в контейнери. Контейнерът е начин да опаковате приложението, за да го изолирате от средата.

За да опаковате приложението в контейнер, ви е нужен Dockerfile. Dockerfile — това е текстов файл, в който се определят командите за компилиране на изходния код на приложението и неговите зависимости в Docker образ. След компилиране качвате образа в регистъра на контейнери, например Docker Hub или Container Registry.

В примера вече има Dockerfile за server и loadgen с всички необходими команди, за да се изградят образи. По-долу — Dockerfile за server:

FROM python:3-slim as base
FROM base as builder
RUN apt-get -qq update 
    && apt-get install -y --no-install-recommends 
        g++ 
    && rm -rf /var/lib/apt/lists/*

# Активиране на небуден лог
FROM base as final
ENV PYTHONUNBUFFERED=1

RUN apt-get -qq update 
    && apt-get install -y --no-install-recommends 
        wget

WORKDIR /helloserver

# Вземи пакети от строителя
COPY --from=builder /usr/local/lib/python3.7/ /usr/local/lib/python3.7/

# Добави приложението
COPY . .

EXPOSE 8080
ENTRYPOINT [ "python", "server.py" ]

  • Команда FROM python:3-slim as base принуждава Docker да използва последния образ Python 3 като базов.
  • Команда COPY. . копира изходните файлове в текущата работна директория (в нашия случай само server.py) в файловата система на контейнера.
  • ENTRYPOINT определя командата, която се използва за стартиране на контейнера. В нашия случай тази команда почти съвпада с тази, която използвахте за стартиране server.py от изходния код.
  • Команда EXPOSE указва, че server очаква данни през порта 8080. Тази команда не предоставя портове.. Това е нещо като документация, която е необходима, за да се отвори порт 8080 при стартиране на контейнера.

Подготовка за контейнеризация на приложението

1) Задайте следните променливи на средата. Заменете PROJECT_ID с идентификатора на вашия проект GCP.

export PROJECT_ID="PROJECT_ID"

export GCR_REPO="preparing-istio"

С помощта на стойностите PROJECT_ID и GCR_REPO отбелязвате Docker образа, когато го изграждате и изпращате в частен Container Registry.

2) Задайте проекта GCP по подразбиране за инструмента за команден ред gcloud.

gcloud config set project $PROJECT_ID

3) Задайте зоната по подразбиране за инструмента за команден ред gcloud.

gcloud config set compute/zone us-central1-b

4) Уверете се, че услугата Container Registry е включена в проекта GCP.

gcloud services enable containerregistry.googleapis.com

Контейнеризация на сървъра

  1. Преминете в директорията, където се намира примера server:

    cd YOUR_WORKING_DIRECTORY/istio-samples/sample-apps/helloserver/server/

  2. Създайте образ с помощта на Dockerfile и променливите на средата, които сте определили по-рано:

    docker build -t gcr.io/$PROJECT_ID/$GCR_REPO/helloserver:v0.0.1 .

Параметър -t представлява Docker таг. Това е името на образа, който използвате при разгръщането на контейнера.

  1. Изпратете образа в Container Registry:
    docker push gcr.io/$PROJECT_ID/$GCR_REPO/helloserver:v0.0.1

Контейнеризация на loadgen

1) Преминете в директорията, където се намира примера loadgen:

cd ../loadgen

2) Създайте образа:

docker build -t gcr.io/$PROJECT_ID/$GCR_REPO/loadgen:v0.0.1 .

3) Изпратете образа в Container Registry:

docker push gcr.io/$PROJECT_ID/$GCR_REPO/loadgen:v0.0.1

Преглед на списъка с образи

Прегледайте списъка с образи в репозитория и се уверете, че образите са изпратени:

gcloud container images list --repository gcr.io/$PROJECT_ID/preparing-istio

Командата дава имената на току-що изпратените образи:

NAME
gcr.io/PROJECT_ID/preparing-istio/helloserver
gcr.io/PROJECT_ID/preparing-istio/loadgen

Създаване на GKE клъстер.

Тези контейнери могат да се стартират на виртуална машина Cloud Shell или на компютър с помощта на docker run. Но в производствена среда е необходим начин за централизирано оркестриране на контейнерите. Например, нужна е система, която следи дали контейнерите винаги работят, и е нужен начин за мащабиране и стартиране на допълнителни инстанции на контейнери, ако трафикът се увеличи.

За стартиране на контейнерни приложения може да се използва GKE. GKE е платформа за оркестрация на контейнери, която комбинира виртуални машини в клъстер. Всяка виртуална машина се нарича възел. GKE клъстерите са базирани на опенсорс система за управление на клъстери Kubernetes. Kubernetes предоставя механизми за взаимодействие с клъстера.

Създаване на GKE клъстер:

1) Създайте клъстер:

gcloud container clusters create istioready 
  --cluster-version latest 
  --machine-type=n1-standard-2 
  --num-nodes 4

Команда gcloud създава клъстер istioready в GCP проекта и зоната по подразбиране, които сте посочили. За стартиране на Istio, препоръчваме поне 4 възела и виртуална машина n1-standard-2.

Командата създава клъстер за няколко минути. Когато клъстерът е готов, командата дава подобно съобщението.

2) Укажете идентификационните данни в инструмента за команден ред kubectl, за да управлявате клъстера:

gcloud container clusters get-credentials istioready

3) Сега можете да взаимодействате с Kubernetes чрез kubectl. Например, с помощта на следната команда можете да проверите статуса на възлите:

kubectl get nodes

Командата дава списък на възлите:

ИМЕ                                       СТАТУС   РОЛИ    ВЪЗРАСТ    ВЕРСИЯ
gke-istoready-default-pool-dbeb23dc-1vg0   Готов    <none>   99с    v1.13.6-gke.13
gke-istoready-default-pool-dbeb23dc-36z5   Готов    <none>   100с   v1.13.6-gke.13
gke-istoready-default-pool-dbeb23dc-fj7s   Готов    <none>   99с    v1.13.6-gke.13
gke-istoready-default-pool-dbeb23dc-wbjw   Готов    <none>   99с    v1.13.6-gke.13

Ключови понятия на Kubernetes

Схемата показва приложение на GKE:

Подготовка на приложението за Istio

Преди да развернете контейнери в GKE, изучете ключовите понятия на Kubernetes. В края можете да намерите връзки, ако искате да научите повече.

  • Възли и клъстери. В GKE възелът е виртуална машина. На други платформи Kubernetes възел може да бъде компютър или виртуална машина. Клъстерът е набор от възли, които можете да разглеждате като едно цяло и където разпъвате контейнеризирано приложение.
  • Pod’и. В Kubernetes контейнерите се стартират в pod’и. Pod в Kubernetes е неделима единица. Pod съдържа един или няколко контейнера. Разпъвате контейнерите server и loadgen в отделни pod’и. Когато в pod’а има няколко контейнера (например, сървър на приложението и прокси сървър), контейнерите се управляват като един обект и споделят ресурсите на pod’а.
  • Разпределения. В Kubernetes разпределение е обект, представляващ набор от идентични pod’и. Разпределението стартира няколко реплики на pod’и, разпределени по възлите на клъстера. Разпределението автоматично заменя pod’ите, които са се провалили или не отговарят.
  • Сервис Kubernetes. Когато стартирате кода на приложението в GKE, се променя свързването между loadgen и server. Когато сте стартирали услуги на виртуалната машина Cloud Shell или на компютър, сте изпращали запитвания до server на адрес localhost:8080. След разполагането в GKE, pod’ите работят на наличните възли. По подразбиране не можете да управлявате на кой възел е стартиран pod, така че pod’ите нямат постоянни IP адреси.
    За да получите IP адрес за server, трябва да определите абстракция на мрежата над pod’ите. Това е сервис Kubernetes. Сервис Kubernetes предоставя постоянна крайна точка за набор от pod’и. Има няколко вида услуги. server използва LoadBalancer, който предоставя външен IP адрес, за да се свърже с server отвън на клъстера.
    В Kubernetes също така има вградена система DNS, която назначава DNS имена (например, helloserver.default.cluster.local) услугите. Благодаря на това pod’ите в кластера са свързани с другите pod’и в кластера с постоянен адрес. DNS името не може да се използва извън кластера, например в Cloud Shell или на компютъра.

Манифести на Kubernetes

Когато стартирахте приложението от изходния код, използвахте императивна команда python3

server.py

Императивността предполага глагол: „направи това“.

Kubernetes използва декларативен модел. Това означава, че не казваме на Kubernetes какво точно да прави, а описваме желаното състояние. Например, Kubernetes стартира и спира pod’и при необходимост, за да съответства действителното състояние на системата на желаното.

Желаното състояние указвате в манифестите или файловете YAML. YAML файлът съдържа спецификации за един или повече Kubernetes обекти.

В примера е включен YAML файл за server и loadgen. Всеки YAML файл указва желаното състояние на обекта на разгръщане и услугата на Kubernetes.

server.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: helloserver
spec:
  selector:
    matchLabels:
      app: helloserver
  replicas: 1
  template:
    metadata:
      labels:
        app: helloserver
    spec:
      terminationGracePeriodSeconds: 5
      restartPolicy: Always
      containers:
      - name: main
        image: gcr.io/google-samples/istio/helloserver:v0.0.1
        imagePullPolicy: Always

  • kind указва типа на обекта.
  • metadata.name указва името на разгръщането.
  • Първото поле spec съдържа описание на желаното състояние.
  • spec.replicas указва желаното количество pod’и.
  • Дял spec.template определя шаблона на pod’а. В спецификацията на pod’ите има поле изображение, където се указва името на образа, който трябва да бъде изтеглен от Container Registry.

Услугата се определя по следния начин:

apiVersion: v1
kind: Service
metadata:
  name: hellosvc
spec:
  type: LoadBalancer
  selector:
    app: helloserver
  ports:
  - name: http
    port: 80
    targetPort: 8080

  • LoadBalancer: клиентите изпращат заявки до IP адреса на балансировача на натоварването, който има постоянен IP адрес и е достъпен извън кластера.
  • targetPort: както помните, командата EXPOSE 8080 в Dockerfile не предостави портове. Вие предоставяте порт 8080, за да може да се свърже с контейнера server извън кластера. В нашия случай hellosvc.default.cluster.local:80 (кратко име: hellosvc) съответства на порта 8080 IP адреса на pod’а helloserver.
  • port: това е номерът на порта, на който останалите услуги в кластера ще изпращат заявки.

loadgen.yaml

Обектът на разгръщане в loadgen.yaml е подобен на server.yaml. Разликата е, че обектът на разгръщане съдържа секция env. Тя определя променливите на средата, от които се нуждаете loadgen и които установихте при стартиране на приложението от изходния код.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: loadgenerator
spec:
  selector:
    matchLabels:
      app: loadgenerator
  replicas: 1
  template:
    metadata:
      labels:
        app: loadgenerator
    spec:
      terminationGracePeriodSeconds: 5
      restartPolicy: Always
      containers:
      - name: main
        image: gcr.io/google-samples/istio/loadgen:v0.0.1
        imagePullPolicy: Always
        env:
        - name: SERVER_ADDR
          value: "http://hellosvc:80/"
        - name: REQUESTS_PER_SECOND
          value: "10"
        resources:
          requests:
            cpu: 300m
            memory: 256Mi
          limits:
            cpu: 500m
            memory: 512Mi

Едно loadgen не приема входящи заявки, за полето тип посочено ClusterIP. Този тип предоставя постоянен IP адрес, който могат да използват услугите в клъстера, но този IP адрес не е достъпен за външни клиенти.

apiVersion: v1
kind: Service
metadata:
  name: loadgensvc
spec:
  type: ClusterIP
  selector:
    app: loadgenerator
  ports:
  - name: http
    port: 80
    targetPort: 8080

Разгръщане на контейнери в GKE

1) Преминете в директорията, където се намира примера server:

cd YOUR_WORKING_DIRECTORY/istio-samples/sample-apps/helloserver/server/

2) Отворете server.yaml в текстов редактор.
3) Заменете името в полето изображение с името на вашия Docker образ.

image: gcr.io/PROJECT_ID/preparing-istio/helloserver:v0.0.1

Заменете PROJECT_ID с идентификатора на вашия проект GCP.
4) Запазете и затворете server.yaml.
5) Разгърнете YAML файла в Kubernetes:

kubectl apply -f server.yaml

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

deployment.apps/helloserver created
service/hellosvc created

6) Отидете в директорията, където се намира loadgen:

cd ../loadgen

7) Отворете loadgen.yaml в текстов редактор.
8) Заменете името в полето изображение с името на вашия Docker образ.

image: gcr.io/PROJECT_ID/preparing-istio/loadgenv0.0.1

Заменете PROJECT_ID с идентификатора на вашия проект GCP.
9) Запазете и затворете loadgen.yaml, затворете текстовия редактор.
10) Разгърнете YAML файла в Kubernetes:

kubectl apply -f loadgen.yaml

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

deployment.apps/loadgenerator created
service/loadgensvc created

11) Проверете статуса на подовете:

kubectl get pods

Командата показва статуса:

NAME                             READY   STATUS    RESTARTS   AGE
helloserver-69b9576d96-mwtcj     1/1     Running   0          58s
loadgenerator-774dbc46fb-gpbrz   1/1     Running   0          57s

12) Изтеглете логовете на приложението от пода loadgen. Заменете POD_ID с идентификатора от предишния отговор.

kubectl logs loadgenerator-POD_ID

13) Получете външните IP адреси hellosvc:

kubectl get service

Отговорът на командата изглежда приблизително така:

NAME         TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)        AGE
hellosvc     LoadBalancer   10.81.15.158   192.0.2.1       80:31127/TCP   33m
kubernetes   ClusterIP      10.81.0.1                443/TCP        93m
loadgensvc   ClusterIP      10.81.15.155             80/TCP         4m52s

14) Изпратете заявка до hellosvc: заменете EXTERNAL_IP с външния IP адрес hellosvc.

curl http://EXTERNAL_IP

Започваме с Istio

Вече имате приложение, разгръщено в GKE. loadgen можете да използвате Kubernetes DNS (hellosvc:80), за да изпращате заявки до server, и можете да изпращате заявки до server чрез външния IP адрес. Въпреки че Kubernetes предлага много функции, липсва информация за услугите:

  • Как взаимодействат услугите? Какви са отношенията между услугите? Как тече трафикът между услугите? Вие сте наясно, че loadgen изпраща заявки към server, но представете си, че не знаете нищо за приложението. За да отговорим на тези въпроси, разглеждаме списъка с активирани контейнери в GKE.
  • Метрики. Колко време server отговаря на входяща заявка? Колко заявки в секунда получава server? Издава ли съобщения за грешки?
  • Информация за сигурността. Трафикът между loadgen и server преминава просто по HTTP или по mTLS?

На всички тези въпроси отговаря Istio. За целта Istio поставя sidecar прокси Envoy в всеки pod. Прокси Envoy прихваща целия входящ и изходящ трафик към контейнерите на приложението. Това означава, че server и loadgen получават през sidecar прокси Envoy и целият трафик от loadgen к server преминава през прокси Envoy.

Връзките между прокси Envoy образуват service mesh. Архитектурата на service mesh предоставя ниво на контрол над Kubernetes.

Подготовка на приложението за Istio

Тъй като прокси Envoy работят в собствените си контейнери, Istio може да бъде инсталиран върху клъстера GKE, почти без да променя кода на приложението. Но вие сте извършили известна работа, за да подготвите приложението за управление чрез Istio:

  • Услуги за всички контейнери. Към разполагането server и loadgen е прикрепена по една услуга на Kubernetes. Дори loadgen, към която не постъпват входящи заявки, има услуга.
  • Портовете в услугите трябва да имат имена. Въпреки че в GKE портовете на услугите могат да остават без име, Istio изисква да се укаже име на порта в съответствие с неговия протокол. В YAML файла портът за server наричан http, защото server използва протокол HTTP. Ако service използва gRPC, вие ще наречете порта grpc.
  • Разполаганията са маркирани. Затова можете да използвате функцията за управление на трафика на Istio, например да разделяте трафика между версии на една услуга.

Инсталиране на Istio

Istio може да бъде инсталиран по два начина. Можете да включите разширението Istio on GKE или или да инсталирате опенсорс версията на Istio в клъстера. С Istio on GKE е лесно да управлявате инсталацията и ъпгрейда на Istio в рамките на жизнения цикъл на клъстера GKE. Ако ви е необходима най-новата версия на Istio или повече контрол над конфигурацията на контролния панел на Istio, инсталирайте опенсорс версия вместо разширението Istio on GKE. За да се определи подходът, прочетете статията Нужен ли ми е Istio on GKE?.

Изберете опция, проучете съответното ръководство и следвайте инструкциите, за да инсталирате Istio в клъстера. Ако искате да използвате Istio с току-що разположено приложение, включете внедряването на sidecar-ове за пространство имена default.

Деинсталиране

За да не се начислява такса за ресурсите, които сте използвали в това ръководство, моля, изтрийте клъстера с контейнери, след като инсталирате Istio и изиграете примера на приложението. По този начин ще бъдат изтрито всички ресурси на клъстера, например изчислителни инстанции, дискове и мрежови ресурси.

Какво следва?

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

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