LoginSignup
0
0

More than 5 years have passed since last update.

juju:lxcで立てたkubernetesにhelmでwordpressをデプロイする

Last updated at Posted at 2018-07-29

動機

最近飼い始めたハムの日記をつけよう、ということでhelm使ってwordpress立ててみたら、意外に苦戦したのでメモしておく。

前提条件

  • kubernetesとhelmが利用できる環境
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"11", GitVersion:"v1.11.1", GitCommit:"b1b29978270dc22fecc592ac55d903350454310a", GitTreeState:"clean", BuildDate:"2018-07-17T18:53:20Z", GoVersion:"go1.10.3", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"10", GitVersion:"v1.10.5", GitCommit:"32ac1c9073b132b8ba18aa830f46b77dcceb0723", GitTreeState:"clean", BuildDate:"2018-06-21T11:34:22Z", GoVersion:"go1.9.3", Compiler:"gc", Platform:"linux/amd64"}
$ helm version
Client: &version.Version{SemVer:"v2.9.1", GitCommit:"20adb27c7c5868466912eebdf6664e7390ebe710", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.9.1", GitCommit:"20adb27c7c5868466912eebdf6664e7390ebe710", GitTreeState:"clean"}
  • helmのChartはstable/wordpressでappVersion: 4.9.7
  • 筆者の環境はconjure-up => Juju:lxcで構築したkubernetes(1node)

Persistent Volumeを作成する

インストールするwordpressのhelmチャートは2つのPersistentVolume(PV)が必要なので、作成する。

nfsでのPVの作成方法はこちらを参考にさせてもらった。
Kubernetes: PersistentVolume概要とminikubeでの検証

まず、各PV用のディレクトリを作成。

install --directory --mode=777 /mnt/datahdd01/kube/rwo20g-wordpress01-wordpress
install --directory --mode=777 /mnt/datahdd01/kube/rwo8g-wordpress01-mariadb

次に、上記で作成したディレクトリをめがけたPVのyamlを作成する。

画像やら保存すると足りなくなりそうなのでサイズは多めに設定

./volumes/nfs/pv-nfs-rwo20g-wordpress01-wordpress.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-rwo20g-wordpress01-wordpress
spec:
  capacity:
    storage: 20Gi
  accessModes:
    - ReadWriteOnce
  # PersistentVolumeClaim を削除した時の動作
  persistentVolumeReclaimPolicy: Recycle
  mountOptions:
    - hard
  ## マウント先のNFS Serverの情報を記載
  nfs:
    path: /mnt/datahdd01/kube/rwo20g-wordpress01-wordpress
    server: 10.174.70.1

どのぐらい使うかわからないのでhelmチャートデフォルトの8Gに設定

./volumes/nfs/pv-nfs-rwo8g-wordpress01-mariadb.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-rwo8g-wordpress01-mariadb
spec:
  capacity:
    storage: 8Gi
  accessModes:
    - ReadWriteOnce
  # PersistentVolumeClaim を削除した時の動作
  persistentVolumeReclaimPolicy: Recycle
  mountOptions:
    - hard
  ## マウント先のNFS Serverの情報を記載
  nfs:
    path: /mnt/datahdd01/kube/rwo8g-wordpress01-mariadb
    server: 10.174.70.1

作成したPVのyamlをkubernetesに適用し、実際にPVを作成する。

kubectl apply -f ./volumes/nfs/pv-nfs-rwo20g-wordpress01-wordpress.yaml
kubectl apply -f ./volumes/nfs/pv-nfs-rwo8g-wordpress01-mariadb.yaml

helm install

helm installでwordpressをインストールする。

helm install \
--name wordpress01 \
--namespace faru \
--set serviceType=NodePort \
--set mariadb.rootUser.password=***** \
--set mariadb.db.password=***** \
--set persistence.size=20Gi \
--set livenessProbe.initialDelaySeconds=1200 \
stable/wordpress

オプションの意味

オプション 役割 備考
--namespace faru リリースするkubernetes上のnamespaceを指定する
--set serviceType=NodePort 作成するServiceのType うちのKubernetesは1NodeしかないのでNodePortを使っている
--set mariadb.rootUser.password=***** MariaDBのルートユーザパスワード *****は置き換える
--set mariadb.db.password=***** MariaDBのWordpress用ユーザパスワード *****は置き換える
--set persistence.size=20Gi WordPress用PVCのサイズ
--set livenessProbe.initialDelaySeconds=1200 生存ヘルスチェックの初期猶予時間 詳細説明します

livenessProbe.initialDelaySeconds

ここが今回詰まったところ。
これを設定せずに起動するとPodsのログが下記のところまで進んだところで、コンテナ再起動してしまい、いつまで待ってもwordpressが起動しなかった。

Welcome to the Bitnami wordpress container
Subscribe to project updates by watching https://github.com/bitnami/bitnami-docker-wordpress
Submit issues and feature requests at https://github.com/bitnami/bitnami-docker-wordpress/issues
 WARN  ==> You set the environment variable ALLOW_EMPTY_PASSWORD=yes. For safety reasons, do not use this flag in a production environment.
nami    INFO  Initializing apache
apache  INFO  ==> Reconfiguring PID file location...
nami    INFO  apache successfully initialized
nami    INFO  Initializing php
nami    INFO  php successfully initialized
nami    INFO  Initializing mysql-client
nami    INFO  mysql-client successfully initialized
nami    INFO  Initializing wordpress
wordpre INFO  WordPress has been already initialized, restoring...
mysql-c INFO  Trying to connect to MySQL server
mysql-c INFO  Found MySQL server listening at wordpress01-mariadb:3306
mysql-c INFO  MySQL server listening and working at wordpress01-mariadb:3306
wordpre INFO  Upgrading WordPress Database ...

調べてみると公式のissueで同じ症状を見つけた。
参考:kubernetes chart hangs after external DB connection #136

つまり、コンテナ初期化に異様に時間がかかることが原因となり、起動が終わる前にヘルスチェック(livenessProbe)が走ることで、
kubernetesはコンテナが壊れたと認識として再起動をかけてしまうようだ。
この対策として、issueにもあるようにinitialDelaySecondsを大幅に引き上げた。
1200秒は適当。

iptablesでポートフォワード

ローカルでlxc上にkubernetesノードを立てているので、外部公開用にServiceをポートフォワードをする。

kubectlのport-forwardはlocalhostしか使えないみたいなので、iptablesをいじってポートフォワードするシェルスクリプトを作ってみた。

./commands/setup_port_forward_for_kubernetes.sh
#!/bin/bash

# exit code not 0 error
set -e

### Usage
usage_exit() {
  echo "Usage: $0 [-m ADD/DEL] [-i private_if_name] [-p local_port] [-n kube_namespace] [ -s kube_service_name]"
  echo "ex) $0 -m ADD -i lxdbr0 -p 8081 -n faru -s metabase01-metabase"
  exit 1
}

### opts
while getopts m:i:p:n:s: OPT
do
  case $OPT in
    m)  MODE=$OPTARG
        ;;
    i)  PRIVATE_IF_NAME=$OPTARG
        ;;
    p)  LOCAL_PORT=$OPTARG
        ;;
    n)  NAMESPACE=$OPTARG
        ;;
    s)  SERVICE_NAME=$OPTARG
        ;;
    \?) usage_exit
        ;;
  esac
done

if [ $OPTIND -lt 11 ]; then
  echo "options are insufficient."
  usage_exit
fi

### opts check
case $MODE in
  ADD)  APPEND_OR_DELETE='I'
        APPEND_NUMBER='1'
        ;;
  DEL)  APPEND_OR_DELETE='D'
        APPEND_NUMBER=''
        ;;
  \?)   echo "option m is ADD or DEL"
        usage_exit
        ;;
esac

### private_if_namebash
echo "getting private IP"
PRIVATE_IP=$(ip -f inet address show dev ${PRIVATE_IF_NAME} | grep -o 'inet [0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+' | grep -o [0-9].* | head -n 1)
echo ">> ${PRIVATE_IP}"

### get info from kubernetes
echo "getting kubernetes service port and IP"
NODE_PORT=$(kubectl get --namespace ${NAMESPACE} -o jsonpath="{.spec.ports[0].nodePort}" services ${SERVICE_NAME})
NODE_IP=$(kubectl get nodes --namespace ${NAMESPACE} -o jsonpath="{.items[0].status.addresses[0].address}")
echo ">> ${NODE_IP}:${NODE_PORT}(${SERVICE_NAME})"

### setting iptables
COMMENT="port forward setting :: port ${LOCAL_PORT} => ${NODE_IP}:${NODE_PORT}(${SERVICE_NAME})"

echo "setting iptables"
# nat:PREROUTING
echo ">> nat:PREROUTING"
iptables -t nat -${APPEND_OR_DELETE} PREROUTING ${APPEND_NUMBER} -p tcp \
  --dport ${LOCAL_PORT} -j DNAT --to-destination ${NODE_IP}:${NODE_PORT} \
  -m comment --comment "port ${COMMENT}"

# nat:OUTPUT  for local packet
echo ">> nat:OUTPUT"
iptables -t nat -${APPEND_OR_DELETE} OUTPUT ${APPEND_NUMBER} -p tcp \
  --dport ${LOCAL_PORT} -j DNAT --to-destination ${NODE_IP}:${NODE_PORT} \
  -m comment --comment "port ${COMMENT}"

sysctl net.ipv4.conf.${PRIVATE_IF_NAME}.route_localnet=1

# nat:POSTROUTING
echo ">> nat:POSTROUTING"
iptables -t nat -${APPEND_OR_DELETE} POSTROUTING ${APPEND_NUMBER} -p tcp \
  --dst ${NODE_IP} --dport ${NODE_PORT} -j SNAT --to-source ${PRIVATE_IP} \
  -m comment --comment "${COMMENT}"

echo ">> ${MODE} ${COMMENT}"
echo "Finished!!"

exit 0

ローカルの8083から今回作成したwordpressのサービス(wordrpess01-wordpress)にポートフォワードする。

sudo ./commands/setup_port_forward_for_kubernetes.sh \
-m ADD -i lxdbr0 -p 8083 -n faru \
-s wordpress01-wordpress

ここまでくると、ブラウザからhttp://localhost:8083/ or http://<IPアドレス>:8083/にアクセスするとwordpress初期ページが表示される。

まとめ

helmでwordpressをデプロイする方法を紹介した。

  • kubernetesでコンテナの初期化に時間を要する場合はlivenessProbeのinitialDelaySecondsを伸ばす
  • lxcで構築したkubernetesでサービスを公開するためにiptablesを使ってポートフォワードするスクリプトを作成した

感想

  • helmの簡単インストールもまだまだこんな感じで動かないことが多い
  • helmに関する日本語の記事がほとんどない
  • 記事の中でおかしいところ、もっと簡単にできるってところがあればコメント頂ければ幸いである
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0