Hejdaの見る夢

一人前のエンジニアを目指して頑張ったこととかをつらつら書くブログ

spot node pool to an Azure Kubernetes Service を試したみた!! 🚀

AKS クラスターに新しい機能が追加されたようなので、試してみました!!

公式ドキュメント

Add a spot node pool to an Azure Kubernetes Service (AKS) cluster

情報元

結論

AKS に spot node pool が使えるようになり、これが AKS の運用においてコスト削減に繋がるとのことです。

spot node pool というのは、Spot VMs[1] を用いた virtual machine scale set (vmss) [2] であり、コスト削減というのはこの Spot VMs を使うからです。

⚠ 注意事項

  • 2020/02/29 の時点では今回取り上げる Spot VMs 等はプレビュー段階のため、GA時にはコマンドや実行状況などは変わる可能性があります。
  • プレビュー版故に SLA は無いので、開発環境であっても自己責任で使用して下さい。
  • SpotVM の制約として、vmss は single fault domain[3] のみで可能なため、HA 構成を設定することが出来ません[4]
  • Azure 側にて、リソースが必要になった場合は、SpotVM は優先的にリソースを奪われるようです。

実際に構築してみる

手順は 2 個です。

順番にやっていきましょう!! 🙌

サブスクリプションの作成とプレビュー機能の有効化

spotpoolpreview preview 機能を使えるようにする

f:id:nari_kyu:20200229230833p:plain

f:id:nari_kyu:20200229230846p:plain

  • 今回の検証用に作成し、iganar-aks-test-20200229 とリネームしたものを使っていきます。
az account list --output table
# az account list --output table
Name                        CloudName    SubscriptionId             State    IsDefault
--------------------------  -----------  -------------------------  -------  -----------
iganari-hogehoge            AzureCloud   zzzzzzzzzzzzzzzzzzzzzzzzz  Enabled  True
iganari-hugahuga            AzureCloud   yyyyyyyyyyyyyyyyyyyyyyyyy  Enabled  False
iganar-aks-test-20200229    AzureCloud   xxxxxxxxxxxxxxxxxxxxxxxxx  Enabled  False
  • Default にセットしていない場合は az account set コマンドを使います。
az account set --subscription ${SubscriptionId}
# az account list --output table
Name                        CloudName    SubscriptionId             State    IsDefault
--------------------------  -----------  -------------------------  -------  -----------
iganari-hogehoge            AzureCloud   zzzzzzzzzzzzzzzzzzzzzzzzz  Enabled  False
iganari-hugahuga            AzureCloud   yyyyyyyyyyyyyyyyyyyyyyyyy  Enabled  False
iganari-aks-test-20200229   AzureCloud   xxxxxxxxxxxxxxxxxxxxxxxxx  Enabled  True
  • spotpoolpreview preview を登録します。

今回の spot node pool を用いた AKS を構築するには、spotpoolpreview 機能を Subscription の中で有効にする必要があるので下記のコマンドを実行しましょう。

az feature register --namespace "Microsoft.ContainerService" --name "spotpoolpreview"
### ex

# az feature register --namespace "Microsoft.ContainerService" --name "spotpoolpreview"
Once the feature 'spotpoolpreview' is registered, invoking 'az provider register -n Microsoft.ContainerService' is required to get the change propagated
{
  "id": "/subscriptions/xxxxxxxxxxxxxxxxxxxxxxxxx/providers/Microsoft.Features/providers/Microsoft.ContainerService/features/spotpoolpreview",
  "name": "Microsoft.ContainerService/spotpoolpreview",
  "properties": {
    "state": "Registering"
  },
  "type": "Microsoft.Features/providers/features"
}
  • 有効化には数分かかりますので、実行中のステータスに関しては以下のコマンドで確認出来ます。
az feature list -o table --query "[?contains(name, 'Microsoft.ContainerService/spotpoolpreview')].{Name:name,State:properties.state}"
### ex

### 実行前は何も表示されない
# az feature list -o table --query "[?contains(name, 'Microsoft.ContainerService/spotpoolpreview')].{Name:name,State:properties.state}

### 実行直後
# az feature list -o table --query "[?contains(name, 'Microsoft.ContainerService/spotpoolpreview')].{Name:name,State:properties.state}"
Name                                        State
------------------------------------------  -----------
Microsoft.ContainerService/spotpoolpreview  Registering

### 有効化完了
# az feature list -o table --query "[?contains(name, 'Microsoft.ContainerService/spotpoolpreview')].{Name:name,State:p
roperties.state}"
Name                                        State
------------------------------------------  ----------
Microsoft.ContainerService/spotpoolpreview  Registered
  • 上記のコマンドの State が Registered になったら、下記のコマンドで登録情報を更新します。
    • az provider register コマンドを使用して、Microsoft.ContainerServiceリソースプロバイダーの登録を更新しています。
az provider register --namespace Microsoft.ContainerService

---> ここまでの作業で spotpoolpreview preview 機能を使えるようになりました!! 🚀

Install aks-preview CLI extension

spot node pool を用いた AKS クラスタCLI から作成する場合、aks-preview CLI extension の version 0.4.32 以降が必要になります。

az extension add コマンドを使用して、aks-preview Azure CLI extension をインストールし、az extension update コマンドを使用して更新を確認しましょう。

az extension add --name aks-preview
az extension update --name aks-preview

---> ここで AKS を作る準備が出来ました!! 🚀

Add a spot node pool to an AKS cluster

複数のノードプールが有効になっている AKS クラスタを作成する

まずはいつも通りの AKS クラスタを作成します。

  • リソースグループの作成をします。
az group create --name my-Resource-Group --location eastus
  • AKS クラスタの作成をします。
    • オプションや K8s のバージョンはあくまでデモ用です。
az aks create \
    --resource-group my-Resource-Group \
    --name iganariAKSCluster \
    --vm-set-type VirtualMachineScaleSets \
    --node-count 2 \
    --generate-ssh-keys \
    --kubernetes-version 1.15.7 \
    --load-balancer-sku standard
  • 比較のために node pool を追加しておきましょう。
az aks nodepool add \
    --resource-group my-Resource-Group \
    --cluster-name iganariAKSCluster \
    --name nodepoolno \
    --node-count 3 \
    --kubernetes-version 1.15.5 \
    --no-wait

spot node pool を追加します。

  • 下記のコマンドにて追加することが出来ます。
    • --priority Spot 及び、 --enable-cluster-autoscaler のオプションが付いていることが分かります。
az aks nodepool add \
    --resource-group my-Resource-Group \
    --cluster-name iganariAKSCluster \
    --name nodepoolspot \
    --priority Spot \
    --eviction-policy Delete \
    --spot-max-price -1 \
    --enable-cluster-autoscaler \
    --min-count 1 \
    --max-count 3 \
    --no-wait

AKS の状態を確認しましょう。

  • CLI にて確認していきましょう。
# az aks nodepool list --resource-group my-Resource-Group --cluster-name iganariAKSCluster -o table
The behavior of this command has been altered by the following extension: aks-preview
Name          OsType    VmSize           Count    MaxPods    ProvisioningState
------------  --------  ---------------  -------  ---------  -------------------
nodepool1     Linux     Standard_DS2_v2  2        110        Succeeded
nodepoolno    Linux     Standard_DS2_v2  3        110        Succeeded
nodepoolspot  Linux     Standard_DS2_v2  3        110        Succeeded
  • ポータルからも確認してみましょう。

f:id:nari_kyu:20200229231711p:plain

---> これで spot node pool を用いた AKS の構築自体は完了です!! 🚀

サンプルプログラムを配置してみる

実際に動くサンプルアプリケーションを用いて挙動を確認してみましょう。

サンプルアプリケーションは公式のものを使用します。

  • まずは AKS との認証を行います。
az aks get-credentials --resource-group my-Resource-Group --name iganariAKSCluster

Azure の公式ドキュメントに載っているサンプルの YAML をすこし改良してみます。

kind: Namespace
apiVersion: v1
metadata:
  name: sample-vote
  labels:
    name: sample-vote

---

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: azure-vote-back
  namespace: sample-vote
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: azure-vote-back
    spec:
      nodeSelector:
        "beta.kubernetes.io/os": linux
      containers:
      - name: azure-vote-back
        image: redis
        ports:
        - containerPort: 6379
          name: redis
      tolerations:
      - key: "kubernetes.azure.com/scalesetpriority"
        operator: "Equal"
        value: "spot"
        effect: "NoSchedule"

---

apiVersion: v1
kind: Service
metadata:
  name: azure-vote-back
  namespace: sample-vote
spec:
  ports:
  - port: 6379
  selector:
    app: azure-vote-back

---

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: azure-vote-front
  namespace: sample-vote
spec:
  replicas: 1
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  minReadySeconds: 5 
  template:
    metadata:
      labels:
        app: azure-vote-front
    spec:
      nodeSelector:
        "beta.kubernetes.io/os": linux
      containers:
      - name: azure-vote-front
        image: microsoft/azure-vote-front:v1
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: 250m
          limits:
            cpu: 500m
        env:
        - name: REDIS
          value: "azure-vote-back"
      tolerations:
      - key: "kubernetes.azure.com/scalesetpriority"
        operator: "Equal"
        value: "spot"
        effect: "NoSchedule"
---

apiVersion: v1
kind: Service
metadata:
  name: azure-vote-front
  namespace: sample-vote
spec:
  type: LoadBalancer
  ports:
  - port: 80
  selector:
    app: azure-vote-front
  • kubectl コマンドを持ちいて、デプロイしましょう。
kubectl create -f sample.yaml
  • デプロイ後に Pod を確認してみましょう。
    • spot node pool 上に Pod が作成出来たのが確認出来ます。
kubectl get po --namespace=sample-vote -o wide
# kubectl get po --namespace=sample-vote -o wide
NAME                                READY   STATUS    RESTARTS   AGE     IP           NODE                                   NOMINATED NODE   READINESS GATES
azure-vote-back-79ccd5b979-qh4bw    1/1     Running   0          8m14s   10.244.7.2   aks-nodepoolspot-20405705-vmss000000   <none>           <none>
azure-vote-front-559d85d4f7-898wz   1/1     Running   0          105s    10.244.4.2   aks-nodepoolno-20405705-vmss000000     <none>           <none>
  • 外部 IP アドレスの確認をします。
# kubectl get service --namespace=sample-vote
NAME               TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)        AGE
azure-vote-back    ClusterIP      10.0.236.31    <none>         6379/TCP       8m19s
azure-vote-front   LoadBalancer   10.0.113.113   40.71.235.54   80:32604/TCP   8m17s

f:id:nari_kyu:20200229232827p:plain

---> ちゃんと起動して、かつ動くことを確認出来ました!! 🚀

削除コマンド

検証が完了した後にはリソースの解放をしておきましょう。

kubectl delete -f sample.yaml
for i in nodepoolno nodepoolspot ;
  do \
    az aks nodepool delete \
      --resource-group my-Resource-Group \
      --cluster-name iganariAKSCluster \
      --name $i ;
  done
az aks delete \
    --resource-group my-Resource-Group \
    --name iganariAKSCluster
az group delete \
    --name my-Resource-Group

---> これでリソースの解放も完了です!! 💪

まとめ

AKS の新しい機能である、spot node pool を使った AKS を構築し、その上に Pod を配置して、ブラウザでアプリケーションの動作確認を取るところまで確認出来ました。

ほぼ、CLI からの操作で簡単に行えるので操作感的には問題ないかと思います。

また、マニュフェストファイルへの追加事項も多くないので、一度書いてしまえばそこまで苦ではありません。

一点、疑問が残るのですが、Spot VMs を使っていること自体を確認するパラメータが今の所見つからないので、名前等で判別出来るようにしておかないといけないのか??と思っています 🤔

さすがにそれは無いと思いますが…

また spot node pool 及び、Spot VMs を使うに当たっていくつかの制約があるので、この機能を使う前に併せて読んでおいたほうが良さそうです。[5]

というとこで、今回の検証は終わりになります。

引き続き、AKS の進化を楽しんでいきましょう!!

Have fun !! :)

参考

Azure の deallocate をちゃんと調べる part.1

発端

先日、第27回 SQL Server 2019勉強会(オンライン) に参加した際に deallocate という機能があり、これが開発環境の Azure Kubernetes Service (AKS) においてコスト削減に繋がるとの情報を頂きました。

ただこのツイートは情報を正確に表現出来ていなく、誤認識を生んでしまう可能性があるのでちゃんと調べることにしました。

  • 第27回 SQL Server 2019勉強会(オンライン)

sqlserver.connpass.com

  • 問題の自分のツイート

結論

個人的な見解

Azure における Deallocate 機能 は、virtual machine (及び、virtual machine scale sets (vmss)) の機能であり、AKS ひいて は Kubernetes (K8s) の機能ではありません。

メリット・デメリットをしっかり把握した上で、自己責任で使用してください。

何故か

AKS の cluster autoscaler は vmss で用いて実現しています。

cluster autoscaler は K8s の機能であり、vmss は Azure の機能です。

マネージド K8s である AKS が cluster autoscaler を実現するために、node pools のリソースを確保する際に vmss の機能を用いて実行しているようです。

注意点

Deallocate は virtual machine (vm) をシャットダウンし、かつリソースを解放する機能です。そのため deallocate 中の vm の維持に掛かる課金は停止します。

しかし、ディスクや 静的 IP アドレスなどのリソースは引き続き課金が継続されるため、完全に課金が発生しなくなるわけではありません。

AKS から cluster autoscaler を使用する場合は --enable-cluster-autoscaler を使用します。

### refs: https://docs.microsoft.com/en-us/azure/aks/cluster-autoscaler#create-an-aks-cluster-and-enable-the-cluster-autoscaler

# First create a resource group
az group create --name myResourceGroup --location eastus

# Now create the AKS cluster and enable the cluster autoscaler
az aks create \
  --resource-group myResourceGroup \
  --name myAKSCluster \
  --node-count 1 \
  --vm-set-type VirtualMachineScaleSets \
  --load-balancer-sku standard \
  --enable-cluster-autoscaler \
  --min-count 1 \
  --max-count 3

この設定をした際は、vmss 自体を操作することは出来なくなり、 az aks コマンド経由で操作を行うようになるようです。

これは誤操作を防ぐためにも必要な処置のように思います。

# Note

Manual scaling is disabled when you use the cluster autoscaler. 
Let the cluster autoscaler determine the required number of nodes. 
If you want to manually scale your cluster, disable the cluster autoscaler.

しかし、cluster autoscaler の設定せずに AKS を構築すると、vmss の deallocate 機能を使えてしまえるかのようにドキュメントからは読めます。

次回はそこを検証してみようと思います。

参考ドキュメント

  • Virtual Machines - Deallocate

  • Automatically scale a cluster to meet application demands on Azure Kubernetes Service (AKS)

  • What are virtual machine scale sets?

まとめ

というわけで、この回は切りが良いのでここまで。

検証は次回に続きます :)

macOS から Raspberry Pi に画面共有したい

結論

Raspberry Pi 側 (LAN 内の IP アドレス = 192.168.202.118)

  • VNC について確認しましょう。
$ sudo systemctl list-unit-files | grep vnc
vncserver-virtuald.service             disabled
vncserver-x11-serviced.service         disabled


---> vncserver-x11-serviced があることが確認出来ました。
sudo systemctl start vncserver-x11-serviced.service
sudo systemctl enable vncserver-x11-serviced.service
  • 確認をします。
$ sudo systemctl status vncserver-x11-serviced.service
● vncserver-x11-serviced.service - VNC Server in Service Mode daemon
   Loaded: loaded (/usr/lib/systemd/system/vncserver-x11-serviced.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2020-02-18 19:30:26 JST; 1h 49min ago
 Main PID: 2493 (vncserver-x11-s)
    Tasks: 6 (limit: 2200)
   Memory: 27.5M
   CGroup: /system.slice/vncserver-x11-serviced.service
           ├─2493 /usr/bin/vncserver-x11-serviced -fg
           ├─2497 /usr/bin/vncserver-x11-core -service
           ├─2506 /usr/bin/vncagent service 13
           ├─2510 /usr/bin/vncserverui service 17
           └─2518 /usr/bin/vncserverui -statusicon 5

Raspberry Pi 側 の設定は以上です。

macOS

  • RealVNC for macOS をダウンロードし、インストールします。

https://www.realvnc.com/en/connect/download/viewer/

f:id:nari_kyu:20200222110503p:plain

f:id:nari_kyu:20200222110517p:plain

  • Applications にコピーしましょう。

f:id:nari_kyu:20200222110533p:plain

  • その後、Launchpad から VNC Viewer を起動し、Raspberry Pi の IP アドレス (= 192.168.202.118) を入れ、Enter を押します。

f:id:nari_kyu:20200222110549p:plain

  • 初回は下記のような確認画面が出ますので、確認して続けましょう。

f:id:nari_kyu:20200222110603p:plain

  • Raspberry Pi にログイン出来るユーザ名とパスワードをいれます。
    • この時、VNC 用のユーザの新規作成は必要ありません。

f:id:nari_kyu:20200222110618p:plain

  • 無事、VNC クライアントを用いて macOS から Raspberry Pi にアクセスすることが出来るようになりました。

f:id:nari_kyu:20200222110633p:plain

まとめ

Raspberry Pi 上の OS に対して、VNC する機会はあまり無いかと思いますが、いざ必要という際に設定するのはめんどうなので備忘として残しておきます :)

nodered-dockercompose を Node-RED v1.0.3 対応させました

nodered-dockercompose ってそもそも何 ??

  • 自前の Repository です。
    • Docker Compose を用いて、 Node-RED (後述) をマシン上に構築することが出来ます。

github.com

  • 今回は、Node-RED の v1 がリリースしたので、上記の Repository もアップデートしました。
    • (正確には v1.0.3 にアップデートしました。)

Node-RED とは??

公式サイト

nodered.org

どんなものか

  • 公式ドキュメントから抜粋します。
https://nodered.org/about/


Node-RED is a flow-based programming tool, originally developed by IBM’s Emerging Technology Services team and now a part of the JS Foundation.
===============================
Node-RED はフローベースドプログラミング (flow-based programming) ツールであり、元は IBM Emerging Technology Services チームによって開発され、JS Foundation 配下のプロジェクトを経て、2019 年 3 月よ りNode.js Foundation と JS Foundation が合併して設立された OpenJS Foundation にホストされています。

コミュニティなど

  • Node-RED日本ユーザ会

nodered.jp

  • Connpass

node-red.connpass.com

その他特徴

nodered-dockercompose を使った Node-RED の使用方法

  • clone します。
cd ${Your WorkDirectory}
git https://github.com/iganari/nodered-dockercompose.git
cd nodered-dockercompose
  • docker-compose コマンドで起動します。
docker-compose up -d
  • 状態の確認コマンド
docker-compose ps
### 例

$ docker-compose ps
         Name                      Command                      State                   Ports
------------------------------------------------------------------------------------------------------
nodered-docker-compose   npm start -- --userDir /data   Up (health: starting)   0.0.0.0:1880->1880/tcp

f:id:nari_kyu:20200207084133p:plain

  • 停止も docker-compose コマンドで行います。
docker-compose stop

今回のアップデートで修正した点などなど

  • 自分で Dockerfile の中でいろいろインストールしていたところを、公式の Repository をものを使用することにしました。
    • メンテナンス性を考慮したため。
  • docker-compose.yml の書き方も公式の Repository に沿って修正しました。

まとめ

Node-RED 自体の構築はシンプルなのでこれくらいで。

あとは、「Node-RED を用いて、何を実現するか!?」 がポイントになります。

とりあえず、LINE BotTwitter に繋げて遊んでみたいと思います!!

Have fun! :)