ニフクラ ブログ

ニフクラやクラウドの技術について、エンジニアが語るブログです。

ニフクラ Kubernetes Service Hatoba の新機能 LoadBalancer を使って Elasticsearch / Kibana をデプロイしてみた

はじめまして、富士通クラウドテクノロジーズの加藤壮悟です。
2021年卒の新入社員で、現在は Hatoba チームにて新人研修中です。
老後の夢は中華料理屋を開くことです。 よろしくお願いします。

さて、2021年7月、ニフクラ Kubernetes Service Hatoba に
type: LoadBalancer 機能が追加されました!

今回はその type: LoadBalancer を活用して、ログデータ検索や分析、可視化ツールの Elasticsearch と Kibana をデプロイし、公開してみたいと思います。

type: LoadBalancer? なにそれおいしいの?」という人(Kubernetes歴 2週間の時の私)もそうじゃない人も、Kubernetes 歴 1か月の私がしっかり解説しますので、ぜひ試してみてください。

ニフクラ Kubernetes Service Hatobaイメージ

ニフクラ Kubernetes Service Hatoba とは

ニフクラ Kubernetes Service Hatoba は、Kubernetes クラスターを簡単に構築・管理できるマネージドサービスです。Kubernetes の標準的な操作で、コンテナ化されたアプリケーションを、クラスター上にデプロイできます。

詳細については「機能・サービス:Kubernetes Service Hatoba」をご確認ください。

Kubernetes の type: LoadBalancer とは

Kubernetes 外部のロードバランサーを Kubernetes マニフェストの type フィールドに LoadBalancer と設定することで利用できます。

ニフクラ Kubernetes Service Hatoba (以降 Hatoba)上のクラスターで type: LoadBalancer を指定するとニフクラのL4ロードバランサーが作成され、それが Kubernetes の Service 用ロードバランサーとして紐づけられます。Service とは Kubernetes 上のコンテナ群(Pod と呼びます)で実行されているアプリケーションを公開するための方法です*1

利用シーン

Kubernetes の type: LoadBalancer は Web サービスを外部に公開するときに便利です。

Elasticsearch と Kibana をデプロイしてみる

今回は、ログの検索・分析エンジンである Elasticsearch とデータの可視化ツール Kibana を Hatoba 上にデプロイし type: LoadBalancer を使って外部公開してみようと思います! 

Hatoba に7月に追加された新機能 type: LoadBalancer を使うため、Elasticsearch と Kibana の構築さえしてしまえばアプリの公開はとても簡単です。

こちらは今回の構成のイメージになります。

f:id:nifcloud-developers:20210906141409p:plain
構成図

手順

  1. ニフクラ上のリソース(プライベートLAN、ルーター、NAS)を作成
  2. Hatoba クラスターを作成
  3. ニフクラNASを PersistentVolume として使うための設定をする
  4. クラスター上に ECK (Elastic Cloud on Kubernetes) をデプロイする
  5. Elasticsearch と Kibana をデプロイする
    ※Kibana を type: LoadBalancer で公開する
  6. あそぶ

検証環境

項目
リージョン east-2
ゾーン east-21
Kubernetes バージョン 1.21.1
Elasticsearch バージョン 7.11.2
Kibana バージョン 7.11.2
  • リージョン・ゾーンは任意で選んでいただいて構いませんが、リージョンにより使用可能な機能が異なります。ニフクラ ゾーン別機能対応表を参考に、ご希望のNASが利用可能なリージョン・ゾーンをご選択ください。
  • お手元に kubectl がインストールされた環境をご用意ください。

1. ニフクラ上のリソース(プライベートLAN、ルーター、NAS)を作成

まず今回のハンズオンで使うニフクラリソースを作成します。
Elasticsearch は PersistentVolume を使用しますが、今回はニフクラNASを利用したいと思います。

また、プライベートLANも設定し、Hatoba クラスターとNASが同一のネットワーク上にあるようにします。

1-1. プライベートLANの作成

サービス一覧から「ネットワーク」を選択します。

ネットワーク図が表示されている画面で「ネットワーク上での操作」のプルダウンから、「プライベートLAN作成」を選び、項目を入力します。

項目
プライベートLAN名 eck(任意の名前)
ゾーン east-21(任意のゾーン)
CIDR 192.168.0.0/16

f:id:nifcloud-developers:20210906135509p:plain
プライベートLAN作成

1-2. ルーターの作成

ルーターの作成に先立って、DHCPコンフィグおよびDHCPオプションを設定します。

左メニューの「DHCPコンフィグ」から、「DHCPコンフィグ作成」をクリックし、「自動割り当てIPアドレス」を追加します。

下記の項目は、Hatoba で作成するクラスターのノードに割り振るIPアドレスです。項目を入力したら「作成する」をクリックします。

項目
開始IPアドレス 192.168.1.0
終了IPアドレス 192.168.1.255

f:id:nifcloud-developers:20210906135541p:plain
DHCPコンフィグ作成

左メニューの「DHCPオプション」から、「DHCPオプション作成」をクリックし「default-router」に 192.168.0.1 と入力します。他の項目は入力不要ですので、「作成する」をクリックします。

f:id:nifcloud-developers:20210906135600p:plain
DHCPオプション作成

左メニューの「ネットワーク」をクリックし、「ネットワーク上での操作」のプルダウンから、「ルーター作成」を選択します。項目を下記の通り入力してください。

項目
ルーター名 router(任意)
ゾーン east-21(プライベートLANと同じゾーン)
タイプ router.small(任意)

f:id:nifcloud-developers:20210906135657p:plain
ルーター作成

「ネットワーク設定へ」をクリックし、ルーターのネットワーク設定の画面へ進みます。「ネットワーク追加」をクリックし、下記の項目を入力します。

項目
ネットワーク 作成したプライベートLAN
IPアドレス(任意) 192.168.0.1
DHCP 有効
DHCPコンフィグ 作成したDHCPコンフィグ
DHCPオプション 作成したDHCPオプション

f:id:nifcloud-developers:20210906135720p:plain
ルーター作成

「ファイアウォール設定へ」をクリックしますが、今回はプライベートネットワークにだけ接続するためファイアウォール設定なしで(「適用しない」を選択して)進めます。設定内容を確認し、ルーターを作成してください。

1-3. NASの作成

サービス一覧から「NAS」を選択します。

左メニューの「ファイアウォール」から「NASファイアウォールグループ作成」をクリックしてください。任意の名前を入力し、ゾーンを選択してから「作成する」をクリックします。

f:id:nifcloud-developers:20210906135821p:plain
NASファイアウォール作成

続いて、ルール変更の画面が表示されますので、接続を許可する接続元のIPアドレスの範囲として、Hatoba クラスターのIPアドレス範囲を指定します。入力が終わったら「追加」をクリックします。

項目
接続元種別 CIDR
IPアドレス・グループ 192.168.1.0/24

f:id:nifcloud-developers:20210906135843p:plain
NASファイアウォール作成

次にNASの作成を行います。左メニューの「NAS」を選択し、「NAS作成」をクリックしてください。

NFSの高速タイプもしくは標準タイプを選択します。

f:id:nifcloud-developers:20210906135936p:plain
NAS作成

基本設定を下記のとおり行ってください。

項目
NAS名 eck(任意の名前)
ゾーン east-21(プライベートLANと同じゾーン)
NAS容量 100GB(任意の容量)
NASファイアウォールグループ名 作成したNASファイアウォールグループ
プライベート側ネットワーク 作成したプライベートLAN
プライベートIPアドレス 192.168.100.1/16

f:id:nifcloud-developers:20210906135955p:plain
NAS作成

NASの作成が完了したら、そのNASを選択し、「選択したNASの操作」のプルダウンから、「設定変更」を選びます。

設定変更画面で、「root squash設定」を「root_squash」から「no_root_squash」に変更します。この設定により、Kubernetes が nobody 以外のユーザー名でのファイルの書き込みできるようになります。root squash について詳しくはニフクラNAS(NFS)のアクセス権限についての FAQ ページをご確認ください。

f:id:nifcloud-developers:20210906140018p:plain
NAS設定変更

2. Hatoba クラスターを作成

2-1.Hatoba ファイアウォール作成

サービス一覧から「Kubernetes Service Hatoba」を選択します。

左メニューの「ファイアウォール」から「ファイアウォールグループ作成」をクリックします。ファイアウォールグループ名は任意の名前を入力してください。

f:id:nifcloud-developers:20210906140148p:plain
Hatoba ファイアウォール作成

続いて、ファイアウォールグループに IN ルールを追加します。「選択したファイアウォールグループの操作」のプルダウンから、「INルール設定の追加」を選びます。

下記のように IN ルールを設定してください。

項目
プロトコル TCP
ポート 6443 - 6443
CIDR xxx.xxx.xxx.xxx/xx(適宜調整してください)

f:id:nifcloud-developers:20210906140208p:plain
Hatoba ファイアウォール作成

2-2. Hatoba クラスター作成

左メニューの「クラスター」から「クラスター作成」をクリックします。各項目を下記の通り入力します。

項目
クラスター名 eck(任意の名前)
ゾーン east-21(プライベートLANと同じゾーン)
プライベートLAN 作成したプライベートLAN
ファイアウォールグループ 作成したファイアウォールグループ
Kubernetesのバージョン v1.21.1(任意のバージョン)
HTTPロードバランサー 利用しない

f:id:nifcloud-developers:20210906140235p:plain
Hatobaクラスター作成

「ノードプール設定へ」をクリックし、続けて「ノードプール追加」をクリックしてください。

項目
ノードプール名 nodepool(任意の名前)
サーバータイプ e-medium8(メモリ8GBのものを推奨)
ノード数 3(任意の数)

f:id:nifcloud-developers:20210906140254p:plain
Hatobaクラスター作成

2-3. Hatoba クラスターのクレデンシャルを登録する

Hatoba クラスターの作成が完了したら、該当のクラスターを選択し、「選択したクラスターの操作」のプルダウンから「クレデンシャル表示」を選びます。この内容をすべてコピーし ~/.kube/config に保存してください。

3. ニフクラNASを PersistentVolume として使うための設定をする

Elasticsearch ではデータの永続化のために PersistentVolume を使用します。このステップでは Kubernetes NFS Subdir External Provisioner を使って、先ほど作成したニフクラNASを PersistentVolume としてプロビジョニングします。

Kubernetes NFS Subdir External Provisioner の Helm を使わない手順を進めていきます。

3-1. リポジトリをクローン

任意のディレクトリに Kubernetes NFS Subdir External Provisioner をクローンします。

$ git clone https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner.git
$ cd nfs-subdir-external-provisioner/

3-2. 認証を設定

# RBAC オブジェクトの subject を provisioner がデプロイされる現在の namespace の値に設定する
$ NS=$(kubectl config get-contexts|grep -e "^\*" |awk '{print $5}')
$ NAMESPACE=${NS:-default}
$ sed -i'' "s/namespace:.*/namespace: $NAMESPACE/g" ./deploy/rbac.yaml ./deploy/deployment.yaml
$ kubectl create -f deploy/rbac.yaml
serviceaccount/nfs-client-provisioner created
clusterrole.rbac.authorization.k8s.io/nfs-client-provisioner-runner created
clusterrolebinding.rbac.authorization.k8s.io/run-nfs-client-provisioner created
role.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created
rolebinding.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created

3-3. NFS subdir external provisioner の構成をする

deploy/deployment.yaml を編集します。NFS_SERVER NFS_PATH の値を変更します(修正箇所は4か所)。

$ sed -i'' "s/10.3.243.101/192.168.100.1/g" ./deploy/deployment.yaml
$ sed -i'' "s/\/ifs\/kubernetes/\//g" ./deploy/deployment.yaml

編集後の deploy/deployment.yaml は以下のようになります。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nfs-client-provisioner
  labels:
    app: nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: default
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: nfs-client-provisioner
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccountName: nfs-client-provisioner
      containers:
        - name: nfs-client-provisioner
          image: k8s.gcr.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: k8s-sigs.io/nfs-subdir-external-provisioner
            - name: NFS_SERVER
              value: 192.168.100.1
            - name: NFS_PATH
              value: /
      volumes:
        - name: nfs-client-root
          nfs:
            server: 192.168.100.1
            path: /

kubectl apply しておきます

$ kubectl apply -f deploy/deployment.yaml
deployment.apps/nfs-client-provisioner created

3-4. StorageClass をデプロイ

$ kubectl apply -f deploy/class.yaml
storageclass.storage.k8s.io/managed-nfs-storage created

3-5. テストしてみる

$ kubectl create -f deploy/test-claim.yaml -f deploy/test-pod.yaml
persistentvolumeclaim/test-claim created
pod/test-pod created

kubectl get pokubectl get pv を実行してみて、異常がなさそうであれば大丈夫です。

$ kubectl get po
NAME                                      READY   STATUS      RESTARTS   AGE
nfs-client-provisioner-7d494d96d4-wqm2b   1/1     Running     0          108s
test-pod                                  0/1     Completed   0          27s
$ kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                STORAGECLASS          REASON   AGE
pvc-77de7867-eb71-4f1e-a62c-a655b0314d8b   1Mi        RWX            Delete           Bound    default/test-claim   managed-nfs-storage            38s
$ kubectl delete -f deploy/test-pod.yaml -f deploy/test-claim.yaml
pod "test-pod" deleted
persistentvolumeclaim "test-claim" deleted

3-6. managed-nfs-storage をデフォルトの StorageClass にする

3-5 で作成した PersistentVolumeClaim test-claim では明示的に storageClassName を指定し、 PersistentVolume を作成させていました。storageClassName は省略可能なパラメータで、省略するとクラスターに設定されたデフォルトの StorageClass を使用します。

ECK のマニフェストでも storageClassName を指定できますが、ここから先 managed-nfs-storage の StorageClass しか使用しないため、 managed-nfs-storageデフォルトの StorageClass として設定します。

# 現在の状態を確認
$ kubectl get storageclass
NAME                  PROVISIONER                                   RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
managed-nfs-storage   k8s-sigs.io/nfs-subdir-external-provisioner   Delete          Immediate           false                  92m
# 変更
$ kubectl patch storageclass managed-nfs-storage -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
storageclass.storage.k8s.io/managed-nfs-storage patched
# 再度確認してみる
$ kubectl get storageclass
NAME                            PROVISIONER                                   RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
managed-nfs-storage (default)   k8s-sigs.io/nfs-subdir-external-provisioner   Delete          Immediate           false                  93m

4. クラスター上に ECK (Elastic Cloud on Kubernetes) をデプロイする

Elastic Cloud on Kubernetes (以下、ECK) とは、Elasticsearch や Kibana 等の Elastic 社の製品のセットアップやアップグレードといった管理をシンプルにしてくれるソフトウェアです。

ECK をデプロイするには下記のコマンドを実行してください*2

$ kubectl create -f https://download.elastic.co/downloads/eck/1.7.0/crds.yaml
customresourcedefinition.apiextensions.k8s.io/agents.agent.k8s.elastic.co created
customresourcedefinition.apiextensions.k8s.io/apmservers.apm.k8s.elastic.co created
customresourcedefinition.apiextensions.k8s.io/beats.beat.k8s.elastic.co created
customresourcedefinition.apiextensions.k8s.io/elasticmapsservers.maps.k8s.elastic.co created
customresourcedefinition.apiextensions.k8s.io/elasticsearches.elasticsearch.k8s.elastic.co created
customresourcedefinition.apiextensions.k8s.io/enterprisesearches.enterprisesearch.k8s.elastic.co created
customresourcedefinition.apiextensions.k8s.io/kibanas.kibana.k8s.elastic.co created
$ kubectl apply -f https://download.elastic.co/downloads/eck/1.7.0/operator.yaml
namespace/elastic-system created
serviceaccount/elastic-operator created
secret/elastic-webhook-server-cert created
configmap/elastic-operator created
clusterrole.rbac.authorization.k8s.io/elastic-operator created
clusterrole.rbac.authorization.k8s.io/elastic-operator-view created
clusterrole.rbac.authorization.k8s.io/elastic-operator-edit created
clusterrolebinding.rbac.authorization.k8s.io/elastic-operator created
service/elastic-webhook-server created
statefulset.apps/elastic-operator created
validatingwebhookconfiguration.admissionregistration.k8s.io/elastic-webhook.k8s.elastic.co created

5. Elasticsearch と Kibana をデプロイする(Kibana を type: LoadBalancer で公開する)

5-1.マニフェストを作成

Elasticsearch をデプロイするためのマニフェストを作成します*3

cat <<EOF | tee ./elasticsearch.yaml
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
  name: quickstart
spec:
  version: 7.11.2
  nodeSets:
  - name: default
    count: 1
    config:
      node.store.allow_mmap: false
    podTemplate:
      spec:
        containers:
        - name: elasticsearch
          env:
          - name: ES_JAVA_OPTS
            value: -Xms2g -Xmx2g
          resources:
            requests:
              memory: 4Gi
            limits:
              memory: 4Gi
EOF

ここで2点ほど注意点があります。

  1. バージョンを 7.11.2 としています Hatoba で作成される Kubernetes クラスターが使用しているコンテナランタイムと JDK の相性が悪く、うまく動作しない問題を回避するためです。(2021年9月現在)*4

  2. メモリの制限を4GBまで上げています Elasticsearch はメモリを大量消費するため、デフォルトの 1GB の制限だとOOM キラーによって殺されてしまいます。 Elastic 社の公式ドキュメントに記載の方法を参考に対処しています。

次に、Kibana のマニフェストを作成します*5

cat <<EOF | tee ./kibana.yaml
apiVersion: kibana.k8s.elastic.co/v1
kind: Kibana
metadata:
  name: quickstart
spec:
  version: 7.11.2
  count: 1
  elasticsearchRef:
    name: quickstart
  http:
    service:
      spec:
        type: LoadBalancer # default is ClusterIP
      metadata:
        annotations:
          service.beta.kubernetes.io/hatoba-load-balancer-name: kibanalb
    tls:
      selfSignedCertificate:
        disabled: true
EOF

このマニフェストに type: LoadBalancer の字が見えると思います。

そう、これが type: LoadBalancer です。

また、annotations に Hatoba のコントロールパネル上で表示されるロードバランサーの名前をつけています。名前の文字列には英数小文字のみ使用可能です。

5-2. Elasticsearch をデプロイ

マニフェストを適用します。

$ kubectl apply -f elasticsearch.yaml
elasticsearch.elasticsearch.k8s.elastic.co/quickstart created

Elasticsearch の状態を確認します。HEALTHgreen ならOKです。

$ kubectl get elasticsearch
NAME         HEALTH   NODES   VERSION   PHASE   AGE
quickstart   green    1       7.11.2    Ready   2m8s

5-3. Kibana をデプロイ

マニフェストを適用します。

$ kubectl apply -f kibana.yaml
kibana.kibana.k8s.elastic.co/qu

同様に Kibana の状態を確認します。HEALTHgreen ならOKです。

$ kubectl get kibana
NAME         HEALTH   NODES   VERSION   AGE
quickstart   green    1       7.11.2    72s

6. あそぶ

これでめでたく、Elasticsearch と Kibana がデプロイされ、Hatoba の新機能 type: LoadBalancer によって Kibana が外部公開されましたので、さっそく遊んでみましょう!

6-1. IPアドレスを確認

ロードバランサーのIPアドレスは kubectl get svc して quickstart-kb-httpEXTERNAL-IP を確認するか、ニフクラのコントロールパネルから確認します。

f:id:nifcloud-developers:20210906140453p:plain
Hatoba ロードバランサー

6-2. パスワードを確認

Kibana のデフォルトパスワードを確認します。

$ kubectl get secret quickstart-es-elastic-user -o=jsonpath='{.data.elastic}' | base64 --decode; echo
<パスワード>

6-3. ログインする

http://<ロードバランサーのIPアドレス>:5601 にアクセスします。

f:id:nifcloud-developers:20210906140523p:plain
Kibana

ログイン画面が表示されますので、ユーザー名 elastic と入力し、パスワードは 6-2 で確認したものを入れます。

f:id:nifcloud-developers:20210906140543p:plain
Kibana

6-4. あそぶ!

お疲れ様でした!

あとはサンプルデータをいじってみたり、自分のデータを入れるなどして遊んでみてください。

f:id:nifcloud-developers:20210906140613p:plain
Kibana

おわりに

少し長くなってしまいましたが、皆さんは無事に完了しましたか?

K8s 初心者の私が検証した際には Elasticsearch のデプロイにハマりにハマりましたが、この記事のメインディッシュである type: LoadBalancer は驚くほど簡単にデプロイできました。文字通り type: LoadBalancer って入れるだけですからね。

type: LoadBalancer は Kubernetes で何か Web アプリケーションをデプロイするなら、とても「欲しい!」機能なのではないでしょうか? 

よりパワーアップした Hatoba で、皆さん良い Kubernetes ライフを!

仕様

ニフクラ Kubernetes Service Hatoba のロードバランサーについての技術仕様はニフクラ Kubernetes Service Hatoba:ロードバランサーのページをご確認ください。

参考文献

ニフクラユーザーガイド Kubernetes Service Hatoba:ニフクラNASを使った永続化ボリューム

Kubernetes NFS Subdir External Provisioner