Kubernetes(也称为 k8s)是一个开源编排系统。它允许用户以最少的停机时间部署、扩展和管理容器化应用程序。在本教程中,您将学习如何部署一个 PHP 应用程序到 Kubernetes 集群上。
Nginx 作为代理指向 PHP-FPM ,同时运行 PHP 应用程序。在单个容器中管理这两个服务是一个困难的过程。Kubernetes 帮助我们在两个不同的容器中管理它们,并减少了麻烦。它还允许用户重用容器,而无需担心为每个新版本的 PHP/Nginx 构建其容器镜像。
您将在两个独立的容器中运行您的应用程序和代理服务。本教程还将深入介绍如何使用本地存储来创建 Persistent Volume (PV) 和 Persistent Volume Claim (PVC)。然后,您将使用此 PVC 将配置文件和代码保留在容器镜像之外。完成本教程后,您将能够将 Nginx 镜像重用于需要代理服务器的其他应用程序。您可以通过传递配置来实现这一点,而无需为此重新构建镜像。
Prerequisites
- 对 Kubernetes (k8s) 及其对象的基本了解。请参考此指南以获取 Kubernetes 生态系统的详细概述.
- 一个在 Ubuntu 18.04 上运行的 Kubernetes 集群。按照本教程来 使用 kubeadm 创建您的 Kubernetes 集群.
- 此外,您需要将应用程序代码托管在公共 URL 上,例如 GitHub.
步骤 1:创建 PHP-FPM 和 Nginx 服务
此步骤将帮助您创建 PHP-FPM 和 Nginx 服务。任何服务都提供对集群内一组 Pod 的访问。集群中存在的所有服务都可以通过其名称相互通信,而无需 IP 地址。PHP-FPM 服务和 Nginx 服务将分别提供对 PHP-FPM 和 Nginx Pod 的访问。
您需要告诉 PHP-FPM 服务如何找到 Nginx Pod,因为它是 PHP-FPM Pod 的代理。为此,您将利用 Kubernetes’ 自动服务发现,并使用易于理解的名称将请求路由到相应的服务。
为了创建任何服务,您需要创建一个 YAML 文件,其中包含对象定义。此 YAML 文件至少包含以下标签:
apiVersion:定义所属的 Kubernetes API 版本。kind:此 YAML 文件创建的 Kubernetes 对象的种类。例如:service、job或pod.metadata:对象的名称以及用户可能想要应用于此对象的不同labels都定义在此标签下。spec:此标签包含对象的规格说明,例如环境变量(ENV)、要使用的容器镜像、可访问容器服务的端口。
创建 PHP-FPM 服务
首先,您应该创建一个目录来保存您的 Kubernetes 对象定义。登录到您的主节点并创建一个名为 “definitions:”
|
1 |
mkdir definitions |
将目录切换到 definitions 目录:
|
1 |
cd definitions |
接下来,创建您的 PHP-FPM 服务文件,命名为 php_service.yaml 文件:
|
1 |
nano php_fpm_service.yaml |
之后,在 apiVersion 和 kind 中设置 php_fpm_service.yaml 文件:
|
1 2 |
apiVersion: v1 kind: Service |
将您的服务命名为 php 或 php-fpm ,因为它将提供对您的 PHP-FPM 应用程序的访问:
|
1 2 3 |
… Metadata: name: php |
将您的 php 服务标记为 tier: backend ,因为 PHP 应用程序将在此服务后运行:
|
1 2 3 |
… labels: tier: backend |
服务使用 selector 标签来确定要访问哪些 Pod。任何与这些标签匹配的 Pod,无论该 Pod 是何时创建的,都会被提供服务。您将在本教程稍后学习如何向 Pod 添加标签。
包含 tier: backend 标签,该标签将您的 pod 分配到后端层,以及 app: php-fpm 标签,以指示该 pod 运行 PHP-FPM 应用程序。您必须在以下部分之后添加这些标签:metadata 部分:
|
1 2 3 4 5 |
… spec: selector: app: php-fpm tier: backend |
接下来,您需要声明用于访问此 php-fpm 服务的端口,位于 spec 之下。您可以添加您选择的任何端口,但在本教程中我们将使用端口 9000:
|
1 2 3 4 |
... ports: - protocol: TCP port: 9000 |
完成上述步骤后,您的 php_fpm_service.yaml 文件将如下所示:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
apiVersion: v1 kind: Service metadata: name: php labels: tier: backend spec: selector: app: php tier: backend ports: - protocol: TCP port: 9000 |
输入 Ctrl + O 保存文件,然后输入 Ctrl + X 退出 nano.
应用 kubectl 命令创建 PHP 服务
创建服务的对象定义后,运行 kubectl apply 命令,并使用 -f 参数指定您的 php_fpm_service.yaml 文件:
|
1 |
kubectl apply -f php_fpm_service.yaml |
上述命令的输出应该为:
|
1 |
service/php created |
运行以下命令以验证您的 php-fpm 服务是否正在运行:
|
1 |
$ kubectl get svc |
您将能够看到 php-fpm 服务已启动并运行:
|
1 2 3 |
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 10m php ClusterIP 10.100.59.238 <none> 9000/TCP 5m |
创建 Nginx 服务
既然您的 PHP-FPM 服务已经准备就绪,现在是时候创建您的 Nginx 服务了。在编辑器中为该服务创建并打开一个新的 YAML 文件,命名为 nginx_service.yaml :
|
1 |
$ nano nginx_service.yaml |
将此服务命名为 nginx ,因为它将针对 Nginx pod。此服务也属于后端,因此您应该为其添加一个 tier: backend 标签:
|
1 2 3 4 5 6 |
apiVersion: v1 kind: Service metadata: name: nginx labels: tier: backend |
就像我们在 php-fpm 服务中所做的那样,添加选择器标签 app: nginx 和 tier: backend 以针对这些 pod。添加默认的 HTTP 端口 80 以访问此服务:
|
1 2 3 4 5 6 7 8 |
... spec: selector: app: nginx tier: backend ports: - protocol: TCP port: 80 |
Nginx 服务可以通过公网 IP 地址在互联网上公开访问。您可以将工作节点的 IP 添加为 your_public_ip。在 spec.externalIPs:
|
1 2 3 4 5 |
... spec: externalIPs: - your_public_ip |
完成上述所有步骤后,您的 nginx_service.yaml 文件应该如下所示:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
apiVersion: v1 kind: Service metadata: name: nginx labels: tier: backend spec: selector: app: nginx tier: backend ports: - protocol: TCP port: 80 externalIPs: - your_public_ip |
添加上述所有必需参数后,保存并关闭文件。
应用 kubectl 命令创建 Nginx 服务
|
1 |
kubectl apply -f nginx_service.yaml |
|
1 |
service/nginx 已创建 |
|
1 |
$ kubectl get svc |
|
1 2 3 4 |
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 13m nginx ClusterIP 10.102.160.47 your_public_ip 80/TCP 50s php ClusterIP 10.100.59.238 <none> 9000/TCP 8m |
|
1 |
$ kubectl delete svc/service_name |
步骤 2:创建本地存储和持久卷
Kubernetes 提供了各种存储插件,可帮助您为环境创建存储空间。本步骤将指导您如何创建一个本地 StorageClass 以及如何进一步使用此 Storage Class 来创建持久卷(Persistent Volume)。
创建本地存储
创建一个文件,例如 storageClass.yaml,在您的编辑器中:
|
1 |
$nano storageClass.yaml |
将 kind 添加为 "storageClass",将 apiVersion 添加为 "storage.k8s.io/v1",如下所示:
|
1 2 |
kind: StorageClass apiVersion: storage.k8s.io/v1 |
将此 StorageClass 命名为 "my-local-storage",并添加 provisioner 和 volumeBindingMode,如下所示:
|
1 2 3 4 5 |
… metadata: name: my-local-storage provisioner: kubernetes.io/no-provisioner volumeBindingMode: Immediate |
保存并退出文件,您最终的 storageClass.yaml 文件应该如下所示:
|
1 2 3 4 5 6 |
kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: my-local-storage provisioner: kubernetes.io/no-provisioner volumeBindingMode: WaitForFirstConsumer |
现在,通过运行 kubectl create 命令来创建 StorageClass,如下所示:
|
1 |
$ kubectl create -f storageClass.yaml |
运行上述命令后,您应该会得到以下输出:
|
1 |
storageclass.storage.k8s.io/my-local-storage 已创建 |
创建本地持久卷
创建本地存储后,您可以创建本地持久卷(Persistent Volume)。持久卷(也称为 PV)是特定大小的块存储,独立于 Pod 的生命周期。本地持久卷无非是 Kubernetes 集群节点上可用的本地磁盘或目录。该本地持久卷允许其用户通过使用本地持久卷声明(Persistent Volume Claim)以非常简单且可移植的方式访问本地存储。您可以使用我们刚刚创建的此存储类来创建此本地持久卷。打开一个文件,例如 persistentVolume.yaml,在您的编辑器中:
|
1 |
$ nano persistentVolume.yaml |
给这个持久卷起一个名字,例如 "my-local-pv":
|
1 2 3 4 |
apiVersion: v1 kind: PersistentVolume metadata: name: my-local-pv |
在创建本地持久卷时,您可以根据您的使用情况添加存储容量。在本教程中,我们将使用 5 Gi 作为存储空间:
|
1 2 3 4 |
… spec: capacity: storage: 5Gi |
添加 accessModes、persistentVolumeReclaimPolicy,并提供与 storageClass.yaml 中使用的相同的 storageClassName:
|
1 2 3 4 5 |
… accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain storageClassName: my-local-storage |
添加 local.path 到您的持久卷,如下所示:
|
1 2 3 |
… local: path: /mnt/disk/vol |
添加所有必需的字段后,您的 persistentVolume.yaml 文件应该像这样:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
apiVersion: v1 kind: PersistentVolume metadata: name: my-local-pv spec: capacity: storage: 5Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain storageClassName: my-local-storage local: path: /mnt/disk/vol nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - worker |
准备本地卷
现在,我们需要在 “worker” 节点上准备一个本地卷,正如我们在 persistentVolume.yaml 文件中添加的那样。在您配置了 persistentVolume 的节点上运行以下命令。在这种情况下,它是 “worker” 节点:
|
1 2 3 |
$ DIRNAME="vol" $ mkdir -p /mnt/disk/$DIRNAME $ chmod 777 /mnt/disk/$DIRNAME |
在您的 persistentVolume.yaml 文件所在的主节点上运行以下命令:
|
1 |
kubectl create -f persistentVolume.yaml |
您应该会得到以下输出:
|
1 |
persistentvolume/my-local-pv created |
由于您已成功创建本地存储和持久卷(Persistent Volume),您现在可以继续创建持久卷声明(Persistent Volume Claim)来保存您的应用程序代码和配置文件。
步骤 3:创建持久卷
在您管理或更新 Pod 时,需要确保您的应用程序代码安全。为此,您将使用在上一步中创建的持久卷(Persistent Volume),该卷通过使用持久卷声明(Persistent Volume Claim,简称 PVC)进行访问。此 PVC 将 PV 挂载到所需的路径上。
打开一个文件,例如 code_volume.yaml,在您的编辑器中:
|
1 |
$ nano code_volume.yaml |
通过向您的文件添加以下参数和值,将您的 PVC 命名为 code:
|
1 2 3 4 |
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: code |
PVC 的 spec 部分包含以下项:
- accessModes:此字段有以下几种可能的值:
- ReadWriteOnce – 为单个节点挂载具有读写权限的卷。
- ReadOnlyMany – 为多个节点挂载仅具有只读权限的卷。
- ReadWriteMany – 为多个节点挂载具有读写权限的卷。
- resources:定义所需的存储空间。
由于本地存储仅挂载到单个节点,因此您需要将 accessMode 设置为 ReadWriteOnce。在本教程中,您只需添加一小部分应用程序代码,因此 1GB 的存储空间就足够了。但是,如果您希望存储更多的数据或代码,可以根据您的要求修改 storage 参数。请注意,卷创建后,您可以增加存储大小。但是,不支持减少存储大小:
|
1 2 3 4 5 6 7 |
... spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi |
现在,声明 Kubernetes 集群将用于分配给卷的存储类。在此处将上一步中创建的 my-local-storage 存储类用于您的 storageClassName:
|
1 2 |
... storageClassName: my-local-storage |
完成上述步骤后,您的 code_volume.yaml 文件应该像这样:
|
1 2 3 4 5 6 7 8 9 10 11 |
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: code spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi storageClassName: my-local-storage |
现在保存并退出文件。
创建 PVC
通过运行 kubectl apply 命令来创建 code PVC:
|
1 |
$ kubectl apply -f code_volume.yaml |
您应该会得到以下输出,表明该对象已成功创建,并准备好将您的 1GB PVC 挂载为卷:
|
1 |
persistentvolumeclaim/code created |
您可以执行以下命令来检查可用的持久卷 (PV):
|
1 |
$ kubectl get pv |
上述命令的输出应该如下所示:
|
1 2 |
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-ca4df10f-ab8c-11e8-b89d-12331aa95b13 1Gi RWO Delete Bound default/code do-block-storage 2m |
除回收策略 (Reclaim Policy) 和状态 (Status) 外,上述所有字段都是配置文件的概述。回收策略定义了在删除访问 PV 的 PVC 后,PV 会发生什么。值 Delete 会将 PV 从 Kubernetes 集群以及存储基础设施中移除。您可以参考 Kubernetes PV 文档 以清楚地了解回收策略和状态。
由于您已成功使用本地存储创建了持久卷,现在可以使用 Deployment 创建 Pod 了。
第 4 步:为您的 PHP-FPM 应用程序创建 Deployment
此步骤将帮助您使用 Deployment 创建 PHP-FPM Pod。Deployment 使用 ReplicaSet 提供了一种创建、更新和管理 Pod 的稳定方法。Deployment 会自动将其 Pod 回滚到以前的镜像。
Deployment 中的 spec.selector 键列出了它管理的所有 Pod 的标签。它还使用 template 键来创建所需的 Pod。
在此步骤中,我们还将介绍 Init 容器 的应用。Init 容器在 Pod 模板中指定的常规容器之前运行一些命令。在这里,Init 容器将使用 GitHub Gist (https://gist.github.com/) 来获取一个示例 index.php 文件。示例文件的内容为:
|
1 2 |
<?php echo phpinfo(); |
创建 PHP Deployment
在编辑器中打开一个名为 php_deployment.yaml 的新文件以创建您的 Deployment:
|
1 |
$ nano php_deployment.yaml |
现在,将 Deployment 对象命名为 PHP,因为此 Deployment 将管理您的 PHP-FPM pod。添加标签 tier: backend,因为该 pod 将属于后端层:
|
1 2 3 4 5 6 |
apiVersion: apps/v1 kind: Deployment metadata: name: php labels: tier: backend |
使用 replica 参数,指定应创建的此 pod 的副本数量。副本数量可能会根据您的需求和可用资源而有所不同。在本教程中,您将仅创建 pod 的一个副本:
|
1 2 3 4 |
... spec: replicas: 1 |
添加 app: php 和 tier:backend 标签在 selector 键下,这表示此 Deployment 将管理与这两个标签匹配的 pod:
|
1 2 3 4 5 |
... selector: matchLabels: app: php tier: backend |
现在,您的 pod’s 对象定义需要在您的 Deployment spec 下有一个模板。此模板定义了创建 pod 所需的规范。首先,添加为 php 服务选择器和 Deployment 的 matchLabels 指定的标签。然后添加 app:php 和 tier:backend 在 template.metadata.labels:
|
1 2 3 4 5 6 7 |
... template: metadata: labels: app: php tier: backend |
首先,您需要指定容器将访问的所有卷。将此卷命名为 code,因为您之前创建了一个名为 code 的 PVC 来保存您的应用程序代码:
|
1 2 3 4 5 6 |
... spec: volumes: - name: code persistentVolumeClaim: claimName: code |
接下来,指定容器名称以及您要在 pod 内运行的镜像。Docker 商店中有各种可用的镜像(https://hub.docker.com/explore/),但在本教程中,我们将使用 php:7-fpm 镜像:
|
1 2 3 4 |
... containers: - name: php image: php:7-fpm |
现在,挂载容器需要访问的卷。由于此容器将运行您的 php 代码,它将需要访问在上一步中创建的 code 卷。在这一步中,您还将学习如何使用 Init 容器复制您的应用程序代码。
为了下载代码,本教程将指导您如何使用带有 busybox 的单个 Init 容器。Busybox 是一个带有 wget 工具的小型容器,您将使用它来实现此目的。
首先,在 spec.template.spec 下添加您的 initContainer 并指定 busybox 镜像:
|
1 2 3 4 |
... initContainers: - name: install image: busybox |
然后,为了在 code 卷中下载代码,您的 Init 容器将需要访问它。将卷 code 挂载到 /code 路径下,位于 spec.template.spec.initContainers:
|
1 2 3 4 |
... volumeMounts: - name: code mountPath: /code |
每个 Init 容器都需要运行一个命令。此 Init 容器将使用 wget 从 code 下载 Github 到 /code 目录中。您可以传递一个 -O 选项来为这个下载的文件命名,您可以将此文件命名为 index.php.
此外,在 install 容器下添加以下行,位于 spec.template.spec.initContainers:
|
1 2 3 4 5 6 |
... command: - wget - "-O" - "/code/index.php" - https://raw.githubusercontent.com/do-community/php-kubernetes/master/index.php |
完成所有这些步骤后,您的 php_deployment.yaml 文件应该像这样:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
apiVersion: apps/v1 kind: Deployment metadata: name: php labels: tier: backend spec: replicas: 1 selector: matchLabels: app: php tier: backend template: metadata: labels: app: php tier: backend spec: volumes: - name: code persistentVolumeClaim: claimName: code containers: - name: php image: php:7-fpm volumeMounts: - name: code mountPath: /code initContainers: - name: install image: busybox volumeMounts: - name: code mountPath: /code command: - wget - "-O" - "/code/index.php" - https://raw.githubusercontent.com/do-community/php-kubernetes/master/index.php |
您现在可以保存文件并退出。接下来,使用 kubectl apply 命令创建您的 PHP-FPM Deployment:
|
1 |
$ kubectl apply -f php_deployment.yaml |
成功创建 Deployment 后,您应该会看到以下输出:
|
1 |
deployment.apps/php created |
此 Deployment 首先会下载指定的镜像,然后它将从您的 PersistentVolume 请求 PersistentVolumeClaim,然后运行您的 initContainers。完成此步骤后,容器将运行并将卷挂载到指定的挂载点。完成所有这些步骤后,您的 pod 将启动并运行。
您可以运行以下命令来查看您的 Deployment:
|
1 |
$ kubectl get deployments |
运行上述命令后,您应该会得到以下输出:
|
1 2 |
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE php 1 1 1 0 19s |
您可以通过此输出了解 Deployment 的当前状态。Deployment 是一个维护期望状态的控制器。DESIRED 字段指定它有 1 个名为 php 的 pod 副本。CURRENT 字段表示当前正在运行的 DESIRED 状态的副本数量。对于健康的 pod,这应该与 DESIRED 状态相匹配。您可以在 Kubernetes Deployments 文档.
中了解有关其余字段的更多信息。之后,要检查正在运行的 pod 的状态,您可以运行以下命令:
|
1 |
$ kubectl get pods |
此命令的输出可能会根据您创建 Deployment 以来所经过的时间而有所不同。如果在创建 Deployment 后不久运行,输出将类似于:
|
1 2 |
NAME READY STATUS RESTARTS AGE php-5d8f6bbf7f-56df2 0/1 Init:0/1 0 9s |
说明:
这些列表示的信息如下:
- Ready:运行此 pod 的当前/期望副本数量。
- Status:您的 pod 的状态。Init:0/1 表示 Init 容器正在运行,且 1 个 Init 容器中有 0 个已运行完毕。
- Restarts:这表示此进程为了启动 pod 而重启的次数。
您的 pod 可能需要几分钟时间才能将状态更改为 podInitializing,具体取决于启动脚本的复杂程度:
|
1 2 |
NAME READY STATUS RESTARTS AGE php-5d8f6bbf7f-56df2 0/1 podInitializing 0 39s |
这表示 Init 容器已成功运行,现在容器正在初始化:
|
1 2 |
NAME READY STATUS RESTARTS AGE php-5d8f6bbf7f-56df2 1/1 Running 0 4m10s |
如您所见,现在您的 pod 已经启动并运行。但是,如果您的 pod 没有启动,您可以运行以下命令进行调试:
1. 查看 pod 的详细信息:
|
1 |
$ kubectl describe pods pod-name |
2. 查看 pod 的日志:
|
1 |
$ kubectl logs pod-name |
3. 查看 pod 中特定容器的日志:
|
1 |
$ kubectl logs pod-name container-name |
恭喜!您已成功挂载应用程序代码,并且 PHP-FPM 服务已准备好处理连接。同样,您可以创建您的 Nginx 部署。
第 5 步:创建您的 Nginx 部署
本步骤将指导您如何使用 ConfigMap。一个 ConfigMap 以键值格式保存所有所需的配置,这些配置将在其他 Kubernetes 对象定义中使用。通过这种方法,您可以根据需要灵活地重用或将 Nginx 镜像更换为其他版本。您可以更新 ConfigMap,它会自动将这些更改复制到挂载了此 ConfigMap.
首先,在编辑器中打开 nginx_configmap.yaml 文件:
|
1 |
$ nano nginx_configMap.yaml |
现在,将此 ConfigMap 命名为 nginx-config 并将其添加到 tier: backend 微服务:
|
1 2 3 4 5 6 |
apiVersion: v1 kind: ConfigMap metadata: name: nginx-config labels: tier: backend |
此外,您可以将数据添加到 ConfigMap。添加一个名为 config 的键,并将所有 Nginx 配置文件内容作为值添加。
由于 Kubernetes 可以将请求路由到服务的相应主机,因此您可以在 fastcgi_pass 参数下输入 PHP-FPM 服务的名称,而不是其 IP 地址。将以下代码行添加到您的 nginx_configMap.yaml 文件中:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
... data: config : | server { index index.php index.html; error_log /var/log/nginx/error.log; access_log /var/log/nginx/access.log; root /code; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass php:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; } } |
完成后,您的 nginx_configMap.yaml 文件将如下所示:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
apiVersion: v1 kind: ConfigMap metadata: name: nginx-config labels: tier: backend data: config : | server { index index.php index.html; error_log /var/log/nginx/error.log; access_log /var/log/nginx/access.log; root /code; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass php:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; } } |
您现在可以保存并退出编辑器。现在执行 kubectl apply 命令来创建 ConfigMap:
|
1 |
$ kubectl apply -f nginx_configMap.yaml |
之后,您应该在屏幕上看到以下输出:
|
1 |
configmap/nginx-config created |
您已成功创建 Nginx Configmap。现在您可以创建 Nginx Deployment。
创建 Nginx Deployment
首先,您可以在编辑器中创建一个名为 nginx_deployment.yaml 的新文件:
|
1 |
$ nano nginx_deployment.yaml |
将此 Deployment 命名为 nginx 并向其添加 tier: backend 标签:
|
1 2 3 4 5 6 7 |
apiVersion: apps/v1 kind: Deployment metadata: name: nginx labels: tier: backend |
之后,通过在 Deployment spec 中添加 replica 字段来指定副本数量,并向其添加 app: nginx 和 tier: backend 标签:
|
1 2 3 4 5 6 7 |
... spec: replicas: 1 selector: matchLabels: app: nginx tier: backend |
同样,添加 pod 模板。确保添加与 Deployment 的 selector.matchLabels 中相同的标签。您可以添加以下内容:
|
1 2 3 4 5 6 |
... template: metadata: labels: app: nginx tier: backend |
通过在以下位置下方添加以下参数,使 Nginx 能够访问之前创建的 code PVC:spec.template.spec.volumes:
|
1 2 3 4 5 6 |
... spec: volumes: - name: code persistentVolumeClaim: claimName: code |
|
1 2 3 4 5 6 7 |
... - name: config configMap: name: nginx-config items: - key: config path: site.conf |
警告:如果未指定文件,键的内容将替换卷的 mountPath。换句话说,如果未明确指定路径,您将丢失目标文件夹中的所有内容。
现在,指定您要在 pod 中使用的名称、镜像和端口。在这里,我们将使用 nginx:1.7.9 镜像和端口 80。将它们添加在以下位置下方:spec.template.spec 部分:
|
1 2 3 4 5 6 |
... containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80 |
此外,将代码卷挂载到 /code,因为 Nginx 和 PHP-FPM 都需要访问相同路径下的文件:
|
1 2 3 4 |
... volumeMounts: - name: code mountPath: /code |
The nginx-1.7.9 镜像会自动加载 /etc/nginx/conf.d 文件夹。现在,如果我们在此目录中挂载配置卷,它将创建 /etc/nginx/conf.d/site.conf。在 volumeMount 部分下添加以下内容:
|
1 2 3 |
... - name: config mountPath: /etc/nginx/conf.d |
完成上述所有步骤后,您的 nginx_deployment.yaml 文件应该像这样:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
apiVersion: apps/v1 kind: Deployment metadata: name: nginx labels: tier: backend spec: replicas: 1 selector: matchLabels: app: nginx tier: backend template: metadata: labels: app: nginx tier: backend spec: volumes: - name: code persistentVolumeClaim: claimName: code - name: config configMap: name: nginx-config items: - key: config path: site.conf containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80 volumeMounts: - name: code mountPath: /code - name: config mountPath: /etc/nginx/conf.d |
您现在可以保存并退出文件,然后通过运行以下命令来创建 Nginx Deployment:
|
1 |
$ kubectl apply -f nginx_deployment.yaml |
成功执行该命令后,您应该会看到以下输出:
|
1 |
deployment.apps/nginx created |
您可以通过执行以下命令来列出所有 Deployment:
|
1 |
$ kubectl get deployments |
您现在应该可以看到 Nginx 和 PHP-FPM Deployment:
此外,您可以执行以下命令来列出由上述两个 Deployment 管理的 pod:
|
1 |
$ kubectl get pods |
您将看到您的两个 pod 都在运行,如下所示:
既然此时您的所有 Kubernetes 对象都处于活动状态,您现在可以在浏览器上访问 Nginx 服务了。
运行以下命令来列出服务:
|
1 |
$ kubectl get services -o wide |
现在,使用 Nginx 服务的这个 External IP,您可以通过在浏览器中输入 http://your_public_ip 来访问您的服务器。您应该能够看到 php_info() 的输出,这证实了您的 Kubernetes 服务已启动并运行。
结论
在本教程中,为了独立管理您的 PHP-FPM 和 Nginx 服务,您对这两个服务进行了容器化。通过这样做,不仅可以提高项目的可扩展性,还可以高效地利用资源。您还学习了如何创建本地存储和持久卷(Persistent Volume),以便将应用程序代码存储在卷上,并在将来能够轻松更新您的服务。通过这样做,您提高了代码的可维护性和可用性。
此外,您可以查看我们博客上其他专注于 Docker 和 Kubernetes 的教程,网址在 我们的博客:
- 了解 Kubernetes
- 如何在 Ubuntu 18.04 上使用 Kubeadm 创建 Kubernetes 集群
- 清理 Docker 资源 – 镜像、容器和数据卷
- 使用 Docker Compose 部署 Laravel、Nginx 和 MySQL
- 如何在公有云的 Ubuntu 上安装 & 操作 Docker
祝您计算愉快!



评论
暂无评论。发表第一条评论吧。