diff --git a/README.md b/README.md index c648c99..37018ac 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ * [Развертывание VPN-сервера на базе MS SSTP](docker/docker-sstp-vpn.md) * [Развертывание прокси базе Shadowsocks (сервер и клиент)](docker/docker-shadowsocks.md) +## Kubernetes (k3s/k8s) +* [Установка k3s на Orange Pi 5 Plus](raspberry-and-orange-pi/k3s.md) +* [Под с Shadowsocks-клиент](kubernetes/k3s-shadowsocks-client.md) (k3s) + ## Python * [Устранение проблем при установке Python-коннектора mysqlclient (MySQL/MariaDB)](python/python-mysql.md) * [Python-скрипт как служба Linux](python/python_as_service.md) diff --git a/kubernetes/k3s-custom-container-deployment.md b/kubernetes/k3s-custom-container-deployment.md new file mode 100644 index 0000000..729a29e --- /dev/null +++ b/kubernetes/k3s-custom-container-deployment.md @@ -0,0 +1,343 @@ +# Развертывание пользовательского контейнера в k3s + + + + +Теперь нам нужно передать образ контейнера на другие ноды кластера. Для этого сначала извлечём образ из k3s в tar-файл: +```bash +sudo docker save shadowsocks-with-tools:latest -o /tmp/shadowsocks.tar +``` + +Затем передадим на вторую ноду, в нашем случае на хосте `192.168.1.28`, затем на третью (придется копировать через +`sudo`, т.к. при создании образа в tar-файл мы тоже использовали `sudo`): +```bash +sudo scp /tmp/shadowsocks.tar opi@192.168.1.28:/tmp/ +``` + +Импортируем на второй ноде этот образ в k3s. Небезопасное использование пароля удаленного хоста в команде, требуется т.к. +в команде через `ssh` не предоставляется интерактивный терминал, а SSH-ключи решают аутентификацию только для входа, но +не для выполнения `sudo` на удалённой машине... c помощью ключа `-S` мы заставляем `sudo` га уделенном хсте +читать пароль из `stdin`, и потому при введении пароля на текущем хосте он будет виден на экране... это выглядит опасно, +но менее безопасно чем передать его с помощью `echo` в команде `echo 'your_password' |` добавив перед `sido -S k3s ...`. +Так пароль, по крайне мере, не будет сохранён в `bash_history`, что было бы совсем, совсем не безопасно (а экран мы +можем очистить после, выполнив команду `clear`): +```bash +ssh opi@192.168.1.28 "echo 'your_password' | sudo -S k3s ctr images import /tmp/shadowsocks.tar" +``` + +Увидим что-то вроде: +```text +unpacking docker.io/library/shadowsocks-with-tools:latest (sha256:ae615618ce9d2aac7d3764ef735108452adf3fc30bb65f23f28c345798880c80)...done +``` + +Удалим временный файл на второй ноде: +```bash +ssh opi@192.168.1.28 "rm /tmp/shadowsocks.tar" +``` + +И убедимся, что образ появился в k3s на второй ноде (снова используем ключ `-S`): +```bash +ssh opi@192.168.1.28 "sudo -S k3s ctr images ls | grep shadowsocks" +``` + +**Повторяем операцию для третьей ноды**. И можем удалить временный файл на первой ноде: +```bash +sudo rm /tmp/shadowsocks.tar +``` + + +---- +Отлично, что всё получилось! Рад, что мы дошли до этого момента вместе. Твой вопрос про "секретные" контейнеры и необходимость публиковать их в Docker Hub — очень важный и актуальный, особенно для больших кластеров или чувствительных данных. Давай разберём это подробно, чтобы ты понял все варианты и мог выбрать тот, который подходит тебе. + +Нужно ли выкладывать "секретный" контейнер в Docker Hub? +Ты прав: если твой контейнер содержит секреты (например, ключи, пароли, защищённые алгоритмы), выкладывать его в публичный реестр вроде Docker Hub — не лучшая идея. Даже если сделать репозиторий приватным на Docker Hub, это всё равно означает передачу твоего образа третьей стороне, что может быть нежелательно с точки зрения безопасности или лицензирования. + +Ответ: Нет, тебе не обязательно публиковать контейнер в Docker Hub. Есть несколько способов хранить и распространять образы "у себя", внутри твоей сети, без выхода в интернет. Давай разберём варианты. + +Варианты хранения и использования контейнеров +1. Локальное использование (как сейчас) +Как это работает: +Ты уже сделал это: собрал образ shadowsocks-with-tools локально и импортировал его в containerd на каждом узле через k3s ctr images import. +В deployment.yaml указал imagePullPolicy: Never, чтобы k3s использовал только локальный образ. +Плюсы: +Никаких внешних реестров — всё остаётся на твоих машинах. +Полный контроль над секретами. +Минусы: +Не масштабируется: нужно вручную копировать образ на каждый узел. +Если узлов сотни, это становится непрактичным. +Вывод: Подходит для небольшого кластера (как твои три мастера), но не для больших систем. + +2. Приватный реестр Docker Hub +Как это работает: +Создаёшь приватный репозиторий на Docker Hub (бесплатно одно приватное репо, дальше платно). +Выкладываешь образ: +bash + +Collapse + +Wrap + +Copy +sudo docker tag shadowsocks-with-tools yourusername/shadowsocks-with-tools:latest +sudo docker push yourusername/shadowsocks-with-tools:latest +В deployment.yaml: +yaml + +Collapse + +Wrap + +Copy +image: yourusername/shadowsocks-with-tools:latest +Настраиваешь доступ через imagePullSecrets в k3s: +yaml + +Collapse + +Wrap + +Copy +apiVersion: v1 +kind: Secret +metadata: + name: dockerhub-credentials + namespace: kube-system +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: +Где — это закодированный JSON с твоими логином и паролем от Docker Hub: +bash + +Collapse + +Wrap + +Copy +echo -n '{"auths":{"https://index.docker.io/v1/":{"username":"yourusername","password":"yourpassword"}}}' | base64 +Добавь в Deployment: +yaml + +Collapse + +Wrap + +Copy +spec: + imagePullSecrets: + - name: dockerhub-credentials +Плюсы: +k3s сам скачивает образ на всех узлах. +Репозиторий приватный, доступ только по ключам. +Минусы: +Образ всё равно уходит в облако. +Ограничения бесплатного плана (1 приватное репо). +Вывод: Подходит, если доверяешь Docker Hub, но не идеально для "секретов". + +3. Локальный приватный реестр в твоей сети +Как это работает: +Разворачиваешь свой собственный реестр на одном из серверов (например, opi5plus-3, 192.168.1.26). +Используешь официальный образ registry: +bash + +Collapse + +Wrap + +Copy +sudo docker run -d -p 5000:5000 --restart=always --name registry registry:2 +Тегни и выложи свой образ: +bash + +Collapse + +Wrap + +Copy +sudo docker tag shadowsocks-with-tools:latest 192.168.1.26:5000/shadowsocks-with-tools:latest +sudo docker push 192.168.1.26:5000/shadowsocks-with-tools:latest +В deployment.yaml: +yaml + +Collapse + +Wrap + +Copy +image: 192.168.1.26:5000/shadowsocks-with-tools:latest +Безопасность (опционально): +Добавь TLS и аутентификацию: +Сгенерируй сертификаты: +bash + +Collapse + +Wrap + +Copy +mkdir -p /etc/docker/certs +openssl req -newkey rsa:4096 -nodes -sha256 -keyout /etc/docker/certs/registry.key -x509 -days 365 -out /etc/docker/certs/registry.crt +Запусти реестр с TLS: +bash + +Collapse + +Wrap + +Copy +sudo docker run -d -p 5000:5000 --restart=always --name registry \ + -v /etc/docker/certs:/certs \ + -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/registry.crt \ + -e REGISTRY_HTTP_TLS_KEY=/certs/registry.key \ + registry:2 +Настрой аутентификацию через htpasswd: +bash + +Collapse + +Wrap + +Copy +sudo apt install apache2-utils +mkdir -p /etc/docker/auth +htpasswd -Bc /etc/docker/auth/htpasswd username password +docker run -d -p 5000:5000 --restart=always --name registry \ + -v /etc/docker/certs:/certs \ + -v /etc/docker/auth:/auth \ + -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/registry.crt \ + -e REGISTRY_HTTP_TLS_KEY=/certs/registry.key \ + -e REGISTRY_AUTH=htpasswd \ + -e REGISTRY_AUTH_HTPASSWD_REALM="Registry Realm" \ + -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \ + registry:2 +Создай Secret для k3s: +yaml + +Collapse + +Wrap + +Copy +apiVersion: v1 +kind: Secret +metadata: + name: registry-credentials + namespace: kube-system +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: +Где : +bash + +Collapse + +Wrap + +Copy +echo -n '{"auths":{"192.168.1.26:5000":{"username":"username","password":"password"}}}' | base64 +В deployment.yaml: +yaml + +Collapse + +Wrap + +Copy +spec: + imagePullSecrets: + - name: registry-credentials +Плюсы: +Образ остаётся в твоей сети. +Полный контроль над доступом. +k3s сам скачивает образ на узлах. +Минусы: +Нужно настроить реестр и поддерживать его. +Вывод: Идеально для "секретных" контейнеров в большом кластере. + +4. Другие приватные реестры (Harbor, Nexus, etc.) +Если кластер большой, можешь развернуть более мощный реестр, например: +Harbor: Open-source, с UI, ролями и интеграцией с Kubernetes. +Nexus Repository: Поддерживает Docker и другие форматы. +Установка сложнее, но для сотен узлов это оправдано. +Ответ на твой вопрос +Можно ли хранить контейнеры у себя? Да, можно! Локальный реестр (Вариант 3) — это то, что тебе нужно. Ты разворачиваешь его на своём сервере (например, 192.168.1.26:5000), загружаешь туда образы, и k3s тянет их оттуда. Никакого Docker Hub, всё под твоим контролем. +Секреты: Они остаются в твоей сети, и доступ ограничивается твоими правилами (TLS, пароли). +Для твоего случая +Сейчас у тебя 3 узла, и локальный импорт работает. Но если кластер вырастет, настрой локальный реестр: + +bash + +Collapse + +Wrap + +Copy +sudo docker run -d -p 5000:5000 --restart=always --name registry registry:2 +sudo docker tag shadowsocks-with-tools:latest 192.168.1.26:5000/shadowsocks-with-tools:latest +sudo docker push 192.168.1.26:5000/shadowsocks-with-tools:latest +В deployment.yaml: + +yaml + +Collapse + +Wrap + +Copy +image: 192.168.1.26:5000/shadowsocks-with-tools:latest +Проверка Shadowsocks +Теперь, когда под работает, давай проверим Shadowsocks: + +Зайди в под: +bash + +Collapse + +Wrap + +Copy +sudo k3s kubectl exec -it -n kube-system shadowsocks-client-stockholm- -- sh +TCP: +bash + +Collapse + +Wrap + +Copy +curl --socks5 127.0.0.1:1081 http://ifconfig.me +Ожидаемый результат: . +UDP: +bash + +Collapse + +Wrap + +Copy +nc -u -l 12345 +С VPS: +bash + +Collapse + +Wrap + +Copy +echo "test" | nc -u v-panel.sw.cube2.ru 12345 +Логи: +bash + +Collapse + +Wrap + +Copy +sudo k3s kubectl logs -n kube-system -l app=shadowsocks-client-stockholm +Итог +"Секретные" контейнеры не нужно выкладывать в Docker Hub — храни их в локальном реестре. +Для проверки Shadowsocks используй команды выше. +Напиши: + +, , имя пользователя. +Результат проверки (curl, nc, логи). +Ты круто всё освоил — теперь ты готов к любым кластерам! Я с тобой! \ No newline at end of file diff --git a/raspberry-and-orange-pi/k3s.md b/raspberry-and-orange-pi/k3s.md index 7d8a5f2..a5bbb2d 100644 --- a/raspberry-and-orange-pi/k3s.md +++ b/raspberry-and-orange-pi/k3s.md @@ -14,9 +14,13 @@ IoT-устройства, edge-серверы и т.п.). Для кластер * Для моего проекта особо важно, что из коробки мастер-узел(ы)) в k3s является "гибридным" и выполняет одновременно функции управления (control-plane) и может запускать обычные поды, как воркер. Компоненты управления (API-сервер, контроллеры, etcd) работают как системные сервисы, а для пользовательских подов используется тот же kubelet, - что и на воркерах. + что и на воркерах. _**Кстати, что такое "поды".** Контейнеры в Kubernates называют "поды", чтобы отличать их от + Docker-контейнеров и подчёркивать, что это абстракция уровня оркестрации. Но под — это не просто контейнер, это + сущность Kubernetes, которая может включать несколько контейнеров, сетевые настройки и тома. Но под капотом + контейнеры всё равно запускаются runtime’ом (это containerd в k3s). И Docker все равно еще нужен для создания + образов, и если при установке k3s не указать `--docker` то k3s будет использовать его как runtime._ -Но, есть у k3s и минус для конкретно моего случая -- распределенная база **etcd**, в которой хранится состояния +Но, есть у k3s и минус для конкретно моего случая -- распределенная база **etcd**, в которой хранится состояния кластера, нод и подов, в нем заменена SQLite. Это круто для маленьких компьютеров: экономно по памяти и другим ресурсам, и, что главное, никак не сказывается на производительности (пока узлов меньше 50-80), но означает, что в кластере k3s может быть только одна мастер-нода. Если мастер-нода упадет, её некому будет заменить и весь кластер умрет. @@ -651,3 +655,8 @@ SSH-тоннель с помощью `autossh` и упаковкой UDP-тра Другим вариантом является подключение внутри самих подов на удаленном узле к необходимым сервисам напрямую. Но таким образом порты базы данных, менеджеров очередей и т.д. будут доступны из интернета, что небезопасно и в целом плохая идея. + + + + +