
Istio – це зручний інструмент для з'єднання, захисту та моніторингу розподілених програм. В Istio використовуються різні технології для масштабного запуску ПЗ та управління ним, включаючи контейнери для пакування коду програми та залежностей для розгортання та Kubernetes – для управління цими контейнерами. Тому для роботи з Istio ви повинні знати, як програма з кількома сервісами на основі цих технологій працює без Істіо. Якщо ці інструменти та поняття вам вже знайомі, сміливо пропускайте цей посібник і переходьте прямо до розділу або встановлення розширення .
Це покрокове керівництво, де ми розглянемо весь процес від вихідного коду до контейнера на GKE, щоб ви отримали базове уявлення про ці технології на прикладі. Також ви побачите, як Istio використовує можливості цих технологій. Передбачається, що ви не знаєте нічого про контейнери, Kubernetes, Service Mesh або Istio.
Завдання
У цьому посібнику виконайте такі завдання:
- Вивчення простої програми hello world з кількома службами.
- Запуск програми з вихідного коду.
- Упаковка програми в контейнери.
- Створення кластера Kubernetes.
- Розгортання контейнерів у кластер.
Перш ніж почати
Виконайте інструкції, щоб увімкнути Kubernetes Engine API:
- Зайдіть на у консолі Google Cloud Platform.
- Створіть або виберіть проект.
- Зачекайте, поки увімкнеться API та пов'язані служби. Це може тривати кілька хвилин.
- Переконайтеся, що для Google Cloud Platform виставлено рахунки. .
У цьому посібнику можна використовувати Cloud Shell, який готує віртуальну машину с Linux на основі Debian, або комп'ютер на Linux або macOS.
Варіант А: використання Cloud Shell
Переваги використання Cloud Shell:
- Середовищ розробки Python 2 і Python 3 (включаючи virtualenv) повністю налаштовані.
- Інструменти командного рядка gcloud, Докер, мерзотник и кубектл, які ми будемо використовувати вже встановлено.
- У вас на вибір кілька :
- , який відкривається значком редагування у верхній частині вікна Cloud Shell.
- Emacs, Vim або Nano, які відкриваються з командного рядка у Cloud Shell.
щоб використовувати :
- Перейдіть до консолі GCP.
- Натисніть кнопку Activate Cloud Shell (Активувати Cloud Shell) у верхній частині вікна консолі GCP.
![]()
У нижній частині у новому вікні відкриється сеанс Cloud Shell із командним рядком.

Варіант Б: використання інструментів командного рядка локально
Якщо ви будете працювати на комп'ютері з Linux або macOS, потрібно налаштувати та встановити наступні компоненти:
Налаштуйте .
з інструментом командного рядка gcloud.
Встановіть кубектл - Інструмент командного рядка для роботи з .
gcloud components install kubectlВстановіть . Ви будете використовувати інструмент командного рядка Докер, щоб створювати образи контейнерів для прикладу програми.
Встановіть інструмент , щоб отримати приклад програми з GitHub.
Завантаження прикладу коду
Завантажте вихідний код helloserver:
git clone https://github.com/GoogleCloudPlatform/istio-samplesПерейдіть до каталогу прикладу коду:
cd istio-samples/sample-apps/helloserver
Вивчення програми з кількома сервісами
Приклад програми написано на Python і складається з двох компонентів, які взаємодіють за допомогою :
- сервер: простий сервер з однією кінцевою точкою GET, /, що виводить «hello world» на консолі.
- loadgen: скрипт, який посилає трафік на сервер, з числом запитів, що налаштовується в секунду.

Запуск програми з вихідного коду
Щоб вивчити приклад програми, запустіть її в Cloud Shell або на комп'ютері.
1) У каталозі istio-samples/sample-apps/helloserver запустіть сервер:
python3 server/server.pyПри запуску сервер відображається таке:
INFO:root:Starting server...2) Відкрийте інше вікно терміналу, щоб надсилати запити до сервер. Якщо ви використовуєте Cloud Shell, натисніть значок додавання, щоб відкрити інший сеанс.
3) Надішліть запит до сервер:
curl http://localhost:8080server відповідає:
Hello World!4) З каталогу, куди ви завантажили приклад коду, перейдіть до каталогу, який містить loadgen:
cd YOUR_WORKING_DIRECTORY/istio-samples/sample-apps/helloserver/loadgen5) Створіть такі змінні середовища:
export SERVER_ADDR=http://localhost:8080
export REQUESTS_PER_SECOND=56) Запустіть virtualenv:
virtualenv --python python3 env7) Активуйте віртуальне середовище:
source env/bin/activate8) Встановіть вимоги для loadgen:
pip3 install -r requirements.txt9) Запустіть 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 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 використовувати останній як базовий.
- Команда 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_ID3) Встановіть стандартну зону для інструменту командного рядка. gcloud.
gcloud config set compute/zone us-central1-b4) Переконайтеся, що сервіс Container Registry увімкнений у проекті GCP.
gcloud services enable containerregistry.googleapis.comКонтейнеризація server
Перейдіть до каталогу, де є приклад сервер:
cd YOUR_WORKING_DIRECTORY/istio-samples/sample-apps/helloserver/server/Зберіть образ за допомогою Докер-файл та змінних середовища, які ви визначили раніше:
docker build -t gcr.io/$PROJECT_ID/$GCR_REPO/helloserver:v0.0.1 .
Параметр -t представляє тег Docker. Це ім'я образу, який ви використовуєте під час розгортання контейнера.
- Надішліть образ у Container Registry:
docker push gcr.io/$PROJECT_ID/$GCR_REPO/helloserver:v0.0.1
Контейнеризація loadgen
1) Перейдіть до каталогу, де є приклад loadgen:
cd ../loadgen2) Зберіть образ:
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 базуються на опенсорс-системі управління кластерами 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 вузли та віртуальну машину .
Команда створює кластер кілька хвилин. Коли кластер буде готовий, команда видає таке. .
2) Вкажіть облікові дані в інструменті командного рядка , щоб з її допомогою керувати кластером:
gcloud container clusters get-credentials istioready3) Тепер можна спілкуватися з 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:

Перш ніж розгорнути контейнери в 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, так що у немає постійних IP-адрес.
Щоб отримати IP-адресу для серверпотрібно визначити абстракцію мережі поверх pod'ів. Це і є . Сервіс 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 created6) Перейдіть до каталогу, де знаходиться loadgen:
cd ../loadgen7) Відкрийте 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 created11) Перевірте статус подів:
kubectl get podsКоманда показує статус:
NAME READY STATUS RESTARTS AGE
helloserver-69b9576d96-mwtcj 1/1 Running 0 58s
loadgenerator-774dbc46fb-gpbrz 1/1 Running 0 57s12) Вийміть логи програми з пода loadgen. Замініть POD_ID на ідентифікатор із попередньої відповіді.
kubectl logs loadgenerator-POD_ID13) Отримайте зовнішні 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 4m52s14) Надішліть запит до hellosvc: замініть EXTERNAL_IP на зовнішню IP-адресу hellosvc.
curl http://EXTERNAL_IPБеремося за Istio
У вас вже є програма, розгорнута в GKE. loadgen може використовувати Kubernetes DNS (hellosvc:80), щоб надсилати запити до сервер, і ви можете надсилати запити до сервер за зовнішньою IP-адресою. Хоча у Kubernetes багато можливостей, деякої інформації про сервіси не вистачає:
- Як взаємодіють послуги? Які стосунки між сервісами? Як відбувається трафік між сервісами? Ви в курсі, що loadgen надсилає запити до сервер, але уявіть, що ви нічого не знаєте про програму. Щоб відповісти на ці запитання, дивимося на список запущених подів у GKE.
- Метрики. Як довго сервер відповідає на запит? Скільки запитів за секунду надходить на server? Він видає повідомлення про помилки?
- Відомості про безпеку. Трафік між loadgen и сервер проходить просто по HTTP або по ?
На ці запитання відповідає Istio. Для цього Istio поміщає sidecar-проксі у кожний pod. Проксі Envoy перехоплює весь вхідний та вихідний трафік до контейнерів програми. Це означає, що сервер и loadgen отримують по sidecar-проксі Envoy, і весь трафік від loadgen к сервер проходить через проксі Envoy.
З'єднання між проксі Envoy утворюють service mesh. Архітектура service mesh надає рівень контролю над Kubernetes.

Якщо проксі Envoy виконуються у своїх контейнерах, Istio можна встановити поверх кластера GKE, майже не змінюючи код програми. Але ви проробили деяку роботу, щоб підготувати додаток до управління за допомогою Istio:
- Сервіси для контейнерів. До розгортань сервер и loadgen прив'язано за сервісом Kubernetes. Навіть у loadgen, якого не надходять вхідні запити, є сервіс.
- У портів у сервісах мають бути імена. Хоча GKE порти сервісів можна залишати без імені, Istio вимагає вказати відповідно до його протоколу. У файлі YAML порт для сервер називається HTTP, тому що сервер використовує протокол HTTP. Якби обслуговування використовував gRPC, ви б назвали порт grpc.
- Розгортання позначаються. Тому можна використовувати функції керування трафіком Istio, наприклад розділяти трафік між версіями одного сервісу.
Встановлення Istio
Встановити Istio можна двома способами. Можна, можливо або на кластері. З Istio on GKE можна легко керувати установкою та апгрейдом Istio у рамках життєвого циклу кластера GKE. Якщо вам потрібна найновіша версія Istio або більше контролю за конфігурацією панелі керування Istio, встановіть опенсорс-версію замість розширення Istio on GKE. Щоб визначитись із підходом, читайте статтю .
Виберіть варіант, вивчіть відповідний посібник та дотримуйтесь інструкцій, щоб встановити Istio на кластері. Якщо ви хочете використовувати Istio з щойно розгорнутим додатком, для простору імен дефолт.
очищення
Щоб з облікового запису Google Cloud Platform не списувалась плата за ресурси, які ви використовували в цьому посібнику, видаліть кластер контейнера, коли встановите Istio та награєтеся з прикладом програми. При цьому будуть видалені всі ресурси кластера, наприклад, обчислювальні екземпляри, диски та мережні ресурси.
Що далі?
Вивчіть такі технології:
Вивчіть наступні інструменти:
Вивчіть поняття Kubernetes:
Джерело: habr.com
