前言:
很多同学安装部署完了kubernetes集群,总会有稍许的疑问:我安了这么一个玩意到底能干什么?
OK,本文就从实战的角度来告诉你,你可以使用kubernetes集群做许多的事情,比如,搭建一个简单的WordPress,这会是非常容易的一件事情,能容易到什么程度呢?可以说比宝塔还要简单,也就是说,搭建一个可以自己玩玩的个人网站非常容易,如果是在云服务器上部署,还可以随时的登录上去玩玩呢,当然,如果有安全风险,想关闭网站了,也非常的简单,一条命令就销毁整个网站了。
部署思路:
(1)k8s部署项目的特点:
WordPress是一个LAMP(LNMP)框架类的PHP个人cms网站,也就是说常规部署需要linux环境,Apache(httpd)或者nginx,PHP环境,MySQL数据库,那么,难点在于需要选择以上所述的软件的版本必须适配,比如,WordPress的版本,是选择4呢还是5呢,和其适配的PHP版本是多少呢?是PHP5还是PHP7呢?或者是其它特定版本呢?MySQL是5.6,5.7还是8.0呢?httpd版本又需要多少呢?这些都是问题,总的来说,常规部署需要考虑的细节非常多,部署步骤也是比较繁琐的。
kubernetes集群部署WordPress这样的需要集成环境的项目则非常简单,一个文件(也就是资源清单文件,这个是不好搞的哦),一条命令就可以搞定了。
(2)小结论
基于以上的分析可以得出一个结论,在k8s中部署,需要使用到一个MySQL镜像(版本为5.7.23),一个WordPress镜像(最新的),这两个镜像生成的容器放在一个pod内。
(3)安全方面的考虑:
既然使用到了MySQL那么肯定需要配置数据库的一些信息,既然是简单的WordPress,那么,数据库就没有必要搞太复杂了,都默认配置即可,只是密码需要使用secret加密一哈(两个密码,一个是WordPress数据库用户密码,一个是MySQLroot密码)。端口也都默认3306。
(4)数据持久化的设想:
数据库使用本地存储卷做永久化处理,避免WordPress丢失数据。由于是本地静态存储卷,因此,pod不能随便漂移了,要是胡乱漂移,比如,今天在node1节点,使用的node1的某个本地目录,然后第二天由于某种原因pod挂了,k8s集群给调度到node2节点了,那就很尴尬了,是吧。因此,需要设定node调度策略,固定到某个节点,本例计划固定在node2节点上。
相关代码如下:
[root@master ~]# k get no --show-labels NAME STATUS ROLES AGE VERSION LABELS k8s-master Ready <none> 22d v1.18.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-master,kubernetes.io/os=linux k8s-node1 Ready <none> 22d v1.18.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node1,kubernetes.io/os=linux k8s-node2 Ready <none> 22d v1.18.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,disk-type=ssd,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node2,kubernetes.io/os=linux,node=LAMP
给node2节点添加两个标签:
kubectl label nodes k8s-node2 disk-type=ssd kubectl label nodes k8s-node2 node=LAMP
再次查询:
[root@master ~]# k get no --show-labels NAME STATUS ROLES AGE VERSION LABELS k8s-master Ready <none> 22d v1.18.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-master,kubernetes.io/os=linux k8s-node1 Ready <none> 22d v1.18.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node1,kubernetes.io/os=linux k8s-node2 Ready <none> 22d v1.18.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,disk-type=ssd,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node2,kubernetes.io/os=linux
可以看到node2有了两个个新标签,因此,可以指定标签进行调度:
1. nodeSelector: 2. disk-type: k8s-node2
或者使用node这个标签也是OK的:
1. nodeSelector: 2. node: LAMP
(5)持久化存储的相关实现:
计划使用pv和pvc做本地化持久,pv绑定到node2节点的/opt/mysql/data目录下,该目录需要提前在node2节点建立:
[root@slave2 opt]# mkdir -p /opt/mysql/data
sc文件--mysql-sc.yaml
kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: local-storage provisioner: kubernetes.io/no-provisioner volumeBindingMode: WaitForFirstConsumer reclaimPolicy: Retain
pv文件---mysql-pv.yaml
apiVersion: v1 kind: Namespace metadata: name: web --- apiVersion: v1 kind: PersistentVolume metadata: name: mysql-pv namespace: web labels: type: local spec: capacity: storage: 2Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain storageClassName: local-storage local: path: "/opt/mysql/data" nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - k8s-node21.
pvc文件---mysql-pvc.yaml
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mysql-pvc namespace: web labels: app: mysql-pvc spec: accessModes: - ReadWriteOnce #此处需要和pv对应才能匹配 resources: requests: storage: 2Gi storageClassName: local-storage #此处需要和StorageClass.yaml匹配
(6)secret文件的加密使用
sercet文件--mysql-secret.yaml:
例如,第二个密码加密(注意哈,WordPress这个用户的密码是wordpress,和下面secret里写的一一样哈):
1. [root@master wordpress]# echo -n wordpress|base64 2. d29yZHByZXNz
kind: Secret apiVersion: v1 metadata: name: user-and-password namespace: web type: Opaque data: username: cm9vdA== password1: c2hpZ3VhbmczMg== password2: d29yZHByZXNz
下面将贴出部署的资源清单文件,如有错误,欢迎指正。
(7)部署文件
部署文件---deploy-wp.yaml(包含service部分):
[root@master wordpress]# cat deploy-wp.yaml apiVersion: v1 kind: Namespace metadata: name: web --- apiVersion: v1 kind: Pod metadata: name: wordpress namespace: web labels: app: wordpress spec: # nodeName: k8s-node2 containers: - name: wordpress image: wordpress imagePullPolicy: IfNotPresent ports: - containerPort: 80 name: wdport env: - name: WORDPRESS_DB_HOST value: 127.0.0.1:3306 - name: WORDPRESS_DB_USER value: wordpress - name: WORDPRESS_DB_PASSWORD value: wordpress # nodeSelector: # disk-type: ssd - name: mysql image: mysql:5.7.23 imagePullPolicy: IfNotPresent ports: - containerPort: 3306 name: dbport env: - name: MYSQL_ROOT_PASSWORD valueFrom: secretKeyRef: name: user-and-password key: password1 - name: MYSQL_DATABASE value: wordpress - name: MYSQL_USER value: wordpress - name: MYSQL_PASSWORD valueFrom: secretKeyRef: name: user-and-password key: password2 volumeMounts: - name: mysql-persistent-storage mountPath: "/var/lib/mysql" #不需要修改,映射到镜像内部目录 volumes: - name: mysql-persistent-storage persistentVolumeClaim: claimName: mysql-pvc #对应到pvc的名字 nodeSelector: node: LAMP --- apiVersion: v1 kind: Service metadata: labels: app: wordpress name: wp-svc namespace: web spec: ports: - port: 8081 protocol: TCP targetPort: 80 selector: app: wordpress type: NodePort
总结:
此部署主要是用到了节点选择策略,主要是pv和deploy的时候由于是本地volume,因此必须要硬选择节点,并且两次节点选择是要同一个node,否则不会部署成功。
其次是本地静态volume挂载pv和pvc以及sc的建立,为了减少不必要的麻烦,将以上部署统一为了web这个namespace。
总共五个文件,统一放到一个文件夹内,部署命令为:
[root@master wordpress]# ll total 20 -rw-r--r-- 1 root root 1553 Sep 19 12:35 deploy-wp.yaml -rw-r--r-- 1 root root 314 Sep 19 11:36 mysql-pvc.yaml -rw-r--r-- 1 root root 528 Sep 19 11:36 mysql-pv.yaml -rw-r--r-- 1 root root 185 Sep 19 11:04 mysql-sc.yaml -rw-r--r-- 1 root root 183 Sep 19 12:43 mysql-secret.yaml
kubectl apply -f 文件夹名称
删除命令为:
kubectl delete -f 文件夹名称
部署成功截图: