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

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

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

  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:

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

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

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

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

python3 server/server.py

При стартиране сървер появява се следното:

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

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

curl http://localhost:8080

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

Здравей, свят!

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

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

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

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

deactivate

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

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

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

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

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/*

# Enable unbuffered logging
FROM base as final
ENV PYTHONUNBUFFERED=1

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

WORKDIR /helloserver

# Grab packages from builder
COPY --from=builder /usr/local/lib/python3.7/ /usr/local/lib/python3.7/

# Add the application
COPY . .

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

  • Екип FROM python:3-slim as base разрешава на Docker да използва последния образ Python 3 като базов.
  • Екип COPY . . копира изходните файлове в текущия работен каталог (в нашия случай само server.py) в файловата система на контейнера.
  • ENTRYPOINT определя командата, която се използва за стартиране на контейнера. В нашия случай тази команда почти съвпада с тази, която сте използвали за стартиране server.py от изходния код.
  • Екип EXPOSE означава, че сървер очаква данни през порт 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. Отидете в директорията, където се намира примерът сървер:

    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 проекта и зоната по подразбиране, които сте посочили. Препоръчваме да имате поне 4 възела и виртуална машина, за да стартирате Istio. n1-standard-2.

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

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

gcloud container clusters get-credentials istioready

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

kubectl get nodes

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

ИМЯ                                       СТАТУС   РОЛИ    ВОЗРАСТ    ВЕРСИЯ
gke-istoready-default-pool-dbeb23dc-1vg0   Готово    <нет>   99с    v1.13.6-gke.13
gke-istoready-default-pool-dbeb23dc-36z5   Готово    <нет>   100с   v1.13.6-gke.13
gke-istoready-default-pool-dbeb23dc-fj7s   Готово    <нет>   99с    v1.13.6-gke.13
gke-istoready-default-pool-dbeb23dc-wbjw   Готово    <нет>   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 и сървер. Когато сте стартирали услуги на виртуална машина Cloud Shell или на компютър, сте изпращали заявки към сървер на адрес localhost:8080. След разгръщането в GKE pod’овете работят на наличните възли. По подразбиране не можете да управлявате на кой възел е стартиран pod, така че няма pod'и постоянни IP адреси.
    За да получите IP адрес за сървер, трябва да определите абстракция на мрежата над pod’овете. Това е Kubernetes сервиз.Kubernetes Сервизът предоставя постоянна крайна точка за набор от pod’ове. Има няколко типа сервизи,. сървер използва LoadBalancer, който предоставя външен IP адрес, за да се свърже с сървер отвън на клъстера.
    Освен това в Kubernetes има вградена система DNS, която присвоява имена DNS (например, helloserver.default.cluster.local) на услуги. Благодарение на това pod’ите вътре в клъстера се свързват с другите pod’и в клъстера чрез постоянен адрес. Името на DNS не може да се използва извън клъстера, например в Cloud Shell или на компютъра.

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

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

server.py

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

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

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

В примера се съдържа YAML файл за сървер и 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’ите има поле image, където се указва името на образа, който трябва да бъде извлечен от 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, за да може да се свържете с контейнера сървер отвън на клъстера. В нашия случай hellosvc.default.cluster.local:80 (кратко име: hellosvc) съответства на порта 8080 IP адреса на pod’a 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) Отидете в директорията, където се намира примера сървер:

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

2) Отворете server.yaml в текстов редактор.
3) Заменете името в полето image с името на вашия 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) Заменете името в полето image с името на вашия 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), за да изпраща заявки до сървер, а вие можете да изпращате заявки до сървер по външния IP адрес. Въпреки че Kubernetes има много възможности, липсва информация за услугите:

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

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

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

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

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

  • Услуги за всички контейнери. Към разгръщанията сървер и loadgen е привързан по един сервис Kubernetes. Дори и loadgen, към който не постъпват входящи заявки, има сервис.
  • Портовете в услугите трябва да имат имена. Въпреки че в GKE портовете на услугите могат да останат без име, Istio изисква да посочите името на порта според протокола му. В YAML файла портът за сървер нарича се http, тъй като сървърът използва протокола 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’ове за пространството на имената по подразбиране.

Изчистване

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

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

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

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