Kubernetes 1.12にHelmでWordpressをインストール

だいたい週末は喫茶店をはしごして本を読んで過ごすことが多いのだけど、今日に限っては台風でほとんどが夕方早くに店を閉めてしまった。
今回はKubernetes 1.12にHelmでWordpressをインストールしてみよう。Helm(v2.11.0 - Pumpkin Spice Latte Edition)はまだKubernetes v1.11までしかサポートしていないが、たぶん動かせば動くだろう。
https://github.com/helm/helm/releases/tag/v2.11.0

#HelmとTillerの導入
まずはhelmをダウンロードしてtillerをインストール。

```
wget https://storage.googleapis.com/kubernetes-helm/helm-v2.11.0-linux-amd64.tar.gz
tar xf helm-v2.11.0-linux-amd64.tar.gz
cd linux-amd64
./helm init
```

Tillerが動き始める。

```
# kubectl get pod -n kube-system
NAME                                    READY   STATUS    RESTARTS   AGE
calico-node-gxpkn                       2/2     Running   2          19h
calico-node-nxnn9                       2/2     Running   0          19h
calico-node-wjzzv                       2/2     Running   0          19h
coredns-576cbf47c7-dqwkv                1/1     Running   1          19h
coredns-576cbf47c7-n2vtz                1/1     Running   1          19h
etcd-192.168.0.131                      1/1     Running   1          19h
kube-apiserver-192.168.0.131            1/1     Running   1          19h
kube-controller-manager-192.168.0.131   1/1     Running   1          19h
kube-proxy-lhjb9                        1/1     Running   1          19h
kube-proxy-vbh4p                        1/1     Running   0          19h
kube-proxy-vrvkm                        1/1     Running   0          19h
kube-scheduler-192.168.0.131            1/1     Running   1          19h
metrics-server-6985c94f4b-t8b2c         1/1     Running   0          19h
tiller-deploy-845cffcd48-ck948          1/1     Running   0          89s
```

#HelmでWordpressのインストール
そしておもむろにWordpressをインストール。

```
./helm repo update
./helm install stable/wordpress
(実行結果)
Error: no available release name found
```

オーケーなんか見たことのあるエラーだ。
とりあえず何も考えず以下４行を実行。

```bash
kubectl create serviceaccount --namespace kube-system tiller
kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
kubectl patch deploy --namespace kube-system tiller-deploy -p '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}'
./helm init --service-account tiller
```

再度インストール。

```
./helm repo update
./helm install stable/wordpress
(実行結果)
Hang tight while we grab the latest from your chart repositories...
...Skip local chart repository
...Successfully got an update from the "stable" chart repository
Update Complete. ⎈ Happy Helming!⎈
root@m16:~/linux-amd64# ./helm install stable/wordpress
NAME:   knotted-molly
LAST DEPLOYED: Sun Sep 30 20:06:44 2018
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/Pod(related)
NAME                                     READY  STATUS   RESTARTS  AGE
knotted-molly-wordpress-f6b99df66-c2pb8  0/1    Pending  0         0s
knotted-molly-mariadb-0                  0/1    Pending  0         0s

==> v1/Secret

NAME                     AGE
knotted-molly-mariadb    0s
knotted-molly-wordpress  0s

==> v1/ConfigMap
knotted-molly-mariadb-init-scripts  0s
knotted-molly-mariadb               0s
knotted-molly-mariadb-tests         0s

==> v1/PersistentVolumeClaim
knotted-molly-wordpress  0s

==> v1/Service
knotted-molly-mariadb    0s
knotted-molly-wordpress  0s

==> v1beta1/Deployment
knotted-molly-wordpress  0s

==> v1beta1/StatefulSet
knotted-molly-mariadb  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 knotted-molly-wordpress'

  export SERVICE_IP=$(kubectl get svc --namespace default knotted-molly-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 knotted-molly-wordpress -o jsonpath="{.data.wordpress-password}" | base64 --decode)

root@m16:~/linux-amd64#
```

よし。
ただ、この時点では永続ボリュームが見つからないのでPVCがPendingになっている。

```
# kubectl get pod
NAME                                      READY   STATUS    RESTARTS   AGE
knotted-molly-mariadb-0                   0/1     Pending   0          106s
knotted-molly-wordpress-f6b99df66-c2pb8   0/1     Pending   0          106s
my-db-f55786649-pznng                     1/1     Running   0          20h
my-node-7488b97dd8-56wk6                  1/1     Running   2          20h
my-node-7488b97dd8-9btbs                  1/1     Running   3          20h
# kubectl get pvc
NAME                           STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
data-knotted-molly-mariadb-0   Pending                                                     113s
knotted-molly-wordpress        Pending                                                     113s
```

まあ、少し面倒くさいがNFSサーバー(192.168.0.135)を作ろうか。
NFSサーバーを作り（手順割愛）、`/share *(rw,no_root_squash)`をexportし、すべてのノードにnfs-commonをインストール。

```
apt-get -y install nfs-common
```

それぞれのPVCが要求する容量はそれぞれ8Gi、10Gi。

```
# kubectl get pvc data-knotted-molly-mariadb-0 -o yaml
...
spec:
  accessModes:
  - ReadWriteOnce
  dataSource: null
  resources:
    requests:
      storage: 8Gi
...
# kubectl get pvc knotted-molly-wordpress -o yaml
...
spec:
  accessModes:
  - ReadWriteOnce
  dataSource: null
  resources:
    requests:
      storage: 10Gi
...
```

ので、8Gi、10Giの順にNFSにPVを作成。

```yaml:pv_data-knotted-molly-mariadb-0.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: data-knotted-molly-mariadb-0
spec:
  capacity:
    storage: 8Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  nfs:
    path: /share/data-knotted-molly-mariadb-0
    server: 192.168.0.135
```

```yaml:pv_knotted-molly-wordpress.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: knotted-molly-wordpress
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  nfs:
    path: /share/knotted-molly-wordpress
    server: 192.168.0.135
```

```
mkdir /share
mount 192.168.0.135:/share /share
mkdir /share/data-knotted-molly-mariadb-0
chmod 777 /share/data-knotted-molly-mariadb-0
mkdir /share/knotted-molly-wordpress
chdmod 777 /share/knotted-molly-wordpress
kubectl create -f pv_data-knotted-molly-mariadb-0.yaml
kubectl create -f pv_knotted-molly-wordpress.yaml
```

まあ実は、helmで作ったアプリケーションが利用するあるPVCに対して狙ったPVを割り当てるうまい方法があるのか良くわからないのだけど、とりあえずストレージは割り当たり、以下の通り。

```
# kubectl get pvc
NAME                           STATUS   VOLUME                         CAPACITY   ACCESS MODES   STORAGECLASS   AGE
data-knotted-molly-mariadb-0   Bound    data-knotted-molly-mariadb-0   8Gi        RWO                           28m
knotted-molly-wordpress        Bound    knotted-molly-wordpress        10Gi       RWO                           28m
```

Podもようやく起動した。

```
# kubectl get pod
NAME                                      READY   STATUS    RESTARTS   AGE
knotted-molly-mariadb-0                   1/1     Running   0          114s
knotted-molly-wordpress-f6b99df66-qghmg   1/1     Running   0          70s
my-db-f55786649-pznng                     1/1     Running   0          20h
my-node-7488b97dd8-56wk6                  1/1     Running   2          20h
my-node-7488b97dd8-9btbs                  1/1     Running   3          20h
```

それでは起動したWordpressにアクセスしたい、が、ServiceがLoadBalancerで作られていてPending、

```
# kubectl get service
NAME                      TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
knotted-molly-mariadb     ClusterIP      10.110.181.27   <none>        3306/TCP                     42m
knotted-molly-wordpress   LoadBalancer   10.96.245.136   <pending>     80:31632/TCP,443:30585/TCP   42m
kubernetes                ClusterIP      10.96.0.1       <none>        443/TCP                      21h
my-db                     ClusterIP      10.106.19.247   <none>        3306/TCP                     20h
my-node                   NodePort       10.96.42.60     <none>        80:30864/TCP                 20h
```

なのでそいつをClusterIPに変更する。

```
kubectl edit service knotted-molly-wordpress
(変更前)
 23   - name: http
 24     nodePort: 31632
 25     port: 80
(変更後)
 23   - name: http
 24 #    nodePort: 31632
 25     port: 80
---
(変更前)
 28   - name: https
 29     nodePort: 30585
 30     port: 443
(変更後)
 28   - name: https
 29 #    nodePort: 30585
 30     port: 443
---
(変更前)
 35   sessionAffinity: None
 36   type: LoadBalancer
 37 status:
(変更後)
 35   sessionAffinity: None
 36   type: NodePort
 37 status:
```

ついでに、手元のPCからWebブラウザでアクセスしたいため、Ingressリソースを作成。

```yaml:ingress_knotted-molly-wordpress-ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: knotted-molly-wordpress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - http:
      paths:
      - path: /
        backend:
          serviceName: knotted-molly-wordpress
          servicePort: 80
    host: knotted-molly-wordpress.com
```

```
kubectl create -f ingress_knotted-molly-wordpress.yaml
```

そして、手元のPCのhostsファイルを書き換えて、`knotted-molly-wordpress.com`で`192.168.0.134`（Ingressが動作するkeepalivedのVIP）にアクセスできるよう修正。

そしてついにWebブラウザから`http://knotted-molly-wordpress.com/admin`にアクセスしてみると。。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/146381/1d93f191-b3f2-b613-d637-f86893098c70.png)

おおー、ついにWordpressの管理画面が。
Usernameは`user`、Passwordは以下のコマンドを実行して入手。

```
echo Password: $(kubectl get secret --namespace default knotted-molly-wordpress -o jsonpath="{.data.wordpress-password}" | base64 --decode)
```

そしてログイン。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/146381/3c7abc97-49c3-0e57-b23c-1333c0a66e5d.png)

うん。

Helmで簡単にWordpressというには程遠いなという話。