Juju: 在使用LXC建立的Kubernetes上,通过Helm部署WordPress
动机
最近开始养仓鼠,想要记录它的日记,于是用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)
创建持久卷。
由于要安装WordPress的Helm Chart,所以需要创建两个必要的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文件。
为了避免图片或保存空间不足的情况发生,建议将尺寸设置得稍大一些。
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。
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
使用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
选项的含义
–set serviceType=NodePort作成するServiceのTypeうちのKubernetesは1NodeしかないのでNodePortを使っている–set mariadb.rootUser.password=*****MariaDBのルートユーザパスワード*****は置き換える–set mariadb.db.password=*****MariaDBのWordpress用ユーザパスワード*****は置き換える–set persistence.size=20GiWordPress用PVCのサイズ
–set livenessProbe.initialDelaySeconds=1200生存ヘルスチェックの初期猶予時間詳細説明します
活动探针的初始延迟秒数。
这就是这次卡住的地方。
如果没有进行这个设置就启动的话,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 ...
在查找过程中,我在官方问题中找到了相同的症状。
参考:kubernetes图表在连接外部数据库后出现卡顿问题#136。
换句话说,因为容器初始化非常耗时,导致在启动完成之前进行健康检查(livenessProbe),从而使Kubernetes错误地认为容器已经崩溃并重新启动。
作为对策,根据问题(issue)中的建议,大幅增加了initialDelaySeconds。
设定1200秒是合适的。
使用iptables进行端口转发
由于在本地lxc上搭建了Kubernetes节点,所以需要将Service进行端口转发以进行外部公开。
由于kubectl的port-forward只能使用localhost,因此我尝试通过修改iptables创建了一个用于端口转发的shell脚本。
#!/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服务(wordpress01-wordpress)上。
sudo ./commands/setup_port_forward_for_kubernetes.sh \
-m ADD -i lxdbr0 -p 8083 -n faru \
-s wordpress01-wordpress
当到达这一步时,通过浏览器访问http://localhost:8083/或http://<IP地址>:8083/,将显示WordPress初始页面。
总结
我介绍了使用Helm部署WordPress的方法。
-
- kubernetesでコンテナの初期化に時間を要する場合はlivenessProbeのinitialDelaySecondsを伸ばす
- lxcで構築したkubernetesでサービスを公開するためにiptablesを使ってポートフォワードするスクリプトを作成した
心得
-
- helmの簡単インストールもまだまだこんな感じで動かないことが多い
-
- helmに関する日本語の記事がほとんどない
- 記事の中でおかしいところ、もっと簡単にできるってところがあればコメント頂ければ幸いである