====== Kubernetes: Network Calico ======
====== Calico ======
===== Режимы работы =====
Calico поддерживает три режима:
* **Direct** — когда поды могут обращаться к другим подам кластера через обычные сетевые соединения без использовани различных видов тунелей (инкапсуляций пакетов).
* **IP-in-IP** — используется возможность Linux: [[https://tldp.org/HOWTO/Adv-Routing-HOWTO/lartc.tunnel.ip-ip.html|IP in IP tunneling]]
* **VXLAN** — инкапсуляция L2 в UDP пакеты. [[https://www.kernel.org/doc/Documentation/networking/vxlan.txt|Virtual eXtensible Local Area Networking documentation]]
Если машины кластера находятся в одной сети, лучшим выбором будет отсутствие любых overlay.
===== Установка драйвера сети =====
Если вы используете NetworkManager, его необходимо настроить перед использованием Calico.
Создадим конфигурационный файл /etc/NetworkManager/conf.d/calico.conf, что бы запретить NetworkManager работать с интерфейсами, управляемыми calico:
[keyfile]
unmanaged-devices=interface-name:cali*;interface-name:tunl*;interface-name:vxlan.calico
Скачаем необходимые для установки файлы.
curl -s https://docs.projectcalico.org/manifests/calico.yaml -O
В файле заменим
- name: CALICO_IPV4POOL_IPIP
value: "Always"
# - name: CALICO_IPV4POOL_CIDR
# value: "192.168.0.0/16"
на
- name: CALICO_IPV4POOL_IPIP
value: "Never"
- name: CALICO_IPV4POOL_CIDR
value: "192.168.180.0/24"
Переменная определяет режим работы сети. Отключив оба режима оверлея, мы включаем Direct режим сети.
Можно заменить размер блока (маска подсети), выделяемого на ноду (Значение по умолчанию — 26):
- name: CALICO_IPV4POOL_BLOCK_SIZE
value: 25
Подробное описание параметров, используемых при конфигурации calico/node, можно посмотреть в [[https://docs.projectcalico.org/reference/node/configuration|документации]].
Установим calico.
kubectl apply -f calico.yaml
==== Смотрим, вникаем ====
Сначал посмотрим какие IP адреса получили поды в namespace kube-system
watch kubectl -n kube-system get pods -o wide
Смотрим таблицы маршрутизации на всех нодах кластера
route -n
Обращаем внимание на интерфейсы типа cali*.
Запускаем nginx на 3-ей ноде кластера.
kubectl run --image=nginx:latest nginx \
--overrides='{"apiVersion": "v1", "spec": {"nodeSelector": { "kubernetes.io/hostname": "ip-174-163.local" }}}'
Смотрим, какой ip адрес был выдан поду
kubectl get pods -o wide
Попытаемся подключиться к ngix в этом поде.
Почему у нас ничего не получается?
==== Установка утилиты calicoctl ====
calicoctl позволяет управлять параметрами сети.
Утилиту можно поставить непосредственно в кластер kubernetes в виде отдельного пода. Или как бинарный файл непосредственно в Linux.
curl -s https://raw.githubusercontent.com/BigKAA/youtube/master/net/02-calico/01-install-calicoctl.sh | bash
Создаем конфигурационный файл программы.
curl -s https://raw.githubusercontent.com/BigKAA/youtube/master/net/02-calico/02-calicoctl.cfg -o /etc/calico/calicoctl.cfg
Проверяем работу программы
calicoctl get nodes
calicoctl node status
==== Замена механизма оверлея ====
calicoctl get ippool default-ipv4-ippool -o yaml> pool.yaml
vim pool.yaml
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
creationTimestamp: "2020-11-08T17:41:07Z"
name: default-ipv4-ippool
resourceVersion: "2278"
uid: 3da935c0-63ba-4c24-b63d-9f49b7549855
spec:
blockSize: 26
cidr: 192.168.180.0/24
ipipMode: Never
natOutgoing: true
nodeSelector: all()
vxlanMode: Never''
В файле заменим параметры
ipipMode: Never -> Always
Применим полученную конфигурацию.
calicoctl apply -f pool.yaml
Смотрим на всех нодах кластера таблицу маршрутизации.
route -n
Пытаемся подключиться к nginx.
Снова открываем на редактирование pool.yaml изаменяем
ipipMode: Always -> CrossSubnet
Удаляем строки:
creationTimestamp:
resourceVersion:
uid:
Применим полученную конфигурацию.
calicoctl apply -f pool.yaml
Смотрим на всех нодах кластера таблицу маршрутизации. Делаем выводы.
===== Calico IPAM =====
Kubernetes использует плагины IPAM (IP Adress Management) для выделения IP адресов подам. Проект calico предоставляет модуль: calico-ipam.
Модуль calico-ipam использует Calico IP pool для определения каким образом выделять IP адреса для подов в кластере.
calicoctl get ippool
По умолчанию используется один IP pool для всего кластера. Но его можно разделить на несколько пулов. В дальнейшем эти пулы можно назначать на под используя различные условия выбора:
* node selectos,
* аннотаций к namespaces,
* аннотаций к подам.
Calico разделяет пулы на меньшие по размеру блоки, которые прикрепляются к node. Мы уже видели эти блоки, когда смотрели таблицу маршрутизации ноды. К каждой ноде кластера может быть подключен один или несколько таких блоков. Calico будет самостоятельно добавлять и удалять их.
По умолчанию размер блока соответствует подсети /26 (64 адреса). Это параметр можно изменить как в процессе установки calico, так и во время обычной работы кластера.
calicoctl get ippool default-ipv4-ippool -o yaml
calicoctl ipam show
==== Назначение пула IP адресов ====
Существует несколько вариантов назначения пула IP адресов. Мы посмотрим наиболее часто используемый при создании территориально распределенных кластеров.
Предположим, что первые две ноды нашего кластера расположены в одном датацентре, а третья в другом. Сеть подов кластера: 192.168.180.0/24
Необходимо, что бы первые две ноды были в подсети 192.168.200.0/24, а третья в 192.168.201.0/24
Нам потребуется выполнить следующие действия:
* Поставить метки на ноды кластера.
* Создать два IP пула, с определением нод кластера, на какие они будут применяться.
* Перевод пула default-ipv4-ippool в состяние disabled.
* Удалить (перезапустить) поды, что бы они при создании получили IP адреса из новых пулов.
* Удалить пул default-ipv4-ippool.
Ставим метки на ноды кластера:
kubectl label nodes ip-218-161 location=datacenter1
kubectl label nodes ip-218-162 location=datacenter1
kubectl label nodes ip-174-163.local location=datacenter2
kubectl get nodes --show-labels
Создаём два пула:
---
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
name: datacenter1
spec:
cidr: 192.168.200.0/24
ipipMode: CrossSubnet
natOutgoing: true
nodeSelector: location == "datacenter1"
---
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
name: datacenter2
spec:
cidr: 192.168.201.0/24
ipipMode: CrossSubnet
natOutgoing: true
nodeSelector: location == "datacenter2"''
calicoctl apply -f pool-locations.yaml
calicoctl get ippool
Переводим пул default-ipv4-ippool в состяние disabled.
calicoctl get ippool default-ipv4-ippool -o yaml> pool.yaml
vim pool.yaml
Удаляем строки:
creationTimestamp:
resourceVersion:
uid:
Добавляем:
disabled: true
Получается файл следующего содержимого:
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
name: default-ipv4-ippool
spec:
blockSize: 26
cidr: 192.168.180.0/24
ipipMode: CrossSubnet
natOutgoing: true
nodeSelector: all()
vxlanMode: Never
disabled: true
Применяем конфиг.
calicoctl apply -f pool.yaml
calicoctl get ippool -o wide
Смотрим какие поды работают на старых ip в сети:
kubectl get pods --all-namespaces -o wide | grep 192.168.180
Удаляем их.
kubectl -n kube-system rollout restart deployment/calico-kube-controllers
kubectl -n kube-system rollout restart deployment.apps/coredns
kubectl delete pod/nginx
Запускаем nginx на третей ноде:
kubectl run --image=nginx:latest nginx \
--overrides='{"apiVersion": "v1", "spec": {"nodeSelector": { "kubernetes.io/hostname": "ip-174-163.local" }}}'
Смотрим что получилось.
kubectl get pods -o wide --all-namespaces | grep -E '192.168.200|192.168.201'
route -n
Удаляем пул.
calicoctl delete pool default-ipv4-ippool
calicoctl get ippool
route -n
===== =====