谷本 心 in せろ部屋

はてなダイアリーから引っ越してきました

Dapr Advent Calendar 20日目 - DaprをAmazon EC2で使う

こんにちは Dapr Advent Calendar 20日目です。錦鯉、M-1優勝おめでとうございます! うるさい漫才は好きではないんですが、錦鯉は、なんでしょうか、キャラのせいなんですかね、わりと好きなんです。優勝したペアが涙を流すことはあっても、審査員までもらい泣きしているのはなかなか見ないなと思いましたね!

DNSにConsulを使ってEC2でDaprを運用する

さて、以前 Dapr Advent Calendar 12日目 - Daprをk8s以外の分散環境で使う で、Amazon EC2のようにIPマルチキャストが使えない環境では、Daprを動かすためにConsulが必要ということを書きました。それについて、@kencharosさんからコメントを貰いました。

Consulはdevモードであれば立てるのがそんなに難しくないようなので、今回はこれで試してみましょう。

EKSで動かした翌日にEC2で動かした話を書くなんて、なんか技術スタックが巻き戻ってる気もするのですが、k8sを使うことに抵抗がある人も多いでしょうから、参考にしてもらえると嬉しいです。

f:id:cero-t:20211220101711p:plain
今回作るアプリケーション

EC2にインスタンスを作成

まずはAmazon EC2インスタンスを3つ作ります。1台はConsulサーバ、残り2台はアプリケーションをデプロイするサーバとして利用します。

EC2の使い方や手順などについては割愛しますが、Amazon Linux 2のt2.microインスタンスを3つ作りました。

EC2にConsul環境を構築

まずはEC2インスタンスの1台にConsulの環境を構築しましょう。

次のコマンドを実行してConsulのCLIツールをインストールします。

curl -LO https://releases.hashicorp.com/consul/1.11.1/consul_1.11.1_linux_amd64.zip
unzip consul_1.11.1_linux_amd64.zip
sudo mv consul /usr/local/bin/

続いて、Consulをサーバとして起動します。

consul agent -dev -client=0.0.0.0

開発用に1インスタンスで起動するだけなので -dev オプションをつけ、別のインスタンスからアクセスできるよう -client=0.0.0.0 オプションをつけました。

これでConsulサーバの構築は完了です。とても簡単でしたね。

アプリケーションのDapr実行環境を構築

続いて、残り2台のインスタンスにアプリケーションを実行するための環境を構築しましょう。

まずはJava 11 (corretto)をインストールします。

sudo yum install -y java-11-amazon-corretto-headless

続いて、Dapr CLIをインストールして初期化します。

wget -q https://raw.githubusercontent.com/dapr/cli/master/install/install.sh -O - | /bin/bash
dapr init --slim

Daprは --slim オプションを付けて、Dockerや設定ファイルを作らないスタンドアロンモードで初期化しました。

これでアプリケーションの実行環境が構築できました。

アプリケーションのデプロイ

ソースコード

続いてアプリケーションの準備です。サンプルアプリケーションのソースコードGitHubに置いてあります。

https://github.com/cero-t/dapr-advent-2021

このうち「hello」と「invoke」を使います。何度も使っているアプリケーションなので、ソースコードの説明は省略します。

名前解決にConsulを使う設定ファイルを作成

Daprが連携するために使う名前解決にConsulを利用できるよう設定ファイルを作成します。ComponentではなくConfigurationとして、次のように設定します。

consul-config.yaml

apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
  name: consul-config
spec:
  nameResolution:
    component: "consul"
    configuration:
      selfRegister: true
      client:
        address: "172.*.*.*:8500"

spec.nameResolution に名前解決の設定をします。

今回はConsulを利用するため componentconsul を指定しました。

そして、起動時にアプリケーションが自動登録されるよう configuration.selfRegistertrue とします。

また configuration.client.address にConsulサーバのプライベートIPアドレスを指定します。後ほど、アプリケーションを実行するインスタンス上でこの値を書き換えます。

この設定ファイルを使うことで、Daprが名前解決としてConsulを利用できるようになります。

ソースコードのダウンロードと書き換え

それでは、アプリケーションを実行する2台のインスタンスでそれぞれアプリケーションのソースコードをダウンロードしして解凍します。

curl -LO https://github.com/cero-t/dapr-advent-2021/archive/refs/heads/main.zip
unzip main.zip

続いて、Consulサーバのアドレスを書き換えましょう。

vi dapr-advent-2021-main/consul-config.yaml

一番最後の行にある 172.*.*.*:8500 の部分に、Consulサーバとして起動したインスタンスのプライベートIPを指定してください。この作業も2台のインスタンスでそれぞれ行います。

アプリケーションの起動

それではアプリケーションを起動しましょう。

1台目のインスタンスでhelloアプリケーションを起動します。

cd dapr-advent-2021-main/hello
dapr run --app-id hello-app --app-port 8080 --dapr-http-port 18080 --config ../consul-config.yaml ../mvnw spring-boot:run

--config ../consul-config.yaml オプションをつけて、設定ファイルが有効化されるようにしました。

2台目のインスタンスも同様にしてinvokeアプリケーションを起動します。

cd dapr-advent-2021-main/invoke
dapr run --app-id invoke-app --app-port 8081 --dapr-http-port 18081 --config ../consul-config.yaml -- ../mvnw spring-boot:run -Dspring-boot.run.profiles=dapr

オプションは上と同様です。また -Dspring-boot.run.profiles=dapr をつけて application-dapr.yaml の設定が有効になるようにしています。

これでアプリケーションの起動が完了しました。

アプリケーションにアクセス

そして、別のコンソールから任意のインスタンス上で次のコマンドでアクセスします。

curl (invokeアプリケーションを起動したインスタンスのプライベートIPアドレス):8081/invokeHello

次のような結果が表示されます。

{"baseUrl":"http://localhost:18081/v1.0/invoke/hello-app/method","remoteMessage":{"message":"Hello, world!"}}

問題なくinvokeアプリケーションからhelloアプリケーションにアクセスできましたね!

AWSではマルチキャストDNSが使えないため、名前解決の設定なしでは通信することができませんでした、Consulを利用することで無事にDapr上で動くアプリケーション同士が連携して通信することができました。

f:id:cero-t:20211220002142p:plain
Consulを使った名前解決

EC2かEKSか

Daprのことを話題にすると、HTTP通信だけですべてが解決できるとか、別のサーバなどなしで開発ができるところをメリットと思ってもらえるのですが、「ただ、k8sはちょっと・・・」というところで尻込みされることが何度となくありました。minikubeやEKSを使ってみて、そこまで難しいとは感じませんでしたが、とは言えやはりこれまで使ってきた技術スタックとは異なるものですし、Daprという新しい技術に加えてk8sまで使うとなると、抵抗があるというのも理解できます。

今回はConsulを使い、EC2アプリケーション上で動くDaprアプリケーション同士が通信できることを確認しました。この方法を使えばk8sを使わなくともDaprアプリケーションを運用することができます。もちろんConsulのサーバを立てて運用する必要がありますが、その辺りはSpring CloudのEurekaなども大きな差はないでしょう。欲を言えば、AWSがマネージドConsulサーバサービスを提供してくれると嬉しいところです。

いずれにせよk8sだけでなく、EC2のような仮想サーバに直接デプロイするとか、ECSのようなコンテナサービスにデプロイするとかが気軽にできるようになれば、またDaprを利用する人も増えるんじゃないかなと思います。名前解決の簡単さはDaprの強みとなるので、今後のアップデートでより洗練されることを期待しています。

まとめ

  • Consulの開発モードを使ってEC2上にConsulサーバを立てました
  • Daprの設定でConsulサーバを名前解決に使うよう設定しました
  • Consulを使えば問題なくEC2でも名前解決ができ、通信することができました

これを12日目のエントリーの時点で書けていれば、もっと良かったのですけどね🙄

ちょっと行き当たりばったりになってしまうところも、毎日ブログを書いてる醍醐味ひとつということで。

それでは、また!