Я новичок в кубернетах. Мне нужны предложения, как получить доступ к приложению, развернутому в кластере.
У меня есть образ докера с приложением Django и Gunicorn для запуска .wsgi. Я использую этот образ для развертывания контейнеров в кластере с 3 узлами (среда для изучения k8s, 1 мастер 2 рабочих). Если я открываю службу с помощью nodePort и использую curl <node'sIP>: [порт] с сервера, не включенного в кластер, я могу связаться с приложением.
Но теперь я хочу иметь единую точку входа, которая могла бы соединяться с любой из реплик.
Я думал о создании еще одной машины, не входящей в кластер с установленным Nginx или HAproxy, но не могу найти решения, как подключить внешний обратный прокси с сервисом kubernetes.
Можете ли вы дать мне лучшее решение или предложения, как мне продолжить свою мысль?
Вам не хватает пары фундаментальных концепций Kubernetes, на которые я рекомендую вам обратить внимание:
TL; DR
В управляемых кластерах Kubernetes типа GKE
, EKS
или AKS
у вас есть возможность запрашивать IP-адреса для услуг у вашего облачного провайдера.
Кластеры Kubernetes, созданные например в Virtualbox
используя либо kubespray
,kubeadm
потребуются дополнительные инструменты, чтобы получить External-IP
за услуги.
Ты можешь использовать metallb
назначить External-IP
в кластерах, не управляемых облачным провайдером. Посетите официальный сайт:
В этом случае шаги по раскрытию приложения будут следующими:
service
прикреплен к стручкамmetallb
и настроить егоLoadBalancer
Ingress
ресурсОтказ от ответственности!
Создание
Ingress
ресурс требуетIngress
контроллер. Я прикрепил ссылку на один из них.
Ниже я привел пример и дополнительные объяснения того, как вы можете открыть свое приложение в кластере, созданном в Virtualbox, с помощью metallb
и nginx-ingress-controller
.
Это пример, показывающий, как открыть приложение в кластере Kubernetes, созданном в Virtualbox, с помощью:
metallb
nginx-ingress-controller
Я разделил этот ответ на 2 части:
Когда вы создаете свой VM's
В Virtualbox у вас есть несколько способов настройки сети. Некоторые из них:
Bridged networking
- подключение кластера Kubernetes к физической сетиHost-only
- возможность подключения одного адаптера к узлам и хосту, обеспечивающего сетевое подключение. Для этого решения требуется либо другой адаптер с доступом в Интернет, либо шлюз (например, PfSense) с тем же Host-only
сетевой адаптер подключен.В этом примере используется клиент и 3 узла с Bridged
адаптеры:
client
с IP-адресом: 192.168.0.2
master
с IP-адресом: 192.168.0.117
worker1
с IP-адресом: 192.168.0.118
worker2
с IP-адресом: 192.168.0.119
Чтобы убедиться, что этот пример работает вне хоста, я использовал другое устройство в той же сети.
Убедитесь, что узлы имеют полное соединение друг с другом, а также что ваш хост имеет полный доступ к ним.
Предположим, что:
8000
)Шаги:
gunicorn
gunicorn
стручокMetallb
LoadBalancer
Ingress
ресурсgunicorn
Я использовал ниже развертывание определение для создания модуля, который будет отвечать на запросы:
apiVersion: apps/v1
kind: Deployment
metadata:
name: gunicorn
spec:
selector:
matchLabels:
app: gunicorn
replicas: 1
template:
metadata:
labels:
app: gunicorn
spec:
containers:
- name: gunicorn
image: ubuntu
command:
- sleep
- "infinity"
я использовал ubuntu
изображение, которое я exec
`d и выполните следующие команды:
$ apt update && apt install -y python3 python3-pip
$ pip3 install gunicorn
Пример кода, который я использовал myapp.py
:
def app(environ, start_response):
data = b"Hello, World!\n"
start_response("200 OK", [
("Content-Type", "text/plain"),
("Content-Length", str(len(data)))
])
return iter([data])
$ gunicorn -w 1 -b 0.0.0.0 myapp:app &
Приведенный выше пример основан на:
После этого ваш под должен ответить на порт. 8000
с участием Hello, World!
.
gunicorn
стручокОпределение службы для gunicorn
стручок:
apiVersion: v1
kind: Service
metadata:
name: gunicorn-service
spec:
selector:
app: gunicorn
ports:
- name: gunicorn-port
port: 8000
targetPort: 8000
type: NodePort
Metallb
После официального Metallb
документация: Metallb.universe.tf: Установка:
kube-proxy
изменить strictARP
режим от false
к true
: $ kubectl edit configmap -n kube-system kube-proxy
$ kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.3/manifests/namespace.yaml
$ kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.3/manifests/metallb.yaml
$ kubectl create secret generic -n metallb-system memberlist --from-literal=secretkey="$(openssl rand -base64 128)
Вам также нужно будет добавить configMap
это скажет metallb
какие IP-адреса он мог выделить для сервисов:
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: default
protocol: layer2
addresses:
- 192.168.0.240-192.168.0.250
Пожалуйста, обратите внимание на деталь:
addresses:
- 192.168.0.240-192.168.0.250
Убедитесь, что этот диапазон адресов не перекрывает какие-либо используемые адреса в вашей сети и что он находится в той же сети, что и узлы, и клиент.
После этого вы сможете создать сервис типа LoadBalancer
который получит IP-адрес.
LoadBalancer
Вы должны уметь запускать:
$ kubectl expose deployment gunicorn --type=LoadBalancer --port=8000
Выход $ kubectl get services
должен показать:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
gunicorn LoadBalancer 10.233.43.104 192.168.0.240 8000:32591/TCP 3s
gunicorn-service NodePort 10.233.34.96 <none> 8000:30862/TCP 73s
kubernetes ClusterIP 10.233.0.1 <none> 443/TCP 23h
как вы видете gunicorn
сервис имеет EXTERNAL-IP
из 192.168.0.240
который находится в пуле IP-адресов metallb
.
Физическая сеть, используемая в этом примере:
192.168.0.0/24
Вы можете запустить: curl 192.168.0.240:8000
и получить: Hello, World!
Ingress
ресурсВам нужно будет развернуть Ingress
контроллер перед открытием вашего приложения. Вы можете развернуть nginx-ingress-controller
запустив:
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/cloud/deploy.yaml
это Ingress
у контроллера будет тип службы LoadBalancer
прикреплен к нему, и это будет входная точка по запросу.
Вы можете получить его IP-адрес, вызвав: $ kubectl get svc -n ingress-nginx
:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller LoadBalancer 10.233.52.8 192.168.0.241 80:31380/TCP,443:30066/TCP 29m
ingress-nginx-controller-admission ClusterIP 10.233.37.255 <none> 443/TCP 29m
Здесь Ingress
определение для маршрутизации трафика от контроллера к вашему модулю:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: gunicorn-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host:
http:
paths:
- path: /
backend:
serviceName: gunicorn-service
servicePort: gunicorn-port
После его применения вы сможете:
curl 192.168.0.241
и получить ответ от gunicorn