おうちで Kubernetes ~ 論理編1 ~

こんにちは miho です。

さて、前回組み立てた Rasberry Pi に中身(OS)を入れていきたいと思います。
私の環境は Windows ですので、Mac をお使いの方は参考に程度にとどめておいてください。

手順はすべてここにあります。

www.raspberrypi.org

インストールに必要なものは以下になります。

  • 物理キーボード
  • 物理マウス
  • HDMIケーブル (mini)
  • ディスプレイ

Rasberry Pi の OS のダウンロード

OS をダウンロードしていきます。ダウンロード先はこちらになります。

www.raspberrypi.org

なお、この時点でインストールしたバージョンは以下の通り。

Release date: May 7th 2021  
Kernel version: 5.10

ウッカリ忘れていたのですが、SD カードリーダーをしばらく使った記憶がなく、どこにあるのかしばらく探すことになりました。
そうですね、大事です。

ダウンロードした OS は balena を使って SD カードにインストールしていきます。

www.balena.io

You’ll see a progress bar. Once complete, the utility will automatically unmount the SD card so it’s safe to remove it from your computer.

とのことなので、無事に完了するまでそっと見守ることにしました。

f:id:kurimotti:20210906210754p:plain 左がイメージ、真ん中が SD カードです。[Flash] ボタンで開始します。 f:id:kurimotti:20210906210807p:plain その後 OS 側の設定を行っていきます。3 台あるので、同じことを 3 回やっていくことになります。ここに意外と時間がかかります。

完了したら、キーボードとマウスデスクトップを Rasberry Pi へ接続します。

OS Setting

Desktop をインストールしたので、まずはwifi の設定後画面から設定しました。

各種アップデートをかけていきます。

apt update

OS を 64bit モードで起動します。

echo "arm_64bit=1" >> /boot/config.txt

Wifi の Statip IP を設定します。3台あるのでそれぞれ異なる IP を設定します。私は分かりやすいように Master Node を起点に割り振りました。

以下は worker Node1 の設定です。

# /etc/dhcpcd.conf

interface wlan0
static ip_address=192.168.1.28/24
static routers=192.168.1.1
static domain_name_servers=8.8.8.8

SSH での接続ができるように設定します。

systemctl enable ssh

その後、一旦リブートし SSH ができることを確認します。

残りやることは細々した設定です。

  • Hostane
  • 言語設定
  • 時刻同期の確認
  • /etc/hosts の設定。ローカル PC の hosts にも 3台の IP を登録する

最後に自分の PC から ssh ができることが確認できれば作業は完了です。

ssh pi@kube-worker-1
pi@kube-worker-1's password: 
Linux kube-worker-1 5.10.52-v8+ #1441 SMP PREEMPT Tue Aug 3 18:14:03 BST 2021 aarch64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sun Sep  5 15:25:41 2021 from 192.168.1.3
pi@kube-worker-1:~ $ 

無事に接続を確認できました。

おわりに

「おうちで Kubernetes」と大した題名をつけましたが、まだこの時点で構築まで進めていません。事前準備の大変なことよ。(= 楽しい)

割とここの設定に時間を割いていました。なぜかというと、OS の設定って LAN ケーブルにつないで、、、アップデートかけて、、、と地道な作業が多いんですよね。
Rasberry Pi で設定漏れがあると、またケーブルを繋ぎ直して、マウスも〜みたいなことになるので、机の上がこんな惨状になります。

f:id:kurimotti:20210906210820j:plain

では次はようやく Kuberenetes を導入していきます。

おうちで Kubernetes ~ 物理編 ~

こんにちは、miho です。

手元にかわいい実験機器が欲しいな、と思い先人の知恵をネットからお借りして「おうちクラスター」を作ることにしました。
クラウドKubernetes を立てて検証していくのもいいですが、継続的な課金も考える必要があるのと、やはりオンプレ機器で Kubernetes を最初から作ると仕組みがより分かっていいよねということから Rasberry Pi で構築することにしました。

必要なもの

構築にあたり購入したものは以下となります。

No Name 金額 Link
1 無線LAN ¥2,482 リンク
2 HDMIケーブル(mini usb) ¥843 リンク
3 スイッチHub ¥2,955 リンク
4 電源 ¥2,599 リンク
5 Rasberry pi タワー ¥1,889 リンク
6 SSD 32GB * 3 ¥780 リンク
7 LAN Cable * 2 (2本セット) ¥663 リンク
8 USB-C & USB-A 3.0 Cable * 3 ¥699 リンク
9 Raspberry Pi 4 Model B/4GB ¥7,700 リンク

合計金額は計算していません。だって怖いもの。 しかしながら新しいオモチャを購入し、今後複数のアプリをここに入れて稼働させることを考えると実質0円です。きっと楽しい未来が見えることでしょう。

もし、今後ラズパイタワーをやめたとしても、この小さい電子機器にはほかにたくさん遊べる用途があります。その用途を考えるだけでもワクワクしてくるので、やはり実質0円だと思います。
Rasberry pi 以外は Amazon で購入しました。実は途中購入した物品もあり、翌日に届くのは大変ありがたかったです。

構築

f:id:kurimotti:20210724181602j:plain:w300

さて、ここから作り上げていきます。この画像からわかると思いますが、開封するときはすっっっごく楽しかったです。電子機器の開封時はなんて楽しいんだろうか、この気持ちを詩にしたためたい…
部品も多いので、ダイニングテーブルを占領して作る必要があります。そのため、おのずと決行は土日となります。そして息子がいない時を狙っています。

f:id:kurimotti:20210828164314j:plain:w300

Raspberry Pi を我が子のように大事に箱から取り出し、ラズパイタワーに取り付けます。

シートヒンクはラズパイタワーに付随していたものを使いました。気になる方は個別に購入しても良いと思います。

f:id:kurimotti:20210901205534j:plain:w300

タワーを組み立てていく際ですが、向きを揃えて取り付けましょう。また、この時点では Rasberry Pi 自体には MicroSD は取り付けしなくても良いです。OS をインストールしてから入れましょう。

f:id:kurimotti:20210901205811j:plain:w300

取り付けたら、トップに電源を入れ繋げていきます。その上に Hub、さらにその上に無線を乗せます。気をつける点としては、Hub が軽かったのと LAN ケーブルが太く頑丈なタイプだったため(ほぼ色で選んだ)、Hub が浮いてしまいました。マスキングテープで固定しています。

f:id:kurimotti:20210901205637j:plain:w300

最後に電源をつけてランプが付いたらひとまず完了です。お疲れ様でした。

私は白色で統一したかったので、白があるものは極力それを選びました。

おわりに

最終的に3時間ほど組み立てにかかりました。(もう少し短かったかも?)
ケーブルについては美しく配線させてやろうという、昔の血が騒いでしまい何度もやり直しを行いました。サーバーをラックに入れた後の配線作業、機器の交換もしやすく考えながら美しくケーブリングすることにハマっていたなぁ、と思いを馳せながら。
この特技(こだわり)はもう披露する場所はないんだろうなとしょんぼりしましたが、いつか「老エンジニアの昔の技術について会話する会」が発足したら話したいと思います。

さて、やっと OS を入れるところになるのですが、こちらを入れると文章が長くなってしまうので、物理編・論理編と分けて書いていきます。
実はこの記事を書いている時点では、最後まで構築できておらず、中途半端なところで止まっているのですが、、、

読書感想文:「学びのきほん」シリーズ

どなたかのTwitterで見かけた本の題名に惹かれて購入した、NHKが出版している「学びのきほん」シリーズ。

www.nhk-book.co.jp

1冊500円ほどで、Kindleでも販売していることから雑誌を読む感覚で読んでいます。 現時点で私が購入したのは以下の3つ。

はみだしの人類学

「読む」って、どんなこと?

ブッダが教える愉快な生き方

それぞれ30分程度で読めるので、何かの隙間時間に読めました。 ただ、読むだけではなくて、テーマに沿った内容を入り口まで丁寧に解説してくれます。

感想、となるとこの手の本は難しく、一言で言うと「ふむふむ」であり、文章とすると「読み終わった時に心が軽くなる」本(全然文章でもないけれど) シリーズはまだまだ出版されているので、次は何を購入しようかなー、と一覧を見ながら悩んでいます。

さいごに

手塚治虫の「ブッダ」をもう一度読み直そうかな!

Trerraform を使ってAKS 環境を構築するぞ 〜 AKS 単体〜

事前確認

さて、Azure 上で AKS を作成していきます。 今回は AKS を作成するだけでは面白くないので、Windows Pod も作成できるように Windows Node を追加します。

基本的な手順はいつものごとく以下と同じです。
https://docs.microsoft.com/ja-jp/azure/developer/terraform/

  1. Resouce Group を作成する
  2. AKS の作成
  3. 作成した AKSWindows Node を追加

今回はここまで進めます。

Terraform 構成ファイルの作成

それでは Terraform 構成ファイルを作成していきます。まずは 前回 作成したファイルをコピーし、基本的なベース部分を作成します。

# Azure provider source and version Setting
terraform {
    required_providers {
        azurerm = {
            source = "hashicorp/azurerm"
            version = "~>2.0"
        }
    }
}
# Azure provider
provider "azurerm" {
    features {}
}

# Create Resource Group
resource "azurerm_resource_group" "rg" {
    name = "aks-rg"
    location = "Japan East"
}

AKS Cluster

では、AKS はどうやって作るのでしょうか。
答えはこちらにあります。もうここにコードも貼ってある、、、ありがとう Terraform, https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/kubernetes_cluster

Windows ノードを作成していきたいので、少し変更します。
AKS を作成する場合は azurerm_kubernetes_cluster の中に必要な情報を書き込んでいきます。

resource "azurerm_kubernetes_cluster" "k8s-blue" { }

通常作成する場合は、以下のみで大丈夫です。シンプルですね。

resource "azurerm_kubernetes_cluster" "k8s-blue" {
  name                = "k8s-blue"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
  dns_prefix          = "sample-aks"

  default_node_pool {
    name       = "default"
    node_count = 1
    vm_size    = "Standard_D2_v2"
  }

  identity {
    type = "SystemAssigned"
  }

  tags = {
    Environment = "Production"
  }
}

Wndows ノードの場合は追加で必要な項目が 2 点あります。

  • Windows のユーザ名とパスワード
  • Network の種類

パスワードについては以下の要件を確認してから、適切な文字列を入れてましょう。
docs.microsoft.com

Network の種類は、Windows ノードを作成する場合、kubenet ではなく Azure CNI を利用することが必須です。他の環境でクラスターを作成する際、今後 Windows ノードの検討をされている場合は Azure CNI を選択しましょう。

docs.microsoft.com

2 つの項目を追加します。

  # Windows の場合は azure CNI ネットワークを使う
  network_profile {
    network_plugin = "azure"
  }

  windows_profile {
    admin_username = "azureuser"
    admin_password = "XXXXXXXXXX"
  }

Windows ノード

次に Windows ノードを追加する構成を追加します。 https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/kubernetes_cluster_node_pool

ノードの構成は azurerm_kubernetes_cluster_node_pool で設定していきます。
os_typeWindows を指定、vm_size では VM サイズを指定します。

ポイントは、どこのクラスターに対して追加するかを指定している kubernetes_cluster_id です。 ここで id のところで記載している k8s-blue は、クラスターで設定している名前です。リソース名の隣で指定した名前を設定しているので、フルネームで入れる必要がありません。

resource "azurerm_kubernetes_cluster_node_pool" "blue-node" {
  name                  = "win01"
  kubernetes_cluster_id = azurerm_kubernetes_cluster.k8s-blue.id
  os_type               = "Windows"
  vm_size               = "Standard_B2s"
  node_count            = 1

  tags = {
    Environment = "Blue"
  }
}

実施

それでは実行していきます。 初期化を行い、実行プランを作成します。

$ terraform init
$ terraform plan -out beta.tfplan

作成には少し時間がかかりますが、しばらく待ったのち作成されたことを確認します。
location は作成した地域を入れてください。

$ az group list --query "[?location=='japaneast']

できました!Azure Portal から確認します。作成したクラスターに Windows Node が追加されていることが確認できると思います。
こちらの画像は割愛します。

以下が Terraform の全体像です。

# Azure provider source and version Setting
terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~>2.0"
    }
  }
}

# Azure provider
provider "azurerm" {
  features {}
}

# Create Resource Group
resource "azurerm_resource_group" "rg" {
  name     = "aks-rg"
  location = "Japan East"
}

# Create AKS
resource "azurerm_kubernetes_cluster" "k8s-blue" {
  name                = "k8s-blue"
  location            = "Japan East"
  resource_group_name = azurerm_resource_group.rg.name
  dns_prefix          = "sample-aks"

  default_node_pool {
    name       = "linux01"
    node_count = 1
    vm_size    = "Standard_D2_v2"
  }

  # Windows の場合は azure CNI ネットワークを使う
  network_profile {
    network_plugin = "azure"
  }
  
  # パスワードポリシーに準じて入力
  windows_profile {
    admin_username = "azureuser"
    admin_password = "XXXXXXXXXX"
  }

  identity {
    type = "SystemAssigned"
  }
  tags = {
    Environment = "Blue"
  }
}

resource "azurerm_kubernetes_cluster_node_pool" "blue-node" {
  name                  = "win01"
  kubernetes_cluster_id = azurerm_kubernetes_cluster.k8s-blue.id
  os_type               = "Windows"
  vm_size               = "Standard_B2s"
  node_count            = 1

  tags = {
    Environment = "Blue"
  }

}

output "client_certificate" {
  value = azurerm_kubernetes_cluster.k8s-blue.kube_config.0.client_certificate
}

output "kube_config" {
  value     = azurerm_kubernetes_cluster.k8s-blue.kube_config_raw
  sensitive = true
}

前の記事を参考に、後片付けも行いましょう。

mihohoi.hatenablog.jp

まとめ

さて、これで AKS 単体を作成することができるようになりました。
次回は本題の AKS に対していくつかの Pod を自動的に作成できるような構成を作りたいと思います。

それではまた!

Terraform で Azure 環境作成ことはじめ

Azure 環境で Terraform を始めたいと思い、検証しました。

基本的な動きはこちら

docs.microsoft.com

と同じです。
同じような内容をあえてブログに書く理由はただ一つ、自分への備忘録です。
ドキュメント最高、ありがとうございます。

Azure で使うには

https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs

ここに詳しく記載されていますが、Azure 使うよ!ということを明記する必要があります。

Features and Bug Requests

そうそう、ここにこうやって記載があるのは良いですね。 その features のところに何を書くかというと、

It's possible to configure the behaviour of certain resources using the features block - more details can be found below.
機能ブロックを使って、特定のリソースの動作を設定することができます。詳細は以下の通りです。

ということが書いてあります。 例えば virtual_machine の場合、仮想マシンが破棄されたときにリソースは仮想マシンに接続されているOSディスクを削除されますが、false にすると削除されます。 デフォルトは true で、仮想マシンを破棄する際に一緒に削除される動作になります。

Azure にログインする

まずはここから始めないといけないところとして、Azure 環境と接続します。
Azure にログインし、自分のアカウント情報を確認します。

$ az account show
{
  "environmentName": "AzureCloud",
  "homeTenantId": "XXXXXXXXXXXXXXXXXXXXX",
  "id": "XXXXXXXXXXXXXXXXXXXXX",
  "isDefault": true,
  "managedByTenants": [],
  "name": "mihoサブスクリプション",
  "state": "Enabled",
  "tenantId": "XXXXXXXXXXXXXXXXXXXXX",
  "user": {
    "name": "miho@mail",
    "type": "user"
  }
}

まだ環境と接続していない場合はログインします。

$ az login

最初の Terraform 構成ファイルを作成する

まずは、Azure に Resource Group を設定する構成ファイルを作成します。

Location は今回東日本を指定します。

https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group

beta.tf という名前で構成ファイルを作成します。
terraform 区分と provide で、Azure 環境を指定します。その後、resource 区分では、作成する ResorceGroup を記載します。名前を sample-rg にしました。
rg と記載している部分は、ResouceGroup を参照する時の変数名です。

# Azure provider source and version Setting
terraform {
    required_providers {
        azurerm = {
            source = "hashicorp/azurerm"
            version = "~>2.0"
        }
    }
}
# Azure provider
provider "azurerm" {
    features {}
}

# Create Resource Group
resource "azurerm_resource_group" "rg" {
    name = "sample-rg"
    location = "Japan East"
}

作成したのち、初期化を行います。

$ terraform init

Initializing the backend...

Initializing provider plugins...
- Finding hashicorp/azurerm versions matching "~> 2.0"...
- Installing hashicorp/azurerm v2.68.0...
- Installed hashicorp/azurerm v2.68.0 (signed by HashiCorp)

Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

実行プランの作成を行います。実は 1 回目は失敗しました。 まずは成功例から。

$ terraform plan -out beta.tfplan

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
  + create

Terraform will perform the following actions:

  # azurerm_resource_group.rg will be created
  + resource "azurerm_resource_group" "rg" {
      + id       = (known after apply)
      + location = "japaneast"
      + name     = "sample-rg"
    }

Plan: 1 to add, 0 to change, 0 to destroy.

───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Saved the plan to: beta.tfplan

To perform exactly these actions, run the following command to apply:
    terraform apply "beta.tfplan"

で、こちらが失敗例です。
location を "East Japan" と書くと失敗しました。他の ResouceGroup は 方角から記載が始まりますが、一部地域は地名から始まるんですね、不思議。
利用するときは、ロケーションの名前をちゃんと調べてから書きましょう。

$ terraform plan -out beta.tfplan
╷
│ Error: "eastjapan" was not found in the list of supported Azure Locations: "westus,westus2,eastus,centralus,centraluseuap,southcentralus,northcentralus,westcentralus,eastus2,eastus2euap,brazilsouth,brazilus,northeurope,westeurope,eastasia,southeastasia,japanwest,japaneast,koreacentral,koreasouth,southindia,westindia,centralindia,australiaeast,australiasoutheast,canadacentral,canadaeast,uksouth,ukwest,francecentral,francesouth,australiacentral,australiacentral2,uaecentral,uaenorth,southafricanorth,southafricawest,switzerlandnorth,switzerlandwest,germanynorth,germanywestcentral,norwayeast,norwaywest,brazilsoutheast,westus3,eastusslv,swedencentral,swedensouth"
│
│   with azurerm_resource_group.rg,
│   on beta.tf line 18, in resource "azurerm_resource_group" "rg":
│   18:     location = "East Japan"
│

さて、成功と出たので実行します。

$ terraform apply beta.tfplan
azurerm_resource_group.rg: Creating...
azurerm_resource_group.rg: Creation complete after 0s [id=/subscriptions/XXXXXXXXXXXXXXXXXX/resourceGroups/sample-rg]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

作成されたのがわかります。

$ az group list --query "[?location=='japaneast']
"
[
  {
    "id": "/subscriptions/XXXXXXXXXXXXXXXXXX/resourceGroups/sample-rg",
    "location": "japaneast",
    "managedBy": null,
    "name": "sample-rg",
    "properties": {
      "provisioningState": "Succeeded"
    },
    "tags": {},
    "type": "Microsoft.Resources/resourceGroups"
  }
]

環境を削除(元に戻す

環境を削除します。Plan の指定で "-destroy" を記載して、アウトプットするファイルも名前を別名で作成されるようにします。

$ terraform plan -destroy -out beta.destroy.tfplan
azurerm_resource_group.rg: Refreshing state... [id=/subscriptions/XXXXXXXXXXXXXXXXXX/resourceGroups/sample-rg]

Note: Objects have changed outside of Terraform

Terraform detected the following changes made outside of Terraform since the last "terraform apply":

  # azurerm_resource_group.rg has been changed
  ~ resource "azurerm_resource_group" "rg" {
        id       = "/subscriptions/XXXXXXXXXXXXXXXXXX/resourceGroups/sample-rg"
        name     = "sample-rg"
      + tags     = {}
        # (1 unchanged attribute hidden)
    }

Unless you have made equivalent changes to your configuration, or ignored the relevant attributes using ignore_changes,
the following plan may include actions to undo or respond to these changes.

───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
  - destroy

Terraform will perform the following actions:

  # azurerm_resource_group.rg will be destroyed
  - resource "azurerm_resource_group" "rg" {
      - id       = "/subscriptions/XXXXXXXXXXXXXXXXXX/resourceGroups/sample-rg" -> null
      - location = "japaneast" -> null
      - name     = "sample-rg" -> null
      - tags     = {} -> null
    }

Plan: 0 to add, 0 to change, 1 to destroy.

───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Saved the plan to: beta.destroy.tfplan

To perform exactly these actions, run the following command to apply:
    terraform apply "beta.destroy.tfplan"

プランが作成されたので、適用します。

$ terraform apply beta.destroy.tfplan
XXXXXXXXXXXXXXXXXX

Apply complete! Resources: 0 added, 0 changed, 1 destroyed.

Azure コマンドを使って環境が削除されたことを確認します。

$ az group list --query "[?location=='japaneast']"
[]

これで、Azure 環境での動作が検証できました。

Terraform を Windows の WSL にインストールする

f:id:kurimotti:20210717130717p:plain ちょっとした検証用を簡単に作成したいので、Terraform に入門します。

Terraform とは

インフラ環境をコードで作成するツールです。Infrastructure as Code (IaC) ですね。
Azure環境やほかのクラウド環境でも利用できるので、幅広く利用されています。

Terraform https://registry.terraform.ioregistry.terraform.io

ざっくりしすぎて説明になっていないような気がしますが、使えるように今回は環境を整備します。

Install

Terraform インストールしてなかったので、インストールします。
インストール先は以下です。

Download Terraform www.terraform.io

環境としては Windows の WSL2 (Windows Subsystem for Linux) にインストールしています。

$ wget https://releases.hashicorp.com/terraform/1.0.2/terraform_1.0.2_linux_amd64.zip
$ unzip terraform_1.0.2_linux_amd64.zip

Command 'unzip' not found, but can be installed with:

sudo apt install unzip

おっと、unzip コマンドをインストールしていませんでした。
unzip コマンドを apt-get コマンドを使ってインストールします。

$ sudo apt-get install unzip

無事にインストールできたところで、再びインストールに戻ります。
zip されているので、ファイルを解凍します。

$ unzip terraform_1.0.2_linux_amd64.zip
Archive:  terraform_1.0.2_linux_amd64.zip
  inflating: terraform

解凍したら、ファイルを /usr/local/bin 配下に移動します。

$ sudo mv terraform /usr/local/bin/
$ cd /usr/local/bin
$ ls
terraform
$ rm terraform_1.0.2_linux_amd64.zip

コマンドが利用できることを確認します。

$ terraform -v
Terraform v1.0.2
on linux_amd64

使えるようになりました。バージョンが v1.0 になったのでこれからますます楽しみですね。