动手动脑学Kubernetes系列之搭建WordPress

查理谈科技 2024-05-13 22:37:14

在之前的文章中, 介绍了搭建好的#minikube#环境,如果你现在还没有一个可用的minikube环境, 那么可以去中直接下载;

在之前的文章中, 先后介绍了如何从源代码开始构建一个Node.js应用和Spring Boot 应用, 并且部署到Kubernetes 中(这个Kubernetes 环境主要是之前建好的#minikube#) , 现在我们开始进一步深入的学习Kubernetes, 用一个个可以实际运行的例子的形式, 深入理解#Kubernetes#的概念以及原理.

在#动手动脑学Kubernetes#系列教程中, 我们展示了Kubernetes的基本用法

在里, 学习了#Pod#的基本知识;

在里, 学习了标签(#Label#)的语法, 使用Label来选择和过滤Kubernetes 资源;

在里, 介绍了#Deployment#的使用, 介绍了Deployment与Replica Set、Pod的关系, 并展示了如何进行应用的版本回滚;

在里, 介绍了#Service#的使用,使用Replication Controller创建Pod, 并创建Service, 展示了从Service 调用应用的方法; 随后又展示了扩展 Pod的数量为2, 比较了Service和之前的不同, 基本展示了Cluster IP 类型的Service的基本用法.

在里, 介绍了#Namespace#的使用, 除了创建,列出系统的Namespace之外, 还说明Namespace 如何对资源进行隔离, 建立Development, Staging, Production等环境的方法.

在里, 介绍了#Service Discovery#的使用, 讲解了如何检查Kube-dns, 如何检查和使用Service的FQDN等知识, 对Kubernetes的DNS 系统有整体的理解.

在里, 介绍了#Port Forwards#, #端口转发#的用法, 在本地程序开发的时候, 使用端口转发可以简化本地测试的工作, 同时介绍了其他几种本地端口转发的用法.

在里, 介绍了#Probe#(#探针#)的知识, 介绍了livenessProbe 和readinessProbe的用法,同时介绍了Pod 容器中的几个状态变化, 以及2个容器生命周期回调接口.

在里, 介绍了#环境变量#的用法, 使用环境变量可以把Pod 定义的信息传递给运行其中的镜像.

在里, 我们介绍了#Volume#, 卷的用法, 主要展示了emptyDir卷的使用, emptyDir卷的生命周期是和Pod 生命周期同步的.

在里, 我们介绍了#Persistent Volume#, 也就是持久卷的用法,展示了当数据存入到PV 之后,数据超乎Pod 生命周期之外的情况.

在里, 介绍了Secret, 也就是机密信息的用法, 机密是绑定在命名空间里的, 在使用时候和Volume的用法一样, 可以被Pod 访问, 本篇展示了Opaque类型的Secret的用法.

在里, 介绍了日志(logging)的使用, 介绍了Kubernetes中基本日志记录的查看和常用的命令行参数,在理论部分展示了其他几种logging的使用.

在里, 介绍了Job, 也就是作业的使用, 介绍了Kubernetes中最基本的、非并行性的一次性运行的作业, 同时介绍了作业的基本概念和基本用法.

在里, 介绍了StatefulSet 的用法, 展示了StatefulSet 的创建, 扩容, 以及和Deployment的不同之处. 在最后的理论部分, 指出了在删除StatefulSet 里面的Pod 的注意事项.

今天, 我们将通过使用WordPress+Mysql, 搭建一个有状态应用,来进一步深入的学习StatefulSet的用法, 继续来学习Kubernetes 吧!

众所周知,Kubernetes处理无状态应用最为合适,Pod的短生命周期特性和无数据本地存储都是为无状态应用而生的,但是有状态应用是否也适合上Kubernetes呢?

答案是肯定的,Kubernetes的最初版本对复杂的有状态应用程序的支持有限,但是Kubernetes社区在这一领域一直在迅速创新, 不断增强对有状态应用的支持.

下面我们看看Kubernetes为了支持有状态应用做出了哪些增强或是创新?

从一开始,Kubernetes就通过PersistentVolume(PV)和 PersistentVolumeClaim(PVC)API支持持久卷。 PersistentVolume(PV)是具有独立于使用PV的任何单个Pod的生命周期的存储卷。这些卷由系统管理员创建,并且可以由各种存储系统(包括Amazon EBS或NFS或Ceph)支持。PersistentVolumeClaim(PVC)是用户的存储请求。该请求包括卷的大小和所需的访问模式-ReadWriteOnce,ReadOnlyMany或ReadWriteMany。

本篇描述了如何通过 Minikube 在 Kubernetes 上安装 WordPress 和 MySQL。这两个应用都使用 PersistentVolumes 和 PersistentVolumeClaims 保存数据, 这是使用Kubernetes 的PV 和PVC来支持有状态应用的例子.

PersistentVolume(PV)是一块集群里由管理员手动提供,或 kubernetes 通过 StorageClass 动态创建的存储。 PersistentVolumeClaim(PVC)是一个满足对 PV 存储需要的请求。PersistentVolumes 和 PersistentVolumeClaims 是独立于 Pod 生命周期而在 Pod 重启,重新调度甚至删除过程中保存数据。如果想快速了解PV和PVC, 可以参考文章.

WordPress

WordPress + Mysql

使用kustomization来创建资源

我们之前在创建资源, 如Pod, Deployment, Service等资源时, 都是专门编写相应的yaml文件, 然后通过kubectl apply -f 的形式来创建, 今天我们来使用kubectl kustomize 来创建相应的资源对象.

对于Kustomize, 我们可以简单的理解为, 这是一个Kubernetes 一个原生的配置管理工具, 可以用来创建其他资源, 比如Deploy, Service, Secret等, Kustomize的出现,简化了创建和管理Kubernetes资源的工作.

下面先来来看看怎么使用Kustomize 来创建Secret. 之前我们在创建Secret的时候, 用的是直接从文件读取, 当我们选择使用Kustomize的时候, 用法是这样的:

cat <<EOF >./kustomization.yamlsecretGenerator:- name: mysql-pass literals: - password=YOUR_PASSWORDEOF

在这里, 我们使用使用字符串entomb-pilfer-excrete-posey-innate-jehu-curve-HEADER 替换YOUR_PASSWORD,所以到目前为止我们的kustomization.yaml文件内容为:

secretGenerator:- name: mysql-pass  literals:  - password=entomb-pilfer-excrete-posey-innate-jehu-curve-HEADER

下面来看看Mysql的配置:

Github地址:

https://raw.githubusercontent.com/hintcnuie/kbe/main/specs/statefulset/mysql-deployment.yaml

文件内容:

apiVersion: v1kind: Servicemetadata: name: wordpress-mysql labels: app: wordpressspec: ports: - port: 3306 selector: app: wordpress tier: mysql clusterIP: None---apiVersion: v1kind: PersistentVolumeClaimmetadata: name: mysql-pv-claim labels: app: wordpressspec: accessModes: - ReadWriteOnce resources: requests: storage: 20Gi---apiVersion: apps/v1kind: Deploymentmetadata: name: wordpress-mysql labels: app: wordpressspec: 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

在上面定义中, manifest 文件描述了单实例 MySQL 部署。MySQL 容器将 PersistentVolume 挂载在/var/lib/mysql。 MYSQL_ROOT_PASSWORD环境变量设置来自 Secret 的数据库密码。

下面来看看Wordpress的配置.

Github地址:

https://raw.githubusercontent.com/hintcnuie/kbe/main/specs/statefulset/wordpress-deployment.yaml

文件内容:

apiVersion: v1kind: Servicemetadata: name: wordpress labels: app: wordpressspec: ports: - port: 80 selector: app: wordpress tier: frontend type: LoadBalancer---apiVersion: v1kind: PersistentVolumeClaimmetadata: name: wp-pv-claim labels: app: wordpressspec: accessModes: - ReadWriteOnce resources: requests: storage: 20Gi---apiVersion: apps/v1kind: Deploymentmetadata: name: wordpress labels: app: wordpressspec: 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

上面的manifest 文件描述了单实例 WordPress 部署。WordPress 容器将网站数据文件位于/var/www/html的 PersistentVolume。WORDPRESS_DB_HOST环境变量集上面定义的 MySQL Service 的名称,WordPress 将通过 Service 访问数据库。WORDPRESS_DB_PASSWORD环境变量设置从 Secret kustomize 生成的数据库密码。

wordpress 和mysql的整体结构如下:

最后, 再把这两个文件添加到kustomize 文件中:

下载 MySQL deployment 配置文件

curl -LO https://raw.githubusercontent.com/hintcnuie/kbe/main/specs/statefulset/mysql-deployment.yaml

下载 WordPress 配置文件

curl -LO https://raw.githubusercontent.com/hintcnuie/kbe/main/specs/statefulset/wordpress-deployment.yaml

补充到 kustomization.yaml 文件

cat <<EOF >>./kustomization.yamlresources: - mysql-deployment.yaml - wordpress-deployment.yamlEOF

最后的kustomization.yaml文件如下:

下载:

curl -LO https://raw.githubusercontent.com/hintcnuie/kbe/main/specs/statefulset/kustomization.yaml

文件内容:

secretGenerator:- name: mysql-pass  literals:  - password=entomb-pilfer-excrete-posey-innate-jehu-curve-HEADERresources:  - mysql-deployment.yaml  - wordpress-deployment.yaml    

三个文件都已经下载完毕:

创建kustomization资源

下面来创建这些资源对象:

$ kubectl apply -k ./secret/mysql-pass-tcm545mb76 createdservice/wordpress-mysql createdservice/wordpress createddeployment.apps/wordpress-mysql createddeployment.apps/wordpress createdpersistentvolumeclaim/mysql-pv-claim createdpersistentvolumeclaim/wp-pv-claim created

现在,来可以验证所有对象是否存在。

通过运行以下命令验证 Secret 是否存在:

$ kubectl get secretNAME TYPE DATA AGEmysql-pass-tcm545mb76 Opaque 1 77s$ kubectl describe secret mysql-pass-tcm545mb76Name: mysql-pass-tcm545mb76Namespace: defaultLabels: <none>Annotations: <none>Type: OpaqueData====

解码Secret

注意, 在这里使用kubectl describe secret 不能够查看Secret 中的密码, 这是为了安全起见, 为了防止 Secret 被意外暴露给旁观者或存储在终端日志中, 如果真的需要解码Secret, 需要使用如下两个语句:

$ kubectl get secret mysql-pass-tcm545mb76 -o jsonpath='{.data} '{"password":"ZW50b21iLXBpbGZlci1leGNyZXRlLXBvc2V5LWlubmF0ZS1qZWh1LWN1cnZlLUhFQURFUg=="}$ echo 'ZW50b21iLXBpbGZlci1leGNyZXRlLXBvc2V5LWlubmF0ZS1qZWh1LWN1cnZlLUhFQURFUg==' | base64 --decodeentomb-pilfer-excrete-posey-innate-jehu-curve-HEADER

最后我们终于成功地解码了Secret, 是不是跟最开始的设置一样呢?!

验证是否已动态配置 PersistentVolume:kubectl get pvc

$ kubectl get pvcNAME             STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGEmysql-pv-claim   Bound    pvc-a4fce9c3-f71a-4a6a-9e58-d7eae8d3504b   20Gi       RWO            standard       13mwp-pv-claim      Bound    pvc-8c58331e-71a6-44f7-bac4-b06c8455e0f6   20Gi       RWO            standard       13m

通过运行以下命令来验证 Pod 是否正在运行:kubectl get pods

$ kubectl get podsNAME                               READY   STATUS    RESTARTS   AGEwordpress-69887cf9f7-bgdzp         1/1     Running   1          13mwordpress-mysql-57f7b8b5d5-vk6g4   1/1     Running   0          13m

说明: 等待 Pod 状态变成RUNNING可能会花费几分钟。

通过运行以下命令来验证 Service 是否正在运行:kubectl get services wordpress

$ kubectl get svc wordpressNAME        TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGEwordpress   LoadBalancer   10.107.214.220   <pending>     80:12689/TCP   18m

说明: Minikube 只能通过 NodePort 公开服务。EXTERNAL-IP 始终处于挂起状态

运行以下命令以获取 WordPress 服务的 IP 地址:minikube service wordpress --url

$ minikube service wordpress --urlhttp://10.0.2.15:12689

复制 IP 地址,然后将页面加载到浏览器中来查看我们的wordpress站点。

应该看到类似于以下屏幕截图的 WordPress 设置页面。

完成设置界面之后, 下面是wordpress的最终页面:

清理现场

最后,运行一下命令删除 Secret,Deployments,Services and PersistentVolumeClaims:

$ kubectl delete -k ./secret "mysql-pass-tcm545mb76" deletedservice "wordpress-mysql" deletedservice "wordpress" deleteddeployment.apps "wordpress-mysql" deleteddeployment.apps "wordpress" deletedpersistentvolumeclaim "mysql-pv-claim" deletedpersistentvolumeclaim "wp-pv-claim" deleted

一键删除, 嗯, kustomize 真的不错!

来学习下相应的理论知识吧!

先来看看kustomize 是什么东东.

Kustomize : 声明式管理Kubernetes 对象

Kustomize 是kubernetes 原生的配置管理工具,用来通过 kustomization 文件, 以一种以无模板方式,来定制 Kubernetes 对象。

kustomize 使用 kubernetes 原生概念帮助创建并复用资源配置(YAML),允许用户以一个应用描述文件 (YAML 文件)为基础(Base YAML),然后通过 Overlay 的方式生成最终部署应用所需的描述文件。

Kustomize 提供以下功能特性来管理 应用配置文件:

从其他来源生成资源为资源设置贯穿性(Cross-Cutting)字段组织和定制资源集合

痛点:

一般应用都会存在多套部署环境:开发环境、测试环境、生产环境,多套环境意味着存在多套 kubernetes 应用资源 YAML。而这么多套 YAML 之间只存在微小配置差异,比如镜像版本不同、Label 不同等,而这些不同环境下的YAML 经常会因为人为疏忽导致配置错误。

再者,多套环境的 YAML 维护通常是通过把一个环境下的 YAML 拷贝出来然后对差异的地方进行修改。一些类似 Helm 等应用管理工具需要额外学习DSL 语法。

总结以上,在 kubernetes 环境下存在多套环境的应用,经常遇到以下几个问题:

如何管理不同环境或不同团队的应用的 Kubernetes YAML 资源如何以某种方式管理不同环境的微小差异,使得资源配置可以复用,减少 copy and change 的工作量如何简化维护应用的流程,不需要额外学习模板语法

kustomize示意

从上面的kustomize 示意图中我们可以看到, Kustomize 通过以下几种方式解决了上述问题:

kustomize 通过 Base & Overlays 方式(下文会说明)方式维护不同环境的应用配置kustomize 使用 patch 方式复用 Base 配置,并在 Overlay 描述与 Base 应用配置的差异部分来实现资源复用kustomize 管理的都是 Kubernetes 原生 YAML 文件,不需要学习额外的 DSL 语法

用法

从 1.14 版本开始,kubectl 也开始支持使用 kustomization 文件来管理 Kubernetes 对象。 要查看包含 kustomization 文件的目录中的资源,执行下面的命令:

kubectl kustomize <kustomization_directory>

要应用这些资源,使用参数 --kustomize 或 -k 标志来执行 kubectl apply:

kubectl apply -k <kustomization_directory>回顾

今天就先写到这里, 今天主要介绍了使用PV和PVC来建立有状态应用--Wordpress+Mysql的过程, 首先讲解了kustomize工具的使用, 然后使用Kustomize来搭建Wordpress 和Mysql实例.

使用PV和PVC来搭建有状态应用还是比较简单的方案, 后续会陆续介绍使用StatefulSet 来搭建有状态应用的例子, 不断学习吧!

阳春布德泽,万物生光辉

0 阅读:0

查理谈科技

简介:感谢大家的关注