Перейти к основному содержимому

Шаг 5. Упаковка приложения в Docker-контейнер

Для дальнейшего продвижения нам потребуется упаковать приложение в Docker-контейнер.

Не забудьте удалить предыдущий контейнер jaeger:

docker stop jaeger

Создадим следующую директорию с содержимым:

observability
├── app
│ ├── .gitignore
│ ├── app.py
│ ├── Dockerfile
│ └── requirements.txt
├── .gitignore
└── docker-compose.yaml

Файл app/.gitignore и .gitignore можно заполнить по примеру отсюда.

Файл app/app.py с учетом адаптации под контейнер выглядит следующим образом:

import os
from flask import Flask
from random import randint
from opentelemetry import trace
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.sdk.trace.export import ConsoleSpanExporter
from opentelemetry.exporter.jaeger.thrift import JaegerExporter
from opentelemetry.sdk.resources import SERVICE_NAME, Resource


provider = TracerProvider()
processor = BatchSpanProcessor(ConsoleSpanExporter())
provider.add_span_processor(processor)
trace.set_tracer_provider(
TracerProvider(
resource=Resource.create({SERVICE_NAME: os.environ.get('APP_SERVICE_NAME',"my-python-service")})
)
)
jaeger_exporter = JaegerExporter(
agent_host_name=os.environ.get('JAEGER_EXPORTER_HOST_NAME', "localhost"),
agent_port=int(os.environ.get('JAEGER_EXPORTER_PORT', 6831)),
)
trace.get_tracer_provider().add_span_processor(
BatchSpanProcessor(jaeger_exporter)
)

tracer = trace.get_tracer(__name__)

app = Flask(__name__)


def roll():
return randint(1, 6)


@app.route("/rolldice")
def roll_dice():
with tracer.start_as_current_span("server_request"):
return str(roll())


if __name__ == "__main__":
host = os.environ.get('APP_HOST_NAME', "0.0.0.0")
port = int(os.environ.get('APP_PORT', 5000))
app.run(debug=True, host=host, port=port)

Файл app/Dockerfile выглядит следующим образом:

FROM python:3.12-slim-bookworm
COPY ./requirements.txt /app/requirements.txt
WORKDIR /app
RUN pip install -r requirements.txt
COPY . /app
EXPOSE 5000
CMD ["python", "app.py" ]

Файл app/requirements.txt выглядит следующим образом:

Flask==3.0.0
opentelemetry-sdk==1.21.0
opentelemetry-exporter-jaeger==1.21.0

Файл docker-compose.yaml выглядит следующим образом:

services:
app:
image: iu5devops/app
build:
context: ./app
dockerfile: Dockerfile
container_name: iu5devops-app
networks:
- iu5devops
ports:
- 8080:5000
environment:
- APP_SERVICE_NAME=iu5devops-app
- JAEGER_EXPORTER_HOST_NAME=iu5devops-jaeger
- JAEGER_EXPORTER_PORT=6831

jaeger:
image: jaegertracing/all-in-one
container_name: iu5devops-jaeger
networks:
- iu5devops
ports:
- 16686:16686

networks:
iu5devops:

Чтобы поднять нашу инфраструктуру, в директории observability выполните:

docker compose build
docker compose up -d

Убедитесь, что Jaeger в контейнере собирает трассировку. Для этого выполните запрос к http://localhost:8080/rolldice несколько раз. Посмотрите трассировку в Jaeger UI http://localhost:16686/.