.NET 6 と Daprを使った分散サービス開発 その11 Secret Store
Daprでシークレット管理
前回は、Daprに備わっているBinding (バインディング)を用いて、RabbitMQでのPubSubを扱ってきました。今回は、接続文字列やDBなどのパスワード、APIのアクセスキーなどのシークレット管理について触れていきたいと思います。
今までの前提の上でバインディングの機能を追加しますので、このページから読まれている方は、前提として以下を読んできてください。
Daprでシークレット管理
マイクロサービスや分散サービスなどでは様々な言語を用いて、これらシークレットを共通で管理するケースも多く、どの言語からも、ローカルでもKubernetesでも、同じように取得できる必要もあり、どのようにルールを定めて運用するか悩ましい所でもあります。
そして、ハードコードする事だけは避けたいものです。
これらに加えて、AWS、Azure、GCPなどのクラウドでは、これらのHSMキー管理のサービスがありますから、対応していくのも大変面倒ですし、ローカルで自分だけってケースであれば、常にそれらを使うというシチュエーションでもないケースも多分にあります。
Secret store(シークレットストア)コンポーネント
そこで、Daprではシークレット管理を抽象化するコンポーネントがあり、コンポーネント設定によって必要に応じて切り替える事ができます。
普段はローカル環境で環境変数で開発しておき、いざAzureなどにデプロイする際にはAzure Key Vaultで管理するとすれば良い事になります。
- Environment Variables (環境変数)
- Local file (ローカルファイル)
- Kubernetes secrets
- AWS Secrets Manager
- Azure Key Vault
- GCP Secret Manager
- HashiCorp Vault
コンポーネントを設定
今回は最も簡単なセッティング方法である、ローカルファイルに集約する方法で試します。componentsフォルダに以下のようにファイルを構成しました。
また、nestedSeparatorによって キー名:ネストされたキー名で呼び出す事ができるようになります。
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: daprsecret
spec:
type: secretstores.local.file
metadata:
- name: secretsFile
value: ./secrets.json
- name: nestedSeparator
value: ":"
また、合わせてsecret.jsonをルートフォルダに作ります。パスが解決できていない場合、Dapr側のログにも見つからないとログでますので、ロードできているか確認しましょう。
例として、以下のようなファイルを作成しました。
nestedSeparatorが設定されているので、以下のファイルの場合では、connectionStrings:productdbというキー名での呼び出しも可能です。
{
"azureStorageKey": "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==",
"redisPassword": "",
"connectionStrings": {
"customerdb": "Server=127.0.0.1;Port=3306;Database=customerdb;Uid=guest@localhost;Pwd=Passw0rd!;SslMode=Required;",
"productdb": "Server=127.0.0.1;Port=3306;Database=productdb;Uid=guest@localhost;Pwd=Passw0rd!;SslMode=Required;"
}
}
他のコンポーネントから読み出す
daprのコンポーネント設定そのものに、このようなシークレットが含まれています。そこで、まずは他のコンポーネントの設定をこれらのシークレットデータに置き換える方法について確認しましょう。
以下は、今まで設定してきたState Store用のRedisを設定しているコンポーネント設定のYMALです。ローカルからアクセスしていますので、特にパスワードの設定をしていないのですが、ここでは設定していると思ってください。
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: statestore
spec:
type: state.redis
version: v1
metadata:
- name: redisHost
value: localhost:6379
- name: redisPassword
value: ""
設定後は、以下のようになります。
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: statestore
spec:
type: state.redis
version: v1
metadata:
- name: redisHost
value: localhost:6379
- name: redisPassword
secretKeyRef:
name: redisPassword
key: redisPassword
auth:
secretStore: daprsecret
設定しているキーが同じ名前なので、ちょっと疑問に思うかもしれません。
これはキー設定の環境によっては、異なる為で、これはローカルから今回jsonを設定しているケースの設定だからです。
secretKeyRef:
name: redisPassword
key: redisPassword
Kubernetes やAzure Key Vaultなどの場合は、このnameとkeyは設定が異なる場合があります。
例えば、以下のようにKubernetes でSecretを作って、読み込みたい場合であるとして
kubectl create secret generic daprsecrets --from-literal=redisPassword=secretPassword -n appsecret
secretKeyRef:
name: daprsecrets
key: redisPassword
となります。
アプリケーション側から呼び出す
今回は、前回使ったpub-serviceのプロジェクトを修正して、シークレットをロードしてみます。
using Dapr.Client;
namespace PubService
{
class Program
{
static async Task Main(string[] args)
{
string PUBSUB_NAME = "daprpubsub";
string TOPIC_NAME = "AppStatus";
while (true)
{
System.Threading.Thread.Sleep(3000);
Random random = new Random();
int stateId = random.Next(1, 1000);
CancellationTokenSource source = new CancellationTokenSource();
CancellationToken cancellationToken = source.Token;
using var client = new DaprClientBuilder().Build();
await client.PublishEventAsync(PUBSUB_NAME, TOPIC_NAME, stateId.ToString(), cancellationToken);
Console.WriteLine("Published data: " + stateId);
// 以下を新規に追加
var storageKey = await client.GetSecretAsync("daprsecret", "azureStorageKey");
Console.WriteLine($"Load secret : {storageKey["azureStorageKey"]}");
var connStr = await client.GetSecretAsync("daprsecret", "connectionStrings:customerdb");
Console.WriteLine($"Load connection string : {connStr["connectionStrings:customerdb"]}");
}
}
}
}
tyeの起動と確認
ここまで来たらTyeを起動して、確認しましょう。
サイドカーとして起動したDaprからシークレットを読み取り、コンソールに表示しているログが出力されているはずです。
Author And Source
この問題について(.NET 6 と Daprを使った分散サービス開発 その11 Secret Store), 我々は、より多くの情報をここで見つけました https://qiita.com/kazumihirose/items/ec98a49743d24702cce5著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .