落とし穴に立て札を立てるが如く

ハマりどころの解決が少しでも早くなることを願って書いていきます

Azure Active DirectoryのアカウントでSQL Databaseにログインしようの会

f:id:nam_yu_sql:20210212090906j:plain
この記事はcloud.config tech blogにもマルチポストしています。

tech-blog.cloud-config.jp

はじめに

DP-300の資格試験に完全勝利したなむゆです。
この資格はAzureのRDBサービス周りの各種機能について習熟していることを示す資格で、その試験勉強中に触った機能で面白かったものをピックアップしてみようということで一席打ちます。
ということで今回はSQL DatabaseにAzure Active Directoryのアカウントでログインできるようにしてみます。

Azure Active DirectoryのアカウントでSQL Databaseにログインできるようにする

まずはいつものようにSQL Databaseのリソースを作成します。
f:id:nam_yu_sql:20210212090937p:plain
リソースを作成したら忘れずに現在のIPからのアクセスを「サーバーファイアウォールの設定」から行っておきましょう。

設定できたら、次はSQL DatabaseのActive Directory管理者を設定します。
このユーザーはAzure Active Directoryに登録されているユーザーの中で最初にSQL Databaseにログインできるようにするユーザーで、そのユーザーを用いて他のActive Directoryに登録されたユーザーをSQL Databaseにログインできるようにできます。
f:id:nam_yu_sql:20210212091148p:plain
SQL Databaseのリソースの中の「Active Directory管理者」を選択します。
出てきた表示の上部に「管理者の追加」があるので、そこをクリックします。
f:id:nam_yu_sql:20210212091151p:plain
そうすると、現在使用しているActive Directoryのユーザーの一覧があるので、今回はあらかじめ作成しておいた「testtest」という名前のユーザーを登録しておきます。
このユーザーを選択し、「選択」ボタンをクリックして戻ります。
最後に「保存」をクリックして保存します。

これによって最初のActive DirectoryのユーザーがこのSQL Databaseにログインできるようになりました。
このユーザー情報でSQL Databaseにログインできることを確認しましょう。
ここからの作業はSSMS(SQL Server Management Studio)を使用しますのでまだインストールしていない場合はインストールしておきます。

SSMSを開き、データベースに接続します。ログイン時に「認証」の欄を「Azure Active Directory - パスワード」を選択します。
その下に先程追加したActive Directoryユーザーのユーザー名とパスワードを入力します。
ユーザー名はユーザープリンシパル名が全文必要なので、プロファイルのページから全文コピーしてきましょう。
f:id:nam_yu_sql:20210212091154p:plain
これでActive Directory管理者のユーザーでログインできたはずです。
次は、このユーザーを用いて他のAzure Active Directory上のユーザーを追加していきましょう。
接続したデータベースを右クリックして「新しいクエリ」を選択し、クエリエディタを呼び出します。
f:id:nam_yu_sql:20210212091144p:plain
そこに、以下のクエリを打ちこんで実行します。
{ユーザープリンシパル名}は実際に存在するユーザーのユーザープリンシパル名を置き換えて実行してください。

CREATE USER [{ユーザープリンシパル名}] FROM EXTERNAL PROVIDER  
GO  

これでもう一つのActive Directory上のユーザーがSQL Databaseに追加されました。
SSMSをもう一つ開き、そのユーザーのユーザー名とパスワードでログインしてみましょう。
ログインできるようになっているはずです。

このようにして、Azure SQL DatabaseにAzure Active Directory上のユーザーを用いてログインできるようにできます。
ただ、この状態だとActive Directory管理者が追加したユーザーは個別のデータベースには接続できず、何の権限も与えられていない状態なので個別に権限を与えてやる費用があります。

おわりに

今回はAzure SQL DatabaseにAzure Active Directoryのアカウントを用いてログインしてみました。
これができることによって、アプリケーションの開発者がSQL Databaseに対して毎回フル権限のある管理者アカウントでログインすることで事故を起こす可能性を減らし、また、それぞれのDBのユーザーの登録情報(例えばパスワード変えたりActive Directoryから削除したり)といった変更をActive Directoryへの変更だけで済ませることができます。
Azure SQL Databaseの利用者の権限について制約がある場合に検討することが多いトピックのように思うので、頭の隅に留めておくと役立つかと思います。

参考

動かしながら学んだKubernetes Istioのメモ

f:id:nam_yu_sql:20210208065704j:plain この記事はcloud.config tech blogにマルチポストしています。

tech-blog.cloud-config.jp

はじめに

最近ずっとkubernetesの勉強しているなむゆです。
特にここ4週間くらいはIstioについて重点的に動かしたり資料を読んだりしていたのでその時に学んだ基礎的な点を記事にまとめておきたいと思います。

istioとは

Istioとは、高機能なオープンソースのサービスメッシュです。
Kubernetesのようなプラットフォームにインストールして使用され、内部にサービスメッシュを展開します。
現在はKubernetesのほかに、HashiCorpによってつくられたサービスディスカバリのConsul、または個別の仮想に対応しています。

サービスメッシュとは

「高機能なサービスメッシュ」と書きましたが、ではそのサービスメッシュとは何かというと、マイクロサービスアーキテクチャのようなサービスを複数展開し、相互に連携して全体の機能を実現しているときにそれらのサービス間のネットワークを仲介する機能です。
例えば、サービス間で通信したいとなった際に通信相手のサービスの名前解決を行ったり、それらの通信に失敗したときのリトライ機能などを基本的な機能として持ちます。
これにより、マイクロサービスアーキテクチャにおいて課題になりがちであった、サービス間の通信の障害や通信が増えることによる性能劣化といった問題を解決し、マイクロサービスアーキテクチャを実現しやすくしてくれます。
実際にどんな実装が行われていてどんな機能が実現されているかはサービスメッシュによって差があります。

これがあると何がうれしいの?

Istioはそんなサービスメッシュを実装しているもののうちの一つです。
これがなくてもkubernetesにおいてリクエストやkubernetes内のネットワークを構築することはできなくはないのですが、サービスメッシュを使うとその仕組みをより高機能に、より簡単に実装できます。
例えば、クラスター内の通信について、リトライ処理を追加したりA/Bテストを行う時に使うような割合でトラフィックを分割する仕組み、リクエストのタイムアウトの時間などを設定できます。
それらの通信についてメトリクスやログを取ることもでき、kialiやgrafana等の可視化ツールと連携してネットワークの監視を行うこともできます。
これらの機能をいくつかの設定を行うだけで実現できるのがサービスメッシュの強みになります。

アーキテクチャ

詳しい個別の情報についてはドキュメントをどうぞ。
ドキュメントが英語なのと個別に見ていくとキリがないので分かりやすい粒度でまとめてみます。
Istioのサービスメッシュは大きく分けるとData Planeという部分とControl Planeという部分に分かれます。
これらはオブジェクトとして物理的にわかれているものではなく概念的な分類なのですが、それぞれでIstio内で担う役割が違います。

Data Plane

まずData Planeなのですが、こちらは外部からやってきたものやサービスの間で交わされる通信を実際に行う役割を担います。
具体的には、Envoyと呼ばれるリソースがあり、これがkubernetes内に立てられるサービスごとにペアとなるように作られます。
このペアのように作られる様子をサイドカーと呼んだりします。バイクに対するサイドカーのように、サービスごとに横付けされるように作られるためです。
で、これが何をするものなのかと言うと、例えるなら家ごとに置かれた郵便受けやポストのようなものになります。
具体的には、他のサービスやkubernetes外部と送受信を行うプロキシになります。
外部からやってきた通信はまずEnvoyに届き、プロキシが横付けしたサービスにその内容を伝えます。
また、外部に対する通信もサービスからEnvoyに送り、そこから他のサービスやkubernetes外部に内容が送られます。
年賀状も家に届くときはまず郵便受けに届いてそこから取り出しますし、送るときは送り先に直接届けるのではなくポストに投函しますよね。
Envoyもそのような役割を果たし、ネットワーク関連の言葉で言うとプロキシの役割を果たします。そしてそれはサービス毎にサイドカーとして作られ横付けされたサービスに対するプロキシになるわけです。
また、Envoyを通して通信を行うことで通信時のトラフィックの統計情報を収集する役割もあります。

Control Plane

Control Planeは、そんなData Planeを制御する役割を持ちます。
代表的な例としてはどんなurlのリクエストがやって来たらどこのサービスにそのリクエストを送り届けるかといったルーティングVirtual Serviceを用いて行うというものがあります。
これによってkubernetes外部からやってきたリクエストをどのサービスに渡すかを制御します。
他にも、kubernetes内のサービス間での通信を制御し、通信時にルールを設定することでセキュリティの機能を実装することもできます。
これらの機能は、細かく分けるとさらにPilot(Istioの通信制御等のルールをEnvoyに伝えたりその他便利機能)、Citadel(証明書周り)、Galley(Istioに対して行う設定受けつけ)といった部分に分かれますが、今は全部まとめてIstiodというものにまとめられているようです。
なので、IstiodはEnvoyの制御を行うControl Planeの役割を大体になっているようなイメージになります。

ざっくりした動作の流れ

ここまでIstioの個別の部分の説明してきましたが、それだけだとそれを使ってどのような流れの処理になるのかイメージしづらいので、外部からリクエストがやってきてそれに対してレスポンスを行うまでの流れをざっくりと解説してみます。

全体の図としてはこのようになります。マイクロサービスアーキテクチャを採用しているのでサービスは複数あり、それぞれにEnvoyがサイドカーとして横付けされています。
この中で、EnvoyはData Planeに属しています。
この図の中で、黄色い付箋はそれぞれ一個のpodになります。
f:id:nam_yu_sql:20210208070035p:plain
kubernetesにリクエストがやってきました!
まずはこれをIngress Gatewayが受け取ります。
Ingress Gatewaykubernetes外部からやってくるリクエストの窓口で、ここからVirtualServiceのようなオブジェクトで設定したルールに応じて各種内部のサービスにリクエストを送り届けます。
f:id:nam_yu_sql:20210208065855p:plain
というわけで今回はサービスAにリクエストを送りたいのでサービスAにサイドカーとして横付けされたEnvoyにリクエストが届きました。
f:id:nam_yu_sql:20210208070048p:plain
EnvoyはそれをサービスAに渡します。
f:id:nam_yu_sql:20210208070057p:plain
今回の処理ではサービスBでの処理も行わなければならないため、サービスBに対しても通信を行います。
その際にも、まずはEnvoyと通信し、そこからサービスBへ通信を行います。
f:id:nam_yu_sql:20210208070107p:plain
サービスBでも同様に、まずEnvoyが通信を受け取り、それをサービス本体に渡します。
こうしてサービスAとサービスBの通信が実現します。
f:id:nam_yu_sql:20210208070120p:plain
サービスBでの処理が終わればまたEnvoyを通して処理結果をサービスAに返し・・・
サービスAはegress gatewayを経由してリクエスト元のkubernetesクラスター外にレスポンスを返します。
f:id:nam_yu_sql:20210208070336p:plain
これがIstioを用いてkubernetes内で通信を行う一連の流れになります。
実際にはさらにDBなどkubernetes外部のリソースと通信するために何度もegress gatewayを用いて通信を行ったりもします。

あれ、Control Planeは?

・・・本当はさらにControl Planeもこれらの処理に一枚噛んでいます。
同時に説明すると一つの動作の説明が増えるので章を分けました。
先程の例でのControl Planeの役割を説明します。

例えば、Ingress gatewayにやっていたリクエストをどのサービスに渡すかのルーティングの制御をControl Planeが行います。
VirtualServiceに設定したルーティングのルールに従い、ingress gatewayで受け取ったリクエストをどのサービスに渡すかを決め、Envoyに対してリクエストを送らせるようにします。
f:id:nam_yu_sql:20210208070416p:plain
また、サービスAとサービスBの間の通信において認証、認可の機能が必要になった場合のそれらの仕組みもControl Planeで実装します。
f:id:nam_yu_sql:20210208070427p:plain
他に、DestinationRuleやVirtualServiceを操作してサービスのバージョンアップを行う際のBlue/Greenデプロイやサーキットブレイカーなどを実装したりもします。
f:id:nam_yu_sql:20210208070447p:plain
こうした形でControl PlaneはData Planeを裏から制御する振舞いをしています。

インストール方法

それでは実際の使い方を説明していきます。
環境としてはWindows 10 HomeのOSのPCにDocker DesktopのKubernetes機能で立てたシングルノードのkubernetesを使用します。
導入方法はこちらでまとめているので、まだ導入していない場合はこちらを参考にどうぞ。

導入されたらば、次に進みます。

まずはPC上にIstioctlをダウンロードしてきます。

こちらのサイトの「istioctl-(バージョン)-win.zip」をダウンロードしてきて解凍します。
解凍したらば、分かりやすい場所に移動してそのディレクトリにPathを通します。

Pathを通してistioctlが使用できる状態になれば、インストールする対象のクラスターを現在使用しているコンテキストに指定します。

例えばDocker Desktopで立てたkubernetesにインストールする場合はPowerShell等で下記のようなコマンドを実行します。

kubectl config use-context docker-desktop  

コンテキストを切り替えたら、下記のコマンドで現在のコンテキストで接続するクラスターにistioをインストールします。

istioctl install --set profile=default -y  

「profile=○○」という部分によって、インストールされる内容が変わります。defaultのほかにdemominimal等があり、それぞれのセットアップの内容はこちらに解説があります。

weatherforecastアプリをデプロイしてみる

ここからはIstio公式サイトのGetting Startedをベースに、.net coreアプリをkubernetes上にデプロイして動かしてみます。
Getting Startedではサンプルのアプリケーションとしてbookinfoアプリを動かしてみていますが、今回は普段触れることの多いので.net coreアプリも同様にデプロイできることを示すため以前のブログで作成したweatherforecastのアプリをデプロイしてみます。
そのため、アプリケーションを作成する部分については上記のブログを参考にしながら作成していることが前提となります。
手順2まで済ませたら、こちらの手順に合流しても大丈夫です。
docker buildする際にはあとでタグが分かりやすくするために以下のコマンドでビルドします。

docker build -t weather-forecast:weather-forecast .  

コンテナが作成できたら、アプリケーションをデプロイしてIstioを用いてルーティングを行うためのマニフェストファイルを作成していきます。
以下の3つのyamlコードをコピーして同じディレクトリのファイルに保存してください。

apiVersion: v1  
kind: Namespace  
metadata:  
  name: weather-forecast  
  labels:  
    istio-injection: enabled  
apiVersion: networking.istio.io/v1alpha3  
kind: Gateway  
metadata:  
  name: weather-forecast  
  namespace: weather-forecast  
spec:  
  selector:  
    istio: ingressgateway # use istio default controller  
  servers:  
    - port:  
        number: 80  
        name: http  
        protocol: HTTP  
      hosts:  
        - "*"  
---  
apiVersion: networking.istio.io/v1alpha3  
kind: VirtualService  
metadata:  
  name: weather-forecast  
  namespace: weather-forecast  
spec:  
  hosts:  
    - "*"  
  gateways:  
    - weather-forecast  
  http:  
    - match:  
        - uri:  
            exact: /weatherforecast  
      route:  
        - destination:  
            host: weather-forecast.weather-forecast.svc.cluster.local  
            port:  
              number: 80  
  
apiVersion: v1  
kind: Service  
metadata:  
  name: weather-forecast  
  namespace: weather-forecast  
  labels:  
    app: weather-forecast  
    service: weather-forecast  
spec:  
  ports:  
    - port: 80  
      name: http  
  selector:  
    app: weather-forecast  
---  
apiVersion: apps/v1  
kind: Deployment  
metadata:  
  name: weather-forecast-v1  
  namespace: weather-forecast  
  labels:  
    app: weather-forecast  
    version: v1  
spec:  
  replicas: 1  
  selector:  
    matchLabels:  
      app: weather-forecast  
      version: v1  
  template:  
    metadata:  
      labels:  
        app: weather-forecast  
        version: v1  
    spec:  
      containers:  
        - name: weather-forecast  
          image: weather-forecast:weather-forecast  
          imagePullPolicy: IfNotPresent  
          ports:  
            - containerPort: 80  

yamlファイルを作成できたら、PowerShellを開きます。
上記の3ファイルを置いてあるディレクトリまで移動しておいてください。

移動出来たら、そのディレクトリにある3つのマニフェストファイルをkubernetesに適用します。

kubectl apply -f .  

これで作成したマニフェストファイルが適用され、指定したオブジェクトが生成されます。
一番重要なアプリケーションのPodが動作しているかどうかは以下のコマンドで確認できます。

kubectl get pods -n weather-forecast  

STATUSの欄がRunningになっていればデプロイに成功しています!

デプロイに成功したら、このAPIを叩いてみましょう。
ブラウザを開き、URLの入力欄にlocalhost:80/weatherforecastと入力してアクセスできます。
Json型のレスポンスが返ってくれば成功です!

このURLにアクセスすると、Gatewayで指定したとおり、80番ポートからkubernetesにリクエストが入ります。
それからIngressGatewayにおいてVirtualServiceに設定したとおりに/weatherforecastのパスにやってきたリクエストはweather-forecast.weather-forecast.svc.cluster.localのhostに送られます。
このhostはこちらで解説されているように、{サービス名}.{namespace名}.svc.cluster.localのルールに従って名前解決されるので、weather-foreastのnamespaceのweather-forecastサービスにリクエストが流れます。
weather-forecastのnamespaceのweather-forecastサービスにはDeploymentのオブジェクトで指定したとおりWeatherForecastのアプリのPodが結び付けられているので、めでたくリクエストはWeatherForecastのアプリケーションにたどり着きます。

このようにして、Istioを使用して通信のルーティングを行うことができます。

おわりに

今回はIstioの基本的な点を説明しながら、実際に動かせるアプリケーションを立てる方法を説明しました。
以前のkubernetesの学習環境の導入方法アプリのコンテナのビルドの方法と合わせることで、アプリケーション開発~kubernetes上でサービスを利用可能にするするまでの一連の作業が順を追って理解できると思うので、Istioだけでなくkubernetes出のアプリの開発、運用の基本的な方法を知りたいという方はこれらの過去記事もご覧ください。

参考

暗号化しろーーー!!!!(もうされてる!)SQL Serverのデータを暗号化して保護するTDEを設定する

f:id:nam_yu_sql:20210203093007j:plain この記事はcloud.config tech blogにもマルチポストしています。

tech-blog.cloud-config.jp

はじめに

こんにちは、相変わらずDP-300受験のためあれこれ調べたり試したりしているなむゆです。
今回もその学習中に見つけたAzure Sql Databaseのセキュリティ系の機能で一席打ちたいと思います。

TDE(透過的なデータ暗号化)とは

TDEとはTransparent Data Encryptionの略で、データベースのデータを暗号化して保護する機能です。
例えば、データベースにINSERT文でデータを挿入するときに、ディスクに書き込みしようとしたタイミングでそのデータを暗号化して保存します。一方で、そのデータを取り出そうとしたときはメモリに読みだされるタイミングで暗号化を解除します。
暗号化と暗号化の解除には暗号化キーと呼ばれるものが必要で、特に自前のサーバーにあるSQL ServerにTDEを設定するときには暗号化キーを作成し、それをSQL Serverの暗号化キーとして設定してやる必要があります。
ちなみに、SQL Databaseでは2017年以降この機能がデフォルトで設定されており、新しくリソースを作る際にTDEを設定するために新しく何かを追加で設定する必要はありません。
f:id:nam_yu_sql:20210203093035p:plain
しかし、例えばもしデータベースの暗号化に自前の鍵を使いたーい!となった場合にはそのような設定を加えることもできます。
次のパートではその方法を見ていきます。

Key Vaultにキーを保存してそのキーを使用してTDEを設定する

こちらに用意しましたのは前回の記事で作成したSQL Databaseです。
こちらには前回の記事で作成したユーザー情報的なデータが格納されています。
f:id:nam_yu_sql:20210203093115p:plain
まずは先にKey Vaultを作成しておきます。
今回は「tdetestnamuyu」あたりの名前でどうでしょうか。
f:id:nam_yu_sql:20210203093128p:plain
それでは、Azure Key Vaultから鍵を取得してTDEを設定するために、まずは SQL Serverのメニューの「Transparent Data Encryption」を開きます。
そして、設定を「顧客が管理するキー」に変更します。
f:id:nam_yu_sql:20210203093140p:plain
するとその下に使用するキーを選択する部分が出てくるので、「キーの変更」をクリックします。
f:id:nam_yu_sql:20210203093151p:plain
ここではキーを保存するKey Vaultを設定します。キーコンテナーのドロップダウンから先程作成したKey Vaultを選択しましょう。
f:id:nam_yu_sql:20210203093200p:plain
するとKey Vaultに保存されている度のキーを使用するか確認されますが今回はまだキーがないので「新規作成」をクリックし、名前を設定して新規作成します。

新規作成したら、作成されたキーのバージョンを設定し、「選択」をクリックして戻ります。
そして最後に、「保存」ボタンをクリックしてTDEの設定を確定すると、それ以降Key Vaultから暗号化キーを取得して暗号化、暗号化解除を行うようになります。
f:id:nam_yu_sql:20210203093208p:plain
と言っても特にそれで何が変わったか実感することはほとんどないですが・・・

ちょっと悪いことしよう

先程の説明で、暗号化キーはデータを挿入するとき、読み出しを行うときに使用されると解説しました。
では、その暗号化キーを削除するといったいどうなってしまうのでしょうか?
試してみましょう。
f:id:nam_yu_sql:20210203093513p:plain
あっあっ大事な鍵がー!
f:id:nam_yu_sql:20210203093523p:plain
ということでさっくり暗号化キーを消し飛ばしました。
さて、TDEの暗号化や複合化で使う暗号化キーを削除すると、SQL Databaseはいったいどうなってしまうのでしょうか(棒)
f:id:nam_yu_sql:20210203093533p:plain
クエリエディタを開いてログインしようとすると、このようなエラーが出ました。
KeyVaultからキーが読み出せなくなったので、SQL Databaseにログインすらできなくなりました。
当然ながらこの状態ではデータの書き込みも読み出しもできません。
f:id:nam_yu_sql:20210203093544p:plain
SQL Databaseの概要画面でも、キーが取得できなくなったことに対する怒りのメッセージが出ています。
f:id:nam_yu_sql:20210203093557p:plain
こうなると、キーをKeyVaultの機能を用いて復元するか別所に用意したKeyVaultに保管しておいた同じキーを再設定しない限りデータは復元できません。
KeyVaultに時前の鍵を用意してそれを用いてTDEを設定する際は、誤ってそのリソースを削除したりキーを削除したりしてしまわないようにリソースにロックをかけたりKeyVaultの設定でキーを論理削除できるようにしておきましょう。
復元の手段は多重に確保しておく必要があります。

おわりに

今回はSQL Database(SQL Serverも)のデータベースの保護機能のであるTDE(透過的なデータ暗号化)について共有しました。
データベースの保護機能としてSQL Databaseにおいてはデフォルトで設定されている部分ですが、要件次第でカスタマイズも可能です。
ただ、その場合はくれぐれも鍵をなくさないように・・・というのがポイントかと思います。
こんな機能もあるのかと心に泊めていただけると幸いです。

参考

隠せーーーー!!!デリケートなデータを隠すSQL Databaseの動的データマスク

f:id:nam_yu_sql:20210131165214j:plain この記事は後でclouf.config tech blogにマルチポストしています。

tech-blog.cloud-config.jp

はじめに

どうも、データベース設計やチューニングタスクが降ってくるのに備えて毎日素振りを欠かさないなむゆです。
最近DP-300の試験を受けようかと考えていて、その学習途中で触って気になったSQL Databaseの機能の「動的データマスク」について一席打ちたいと思います。

動的データマスクとは

動的データマスクとは、特権のないユーザーに対してデリケートなデータをマスクして表示し、データの公開を制限する機能です。
例えば、データベースの電話番号を保存するカラムをSELECT文で取得したとき、普通は全部のデータが表示されますが、この機能によって指定した電話番号のカラムに保存された番号全体を「XXX-XXX-XXXX」と表示したり、あるいは頭3文字だけ表示させたりといったことが可能になります。

使い方の例

まずは適当にSQL Databaseのインスタンスを作ります。
f:id:nam_yu_sql:20210131165319p:plainサーバーファイアウォールの設定」から現在のIPからの接続を許可することを忘れずに!
f:id:nam_yu_sql:20210131165343p:plain テーブルと初期データを挿入していきます。
SQL Databaseのクエリエディターで以下のようなクエリを打ちます。

CREATE TABLE [dbo].[User](  
    [UserId] [uniqueidentifier] NOT NULL,  
    [UserName] [nvarchar](max) NOT NULL,  
    [MailAddress] [nvarchar](max) NOT NULL,  
    [PhoneNumber] [nvarchar](max) NOT NULL,  
 CONSTRAINT [PK_User] PRIMARY KEY CLUSTERED   
(  
    [UserId] ASC  
)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]  
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]  
INSERT [dbo].[User] ([UserId], [UserName], [MailAddress], [PhoneNumber]) VALUES (N'a65571b6-a0d2-4711-a2b2-4dc7127ad901', N'Namuyu', N'namuyu@namuyuno.com', N'012-345-6789')  
INSERT [dbo].[User] ([UserId], [UserName], [MailAddress], [PhoneNumber]) VALUES (N'9fe245ea-a570-41c1-8ebf-9bd95d17c0ed', N'FumiFumi', N'fumifumi@fumii.com', N'098-765-4321')  

上記のクエリでUserテーブルとそこに2つ分のデータが挿入されます。
中でもメールアドレス(MailAddress)と電話番号(PhoneNumber)は機微なデータになります。
これらをいい感じに隠していきます。

Azure Portalの作成したSQL Databaseのメニューから「動的データマスキング」を選びます。
f:id:nam_yu_sql:20210131165356p:plain そうするとSQL Database上にあるマスキングした方がよさそうなカラムが自動でいくつかピックアップされます。マスキングしたいカラムは「マスクを追加」をクリックしてマスキングするルールに追加します。
f:id:nam_yu_sql:20210131165416p:plain 次はマスキングするルールでどのようなマスキングを施すか設定していきます。
設定したいルールをクリックして設定を開きます。
f:id:nam_yu_sql:20210131165425p:plain 例えばMailAddressのカラムには「電子メール」を選択します。選択したら「更新」を押しておきましょう。
f:id:nam_yu_sql:20210131165442p:plain 「電話番号」のカラムではもう少しカスタムしたフィールドを設定してみましょう。
マスクフィールド形式では「カスタム文字列」を選択します。
そうすると下に「公開されたプレフィックス」「文字列のパティング」「公開されたサフィックス」を設定するテキストボックスが出てきます。
この中の、プレフィクスとサフィックスはそれぞれ頭から何文字、最後から何文字は見せる形でマスキングをかけるかを設定します。
そして文字列のパディングはそれ以外の部分をどんな文字列で置き換えてマスキングするかを設定できます。
今回は公開されたプレフィックスは3文字、パディングは公開される3文字以降を全部Xで置き換えた「-XXX-XXXX」、差フィクスは0文字で設定してみましょう。
こちらも設定できたら更新を押して戻ります。
最後にマスクルール全体を「保存」を押して保存して設定完了となります。
f:id:nam_yu_sql:20210131165450p:plain これだけだけどこれだけじゃない!
この動的データマスクはデータベースの管理者には適用されません。データベース管理者(SQL Databaseの作成時に設定するアカウントがそれ)はDB作成初期から存在して最強の権限を持っている神なので少なくともその権限ではデータ全体を確認できるようになっています。
なので、動的データマスクによるマスキングが適用される一般ユーザーを作っておきましょう。
f:id:nam_yu_sql:20210131165458p:plain 再びクエリエディタに戻り、ユーザー作成のクエリ、権限付与のクエリを順に打ちます。
画像を参考にパスワード等はそれぞれ考えて設定してください。
f:id:nam_yu_sql:20210131165506p:plain 設定できたらクエリエディタ左上の「ログイン」から今しがた作成したユーザー情報でログインします。
そして、以下のようなクエリを打ってみましょう。

SELECT * FROM [User]  

すると画像のようにメールアドレスや電話番号がマスクされた結果が出力されるはずです!
f:id:nam_yu_sql:20210131165519p:plain ついでなので元の管理者ユーザーで再度ログインして同じクエリを打ってみましょう。
f:id:nam_yu_sql:20210131165528p:plain 今度は全部のデータが見えてしまいました。見てしまいましたね?

このようにして開発者でもあまり見てほしくないデータについては動的データマスクを施したうえで開発者には動的データマスクが行われる一般ユーザーでDBの操作を行ってもらい、一方でアプリケーションは動的データマスクの影響を受けないユーザーを使わせるような設定ができます。
これにより、アプリケーションでは必要なデータをすべて使うことができ、、開発者がデータベースを覗くときにはそれらのデータは見えないようにすることがでいます。

おわりに

今回はSQL データベースの機能でユーザーがデリケートな情報を見ようとしたときに自動でマスクがかけられる動的データマスクについて紹介しました。
これを使うことで、アプリケーションの機能には影響を与えずに「たとえ開発者といえどもユーザーの個人情報を見てはならない」といった要件にも対応できるようになります。
機微な個人情報を扱う際の要件によって出番が増えそうな気がする機能ですので、「こんなのあるんだ」と心に留めていただけると幸いです。

参考

Windows10 HomeのPCにDocker Desktopを使ってkubernetesを導入する

f:id:nam_yu_sql:20210125212250j:plain この記事はcloud.config tech blogにマルチポストしています。

はじめに

Kubernetes、触ってますか?
普段は業務で触っているKubernetesですが、家でも学習用に環境を整えようとしたところかなり苦労した挙句やっとこさインストール方法を見つけることができました。
身の回りにもkubernetesやDockerのインストールで詰まる人を見かけるので今回はその時の導入手順をメモして共有しておきたいと思います。

Docker Desktopを使ってkubernetesを導入する

大雑把な方法としては、Docker Desktopには機能の一つとしてシングルノードのKubernetesを立てる機能が含まれているので、それを使ってWindows host上にkubernetesクラスターを立てます。
windows host上にkubernetesクラスターを立てる方法として他にminikubeを使う方法などもありますが、それよりシンプルに実行できるので個人的にはおすすめです。

Linux カーネル更新プログラム パッケージをダウンロード

まずはLinux カーネル更新プログラム パッケージをダウンロードします。
Docker Desktopでは仮想化に使用するWSL2を自動でインストールしてくれるのですが、そのために使用するLinix カーネルの更新プログラムを実行しておくする必要があります。
msdnのWSLのインストール方法の手順4にある「x64 マシン用 WSL2 Linux カーネル更新プログラム パッケージ」をダウンロードして実行しておきます。
これでDocker Desktopのインストールの準備は完了です。

Docker Desktopをインストール

DockerHubのサイトからDocker Desktopをダウンロードし、インストールします。
このとき、「Install required Windows components for WSL2」のチェックボックスにチェックを入れておきます。
チェックしたらOkをクリックしてインストールを行います。
f:id:nam_yu_sql:20210125212559p:plain なお、このタイミングでkubectlなどの後々必要になるツールも自動でインストールされます。便利!

kubernetesを有効化

タスクバーのDockerのアイコンを右クリックし、「Dashboard」をクリックします。
Dashboard上部の歯車のアイコンからセッティング画面に移動します。
セッティング画面のメニューからKubernetesを選びます。
f:id:nam_yu_sql:20210125212635p:plain Kubernetesのオプションの中で、「Enable Kubernetes」のチェックボックスをチェックします。
f:id:nam_yu_sql:20210125212648p:plain 「インストールには時間がかかるよ~」というような文言が出るので、「Install」をクリックします。
f:id:nam_yu_sql:20210125212655p:plain しばらく時間が経った後、インストールが完了してdashboard下にDockerのマークとその横にkubernetesのマークが出ていれば完了です。
f:id:nam_yu_sql:20210125212704p:plain このタイミングで、Docker Desktopを利用して立てたkubernetesクラスターに接続するためのkubeconfigの追記等が自動的に行われるようです。
なので、Powershellなどを開いてkubectl config get-contextのコマンドを打つと、現在docker-desktopのコンテキストが存在していてそれを利用していることが確認できます。

CURRENT   NAME             CLUSTER          AUTHINFO         NAMESPACE                                                    
*         docker-desktop   docker-desktop   docker-desktop          

もちろんこの状態からマニフェストファイルを適用するなどして作業を開始することができます。

幸せなkubernetesライフを!

おわりに

今回はWin10 Homeユーザー向けにローカル環境でのシングルノードのkubernetes環境の構築方法を共有しました。
普段使いの家のPCでkubernetesの学習環境を立ち上げたくなった時の方法はいくつもあり、結構複雑に感じる方法もあります。
その中でDocker Desktopを使う方法は個人的にシンプルでわかりやすく、手数も少なく済んだと感じています。
自宅でもkubernetesを触りってみたいという方に役立てば幸いです。

参考

【小ネタ】Kubernetesでアプリへのリクエストに503が返って七転八倒斎したお話

f:id:nam_yu_sql:20210125064953j:plain

この記事はcloud.config tech blogにマルチポストしています。

tech-blog.cloud-config.jp


# はじめに
kubernetes社内最強になりたいなむゆです。
最近Kubernetes上にアプリケーションをデプロイしていて、ルーティング周りでエラーシュートをしました。
その時起きていた問題について色々キーワードで調べても(kubernetes 503 VirtualService とか)あまり問題解決につながる情報が出てこなかったのでメモしておきます。

# 起きたこと
アプリケーションにAPIを追加したのでVirtualServiceにそのAPIへのルーティングを加え、applyしました。
それ以降、kubernetesにデプロイしているserviceの、新たにVirtualServiceに追加したルーティング以外のアプリのAPIのパスに対するリクエストに対して503が返ってくるようになりました。
ログを見ると、APIのPodログには正常にレスポンスが返っているときのログは残っているのですが、503が返ってくるときのログは残っていませんでした。
istio-ingressgatewayのPodのログを確認すると、503のエラーが返った履歴が残っていました。
そのアプリをローカルで実行すると全APIから正常にレスポンスが返りました。
これらのことから、アプリケーションのPodは正常に動作していてistio-ingressgatewayまでリクエストはやってきているもののVirtualServiceに書いてあるルーティングか何かでコケているんじゃないかと考えました。
VirtualServiceのrouteもちゃんと設定してあるしhostの設定もドキュメントにあるとおりに、`{service名}.{namespace}.svc.cluster.local`にしてあるし・・・(そもそも一部APIは正常にルーティングされたので当然といえば当然)
ということで謎にハマりました。

# 原因
別のnamespaceに更新前のVirtualServiceが生きていました。
VirtualServiceの更新時にnamespaceが他と被りそうで怖かったのでそちらも更新していたのですね。
すると、metadataの中身が変わったのでkubernetesとしては「あ、別のオブジェクトなんだな~」と勘違いして、新しいVirtualServiceのオブジェクトを作ってしまっていました。
VirtualServiceは、同じ条件のuriに対してルーティング先が複数あるとエラーを起こして503を返すようです。(一次ソース見つからず。なぜ?)
今回は古いVirtualServiceと新しいVirtualServiceが両方存在してしまっていたためにuriの条件が競合してエラーが起きていたようです。
古い方のVirtualServiceを削除したところ、問題は解決しました。

# 教訓
マニフェストファイルのmetadataを変更したらkubernetes上の元のオブジェクトは消しましょう。  

同じ部分で詰まったほかの人の役に立ちますように・・・

Google版の開発者向けサイト(Beta版)のGoogle Developer Profileっていうのがあるんだって

f:id:nam_yu_sql:20210121081936j:plain この記事はcloud.config tech blogにマルチポストしています。

tech-blog.cloud-config.jp

Google Developer Profileっていうのがあるんだって

最近Google技術のコミュニティの勉強会で教えてもらって知ったのですが、GoogleのサイトでGoogle Developer Profileというものがあるみたいです。
これはGoogle版の開発者向けサイトで、登録することで学習コンテンツの学習状況やコミュニティへの参加状況を保存できるサービスみたいです。
去年の10月ごろにオープンされたようなのですが、今もBeta版で機能は開発中みたいです。
f:id:nam_yu_sql:20210121081937p:plain

使い方

使い方は簡単で、トップページの「Create Developer Profile」から各種情報を記入します。
f:id:nam_yu_sql:20210121082036p:plain あとはGoogle Developer Profileの更新情報のメールを受ける場合はチェックボックスにチェックしてFinishを押して完了です。
f:id:nam_yu_sql:20210121082044p:plain

こんなコンテンツがあるよ

ホーム画面では実績のバッジが確認できます。
ここのバッジは学習コンテンツの学習状況やコミュニティへの参加などの実績でバッジが獲得できるそうです。
登録しただけでも登録したのとベータバージョンに登録したバッジが解放されました。
f:id:nam_yu_sql:20210121082053p:plain Pathwayからは各種学習コンテンツのページに飛ぶことができます。
動画教材や実際にGCP環境でリソースを立てて学習を行うCodelab等を通してGoogle関連の技術を学ぶことができます。
章末問題は結構難易度高めです。
単語を記入する問題なんかもあります。
f:id:nam_yu_sql:20210121082101p:plain その他、TopicsにおいてはDatabaseやFirebaseなどのGoogle技術のトピックごとに資料が集約されています。
例えばぼくらのお気に入りの簡単にWebアプリをホストできちゃうFirebaseだと・・・
f:id:nam_yu_sql:20210121082111p:plain Firebase関連のドキュメント、アップデート、教材(Pathway)、動画などといったコンテンツが1ページにまとめられています。
「Firebaseについていろんなコンテンツを見たい!」という気分の時にはもってこいって感じがします。
f:id:nam_yu_sql:20210121082121p:plain また、他にもGoogleの技術系イベントがまとめられているページなどもあります。イベント内で公開された動画なども見ることができます。
f:id:nam_yu_sql:20210121082145p:plain GDGというGoogleの技術者コミュニティに関する情報のページもあります。
f:id:nam_yu_sql:20210121082200p:plain GDGはGoogle Developers Groupの略で、Googleとは独立したGoogle関連の技術に関する開発者グループです。
こちらで詳しく紹介されています。
一つ一つのグループは「Chapter」と呼ばれ、日本国内にもいくつか存在し、大体「GDG○○」という名前で定期的に勉強会を行っています。
例えば地元の四国の周りだと、「GDGShikoku」というチャプターがあり、AndroidやFirebase、Go言語に関するハンズオンやもくもく会を開いています。
私も過去何度か参加したことがあります
最近は時節柄オンラインでも色々なイベントを開いているようですね。
Google Developer ProfileのGoogle Developer Groupsのページでは、このような技術者グループの情報を閲覧することができます。

おわりに

今回はGoogle Developer ProfileというGoogleの技術者向けサイトがあるんだよ~ってお話でした。
まだまだBeta版ということで、これからも機能が増えていったりするかもしれません。
自分もちょくちょく覗いていこうと思います。