Add week 6 materials
This commit is contained in:
@@ -0,0 +1 @@
|
||||
consul-data-*
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM python:3.9-slim-buster
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY requirements.txt requirements.txt
|
||||
RUN pip install -r requirements.txt
|
||||
|
||||
COPY . .
|
||||
|
||||
CMD ["python", "./main.py"]
|
||||
@@ -0,0 +1,33 @@
|
||||
import os
|
||||
from flask import Flask
|
||||
from consul import Consul, Check
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
consul_host = os.environ.get('CONSUL_HOST', 'localhost')
|
||||
consul_port = os.environ.get('CONSUL_PORT', 8500)
|
||||
my_host = os.environ.get('MY_HOST', 'localhost')
|
||||
my_port = os.environ.get('MY_PORT', 5000)
|
||||
|
||||
# Initialize Consul client
|
||||
consul = Consul(host=consul_host, port=consul_port)
|
||||
|
||||
# Register the Flask app in Consul
|
||||
service_name = 'flask-hello-world'
|
||||
consul.agent.service.register(
|
||||
name=service_name,
|
||||
service_id=f'{service_name}-{my_host}',
|
||||
port=my_port,
|
||||
check=Check.http(f'http://{my_host}:{my_port}/health', interval='10s', deregister='30s')
|
||||
)
|
||||
|
||||
@app.route('/')
|
||||
def hello():
|
||||
return 'Hello, World!'
|
||||
|
||||
@app.route('/health')
|
||||
def health():
|
||||
return 'OK'
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(host='0.0.0.0', port=my_port)
|
||||
@@ -0,0 +1,3 @@
|
||||
python-consul==1.1.0
|
||||
Flask==2.2.2
|
||||
Werkzeug==2.2.2
|
||||
@@ -0,0 +1,62 @@
|
||||
version: '3'
|
||||
services:
|
||||
consul-server-1:
|
||||
image: consul:1.15
|
||||
command: |
|
||||
consul agent -ui -server -bootstrap-expect=3 -data-dir=/consul/data -client=0.0.0.0
|
||||
volumes:
|
||||
- ./consul-data-1:/consul/data
|
||||
ports:
|
||||
- 8500:8500
|
||||
- 8600:8600/udp
|
||||
|
||||
consul-server-2:
|
||||
image: consul:1.15
|
||||
command: |
|
||||
consul agent -server -retry-join=consul-server-1 -data-dir=/consul/data -client=0.0.0.0
|
||||
volumes:
|
||||
- ./consul-data-2:/consul/data
|
||||
ports:
|
||||
- 8501:8500
|
||||
- 8601:8600/udp
|
||||
depends_on:
|
||||
- consul-server-1
|
||||
|
||||
consul-server-3:
|
||||
image: consul:1.15
|
||||
command: |
|
||||
consul agent -server -retry-join=consul-server-1 -data-dir=/consul/data -client=0.0.0.0
|
||||
volumes:
|
||||
- ./consul-data-3:/consul/data
|
||||
ports:
|
||||
- 8502:8500
|
||||
- 8602:8600/udp
|
||||
depends_on:
|
||||
- consul-server-1
|
||||
|
||||
app-1:
|
||||
build:
|
||||
context: ./app
|
||||
ports:
|
||||
- 5001:5000
|
||||
environment:
|
||||
CONSUL_HOST: consul-server-1
|
||||
MY_HOST: app-1
|
||||
|
||||
app-2:
|
||||
build:
|
||||
context: ./app
|
||||
ports:
|
||||
- 5002:5000
|
||||
environment:
|
||||
CONSUL_HOST: consul-server-2
|
||||
MY_HOST: app-2
|
||||
|
||||
app-3:
|
||||
build:
|
||||
context: ./app
|
||||
ports:
|
||||
- 5003:5000
|
||||
environment:
|
||||
CONSUL_HOST: consul-server-3
|
||||
MY_HOST: app-3
|
||||
@@ -0,0 +1,57 @@
|
||||
# Consul: членство агентов и здоровье сервисов
|
||||
|
||||
[К материалам семинара](../readme.md)
|
||||
|
||||
В стенде работают три сервера Consul и три экземпляра Flask-приложения. Каждый экземпляр регистрирует себя в Consul вместе с HTTP-проверкой `/health`, выполняемой раз в 10 секунд. Проверка приложения и обнаружение недоступности агентов Consul — разные механизмы.
|
||||
|
||||
## Запуск и наблюдение
|
||||
|
||||
Нужны Docker и Docker Compose. Команды выполняются из этой директории. В PowerShell вместо `curl` используйте `curl.exe`.
|
||||
|
||||
Сначала запустите серверы:
|
||||
|
||||
```shell
|
||||
docker compose up -d consul-server-1 consul-server-2 consul-server-3
|
||||
```
|
||||
|
||||
Дождитесь появления трёх узлов в [интерфейсе Consul](http://localhost:8500), затем запустите приложения. Такой порядок нужен, потому что регистрация приложения выполняется один раз при старте и требует доступного Consul.
|
||||
|
||||
```shell
|
||||
docker compose up --build -d app-1 app-2 app-3
|
||||
docker compose exec consul-server-1 consul members
|
||||
curl http://localhost:8500/v1/catalog/services
|
||||
curl http://localhost:8500/v1/health/checks/flask-hello-world
|
||||
curl "http://localhost:8500/v1/health/service/flask-hello-world?passing=true"
|
||||
```
|
||||
|
||||
Здесь `consul members` показывает агентов, каталог — зарегистрированные сервисы, а health API — проверки и экземпляры, прошедшие их. Дождитесь успешных проверок всех трёх приложений. Если приложение завершилось при регистрации, причину можно увидеть через `docker compose logs app-1 app-2 app-3`.
|
||||
|
||||
## Остановка приложения
|
||||
|
||||
```shell
|
||||
docker compose stop app-2
|
||||
```
|
||||
|
||||
Повторите запросы к health API и `consul members`. После очередной проверки экземпляр `app-2` перестанет попадать в выдачу с `passing=true`, хотя агент `consul-server-2` останется участником группы. Сервис может ещё быть зарегистрирован в каталоге: каталог и список здоровых экземпляров имеют разный смысл. При длительном провале проверки настроена автоматическая отмена регистрации.
|
||||
|
||||
Верните приложение и после проверки снова сравните результаты:
|
||||
|
||||
```shell
|
||||
docker compose start app-2
|
||||
```
|
||||
|
||||
Обработчик `/health` в [коде приложения](app/main.py) просто возвращает `OK`. Он позволяет заметить недоступность HTTP-сервера, но не проверяет выполнение полезной работы или доступность зависимостей. Этот опыт показывает проверку сервиса; для изучения отказов самих агентов потребовался бы другой сценарий.
|
||||
|
||||
## Связь с маршрутизацией
|
||||
|
||||
Клиент или балансировщик может использовать сведения о здоровых экземплярах для выбора адреса. В этом стенде балансировщик не настроен, и с [демо Envoy](../envoy-outlier-detection/readme.md) он не соединён.
|
||||
|
||||
После работы остановите стенд:
|
||||
|
||||
```shell
|
||||
docker compose down
|
||||
```
|
||||
|
||||
Данные Consul сохраняются в каталогах `consul-data-*`, поэтому следующий запуск не обязательно начинается с пустого каталога.
|
||||
|
||||
Документация: [Health API](https://developer.hashicorp.com/consul/api-docs/health), [gossip и Lifeguard в Consul](https://developer.hashicorp.com/consul/docs/concept/gossip).
|
||||
Reference in New Issue
Block a user