Усунення проблем з мультикластерами

Ця сторінка описує, як усувати проблеми з Istio, розгорнутим на кількох кластерах та/або мережах. Перед тим як читати це, слід виконати кроки, зазначені у Встановлення мультикластера та ознайомитися з Моделями розгортання.

Балансування навантаження між кластерами

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

$ for i in $(seq 10); do kubectl --context=$CTX_CLUSTER1 -n sample exec curl-dd98b5f48-djwdw -c curl -- curl -s helloworld:5000/hello; done
Hello version: v1, instance: helloworld-v1-578dd69f69-j69pf
Hello version: v1, instance: helloworld-v1-578dd69f69-j69pf
Hello version: v1, instance: helloworld-v1-578dd69f69-j69pf
...

При дотриманні інструкцій для перевірки установки мультикластера ми очікували б відповіді від обох версій v1 і v2, що свідчить про те, що трафік йде до обох кластерів.

Є безліч можливих причин цієї проблеми:

Проблеми з підключенням і брандмауерами

У деяких середовищах може бути неочевидно, що брандмауер блокує трафік між вашими кластерами. Можливо, що ICMP (ping) трафік може успішно проходити, але HTTP та інші види трафіку — ні. Це може проявлятися як тайм-аут або, в деяких випадках, як більш заплутана помилка, така як:

upstream connect error or disconnect/reset before headers. reset reason: local reset, transport failure reason: TLS error: 268435612:SSL routines:OPENSSL_internal:HTTP_REQUEST

Хоча Istio надає можливості виявлення сервісів для спрощення цього процесу, міжкластерний трафік все одно повинен бути успішним якщо podʼи в кожному кластері знаходяться в одній мережі без Istio. Щоб виключити проблеми з TLS/mTLS, ви можете провести ручне тестування трафіку, використовуючи pod без sidecarʼів Istio.

У кожному кластері створіть новий простір імен для цього тесту. Не вмикайте інʼєкції sidecar:

$ kubectl create --context="${CTX_CLUSTER1}" namespace uninjected-sample
$ kubectl create --context="${CTX_CLUSTER2}" namespace uninjected-sample

Далі розгорніть ті ж самі застосунки, що і в перевірці установки мультикластера:

$ kubectl apply --context="${CTX_CLUSTER1}" \
    -f samples/helloworld/helloworld.yaml \
    -l service=helloworld -n uninjected-sample
$ kubectl apply --context="${CTX_CLUSTER2}" \
    -f samples/helloworld/helloworld.yaml \
    -l service=helloworld -n uninjected-sample
$ kubectl apply --context="${CTX_CLUSTER1}" \
    -f samples/helloworld/helloworld.yaml \
    -l version=v1 -n uninjected-sample
$ kubectl apply --context="${CTX_CLUSTER2}" \
    -f samples/helloworld/helloworld.yaml \
    -l version=v2 -n uninjected-sample
$ kubectl apply --context="${CTX_CLUSTER1}" \
    -f samples/curl/curl.yaml -n uninjected-sample
$ kubectl apply --context="${CTX_CLUSTER2}" \
    -f samples/curl/curl.yaml -n uninjected-sample

Перевірте, що є pod helloworld, що працює в cluster2, використовуючи прапорець -o wide, щоб отримати IP Pod:

$ kubectl --context="${CTX_CLUSTER2}" -n uninjected-sample get pod -o wide
NAME                             READY   STATUS    RESTARTS   AGE   IP           NODE     NOMINATED NODE   READINESS GATES
curl-557747455f-jdsd8            1/1     Running   0          41s   10.100.0.2   node-2   <none>           <none>
helloworld-v2-54df5f84b-z28p5    1/1     Running   0          43s   10.100.0.1   node-1   <none>           <none>

Занотуйте стовпець IP для helloworld. У цьому випадку це 10.100.0.1:

$ REMOTE_POD_IP=10.100.0.1

Далі спробуйте надіслати трафік від podʼа curl в cluster1 безпосередньо на цей IP Pod:

$ kubectl exec --context="${CTX_CLUSTER1}" -n uninjected-sample -c curl \
    "$(kubectl get pod --context="${CTX_CLUSTER1}" -n uninjected-sample -l \
    app=curl -o jsonpath='{.items[0].metadata.name}')" \
    -- curl -sS $REMOTE_POD_IP:5000/hello
Hello version: v2, instance: helloworld-v2-54df5f84b-z28p5

Якщо успішно, мають бути відповіді тільки від helloworld-v2. Повторіть ці кроки, але надішліть трафік з cluster2 до cluster1.

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

Балансування навантаження по локації

Балансування навантаження по локації може використовуватися для того, щоб клієнти віддавали перевагу трафіку до найближчого призначення. Якщо кластери перебувають в різних локаціях (регіон/зона), балансування навантаження по локації віддасть перевагу локальному кластеру, і це працює як очікується. Якщо балансування навантаження по локації вимкнене або кластери знаходяться в одній локації, може бути інша проблема.

Конфігурація довіри

Трафік між кластерами, як і трафік всередині кластера, залежить від спільного кореня довіри між проксі. Стандартно Istio використовує свої власні індивідуально згенеровані сертифікати кореня. Для мультикластерних установок ми повинні вручну налаштувати спільний корінь довіри. Слідкуйте за підрозділом “Додавання сертифікатів” нижче або читайте Моделі ідентичності та довіри, щоб дізнатися більше.

Додавання сертифікатів:

Щоб перевірити, чи сертифікати налаштовані правильно, ви можете порівняти кореневий сертифікат у кожному кластері:

$ diff \
   <(kubectl --context="${CTX_CLUSTER1}" -n istio-system get secret cacerts -ojsonpath='{.data.root-cert\.pem}') \
   <(kubectl --context="${CTX_CLUSTER2}" -n istio-system get secret cacerts -ojsonpath='{.data.root-cert\.pem}')

Якщо кореневі сертифікати не збігаються або секрет взагалі не існує, слід слідувати інструкціям з Додавання сертифікатів CA, забезпечуючи виконання кроків для кожного кластера.

Покрокова діагностика

Якщо ви пройшли через вищезазначені розділи та все ще стикаєтеся з проблемами, то час заглибитися трохи глибше.

Наступні кроки передбачають, що ви дотримуєтеся перевірки HelloWorld. Перед тим як продовжити, переконайтеся, що як helloworld, так і curl розгорнуті в кожному кластері.

З кожного кластера знайдіть точки доступу сервісу curl для helloworld:

$ istioctl --context $CTX_CLUSTER1 proxy-config endpoint curl-dd98b5f48-djwdw.sample | grep helloworld

Інформація для усунення неполадок відрізняється залежно від того, який кластер є джерелом трафіку:

$ istioctl --context $CTX_CLUSTER1 proxy-config endpoint curl-dd98b5f48-djwdw.sample | grep helloworld
10.0.0.11:5000                   HEALTHY     OK                outbound|5000||helloworld.sample.svc.cluster.local

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

$ kubectl get secrets --context=$CTX_CLUSTER1 -n istio-system -l "istio/multiCluster=true"
  • Якщо секрет відсутній, створіть його.
  • Якщо секрет присутній:
    • Перегляньте конфігурацію в секреті. Переконайтеся, що імʼя кластера використовується як ключ даних для віддаленого kubeconfig.
    • Якщо секрет виглядає правильно, перевірте журнали istiod на наявність проблем з підключенням або дозволами для досягнення віддаленого Kubernetes API сервера. Журнали можуть містити повідомлення Failed to add remote cluster from secret разом з причиною помилки.
Чи була ця інформація корисною?
Чи є у вас пропозиції щодо покращення?

Дякуємо за ваш відгук!