Це багатосторінковий друкований вигляд цього розділу. Натисність щоб друкувати.
Доступ до застосунків у кластері
- 1: Використання перенаправлення портів для доступу до застосунків у кластері
- 2: Використання Service для доступу до застосунку в кластері
- 3: Зʼєднання фронтенду з бекендом за допомогою Services
- 4: Створення зовнішнього балансувальника навантаження
- 5: Отримання переліку всіх образів контейнерів, що працюють у кластері
- 6: Взаємодія контейнерів в одному Podʼі за допомогою спільного тому
- 7: Налаштування DNS для кластера
- 8: Доступ до сервісів, що працюють у кластерах
1 - Використання перенаправлення портів для доступу до застосунків у кластері
На цій сторінці показано, як за допомогою kubectl port-forward підʼєднатися до сервера MongoDB, що працює в кластері Kubernetes. Таке підʼєднання може бути корисним для налагодження бази даних.
Перш ніж ви розпочнете
Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:
Версія вашого Kubernetes сервера має бути не старішою ніж v1.10.Для перевірки версії введіть
kubectl version.- Встановіть MongoDB Shell.
Створення Deployment і Service для MongoDB
Створіть Deployment, що запускає MongoDB:
kubectl apply -f https://k8s.io/examples/application/mongodb/mongo-deployment.yamlВивід успішної команди підтверджує, що Deployment створено:
deployment.apps/mongo createdПерегляньте статус Podʼа, щоб переконатися, що він готовий:
kubectl get podsВивід показує створений Pod:
NAME READY STATUS RESTARTS AGE mongo-75f59d57f4-4nd6q 1/1 Running 0 2m4sПерегляньте статус Deployment:
kubectl get deploymentВивід показує, що Deployment створено:
NAME READY UP-TO-DATE AVAILABLE AGE mongo 1/1 1 1 2m21sDeployment автоматично керує ReplicaSet. Перегляньте статус ReplicaSet за допомогою:
kubectl get replicasetВивід показує, що ReplicaSet створено:
NAME DESIRED CURRENT READY AGE mongo-75f59d57f4 1 1 1 3m12sСтворіть Service, щоб відкрити доступ до MongoDB у мережі:
kubectl apply -f https://k8s.io/examples/application/mongodb/mongo-service.yamlВивід успішної команди підтверджує, що Service створено:
service/mongo createdПеревірте створений Service:
kubectl get service mongoВивід показує створений Service:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mongo ClusterIP 10.96.41.183 <none> 27017/TCP 11sПереконайтеся, що сервер MongoDB працює в Podʼі й слухає порт 27017:
# Замініть mongo-75f59d57f4-4nd6q на назву Podʼа kubectl get pod mongo-75f59d57f4-4nd6q --template='{{(index (index .spec.containers 0).ports 0).containerPort}}{{"\n"}}'Вивід показує порт MongoDB у цьому Podʼі:
2701727017 — офіційний порт TCP для MongoDB.
Перенаправлення локального порту на порт Podʼа
kubectl port-forwardдозволяє використовувати назву ресурсу, наприклад назву Podʼа, щоб вибрати відповідний Pod для перенаправлення порту.# Замініть mongo-75f59d57f4-4nd6q на назву Podʼа kubectl port-forward mongo-75f59d57f4-4nd6q 28015:27017що те саме, що й
kubectl port-forward pods/mongo-75f59d57f4-4nd6q 28015:27017або
kubectl port-forward deployment/mongo 28015:27017або
kubectl port-forward replicaset/mongo-75f59d57f4 28015:27017або
kubectl port-forward service/mongo 28015:27017Будь-яка з наведених вище команд працює. Вивід подібний до такого:
Forwarding from 127.0.0.1:28015 -> 27017 Forwarding from [::1]:28015 -> 27017Примітка:
kubectl port-forwardне завершується сам. Щоб продовжити вправи, потрібно відкрити інший термінал.Запустіть інтерфейс командного рядка MongoDB:
mongosh --port 28015У командному рядку MongoDB введіть команду
ping:db.runCommand( { ping: 1 } )Успішний запит ping повертає:
{ ok: 1 }
За бажання дозвольте kubectl вибрати локальний порт
Якщо вам не потрібен конкретний локальний порт, ви можете дозволити kubectl вибрати й призначити його, що позбавить вас потреби розвʼязувати конфлікти локальних портів, за допомогою дещо простішого синтаксису:
kubectl port-forward deployment/mongo :27017
Інструмент kubectl вибирає вільний номер локального порту (уникаючи низьких номерів, оскільки їх можуть використовувати інші застосунки). Вивід подібний до такого:
Forwarding from 127.0.0.1:63753 -> 27017
Forwarding from [::1]:63753 -> 27017
Обговорення
Зʼєднання з локальним портом 28015 перенаправляються на порт 27017 Podʼа, у якому працює сервер MongoDB. Завдяки цьому зʼєднанню ви можете налагоджувати базу даних, що працює в Podʼі, зі своєї локальної робочої станції.
Примітка:
kubectl port-forward реалізовано лише для портів TCP. Підтримка протоколу UDP відстежується в issue 47862.Авторизація та міркування безпеки
Доступ до kubectl port-forward контролюється механізмами авторизації Kubernetes, такими як контроль доступу на основі ролей (RBAC). Авторизацію забезпечує API-сервер Kubernetes, а не клієнт kubectl.
Щоб використовувати kubectl port-forward, користувач повинен мати дозвіл на доступ до цільового ресурсу (наприклад, Pod або Service) і субресурсу portforward. Зазвичай потрібні дозволи get для pods і create для pods/portforward.
Адміністратори кластерів мають ретельно обмежувати ці дозволи, оскільки перенаправлення портів може надавати прямий мережевий доступ до робочих навантажень і обходити засоби контролю на рівні мережі.
Що далі
Дізнайтеся більше про kubectl port-forward.
2 - Використання Service для доступу до застосунку в кластері
На цій сторінці показано, як створити обʼєкт Service у Kubernetes, за допомогою якого зовнішні клієнти можуть отримати доступ до застосунку, що працює в кластері. Service забезпечує балансування навантаження для застосунку, який має два запущені екземпляри.
Перш ніж ви розпочнете
Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:
Цілі
- Запустити два екземпляри застосунку Hello World.
- Створити обʼєкт Service, який відкриває порт вузла.
- Використовувати обʼєкт Service для доступу до запущеного застосунку.
Створення Service для застосунку, що працює у двох Podʼах
Ось файл конфігурації Deployment застосунку:
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-world
spec:
selector:
matchLabels:
run: load-balancer-example
replicas: 2
template:
metadata:
labels:
run: load-balancer-example
spec:
containers:
- name: hello-world
image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0
ports:
- containerPort: 8080
protocol: TCP
Запустіть застосунок Hello World у кластері: створіть Deployment застосунку за допомогою наведеного вище файлу:
kubectl apply -f https://k8s.io/examples/service/access/hello-application.yamlПопередня команда створює Deployment і повʼязаний ReplicaSet. ReplicaSet має два Podʼи, кожен з яких запускає застосунок Hello World.
Перегляньте інформацію про Deployment:
kubectl get deployments hello-world kubectl describe deployments hello-worldПерегляньте інформацію про ваші обʼєкти ReplicaSet:
kubectl get replicasets kubectl describe replicasetsСтворіть обʼєкт Service, який відкриває доступ до Deployment:
kubectl expose deployment hello-world --type=NodePort --name=example-serviceПерегляньте інформацію про Service:
kubectl describe services example-serviceВивід подібний до такого:
Name: example-service Namespace: default Labels: run=load-balancer-example Annotations: <none> Selector: run=load-balancer-example Type: NodePort IP: 10.32.0.16 Port: <unset> 8080/TCP TargetPort: 8080/TCP NodePort: <unset> 31496/TCP Endpoints: 10.200.1.4:8080,10.200.2.5:8080 Session Affinity: None Events: <none>Занотуйте значення NodePort для Service. Наприклад, у попередньому виводі значення NodePort становить 31496.
Виведіть Podʼи, на яких працює застосунок Hello World:
kubectl get pods --selector="run=load-balancer-example" --output=wideВивід подібний до такого:
NAME READY STATUS ... IP NODE hello-world-2895499144-bsbk5 1/1 Running ... 10.200.1.4 worker1 hello-world-2895499144-m1pwt 1/1 Running ... 10.200.2.5 worker2Отримайте публічну IP-адресу одного з вузлів, на якому працює Pod Hello World. Спосіб отримання цієї адреси залежить від того, як налаштовано кластер. Наприклад, якщо ви використовуєте Minikube, адресу вузла можна побачити, виконавши
kubectl cluster-info. Якщо ви використовуєте екземпляри Google Compute Engine, переглянути публічні адреси вузлів можна командоюgcloud compute instances list.На вибраному вузлі створіть правило фаєрвола, яке дозволяє TCP-трафік на порт вузла. Наприклад, якщо значення NodePort вашого Service — 31568, створіть правило фаєрвола, яке дозволяє TCP-трафік на порт 31568. Різні хмарні провайдери пропонують різні способи налаштування правил фаєрвола.
Використовуйте адресу вузла та порт вузла для доступу до застосунку Hello World:
curl http://<public-node-ip>:<node-port>де
<public-node-ip>— публічна IP-адреса вашого вузла, а<node-port>— значення NodePort вашого сервісу. Відповідь на успішний запит — вітальне повідомлення:Hello, world! Version: 2.0.0 Hostname: hello-world-cdd4458f4-m47c8
Використання файлу конфігурації Service
Замість kubectl expose можна використати файл конфігурації Service, щоб створити Service.
Очищення
Щоб видалити Service, введіть цю команду:
kubectl delete services example-service
Щоб видалити Deployment, ReplicaSet і Podʼи, на яких працює застосунок Hello World, введіть цю команду:
kubectl delete deployment hello-world
Що далі
Скористайтеся навчальним матеріалом Підключення застосунків за допомогою Services.
3 - Зʼєднання фронтенду з бекендом за допомогою Services
Це завдання показує, як створити мікросервіси фронтенду й бекенду. Мікросервіс бекенду — це сервіс привітання. Фронтенд відкриває доступ до бекенду за допомогою nginx та обʼєкта Service Kubernetes.
Цілі
- Створити й запустити приклад мікросервісу бекенду
helloза допомогою обʼєкта Deployment. - Використовувати обʼєкт Service для надсилання трафіку до кількох реплік мікросервісу бекенду.
- Створити й запустити мікросервіс фронтенду
nginx, також за допомогою обʼєкта Deployment. - Налаштувати мікросервіс фронтенду на надсилання трафіку до мікросервісу бекенду.
- Використати обʼєкт Service
type=LoadBalancer, щоб відкрити доступ до мікросервісу фронтенду ззовні кластера.
Перш ніж ви розпочнете
Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:
Для перевірки версії введіть kubectl version.
Це завдання використовує Services із зовнішніми балансувальниками навантаження, які потребують підтримуваного середовища. Якщо ваше середовище їх не підтримує, натомість можна використати Service типу NodePort.
Створення бекенду за допомогою Deployment
Бекенд — це простий мікросервіс привітання. Ось файл конфігурації Deployment бекенду:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
spec:
selector:
matchLabels:
app: hello
tier: backend
track: stable
replicas: 3
template:
metadata:
labels:
app: hello
tier: backend
track: stable
spec:
containers:
- name: hello
image: "gcr.io/google-samples/hello-go-gke:1.0"
ports:
- name: http
containerPort: 80
...Створіть Deployment для бекенду:
kubectl apply -f https://k8s.io/examples/service/access/backend-deployment.yaml
Перегляньте інформацію про Deployment бекенду:
kubectl describe deployment backend
Вивід подібний до такого:
Name: backend
Namespace: default
CreationTimestamp: Mon, 24 Oct 2016 14:21:02 -0700
Labels: app=hello
tier=backend
track=stable
Annotations: deployment.kubernetes.io/revision=1
Selector: app=hello,tier=backend,track=stable
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 1 max unavailable, 1 max surge
Pod Template:
Labels: app=hello
tier=backend
track=stable
Containers:
hello:
Image: "gcr.io/google-samples/hello-go-gke:1.0"
Port: 80/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: hello-3621623197 (3/3 replicas created)
Events:
...
Створення обʼєкта Service hello
Ключовим для надсилання запитів із фронтенду до бекенду є Service бекенду. Service створює постійну IP-адресу й запис імені DNS, щоб мікросервіс бекенду завжди був доступний. Service використовує селектори, щоб визначити Podʼи, до яких спрямовувати трафік.
Спочатку перегляньте файл конфігурації Service:
---
apiVersion: v1
kind: Service
metadata:
name: hello
spec:
selector:
app: hello
tier: backend
ports:
- protocol: TCP
port: 80
targetPort: http
...У файлі конфігурації видно, що Service з назвою hello спрямовує трафік до Podʼів із мітками app: hello і tier: backend.
Створіть Service для бекенду:
kubectl apply -f https://k8s.io/examples/service/access/backend-service.yaml
На цьому етапі у вас є Deployment backend, що виконує три репліки застосунку hello, і Service, який може спрямовувати до них трафік. Однак цей сервіс недоступний і не розвʼязується ззовні кластера.
Створення фронтенду
Тепер, коли бекенд працює, можна створити фронтенд, доступний ззовні кластера, який підʼєднується до бекенду, проксіюючи до нього запити.
Фронтенд надсилає запити до робочих Podʼів бекенду, використовуючи DNS-імʼя, надане Service бекенду. DNS-імʼя — hello, це значення поля name у файлі конфігурації examples/service/access/backend-service.yaml.
Podʼи в Deployment фронтенду запускають образ nginx, налаштований на проксіювання запитів до Service бекенду hello. Ось файл конфігурації nginx:
# The identifier Backend is internal to nginx, and used to name this specific upstream
upstream Backend {
# hello is the internal DNS name used by the backend Service inside Kubernetes
server hello;
}
server {
listen 80;
location / {
# The following statement will proxy traffic to the upstream named Backend
proxy_pass http://Backend;
}
}
Як і бекенд, фронтенд має Deployment і Service. Важлива відмінність між сервісами бекенду й фронтенду в тому, що конфігурація Service фронтенду має type: LoadBalancer, тобто Service використовує балансувальник навантаження, наданий вашим хмарним провайдером, і буде доступний ззовні кластера.
---
apiVersion: v1
kind: Service
metadata:
name: frontend
spec:
selector:
app: hello
tier: frontend
ports:
- protocol: "TCP"
port: 80
targetPort: 80
type: LoadBalancer
...---
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
spec:
selector:
matchLabels:
app: hello
tier: frontend
track: stable
replicas: 1
template:
metadata:
labels:
app: hello
tier: frontend
track: stable
spec:
containers:
- name: nginx
image: "gcr.io/google-samples/hello-frontend:1.0"
lifecycle:
preStop:
exec:
command: ["/usr/sbin/nginx","-s","quit"]
...Створіть Deployment і Service фронтенду:
kubectl apply -f https://k8s.io/examples/service/access/frontend-deployment.yaml
kubectl apply -f https://k8s.io/examples/service/access/frontend-service.yaml
Вивід підтверджує, що обидва ресурси створено:
deployment.apps/frontend created
service/frontend created
Примітка:
Конфігурацію nginx вбудовано в образ контейнера. Кращий спосіб — використати ConfigMap, щоб легше змінювати конфігурацію.Взаємодія із Service фронтенду
Після створення Service типу LoadBalancer цією командою можна знайти зовнішню IP-адресу:
kubectl get service frontend --watch
Це показує конфігурацію Service frontend і відстежує зміни. Спочатку зовнішня IP-адреса вказана як <pending>:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
frontend LoadBalancer 10.51.252.116 <pending> 80/TCP 10s
Щойно зовнішню IP-адресу буде надано, конфігурація оновиться й міститиме нову IP-адресу в колонці EXTERNAL-IP:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
frontend LoadBalancer 10.51.252.116 XXX.XXX.XXX.XXX 80/TCP 1m
Тепер цю IP-адресу можна використовувати для взаємодії із сервісом frontend ззовні кластера.
Надсилання трафіку через фронтенд
Фронтенд і бекенд тепер зʼєднані. Ви можете звернутися до точки доступу командою curl за зовнішньою IP-адресою Service фронтенду.
curl http://${EXTERNAL_IP} # замініть це на EXTERNAL-IP, який ви бачили раніше
Вивід показує повідомлення, згенероване бекендом:
{"message":"Hello"}
Очищення
Щоб видалити Services, введіть цю команду:
kubectl delete services frontend backend
Щоб видалити Deployments, ReplicaSets і Podʼи, у яких працюють застосунки бекенду й фронтенду, введіть цю команду:
kubectl delete deployment frontend backend
Що далі
- Дізнайтеся більше про Services
- Дізнайтеся більше про ConfigMaps
- Дізнайтеся більше про DNS для Services і Podʼів
4 - Створення зовнішнього балансувальника навантаження
На цій сторінці показано, як створити зовнішній балансувальник навантаження.
Під час створення Service ви можете автоматично створити хмарний балансувальник навантаження. Він надає доступну ззовні IP-адресу, яка спрямовує трафік на потрібний порт вузлів кластера, за умови, що ваш кластер працює в підтримуваному середовищі й налаштований із відповідним пакетом постачальника хмарного балансувальника навантаження.
Ви також можете використовувати Ingress замість Service. Докладніше дивіться в документації про Ingress.
Перш ніж ви розпочнете
Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:
Ваш кластер має працювати в хмарі або іншому середовищі, яке вже підтримує налаштування зовнішніх балансувальників навантаження.
Створення Service
Створення Service з маніфесту
Щоб створити зовнішній балансувальник навантаження, додайте такий рядок до маніфесту Service:
type: LoadBalancer
Ваш маніфест може виглядати так:
apiVersion: v1
kind: Service
metadata:
name: example-service
spec:
selector:
app: example
ports:
- port: 8765
targetPort: 9376
type: LoadBalancer
Створення Service за допомогою kubectl
Також можна створити сервіс командою kubectl expose із прапорцем --type=LoadBalancer:
kubectl expose deployment example --port=8765 --target-port=9376 \
--name=example-service --type=LoadBalancer
Ця команда створює новий Service із тими самими селекторами, що й у вказаного ресурсу (у наведеному прикладі — Deployment з назвою example).
Докладніше, зокрема про необовʼязкові прапорці, дивіться в довіднику kubectl expose.
Пошук вашої IP-адреси
Щоб знайти IP-адресу, створену для вашого сервісу, отримайте інформацію про сервіс через kubectl:
kubectl describe services example-service
що має дати вивід, подібний до такого:
Name: example-service
Namespace: default
Labels: app=example
Annotations: <none>
Selector: app=example
Type: LoadBalancer
IP Families: <none>
IP: 10.3.22.96
IPs: 10.3.22.96
LoadBalancer Ingress: 192.0.2.89
Port: <unset> 8765/TCP
TargetPort: 9376/TCP
NodePort: <unset> 30593/TCP
Endpoints: 172.17.0.3:9376
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
IP-адреса балансувальника навантаження вказана поруч з LoadBalancer Ingress.
Примітка:
Якщо ви запускаєте сервіс у Minikube, призначену IP-адресу й порт можна знайти за допомогою:
minikube service example-service --url
Збереження вихідної IP-адреси клієнта
Стандартно вихідна IP-адреса, яку бачить цільовий контейнер, не є початковою вихідною IP-адресою клієнта. Щоб увімкнути збереження IP-адреси клієнта, можна налаштувати такі поля в .spec Service:
.spec.externalTrafficPolicy— визначає, чи має цей Service маршрутизувати зовнішній трафік до точок доступу на локальному вузлі чи до точок доступу в усьому кластері. Є два варіанти:Cluster(стандартно) іLocal.Clusterприховує вихідну IP-адресу клієнта й може спричинити другий перехід на інший вузол, але має добре загальне розподілення навантаження.Localзберігає вихідну IP-адресу клієнта й уникає другого переходу для Services типів LoadBalancer і NodePort, але створює ризик нерівномірного розподілення трафіку..spec.healthCheckNodePort— задає порт вузла для перевірки справності (числовий номер порту) для сервісу. Якщо ви не вкажетеhealthCheckNodePort, контролер сервісів виділить порт із діапазону NodePort вашого кластера. Цей діапазон можна налаштувати параметром командного рядка API-сервера--service-node-port-range. Service використовуватиме вказане користувачем значенняhealthCheckNodePort, якщо ви його задасте, за умови, щоtypeService — LoadBalancer, аexternalTrafficPolicy—Local.
Значення Local для externalTrafficPolicy у маніфесті Service вмикає цю можливість. Наприклад:
apiVersion: v1
kind: Service
metadata:
name: example-service
spec:
selector:
app: example
ports:
- port: 8765
targetPort: 9376
externalTrafficPolicy: Local
type: LoadBalancer
Застереження й обмеження під час збереження вихідних IP-адрес
Сервіси балансування навантаження деяких хмарних провайдерів не дозволяють налаштувати різну вагу для кожної цілі.
Коли всі цілі мають однакову вагу під час надсилання трафіку на вузли, зовнішній трафік розподіляється між різними Podʼами нерівномірно. Зовнішній балансувальник навантаження не знає, скільки Podʼів на кожному вузлі використовується як ціль.
Коли NumServicePods << NumNodes або NumServicePods >> NumNodes, розподіл буде досить близьким до рівномірного навіть без ваг.
Внутрішній трафік між Podʼами має поводитися так само, як у Services типу ClusterIP, з однаковою ймовірністю для всіх Podʼів.
Збір сміття балансувальників навантаження
Зазвичай відповідні ресурси балансувальника навантаження в хмарного провайдера мають бути очищені незабаром після видалення Service типу LoadBalancer. Але відомо, що існують різні крайні випадки, коли хмарні ресурси лишаються без власника після видалення повʼязаного Service. Щоб цьому запобігти, було введено захист Service типу LoadBalancer завершувачами. Завдяки завершувачам ресурс Service не буде видалено, доки не будуть видалені й відповідні ресурси балансувальника навантаження.
Зокрема, якщо Service має type LoadBalancer, контролер сервісів додає завершувач з назвою service.kubernetes.io/load-balancer-cleanup. Завершувач вилучається лише після очищення ресурсу балансувальника навантаження. Це запобігає появі завислих ресурсів балансувальника навантаження навіть у крайніх випадках, наприклад під час збою контролера сервісів.
Постачальники зовнішніх балансувальників навантаження
Важливо зазначити, що шлях даних для цієї можливості забезпечує балансувальник навантаження, зовнішній щодо кластера Kubernetes.
Коли type Service встановлено в LoadBalancer, Kubernetes надає Podʼам у кластері можливості, рівнозначні type ClusterIP, і розширює їх, програмуючи (зовнішній щодо Kubernetes) балансувальник навантаження записами для вузлів, на яких розміщені відповідні Podʼи Kubernetes. Панель управління Kubernetes автоматизує створення зовнішнього балансувальника навантаження, перевірки справності (за потреби) і правила фільтрації пакетів (за потреби). Після того як хмарний провайдер виділить IP-адресу для балансувальника навантаження, панель управління отримує цю зовнішню IP-адресу й заносить її в обʼєкт Service.
Що далі
- Скористайтеся навчальним матеріалом Підключення застосунків за допомогою Services
- Прочитайте про Service
- Прочитайте про Ingress
5 - Отримання переліку всіх образів контейнерів, що працюють у кластері
На цій сторінці показано, як за допомогою kubectl отримати перелік усіх образів контейнерів для Podʼів, що працюють у кластері.
Перш ніж ви розпочнете
Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:
Для перевірки версії введіть kubectl version.
У цій вправі ви за допомогою kubectl отримаєте всі Podʼи, що працюють у кластері, і відформатуєте вивід, щоб отримати перелік контейнерів для кожного з них.
Перелік усіх образів контейнерів у всіх просторах імен
- Отримайте всі Podʼи у всіх просторах імен за допомогою
kubectl get pods --all-namespaces. - Відформатуйте вивід, щоб він містив лише перелік назв образів контейнерів, за допомогою
-o jsonpath={.items[*].spec['initContainers', 'containers'][*].image}. Це рекурсивно витягне полеimageз отриманого json.- Докладніше про використання jsonpath дивіться в довіднику з jsonpath.
- Відформатуйте вивід за допомогою стандартних інструментів:
tr,sort,uniq.- Використовуйте
trдля заміни пробілів на нові рядки. - Використовуйте
sortдля сортування результатів. - Використовуйте
uniqдля підрахунку образів.
- Використовуйте
kubectl get pods --all-namespaces -o jsonpath="{.items[*].spec['initContainers', 'containers'][*].image}" |\
tr -s '[[:space:]]' '\n' |\
sort |\
uniq -c
Jsonpath інтерпретується так:
.items[*]: для кожного отриманого значення..spec: отримати spec.['initContainers', 'containers'][*]: для кожного контейнера..image: отримати образ.
Примітка:
Під час отримання одного Podʼа за назвою, наприкладkubectl get pod nginx, частину шляху .items[*] слід пропустити, оскільки повертається один Pod, а не список елементів.Перелік образів контейнерів за Podʼами
Форматування можна додатково контролювати за допомогою операції range, щоб перебирати елементи окремо.
kubectl get pods --all-namespaces -o jsonpath='{range .items[*]}{"\n"}{.metadata.name}{":\t"}{range .spec.containers[*]}{.image}{", "}{end}{end}' |\
sort
Перелік образів контейнерів із фільтрацією за міткою Podʼа
Щоб вибрати лише Podʼи з певною міткою, використовуйте прапорець -l. Наведена нижче команда вибирає лише Podʼи з міткою app=nginx.
kubectl get pods --all-namespaces -o jsonpath="{.items[*].spec.containers[*].image}" -l app=nginx
Перелік образів контейнерів із фільтрацією за простором імен Podʼа
Щоб вибрати лише Podʼи в певному просторі імен, використовуйте прапорець namespace. Наведена нижче команда вибирає лише Podʼи в просторі імен kube-system.
kubectl get pods --namespace kube-system -o jsonpath="{.items[*].spec.containers[*].image}"
Перелік образів контейнерів за допомогою go-template замість jsonpath
Як альтернативу jsonpath kubectl підтримує go-templates для форматування виводу:
kubectl get pods --all-namespaces -o go-template --template="{{range .items}}{{range .spec.containers}}{{.image}} {{end}}{{end}}"
Що далі
Довідка
- Довідник Jsonpath
- Довідник Go template
6 - Взаємодія контейнерів в одному Podʼі за допомогою спільного тому
На цій сторінці показано, як використовувати том для взаємодії двох контейнерів, що працюють в одному Podʼі. Дивіться також, як дозволити процесам взаємодіяти через спільний простір імен процесів між контейнерами.
Перш ніж ви розпочнете
Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:
Для перевірки версії введіть kubectl version.
Створення Podʼа, що запускає два контейнери
У цій вправі ви створите Pod, який запускає два контейнери. Ці контейнери спільно використовують том, через який вони можуть взаємодіяти. Ось файл конфігурації Podʼа:
apiVersion: v1
kind: Pod
metadata:
name: two-containers
spec:
restartPolicy: Never
volumes:
- name: shared-data
emptyDir: {}
containers:
- name: nginx-container
image: nginx
volumeMounts:
- name: shared-data
mountPath: /usr/share/nginx/html
- name: debian-container
image: debian
volumeMounts:
- name: shared-data
mountPath: /pod-data
command: ["/bin/sh"]
args: ["-c", "echo Hello from the debian container > /pod-data/index.html"]
У файлі конфігурації видно, що Pod має том з назвою shared-data.
Перший контейнер, вказаний у файлі конфігурації, запускає сервер nginx. Шлях монтування спільного тому — /usr/share/nginx/html. Другий контейнер базується на образі debian і має шлях монтування /pod-data. Другий контейнер виконує таку команду, а потім завершується.
echo Hello from the debian container > /pod-data/index.html
Зверніть увагу, що другий контейнер записує файл index.html в кореневу теку сервера nginx.
Створіть Pod і два контейнери:
kubectl apply -f https://k8s.io/examples/pods/two-container-pod.yaml
Перегляньте інформацію про Pod та контейнери:
kubectl get pod two-containers --output=yaml
Ось частина виводу:
apiVersion: v1
kind: Pod
metadata:
...
name: two-containers
namespace: default
...
spec:
...
containerStatuses:
- containerID: docker://c1d8abd1 ...
image: debian
...
lastState:
terminated:
...
name: debian-container
...
- containerID: docker://96c1ff2c5bb ...
image: nginx
...
name: nginx-container
...
state:
running:
...
Ви бачите, що контейнер debian завершив роботу, а контейнер nginx досі працює.
Отримайте доступ до оболонки контейнера nginx:
kubectl exec -it two-containers -c nginx-container -- /bin/bash
В оболонці перевірте, що nginx працює:
root@two-containers:/# apt-get update
root@two-containers:/# apt-get install curl procps
root@two-containers:/# ps aux
Вивід подібний до такого:
USER PID ... STAT START TIME COMMAND
root 1 ... Ss 21:12 0:00 nginx: master process nginx -g daemon off;
Згадайте, що контейнер debian створив файл index.html у кореневій теці nginx. Використайте curl, щоб надіслати GET-запит на сервер nginx:
root@two-containers:/# curl localhost
Вивід показує, що nginx обслуговує вебсторінку, записану контейнером debian:
Hello from the debian container
Обговорення
Основна причина, чому Podʼи можуть мати кілька контейнерів, — підтримка допоміжних застосунків, які допомагають основному застосунку. Типові приклади допоміжних застосунків — програми для отримання й надсилання даних, а також проксі. Допоміжні й основні застосунки часто мають взаємодіяти між собою. Зазвичай це робиться через спільну файлову систему, як показано в цій вправі, або через петлевий мережевий інтерфейс localhost. Приклад такого шаблону — вебсервер разом із допоміжною програмою, яка перевіряє наявність нових оновлень у репозиторії Git.
Том у цій вправі надає контейнерам спосіб взаємодіяти протягом життя Podʼа. Якщо Pod видалено й створено заново, усі дані, збережені в спільному томі, втрачаються.
Що далі
Дізнайтеся більше про шаблони для композитних контейнерів.
Дізнайтеся про композитні контейнери для модульної архітектури.
Перегляньте Налаштування Podʼа для використання тому для зберігання.
Перегляньте Налаштування Podʼа для спільного використання простору імен процесів між контейнерами в Podʼі.
Перегляньте Volume.
Перегляньте Pod.
7 - Налаштування DNS для кластера
Kubernetes пропонує надбудову DNS для кластера, яка стандартно ввімкнена в більшості підтримуваних середовищ. У Kubernetes версії 1.11 і новіших рекомендовано CoreDNS, який стандартно встановлюється з kubeadm.
Докладніше про налаштування CoreDNS для кластера Kubernetes дивіться Налаштування сервісу DNS.
8 - Доступ до сервісів, що працюють у кластерах
На цій сторінці показано, як підʼєднатися до сервісів, що працюють у кластері Kubernetes.
Перш ніж ви розпочнете
Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:
Для перевірки версії введіть kubectl version.
Доступ до сервісів, що працюють у кластері
У Kubernetes вузли, Podʼи і сервіси мають власні IP-адреси. У багатьох випадках IP-адреси вузлів, Podʼів і деяких сервісів у кластері не маршрутизуються, тому вони недосяжні з машини поза кластером, наприклад із вашого настільного компʼютера.
Способи підʼєднання
Є кілька варіантів підʼєднання до вузлів, Podʼів і сервісів ззовні кластера:
- Доступ до сервісів через публічні IP-адреси.
- Використайте Service типу
NodePortабоLoadBalancer, щоб зробити сервіс доступним ззовні кластера. Дивіться документацію про Services і kubectl expose. - Залежно від середовища кластера сервіс може стати доступним лише у вашій корпоративній мережі або в інтернеті. Подумайте, чи є сервіс, до якого відкривається доступ, безпечним. Чи виконує він власну автентифікацію?
- Розміщуйте Podʼи за сервісами. Щоб отримати доступ до одного конкретного Podʼа з набору реплік, наприклад для налагодження, додайте до Podʼа унікальну мітку й створіть новий Service, який вибирає цю мітку.
- У більшості випадків розробнику застосунків не потрібно звертатися до вузлів безпосередньо за їхніми nodeIP.
- Використайте Service типу
- Доступ до сервісів, вузлів або Podʼів за допомогою дієслова Proxy.
- Виконує автентифікацію й авторизацію на API-сервері перед доступом до віддаленого сервісу. Використовуйте це, якщо сервіси недостатньо безпечні для відкриття в інтернет, для доступу до портів на IP-адресі вузла або для налагодження.
- Проксі можуть викликати проблеми для деяких вебзастосунків.
- Працює лише для HTTP/HTTPS.
- Описано тут.
- Доступ з вузла або Podʼа в кластері.
- Запустіть Pod, а потім підʼєднайтеся до оболонки в ньому за допомогою kubectl exec. З цієї оболонки підʼєднуйтеся до інших вузлів, Podʼів і сервісів.
- Деякі кластери дозволяють підʼєднатися до вузла кластера через ssh. Звідти ви зможете отримати доступ до сервісів кластера. Це нестандартний спосіб, який працює на одних кластерах і не працює на інших. Браузери та інші інструменти можуть бути не встановлені. DNS кластера може не працювати.
Виявлення вбудованих сервісів
Зазвичай у кластері є кілька сервісів, запущених у kube-system. Отримайте їх список командою kubectl cluster-info:
kubectl cluster-info
Вивід подібний до такого:
Kubernetes master is running at https://192.0.2.1
elasticsearch-logging is running at https://192.0.2.1/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy
kibana-logging is running at https://192.0.2.1/api/v1/namespaces/kube-system/services/kibana-logging/proxy
coredns is running at https://192.0.2.1/api/v1/namespaces/kube-system/services/kube-dns/proxy
grafana is running at https://192.0.2.1/api/v1/namespaces/kube-system/services/monitoring-grafana/proxy
heapster is running at https://192.0.2.1/api/v1/namespaces/kube-system/services/monitoring-heapster/proxy
Тут показано URL проксі-дієслова для доступу до кожного сервісу. Наприклад, у цьому кластері ввімкнено логування на рівні кластера (за допомогою Elasticsearch), до якого можна звернутися за адресою https://192.0.2.1/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/ за наявності відповідних облікових даних або через kubectl proxy, наприклад за адресою http://localhost:8080/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/.
Примітка:
Про те, як передавати облікові дані або використовувати kubectl proxy, дивіться Доступ до кластерів за допомогою API Kubernetes.Ручне створення URL проксі API-сервера
Як згадано вище, URL проксі сервісу можна отримати командою kubectl cluster-info. Щоб створити URL проксі, які містять точки доступу сервісу, суфікси й параметри, додайте їх до URL проксі сервісу: http://kubernetes_master_address/api/v1/namespaces/namespace_name/services/[https:]service_name[:port_name]/proxy
Якщо ви не задали назву порту, port_name в URL вказувати не потрібно. Також можна використовувати номер порту замість port_name як для іменованих, так і для неіменованих портів.
Стандартно API-сервер проксіює запити до вашого сервісу через HTTP. Щоб використовувати HTTPS, додайте до назви сервісу префікс https:: http://<kubernetes_master_address>/api/v1/namespaces/<namespace_name>/services/<service_name>/proxy
Підтримувані формати сегмента <service_name> в URL:
<service_name>— проксіює до стандартного або неіменованого порту через http<service_name>:<port_name>— проксіює до вказаної назви порту або номера порту через httphttps:<service_name>:— проксіює до стандартного або неіменованого порту через https (зверніть увагу на двокрапку в кінці)https:<service_name>:<port_name>— проксіює до вказаної назви порту або номера порту через https
Приклади
Щоб отримати доступ до точки доступу
_search?q=user:kimchyсервісу Elasticsearch, використайте:http://192.0.2.1/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/_search?q=user:kimchyЩоб отримати інформацію про справність кластера Elasticsearch
_cluster/health?pretty=true, використайте:https://192.0.2.1/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/_cluster/health?pretty=trueІнформація про справність подібна до такої:
{ "cluster_name" : "kubernetes_logging", "status" : "yellow", "timed_out" : false, "number_of_nodes" : 1, "number_of_data_nodes" : 1, "active_primary_shards" : 5, "active_shards" : 5, "relocating_shards" : 0, "initializing_shards" : 0, "unassigned_shards" : 5 }Щоб отримати інформацію про справність сервісу Elasticsearch через https
_cluster/health?pretty=true, використайте:https://192.0.2.1/api/v1/namespaces/kube-system/services/https:elasticsearch-logging:/proxy/_cluster/health?pretty=true
Використання браузерів для доступу до сервісів, що працюють у кластері
Ви можете ввести URL проксі API-сервера в адресний рядок браузера. Однак:
- Браузери зазвичай не можуть передавати токени, тому може знадобитися базова автентифікація (пароль). API-сервер можна налаштувати на прийняття базової автентифікації, але ваш кластер може бути не налаштований на це.
- Деякі вебзастосунки можуть не працювати, особливо ті, що мають клієнтський javascript, який створює URL, не враховуючи префікс шляху проксі.