Help us understand the problem. What is going on with this article?

EKSでEFSファイルシステムを永続ボリュームとして利用する

はじめに

ここ2ヶ月ほどEKS/Kubernetesを触っています。

アプリケーションをコンテナ化する以上、コンテナは状態をなるべく持たず状態はデータベースやオブジェクトストレージに保存するようにするのがベストプラクティスですが、どうしてもファイルシステムにファイルを保存したいという場合はあるのではないでしょうか。

そういった場合、KubernetesのPersistent Volumeの仕組みを使うとPodに非揮発性のファイルシステムをマウントすることができます。
ただ、マウント対象のファイルシステムは自分で用意しないといけません。

マウント対象としてはいくつか選べるのですが、複数のPodから同時に読めて状態を共有できるようにするにはNFSファイルシステムをマウントするのがよいと思われます。

そこで、マネージドNFSファイルシステムであるAmazon EFSのファイルシステムをEKSクラスタで利用しようとしました。
EKSもEFSもAWSのマネージドサービスだし楽勝だろ、と思っていたら意外とハマったので、手順を共有して苦しむ人が減ればと思います。

EFSファイルシステムを作成する

AWSコンソールからEFSファイルシステムを作成します。

このとき、EKSのワーカーノードが存在するサブネットすべてをマウントターゲットに追加し、またそれぞれセキュリティグループをEKSが勝手に作成するセキュリティグループを設定しておきます。

https://aws.amazon.com/jp/about-aws/whats-new/2019/02/deploy-a-kubernetes-cluster-using-amazon-eks-with-new-quick-start/

こちらのクイックスタートをつかっていれば、xxx-NodeSecurityGroup-yyyみたいな名前のセキュリティグループができているかと思いますが、それです。

sc-2019-09-18 21.55.42.jpg

ワーカーノードのIAMロール

EKSワーカーノードのロールに1で作ったEFSボリュームに関するポリシーを追加します。こちらもクイックスタートを使っていると、xxx-NodeInstanceRole-yyyという名前になっているかと。

こちらのロールに、さきほど作成したEFSファイルシステムの「リスト・読み込み・書き込み」の権限が付与されていればOKです。

50bac8bd-88f9-478b-a0d5-b302239b7f99.png

efs-provisioner の設定

EFSをKubernetesの永続ボリュームとして使うには、efs-provisionerを使う必要があります。

https://github.com/kubernetes-incubator/external-storage/tree/master/aws/efs

しかし、これがREADMEの通りに手順をたどっても動かせないという罠があります。
リポジトリのサンプルマニフェストの記述が間違っているからです。。😡

こちらのIssueに解決策が載っていました。

https://github.com/kubernetes-incubator/external-storage/issues/1209

ただマウントしたいだけなら、

https://github.com/kubernetes-incubator/external-storage/blob/master/aws/efs/deploy/rbac.yaml


https://github.com/kubernetes-incubator/external-storage/blob/master/aws/efs/deploy/manifest.yaml

の2つをapplyする必要がありますが、両方とも修正する必要があります。

まずrbac.yamlですが、よくわからないRoleとClusterRoleの使い分けがありますが、ClusterRoleに一本化しましょう。また、サービスロールの記述も追加しないといけません。

rbac.yaml
---

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: efs-provisioner-runner
rules:
  - apiGroups: [""]
    resources: ["persistentvolumes"]
    verbs: ["get", "list", "watch", "create", "delete"]
  - apiGroups: [""]
    resources: ["persistentvolumeclaims"]
    verbs: ["get", "list", "watch", "update"]
  - apiGroups: ["storage.k8s.io"]
    resources: ["storageclasses"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["events"]
    verbs: ["list", "watch", "create", "update", "patch"]
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]

---

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: run-efs-provisioner
subjects:
  - kind: ServiceAccount
    name: efs-provisioner
    namespace: development # ClusterRoleBindingの指定はネームスペースごと
roleRef:
  kind: ClusterRole
  name: efs-provisioner-runner
  apiGroup: rbac.authorization.k8s.io

---

apiVersion: v1
kind: ServiceAccount
metadata:
  namespace: development # ServiceAccountの指定もネームスペースごと
  name: efs-provisioner

そして、manifest.yamlは、Deploymentのところにネームスペースとサービスアカウントを追記します。

manifest.yaml
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  namespace: development # この記述もネームスペースごと
  name: efs-provisioner
  spec:
    serviceAccount: efs-provisioner
    containers:
      - name: efs-provisioner
        image: quay.io/external_storage/efs-provisioner:latest

ディレクトリ分割

前の手順までで、Podの永続ボリュームとしてEFSファイルシステムを利用できるようになります。

適当なEC2インスタンスをたててEFSファイルシステムをマウントしてみるとわかるのですが、manifest.yamlのPersistentVolumeClaimごとにディレクトリが切られて、各Podからはその中しか見られないようになっています。
なので、1つのEFSファイルシステムを複数のPodで相乗り利用する場合は、共通のStorageClassを利用するPersistentVolumeClaimを複数定義すればよいです。

おわりに

これでEKSクラスタ上で動くPodの永続ボリュームとしてEFSファイルシステムを利用できるようになりました。
EKSもEFSもAWSの製品なのでありがちなユースケースなのではないかと思うのですが、意外とドンピシャな情報がなかったので、参考になればと思います。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away