【2019年最新】Helm 2.12.3のインストール手順

※当ブログではアフィリエイト広告を利用しています

Helm(英語で舵の意)はKubernetesクラスターで使えるパッケージ・マネージャーです。Linuxでいうapt-getやyum、MacでいうHomebrewみたいなものです。

HelmはKubernetesの標準では導入されていないため、別途導入する手順を紹介します。

Kubernetes環境を作ったことがない、持っていない方は、以下を参考に導入してみてください。

なぜHelmを使うのか

Kubernetesクラスターにアプリケーションをまともに導入しようとすると、実際には様々なリソースを作成する必要があります。

このブログが動いているWordPressで考えてみましょう。WordPressは大きく分けてWebサーバーとDBサーバーに大別されます。

これを動かそうとすると、例えば以下のような定義が必要になってきます。

  • Deployment – WebサーバーのPod定義
  • StatefulSet – DBサーバーのPod定義
  • Service/Ingress – Webサーバーの外部への公開
  • PersistentVolume/PersistentVolumeClaim – データの永続化
  • Secret – DBのパスワードやSSL証明書の保管
  • ConfigMap – php.ini などの構成ファイルの保管
  • HorizontalPodAutoscaler – WebサーバーのPodの自動スケーリング

・・・などなど、他にもたくさんあると思います。

これらを一つずつyamlファイルを書いて作成していくのは非常に手間ですし、あまり経験がない場合に正しくデプロイするのはかなり難易度が高いと思います。

Helmを使うと、コマンド一つで割と簡単に導入することができます。

WordPressの場合、例えば以下のようになります。

helm install stable/wordpress

めちゃくちゃ簡単ですよね。これで必要なリソース定義が全部導入されます。

「割と」と書いたのは、全部が全部簡単に入るわけではないためです・・・これは後で書きます。

最近はKubernetes上で動くアプリケーションは基本的にHelmチャートが提供されています。(個人的な感覚)

アップデートやロールバックも簡単にできるので、基本的に何かアプリケーションを導入する場合はHelmチャートの有無を確認してみてください。

Helmのインストール

それでは早速Helmをインストールしていきましょう。といってもモジュールをダウンロード・解凍して配置するだけなので非常に簡単です。

以下から「Latest Release」とあるバージョンをダウンロードしてください。2019/2/17現在、最新は2.12.3です。

https://github.com/helm/helm/releases/

こちらの記事でKubernetesを構築した場合は、マスター(k8smaster)から以下を実行して下さい。

curl https://storage.googleapis.com/kubernetes-helm/helm-v2.12.3-linux-amd64.tar.gz | tar zx linux-amd64/helm
mv linux-amd64/helm /usr/local/bin/helm; rm -rf linux-amd64

そうでない場合、kubectlを使っているマシンのOS種類に応じて上記のリンクに応じたモジュールをダウンロードしてください。

ダウンロードしたらファイルを解凍し、helmファイルをパスの通った場所へ配置してください。

以下を実行して、表示が返ってくればOKです。

helm version
# 以下出力例
Client: &version.Version{SemVer:"v2.12.3", GitCommit:"eecf22f77df5f65c823aacd2dbd30ae6c65f186e", GitTreeState:"clean"}
Error: could not find tiller

Errorが出ていますが、これはまだtillerのセットアップが済んでいないためなので問題ありません。次の章で解説します。

Helmの初期設定

Tillerの導入

RBCAの設定

Tiller(英語で舵を操作するための柄を意味する)は、Helmコマンドを叩いた際に動作するPodです。このTillerがKubernetesクラスターへのリソース定義の作成を行うため、Helmを使うためには必ず導入が必要です。

まずは、RBCAの定義を行い、TillerのPodが様々な操作を行うための権限を与えます。

以下のyamlファイルを作成してください。

apiVersion: v1
kind: ServiceAccount
metadata:
  name: tiller
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: tiller
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
  - kind: ServiceAccount
    name: tiller
    namespace: kube-system

そして、作成したファイルを使ってkubectlで作成します。

kubectl create -f tiller-rbca.yaml

serviceaccount/tiller created
clusterrolebinding.rbac.authorization.k8s.io/tiller created

Tillerの作成

とはいっても、以下のコマンドを実行すればよいだけです。

helm init --service-account tiller

#以下出力例
Creating /root/.helm
Creating /root/.helm/repository
Creating /root/.helm/repository/cache
Creating /root/.helm/repository/local
Creating /root/.helm/plugins
Creating /root/.helm/starters
Creating /root/.helm/cache/archive
Creating /root/.helm/repository/repositories.yaml
Adding stable repo with URL: https://kubernetes-charts.storage.googleapis.com
Adding local repo with URL: http://127.0.0.1:8879/charts
$HELM_HOME has been configured at /root/.helm.

Tiller (the Helm server-side component) has been installed into your Kubernetes Cluster.

Please note: by default, Tiller is deployed with an insecure 'allow unauthenticated users' policy.
To prevent this, run `helm init` with the --tiller-tls-verify flag.
For more information on securing your installation see: https://docs.helm.sh/using_helm/#securing-your-helm-installation
Happy Helming!

実行が完了すると、Tillerがデプロイされています。

kubectl get deploy -n kube-system

NAME            READY   UP-TO-DATE   AVAILABLE   AGE
calico-typha    0/0     0            0           3d23h
coredns         2/2     2            2           3d23h
tiller-deploy   1/1     1            1           2m59s

WordPressを導入してみる

では、試しにWordPressを導入してみましょう。実は事情により動かすことはできないんですが、動きそう、というのを見ていただければと。

Githubリポジトリはここ。

https://github.com/helm/charts/tree/master/stable/wordpress

helm install --name my-release stable/wordpress

実行すると、以下のようにたくさんのメッセージが表示されると思います。上記のコマンド一つで、以下のリソースがすべて作成されたということです。

NAME:   my-release
LAST DEPLOYED: Sun Feb 17 23:45:16 2019
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1beta1/Deployment
NAME                  DESIRED  CURRENT  UP-TO-DATE  AVAILABLE  AGE
my-release-wordpress  1        1        1           0          0s

==> v1beta1/StatefulSet
NAME                DESIRED  CURRENT  AGE
my-release-mariadb  1        1        0s

==> v1/Pod(related)
NAME                                  READY  STATUS   RESTARTS  AGE
my-release-wordpress-d9fc5bf6c-q6h9z  0/1    Pending  0         0s
my-release-mariadb-0                  0/1    Pending  0         0s

==> v1/Secret
NAME                  TYPE    DATA  AGE
my-release-mariadb    Opaque  2     0s
my-release-wordpress  Opaque  1     0s

==> v1/ConfigMap
NAME                      DATA  AGE
my-release-mariadb        1     0s
my-release-mariadb-tests  1     0s

==> v1/PersistentVolumeClaim
NAME                  STATUS   VOLUME  CAPACITY  ACCESS MODES  STORAGECLASS  AGE
my-release-wordpress  Pending  0s

==> v1/Service
NAME                  TYPE          CLUSTER-IP     EXTERNAL-IP  PORT(S)                     AGE
my-release-mariadb    ClusterIP     10.101.85.57   <none>       3306/TCP                    0s
my-release-wordpress  LoadBalancer  10.107.65.222  <pending>    80:30762/TCP,443:31320/TCP  0s


NOTES:
1. Get the WordPress URL:

  NOTE: It may take a few minutes for the LoadBalancer IP to be available.
        Watch the status with: 'kubectl get svc --namespace default -w my-release-wordpress'
  export SERVICE_IP=$(kubectl get svc --namespace default my-release-wordpress --template "{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}")
  echo "WordPress URL: http://$SERVICE_IP/"
  echo "WordPress Admin URL: http://$SERVICE_IP/admin"

2. Login with the following credentials to see your blog

  echo Username: user
  echo Password: $(kubectl get secret --namespace default my-release-wordpress -o jsonpath="{.data.wordpress-password}" | base64 --decode)

よく見ると、Pendingの項目がいくつかありますね。これは以下の理由によるものです。今回はすべてデフォルト値で入れたので、パラメーターをちゃんとしたり、事前準備をしておけば入るものなので、チャートが悪いわけではありません。

  • ServiceのタイプとしてLoadBalancerが指定されている。これはざっくりいうとAWSなどのKubernetes クラスターを使っている場合に自動で外部IPアドレスを振ってくれるものであるため、ローカルにKubernetesを立てている場合は何もしてくれません。タイプをCluster IPに変更して、Ingress経由でアクセスできるように修正する必要があります。
  • PersistentVolumeClaimもPendingですが、これはPersistentVolumeを定義していないからです。手作業でPVを定義すれば、動作するようになりますが、通常はGlusterFSやCephなどと連携させてDynamic Provisioningができるようにしておくべきです。これも別途取り上げたいと思います。(一応、NFSでもDynamic Provisioningできるようにする方法はあります。)

Helmは本当に簡単なのか?

Helmは一見コマンド一つで導入できてらくちん、という風に言うこともできるのですが、実際はそこまで甘くはないのが現実です。(とはいえ普通に入れるよりははるかに楽ではある)

先ほどの例のように、ただデフォルト値で導入しただけでは動かないケースも多くありますし、Helmチャートを動かす前に様々な準備作業を要求してくるチャートもあります。

また、先ほどはWordPressをすべてデフォルト値で導入しましたが、実際には莫大な数のパラメーターが存在します。以下リンクのConfigurationの部分を見て下さい。

https://github.com/helm/charts/tree/master/stable/wordpress

本番運用するうえでは、これらのパラメーター値をすべて検討した上で導入する必要があるため、設計にかなり苦労するかもしれません。

とはいえ、先ほどから何度も書いているように、素の状態で入れるよりは遥かにましだと思ってください。Kubernetes上に何かアプリケーションを導入する際にはぜひHelmチャートの有無を確認し、Helmでの導入を検討してみてください。

あとがき

今はWordPressといえばレンタルサーバーを借りるのが主流だと思います。(私はmixhost を使っています)

しかし、今後はKubernetesクラスター上に構築されたサービスも出てくるかもしれません。ブログのように突発的にアクセスが集中してもオートスケール可能ですし、よほどのことがない限りは落ちないサービスができるはず。ストレージもCephなどの分散ストレージを使えばHW障害もあまり影響なく運用できるはずだし、理論上はかなり良いサービスになるんじゃないかと思います。だれか作ってください。