Разоблачение голого металлического кластера kubernetes для интернета
Я пытаюсь настроить собственный одноузловой кластер kubernetes на голом выделенном сервере. Я не настолько опытен в разработке, но мне нужен какой-то сервис для моего собственного проекта. Я уже сделал настройку кластера с juju
а также conjure-up kubernetes
над LXD
, У меня работает кластер довольно хорошо.
$ juju status
Model Controller Cloud/Region Version SLA Timestamp
conjure-canonical-kubern-3b3 conjure-up-localhost-db9 localhost/localhost 2.4.3 unsupported 23:49:09Z
App Version Status Scale Charm Store Rev OS Notes
easyrsa 3.0.1 active 1 easyrsa jujucharms 195 ubuntu
etcd 3.2.10 active 3 etcd jujucharms 338 ubuntu
flannel 0.10.0 active 2 flannel jujucharms 351 ubuntu
kubeapi-load-balancer 1.14.0 active 1 kubeapi-load-balancer jujucharms 525 ubuntu exposed
kubernetes-master 1.13.1 active 1 kubernetes-master jujucharms 542 ubuntu
kubernetes-worker 1.13.1 active 1 kubernetes-worker jujucharms 398 ubuntu exposed
Unit Workload Agent Machine Public address Ports Message
easyrsa/0* active idle 0 10.213.117.66 Certificate Authority connected.
etcd/0* active idle 1 10.213.117.171 2379/tcp Healthy with 3 known peers
etcd/1 active idle 2 10.213.117.10 2379/tcp Healthy with 3 known peers
etcd/2 active idle 3 10.213.117.238 2379/tcp Healthy with 3 known peers
kubeapi-load-balancer/0* active idle 4 10.213.117.123 443/tcp Loadbalancer ready.
kubernetes-master/0* active idle 5 10.213.117.172 6443/tcp Kubernetes master running.
flannel/1* active idle 10.213.117.172 Flannel subnet 10.1.83.1/24
kubernetes-worker/0* active idle 7 10.213.117.136 80/tcp,443/tcp Kubernetes worker running.
flannel/4 active idle 10.213.117.136 Flannel subnet 10.1.27.1/24
Entity Meter status Message
model amber user verification pending
Machine State DNS Inst id Series AZ Message
0 started 10.213.117.66 juju-b03445-0 bionic Running
1 started 10.213.117.171 juju-b03445-1 bionic Running
2 started 10.213.117.10 juju-b03445-2 bionic Running
3 started 10.213.117.238 juju-b03445-3 bionic Running
4 started 10.213.117.123 juju-b03445-4 bionic Running
5 started 10.213.117.172 juju-b03445-5 bionic Running
7 started 10.213.117.136 juju-b03445-7 bionic Running
Я также развернул приложение Hello world для вывода приветствия через порт 8080
внутри стручка и nginx-ingress
чтобы он перенаправил трафик на этот сервис на указанном хосте.
NAME READY STATUS RESTARTS AGE
pod/hello-world-696b6b59bd-fznwr 1/1 Running 1 176m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/example-service NodePort 10.152.183.53 <none> 8080:30450/TCP 176m
service/kubernetes ClusterIP 10.152.183.1 <none> 443/TCP 10h
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/hello-world 1/1 1 1 176m
NAME DESIRED CURRENT READY AGE
replicaset.apps/hello-world-696b6b59bd 1 1 1 176m
Когда я делаю curl localhost
как и ожидалось connection refused
, который выглядит все еще хорошо, поскольку он не подвергается воздействию кластера. когда я сверну kubernetes-worker/0
с публичным адресом 10.213.117.136
в порту 30450
(который я получаю от kubectl get all
)
$ curl 10.213.117.136:30450
Hello Kubernetes!
Все работает как шарм (что очевидно). Когда я делаю
curl -H "Host: testhost.com" 10.213.117.136
Hello Kubernetes!
Он снова работает как шарм! Это означает, что входной контроллер успешно маршрутизирует порт 80 на основе host
Правило исправить услуги. На данный момент я на 100% уверен, что кластер работает как надо.
Сейчас я пытаюсь получить доступ к этой услуге через Интернет извне. Когда я загружаю <server_ip>
очевидно, ничего не загружается, так как он живет внутри собственного lxd
подсети. Поэтому я думал вперед порт 80
с сервера eth0
на этот IP. Поэтому я добавил это правило в iptables
sudo iptables -t nat -A PREROUTING -p tcp -j DNAT --to-destination 10.213.117.136
(Для примера давайте маршрутизируем все, а не только порт 80). Теперь, когда я открываю на своем компьютере http://<server_ip>
это загружает!
Так что настоящий вопрос в том, как это сделать на производстве? Должен ли я установить это правило пересылки в iptables? Это нормальный подход или хакерское решение и есть что-то "стандартное", которого мне не хватает? Дело в том, чтобы добавить это правило со статическим worker
узел сделает кластер полностью статичным. IP в конце концов изменится, я могу удалить / добавить юниты к работникам и он перестанет работать. Я думал о написании сценария, который получит этот IP-адрес от juju
как это:
$ juju status kubernetes-worker/0 --format=json | jq '.machines["7"]."dns-name"'
"10.213.117.136"
и добавить его в IP-таблицы, что является более подходящим решением, чем жестко закодированный IP, но все же я чувствую, что это сложно, и должен быть лучший способ.
Как последняя идея, я бегу HAProxy
вне кластера, прямо на машине и просто делайте пересылку трафика всем доступным работникам. Это может в конечном итоге также работать. Но все же я не знаю ответа, что это correct
решение и что обычно используется в этом случае. Спасибо!
1 ответ
Так что настоящий вопрос в том, как это сделать на производстве?
Обычный способ сделать это в производственной системе - использовать Сервис.
Самый простой случай - это когда вы просто хотите, чтобы ваше приложение было доступно извне на вашем узле (ах). В этом случае вы можете использовать сервис Type NodePort. Это создаст правила iptables, необходимые для пересылки трафика с IP-адреса хоста на модуль (и), предоставляющие услугу.
Если у вас есть один узел (что не рекомендуется в производстве!), Вы готовы к этому моменту.
Если у вас есть несколько узлов в вашем кластере Kubernetes, все они будут настроены Kubernetes для предоставления доступа к службе (ваши клиенты могут использовать любой из них для доступа к службе). Тем не менее, вам придется решить проблему того, как клиенты узнают, с какими узлами можно связаться...
Есть несколько способов справиться с этим:
использовать протокол, понятный клиенту, для публикации доступных в настоящее время IP-адресов (например, DNS),
использовать плавающий (аварийный, виртуальный, HA) IP-адрес, управляемый некоторым программным обеспечением на ваших узлах Kubernetes (например, кардиостимулятор /corosync), и направлять клиентов по этому адресу,
использовать внешний балансировщик нагрузки, настроенный отдельно, для пересылки трафика на некоторые из рабочих узлов,
использовать внешний балансировщик нагрузки, автоматически настроенный Kubernetes с помощью сценария интеграции облачного провайдера (с помощью службы Type LoadBalancer), для пересылки трафика на некоторые из рабочих узлов.