以前の記事で、Docker Composeを使ってローカルマシンにRedis Clusterを構築しました。 今回は少し発展させて、Visual Studioで同Docker Composeにアプリケーションをコンテナ起動 & デバッグ実行する方法を紹介します。
- 接続図
- Visual StudioのDocker Compose統合
- Redis ClusterをDocker Composeに追加
- デバッグ実行
- ローカルRedis Clusterを組んでもフェイルオーバー処理の確認は難しい
- まとめ
接続図
ちょっと何を言っているかよくわからないってなりそうなので、まずはどのような接続をしたいのかを説明します。
Docker Composeを使ってRedis ClusterとVisual Studioのアプリケーションをコンテナ起動します。Visual StudioのDocker Compose統合でコンテナ実行したアプリケーションをデバッグ実行できるという寸法です。 Docker Composeのファイル的には次のようなイメージです。
services: # Visual Studoでデバッグ実行するアプリケーション redisfailover.direct: image: ${DOCKER_REGISTRY-}redisfailoverdirect build: context: src/Redis/RedisFailover.Direct dockerfile: Dockerfile # Redis Cluster redis-node-0: image: docker.io/bitnami/redis-cluster:7.2 environment: - 'REDIS_PASSWORD=bitnami' - 'REDIS_NODES=redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5' redis-node-1: image: docker.io/bitnami/redis-cluster:7.2 environment: - 'REDIS_PASSWORD=bitnami' - 'REDIS_NODES=redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5' redis-node-2: image: docker.io/bitnami/redis-cluster:7.2 environment: - 'REDIS_PASSWORD=bitnami' - 'REDIS_NODES=redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5' redis-node-3: image: docker.io/bitnami/redis-cluster:7.2 environment: - 'REDIS_PASSWORD=bitnami' - 'REDIS_NODES=redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5' redis-node-4: image: docker.io/bitnami/redis-cluster:7.2 environment: - 'REDIS_PASSWORD=bitnami' - 'REDIS_NODES=redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5' redis-node-5: image: docker.io/bitnami/redis-cluster:7.2 depends_on: - redis-node-0 - redis-node-1 - redis-node-2 - redis-node-3 - redis-node-4 environment: - 'REDIS_PASSWORD=bitnami' - 'REDISCLI_AUTH=bitnami' - 'REDIS_CLUSTER_REPLICAS=1' - 'REDIS_NODES=redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5' - 'REDIS_CLUSTER_CREATOR=yes' ports: - 6379:6379
図にすると次のような構成です。
flowchart LR
subgraph "ホストマシン"
visualstudio["Visual Studio"]
end
subgraph "Docker Desktop"
subgraph "Docker Compose"
redisfailover.direct
subgraph "Redis Cluster"
redis-node-0
redis-node-1
redis-node-2
redis-node-3
redis-node-4
redis-node-5
end
end
end
redisfailover.direct --クラスターエンドポイント---> redis-node-5
redisfailover.direct -. 必要に応じてスロット先ノードに切り替え .-> redis-node-4
redisfailover.direct -. 必要に応じてスロット先ノードに切り替え .-> redis-node-3
redisfailover.direct -. 必要に応じてスロット先ノードに切り替え .-> redis-node-2
redisfailover.direct -. 必要に応じてスロット先ノードに切り替え .-> redis-node-1
redisfailover.direct -. 必要に応じてスロット先ノードに切り替え .-> redis-node-0
visualstudio --vsdbg--> redisfailover.direct
ポイントは「ホストからRedis Clusterの各ノードにはホスト名で直接接続できない」制約です。Docker Compose内で解決される各ホスト名を使ってRedis Clusterの各ノードをつないでいるため、スロット先の接続先がこのホスト名(redis-node-0とか)になります。このホスト名はCompose内では解決できますがホストマシンからは解決できないので、ホストマシンからRedis Clusterの接続しスロットが別ノードの場合、ホストからそのノードへの接続名1が解決できず接続エラーになります。
そこで、Visual StudioのDocker Compose統合を使ってアプリケーションを同Docker Composeでコンテナ起動します。アプリケーションはRedis Clusterのホスト名が解決できるの、でRedis Clusterのスロットが別ノードに格納されていても問題なく接続できます。開発者は、Visual Studioから同コンテナ上のアプリケーションにデバッガーをさした状態なので、いつも通りVSデバッグできます。2
ホストから繋げないことは別に問題ではなく、Visual Studioでデバッグできればいいという考え方です。
Visual StudioのDocker Compose統合
Visual Studioにはコンテナオーケストレーションサポートがあります。csprojを右クリック > Add > Container Orchestrator Support... でDocker Composeを追加できます。
追加するとslnと同じパスに以下のファイルができます。
- docker-compose.dcproj
- docker-compose.override.yml
- docker-compose.yml
- .dockerignore
見慣れないdocker-compose.dcprojはVisual StudioのDocker Compose統合の象徴で、このファイルがVisual Studioで認識されると、Visual StudioにDocker Composeプロファイルができて、指定したcsprojのアプリケーションをコンテナビルド & Docker Composeで実行します。
docker-compose.yamlには右クリックしたcsprojのコンテナ定義が書かれており、docker-compose.override.ymlにはデバッグ実行用のオーバーライド設定が書かれています。ASP.NET Coreの環境名やエンドポイントが環境変数で上書き指定されています。
# docker-compose.yaml services: redisfailover.direct: image: ${DOCKER_REGISTRY-}redisfailoverdirect build: context: src/Redis/RedisFailover.Direct dockerfile: Dockerfile # docker-compose.override.yml services: redisfailover.direct: environment: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_HTTP_PORTS=8080 ports: - "8080"
このdocker-compose.yamlに起動したいコンテナを追加すれば、アプリケーションから名前解決できる状態を作れそうですね?次節でRedis Clusterを追加してみましょう。
Redis ClusterをDocker Composeに追加
Visual StudioのDocker Compose統合で追加されたdocker-compose.ymlにRedis Clusterを追加します。Visual StudioのDocker Composeプロファイルでデバッグ実行すると、Redis Clusterとアプリケーションが同じDocker Composeで起動します。
services: redisfailover.direct: image: ${DOCKER_REGISTRY-}redisfailoverdirect build: context: src/Redis/RedisFailover.Direct dockerfile: Dockerfile redis-node-0: image: docker.io/bitnami/redis-cluster:7.2 environment: - 'REDIS_PASSWORD=bitnami' - 'REDIS_NODES=redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5' redis-node-1: image: docker.io/bitnami/redis-cluster:7.2 environment: - 'REDIS_PASSWORD=bitnami' - 'REDIS_NODES=redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5' redis-node-2: image: docker.io/bitnami/redis-cluster:7.2 environment: - 'REDIS_PASSWORD=bitnami' - 'REDIS_NODES=redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5' redis-node-3: image: docker.io/bitnami/redis-cluster:7.2 environment: - 'REDIS_PASSWORD=bitnami' - 'REDIS_NODES=redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5' redis-node-4: image: docker.io/bitnami/redis-cluster:7.2 environment: - 'REDIS_PASSWORD=bitnami' - 'REDIS_NODES=redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5' redis-node-5: image: docker.io/bitnami/redis-cluster:7.2 depends_on: - redis-node-0 - redis-node-1 - redis-node-2 - redis-node-3 - redis-node-4 environment: - 'REDIS_PASSWORD=bitnami' - 'REDISCLI_AUTH=bitnami' - 'REDIS_CLUSTER_REPLICAS=1' - 'REDIS_NODES=redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5' - 'REDIS_CLUSTER_CREATOR=yes' ports: - 6379:6379
コンテナ起動したアプリケーションがRedis Clusterに接続できるように、appsettings.jsonにDocker Composeで起動したRedis Clusterへの接続情報を書いておきましょう。
{ "ConnectionStrings": { "Redis1": "redis-node-5:6379,ssl=false,keepAlive=60,password=bitnami", "Redis2": "redis-node-5:6379,ssl=false,keepAlive=60,password=bitnami" } }
用意完了です。
デバッグ実行
Docker Composeプロファイルでデバッグ実行しましょう。
Visual StudioのContainers Windowを見ると、dockercomposeXxxxxとしてRedis Clusterの各ノードとアプリケーションコンテナがまとめて起動しているのがわかります。
Containers WindowのLogsをみると、Redis Clusterの各ノードが起動しているのがわかります。
このアプリケーションはSwagger統合しているASP.NET Coreアプリケーションなので、デバッグ実行するとコンテナのSwagger UIがブラウザで開きます。
RedisへのSetStringを実行すると無事に実行できたことがログからわかります。Redis Cluster接続も確認できます。
RedisFailover.Direct | info: RedisFailover.Direct.Infrastructures.ElastiCacheConnectionContext[0] RedisFailover.Direct | Connecting to redis: ElastiCache/Unspecified/redis-node-5:6379
このアプリケーションは、以前の記事で紹介したフェイルオーバー処理が入っています。アプリケーションが接続していたredis-node-05を終了させてみましょう。ログから接続切断イベントを拾って別ノードとつながって自動復旧しているのがわかります。
ちなみに複数ノードをストップさせることで、CLUSTER DOWNを再現したり、そこからノードを起動してコネクションが自動復旧することも確認できます。
ローカルRedis Clusterを組んでもフェイルオーバー処理の確認は難しい
今回みはRedis Clusterの中に6シャード(0-5)を起動していますがレプリカは存在しません。このため、ElastiCacheやMemoryDBに期待するようなレプリカのフェイルオーバー処理は確認できません。
このため、フェイルオーバー処理を確認するなら、基本的な接続切断回りまではこの仕組みで動作確認しつつ、フェイルオーバー挙動自体はElastiCacheやMemoryDBを用いて確認したほうがいいでしょう。
まとめ
Redis ClusterとVisual Studioを連携させて、アプリケーションのデバッグ実行をできることを示しました。コンテナを使うメリットはホストマシンにアプリケーションを構築せず、こういった検証が簡単にできることです。また、Visual StudioのDocker Compose統合はコンテナのデバッグ実行を簡単にできるので、ぜひ使ってみてください。
Redis Clusterの仕組みは軽くしか触れていないので、Redis Clusterの仕組みを理解したい方はRedis cluster specification | Docs | Redisを参照してください。Redis Clusterを知るいいチャンスです。