这部分我们结合之前的 k8s 知识点给大家展示如何使用 kubernetes 部署 wordpress+MySQL, 并利用 NFS 去保存我们容器的源代码以及 DB 数据.
安装环境
System: CentOS 7.4
Kubernetes: Kubernetes1.9
Docker: 17.03.2-ce
kube-master 10.110.16.10
kube-node-1 10.110.16.11
一. NFS 配置:
- NFS 依赖包安装
在 Master 与 Node 分别安装 NFS 组件
yum install nfs-utils -y
Tip: 这里需保证 nfs-utils 安装到所有 master 和 node 中, 否则容器挂载 NFS 时会报错.
- 为 Master 下 mysql data 和 wordpress 源码配置 NFS 共享目录
# systemctl enable nfs-server && systemctl start nfs-server
# mkdir -p /kube/mysql-db
# mkdir -p /kube/wordpress
# chown nfsnobody:nfsnobody /kube/mysql-db
# chown nfsnobody:nfsnobody /kube/wordpress
# chmod 755 /kube/mysql-db
# chmod 755 /kube/wordpress
# echo -e "/kube/mysql-db kube-(rw,sync,no_subtree_check,no_root_squash)" > /etc/exports
# echo -e "/kube/wordpress kube-(rw,sync,no_subtree_check,no_root_squash)" >> /etc/exports
Tip: 这里 kube-* 限制只有 kube 相关的 server 才能连接 Master 下 NFS 共享目录, no_root_squash 参数保证 wordpress-mysql pod 在初始化 mysql 配置的时候向在其下挂载的 / var/lib/mysql 目录有写入权限
- 应用配置
# exportfs -a
二. Persistent volume 配置
-
为 mysql data 与 wordpress 源码存储创建 Persistent volume
kubectl create -f mysql-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv
labels:
app: mysql
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
nfs:
path: /kube/mysql-db
server: kube-master
kubectl create -f wordpress-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: wp-pv
labels:
app: wordpress
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
nfs:
path: /kube/wordpress
server: kube-master
-
创建存放 mysql data 的 PVC
kubectl create -f mysql-pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: mysql-pv-claim
labels:
app: mysql
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
-
创建存放 wordpress 源码的 PVC
kubectl create -f wordpress-pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: wp-pv-claim
labels:
app: wordpress
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
查看绑定
# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
mysql-pv-claim Bound mysql-pv 5Gi RWO 3m
wp-pv-claim Bound wp-pv 5Gi RWO 6s
三. Secret 配置
- 创建 mysql root password
# kubectl create secret generic mysql-pass --from-literal='password=countonme'
四. Deployment 配置
- 部署 mysql deployment with PVC
# kubectl create -f mysql-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress-mysql
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
tier: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: wordpress
tier: mysql
spec:
containers:
- image: mysql:5.6
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-pass
key: password
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pv-claim
- 部署 wordpress deployment with PVC
# kubectl create -f wordpress-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
tier: frontend
strategy:
type: Recreate
template:
metadata:
labels:
app: wordpress
tier: frontend
spec:
containers:
- image: wordpress:4.8-apache
name: wordpress
env:
- name: WORDPRESS_DB_HOST
value: wordpress-mysql
- name: WORDPRESS_DB_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-pass
key: password
ports:
- containerPort: 80
name: wordpress
volumeMounts:
- name: wordpress-persistent-storage
mountPath: /var/www/html
volumes:
- name: wordpress-persistent-storage
persistentVolumeClaim:
claimName: wp-pv-claim
3.Service 配置
Tip: 这里我们开启了 node IP 的 80 端口的外部访问权限, 可以方便我们直接利用主机去访问虚拟机任意 Node 地址从而登录我们的 Wordpress 网站.
# kubectl create -f wp-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: wordpress-mysql
labels:
app: wordpress
spec:
ports:
- port: 3306
selector:
app: wordpress
tier: mysql
clusterIP: None
---
apiVersion: v1
kind: Service
metadata:
name: wordpress
labels:
app: wordpress
spec:
ports:
- port: 80
nodePort: 80
selector:
app: wordpress
tier: frontend
type: NodePort
Tip: 这里 service 定义的 name: wordpress-mysql 保证我们 wordpress-deployment.yaml 定义的如下环境变量可以作为有效的域名成功去访问我们的 mysql 容器, 保证网站服务器与数据库服务器的通讯.
env:
- name: WORDPRESS_DB_HOST
value: wordpress-mysql
五. 验证结果
- 访问 wordpress 主页
这里我们可以直接在浏览器访问任意 node 的 IP 地址从而进入 wordpress 主页
-
查看 NFS 主机对在容器里的 mysql data 与 wordpress root dir 的目录挂载.
#mount |grep kube-master
-
后记:
果我们使用 helm 包管理去部署 wordpress, 将大大简化我们的工作量.
Helm deployment:
1. 搜索 chart
搜索 wordpress 的 charts
# helm search wordpress
NAME CHART VERSION APP VERSION DESCRIPTION
stable/wordpress 5.0.3 5.0.2 Web publishing platform for building blogs and websites.
2. 查看 chart 的存储信息
创建 wordpress 的时候需要申请 PersistentVolumeClaim,由于我们的环境不支持动态申请所以需要手动创建
# helm inspect value stable/wordpress
……
## MariaDB admin password
## ref: https://github.com/bitnami/bitnami-docker-mariadb/blob/master/README.md#setting-the-root-password-on-first-run
##
# rootUser:
# password:
## Enable persistence using Persistent Volume Claims
## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/
##
master:
persistence:
enabled: true
## mariadb data Persistent Volume Storage Class
## If defined, storageClassName: <storageClass>
## If set to "-", storageClassName: "", which disables dynamic provisioning
## If undefined (the default) or set to null, no storageClassName spec is
## set, choosing the default provisioner. (gp2 on AWS, standard on
## GKE, AWS & OpenStack)
##
# storageClass: "-"
accessMode: ReadWriteOnce
size: 8Gi
……
persistence:
enabled: true
## wordpress data Persistent Volume Storage Class
## If defined, storageClassName: <storageClass>
## If set to "-", storageClassName: "", which disables dynamic provisioning
## If undefined (the default) or set to null, no storageClassName spec is
## set, choosing the default provisioner. (gp2 on AWS, standard on
## GKE, AWS & OpenStack)
##
# storageClass: "-"
##
## If you want to reuse an existing claim, you can pass the name of the PVC using
## the existingClaim variable
# existingClaim: your-claim
accessMode: ReadWriteOnce
size: 10Gi
可以看到 wordpress 的 chart 需要两个 pv,分别用于 mariadb(8G) 和 wordpress(10G) 的数据存储。
3. 手动创建 chart 所需的 pv
创建 create-pv.yml 文件,输入以下内容
# vim create-pv.yml
apiVersion: v1
kind: PersistentVolume
metadata:
name: mariadb-pv
spec:
capacity:
storage: 8Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
#storageClassName: nfs
nfs:
path: /nfsdata/mariadb-pv
server: 172.20.6.116
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: wordpress-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
#storageClassName: nfs
nfs:
path: /nfsdata/wordpress-pv
server: 172.20.6.116
创建 pv
# kubectl apply -f create-pv.yml
persistentvolume/mariadb-pv created
persistentvolume/wordpress-pv created
4. 安装 chart
# helm install --name wordpress stable/wordpress
NAME: wordpress ---------①---------
LAST DEPLOYED: Fri Jan 4 10:32:57 2019
NAMESPACE: default
STATUS: DEPLOYED
RESOURCES: ---------②---------
==> v1beta1/Deployment
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
wordpress-wordpress 1 1 1 0 0s
==> v1beta1/StatefulSet
NAME DESIRED CURRENT AGE
wordpress-mariadb 1 1 0s
==> v1/Pod(related)
NAME READY STATUS RESTARTS AGE
wordpress-wordpress-56794ff7b9-rf98x 0/1 Pending 0 0s
wordpress-mariadb-0 0/1 Pending 0 0s
==> v1/Secret
NAME TYPE DATA AGE
wordpress-mariadb Opaque 2 0s
wordpress-wordpress Opaque 1 0s
==> v1/ConfigMap
NAME DATA AGE
wordpress-mariadb 1 0s
wordpress-mariadb-tests 1 0s
==> v1/PersistentVolumeClaim
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
wordpress-wordpress Pending 0s
RESOURCES:
==> v1/Service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
wordpress-mariadb ClusterIP 10.100.218.132 <none> 3306/TCP 0s
wordpress-wordpress LoadBalancer 10.100.36.64 <pending> 80:31051/TCP,443:30169/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 wordpress-wordpress'
export SERVICE_IP=$(kubectl get svc --namespace default wordpress-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 wordpress-wordpress -o jsonpath="{.data.wordpress-password}" | base64 --decode)
输出分为 3 部分(上文输出结果中的①②③):
- ① 本次部署 chart 的描述信息。包括 release 的名字(没有指定,则默认生成)。release 部署的 namespace,默认是 default。release的状态 DEPLOYED 表示已经将 chart 部署到集群。
- ② release 包含的资源: Service、 Deployment、 Secret 等
- ③ release 的使用方法
5. 访问 wordpress
使用 http://nodeip+service_port 访问wordpress
其他信息,包括后台地址,管理员账号等信息可以参考release 的 NOTES 部分。
写在最后
Helm 的使用有点类似 ubuntu 的 apt 或者 RHEL 的 yum,极大的简化了部署一个应用的流程。对于使用者而言,使用 Helm 后不用需要了解 Kubernetes 的 yaml 语法并编写应用部署文件,也无需考虑应用的各种依赖,可以直接通过 Helm 下载并在 kubernetes 上安装需要的应用。 除此以外,Helm 还提供了 kubernetes 上的软件部署,删除,升级,回滚应用的强大功能。