753
content/ru/start-with-k8s.md
Normal file
753
content/ru/start-with-k8s.md
Normal file
@ -0,0 +1,753 @@
|
||||
---
|
||||
title: Начало работы с kubernetes
|
||||
description: Как там это всё разворачивать в двух словах.
|
||||
category: DevOps
|
||||
position: 4
|
||||
---
|
||||
|
||||
# Проблема в изучении кубернетес
|
||||
|
||||
Многие люди, кто задавались вопросом как начать работать с
|
||||
кубернетесом сталкивались с тем, что документация крайне
|
||||
большая сложная и нет нормального описания как
|
||||
завернуть маленький проект из одного проекта в свой кластер или
|
||||
как развернуть свой кластер без боли.
|
||||
|
||||
А всё потому что вся документация нацелена на большие
|
||||
production-ready системы с большим rps и тому подобным.
|
||||
|
||||
В данной статье я попробую исправить это вселенское
|
||||
недопонимание используя k3s, свой комплюктер и немного знаний по кодингу.
|
||||
|
||||
<div align="center">
|
||||
|
||||

|
||||
|
||||
</div>
|
||||
|
||||
# Что такое кубернетес и почему это лучше докера
|
||||
|
||||
Многие ребята, кто хорошо знаком с докером и его
|
||||
возможностями могут задаваться таким вопросом.
|
||||
Для тех кто в танке, напомню, что докер
|
||||
имеет вариант запуска в режиме кластера.
|
||||
Этот функционал называется docker swarm.
|
||||
В целом, swarm отдалённо напоминает kubernetes,
|
||||
так как в этом режиме докер, худо-бедно но умеет
|
||||
автоскейлится и запускаться в кластере,
|
||||
но это всё равно немного не то.
|
||||
|
||||
<b-message type="is-info" has-icon>
|
||||
Также замечу, что кубер активно развивается и поддерживается.
|
||||
огромным количество компаний. А вот docker swarm уже по-немногу
|
||||
умирает и документация по нему не то чтобы супер хороша.
|
||||
</b-message>
|
||||
|
||||
По большей части кубернетес это система,
|
||||
которая будет управлять вашими приложениями,
|
||||
следить за их состоянием и помогать вам в их
|
||||
конфигурации. Кубер умеет очень много, поэтому
|
||||
все интересные способности я в этой статье не смогу осветить,
|
||||
но самую базу попробую рассказать.
|
||||
|
||||
# Из чего состоит кубернетес
|
||||
|
||||
Так как я в этой статье хотел затронуть
|
||||
совсем базовые и практические вещи, то рассматривать
|
||||
мы будем только крайне полезные компоненты.
|
||||
|
||||
- Container
|
||||
- Pod
|
||||
- Deployment
|
||||
- Service
|
||||
- Ingress
|
||||
- Namespace
|
||||
- Secret
|
||||
- ConfigMap
|
||||
|
||||
А теперь рассмотрим немного поподробнее.
|
||||
|
||||
## Container
|
||||
|
||||
Контейнеры не то чтобы часть специфичная для кубернетес.
|
||||
С контейнерами вы можете быть знакомы из кучи систем.
|
||||
В контексте кубера они не обладают никакими дополнительными
|
||||
свойствами. Это ровно то же, что и контейнеры `containerd`
|
||||
или те, с которыми вы возились с докером. Ничего нового.
|
||||
|
||||
Собираются контейнеры для кубернетеса ровно тем же образом,
|
||||
что и для докера.
|
||||
|
||||
<b-message type="is-warning" has-icon>
|
||||
|
||||
Важная ремарка. Кубер начиная с 2021 кубернетес не поддерживает
|
||||
докер как бэкенд. Теперь кубер будет общаться с
|
||||
containerd напрямую. Это значит, что теперь перед использованием
|
||||
контейнеров собранных на локальной машине надо будет импортировать их
|
||||
в `containerd` используя `ctr image import`.
|
||||
|
||||
Как импортировать образы почитать можно в [этой статье](https://cwienczek.com/2020/06/import-images-to-k3s-without-docker-registry/).
|
||||
|
||||
</b-message>
|
||||
|
||||
## Pod
|
||||
|
||||
<div align="center">
|
||||
<img alt="Pods" style="width: 100%" src="/images/k3s_start/pods.svg">
|
||||
</div>
|
||||
|
||||
Поды - это логически связанные группы контейнеров.
|
||||
Это самая базовая еденица кубернетеса.
|
||||
|
||||
В поде находится от одного до множества контейнеров.
|
||||
Интересная особенность пода в том, что все контейнеры
|
||||
делят один сетевой адресс. Другими словами,
|
||||
если у вас один из контейнеров открыл порт `3000`,
|
||||
то другие контейнеры из пода эти порты использовать не смогут.
|
||||
|
||||
То есть, если вы хотите логически связанные приложения
|
||||
поместить в под, то они могут ходить друг к другу через лупбек
|
||||
адреса. Такие как `localhost` или `127.0.0.1`.
|
||||
|
||||
## Deployment
|
||||
|
||||
Поды это круто, но есть одно но. Данные объекты неизменяемые
|
||||
и сам под скейлить вручную занятие сомнительное.
|
||||
|
||||
Конечно, никто не мешает создать вам вручную [ReplicaSet](https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/)
|
||||
и самому крутить там нужные значения. Но в среднем
|
||||
вам с этим возиться не очень то хочется.
|
||||
|
||||
<br>
|
||||
|
||||
Deployment нужна именно для описания подов и создания
|
||||
некоторых ресурсов, нужных для скейлинга.
|
||||
Также с помощью деплойментов можно делать откаты приложения через
|
||||
механиз роллбеков. Я это рассматривать не буду. Тут только база.
|
||||
|
||||
## Service
|
||||
|
||||
Сервис - это ресурс, с помощью которого поды могут общаться
|
||||
между собой. По факту сервис описывает, какие порты пода
|
||||
открыты и перенаправляет трафик на них.
|
||||
|
||||
Представьте себе под, который просто проксирует весь трафик с одного
|
||||
порта на какой-нибудь порт пода. Это и есть Service.
|
||||
|
||||
<div align="center">
|
||||
|
||||

|
||||
|
||||
</div>
|
||||
|
||||
Выглядит сервис примерно так как показано на кртинке выше.
|
||||
Он направляет весь входной трафик с указанного порта на
|
||||
порты подов.
|
||||
|
||||
Также сервис выступает как балансировщик.
|
||||
|
||||
<b-message type="is-info" has-icon>
|
||||
Если вы хотите сделать запрос от одного пода до дргого внутри кластера, то
|
||||
вам придётся использовать сервис.
|
||||
<br>
|
||||
Если вы попробуете сделать запрос напрямую по IP пода, то у вас, конечно же,
|
||||
получится, но это довольно странная идея из-за того, что при пересоздании
|
||||
пода у него может обновится IP внутри кластера. Поэтому лучше использовать сервисы. Также они потребуются для ингресса.
|
||||
</b-message>
|
||||
|
||||
## Ingress
|
||||
|
||||
Ингрессы это сервис описывающий куда пускать трафик,
|
||||
который поступает снаружи кластера.
|
||||
|
||||
<div align="center">
|
||||
|
||||

|
||||
|
||||
</div>
|
||||
|
||||
Принцип работы ингресса следующий:
|
||||
|
||||
Вы указываете хост ингресса и различные регексы пути.
|
||||
В зависимости от входящего запроса ингресс выбирает в какой сервис
|
||||
направить его и в какой порт.
|
||||
|
||||
Настройка ингресса достаточно гибкая и я не думаю,
|
||||
что вы можете столкнуться с какими либо проблемами.
|
||||
|
||||
## Namespace
|
||||
|
||||
Неймспейсы это логические разделители уровня доступа.
|
||||
|
||||
Я предпочитаю использовать разные неймспейсы под различные логические группы приложений.
|
||||
|
||||
Например, в моём кластере есть отдельные неймспейсы для каждого приложения.
|
||||
|
||||
Скажем, у меня есть проект, в котором есть база данных и веб сервер.
|
||||
Я держу их в одном неймспейсе, который называется также, как и приложени.
|
||||
|
||||
А вот телеграм боты -- приложения достаточно лёгкие.
|
||||
Поэтому у меня есть неймспейс со всеми телеграм ботами.
|
||||
|
||||
Эта штука позволяет просто лучше организовать свой кубернетес кластер.
|
||||
|
||||
Также неймспейсы очень полезны для ограничивания возможностей
|
||||
конкретного пользователя.
|
||||
Например, вы можете создать правило, которое будет разрешать пользователю
|
||||
смотреть на поды в каком-то неймспейсе, но при этом ему нельзя будет
|
||||
что либо изменять.
|
||||
|
||||
## Secret и ConfigMap
|
||||
|
||||
Данные ресурсы нужны только чтобы хранить
|
||||
внутри кластера какую-нибудь информацию.
|
||||
|
||||
Например вы можете сохранить в ConfigMap
|
||||
переменные среды и потом использовать их в подах в одном неймспейсе.
|
||||
|
||||
В секреты обычно кидают сертификаты или какие-нибудь ключи.
|
||||
Но так как секреты не особо секретные принято использовать [Vault](https://www.vaultproject.io/docs/platform/k8s). Но так как эта статья затрагивает только
|
||||
основы рассматривать развертку и настройку Vault мы не будем, ну и также HashiCorp
|
||||
всё довольно подробно расписали сами.
|
||||
|
||||
# Как развернуть k8s у себя
|
||||
|
||||
Для локального кубера есть пара вариантов.
|
||||
|
||||
- k3s (Недоступен под Windows)
|
||||
- minikube
|
||||
|
||||
На первый взгляд minikube может показаться лучшим вариантом.
|
||||
И он действительно хорош тем, что его легко почистить после
|
||||
своих экспериментов. Однако, там есть проблемы с ингрессами.
|
||||
По факту они не работают и там надо окольными путями получать
|
||||
адреса приложения.
|
||||
|
||||
<br>
|
||||
|
||||
k3s - это легковесная production-ready реализация k8s. Ingress у него работают
|
||||
отлично, поэтому я буду использовать его.
|
||||
|
||||
<br>
|
||||
|
||||
Я не буду зацикливаться на установке `minikube`, так как
|
||||
он прост в установке и первоначальной настройке. Почитать подробнее можно в
|
||||
[официальном гайде от minikube](https://minikube.sigs.k8s.io/docs/start/).
|
||||
|
||||
С `k3s` всё немного посложнее, но тоже достаточно просто, если немного разобраться. Первоначальная установка описана в [официальной доке k3s](https://rancher.com/docs/k3s/latest/en/installation/install-options/).
|
||||
|
||||
## Подключение кластера
|
||||
|
||||
После установки в домашней дериктории должен был быть
|
||||
сгенерирован файл `.kube/config`. Этот файл содержит данные для
|
||||
подключения к различным кластерам. `minikube` Сам добавляет
|
||||
ключи для подключения к .kube/config. `K3S` не изменяет
|
||||
никаким образом `.kube/config`, поэтому надо будет это сделать вручную.
|
||||
|
||||
Для того, чтобы это сделать сначала разберёмся как выглядит конфиг.
|
||||
|
||||
```yaml{}[.kube/config]
|
||||
apiVersion: v1
|
||||
kind: Config
|
||||
preferences: {}
|
||||
# Массив кластеров.
|
||||
# Каждый элемент -- данные для подключения
|
||||
# Тут также есть названия для каждого кластера.
|
||||
clusters:
|
||||
- name: hyper
|
||||
cluster:
|
||||
certificate-authority-data: DATA+OMITTED
|
||||
server: https://192.168.1.55:6443
|
||||
- name: k3s-local
|
||||
cluster:
|
||||
certificate-authority-data: DATA+OMITTED
|
||||
server: https://127.0.0.1:6443
|
||||
# Массив данных пользователя.
|
||||
# Тут указаны пользователи с
|
||||
# различными сертификатами.
|
||||
# Обычно для разных серверов у вас будут
|
||||
# Различные данные для входа.
|
||||
users:
|
||||
- name: hyper-s3rius
|
||||
user:
|
||||
client-certificate-data: REDACTED
|
||||
client-key-data: REDACTED
|
||||
- name: k3s-user
|
||||
user:
|
||||
client-certificate-data: REDACTED
|
||||
client-key-data: REDACTED
|
||||
# Массив контекстов.
|
||||
# Контекст - это связующее звено
|
||||
# между кластероами и пользователями.
|
||||
contexts:
|
||||
- context:
|
||||
cluster: hyper
|
||||
user: hyper-s3rius
|
||||
name: hyper
|
||||
- context:
|
||||
cluster: k3s-local
|
||||
user: k3s-user
|
||||
name: k3s
|
||||
# Текущий контекст указывает какой
|
||||
# контекст использовать по умолчанию.
|
||||
current-context: "k3s"
|
||||
```
|
||||
|
||||
Для работы с кубером из командной строки
|
||||
можно использовать `kubectl`. Чтобы сменить контекст в любой команде вы
|
||||
можете передать параметр `--context $CONTEXT_NAME`, где `$CONTEXT_NAME` это название контекста.
|
||||
|
||||
Чтобы достать данные для подключения к `k3s` надо посмотреть его конфиг
|
||||
и скопировать данные. Либо выставить переменную среды, которая будет
|
||||
указывать конфиг k3s. Конфиг подключения `k3s` лежит в файле `/etc/rancher/k3s/k3s.yaml`.
|
||||
|
||||
Можете выполнить команду, которая будет просить kubectl использовать указанный конфиг:
|
||||
`export KUBE_CONFIG=/etc/rancher/k3s/k3s.yaml`
|
||||
|
||||
<br>
|
||||
|
||||
Либо скопируйте нужные данные для подключения себе в `.kube/config`.
|
||||
|
||||
После настройки выполните команду и проверьте что вам вернулось
|
||||
что-то подобное. Это значит, что никаких ресурсов пока в
|
||||
кластере нет. Это мы исправим позже. Пока что можно сказать,
|
||||
что подключение прошло успешно.
|
||||
|
||||
```bash
|
||||
$ kubectl --context "my-context" get pods
|
||||
No resources found in default namespace.
|
||||
```
|
||||
|
||||
Если же у вас выпадает ошибка, например такая.
|
||||
|
||||
```
|
||||
The connection to the server localhost:8080 was refused - did you specify the right host or port?
|
||||
```
|
||||
|
||||
То либо запустите кластер
|
||||
|
||||
```
|
||||
sudo systemctl start k3s.service
|
||||
```
|
||||
|
||||
Либо у вас неверные данные для входа.
|
||||
|
||||
### Мониторинг кластера
|
||||
|
||||
Для просматривания управления кластером используется cli утилита `kubectl`.
|
||||
Но для того, чтобы с ней работать нужно получше понять что вообще в кластере есть.
|
||||
|
||||
Для этого я советую использовать [Lens](https://k8slens.dev/). Это крайне
|
||||
удобный интерфейс для управления своим кластером.
|
||||
Также там есть очень клёвая настрока, которая сама включит мониторинг
|
||||
потребления памяти и процессора для всех подов и кластера в общем.
|
||||
|
||||
На локальной машине это не очень много смысла имеет,
|
||||
а вот в проде было бы очень полезно.
|
||||
|
||||
Выглядит Lens примерно так:
|
||||
|
||||
<div align="center" style="margin-top:15px;">
|
||||
|
||||

|
||||
|
||||
</div>
|
||||
|
||||
Для изучения **крайне настоятельно рекомендую** настроить Lens.
|
||||
|
||||
# Ваше первое приложение в кластере.
|
||||
|
||||
### Сервер
|
||||
|
||||
Давайте создадим своё первое приложение.
|
||||
|
||||
Для этого я буду использовать [express.js](https://expressjs.com/), так как он крайне популярен и прост.
|
||||
|
||||
Для этого сначала напишем сам сервер. Я буду использовать yarn, но можете и npm,
|
||||
сути не поменяет.
|
||||
|
||||
Создайте какую-нибудь папку, где вы будете эксперементировать, откройте в ней ваш любимый тектовый редактор и просто копируйте файлы ниже.
|
||||
|
||||
```json{}[package.json]
|
||||
{
|
||||
"name": "req_counter",
|
||||
"version": "1.0.0",
|
||||
// Указан модуль,
|
||||
// чтобы использовать нормальны импорты,
|
||||
// а не require.
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
// Скрипт старта сервера.
|
||||
"server": "node index.js"
|
||||
},
|
||||
// Зависимости проекта.
|
||||
"dependencies": {
|
||||
"express": "^4.17.1"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
И само приложение
|
||||
|
||||
```js{}[index.js]
|
||||
import express from "express";
|
||||
import { hostname } from "os";
|
||||
import { argv, exit } from "process";
|
||||
|
||||
// Серверное приложение.
|
||||
const app = express();
|
||||
|
||||
// Глобальный счётчик входящих запросов.
|
||||
let requests = 0;
|
||||
|
||||
// Обработка входящего запроса.
|
||||
app.get("*", (req, res) => {
|
||||
// Увеличиваем глобальный счётчик запросов.
|
||||
requests += 1;
|
||||
// Логгируем входящий запрос.
|
||||
console.log(`${req.method} ${req.url}`);
|
||||
// Возвращаем информацию о текущем хосте и количестве запросов.
|
||||
res.json({
|
||||
requests: requests,
|
||||
hostname: hostname(),
|
||||
});
|
||||
});
|
||||
|
||||
// Аргументы командной строки.
|
||||
// Напрмиер yarn run server 127.0.0.1 8000
|
||||
const args = argv.slice(2);
|
||||
|
||||
// Если передано неверное количество аргументов.
|
||||
if (args.length != 2) {
|
||||
console.error("Usage: yarn run server {host} {port}");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Простейший "парсинг" аргументов командной строки.
|
||||
const host = args[0];
|
||||
const port = args[1];
|
||||
|
||||
// Старт сервера.
|
||||
app.listen(port, host, () => {
|
||||
console.log(`Server listening at http://${host}:${port}`);
|
||||
});
|
||||
```
|
||||
|
||||
Это всё. Сервер готов.
|
||||
|
||||
<hr>
|
||||
Протестируем запуск сервера выполнив команду ниже и открыв в
|
||||
своём любимом браузере http://localhost:8080.
|
||||
|
||||
```
|
||||
yarn run server 0.0.0.0 8080
|
||||
```
|
||||
|
||||
У меня всё работает и успешно отдаётся нужная информация.
|
||||
|
||||
```json
|
||||
{
|
||||
"requests": 1,
|
||||
"hostname": "s3rius-pc"
|
||||
}
|
||||
```
|
||||
|
||||
### Docker образ
|
||||
|
||||
Теперь создадим докер образ приложения.
|
||||
|
||||
Добавим `.dockerignore`, чтобы игнорировать ненужные файлы во время сборки образа.
|
||||
|
||||
```gitignore{}[.dockerignore]
|
||||
node_modules/
|
||||
```
|
||||
|
||||
И добавим в проект `Dockerfile` для описания самого процесса сборки.
|
||||
|
||||
```dockerfile{}[Dockerfile]
|
||||
FROM node:17-alpine
|
||||
|
||||
WORKDIR /app
|
||||
COPY . /app/
|
||||
|
||||
RUN yarn install
|
||||
|
||||
CMD [ "yarn", "run", "server", "0.0.0.0", "8000"]
|
||||
```
|
||||
|
||||
Давайте соберём и запустим проект в контейнере.
|
||||
|
||||
```bash
|
||||
docker build --tag="s3rius/req-counter-express:latest" .
|
||||
|
||||
docker run --rm -it -p 3400:8000 "s3rius/req-counter-express:latest"
|
||||
```
|
||||
|
||||
Можете проверить, что приложение работает успешно, открыв в браузере http://localhost:3400.
|
||||
|
||||
У меня в ответ пришло то же сообщение. Только, как можно заметить,
|
||||
`hostname` поменялся. На самом деле контейнеры используют свои hostname
|
||||
отличные от `hostname` локальной машины.
|
||||
|
||||
```json
|
||||
{
|
||||
"requests": 10,
|
||||
"hostname": "8f23adadc640"
|
||||
}
|
||||
```
|
||||
|
||||
Вариантов как положить это приложение в K8S несколько.
|
||||
|
||||
- Вы можете запушить собранное приложение в [Docker HUB](https://hub.docker.com/) и использовать его.
|
||||
- Можете использовать мой образ `s3rius/req-counter-express:latest`
|
||||
- Импортировать собранный образ как tar файл и импортировать его в containerd напрямую.
|
||||
Как это сделать почитать можно в [этой статье](https://cwienczek.com/2020/06/import-images-to-k3s-without-docker-registry/).
|
||||
|
||||
### Деплой в k8s
|
||||
|
||||
Создайте папку `kube` в папке проекта и теперь мы будем работать в ней.
|
||||
Все ресурсы будут описаны yaml-файлами.
|
||||
|
||||
```yaml{}[kube/deployment.yml]
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
# метаданные самого деплоймента.
|
||||
metadata:
|
||||
name: req-counter-deployment
|
||||
spec:
|
||||
# Количество реплик пода.
|
||||
replicas: 1
|
||||
# Селектор, который выбирает
|
||||
# какие поды принадлежат этому деплойменту.
|
||||
selector:
|
||||
matchLabels:
|
||||
app: req-counter
|
||||
# Шаблон пода,
|
||||
# который будет использоваться при
|
||||
# маштабировании.
|
||||
template:
|
||||
# Метаданные пода.
|
||||
# тут обычно помещаются лейблы,
|
||||
# с помощью которых деплоймент идентифицирует
|
||||
# свои поды.
|
||||
metadata:
|
||||
labels:
|
||||
app: req-counter
|
||||
spec:
|
||||
# Масссив контейнеров
|
||||
containers:
|
||||
# Название контейнера внутри пода.
|
||||
- name: req-counter-app
|
||||
# Образ приложения.
|
||||
image: s3rius/req-counter-express:latest
|
||||
# Ресурсы требуемые для работы приложения.
|
||||
resources:
|
||||
# Минимальное количество ресурсов,
|
||||
# которое кластер гарантированно предоставит приложению.
|
||||
# Также данные значения используются для того,
|
||||
# чтобы выяснить на какой ноде запускать приложение.
|
||||
requests:
|
||||
memory: "50Mi"
|
||||
cpu: "30m"
|
||||
# Максимально возможные значения приложения.
|
||||
# Если приложение выйдет за лимиты,
|
||||
# то кубер убьёт приложение.
|
||||
limits:
|
||||
memory: "128Mi"
|
||||
cpu: "100m"
|
||||
# Порты на которых открыты приложения.
|
||||
ports:
|
||||
- containerPort: 8000
|
||||
protocol: TCP
|
||||
```
|
||||
|
||||
Теперь опишем сервис для управления трафиком.
|
||||
|
||||
```yaml{}[kube/service.yml]
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
# Метадата сервиса.
|
||||
metadata:
|
||||
name: req-counter-service
|
||||
spec:
|
||||
# Селектор подов,
|
||||
# которым будет пускаться трафик.
|
||||
# Трафик может идти в любой под,
|
||||
# который матчит данному селектору.
|
||||
selector:
|
||||
app: req-counter
|
||||
# Порты для проксирования соединений.
|
||||
ports:
|
||||
# Порт сервиса
|
||||
- port: 80
|
||||
# Порт пода, куда будет идти трафик дальше.
|
||||
targetPort: 8000
|
||||
```
|
||||
|
||||
И в последнюю очередь опишем наш ингрес.
|
||||
|
||||
```yaml{}[kube/ingress.yml]
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
# Метаданные ингресса.
|
||||
metadata:
|
||||
name: req-counter-ingress
|
||||
labels:
|
||||
name: req-counter-ingress
|
||||
spec:
|
||||
# Правила роутинга.
|
||||
rules:
|
||||
# Требуемый хост.
|
||||
- host: req-counter.local
|
||||
http:
|
||||
paths:
|
||||
# Тип пути Prefix значит,
|
||||
# что все запросы, которые начинаются c
|
||||
# ${path} будут матчится тут.
|
||||
- pathType: Prefix
|
||||
# Сам путь.
|
||||
path: "/"
|
||||
backend:
|
||||
service:
|
||||
# Название нашего сервиса.
|
||||
name: req-counter-service
|
||||
# Порт сервиса, куда перенаправлять входящий трафик.
|
||||
port:
|
||||
number: 80
|
||||
```
|
||||
|
||||
Перед тем, как создать все описанные ресурсы создадим неймспейс.
|
||||
|
||||
```bash
|
||||
$ kubectl --context k3s create namespace req-couter-ns
|
||||
namespace/req-couter-ns created
|
||||
```
|
||||
|
||||
После того, как неймспейс создан самое время сделать последний штрих.
|
||||
|
||||
<div align="center">
|
||||
|
||||

|
||||
|
||||
</div>
|
||||
|
||||
```bash
|
||||
$ kubectl --context k3s --namespace req-couter-ns apply -f ./kube/
|
||||
deployment.apps/req-counter-deployment created
|
||||
ingress.networking.k8s.io/req-counter-ingress created
|
||||
service/req-counter-service created
|
||||
```
|
||||
|
||||
Готово. Теперь вы можете зайти в lens, выбрать свой кластер из списка
|
||||
и посмотреть как там поживает ваше приложение.
|
||||
|
||||
Также не забудьте указать неймспей, в который вы беплоиди приложение.
|
||||
|
||||
Выглядит это чудо примерно так:
|
||||
|
||||
<div align="center">
|
||||
|
||||

|
||||
|
||||
</div>
|
||||
|
||||
Также можно использовать команду и вывести всё себе в терминал.
|
||||
|
||||
```
|
||||
$ kubectl --context k3s --namespace req-couter-ns get all
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
pod/req-counter-deployment-764476db97-dt2tc 1/1 Running 0 8m11s
|
||||
|
||||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
service/req-counter-service ClusterIP 10.43.50.23 <none> 80/TCP 8m11s
|
||||
|
||||
NAME READY UP-TO-DATE AVAILABLE AGE
|
||||
deployment.apps/req-counter-deployment 1/1 1 1 8m11s
|
||||
|
||||
NAME DESIRED CURRENT READY AGE
|
||||
replicaset.apps/req-counter-deployment-764476db97 1 1 1 8m11s
|
||||
```
|
||||
|
||||
### Маштабирование
|
||||
|
||||
В рамках демонстрации давате поменяем значение
|
||||
`replicas` в нашем файле деплоймента до `3`.
|
||||
|
||||
```yaml{}[kube/deployment.yml]
|
||||
...
|
||||
spec:
|
||||
# Количество реплик пода.
|
||||
replicas: 3
|
||||
...
|
||||
```
|
||||
|
||||
После изменения просто ещё раз вызовите команду apply.
|
||||
|
||||
```bash
|
||||
$ kubectl --context k3s --namespace req-couter-ns apply -f ./kube/
|
||||
deployment.apps/req-counter-deployment configured
|
||||
ingress.networking.k8s.io/req-counter-ingress unchanged
|
||||
service/req-counter-service unchanged
|
||||
```
|
||||
|
||||
Как можно видеть изменился только наш `Deployment`.
|
||||
Остальные ресурсы остались нетронутыми.
|
||||
|
||||
Давайте посмотрим на поды в нашем неймспейсе.
|
||||
|
||||
```
|
||||
$ kubectl --context k3s --namespace req-couter-ns get pods
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
req-counter-deployment-764476db97-dt2tc 1/1 Running 0 13m
|
||||
req-counter-deployment-764476db97-tdjrb 1/1 Running 0 69s
|
||||
req-counter-deployment-764476db97-x28fr 1/1 Running 0 69s
|
||||
```
|
||||
|
||||
Как видно, всё правильно. Теперь у нас 3 пода
|
||||
нашего приложения.
|
||||
|
||||
|
||||
Теперь я пойду и выполню кучу запросов по адресу http://req-counter.local/
|
||||
и получу балансировку между подами из коробки, без дополнительных
|
||||
конфигураций.
|
||||
|
||||
Если у вас не получается найти адрес. Добавьте данный хост себе в
|
||||
`/etc/hosts` на линуксе или в `C:\Windows\System32\drivers\etc\hosts` на windows,
|
||||
дописав в конец файла следующее:
|
||||
|
||||
```
|
||||
...
|
||||
127.0.0.1 req-couter.local
|
||||
```
|
||||
|
||||
И теперь вы можете открыть в браузере своё приложение и увидеть,
|
||||
как кубернетес заботливо направляет трафик туда, куда вы хотите.
|
||||
|
||||
<div align="center">
|
||||
|
||||

|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### Как мне очистить мой кластер?
|
||||
|
||||
Всё очень просто.
|
||||
|
||||
Так как у нас имеются описния ресурсов, то мы
|
||||
можем удалить всё сразу используя команду
|
||||
|
||||
```bash
|
||||
$ kubectl --context k3s --namespace req-couter-ns delete -f ./kube/
|
||||
deployment.apps "req-counter-deployment" deleted
|
||||
ingress.networking.k8s.io "req-counter-ingress" deleted
|
||||
service "req-counter-service" deleted
|
||||
```
|
||||
|
||||
Таким образом k8s удалит все описанные ресурсы из вашего кластера.
|
||||
|
||||
До новых встреч.
|
Reference in New Issue
Block a user