この記事は エーピーコミュニケーションズ Advent Calendar 2018 の 20 日目の記事となります。
はじめに
今回は Kubernetes(k8s) の CloudProvider の実装を説明します。
そもそも CloudProvider とは各種クラウドで k8s を実装した際に、各リソース(Volume や Service)をクラウドのリソース(ELB や EBS)を使って実装することができる機能となっております。
社内研修の一環として k8s / Rancher について学習した際に、検証として CloudProvider について調査を行いました。
今回は AWS の EC2 上に Rancher を使って k8s 環境を構築し、構築したクラスターに対し CloudProvider の機能を実装、合わせて利用方法について説明したいと思います。
サーバ構成
今回構築するサーバーの構成です。
- Rancher x 1
- インスタンスタイプ:t3.medium
- Control & etcd x 1
- インスタンスタイプ:t3.small
- Worker x 1
- インスタンスタイプ:t3.small
- 共通
- AMI:CentOS 7
- docker:17.03.2
- k8s:1.11
- Rancher:2.1.1
※今回は rancher / k8s についてがメインとなりますので AWS の説明は省いております。
ご了承ください。
事前準備
AWS ( IAM - 全般 )
事前に以下のポリシーが付与されている IAM アカウントを用意します。
用意したアカウントでインスタンスを構築します。
- PowerUserAccess
- IAM Role の参照、EC2インスタンスへの付与が出来る権限(iam:PassRole)
AWS ( IAM - Role )
事前に以下のポリシーが適用されている Role を作成しておく。
構築
AWS 上に以下のインスタンスを構築していきます。
AWS インスタンスの構築(3サーバ共通)
【ステップ 1】: Amazon マシンイメージ (AMI):CentOS 7 (x86_64) - with Updates HVM
【ステップ 2】: インスタンスタイプの選択:サーバ構成のインスタンスタイプを指定
【ステップ 3】: インスタンスの詳細の設定:
・IAM ロール:事前に用意したロールを指定(今回は RancherRole という名前で用意しています)
【ステップ 4】: ストレージの追加:8 GiB / 汎用SSD ( gp2 )
【ステップ 5】: タグの追加
・Key = kubernetes.io/cluster/CLUSTERID
・Value = owned
※ CLUSTERIDは任意の識別子を付ける(3 台共同じ ID)
【ステップ 6】セキュリティグループを指定
※IAM ロールの指定、およびタグの追加以外は基本的な EC2 の構築と変わりません。
VPC(Subnet) / SecurityGroup にタグを付与
以下のリソースにも EC2 インスタンスに付与したタグを付与する
- VPC(Subnet)
- SecurityGroup
付与するタグ
・Key = kubernetes.io/cluster/CLUSTERID
・Value = owned
※CLUSTERID は EC2 インスタンスに付与した識別子と同じ値を指定する
Docker / Rancher 構築
Docker / Rancher の構築は弊社 T氏の以下記事を参考に構築します。
Rancher2.0を使って超高速にkubernetesクラスタを構築した時のメモ
k8s クラスタ構築
k8s クラスタの構築も上記 T氏の記事を参考に構築します。
【注意】
クラスタを構築する際に以下を指定してください。
クラスタタイプ
- k8s サービスを利用せず、EC2 にインスタンスを構築して実装している為、クラスターのタイプで【 CUSTOM 】を指定してください。
クラスタオプション
- クラスターのオプションで左下の【 CloudProvider 】の項目において【 Amazon 】を指定してクラスターを作成してください。
CloudProvider を使ったリソース作成
Service(LoadBalancer)
Rancher 管理画面から【ワークロード】⇒【YAML を インポート】より、以下で Deployment をデプロイしてみましょう。
※nginx の Pod と Service を定義しています。
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: my-nginx
labels:
run: my-nginx
spec:
ports:
- port: 80
protocol: TCP
selector:
run: my-nginx
type: LoadBalancer
実行後、AWS のコンソールを確認してみましょう。
ELB に一台 LoadBalancer が追加されております。
これは CloudProvider によって Service(LoadBalancer) で定義されたリソースを ELB で実装された形となります。
PersistentVolume
PersistentVolume 作成前に PersistentVolume 作成用の StorageClass を作成します。
- クラスターの【ストレージ】⇒【ストレージクラス】から【クラスを追加】でストレージクラスを追加します
- 名前は任意で指定し、プロビジョナーを【Amazon EBS ディスク】を指定して作成します
それでは実際に PersistentVolume を作成してみましょう
- 各プロジェクト(名前空間)の【ワークロード】⇒【ボリューム】から【ボリューム追加】でボリュームを追加します
- 【ストレージクラス】を上記で作成した際のストレージクラス名を選択します
- 【容量】は適当に指定します(まずは 1GiB 程度から)
実行後、AWS のコンソールを確認してみましょう。
EBS に一つ Volume が追加されております。
これは CloudProvider によって PersistentVolume で定義されたリソースを EBS で実装された形となります。
まだ、どこにも割り振っていない為、available の状態が確認できると思います。
Service 同様、PersistentVolume でも nginx の Pod を作成し実際にVolumeをマウントさせてみましょう。
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
ports:
- containerPort: 80
volumeMounts:
- mountPath: /usr/share/nginx/html
name: vol1
volumes:
- name: vol1
persistentVolumeClaim:
claimName: ###### <Volume名> ######
無事に Pod の作成、Volume のマウントが完了すると、EBS の available の状態から in-use の状態に変わったことが確認できると思います。
まとめ
CloudProvider の実装・利用説明については以上となります。
PersistentVolume を利用する際に、NFS等の別の機構を用意する必要が無くなり、マネージドなリソースが利用できるのはメリットとはなりますが、HA や運用については別途検討が必要と考えています。
また、Service についてはマネージドな LB である ELB を利用でき、自動でアタッチしてくれることはメリットと考えています。
AWS での k8s 実装は EKS が主流となりそうですが、機構を学習するという面ではよい勉強になったと思っています。
AWS での k8s 実装の参考になれば幸いです。