Настройка распределенной трассировки в Kubernetes с OpenTracing, Jaeger и Ingress-NGINX

Kate

Administrator
Команда форума
В эпоху, когда крупные компании используют более 500 микросервисов одновременно, важно иметь возможность быстро выяснить, из-за чего произошел сбой или снизилась производительность. Без специализированных инструментов это может быть похоже на поиск иголки в стоге сена.

Распределённая трассировка (Distributed Tracing) - это метод, используемый для мониторинга приложений. Для микросервисов он просто незаменим.

В качестве примера мы будем использовать приложение Meow-Micro, специально созданное для этой статьи. Но вы можете развернуть собственные приложения, если захотите.

Что нам потребуется?​

В этом руководстве предполагается, что вы понимаете код, написанный на Go, умеете использовать Ingress-nginx и знаете, как работают основные объекты Kubernetes, такие как Service и Deployment.

Если вы хотите освежить знания, воспользуйтесь этими материалами:

Запуск Kubernetes в Docker Desktop​

Начнём с установки Docker Desktop, который позволяет не только запускать контейнеры, но и создать локальный кластер Kubernetes.

После установки Docker Desktop выполните следующие действия, чтобы создать кластер Kubernetes:

  1. Нажмите на иконку Preferences
c820a0e455fd2143479a63f3a781e894.png

2. Выберете вкладку Kubernetes, установите флажок Enable Kubernetes и нажмите кнопку Apply & Restart

b4e475b92362300f9008215669fccd1b.png

3. В появившемся окне нажмите кнопку Install и дождитесь пока установка завершится

a5088f5cb251961baf0ab700c23f5b23.png

4. Выберите пункт Kubernetes в панели задач

06edf49c2c4463f1179b94abb1fc226c.png

5. В контекстном меню выбирите docker-desktop

8a9def10239c868de03e67e267a09c9e.png

6. Проверьте, что вы подключены к нужному кластеру

$ kubectl cluster-info

Kubernetes master is running at
KubeDNS is running at https://kubernetes.docker.internal:6443/api/v1/
namespaces/kube-system/services/kube-dns:dns/proxy

Установка Ingress-NGINX Controller​

1. Воспользуйтесь командой из официального руководства для установки Ingress-NGINX Controller.

$ kubectl apply -f https://raw.githubusercontent.com/k...45.0/deploy/static/provider/cloud/deploy.yaml

namespace/ingress-nginx created
serviceaccount/ingress-nginx created
configmap/ingress-nginx-controller created
clusterrole.rbac.authorization.k8s.io/ingress-nginx created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx created
role.rbac.authorization.k8s.io/ingress-nginx created
rolebinding.rbac.authorization.k8s.io/ingress-nginx created
service/ingress-nginx-controller-admission created
service/ingress-nginx-controller created\
deployment.apps/ingress-nginx-controller created
validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission created
serviceaccount/ingress-nginx-admission created]
clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
role.rbac.authorization.k8s.io/ingress-nginx-admission created
rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
job.batch/ingress-nginx-admission-create created\
job.batch/ingress-nginx-admission-patch created
2. Проверьте, что установка Ingress Сontroller прошла успешно. Pods должны быть запущены и находятся в статусе Ready.

$ kubectl get pods -n ingress-nginx

NAME READY STATUS RESTARTS
ingress-nginx-admission-create-52jsl 0/1 Completed 0
ingress-nginx-admission-patch-78fkc 0/1 Completed 0
ingress-nginx-controller-6f5454cbfb-qsfnn 1/1 Running 0
Важно: Если Pod находится в статусе Pending из-за нехватки ресурсов CPU/Memory, вы можете добвить ресурсы вашему кластеру в настройках Docker Desktop.

7052b560f0c17ade4fb584dba3b53b5d.png

Установка Jaeger и настройка Ingress Controller​

Jaeger - это платформа распределенная трассировки, которую мы будем использовать для мониторинга наших микросервисов. Установим Jaeger и включим трассировку на уровне Ingress Controller.

1. Вначале склонируйте репозиторий meow-micro, этот проект мы будем использовать во всех примерах.

$ git clone https://github.com/diazjf/meow-micro.git

Cloning into 'meow-micro'...
remote: Enumerating objects: 105, done.
...
$ cd meow-micro
2. В репозитории вы найдёте манифесты для jaeger-all-in-one. Установим Jaeger из этих манифестов.

$ kubectl apply -f jaeger/jaeger-all-in-one.yaml

deployment.apps/jaeger created
service/jaeger-query created
service/jaeger-collector created
service/jaeger-agent created
service/zipkin created
3. Убедимся, что Jaeger запущен и готов к работе.

$ kubectl get pods

NAME READY STATUS RESTARTS AGE
jaeger-6f6b5d8689-8gccp 1/1 Running 0 17s
4. Пришло время настроить совместную работу Ingress-NGINX and Jaeger, для этого необходимо добавить параметры enable-opentracing и jaeger-collector-host в ingress-nginx-controller ConfigMap. В параметре jaeger-collector-host указываем имя сервиса Jaeger.

$ echo '
apiVersion: v1
kind: ConfigMap
data:
enable-opentracing: "true"
jaeger-collector-host: jaeger-agent.default.svc.cluster.local
metadata:
name: ingress-nginx-controller
namespace: ingress-nginx
' | kubectl replace -f -
configmap/ingress-nginx-controller replaced
5. Убедимся, что в настройках Ingress Controller включен и настроен opentracing.

$ kubectl get pods -n ingress-nginx | grep controller

ingress-nginx-controller-6f5454cbfb-qptxt 1/1 Running 0 8m56s

$ kubectl exec -it ingress-nginx-controller-6f5454cbfb-qptxt -n ingress-nginx -- bash -c "cat nginx.conf | grep ngx_http_opentracing_module.so"

load_module /etc/nginx/modules/ngx_http_opentracing_module.so;

$ kubectl exec -it ingress-nginx-controller-6f5454cbfb-qptxt -n ingress-nginx -- bash -c "cat nginx.conf | grep jaeger"

opentracing_load_tracer /usr/local/lib/libjaegertracing_plugin.so /etc/nginx/opentracing.json;

$ kubectl exec -it ingress-nginx-controller-6f5454cbfb-qptxt -n ingress-nginx -- bash -c "cat /etc/nginx/opentracing.json"

{
"service_name": "nginx",
"propagation_format": "jaeger",
"sampler": {
"type": "const",
"param": 1,
"samplingServerURL": "http://127.0.0.1:5778/sampling"
},
"reporter": {
"endpoint": "",
"localAgentHostPort": "jaeger-agent.default.svc.cluster.local:6831"
},
"headers": {
"TraceContextHeaderName": "",
"jaegerDebugHeader": "",
"jaegerBaggageHeader": "",
"traceBaggageHeaderPrefix": ""
}
}
Jaeger и Ingress Controller успешно установлены и настроены. Самое время развернуть наши микросервисы!

Разворачиваем тестовое приложение​

Тестовое приложение meow-micro состоит из двух микросервисов. Клиент meow-client - принимает REST запрос и отправляет информацию сервису meow-server через GRPC.

Подробная информация об использовании REST и GRPC с GoLang:

Тестовое приложение также содержит несколько дополнительных инструментов:

tracing.go​

Получает параметры для настройки Jaeger из окружения, в котором запускается Helm для установки meow-client and meow-server.

cfg, err := config.FromEnv()
if err != nil {
panic(fmt.Sprintf("Could not parse Jaeger env vars: %s", err.Error()))
}
tracer, closer, err := cfg.NewTracer()
if err != nil {
panic(fmt.Sprintf("Could not initialize jaeger tracer: %s", err.Error()))
}

client.go​

Выполняет конфигурирование клиента - задает service name для trace и определяет span.

  • Span — базовый элемент распределенной трассировки. Представляет собой описание некоего рабочего процесса (например, запроса к базе данных). Span'ы обычно содержат ссылки на другие span'ы, что позволяет объединять множество span'ов в Trace.
  • Trace — визуализация жизни запроса в процессе его перемещения по распределенной системе.
Подробную информацию о понятиях trace и span можно посмотреть в официальной документации.

// main function span
os.Setenv("JAEGER_SERVICE_NAME", "meow-client")
tracer, closer := tracing.Init()
defer closer.Close()
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
spanCtx, _ := tracer.Extract(opentracing.HTTPHeaders, opentracing.HTTPHeadersCarrier(r.Header))
span := tracer.StartSpan("send-meow-communication", ext.RPCServerOption(spanCtx))
defer span.Finish()
...
// sleep function span
os.Setenv("JAEGER_SERVICE_NAME", "meow-client")
tracer, closer := tracing.Init()
defer closer.Close()
span := tracer.StartSpan("sleep")
defer span.Finish()

Установка тестового приложения​

Установить Helm v3 можно на любую операционную систему, например на macOS с помощью brew. Теперь мы готовы развернуть микросервисы в нашем кластере.

$ brew install helm
...
==> Downloading https://ghcr.io/v2/homebrew/core/helm/manifests/3.5.4
######################################################################## 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/helm/blobs/sha256:5dac5803c1ad2db3a91b0928fc472aaf80a4
==> Downloading from https://pkg-containers-az.githubusercontent.com/ghcr1/blobs/sha256:5dac5803c1ad2db
######################################################################## 100.0%
==> Pouring helm--3.5.4.big_sur.bottle.tar.gz
...
$ helm version
version.BuildInfo{Version:"v3.3.4", GitCommit:"a61ce5633af99708171414353ed49547cf05013d", GitTreeState:"clean", GoVersion:"go1.14.9"}
Воспользуемся Makefile из репозитория, чтобы развернуть тестовое приложение в кластере Kubernetes.

# Build client and server from Dockerfile
$ make build
docker build -t meow-client:1.0 -f client/Dockerfile .
[+] Building 17.1s (10/10) FINISHED
...
docker build -t meow-server:1.0 -f server/Dockerfile .
[+] Building 0.5s (10/10) FINISHED
...
# Install Microservices into Kubernetes via Helm

$ make install
helm install -f helm/Values.yaml meow-micro ./helm
NAME: meow-micro
LAST DEPLOYED: Mon Apr 26 13:42:38 2021
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
Проверим, что Pods обоих сервисов запустились и работают.

$ kubectl get pods

NAME READY STATUS RESTARTS AGE
jaeger-6f6b5d8689-s7cln 1/1 Running 0 26m
meow-client-8b974778c-85896 1/1 Running 0 15m
meow-server-56f559db44-5mvgp 1/1 Running 0 15m

Просмотр данных трассировки​

А теперь самое интересное! Взглянем на трассировку.

Откройте консоль Jaeger, указав в браузере адрес http://localhost:8081.

2b4f71615c076670237a0b99e8b2752f.png

2. Отправим запрос нашему приложению.

$ curl http://localhost/meow -X POST -d '{"name": "Meow-Mixer"}'
200 - Meow sent: Meow-Mixer
3. Обновите страницу браузера. В меню Service выберите - nginx.

bfac382a0a06995ad6699b7fac93ba22.png

4. Нажмите кнопку Find Traces.

2de83261ca9bb60c32ec8ede1c492218.png

5. Отобразятся все трассировки для nginx. Каждую из них можно развернуть, чтобы получить больше информации.

56e65e36128155e796beca24b66c576c.png

6. Теперь вы можете отслеживать, сколько времени занял каждый запрос.

289c65027489afdbd97db7274f790b95.png

И выводить дополнительную информацию по каждому запросу.

063a3f33ef02d7412a452bec5669f11b.png

Не смотря на то, что этот небольшой пример даёт представление о том, что такое распределенная трассировка, увидеть всю её мощь можно только на реальных приложениях под нагрузкой.

Другие системы трассировки​

Мы рассмотрели как использовать Jaeger для трассировки запросов Ingress-Nginx. Для этих целей можно также использовать Zipkin или DataDog.


Источник статьи: https://habr.com/ru/company/timeweb/blog/558288/
 
Сверху