Підготовка програми для Istio

Підготовка програми для Istio

Istio – це зручний інструмент для з'єднання, захисту та моніторингу розподілених програм. В Istio використовуються різні технології для масштабного запуску ПЗ та управління ним, включаючи контейнери для пакування коду програми та залежностей для розгортання та Kubernetes – для управління цими контейнерами. Тому для роботи з Istio ви повинні знати, як програма з кількома сервісами на основі цих технологій працює без Істіо. Якщо ці інструменти та поняття вам вже знайомі, сміливо пропускайте цей посібник і переходьте прямо до розділу Встановлення Istio на Google Kubernetes Engine (GKE) або встановлення розширення Istio on 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, Докер, мерзотник и кубектл, які ми будемо використовувати вже встановлено.
  • У вас на вибір кілька текстових редакторів:
    1. Редактор коду, який відкривається значком редагування у верхній частині вікна Cloud Shell.
    2. Emacs, Vim або Nano, які відкриваються з командного рядка у Cloud Shell.

щоб використовувати Хмарна оболонка:

  1. Перейдіть до консолі GCP.
  2. Натисніть кнопку Activate Cloud Shell (Активувати Cloud Shell) у верхній частині вікна консолі GCP.

Підготовка програми для Istio

У нижній частині консолі GCP у новому вікні відкриється сеанс Cloud Shell із командним рядком.

Підготовка програми для Istio

Варіант Б: використання інструментів командного рядка локально

Якщо ви будете працювати на комп'ютері з Linux або macOS, потрібно налаштувати та встановити такі компоненти:

  1. Налаштуйте середовище розробки Python 3 та Python 2.

  2. Встановіть Cloud SDK з інструментом командного рядка gcloud.

  3. Встановіть кубектл - Інструмент командного рядка для роботи з Кубернетес.

    gcloud components install kubectl

  4. Встановіть Docker Community Edition (CE). Ви будете використовувати інструмент командного рядка Докер, щоб створювати образи контейнерів для прикладу програми.

  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:Starting server...

2) Відкрийте інше вікно терміналу, щоб надсилати запити до сервер. Якщо ви використовуєте Cloud Shell, натисніть значок додавання, щоб відкрити інший сеанс.
3) Надішліть запит до сервер:

curl http://localhost:8080

server відповідає:

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 виводить приблизно таке повідомлення:

Starting loadgen: 2019-05-20 10:44:12.448415
5 request(s) complete to http://localhost:8080

В іншому вікні терміналу сервер виводить на консоль приблизно такі повідомлення:

127.0.0.1 - - [21/Jun/2019 14:22:01] "GET / HTTP/1.1" 200 -
INFO:root:GET request,
Path: /
Headers:
Host: localhost:8080
User-Agent: python-requests/2.22.0
Accept-Encoding: gzip, deflate
Accept: */*

З точки зору мережі, вся програма працює на одному хості (локальному комп'ютері або віртуальній машині Cloud Shell). Тому можна використовувати локальний, щоб надсилати запити сервер.
10) Щоб зупинити loadgen и сервер, введіть Ctrl-c у кожному вікні терміналу.
11) У вікні терміналу loadgen деактивуйте віртуальне середовище:

deactivate

Упаковка програми у контейнери

Щоб запустити програму на GKE, потрібно запакувати приклад програми — сервер и loadgen - У контейнери. Контейнер — це спосіб запакувати програму, щоб ізолювати її від середовища.

Щоб запакувати додаток у контейнер, потрібен Докер-файл. Докер-файл — це текстовий файл, де визначаються команди для збирання вихідного коду програми та її залежностей зображення Docker. Після складання ви завантажуєте образ до реєстру контейнерів, наприклад Docker Hub або Реєстр контейнерів.

У прикладі вже є Докер-файл для сервер и loadgen зі всіма потрібними командами, щоб зібрати образи. Нижче Докер-файл для сервер:

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) у файлову систему контейнера.
  • ТОЧКА ВХОДУ визначає команду, яка використовується для запуску контейнера У нашому випадку ця команда майже збігається з тією, яку ви використовували для запуску server.py із вихідного коду.
  • Команда ВИКРИТИ вказує, що сервер очікує дані через порт 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

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

  1. Перейдіть до каталогу, де є приклад сервер:

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

  2. Зберіть образ за допомогою Докер-файл та змінних середовища, які ви визначили раніше:

    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 або на комп'ютері командою докер-біг. Але у виробничому середовищі необхідний метод централізовано оркеструвати контейнери. Наприклад, потрібна система, яка стежить, щоб контейнери завжди працювали, і потрібен спосіб збільшувати масштаб і запускати додаткові екземпляри контейнерів, якщо трафік зросте.

Для запуску контейнерних програм можна використовувати 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-стандарт-2.

Команда створює кластер кілька хвилин. Коли кластер буде готовий, команда видає таке. повідомлення.

2) Вкажіть облікові дані в інструменті командного рядка кубектл, щоб з її допомогою керувати кластером:

gcloud container clusters get-credentials istioready

3) Тепер можна спілкуватися з Kubernetes через кубектл. Наприклад, наступною командою можна дізнатися про статус вузлів:

kubectl get nodes

Команда видає список вузлів:

NAME                                       STATUS   ROLES    AGE    VERSION
gke-istoready-default-pool-dbeb23dc-1vg0   Ready    <none>   99s    v1.13.6-gke.13
gke-istoready-default-pool-dbeb23dc-36z5   Ready    <none>   100s   v1.13.6-gke.13
gke-istoready-default-pool-dbeb23dc-fj7s   Ready    <none>   99s    v1.13.6-gke.13
gke-istoready-default-pool-dbeb23dc-wbjw   Ready    <none>   99s    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'и, які відмовили чи не відповідають.
  • Сервіс Оцінка: XNUMX 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 містить специфікації для одного або кількох об'єктів 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

  • вид вказує тип об'єкта.
  • 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: як ви пам'ятаєте, команда ВИКЛИТИ 8080 в Докер-файл не надавала портів. Ви надаєте порт 8080щоб можна було зв'язатися з контейнером сервер зовні кластера. У нашому випадку hellosvc.default.cluster.local:80 (коротке ім'я: hellosvc) відповідає порту 8080 IP-адреси пода helloserver.
  • порт: це номер порту, куди інші послуги в кластері будуть надсилати запити.

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) Замініть ім'я у полі зображення на ім'я вашого образу 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      <none>          443/TCP        93m
loadgensvc   ClusterIP      10.81.15.155   <none>          80/TCP         4m52s

14) Надішліть запит до hellosvc: замініть EXTERNAL_IP на зовнішню IP-адресу hellosvc.

curl http://EXTERNAL_IP

Беремося за Istio

У вас вже є програма, розгорнута в GKE. loadgen може використовувати Kubernetes DNS (hellosvc:80), щоб надсилати запити до сервер, і ви можете надсилати запити до сервер за зовнішньою IP-адресою. Хоча у Kubernetes багато можливостей, деякої інформації про сервіси не вистачає:

  • Як взаємодіють послуги? Які стосунки між сервісами? Як відбувається трафік між сервісами? Ви в курсі, що loadgen надсилає запити до сервер, але уявіть, що ви нічого не знаєте про програму. Щоб відповісти на ці запитання, дивимося на список запущених подів у GKE.
  • Метрики. Як довго сервер відповідає на запит? Скільки запитів за секунду надходить на server? Він видає повідомлення про помилки?
  • Відомості про безпеку. Трафік між loadgen и сервер проходить просто по HTTP або по mTLS?

На ці запитання відповідає Istio. Для цього Istio поміщає sidecar-проксі Посланець у кожний 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. Якби обслуговування використовував 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

Додати коментар або відгук