====== Доступ к приложениям в Bare-Metal Kubernetes ======
===== Реклама =====
* Если Вы придерживаетесь рекомендации "не разворачивайте Kubernetes сами, а воспользуетесь managed service" то эту задачу за Вас решит провайдер, но, если Ваш путь - Kubernetes The Hard Way - Bare Metal, добро пожаловать поскольку эта тема меньше других освещена в документации
* На нашем вебинаре мы на практических примерах разберем использование вариантов доступа к приложениям в Kubernetes через port-forward, proxy и ingress, узнаем, как лучше развернуть Ingress Controller и выясним, чем отличаются балансировщики нагрузки Nginx, HAProxy и Keepalived
===== Техническое задание =====
* Развернуть несколько web приложений, в том числе, Keycloak, в корпоративном On-Premises Kubernetes
* Предоставить к ним безопасный, отказоустойчивой https доступ
===== Запись вебинара =====
* https://youtu.be/oIczkkD-hOU
* Тэги: Kubernetes, LoadBalancer, ClusterIP, MetalLB, Nginx, Keepalived, Ingress-Nginx, Helm, HAProxy, ArgoCD, Dashboard
===== Методическая подготовка =====
* В процессе прохождения курса [[DevOps2. Использование Kubernetes]] в конце лабораторной работы 5.3 обнаружено, что кластер kubernetes, развернутый kubespray не поддерживает insecure-registry
* Вместо решения, описанного в последнем фрагменте видео выбираем альтернативный вариант
===== Шаг 1. Исходные данные =====
* kubernetes развернут через kubespray "по дефолту" (уже сделано, что бы не ждать 40 минут)
~/kubespray# time ansible-playbook -i inventory/mycluster/hosts.yaml reset.yml
~/kubespray# git checkout origin/release-2.22
~/kubespray# time pip3 install -r requirements.txt
~/kubespray# cp -rvfpT inventory/sample inventory/mycluster
~/kubespray# time ansible-playbook -i inventory/mycluster/hosts.yaml cluster.yml
kube1:~# kubectl get nodes
kube1:~# kubectl get ns
* GitLab и его registry c http доступом и проектом с образом gowebd
===== Шаг 2. Переводим GitLab и его registry на https =====
* [[Пакет OpenSSL#Создание самоподписанного сертификата]] wildcard
* [[Инструмент GitLab#Включение TLS]]
* [[Инструмент GitLab#Установка через docker-compose]]
===== Шаг 3. Добавляем корпоративный сертификат в кластер kubernetes и рабочие станции =====
server#
mkdir -p /var/www/html/
cp wild.crt /var/www/html/ca.crt
bash -c '
scp /var/www/html/ca.crt kube1:/usr/local/share/ca-certificates/
ssh kube1 update-ca-certificates
ssh kube1 systemctl restart containerd
scp /var/www/html/ca.crt kube2:/usr/local/share/ca-certificates/
ssh kube2 update-ca-certificates
ssh kube2 systemctl restart containerd
scp /var/www/html/ca.crt kube3:/usr/local/share/ca-certificates/
ssh kube3 update-ca-certificates
ssh kube3 systemctl restart containerd
'
kubeN#
crictl pull server.corp13.un:5000/student/gowebd
crictl images
crictl rmi server.corp13.un:5000/student/gowebd
* Разворачиваем win client2 (ip/m: 172.16.1.100+X/24, dns: 192.168.X.10)
* В паузах:
* Знакомимся
* Схема стенда (новые названия сетей LAN - KUBENET, INTERNET - CORPNET)
* [[Преимущества обучения в specialist.ru]]
* Добавляем в client2 ca.crt
server# ss -lnp | grep ':80'
server# apt install apache2
server# rm /var/www/html/index.html
* Проверяем https доступ в gitlab с client2 и загрузку образа в k8s
===== Шаг 4. Доступ к приложению в Kubernetes через LoadBalancer =====
* Разворачиваем gowebd в [[Система Kubernetes#namespace для своего приложения]] с kube1
* Добавляем LoadBalancer [[Система Kubernetes#MetalLB]]
* Добавляем [[Система Kubernetes#Service]] типа LoadBalancer
===== Шаг 5. Использование Nginx для HTTPS доступа к приложению =====
server# scp wild.crt gate:gowebd.crt; scp wild.key gate:gowebd.key
* Устанавливаем на gate [[Сервис HTTP#NGINX]]
* Настраиваем [[Сервис HTTP#HTTPS Прокси (пример 4)]]
server# cat /etc/bind/corpX.un
...
gowebd A 172.16.1.13
* Тестируем с client2
C:\Users\student>nslookup gowebd.corp13.un
MSIE: https://gowebd.corp13.un
* Тестируем отказоустойчивость, отключая узлы kubeN
===== Шаг 6. Делаем отказоустойчивым gate =====
* Импортируем gate2
server# cat /etc/bind/corp13.un
...
gate1 A 192.168.13.21
gate2 A 192.168.13.22
* Превращаем gate в gate1
gate# hostnamectl set-hostname gate1.corp13.un
gate# cat /etc/network/interfaces
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
address 192.168.13.2N
netmask 255.255.255.0
gateway 192.168.13.1
auto eth1
iface eth1 inet manual
up ip link set eth1 up
* Устанавливаем [[Сервис Keepalived]]
gateN# cat /etc/keepalived/keepalived.conf
vrrp_instance KUBE_GATE {
state MASTER
# state BACKUP
interface eth0
virtual_router_id 1
virtual_ipaddress {
172.16.1.13/24 dev eth1
192.168.13.1/24 dev eth0
}
virtual_routes {
0.0.0.0/0 via 172.16.1.254 dev eth1
}
}
gate# init 6
gate2# ifconfig eth0 inet 192.168.13.22
server#
ssh-copy-id gate1
ssh-copy-id gate2
server#
scp -3 gate1:/etc/network/interfaces gate2:/etc/network/
scp -3 gate1:/etc/resolv.conf gate2:/etc/
scp -3 gate1:/etc/sysctl.conf gate2:/etc/
gate2# hostnamectl set-hostname gate2.corp13.un
gate2# cat /etc/network/interfaces
gate2# init 6
gate2# apt update && apt install keepalived nginx -y
server#
scp -3 gate1:/etc/keepalived/keepalived.conf gate2:/etc/keepalived/
scp -3 gate1:/etc/nginx/sites-available/gowebd gate2:/etc/nginx/sites-available/gowebd
scp -3 gate1:/etc/nginx/sites-enabled/gowebd gate2:/etc/nginx/sites-enabled/gowebd
scp -3 gate1:gowebd.* gate2:
gate2# cat /etc/keepalived/keepalived.conf
* Сервис Keepalived [[Сервис Keepalived#Запуск и мониторинг]]
* Сервис Nginx [[Сервис HTTP#Подключение, тестирование, применение и мониторинг конфигурации]]
server# ssh gate1 tail -f /var/log/nginx/access.log
server# ssh gate2 tail -f /var/log/messages
* Обсуждаем достоинства (все работает) и недостатки (учет IP адресов в ПО версии 0.14.3 :)
* Если есть время и желание выполняем [[#Шаг 6.2. Закрываем доступ в сеть кластера]]
===== Шаг 7. Заменяем nginx на ingress-nginx =====
* Меняем [[Система Kubernetes#Service]] на ClusterIP
* Удаляем [[Система Kubernetes#MetalLB]]
gateN# systemctl disable nginx --now
* Установка [[Система Kubernetes#Helm]] на kube1
* Развертываем через [[Система Kubernetes#Работа с готовыми Charts]] [[Система Kubernetes#ingress-nginx]]
===== Шаг 8. Использование ingress для http/https доступа к приложению =====
server:~# scp wild.key kube1:gowebd.key; scp wild.crt kube1:gowebd.crt
* Создаем [[Система Kubernetes#secrets tls]] для приложения gowebd
* Развертываем [[Система Kubernetes#ingress example]] для приложения gowebd
$ curl --connect-to "":"":kubeN:443 https://gowebd.corpX.un #-vk
* Обсуждаем, почему не стоит прописать в DNS адреса узлов k8s для приложения gowebd?
===== Шаг 9. Отказоустойчивой доступ к приложению с использованием Keepalived =====
gateN# cat /etc/keepalived/keepalived.conf
...
virtual_server 172.16.1.13 443 {
protocol TCP
lb_algo wlc
lb_kind NAT
real_server 192.168.13.221 443 {TCP_CHECK {}}
real_server 192.168.13.222 443 {TCP_CHECK {}}
real_server 192.168.13.223 443 {TCP_CHECK {}}
}
* Сервис Keepalived [[Сервис Keepalived#Запуск и мониторинг]]
* Обсуждаем достоинства (все работает) и недостатки (сертификаты внутри кластера, кластер только один)
===== Шаг 10. Использование Helm репозитория для развертывания http приложения =====
kube1# kubectl delete ns my-ns
* Продолжаем с момента, на котором остановились в курсе - [[Система Kubernetes#Работа со своим репозиторием]] Helm для переноса приложения с node на kube кластер
$ curl http://kubeN/ -H "Host: gowebd.corp13.un"
===== Шаг 11. Использование HAProxy для https доступа к приложению =====
* Комментируем virtual_server в keepalived на gateN
server# scp wild.* gate1:
* [[Решение HAProxy]]
server# ssh gate2 apt install haproxy
server#
scp -3 gate1:/etc/ssl/private/* gate2:/etc/ssl/private/
scp -3 gate1:/etc/haproxy/haproxy.cfg gate2:/etc/haproxy/haproxy.cfg
ssh gate2 service haproxy restart
server# ssh gateN tail -f /var/log/haproxy.log
===== Шаг 12. Использование ArgoCD для развертывания http приложения =====
* Удаляем приложение, можно просто namespace
kube1# kubectl delete ns my-ns
* Разворачиваем [[Контроллер ArgoCD]]
* Устанавливаем [[Система Kubernetes#Инструмент командной строки kubectl]] и настраиваем [[Система Kubernetes#Подключение к кластеру]] на рабочей станции администратора
* Используя port-forward подключаем рабочую станцию администратора к ArgoCD
* Используя [[Контроллер ArgoCD#Управление приложениями через kubectl]] разворачиваем приложение
* Подключаемся через [[Система Kubernetes#port-forward]] к нашему приложению
cmder> kubectl port-forward -n my-ns services/my-webd-webd-chart 1234:80
* http://localhost:1234/
* Меняем в файле проекта gowebd-k8s/webd-chart/Chart.yaml версию образа и ждем обновление через argocd
===== Шаг 13. Использование Dashboard для работы с кластером =====
* Разворачиваем [[Система Kubernetes#Kubernetes Dashboard]]
* Используя [[Система Kubernetes#kubectl proxy]] подключаем рабочую станцию администратора к Dashboard
* Подключаемся через [[Система Kubernetes#kubectl proxy]] к нашему приложению
* http://localhost:8001/api/v1/namespaces/my-ns/services/my-webd-webd-chart:80/proxy/
===== Шаг 14. Готовимся к развертыванию Кeycloak =====
* Настраиваем HAProxy на работу с несколькими кластерами
gate1#
cp /etc/ssl/private/wild.crtkey /etc/ssl/private/gowebd.crtkey
cp /etc/ssl/private/wild.crtkey /etc/ssl/private/keycloak.crtkey
gate1# cat /etc/haproxy/haproxy.cfg
...
gate1# service haproxy restart
server#
scp -3 gate1:/etc/haproxy/haproxy.cfg gate2:/etc/haproxy/haproxy.cfg
scp -3 gate1:/etc/ssl/private/* gate2:/etc/ssl/private/
ssh gate2 service haproxy restart
===== Вопросы =====
* Сколько вариантов доступа к приложению в k8s Вы насчитали? :)
===== Дополнительные материалы =====
===== Шаг 6.2. Закрываем доступ в сеть кластера =====
* Добавляем [[Сервис NAT]]
gateN# apt install iptables conntrack iptables-persistent
gateN#
iptables -t nat --flush
iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to-source 172.16.1.13
iptables -t nat -A PREROUTING -i eth1 --destination 172.16.1.13 -p udp --dport 53 -j DNAT --to-destination 192.168.13.10:53
iptables --flush
iptables -A FORWARD -i eth0 -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i eth1 -p udp -d 192.168.13.10 --dport 53 -j ACCEPT
iptables -A FORWARD -j DROP
conntrack -F
netfilter-persistent save
* Настраиваем win client2 dns: 172.16.1.13
===== Как все вернуть обратно =====
* 1. Удалить gowebd с kube
kube1:~# kubectl delete -f application.yaml
kube1:~# kubectl delete ns my-ns
kube1:~# rm application.yaml
kube1:~# crictl rmi server.corp13.un:5000/student/gowebd:ver1.1
kube1:~# crictl rmi server.corp13.un:5000/student/gowebd:ver1.2
* 2. Удалить [[Система Kubernetes#Kubernetes Dashboard]] и Argo CD
kube1:~# kubectl delete -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
kube1:~# kubectl delete ns argocd
cmder> rm -rf ~/.kube/
cmder> rm /usr/bin/kubectl.exe
* 3. Удалить ingress-nginx и Helm с kube1
kube1:~# helm delete ingress-nginx --namespace ingress-nginx
kube1:~# kubectl delete ns ingress-nginx
kube1:~# rm -r helm* linux-amd64/ /usr/local/bin/helm
kube1:~# rm -r gowebd/ ingress-nginx/
* 4. Удалить корневые сертификаты с kubeN
kubeN#
rm /usr/local/share/ca-certificates/ca.crt /etc/ssl/certs/ca.pem
update-ca-certificates
systemctl restart containerd
* 5. Удалить манифесты и сертификаты проекта gowebd с kube1
kube1:~# rm gowebd.crt gowebd.key my-ingress.yaml my-webd-service.yaml my-webd-deployment.yaml
* 6. Удалить VM client2 и gate2
* 7. Перезагрузить gate.isp.un
* 8. Восстановить из снапшотов gate и server
* 9. Удалить, чего не было в курсе
server# rm -rf /var/www/
server# rm server.key