1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Terraform×OKEで無料マネージドKubernetesクラスタを構築してみた

Posted at

はじめに

自分用のKubernetesクラスタがほしいと思ったことはありませんか?私はあります。
minikubeやkindなどもありますが、せっかくなら本物(?)のKubernetesを使いたいですよね。

自分用Kubernetesを構築するパターンとして、①自宅サーバを用意して構築する(Raspberry PiやVM)②クラウドを利用するという2パターンが考えられます。

しかし、それぞれ以下の懸念点があります。

①自宅サーバ
・物品調達から必要な場合がある
・自分で1から構築しないといけない
・サーバの管理が必要
②クラウド
・料金がかかる
 例)AWSのEKSは1ヶ月あたり約140 USD
   ※EC2(t3.medium、EBS 30GB)×1台、ALB×1台の場合

そこで、Oracle Cloud Infrastructure(OCI)で無料マネージドKubernetesクラスタを構築してみました。
さらにOCIのマネージドTerraformサービスであるリソースマネージャ(こちらも無料)を使い、IaCによって構築してみました。

無料で使える仕組み

OKEの基本クラスタ

OCIのマネージドKubernetesサービスは OKE(Oracle Container Engine for Kubernetes) といいます。
OKEには一部機能が制限される基本クラスタと全機能が利用できる拡張クラスタの2種類があります。

そして、基本クラスタはクラスタ自体の料金が無料です。
ワーカーノードとしてデプロイされるコンピュートインスタンス(とそのボリューム)や、LoadBalancer Service適用時のロードバランサの料金のみが発生します。
image.png

基本クラスタを作成するには、作成時に拡張クラスタ機能を設定しないようにする必要があります。(参考)

Always Freeリソース

OCIにはAlways Freeという無料枠が存在します。
OKEの基本クラスタを構築するために以下のサービスが必要となりますが、各サービスにAlways Freeの無料枠が存在します。

サービス 無料枠 備考
コンピュートインスタンス
(シェイプ)
VM.Standard.A1.Flex(Arm)
(合計4 OCPU、24GBメモリ)
・VM.Standard.E2.1.Micro(AMD)
もあるがOKEで使用不可
ブロックボリューム 合計200GB ・ブートボリュームを含む
ロードバランサ(FLB) 1台、帯域幅10Mbps ・LoadBalancer Service適用時に利用
・フレキシブルシェイプ

Always Freeはホームリージョンでのみ提供されます。

つまり、OKEの基本クラスタとAlways Freeリソースを組み合わせることで、無料のKubernetesクラスタを構築することができます。

前提条件

  • OCIアカウント (有料アカウントにアップグレード済) およびコンパートメントが作成済みであること

有料アカウントにアップグレードしても課金対象のリソースを作成しない限り料金は発生しません。また、Always Freeは有料アカウントでも無料で利用可能です。

構成図

本記事では東京リージョンに構築します。
image.png

Always Freeや後述するCloudShellによるアクセスのためホームリージョンに構築します。
ホームリージョンはOCIアカウント作成時に指定し、後から変更できないので注意してください。

構築手順

1. Terraform構成ファイル(.tf)の作成

1から構成ファイルを作ってもよいですが、今回はスタックとして保存する機能を使ってTerraform構成ファイル(.tf)のひな形を入手します。
開発者サービス>Kubernetesクラスタ(OKE)>クラスタの作成からクイック作成の画面に行きます。
image.png

どうせ後で編集するのでデフォルト設定のまま進み、スタックとして保存します。
image.png

拡張クラスタ機能(ノードタイプ「仮想」)を設定していない状態で、この画面の「クラスタの作成」をクリックすると「基本クラスタの作成」のチェックボックスが表示されるので、チェックを入れて「クラスタの作成」をクリックすると基本クラスタが作成されます。
Terraformを使わない場合はこれでOKです。(シェイプの設定などは行ってください。)

スタックとして保存すると、OKEを構築するためのTerraform構成ファイルがリソースマネージャのスタックとして保存されます。

スタックとはリソースマネージャにおけるTerraform構成のセットです。

image.png

スタックから構成ファイルをダウンロードしてその内容をもとに編集します。
image.png

作成したファイルはこちらです。

なお、通常Terraformで必要な認証情報はリソースマネージャを操作するユーザの情報を利用するため、構成ファイルに記載したりする必要はありません。

作成のポイント

(必須)

  • oci_containerengine_clustertype"BASIC_CLUSTER"(基本クラスタ)とすること
  • oci_containerengine_node_poolnode_shapeは無料枠の対象であるVM.Standard.A1.Flexとし、node_shape_configのOCPUとメモリがそれぞれ無料枠の範囲内に収まるようにすること
    今回の構成では1 OCPU、8GBメモリを3台としています。(合計3 OCPU、24GBメモリ)

(任意)

  • セキュリティの観点からKubernetes APIエンドポイントはプライベートサブネットにしました

2. リソースマネージャを使って構築

OCIのマネージドTerraformサービスであるリソースマネージャを使って、OKEを構築します。

スタックの作成

リソースマネージャのスタックの作成からマイ構成を選び、作成したファイルをフォルダごとドラッグアンドドロップすることでスタックを作成できます。
image.png

ソース・コード制御システムを選ぶとGitHub等で管理しているコードをスタックとすることもできます。

名前や変数(variable)を入力して作成します。
image.png

image.png

計画(terrafrom plan)

まずは計画を実行します。
image.png

成功するとログに作成予定のリソースが表示されます。
基本クラスタ(BASIC_CLUSTER)を作成予定であることが分かりますね。
image.png

適用(terraform apply)

計画が成功したら適用し、リソースを作成します。
先ほど成功した計画をもとに適用します。
image.png

基本クラスタが作成できています。(なぜか作成日のところに自分のメールアドレスが表示されています…)
image.png

ノードプールには指定した通りワーカーノードが3台作成されています。
image.png

実体はコンピュートインスタンスなのでインスタンスの画面からも確認できます。
Always Freeの対象であるVM.Standard.A1.Flexで作成されています。
image.png

もちろんVCNやサブネットといったネットワークも作成されています。
image.png

ちなみに、適用が完了するまで約25分かかりました。
ノードプールの作成に時間がかかるようです。
image.png

破棄(terraform destroy)

削除する場合は破棄します。
image.png

3. クラスタにアクセス・動作確認

リソースマネージャでクラスタが作成できたら、kubectlを使ってクラスタにアクセスします。
ここではコンソール上で利用できるターミナルであるCloudShellを使います。

今回作成したクラスタのAPIエンドポイントはプライベートサブネットに配置したため、そのままではCloudShellからアクセスできません。
CloudShellからプライベートサブネットにアクセスする方法はいくつかありますが、今回はCloudShellのプライベートネットワーク機能を使います。

プライベートネットワークはホームリージョンでのみ使用できます。

CloudShellの設定

APIエンドポイントにアクセスするため、プライベートネットワークの設定を行います。
プライベートネットワークをAPIエンドポイントのサブネットに設定します。

画面右上のアイコンからCloudShellを起動し、ネットワークからエフェメラル・プライベート・ネットワークを選び、APIエンドポイントサブネットをアクティブなネットワークとして使用します。
設定が完了するとネットワークパブリックからエフェメラルになります。
image.png

プライベートネットワークの設定ができたら、OKEのクラスタ詳細画面のクイック・スタート:サンプル・アプリケーションのデプロイ>クラスタのアクセスローカル・アクセスにあるプライベート・エンドポイント・アクセス・コマンドをコピーして実行します。
(APIエンドポイントサブネットがプライベートサブネットだとCloudShellアクセスが選択できないようです。)
image.png

CloudShell
$ oci ce cluster create-kubeconfig --cluster-id <クラスタのOCID> --file $HOME/.kube/config --region ap-tokyo-1 --token-version 2.0.0 --kube-endpoint PRIVATE_ENDPOINT

kubeconfig(~/.kube/config)が作成されます。

kubectlでクラスタにアクセスできることを確認します。

CloudShell
$ kubectl get nodes
NAME          STATUS   ROLES   AGE   VERSION
10.0.10.158   Ready    node    27m   v1.34.1
10.0.10.16    Ready    node    27m   v1.34.1
10.0.10.90    Ready    node    27m   v1.34.1

ワーカーノードが表示され、クラスタにアクセスできていることが確認できました。

これで無料Kubernetesクラスタが使えるようになりました!

サンプルアプリケーションのデプロイ

Kubernetes公式ドキュメントに記載されているdeployment.yamlを適用します。
なお、今回作成したクラスタのバージョンは執筆時点(2025/11)の最新バージョンであるKubernetes 1.34.1およびCRI-O 1.34.0ですが、本バージョンではそのままでは正常に適用できないため、一部修正します。(詳細は別記事にまとめています)

CloudShell
$ wget https://k8s.io/examples/application/deployment.yaml
$ sed -i 's/image: nginx:1.14.2/image: docker.io\/nginx:1.14.2/g' deployment.yaml
修正後のdeployment.yaml
deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: docker.io/nginx:1.14.2 #修正
        ports:
        - containerPort: 80

適用します。

CloudShell
$ kubectl apply -f deployment.yaml
$ kubectl get deployments
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   2/2     2            2           23s
$ kubectl get pods
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-5bd9f86786-ch2dm   1/1     Running   0          38s
nginx-deployment-5bd9f86786-k6tvg   1/1     Running   0          38s

deployment.yamlの内容でPodが起動しました。

確認ができたらいったん削除します。

CloudShell
$ kubectl delete -f deployment.yaml
$ kubectl get deployments
No resources found in default namespace.
$ kubectl get pods
No resources found in default namespace.

4. LoadBalancerを使う

LoadBalancer Serviceを作成してOCIのロードバランサ(FLB)が利用できることを確認してみます。
3.で使ったdeployment.yamlにServiceを追加したdeployment_lb.yamlを作成します。

deployment_lb.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: docker.io/nginx:1.14.2
        ports:
        - containerPort: 80
---
# 以下追加
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  # OCI FLBの設定(帯域幅10MbpsのAlways Free FLB)
  # ここがないと有料のロードバランサが作成される
  annotations:
    oci.oraclecloud.com/load-balancer-type: "lb"
    service.beta.kubernetes.io/oci-load-balancer-shape: "flexible"
    service.beta.kubernetes.io/oci-load-balancer-shape-flex-min: "10"
    service.beta.kubernetes.io/oci-load-balancer-shape-flex-max: "10"
spec:
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: LoadBalancer

annotations:についてはこちらこちらに詳細が記載されています。

適用します。

CloudShell
$ kubectl apply -f deployment_lb.yaml
$ kubectl get deployments
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   2/2     2            2           5s
$ kubectl get pods
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-5bd9f86786-8pb7d   1/1     Running   0          18s
nginx-deployment-5bd9f86786-msdvg   1/1     Running   0          18s
$ kubectl get services
NAME            TYPE           CLUSTER-IP     EXTERNAL-IP       PORT(S)             AGE
kubernetes      ClusterIP      10.96.0.1      <none>            443/TCP,12250/TCP   65m
nginx-service   LoadBalancer   10.96.240.26   xxx.xxx.xxx.xxx   80:31774/TCP        31s

LoadBalancer Serviceが作成されており、EXTERNAL-IPにグローバルIPアドレスが割り当てられています。

コンソールで確認すると、EXTERNAL-IPに割り当てられたグローバルIPアドレスを持つFLBが作成されています。
image.png

また、LB用サブネットのセキュリティリストが自動で更新され、全てのIPアドレス(0.0.0.0/0)からのTCP/80(port: 80)が許可されています。(その他にもLBのヘルスチェックポートなども適切に許可されます。)
image.png

セキュリティリストの自動更新を無効にすることもできるようです。
詳細はこちら

インターネットからFLB経由でPodにアクセスしてみます。
ブラウザでhttp://<FLBのグローバルIPアドレス>にアクセスします。
image.png

FLBを経由してPodにアクセスできました!

料金の確認

しばらく4.を適用した状態のままにしましたが、料金は0円でした。
image.png

まとめ

OKEを使って無料でマネージドKubernetesクラスタを構築してみました。
Terraformを利用することで構築を自動化でき、簡単に作成/削除ができるようになりました。
学習やちょっとした検証などの用途であれば十分使えるかと思います。

お読みいただきありがとうございました。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?