Oracle Cloud Free Tierで0円KubernetesをTerraform+Ansibleで自動構築する

# はじめに

2019年のOracle OpenWorld 2019で特定の機能を期限なく無料で使える「Always Free」が発表されました。

https://www.oracle.com/jp/cloud/free/
Oracle Cloud Free Tierには下記が含まれます。

- 30日間の無償トライアル
  - 300米ドルの無償クレジット。
    - データベース、アナリティクス、コンピュート、Container Engine for Kubernetesなどの幅広いOracle Cloudサービスに30日間アクセス可能
    - すべての使用可能なサービスで最大8つのインスタンス
    - 最大5TBのストレージ
    - etc...
- **Always Freeサービス**
  - 無期限に使用できるサービス。
    - Oracle Application Express（APEX）やOracle SQL Developerなどの強力なツールを含む、2つのOracle Autonomous Database
    - **2つのOracle Cloud Infrastructure Compute VM**、ブロック・ストレージ、オブジェクト・ストレージ、アーカイブ・ストレージ、ロード・バランサとデータ・エグレス、監視と通知


このAlways Free Resourceを使ってKubernetesクラスタを自動で組んでしまおうというのが本記事の主旨になります。

作成したTerraformのHCLやAnsible Playbookについては下記に配置しています。
https://github.com/gashirar/kubernetes-on-oci-free-tier



# 構成図

Always Freeの2つのインスタンスをそれぞれMasterとWorkerとしたKubernetesクラスタをKubeadmで構築します。
ネットワークやインスタンスの構築までをTerraformで実施し、インスタンス上のコンテナランタイムの設定やKubeadmの実行はAnsibleで行います。

[2022/03/14 追記]
VCNのCIDRですが、正しくは`10.0.0.0/16`です。
指摘がありがとうございます。


![architectur.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116002/123575f9-2017-7456-6ee4-84f81410c185.png)

# 構築の流れ

## OCI CLIの設定

こちらをどうぞ。
https://docs.cloud.oracle.com/ja-jp/iaas/Content/API/SDKDocs/cliinstall.htm

## テナンシOCIDの取得

右上のアイコンから「テナンシ」をクリックし、テナンシのOCIDを取得します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116002/b4c9c039-bbc2-c538-980b-bbad82a8615c.png)

## ユーザーOCIDの取得

右上のアイコンから「ユーザー設定」をクリックし、ユーザのOCIDを取得します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116002/2ca3c83f-a6c0-7276-fce1-3aa82e6bc83d.png)


## コンパートメントの作成とOCIDの取得

Oracle Cloud Infrastructureのコンパートメントについては下記が詳しいです。  
https://blogs.techvan.co.jp/oci/2019/02/06/oracle-cloud-infrastructureのコンパートメントについて/

左側のメニューから「アイデンティティ」→「コンパートメント」と選択し、コンパートメントを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116002/48ffb4f0-91fd-9b0e-cb2a-7da23860fe0c.png)

上記の「OCID」を後の工程で使うのでメモしておきましょう。

## Terraformのパラメータ設定

リポジトリの`terraform/main.tfvars.example`をコピーし、`terraform/main.tfvars`を作成します。

```hcl
# OCI Provider Settings
tenancy_ocid         = "<テナンシのOCID>"
compartment_ocid     = "<コンパートメントのOCID>"
user_ocid            = "<ユーザのOCID>"
private_key_path     = "<OCI CLIの秘密鍵の絶対パス>"
private_key_password = "<OCI CLIの秘密鍵のパスフレーズ>"
fingerprint          = "<OCI CLIのフィンガープリント>"
region               = "ap-tokyo-1"
ssh_public_key_path  = "<SSHログイン用の公開鍵の絶対パス>"
cluster_name         = "任意のクラスタ名"

# VCN
vcn_cidr_block           = "10.0.0.0/16"
master_subnet_cidr_block = "10.0.0.0/24"
worker_subnet_cidr_block = "10.0.1.0/24"

shape = "VM.Standard.E2.1.Micro"

## Oracle-Linux-7.8
os_user  = "opc"
image_id = "ocid1.image.oc1.ap-tokyo-1.aaaaaaaawuqkyea4y5khemhmw4j3yqmekacaan4d5yb2kvkkustj737fikqa"
```

設定後に`./bin/terraform.sh`を実行すると、OCI上に各種リソースが作成されます。

## Ansible Playbookの実行

`./bin/terraform.sh`の実行後、`ansible`ディレクトリに`hosts.ini`が作成されているはずです。
正しく生成されていることを確認したら、`./bin/ansible.sh`を実行することでKubeadmによるクラスタの構築が行われます。

## kubectlによるクラスタの操作

Ansible PlaybookでホームディレクトリにAdmin用のkubeconfigファイル`admin.conf`が生成されるので、それをkubectlに設定してください。

## クラスタの削除

`./bin/destroy.sh`で`terraform destroy`が実行されます。

# 実装ポイント

## メモリ不足を補うためにSwapをOnにする

Free Tierで利用できるインスタンスですが、1GBであるためKubeadmで構築したKubernetesクラスタを実行するには少々貧弱です。そのメモリ不足を補うためにも、今回はswapをonにした状態で構築できるようにしました。

通常のKubernetesクラスタであればNodeのSwapはOffにすることが推奨となっており、Onの場合はエラーで構築ができません。
今回はkubeadmのインストール時のパラメータを変更することでSwap onのままでも構築できるようにしています。

`ansible/roles/kubernetes/master/tasks/init.yaml`

```yaml
- name: Init Kubernetes cluster
  when: reset_cluster is succeeded
  shell: |
    kubeadm init --config "/etc/kubernetes/kubeadm-config.yaml" \
                 --upload-certs \
                 --ignore-preflight-errors=swap ★swapのエラーは無視する設定
```

`ansible/roles/kubernetes/master/templates/kubeadm-config.yaml.j2`

```yaml
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
failSwapOn: false ★swapが有効化されていてもエラーで終了しないように
```

Swap周りについては下記のブログを参考にしました。ありがとうございます。
https://inajob.hatenablog.jp/entry/always-free-kubernetes

# TODO
Oracle Cloud Free TierにはLoadBalancerも1つ無料で利用できるので、このロードバランサ―をつかってIngressも自動で構築するのもよさそうですね。また時間があるときに。

# 本当に無料？

とりあえず稼働させてみてますが、トライアルクレジットが33,000円から変化がないので（多分）大丈夫だと思われます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116002/a1d456e1-522a-ac27-2f6f-962829d3932d.png)


# 参考
https://blog.potproject.net/2019/11/05/oracle-cloud-kubernetes-k3s-cluster
https://inajob.hatenablog.jp/entry/always-free-kubernetes