#はじめに
Azure Kubernetes Service(AKS)が2018年6月26日付けで日本リージョンで利用可能になりました。
まずはお試しとして、WordPressのDocker ContainerをAKS上で動かしました。
データベースであるMySQLはAzureのDatabase as a Service(DaaS)であるAzure Database for MySQLを利用します。
「別にApp ServicesとAzure Database for MySQLでいいじゃん」というツッコミもあるかと存じますが、そういう方はこちらの記事を参考にしてください。
App ServiceとAzure Database for MySQLで簡単Wordpressサイト構築
#構成の説明
##AKS
- Docker Hubで提供されている「wordpress」コンテナをそのまま利用。
- wordpressコンテナを動かすPodは1つ。
- 外部ロードバランサを作成して(今回はとりあえず) http(TCP/80)によるアクセスを可能にする
- 永続化領域(/var/www/html)はAKSが提供しているストレージクラスを利用
- Azure Database for MySQLに繋げられるようにExternalNameも作成する
##Azure Database for MySQL
- AKSからの接続にはサービスエンドポイント(Preview)を使って内部経路でアクセスする
- 内部経路でアクセスするため、とりあえず今回はSSL接続は強制せずにTCP/3306でWordPressから繋げる
#AzureでKubernetesを利用する際のポイント
特にAKSを活用する上で、Azureに特化した構築ポイントとしては以下のものが挙げられます。
##ストレージ
AKSにはデフォルトで以下のストレージクラスが定義されており、簡単にAzure Managed Diskが利用可能です。
ストレージクラス名 | Managed Diskの種類 |
---|---|
default | Standard Storage |
managed-premium | Premium Storage |
参考 : Azure ディスクを含む永続ボリューム
##パブリックIPアドレス
AKSの各種リソースがAzure上に実際にデプロイされているリソースグループ(MC_<Resource Group Name><AKS Name><Region>)配下にパブリックIPアドレスのリソースを作成するだけで、AKSのロードバランサから利用可能になります。
参考 : Azure Kubernetes Service (AKS) ロード バランサーで静的 IP アドレスを使用する
##Azure Database for MySQLへはプライベート接続
まだプレビュー段階ですが、サービスエンドポイントの機能を使って、AKSの仮想ネットワークからのみアクセスできるように接続を制限します。
参考 : Azure portal を使用して、Azure Database for MySQL VNet のサービス エンドポイントと VNet ルールを作成および管理する
MySQLでサービスエンドポイントを利用する時は、汎用サーバーとメモリ最適化サーバーでのみサポートされるため、Azure利用料としては泣けてきますw
#AKSのデプロイ
それでは早速構築していきましょう。
Azureポータルにサインイン後、Marketplaceから「kubernetes Service」を探して作成します。
今回は「基本」タブで必要な情報だけ設定して、後の項目はデフォルトのままで作成します。
ノード数はデフォルトの「3」のままだとAzureの課金が心配なので、今回は検証目的であるため「1」に変更しました。
他の必須項目はご自身の環境に併せて適宜入力します。
(ここではAzureポータルの詳細な操作説明は除きます)
#Azure Database for MySQLのデプロイ
Azureポータルにサインイン後、Marketplaceから「Azure Database for MySQL」を探して作成します。
設定項目の注意点としては価格レベルはデフォルトのまま、「汎用目的」を選んでおきます。こちらを「Basic」にするとサービスエンドポイントが利用できません。
(ここではAzureポータルの詳細な操作説明は除きます)
作成されたMySQLの「サーバー名」「サーバー管理者ログイン名」と作成時に指定したパスワードは後からAKSのyamlファイル編集時に使用するため、メモしておきます。
続いてサービスエンドポイントを有効にするため、AzureポータルからAKSの各種リソースが実際にAzure上にデプロイされているリソースグループ(MC_<Resource Group Name><AKS Name><Region>)配下にある「aks-vnet-」から始まる仮想ネットワークを選択します。
「サービスエンドポイント」のメニューから「+追加」をクリックして、「サービスエンドポイントの追加」画面でサービスに「Microsoft.Sql」を選択、サブネットに「aks-subnet」を選択後「追加」をクリックします。
続いてMySQLのリソース画面に戻り「接続のセキュリティ」メニューから「+既存の仮想ネットワークを追加」をクリック。
「名前」欄は適当に、サブスクリプション、仮想ネットワーク、サブネット名は実際にAKSのリソースがデプロイされている仮想ネットワークの「aks-subnet」の情報を設定して、最後に「OK」をクリックします。
今回の検証ではWordPressからMySQLへのアクセスはプライベートネットワークを使用するため、暗号化は行わずに接続します。
「SSL設定」の「SSL接続を強制する」を「無効」に変更後、「保存」をクリックしてMySQLの準備は完了です。
#Public IP Addressの作成
AzureポータルからAKSの各種リソースが実際にAzure上にデプロイされているリソースグループ(MC_<Resource Group Name><AKS Name><Region>)配下にPulic IP Addressを作成します。
リソース名(名前)は適当に。IPアドレスの割り当ては一応「静的」にします。
後からWordPressへのアクセスも楽になるようにDNS名ラベルも付けておきます。
Public IP Addressの作成が完了したらリソースの概要を確認して「IPアドレス」の値をメモしておきます。
#AKSのデプロイ準備
Kubernetesを制御するのには基本「kubectl」コマンドを使用します。
クライアントPC上にインストールするのは追加手順として多いため、今回はAzureポータルから起動できるCloud Shellを利用します。
Cloud Shell(bash)のコンソールが開いたら、以下のコマンドを入力することでkubectlが実行できるようになります。
$ az aks get-credentials --resource-group <Resource Group Name> --name <AKS Name>
Merged "<AKS Name>" as current context in /home/yoshimasa_katakura/.kube/config
#AKS上各種サービスのデプロイ
##シークレットの作成
最初にMySQLのデプロイ時に指定した管理者パスワードをKubernetesのシークレットで作成します。
これによって、yamlファイル上にパスワードを直に記述しないですみます。
$ kubectl apply secret generic wp-secrets --from-literal=WORDPRESS_DB_PASSWORD=<PASSWORD>
##MySQLのExternalName作成
MySQLのエンドポイント名も環境依存になるため、WordPress本体のyamlファイルに記載はせずに、ExternalNameとして最初に作成します。
以下のyamlファイルを準備します。
externalNameには先に作成したMySQLのサーバー名を設定します。
apiVersion: v1
kind: Service
metadata:
name: azure-mysql
spec:
type: ExternalName
externalName: XXX.mysql.database.azure.com (ここは適宜変更)
以下のコマンドで作成します。
$ kubectl apply -f mysql-service.yaml
##WordPressに渡す環境変数の作成(ConfigMap)
上でシークレットで作成したWORDPRESS_DB_PASSWORDの他に、WordPress Containerにわたす必要がある環境変数を準備します。このような環境依存の値は別のyamlファイルにしておいたほうが後々のメンテ性も高くなります。
WORDPRESS_DB_USERには先に作成したMySQLのサーバー管理者ログイン名を指定します。
apiVersion: v1
kind: ConfigMap
metadata:
name: wp-configmap
data:
WORDPRESS_DB_NAME: wordpress
WORDPRESS_DB_USER: dbadmin@aks-mysql (ここは適宜変更)
WORDPRESS_DB_HOST: azure-mysql:3306
以下のコマンドで作成します。
$ kubectl apply -f wp-configmap.yaml
##永続化ストレージの作成
今回利用する永続化ストレージはAzureのStandard Diskを使用するため、storage-classには「default」を指定します。
サイズはとりあえず5Giを確保しましたが、適宜変更してください。
/var/www/html配下にマウントされるため、本格的にWordPressを利用してメディアファイルもたくさんアップロードする際にはもっと大きくする必要があるでしょう。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: wp-azure-disk
annotations:
volume.beta.kubernetes.io/storage-class: default
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
以下のコマンドで作成します。
$ kubectl apply -f wp-storage.yaml
#External Load Balancerの作成
WordPressにインターネット側からアクセス可能にするため、外部ロードバランサーを作成します。
先に作成したAzure上のPublic IPアドレスのIPアドレスと同じ値をyamlファイル内に設定します。
apiVersion: v1
kind: Service
metadata:
name: wp-external-lb
spec:
loadBalancerIP: XX.XX.XX.XX (ここは適宜変更)
type: LoadBalancer
ports:
- port: 80
selector:
app: wordpress
以下のコマンドで作成します。
$ kubectl apply -f wp-lb.yaml
余談ですがこのコマンドを実行すると、Azure上のロードバランサーリソース「kubernetes」の構成が変更となり、Kubernetesのノードへ指定したパブリックIPアドレスからロードバランスされる設定が追加されます。
##WordPressの作成
以下が作成完了したら、後は最後にWordPressのDeploymentを作成します。
- シークレット(Secrets)「wp-secrets」
- 環境変数(ConfigMap)「wp-configmap」
- 永続化ストレージ(PersistentVolumeClaim)「wp-azure-disk」
- MySqlのExternalName「mysql-service」
- ロードバランサー(LoadBalancer)「wp-external-lb」
このyamlファイル内には環境に依存した記述が一切ありませんね。
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
labels:
app: wordpress
spec:
replicas: 1
selector:
matchLabels:
app: wordpress
template:
metadata:
labels:
app: wordpress
spec:
containers:
- name: wordpress
image: wordpress
envFrom:
- configMapRef:
name: wp-configmap
- secretRef:
name: wp-secrets
ports:
- containerPort: 80
name: wordpress
volumeMounts:
- name: wp-azure-disk
mountPath: /var/www/html
volumes:
- name: wp-azure-disk
persistentVolumeClaim:
claimName: wp-azure-disk
以下のコマンドで作成します。
$ kubectl apply -f wp-service.yaml
#動作確認
##AKS上のデプロイ状態確認
もっと前のタイミングでも良いのですが、AKS上に作成した各種ワークロードの確認をします。
# シークレットの状態確認
$ kubectl get secrets
NAME TYPE DATA AGE
azure-storage-account-ktkraksst01-secret Opaque 2 4d
default-token-bjsjg kubernetes.io/service-account-token 3 8d
wp-secrets Opaque 1 2h
# 環境変数の状態確認
$ kubectl get configmap
NAME DATA AGE
wp-configmap 3 11h
# 永続化ストレージの状態確認
$ kubectl get persistentVolumeClaim
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
wp-azure-disk Bound pvc-e4f26c86-8c02-11e8-b0bf-da69366a1397 5Gi RWO default 1d
# ExternalNameとLoadbalancer(両方共service)の状態確認
$ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
azure-mysql ExternalName <none> aks-mysql.mysql.database.azure.com <none> 1d
kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 8d
wp-external-lb LoadBalancer 10.0.145.26 XX.XX.XX.XX 80:31367/TCP 25m
# WordPressのPodの状態確認
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
wordpress-5fbc6d9cc8-mhd8h 1/1 Running 0 2h
WordPressのPodの詳細情報を表示するには以下のコマンドを入力します。
$ kubectl describe pod wordpress-5fbc6d9cc8-mhd8h
Name: wordpress-5fbc6d9cc8-mhd8h
Namespace: default
Node: aks-agentpool-10122857-1/10.240.0.4
Start Time: Sun, 22 Jul 2018 10:15:26 +0900
Labels: app=wordpress
pod-template-hash=1967285774
Annotations: <none>
Status: Running
IP: XX.XX.XX.XX
Controlled By: ReplicaSet/wordpress-5fbc6d9cc8
Containers:
wordpress:
Container ID: docker://2e39cffc356eba2b9e634d143dd2887df7d2da4255b10835876732b0bd45d30a
Image: wordpress
Image ID: docker-pullable://wordpress@sha256:1958b7258b1e1b09bbec1c6269e2e150bcc85c18383aa2420d95cb95a30d107f
Port: 80/TCP
Host Port: 0/TCP
State: Running
Started: Sun, 22 Jul 2018 10:16:10 +0900
Ready: True
Restart Count: 0
Environment Variables from:
wp-configmap ConfigMap Optional: false
wp-secrets Secret Optional: false
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-bjsjg (ro)
/var/www/html from wp-azure-disk (rw)
Conditions:
Type Status
Initialized True
Ready True
PodScheduled True
Volumes:
wp-azure-disk:
Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
ClaimName: wp-azure-disk
ReadOnly: false
default-token-bjsjg:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-bjsjg
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events: <none>
ConditionsのReadyが「True」になっているので準備完了です。
##実際にWordPressサイトに接続
前に作成したPublic IP Adoressを直接ブラウザで入力するか、DNS名で指定したFQDN「XXX.japanease.cloudapp.azure.com」を入力してWordPressサイトに接続します。
「ようこそ」画面ではWordPressの管理者情報、サイト名などを入力して先に進みます。
これらの詳細な設定内容は本記事では割愛します。
トップページもちゃんと表示されました。後はお好きなようにWordPressのカスタマイズを行ってくださいね!
#おわりに
今回の記事ではKubernetesそのもののベストプラクティスについての話ではなく、Azure Kubernetes Service(AKS)の概要を中心に記載しました。
Azure Kubernetes Serviceを利用していく上でAzureの関連サービスをうまく連携して活用していく上で参考になればと思います。
最後に今回利用したyamlファイル一式をGitHubに上げておきましたのでご利用くださいね。