1 - Розширення діапазонів IP-адрес Service

СТАН ФУНКЦІОНАЛУ: GA since Kubernetes v1.33
More information about this feature

This is a stable feature in Kubernetes, and has been since version v1.33. It was first available in the v1.27 release. You can no longer disable or opt out of this feature or behavior (it is locked); if you explicitly set a value for the associated feature gate MultiCIDRServiceAllocator, Kubernetes ignores it but does not report any error.

У цьому документі описано, як розширити наявний діапазон IP-адрес Service, призначений кластеру.

Перш ніж ви розпочнете

Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:

Версія вашого Kubernetes сервера має бути не старішою ніж v1.29.

Для перевірки версії введіть kubectl version.

Примітка:

Хоча цю можливість можна використовувати в раніших версіях, вона є GA й офіційно підтримується лише з v1.33.

Розширення діапазонів IP-адрес Service

Панель управління забезпечує наявність спеціального обʼєкта ServiceCIDR із загальновідомою назвою kubernetes, який визначає діапазон IP-адрес на основі значення аргументу командного рядка --service-cluster-ip-range для kube-apiserver.

kubectl get servicecidr
NAME         CIDRS          AGE
kubernetes   10.96.0.0/28   17d

Загальновідомий Service kubernetes, який відкриває Podʼам доступ до точки доступу kube-apiserver, обчислює першу IP-адресу зі стандартного діапазону ServiceCIDR і використовує її як свою кластерну IP-адресу.

kubectl get service kubernetes
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   17d

Стандартний Service у цьому випадку використовує ClusterIP 10.96.0.1, що має відповідний обʼєкт IPAddress.

kubectl get ipaddress 10.96.0.1
NAME        PARENTREF
10.96.0.1   services/default/kubernetes

ServiceCIDRs захищені завершувачами, щоб ClusterIP у Service не лишалися без батьківського обʼєкта; завершувач вилучається лише тоді, коли існує інша підмережа з наявними IPAddresses або немає IPAddresses, що належать до цієї підмережі.

Розширення кількості доступних IP-адрес для Services

Іноді користувачам потрібно збільшити кількість адрес, доступних для Services. Раніше збільшення діапазону Service було операцією з порушенням роботи, яка також могла спричинити втрату даних. Завдяки цій новій можливості користувачам достатньо додати новий ServiceCIDR, щоб збільшити кількість доступних адрес.

Додавання нового ServiceCIDR

У кластері з діапазоном 10.96.0.0/28 для Services доступно лише 2^(32-28) - 2 = 14 IP-адрес. Service kubernetes.default створюється завжди; у цьому прикладі лишається лише 13 можливих Services.

for i in $(seq 1 13); do kubectl create service clusterip "test-$i" --tcp 80 -o json | jq -r .spec.clusterIP; done
10.96.0.11
10.96.0.5
10.96.0.12
10.96.0.13
10.96.0.14
10.96.0.2
10.96.0.3
10.96.0.4
10.96.0.6
10.96.0.7
10.96.0.8
10.96.0.9
error: failed to create ClusterIP service: Internal error occurred: failed to allocate a serviceIP: range is full

Ви можете збільшити кількість IP-адрес, доступних для Services, створивши новий ServiceCIDR, який розширює наявні або додає нові діапазони IP-адрес.

cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: ServiceCIDR
metadata:
  name: newcidr1
spec:
  cidrs:
  - 10.96.0.0/24
EOF
servicecidr.networking.k8s.io/newcidr1 created

і це дозволить створювати нові Services з ClusterIP, вибраними з цього нового діапазону.

for i in $(seq 13 16); do kubectl create service clusterip "test-$i" --tcp 80 -o json | jq -r .spec.clusterIP; done
10.96.0.48
10.96.0.200
10.96.0.121
10.96.0.144

Видалення ServiceCIDR

Ви не можете видалити ServiceCIDR, якщо є IPAddresses, які залежать від цього ServiceCIDR.

kubectl delete servicecidr newcidr1
servicecidr.networking.k8s.io "newcidr1" deleted

Kubernetes використовує завершувач на ServiceCIDR, щоб відстежувати цю залежність.

kubectl get servicecidr newcidr1 -o yaml
apiVersion: networking.k8s.io/v1
kind: ServiceCIDR
metadata:
  creationTimestamp: "2023-10-12T15:11:07Z"
  deletionGracePeriodSeconds: 0
  deletionTimestamp: "2023-10-12T15:12:45Z"
  finalizers:
  - networking.k8s.io/service-cidr-finalizer
  name: newcidr1
  resourceVersion: "1133"
  uid: 5ffd8afe-c78f-4e60-ae76-cec448a8af40
spec:
  cidrs:
  - 10.96.0.0/24
status:
  conditions:
  - lastTransitionTime: "2023-10-12T15:12:45Z"
    message: There are still IPAddresses referencing the ServiceCIDR, please remove
      them or create a new ServiceCIDR
    reason: OrphanIPAddress
    status: "False"
    type: Ready

Видаляючи Services з IP-адресами, які блокують видалення ServiceCIDR,

for i in $(seq 13 16); do kubectl delete service "test-$i" ; done
service "test-13" deleted
service "test-14" deleted
service "test-15" deleted
service "test-16" deleted

панель управління помічає це видалення. Потім панель управління вилучає свій завершувач, і ServiceCIDR, що очікував на видалення, справді буде видалено.

kubectl get servicecidr newcidr1
Error from server (NotFound): servicecidrs.networking.k8s.io "newcidr1" not found

Політики Service CIDR у Kubernetes

Адміністратори кластера можуть застосовувати політики для контролю створення й зміни ресурсів ServiceCIDR у кластері. Це дає змогу централізовано керувати діапазонами IP-адрес, які використовуються для Services, і запобігає ненавмисним або конфліктним конфігураціям. Kubernetes надає для застосування цих правил такі механізми, як валідаційні політики допуску (Validating Admission Policies).

Запобігання несанкціонованому створенню й оновленню ServiceCIDR за допомогою валідаційної політики допуску

Іноді адміністратори кластера хочуть обмежити дозволені діапазони або повністю заборонити будь-які зміни діапазонів IP-адрес Service кластера.

Примітка:

Стандартний ServiceCIDR "kubernetes" створюється kube-apiserver для забезпечення узгодженості в кластері й потрібен для роботи кластера, тому його завжди потрібно дозволяти. Щоб ValidatingAdmissionPolicy не обмежувала стандартний ServiceCIDR, додайте таку умову:

  matchConditions:
  - name: 'exclude-default-servicecidr'
    expression: "object.metadata.name != 'kubernetes'"

як у наведених нижче прикладах.

Обмеження діапазонів Service CIDR конкретними діапазонами

Нижче наведено приклад ValidatingAdmissionPolicy, яка дозволяє створювати ServiceCIDR, лише якщо вони є піддіапазонами заданих діапазонів allowed. (Отже, ця політика дозволить ServiceCIDR з cidrs: ['10.96.1.0/24'] або cidrs: ['2001:db8:0:0:ffff::/80', '10.96.0.0/20'], але не дозволить ServiceCIDR з cidrs: ['172.20.0.0/16'].) Ви можете скопіювати цю політику й змінити значення allowed на відповідне для вашого кластера.

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
  name: "servicecidrs.default"
spec:
  failurePolicy: Fail
  matchConstraints:
    resourceRules:
    - apiGroups:   ["networking.k8s.io"]
      apiVersions: ["v1"]
      operations:  ["CREATE", "UPDATE"]
      resources:   ["servicecidrs"]
  matchConditions:
  - name: 'exclude-default-servicecidr'
    expression: "object.metadata.name != 'kubernetes'"
  variables:
  - name: allowed
    expression: "['10.96.0.0/16','2001:db8::/64']"
  validations:
  - expression: "object.spec.cidrs.all(newCIDR, variables.allowed.exists(allowedCIDR, cidr(allowedCIDR).containsCIDR(newCIDR)))"
  # For all CIDRs (newCIDR) listed in the spec.cidrs of the submitted ServiceCIDR
  # object, check if there exists at least one CIDR (allowedCIDR) in the `allowed`
  # list of the VAP such that the allowedCIDR fully contains the newCIDR.
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicyBinding
metadata:
  name: "servicecidrs-default-binding"
spec:
  policyName: "servicecidrs.default"
  validationActions: [Deny,Audit]

Щоб дізнатися більше про CEL і написати власний expression для валідації, дивіться документацію CEL.

Обмеження будь-якого використання API ServiceCIDR

Наведений нижче приклад показує, як використовувати ValidatingAdmissionPolicy та її привʼязку, щоб обмежити створення будь-яких нових діапазонів Service CIDR, окрім стандартного ServiceCIDR "kubernetes":

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
  name: "servicecidrs.deny"
spec:
  failurePolicy: Fail
  matchConstraints:
    resourceRules:
    - apiGroups:   ["networking.k8s.io"]
      apiVersions: ["v1"]
      operations:  ["CREATE", "UPDATE"]
      resources:   ["servicecidrs"]
  validations:
  # Deny changes to all ServiceCIDRs except the default one
  - expression: "object.metadata.name == 'kubernetes'"
    message: "you can only create or update the default ServiceCIDR"
  # Deny changes from all users except kube-apiserver
  - expression: "request.userInfo.username == 'system:apiserver' && 'system:masters' in request.userInfo.groups"
    message: "you can not create or update ServiceCIDR objects"
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicyBinding
metadata:
  name: "servicecidrs-deny-binding"
spec:
  policyName: "servicecidrs.deny"
  validationActions: [Deny,Audit]

2 - Перевірка подвійного стека IPv4/IPv6

У цьому документі описано, як перевірити кластери Kubernetes з увімкненим подвійним стеком IPv4/IPv6.

Перш ніж ви розпочнете

  • Підтримка мереж із подвійним стеком з боку постачальника (хмарний провайдер або інший постачальник має забезпечити вузли Kubernetes маршрутизованими мережевими інтерфейсами IPv4/IPv6)
  • Мережевий втулок, що підтримує мережі з подвійним стеком.
  • Кластер з увімкненим подвійним стеком
Версія вашого Kubernetes сервера має бути не старішою ніж v1.23.

Для перевірки версії введіть kubectl version.

Примітка:

Хоча перевірку можна виконати й на раніших версіях, ця можливість є GA й офіційно підтримується лише з v1.23.

Перевірка адресації

Перевірка адресації вузлів

Кожен вузол із подвійним стеком повинен мати виділений один блок IPv4 і один блок IPv6. Перевірте, що діапазони адрес Podʼів IPv4/IPv6 налаштовано, виконавши наведену нижче команду. Замініть назву вузла з прикладу на назву дійсного вузла з подвійним стеком у вашому кластері. У цьому прикладі назва вузла — k8s-linuxpool1-34450317-0:

kubectl get nodes k8s-linuxpool1-34450317-0 -o go-template --template='{{range .spec.podCIDRs}}{{printf "%s\n" .}}{{end}}'
10.244.1.0/24
2001:db8::/64

Має бути виділено один блок IPv4 та один блок IPv6.

Перевірте, що на вузлі виявлено інтерфейси IPv4 та IPv6. Замініть назву вузла на назву дійсного вузла з кластера. У цьому прикладі назва вузла — k8s-linuxpool1-34450317-0:

kubectl get nodes k8s-linuxpool1-34450317-0 -o go-template --template='{{range .status.addresses}}{{printf "%s: %s\n" .type .address}}{{end}}'
Hostname: k8s-linuxpool1-34450317-0
InternalIP: 10.0.0.5
InternalIP: 2001:db8:10::5

Перевірка адресації Podʼів

Перевірте, що Podʼу призначено адреси IPv4 та IPv6. Замініть назву Podʼа на назву дійсного Podʼа у вашому кластері. У цьому прикладі назва Podʼа — pod01:

kubectl get pods pod01 -o go-template --template='{{range .status.podIPs}}{{printf "%s\n" .ip}}{{end}}'
10.244.1.4
2001:db8::4

Ви також можете перевірити IP-адреси Podʼа за допомогою Downward API через fieldPath status.podIPs. Наведений нижче фрагмент показує, як надати IP-адреси Podʼа контейнеру через змінну середовища MY_POD_IPS.

        env:
        - name: MY_POD_IPS
          valueFrom:
            fieldRef:
              fieldPath: status.podIPs

Наведена нижче команда виводить значення змінної середовища MY_POD_IPS усередині контейнера. Значення — це список, розділений комами, який відповідає адресам IPv4 та IPv6 Podʼа.

kubectl exec -it pod01 -- set | grep MY_POD_IPS
MY_POD_IPS=10.244.1.4,2001:db8::4

IP-адреси Podʼа також записуються в /etc/hosts усередині контейнера. Наведена нижче команда виконує cat для /etc/hosts у Podʼі з подвійним стеком. З виводу можна перевірити адреси IPv4 та IPv6 Podʼа.

kubectl exec -it pod01 -- cat /etc/hosts
# Kubernetes-managed hosts file.
127.0.0.1    localhost
::1    localhost ip6-localhost ip6-loopback
fe00::0    ip6-localnet
fe00::0    ip6-mcastprefix
fe00::1    ip6-allnodes
fe00::2    ip6-allrouters
10.244.1.4    pod01
2001:db8::4    pod01

Перевірка Services

Створіть наведений нижче Service, який явно не визначає .spec.ipFamilyPolicy. Kubernetes призначить Service кластерний IP з першого налаштованого service-cluster-ip-range і встановить .spec.ipFamilyPolicy у SingleStack.

apiVersion: v1
kind: Service
metadata:
  name: my-service
  labels:
    app.kubernetes.io/name: MyApp
spec:
  selector:
    app.kubernetes.io/name: MyApp
  ports:
    - protocol: TCP
      port: 80

Використайте kubectl, щоб переглянути YAML цього Service.

kubectl get svc my-service -o yaml

Service має .spec.ipFamilyPolicy зі значенням SingleStack і .spec.clusterIP з адресою IPv4 із першого налаштованого діапазону, заданого прапорцем --service-cluster-ip-range у kube-controller-manager.

apiVersion: v1
kind: Service
metadata:
  name: my-service
  namespace: default
spec:
  clusterIP: 10.0.217.164
  clusterIPs:
  - 10.0.217.164
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - port: 80
    protocol: TCP
    targetPort: 9376
  selector:
    app.kubernetes.io/name: MyApp
  sessionAffinity: None
  type: ClusterIP
status:
  loadBalancer: {}

Створіть наведений нижче Service, який явно визначає IPv6 як перший елемент масиву .spec.ipFamilies. Kubernetes призначить Service кластерний IP із діапазону IPv6, налаштованого в service-cluster-ip-range, і встановить .spec.ipFamilyPolicy у SingleStack.

apiVersion: v1
kind: Service
metadata:
  name: my-service
  labels:
    app.kubernetes.io/name: MyApp
spec:
  ipFamilies:
  - IPv6
  selector:
    app.kubernetes.io/name: MyApp
  ports:
    - protocol: TCP
      port: 80

Використайте kubectl, щоб переглянути YAML цього Service.

kubectl get svc my-service -o yaml

Service має .spec.ipFamilyPolicy зі значенням SingleStack і .spec.clusterIP з адресою IPv6 із діапазону IPv6, заданого прапорцем --service-cluster-ip-range у kube-controller-manager.

apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/name: MyApp
  name: my-service
spec:
  clusterIP: 2001:db8:fd00::5118
  clusterIPs:
  - 2001:db8:fd00::5118
  ipFamilies:
  - IPv6
  ipFamilyPolicy: SingleStack
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app.kubernetes.io/name: MyApp
  sessionAffinity: None
  type: ClusterIP
status:
  loadBalancer: {}

Створіть наведений нижче Service, який явно визначає PreferDualStack у .spec.ipFamilyPolicy. Kubernetes призначить адреси IPv4 та IPv6 (оскільки в цьому кластері ввімкнено подвійний стек) і вибере .spec.ClusterIP зі списку .spec.ClusterIPs на основі сімейства адрес першого елемента масиву .spec.ipFamilies.

apiVersion: v1
kind: Service
metadata:
  name: my-service
  labels:
    app.kubernetes.io/name: MyApp
spec:
  ipFamilyPolicy: PreferDualStack
  selector:
    app.kubernetes.io/name: MyApp
  ports:
    - protocol: TCP
      port: 80

Примітка:

Команда kubectl get svc показує лише основну IP-адресу в полі CLUSTER-IP.

kubectl get svc -l app.kubernetes.io/name=MyApp
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
my-service   ClusterIP   10.0.216.242   <none>        80/TCP    5s

Перевірте за допомогою kubectl describe, що Service отримує кластерні IP з блоків адрес IPv4 та IPv6. Потім можна перевірити доступ до сервісу через IP-адреси й порти.

kubectl describe svc -l app.kubernetes.io/name=MyApp
Name:              my-service
Namespace:         default
Labels:            app.kubernetes.io/name=MyApp
Annotations:       <none>
Selector:          app.kubernetes.io/name=MyApp
Type:              ClusterIP
IP Family Policy:  PreferDualStack
IP Families:       IPv4,IPv6
IP:                10.0.216.242
IPs:               10.0.216.242,2001:db8:fd00::af55
Port:              <unset>  80/TCP
TargetPort:        9376/TCP
Endpoints:         <none>
Session Affinity:  None
Events:            <none>

Створення Service з подвійним стеком і балансуванням навантаження

Якщо хмарний провайдер підтримує надання зовнішніх балансувальників навантаження з підтримкою IPv6, створіть наведений нижче Service із PreferDualStack у .spec.ipFamilyPolicy, IPv6 як першим елементом масиву .spec.ipFamilies і полем type зі значенням LoadBalancer.

apiVersion: v1
kind: Service
metadata:
  name: my-service
  labels:
    app.kubernetes.io/name: MyApp
spec:
  ipFamilyPolicy: PreferDualStack
  ipFamilies:
  - IPv6
  type: LoadBalancer
  selector:
    app.kubernetes.io/name: MyApp
  ports:
    - protocol: TCP
      port: 80

Перевірте Service:

kubectl get svc -l app.kubernetes.io/name=MyApp

Перевірте, що Service отримує адресу CLUSTER-IP із блоку адрес IPv6 разом з EXTERNAL-IP. Потім можна перевірити доступ до сервісу через IP-адресу й порт.

NAME         TYPE           CLUSTER-IP            EXTERNAL-IP        PORT(S)        AGE
my-service   LoadBalancer   2001:db8:fd00::7ebc   2603:1030:805::5   80:30790/TCP   35s

3 - Додавання записів до файлу /etc/hosts у Podʼі за допомогою HostAliases

Додавання записів до файлу /etc/hosts у Podʼі дає змогу перевизначити розвʼязання імен хостів на рівні Podʼа, коли DNS та інші варіанти не підходять. Ви можете додавати ці власні записи за допомогою поля HostAliases у PodSpec.

Проєкт Kubernetes рекомендує змінювати конфігурацію DNS за допомогою поля hostAliases (частина .spec Podʼа), а не за допомогою init-контейнера чи інших засобів безпосереднього редагування /etc/hosts. Зміни, внесені іншим способом, kubelet може перезаписати під час створення або перезапуску Podʼа.

Стандартний вміст файлу hosts

Запустіть Pod із Nginx, якому призначено IP-адресу Podʼа:

kubectl run nginx --image nginx
pod/nginx created

Перевірте IP-адресу Podʼа:

kubectl get pods --output=wide
NAME     READY     STATUS    RESTARTS   AGE    IP           NODE
nginx    1/1       Running   0          13s    10.200.0.4   worker0

Вміст файлу hosts виглядатиме так:

kubectl exec nginx -- cat /etc/hosts
# Kubernetes-managed hosts file.
127.0.0.1	localhost
::1	localhost ip6-localhost ip6-loopback
fe00::0	ip6-localnet
fe00::0	ip6-mcastprefix
fe00::1	ip6-allnodes
fe00::2	ip6-allrouters
10.200.0.4	nginx

Стандартно файл hosts містить лише шаблонні записи IPv4 та IPv6, такі як localhost і власне імʼя хоста.

Додавання додаткових записів за допомогою hostAliases

Крім стандартних шаблонних записів, ви можете додати до файлу hosts інші записи. Наприклад, щоб розвʼязувати foo.local, bar.local у 127.0.0.1, а foo.remote, bar.remote у 10.1.2.3, налаштуйте HostAliases для Podʼа в полі .spec.hostAliases:

apiVersion: v1
kind: Pod
metadata:
  name: hostaliases-pod
spec:
  restartPolicy: Never
  hostAliases:
  - ip: "127.0.0.1"
    hostnames:
    - "foo.local"
    - "bar.local"
  - ip: "10.1.2.3"
    hostnames:
    - "foo.remote"
    - "bar.remote"
  containers:
  - name: cat-hosts
    image: busybox:1.28
    command:
    - cat
    args:
    - "/etc/hosts"

Ви можете запустити Pod із такою конфігурацією, виконавши:

kubectl apply -f https://k8s.io/examples/service/networking/hostaliases-pod.yaml
pod/hostaliases-pod created

Перегляньте подробиці Podʼа, щоб побачити його адресу IPv4 і статус:

kubectl get pod --output=wide
NAME                           READY     STATUS      RESTARTS   AGE       IP              NODE
hostaliases-pod                0/1       Completed   0          6s        10.200.0.5      worker0

Вміст файлу hosts виглядає так:

kubectl logs hostaliases-pod
# Kubernetes-managed hosts file.
127.0.0.1	localhost
::1	localhost ip6-localhost ip6-loopback
fe00::0	ip6-localnet
fe00::0	ip6-mcastprefix
fe00::1	ip6-allnodes
fe00::2	ip6-allrouters
10.200.0.5	hostaliases-pod

# Entries added by HostAliases.
127.0.0.1	foo.local	bar.local
10.1.2.3	foo.remote	bar.remote

з додатковими записами, вказаними внизу.

Чому kubelet керує файлом hosts?

kubelet керує файлом hosts для кожного контейнера Podʼа, щоб середовище виконання контейнерів не змінювало цей файл після запуску контейнерів. Історично Kubernetes завжди використовував Docker Engine як середовище виконання контейнерів, а Docker Engine змінював файл /etc/hosts після запуску кожного контейнера.

Поточний Kubernetes може використовувати різні середовища виконання контейнерів; попри це, kubelet керує файлом hosts у кожному контейнері, щоб результат був очікуваним незалежно від середовища виконання контейнерів, яке ви використовуєте.

Увага:

Уникайте ручних змін файлу hosts усередині контейнера.

Якщо ви вносите ручні зміни до файлу hosts, ці зміни втрачаються, коли контейнер завершує роботу.

4 - Переналаштування стандартного ServiceCIDR Kubernetes

СТАН ФУНКЦІОНАЛУ: GA since Kubernetes v1.33
More information about this feature

This is a stable feature in Kubernetes, and has been since version v1.33. It was first available in the v1.27 release. You can no longer disable or opt out of this feature or behavior (it is locked); if you explicitly set a value for the associated feature gate MultiCIDRServiceAllocator, Kubernetes ignores it but does not report any error.

У цьому документі описано, як переналаштувати стандартні діапазони IP-адрес Service, призначені кластеру.

Перш ніж ви розпочнете

Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:

Версія вашого Kubernetes сервера має бути не старішою ніж v1.33.

Для перевірки версії введіть kubectl version.

Переналаштування стандартного ServiceCIDR Kubernetes

У цьому документі пояснено, як керувати діапазоном IP-адрес Service у кластері Kubernetes, що також впливає на сімейства IP, які кластер підтримує для Services.

Сімейства IP, доступні для ClusterIP у Service, визначаються прапорцем --service-cluster-ip-range у kube-apiserver. Щоб краще зрозуміти виділення IP-адрес Service, дивіться документацію Відстеження виділення IP-адрес Services.

Починаючи з Kubernetes 1.33, сімейства IP Service, налаштовані для кластера, відображаються в обʼєкті ServiceCIDR з назвою kubernetes. Обʼєкт ServiceCIDR kubernetes створює перший запущений екземпляр kube-apiserver на основі свого налаштованого прапорця --service-cluster-ip-range. Щоб забезпечити узгоджену поведінку кластера, усі екземпляри kube-apiserver мають бути налаштовані з однаковими значеннями --service-cluster-ip-range, які мають відповідати стандартному обʼєкту ServiceCIDR kubernetes.

Категорії переналаштування ServiceCIDR Kubernetes

Переналаштування ServiceCIDR зазвичай належить до однієї з таких категорій:

  • Розширення наявних ServiceCIDR: Це можна зробити динамічно, додавши нові обʼєкти ServiceCIDR без переналаштування kube-apiserver. Дивіться окрему документацію про Розширення діапазонів IP-адрес Service.

  • Перетворення з одного стека на подвійний стек зі збереженням первинного ServiceCIDR: Це передбачає додавання вторинного сімейства IP (IPv6 до кластера лише з IPv4 або IPv4 до кластера лише з IPv6) зі збереженням початкового сімейства IP як первинного. Для цього потрібно оновити конфігурацію kube-apiserver і відповідно змінити різні компоненти кластера, які мають працювати з цим додатковим сімейством IP. Серед цих компонентів, зокрема, kube-proxy, CNI або мережевий втулок, реалізації service mesh і сервіси DNS.

  • Перетворення з подвійного стека на один зі збереженням первинного ServiceCIDR: Це передбачає вилучення вторинного сімейства IP з кластера з подвійним стеком і повернення до одного сімейства IP зі збереженням початкового первинного сімейства IP. Окрім переналаштування компонентів відповідно до нового сімейства IP, може знадобитися розібратися з Services, які явно налаштовані на використання вилученого сімейства IP.

  • Усе, що призводить до зміни первинного ServiceCIDR: Повна заміна стандартного ServiceCIDR — складна операція. Якщо новий ServiceCIDR не перетинається з наявним, потрібно буде перенумерувати всі наявні Services і змінити Service kubernetes.default. Випадок, коли змінюється ще й первинне сімейство IP, ще складніший і може потребувати зміни кількох компонентів кластера (kubelet, мережевих втулків тощо) відповідно до нового первинного сімейства IP.

Ручні операції для заміни стандартного ServiceCIDR

Переналаштування стандартного ServiceCIDR потребує ручних дій з боку оператора кластера, адміністратора або програмного забезпечення, що керує життєвим циклом кластера. Зазвичай це такі дії:

  1. Оновлення конфігурації kube-apiserver: змініть прапорець --service-cluster-ip-range, указавши нові діапазони IP.
  2. Переналаштування мережевих компонентів: це критичний крок, і конкретна процедура залежить від мережевих компонентів, що використовуються. Він може охоплювати оновлення файлів конфігурації, перезапуск Podʼів агентів або оновлення компонентів для керування новими ServiceCIDR і бажаною конфігурацією сімейства IP для Podʼів. Такими компонентами можуть бути реалізація Services Kubernetes, наприклад kube-proxy, налаштований мережевий втулок і, можливо, інші мережеві компоненти, такі як контролери service mesh і сервери DNS, щоб вони могли правильно обробляти трафік і виконувати виявлення сервісів із новою конфігурацією сімейства IP.
  3. Керування наявними Services: Services з IP-адресами зі старого CIDR потрібно обробити, якщо вони не входять до нових налаштованих діапазонів. Варіанти: повторне створення (що призводить до простою і призначення нових IP-адрес) або потенційно складніші стратегії переналаштування.
  4. Повторне створення внутрішніх сервісів Kubernetes: Service kubernetes.default потрібно видалити й створити заново, щоб отримати IP-адресу з нового ServiceCIDR, якщо первинне сімейство IP змінено або замінено іншою мережею.

Приклад кроків переналаштування

Наведені нижче кроки описують контрольоване переналаштування з повною заміною стандартного ServiceCIDR і повторним створенням Service kubernetes.default:

  1. Запустіть kube-apiserver з початковим --service-cluster-ip-range.
  2. Створіть початкові Services, які отримують IP-адреси з цього діапазону.
  3. Створіть новий ServiceCIDR як тимчасову ціль переналаштування.
  4. Позначте стандартний ServiceCIDR kubernetes для видалення (він лишатиметься в очікуванні через наявні IP-адреси й завершувачі). Це запобігає новим виділенням зі старого діапазону.
  5. Повторно створіть наявні Services. Тепер вони мають отримати IP-адреси з нового тимчасового ServiceCIDR.
  6. Перезапустіть kube-apiserver із налаштованими новими ServiceCIDR і вимкніть старий екземпляр.
  7. Видаліть Service kubernetes.default. Новий kube-apiserver створить його заново в новому ServiceCIDR.

Що далі