はじめに
Terraform で Kubernetes リソースを管理する記事はよくありますが、
今回は macOS 上で Podman を使い、ローカルの Kubernetes クラスタに Open Liberty をデプロイする ところまでやってみます。
この記事は、こんな人向けです。
- Terraform を触ったことがない/少し触ったことがある
- Kubernetes をローカルで試してみたい
- まずは本番環境ではなく、Mac 上で動作確認したい
- Open Liberty をコンテナで手軽に試したい
この記事を読み終えると、次のことができるようになります。
- Podman / kind を使ってローカル Kubernetes クラスタを作る
- Terraform で Kubernetes の
Namespace/Deployment/Serviceを作る - Open Liberty のコンテナをデプロイする
- ブラウザで起動確認する
この記事で使うもの
最初に、それぞれの役割をざっくり整理しておきます。
-
Podman
コンテナを動かすためのソフトです。Docker に近い感覚で使えます。 -
kind
ローカル環境に Kubernetes クラスタを作るためのツールです。
開発や検証でよく使われます。 -
Kubernetes
コンテナをまとめて動かして管理する仕組みです。 -
Terraform
「どんなリソースを作るか」をコードで定義して、まとめて適用できるツールです。 -
Open Liberty
Java アプリケーションを動かすための軽量ランタイムです。
今回は公式コンテナイメージをそのまま使います。
全体構成
今回の構成は次のようになります。
macOS
└─ Podman / Podman Desktop
└─ podman machine (Linux VM)
└─ kind cluster
└─ Kubernetes
└─ Open Liberty (Deployment / Service)
ポイントは、macOS では Podman が直接 Linux コンテナを動かすのではなく、podman machine という Linux VM を経由して動く ことです。
その上で kind が Kubernetes クラスタを作り、Terraform は ~/.kube/config を使ってそのクラスタに接続します。
前提
以下がインストール済みであることを前提にします。
- macOS
- Podman または Podman Desktop
- kubectl
- kind
- Terraform
まずは Podman をセットアップする
Podman を CLI でセットアップする最小手順は次のとおりです。
podman machine init
podman machine start
podman info
podman info が成功すれば、Podman の準備はできています。
kind でローカル Kubernetes クラスタを作る
次に、ローカル Kubernetes クラスタを作ります。
今回は kind を使います。
kind とは?
kind は、ローカルで Kubernetes をすぐ試すためのツールです。
本番のように複数サーバーを用意するのではなく、コンテナを使って Kubernetes ノードを再現します。
つまり今回は、
- Podman がコンテナを動かす
- kind がその上に Kubernetes クラスタを作る
という流れになります。
方法1: Podman Desktop から作る
Podman Desktop を使っている場合は、GUI から kind クラスタを作れます。
Settings → Resources → Create new Kind clusterを選択します。
デフォルトの設定で作成してみます。
作成後は ~/.kube/config に context が追加されるため、kubectl ですぐ操作できます。
方法2: CLI から作る
CLI で作る場合は以下です。
kind create cluster --name kind-cluster
kubectl cluster-info
kubectl get nodes
kubectl get nodes の結果で、ノードが Ready になっていれば準備完了です。
Open Liberty について
今回デプロイするのは Open Liberty の公式コンテナイメージです。
まずは最小構成で試したいので、アプリケーションは入れずにランタイムイメージをそのまま使います。
今回使うイメージは以下です。
icr.io/appcafe/open-liberty:full-java17-openj9-ubi-minimal
Open Liberty では、HTTP が 9080、HTTPS が 9443 で待ち受ける構成がよく使われます。
今回はローカルで簡単に確認したいので、主に 9080 を使います。
Terraform の構成を作る
ディレクトリ構成はシンプルにします。
.
├── main.tf
└── variables.tf
先に Kubernetes の用語をざっくり理解する
Terraform のコードを見る前に、今回作る Kubernetes リソースをざっくり理解しておくと読みやすいです。
-
Namespace
Kubernetes の中でリソースを分けて管理するための「箱」 -
Deployment
どのコンテナを、いくつ動かすかを管理するもの -
Service
Pod へアクセスするための「入口」
今回やりたいことを一言でいうと、
openliberty という箱(Namespace)を作り、その中で Open Liberty のコンテナを1つ動かし、そのコンテナへアクセスするための入口(Service)を作る
ということです。
main.tf
terraform {
required_providers {
kubernetes = {
source = "hashicorp/kubernetes"
version = "~> 3.0"
}
}
}
provider "kubernetes" {
config_path = "~/.kube/config"
# kubectl config current-context で確認した context 名を指定してください
config_context = "kind-kind-cluster"
}
resource "kubernetes_namespace_v1" "openliberty" {
metadata {
name = var.namespace
}
}
resource "kubernetes_deployment_v1" "openliberty" {
metadata {
name = var.app_name
namespace = kubernetes_namespace_v1.openliberty.metadata[0].name
labels = {
app = var.app_name
}
}
spec {
replicas = var.replicas
selector {
match_labels = {
app = var.app_name
}
}
template {
metadata {
labels = {
app = var.app_name
}
}
spec {
container {
name = var.app_name
image = var.image
port {
container_port = var.http_port
}
port {
container_port = var.https_port
}
}
}
}
}
depends_on = [kubernetes_namespace_v1.openliberty]
}
resource "kubernetes_service_v1" "openliberty" {
metadata {
name = var.app_name
namespace = kubernetes_namespace_v1.openliberty.metadata[0].name
}
spec {
selector = {
app = var.app_name
}
port {
name = "http"
port = var.http_port
target_port = var.http_port
}
port {
name = "https"
port = var.https_port
target_port = var.https_port
}
type = "ClusterIP"
}
depends_on = [kubernetes_namespace_v1.openliberty]
}
この Terraform で何をしているのか
初心者向けに、コードのポイントだけ整理しておきます。
provider "kubernetes"
Terraform が どの Kubernetes クラスタに接続するか を指定しています。
今回は ~/.kube/config を使っています。
特にハマりやすいのが config_context です。
こちらは以下のコマンドで確認した context 名を指定してください。
kubectl config get-contexts
もし context 名が違っていると、Terraform はクラスタに接続できません。
kubernetes_namespace_v1
openliberty という Namespace を作っています。
これは、Kubernetes の中で今回のリソースをまとめて管理するための箱です。
kubernetes_deployment_v1
Open Liberty のコンテナを起動する定義です。
ここでは、
- コンテナイメージは何を使うか
- 何個起動するか
- どのポートを使うか
を決めています。
replicas = 1 なので、今回は Pod を1つだけ起動します。
kubernetes_service_v1
起動した Pod にアクセスするための Service を作っています。
今回は type = "ClusterIP" にしています。
これは クラスタ内部だけで使う Service です。
つまり、このままでは Mac のブラウザから直接アクセスできません。
そのため、後で kubectl port-forward を使ってローカルに転送します。
variables.tf
variable "namespace" {
description = "Open Liberty をデプロイする Namespace 名"
type = string
default = "openliberty"
}
variable "app_name" {
description = "Deployment / Service 名"
type = string
default = "openliberty"
}
variable "image" {
description = "Open Liberty のコンテナイメージ"
type = string
default = "icr.io/appcafe/open-liberty:full-java17-openj9-ubi-minimal"
}
variable "replicas" {
description = "Pod のレプリカ数"
type = number
default = 1
}
variable "http_port" {
description = "Open Liberty の HTTP ポート"
type = number
default = 9080
}
variable "https_port" {
description = "Open Liberty の HTTPS ポート"
type = number
default = 9443
}
変数ファイルに分けておくと、後から
- イメージを差し替える
- Pod 数を増やす
- 名前空間を変える
といった変更がしやすくなります。
デプロイする
ここまでできたら、Terraform を実行します。
terraform init
terraform plan
terraform apply
実行後、Kubernetes 側でも確認してみます。
kubectl get ns
kubectl get deploy -n openliberty
kubectl get pods -n openliberty
kubectl get svc -n openliberty
Pod が Running になっていれば、Open Liberty のコンテナは起動しています。
動作確認する
今回は Service が ClusterIP なので、そのままでは Mac からアクセスできません。
ローカルで簡単に確認するため、kubectl port-forward を使います。
kubectl port-forward -n openliberty svc/openliberty 9080:9080
このコマンドは、
- Kubernetes 内の
openlibertyService の 9080 番ポートを - 手元の Mac の 9080 番ポートにつなぐ
という意味です。
その後、ブラウザで以下にアクセスします。
http://localhost:9080
Open Libertyが起動していることが確認できました。
ベースイメージをそのままデプロイしたので、Libertyのページが表示されています。
今回はランタイムイメージをそのまま起動しているため、「Open Liberty が動いていることの確認」が主目的です。
実際のアプリケーションを動かすには、別途アプリを含んだ独自イメージを作成します。
注意点
1. macOS の Podman は VM 経由で動く
Mac 上で Podman を使う場合、Linux コンテナは podman machine 上で動きます。
そのため、「Mac の中でそのまま直接動いている」と思うと少し混乱しやすいです。
2. Terraform は Kubernetes クラスタ自体を作るわけではない
Terraform の Kubernetes Provider は、すでに存在する Kubernetes クラスタに対してリソースを作るためのものです。
つまり今回は、
- kind でクラスタを作る
- Terraform でその中に Namespace / Deployment / Service を作る
という役割分担になっています。
3. config_context の名前違いで失敗しやすい
まず次を実行して、実際の context 名を確認してください。
kubectl config get-contexts
その名前を config_context に設定すれば OK です。
4. ランタイムだけでは「アプリ本体」は入っていない
今回使っているのは Open Liberty のランタイムイメージです。
そのため、業務アプリやサンプルアプリまで含まれているわけではありません。
実際にアプリを載せたい場合は、Dockerfile または Containerfile で
- アプリケーション
- Liberty の設定
を追加した独自イメージを作る流れになります。
まとめ
今回は、mac + Podman + kind + Terraform という構成で、
Open Liberty をローカル Kubernetes にデプロイしてみました。
流れとしては次の4ステップです。
- Podman を使えるようにする
- kind でローカル Kubernetes クラスタを作る
- Terraform で
Namespace/Deployment/Serviceを作る -
kubectl port-forwardでローカルから確認する
Terraform の Kubernetes Provider を使うと、Kubernetes リソースをコードで管理できるので、
「まずはローカルで構成を試したい」という場面にかなり向いています。
次にやるなら、以下に進むとさらに面白いと思います。
- Open Liberty のアプリケーションを含む独自コンテナイメージを作る
- Ingress や LoadBalancer 相当の公開方法を試す
-
kubernetes_manifestを使ってより柔軟な Kubernetes 定義を書く


