Это вторая часть статьи про k8s. Первая была тут.
В этой статьe рассмотрим как настроить ingress контроллер в нашем кластере и повесить kubernetes-dashboard на него, а также сделаем доступ ко всему этому делу по доменным именам.
Для работы с ДНС нам нужно развернуть локальный ДНС сервер. Это уже было рассмотрено в этой статье. Давайте пробежимся еще раз в контексте кубера.
Редактируем наш Vagrantfile и приводим его к виду:
servers=[
{:hostname => "k8s-master",:ip => "192.168.10.27",:ssh_port => 2222},
{:hostname => "k8s-worker1",:ip => "192.168.10.26",:ssh_port => 2223},
{:hostname => "k8s-worker2",:ip => "192.168.10.25",:ssh_port => 2224},
{:hostname => "k8s-ingress1",:ip => "192.168.10.24",:ssh_port => 2226},
{:hostname => "dnsmasq",:ip => "192.168.10.100",:ssh_port => 2227}
]
#last_vm = servers[(servers.length) -1][:hostname]
Vagrant.configure("2") do |config|
config.vm.provider "virtualbox" do |vb|
vb.gui = false
vb.memory = 1024
vb.cpus = 1
vb.check_guest_additions = false
config.vm.box_check_update = false
config.vm.box = "bento/ubuntu-22.04"
end
servers.each do |machine|
config.vm.define machine[:hostname] do |node|
node.vm.hostname = machine[:hostname]
node.vm.network "public_network", ip: machine[:ip], bridge: "wlo1"
node.vm.network "forwarded_port", id: "ssh", host: machine[:ssh_port], guest: 22
if machine[:hostname] == "k8s-master"
node.vm.provider "virtualbox" do |vb|
vb.memory = 2048
end
end
if machine[:hostname] == "dnsmasq"
node.vm.provision "ansible_local" do |ansible|
ansible.playbook = "ansible/playbook/dnsmasq.yaml"
ansible.limit = "all,localhost"
end
end
end
end
endПо сути мы добавили один хост (dnsmasq) и добавили ему локальный ansible provision.
Структура проекта стала выглядеть так:

В переменные для ДНС добавляем такую строку:
- address=/.{{ local_domain }}/192.168.10.24Это wilcard запись для резолвинга любых доменных имен вида *.dev.local в ip адрес 192.168.10.24, это адрес нашей ingress ноды.
Запускаем ВМ
vagrant up dnsmasq --provisionКак итог, мы должны получить вот такой список машин:

Настраиваем ПК на использование локального ДНС:
Отключаем системный резолвер:
systemctl stop systemd-resolvedУдаляем сгенерированный им resolv.conf и создаем его заново:
$ cat /etc/resolv.conf
nameserver 192.168.10.100Теперь мы работаем через наш локальный ДНС.
Проверяем резолвинг в локальной сети и интернет:

Устанавливаем ingress-controller
Так как мы используем kubernetes на bare metal, то нам надо ставить специально написанный для этого манифест ingress-controller. Его основное отличие от обычного в том, что там используется для сущности service тип nodePort. Этот тип автоматически (если не определено иное) откроет на нодах порты из диапозона 30000-32767. В контексте ингресса будут открыты порты для http(80) и https(443).
Устанавливаем манифест:
k_local apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/baremetal/deploy.yamlПроверяем создался ли namespace:

Проверяем сущности внутри namespace:

Видим что у нас есть pod — ingress-nginx-controller, а также service типа nodePort с открытыми портами 80:32450 и 443:30574.
Это означает, что эти порты доступны с любой ноды. Это легко можно проверить, например так:

Тоже самое будет, если отправить запрос на любую из нод.
Прибиваем гвоздями ingress-controller к ноде ingress
Сейчас наш ingress контроллер может оказаться на любой из нод. Мы же хотим его видеть на специально выделенной для него ноде, тем более что именно для нее у нас уже настроен локальный ДНС с wilcard записью.
Для этого сначала вешаем taint на ноду. Почитать подробнее про taint and tolerations можно тут.
k_local taint node k8s-ingress1 ingress=true:NoScheduleМы говорим k8s что эта нода будет помечана как ingress=true (это ключ и значение соответственно) и будет иметь эффект NoSchedule. Теперь новые поды не смогут попасть на эту ноду. Это нам и нужно.
Правим deployment ingress-controller
Во-первых добавляем правильный nodeSelector, чтобы под с контроллером заезжал всегда на нашу ноду.
Во-вторых прописывает «толерантность» к добавленному ранее taint.
Открываем на редактирование deployment любым удобным способом:
nodeSelector:
node-role.kubernetes.io/ingress: ""
tolerations:
- effect: NoSchedule
key: ingress
operator: Equal
value: "true"Проверяем заехал ли под на нужную ноду:
$ k_local get pod -n ingress-nginx -o wide |grep -i running
ingress-nginx-controller-68685dcd96-fgp7z 1/1 Running 3 (103m ago) 4h3m 10.244.3.10 k8s-ingress1 <none> <none>
Создаем сущность ingress для kubernetes-dashboard
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: kubernetes-dashboard
name: kubernetes-dashboard-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
spec:
tls:
- hosts:
- k8s-dashboard.dev.local
rules:
- host: k8s-dashboard.dev.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: kubernetes-dashboard
port:
number: 443После применения манифеста идем в браузер по адресу: https://k8s-dashboard.dev.local:30574

30574 — это порт для https, который нам открыл nodePort сервис ингресс контроллера. Выглядит не очень красиво с указанием порта, но для локальных целей вполне сгодится.
Если мы хотим переходить просто по доменному имени, без указания порта, то перед ingress нодой надо ставить например все тот же nginx в качестве обратного прокси сервера.
Полный код ansible тут.


