この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
おはようございます、加藤です。Consul チュートリアルをやってみたの第2回です。Connect機能を触って見ました。
- Consul by HashiCorp
- Consulのメインページ
- Consul Curriculum - HashiCorp Learn
- Consulのチュートリアル
Connect機能の説明
Connect機能はサービス間をTLS暗号化と認証を行う機能です。 サイドカープロキシとして動作し、例えばサービスA→サービスBへ通信を行う際に異なるホストで動作していたとしても、サービスA, Bどちらもlocalhostへの通信(Consul Connectへの通信)を行う事でサービス間通信を行えます。
やってみる内容
socat
とnc
を使って、TCPでメッセージを送るとオウム返しされる環境をConsul Connect経由で行ってみます。
今回やってみる内容は学習の為のものです。本番利用に耐えうる物では無いので、その際は下記を確認してください。 Connect in Production - Consul by HashiCorp
Consulへサービスを登録
サービス定義ファイルを作成します。
host
cat <<EOF | tee ./consul.d/socat.json
{
"service": {
"name": "socat",
"port": 8181,
"connect": { "sidecar_service": {} }
}
}
EOF
cat <<EOF | tee ./consul.d/web.json
{
"service": {
"name": "web",
"port": 8080,
"connect": {
"sidecar_service": {
"proxy": {
"upstreams": [{
"destination_name": "socat",
"local_bind_port": 9191
}]
}
}
}
}
}
EOF
コンテナ起動
操作はコンテナ上で行います。作成したサービス定義をマウントして、コンテナを起動し中に入ります。
host
docker run --rm --name consul_getting_started -v $(pwd)/consul.d/:/consul/config -d consul
docker exec -it consul_getting_started sh
サービスとConnectの起動
socat
をバックグラウンドで立ち上げます。ログを後で見れるようにファイルに書き出しておきます。/consul/log/
は、ホストだと.consul.d/log/
に該当します。
container
apk add socat
mkdir -p /consul/log
socat -v tcp-l:8181,fork exec:"/bin/cat" > /consul/log/socat.txt 2>&1 &
Consul Connectをそれぞれバックグラウンドで立ち上げます。
container
consul connect proxy -sidecar-for socat > /consul/log/connect_socat.txt 2>&1 &
consul connect proxy -sidecar-for web > /consul/log/connect_web.txt 2>&1 &
動作確認と説明
nc
を使って通信を開始します。テキストを入力してEnterを押すとオウム返しされることを確認してください。
確認が終わったらCtrl + C
で終了してください。
container
nc 127.0.0.1 9191
お気づきでしょうか?socat
は8181
待機しているのに、nc
は9191
へ通信を行っています。
サービス定義ファイルを確認しながら簡単に説明して行きます。
socat.json
はサービス名がsocat
でポートが8181
である事が定義されています。
socat.json
{
"service": {
"name": "socat",
"port": 8181,
"connect": { "sidecar_service": {} }
}
}
web.json
はサービス名がweb
でポートが8080
である事が定義されています...がこちらは関係はありません。
sidecar_service
の部分が重要です。ここでは、プロキシのルールが書かれておりlocalhost:9191
へ通信するとsocat
サービスへ転送する内容になっています。
web.json
{
"service": {
"name": "web",
"port": 8080,
"connect": {
"sidecar_service": {
"proxy": {
"upstreams": [{
"destination_name": "socat",
"local_bind_port": 9191
}]
}
}
}
}
}
アクセス制御
Consul Connectの機能には認証もあります。今はnc
の通信が出来ていますが、これを遮断してみましょう。
container
consul intention create -deny web socat
# Created: web => socat (deny)
通信できるか確認してみると、意図したとおり失敗しました。
container
nc -v 127.0.0.1 9191
127.0.0.1 (127.0.0.1:9191) open
nc: too many output retries
アクセスを開放します。
container
consul intention delete web socat
Intention deleted.
この機能によって、IDベースでの認証が可能になります。(IDはConsulサービス定義で指定した名前を指しています。)
あとがき
前回と合わせて、Consulの出来ること・良さが少しずつ見えてきた気がします。早く一通りやり切って本番運用に耐えうる環境を作ってみたいです。