Istio – це зручний інструмент для з'єднання, захисту та моніторингу розподілених програм. В Istio використовуються різні технології для масштабного запуску ПЗ та управління ним, включаючи контейнери для пакування коду програми та залежностей для розгортання та Kubernetes – для управління цими контейнерами. Тому для роботи з Istio ви повинні знати, як програма з кількома сервісами на основі цих технологій працює без Істіо. Якщо ці інструменти та поняття вам вже знайомі, сміливо пропускайте цей посібник і переходьте прямо до розділу Встановлення Istio на Google Kubernetes Engine (GKE) або встановлення розширення Istio on GKE.
Це покрокове керівництво, де ми розглянемо весь процес від вихідного коду до контейнера на GKE, щоб ви отримали базове уявлення про ці технології на прикладі. Також ви побачите, як Istio використовує можливості цих технологій. Передбачається, що ви не знаєте нічого про контейнери, Kubernetes, Service Mesh або Istio.
Завдання
У цьому посібнику виконайте такі завдання:
Вивчення простої програми hello world з кількома службами.
Запуск програми з вихідного коду.
Упаковка програми в контейнери.
Створення кластера Kubernetes.
Розгортання контейнерів у кластер.
Перш ніж почати
Виконайте інструкції, щоб увімкнути Kubernetes Engine API:
У цьому посібнику можна використовувати Cloud Shell, який готує віртуальну машину g1-small у Google Compute Engine з Linux на основі Debian або комп'ютер на Linux або macOS.
Варіант А: використання Cloud Shell
Переваги використання Cloud Shell:
Середовищ розробки Python 2 і Python 3 (включаючи virtualenv) повністю налаштовані.
Інструменти командного рядка gcloud, Докер, мерзотник и кубектл, які ми будемо використовувати вже встановлено.
Встановіть кубектл - Інструмент командного рядка для роботи з Кубернетес.
gcloud components install kubectl
Встановіть Docker Community Edition (CE). Ви будете використовувати інструмент командного рядка Докер, щоб створювати образи контейнерів для прикладу програми.
Встановіть інструмент контролю версій Git, щоб отримати приклад програми з GitHub.
Приклад програми написано на Python і складається з двох компонентів, які взаємодіють за допомогою REST:
сервер: простий сервер з однією кінцевою точкою 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:8080
server відповідає:
Hello World!
4) З каталогу, куди ви завантажили приклад коду, перейдіть до каталогу, який містить loadgen:
cd YOUR_WORKING_DIRECTORY/istio-samples/sample-apps/helloserver/loadgen
З точки зору мережі, вся програма працює на одному хості (локальному комп'ютері або віртуальній машині 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 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 надає механізми взаємодії з кластером.
Команда gcloud створює кластер istioready у проекті GCP і зоні за замовчуванням, які ви вказали. Щоб запустити Istio, рекомендуємо мати хоча б 4 вузли та віртуальну машину n1-стандарт-2.
Команда створює кластер кілька хвилин. Коли кластер буде готовий, команда видає таке. повідомлення.
2) Вкажіть облікові дані в інструменті командного рядка кубектл, щоб з її допомогою керувати кластером:
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:
Перш ніж розгорнути контейнери в 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.
Розділ spec.template визначає шаблон pod'а. У специфікації pod'ів є поле зображення, де вказується ім'я образу, що його потрібно витягти з Container Registry.
LoadBalancer: клієнти надсилають запити на IP-адресу балансувальника навантаження, яка має постійну IP-адресу і яка доступна з-за меж кластера.
targetPort: як ви пам'ятаєте, команда ВИКЛИТИ 8080 в Докер-файл не надавала портів. Ви надаєте порт 8080щоб можна було зв'язатися з контейнером сервер зовні кластера. У нашому випадку hellosvc.default.cluster.local:80 (коротке ім'я: hellosvc) відповідає порту 8080 IP-адреси пода helloserver.
порт: це номер порту, куди інші послуги в кластері будуть надсилати запити.
loadgen.yaml
Об'єкт розгортання в loadgen.yaml схожий на server.yaml. Різниця в тому, що об'єкт розгортання містить розділ env. Він визначає змінні середовища, які потрібні loadgen і які ви встановили під час запуску програми з вихідного коду.
Раз loadgen не приймає вхідні запити для поля тип вказано ClusterIP. Цей тип надає постійну IP-адресу, яка може використовувати сервіси в кластері, але ця IP-адреса не надається зовнішнім клієнтам.
Замініть 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.
Якщо проксі 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 та награєтеся з прикладом програми. При цьому будуть видалені всі ресурси кластера, наприклад, обчислювальні екземпляри, диски та мережні ресурси.