如何在 Ubuntu 16.04 上使用 Kubernetes 部署 PHP 应用程序如何在 Ubuntu 16.04 上使用 Kubernetes 部署 PHP 应用程序如何在 Ubuntu 16.04 上使用 Kubernetes 部署 PHP 应用程序如何在 Ubuntu 16.04 上使用 Kubernetes 部署 PHP 应用程序
  • 文章
  • 正则表达式
    • 工具
  • 登录
找到的结果: {phrase} (显示: {results_count} 共: {results_count_total})
显示: {results_count} 共: {results_count_total}

加载更多搜索结果...

搜索范围
模糊匹配
搜索标题
搜索内容
发表 admin at 2025年2月28日
类别
  • 未分类
标签

如何在 Ubuntu 16.04 上使用 Kubernetes 部署 PHP 应用程序

作者选择了 Write for DOnations 计划。

介绍

Kubernetes 是一个开源的容器编排系统。它允许您创建、更新和缩放容器,而无需担心停机。

为了运行 PHP 应用程序,Nginx 充当 PHP-FPM 的代理。将此设置容器化在单个容器中可能是一个繁琐的过程,但 Kubernetes 将有助于在单独的容器中管理这两种服务。使用 Kubernetes 将使您的容器保持可重用和可交换,并且您不必在每次出现新版本的 Nginx 或 PHP 时都重建容器映像。

在本教程中,您将在 Kubernetes 集群上部署一个 PHP 7 应用程序,并在单独的容器中运行 Nginx 和 PHP-FPM。您还将学习如何使用 DigitalOcean 的块存储系统将配置文件和应用程序代码保存在容器镜像之外。这种方法将允许您通过传递配置卷将 Nginx 映像重新用于任何需要 Web/代理服务器的应用程序,而不是重建映像。

注意:本教程已经在使用 DigitalOcean Kubernetes 产品文档制作的 Kubernetes 集群上进行了测试,以获取最新的信息和教程。

先决条件

  • 对 Kubernetes 对象有基本的了解。查看我们的 Kubernetes 简介文章了解更多信息。
  • 在 Ubuntu 16.04 上运行的 Kubernetes 集群。您可以按照如何在 Ubuntu 16.04 上使用 Kubeadm 创建 Kubernetes 1.10 集群教程进行设置。
  • 一个 DigitalOcean 帐户和一个具有读写权限的 API 访问令牌,用于创建我们的存储卷。如果您没有 API 访问令牌,可以从此处创建。
  • 您的应用程序代码托管在可公开访问的 URL 上,例如 Github。

第 1 步 — 创建 PHP-FPM 和 Nginx 服务

在此步骤中,您将创建 PHP-FPM 和 Nginx 服务。服务允许从集群内访问一组 pod。集群内的服务可以直接通过它们的名称进行通信,而不需要 IP 地址。 PHP-FPM 服务将允许访问 PHP-FPM pod,而 Nginx 服务将允许访问 Nginx pod。

由于 Nginx pod 将代理 PHP-FPM pod,因此您需要告诉服务如何找到它们。您将不使用 IP 地址,而是利用 Kubernetes 的自动服务发现功能,使用人类可读的名称将请求路由到适当的服务。

要创建服务,您将创建一个对象定义文件。每个 Kubernetes 对象定义都是一个 YAML 文件,至少包含以下项目:

  • apiVersion:定义所属的 Kubernetes API 的版本。
  • kind:此文件代表的 Kubernetes 对象。例如,pod 或 service。
  • 元数据:这包含对象的名称以及您可能希望应用于它的任何标签。
  • spec:这包含特定配置,具体取决于您正在创建的对象类型,例如容器映像或可访问容器的端口。

首先,您将创建一个目录来保存您的 Kubernetes 对象定义。

SSH 到您的主节点并创建 definitions 目录来保存您的 Kubernetes 对象定义。

  1. mkdir definitions

导航到新创建的 definitions 目录:

  1. cd definitions

通过创建一个 php_service.yaml 文件来创建您的 PHP-FPM 服务:

  1. nano php_service.yaml

将 kind 设置为 Service 以指定此对象是服务:

...
apiVersion: v1
kind: Service

将服务命名为 php 因为它将提供对 PHP-FPM 的访问:

...
metadata:
  name: php

您将使用标签对不同的对象进行逻辑分组。在本教程中,您将使用标签将对象分组为“层”,例如前端或后端。PHP pod 将在此服务后面运行,因此您将其标记为 tier: backend。

...
  labels:
    tier: backend

服务通过使用 selector 标签来确定访问哪些 pod。与这些标签匹配的 pod 将被服务,与 pod 是在服务之前还是之后创建无关。您将在本教程后面的部分为您的广告连播添加标签。

使用 tier: backend 标签将 pod 分配到后端层。您还将添加 app: php 标签以指定此 pod 运行 PHP。在 metadata 部分之后添加这两个标签。

...
spec:
  selector:
    app: php
    tier: backend

接下来,指定用于访问该服务的端口。您将在本教程中使用端口 9000。将其添加到 spec 下的 php_service.yaml 文件中:

...
  ports:
    - protocol: TCP
      port: 9000

您完成的 php_service.yaml 文件将如下所示:

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 apply 命令和 -f 参数并指定您的 php_service.yaml 文件。

创建您的服务:

  1. kubectl apply -f php_service.yaml

此输出确认服务创建:

Output
service/php created

验证您的服务是否正在运行:

  1. kubectl get svc

您将看到您的 PHP-FPM 服务正在运行:

Output
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

Kubernetes 支持多种服务类型。您的 php 服务使用默认服务类型 ClusterIP。此服务类型分配一个内部 IP 并使该服务只能从集群内访问。

现在 PHP-FPM 服务已准备就绪,您将创建 Nginx 服务。使用编辑器创建并打开一个名为 nginx_service.yaml 的新文件:

  1. nano nginx_service.yaml

此服务将以 Nginx pod 为目标,因此您将其命名为 nginx。您还将添加一个 tier: backend 标签,因为它属于后端层:

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    tier: backend

与 php 服务类似,使用选择器标签 app: nginx 和 tier: backend 定位 pod。使此服务可在默认 HTTP 端口 80 上访问。

...
spec:
  selector:
    app: nginx
    tier: backend
  ports:
  - protocol: TCP
    port: 80

Nginx 服务将可从您的 Droplet 的公共 IP 地址公开访问互联网。 your_public_ip 可以从您的 DigitalOcean 云面板找到。在 spec.externalIPs 下,添加:

...
spec:
  externalIPs:
  - your_public_ip

您的 nginx_service.yaml 文件将如下所示:

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    

保存并关闭文件。创建 Nginx 服务:

  1. kubectl apply -f nginx_service.yaml

当服务运行时,您将看到以下输出:

Output
service/nginx created

您可以通过执行以下命令查看所有正在运行的服务:

  1. kubectl get svc

您将看到输出中同时列出了 PHP-FPM 和 Nginx 服务:

Output
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

现在您已经创建了 PHP-FPM 和 Nginx 服务,您需要指定存储应用程序代码和配置文件的位置。

第 2 步 — 安装 DigitalOcean 存储插件

Kubernetes 提供了不同的存储插件,可以为您的环境创建存储空间。在此步骤中,您将在 DigitalOcean 上安装块存储。安装完成后,它将添加一个名为 do-block-storage 的存储类,您将使用它来创建块存储。

您将首先配置一个 Kubernetes Secret 对象来存储您的 DigitalOcean API 令牌。秘密对象用于与同一命名空间内的其他 Kubernetes 对象共享敏感信息,例如 SSH 密钥和密码。命名空间提供了一种在逻辑上分离 Kubernetes 对象的方法。

使用编辑器打开名为 secret.yaml 的文件:

  1. nano secret.yaml

您将您的 Secret 对象命名为 digitalocean 并将其添加到 kube-system namespace。 kube-system 命名空间是 Kubernetes 内部服务的默认命名空间,也被 DigitalOcean 存储插件用来启动各种组件。

apiVersion: v1
kind: Secret
metadata:
  name: digitalocean
  namespace: kube-system

Secret 使用 data 或 stringData 键来保存所需信息,而不是 spec 键。 data 参数保存 base64 编码的数据,检索时会自动解码这些数据。 stringData 参数保存在创建或更新期间自动编码的非编码数据,并且在检索 Secrets 时不输出数据。为方便起见,您将在本教程中使用 stringData。

将 access-token 添加为 stringData:

...
stringData:
  access-token: your-api-token

保存并退出文件。

您的 secret.yaml 文件将如下所示:

apiVersion: v1
kind: Secret
metadata:
  name: digitalocean
  namespace: kube-system
stringData:
  access-token: your-api-token

创建秘密:

  1. kubectl apply -f secret.yaml

您将在创建 Secret 时看到此输出:

Output
secret/digitalocean created

您可以使用以下命令查看机密:

  1. kubectl -n kube-system get secret digitalocean

输出将类似于:

Output
NAME TYPE DATA AGE digitalocean Opaque 1 41s

Opaque 类型意味着这个 Secret 是只读的,这是 stringData Secrets 的标准。您可以在秘密设计规范中阅读更多相关信息。 DATA 字段显示存储在此 Secret 中的项目数。在本例中,它显示 1 因为您存储了一个密钥。

现在您的 Secret 已就位,请安装 DigitalOcean 块存储插件:

  1. kubectl apply -f https://raw.githubusercontent.com/digitalocean/csi-digitalocean/master/deploy/kubernetes/releases/csi-digitalocean-v0.3.0.yaml

您将看到类似于以下内容的输出:

Output
storageclass.storage.k8s.io/do-block-storage created serviceaccount/csi-attacher created clusterrole.rbac.authorization.k8s.io/external-attacher-runner created clusterrolebinding.rbac.authorization.k8s.io/csi-attacher-role created service/csi-attacher-doplug-in created statefulset.apps/csi-attacher-doplug-in created serviceaccount/csi-provisioner created clusterrole.rbac.authorization.k8s.io/external-provisioner-runner created clusterrolebinding.rbac.authorization.k8s.io/csi-provisioner-role created service/csi-provisioner-doplug-in created statefulset.apps/csi-provisioner-doplug-in created serviceaccount/csi-doplug-in created clusterrole.rbac.authorization.k8s.io/csi-doplug-in created clusterrolebinding.rbac.authorization.k8s.io/csi-doplug-in created daemonset.apps/csi-doplug-in created

现在您已经安装了 DigitalOcean 存储插件,您可以创建块存储来保存您的应用程序代码和配置文件。

第 3 步 — 创建持久卷

准备好 Secret 并安装块存储插件后,您现在就可以创建持久卷了。持久卷或 PV 是指定大小的块存储,独立于 pod 的生命周期。使用 Persistent Volume 将允许您管理或更新您的 pod,而不必担心丢失您的应用程序代码。持久卷通过使用 PersistentVolumeClaim 或 PVC 来访问,PVC 会将 PV 安装在所需的路径上。

使用编辑器打开名为 code_volume.yaml 的文件:

  1. nano code_volume.yaml

通过将以下参数和值添加到您的文件来命名 PVC code:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: code

PVC 的 spec 包含以下项目:

  • accessModes 因用例而异。这些都是:
    • ReadWriteOnce – 将卷挂载为单个节点的读写
    • ReadOnlyMany – 将卷挂载为多个节点只读
    • ReadWriteMany – 将卷挂载为多个节点的读写

    DigitalOcean 块存储仅挂载到单个节点,因此您需要将 accessModes 设置为 ReadWriteOnce。本教程将指导您添加少量应用程序代码,因此在此用例中 1GB 足够了。如果您计划在该卷上存储大量代码或数据,您可以修改 storage 参数以满足您的要求。您可以在创建卷后增加存储量,但不支持缩小磁盘。

    ...
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi
    

    接下来,指定 Kubernetes 将用于配置卷的存储类。您将使用由 DigitalOcean 块存储插件创建的 do-block-storage 类。

    ...
      storageClassName: do-block-storage
    

    您的 code_volume.yaml 文件将如下所示:

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: code
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi
      storageClassName: do-block-storage
    

    保存并退出文件。

    使用 kubectl 创建 code PersistentVolumeClaim:

    1. kubectl apply -f code_volume.yaml

    以下输出告诉您对象已成功创建,您已准备好将 1GB PVC 作为卷安装。

    Output
    persistentvolumeclaim/code created

    查看可用的持久卷 (PV):

    1. kubectl get pv

    你会看到你的 PV 列出:

    Output
    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 除外。 Reclaim Policy 定义了在删除访问它的 PVC 后对 PV 执行的操作。 Delete 从 Kubernetes 和 DigitalOcean 基础设施中删除 PV。您可以从 Kubernetes PV 文档了解有关回收政策和状态的更多信息。

    您已经使用 DigitalOcean 块存储插件成功创建了一个持久卷。现在您的 Persistent Volume 已准备就绪,您将使用 Deployment 创建 Pod。

    第 4 步 — 创建 PHP-FPM 部署

    在此步骤中,您将学习如何使用 Deployment 创建 PHP-FPM pod。部署提供了一种使用 ReplicaSets 创建、更新和管理 pod 的统一方式。如果更新没有按预期工作,Deployment 将自动将其 pod 回滚到以前的图像。

    Deployment spec.selector 键将列出它将管理的 pod 的标签。它还将使用 template 键来创建所需的 pod。

    这一步也会介绍Init Container的使用。 Init Containers 在 pod 的 template 键下指定的常规容器之前运行一个或多个命令。在本教程中,您的 Init 容器将使用 wget 从 GitHub Gist 获取示例 index.php 文件。这些是示例文件的内容:

    <?php
    echo phpinfo(); 
    

    要创建 Deployment,请使用编辑器打开一个名为 php_deployment.yaml 的新文件:

    1. nano php_deployment.yaml

    此 Deployment 将管理您的 PHP-FPM pod,因此您将 Deployment 对象命名为 php。 Pod 属于后端层,因此您将使用 tier: backend 标签将 Deployment 分组到该组中:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: php
      labels:
        tier: backend
    

    对于部署 spec,您将使用 replicas 参数指定要创建的此 pod 的副本数。 副本 的数量将根据您的需求和可用资源而有所不同。您将在本教程中创建一个副本:

    ...
    spec:
      replicas: 1
    

    此 Deployment 将管理与 app: php 和 tier: backend 标签相匹配的 pod。在 selector 键下添加:

    ...
      selector:
        matchLabels:
          app: php
          tier: backend
    

    接下来,部署 spec 需要用于 pod 对象定义的 template。该模板将定义用于创建 pod 的规范。首先,您将添加为 php 服务 selectors 和 Deployment 的 matchLabels 指定的标签。在template.metadata.labels 下添加app: php 和tier: backend:

    ...
      template:
        metadata:
          labels:
            app: php
            tier: backend
    

    一个 pod 可以有多个容器和卷,但每个容器和卷都需要一个名称。您可以通过为每个卷指定装载路径来选择性地将卷装载到容器中。

    首先,指定您的容器将访问的卷。您创建了一个名为 code 的 PVC 来保存您的应用程序代码,因此也将此卷命名为 code。在 spec.template.spec.volumes 下,添加以下内容:

    ...
        spec:
          volumes:
          - name: code
            persistentVolumeClaim:
              claimName: code
    

    接下来,指定要在此 pod 中运行的容器。您可以在 Docker 商店中找到各种图像,但在本教程中,您将使用 php:7-fpm 图像。

    在 spec.template.spec.containers 下,添加以下内容:

    ...
          containers:
          - name: php
            image: php:7-fpm
    

    接下来,您将装载容器需要访问的卷。此容器将运行您的 PHP 代码,因此它需要访问 code 卷。您还将使用 mountPath 将 /code 指定为挂载点。

    在 spec.template.spec.containers.volumeMounts 下,添加:

    ...
            volumeMounts:
            - name: code
              mountPath: /code
    

    现在您已经安装了您的卷,您需要在该卷上获取您的应用程序代码。您之前可能使用过 FTP/SFTP 或通过 SSH 连接克隆代码来完成此操作,但此步骤将向您展示如何使用 Init Container 复制代码。

    根据设置过程的复杂性,您可以使用单个 initContainer 来运行构建应用程序的脚本,或者您可以为每个命令使用一个 initContainer。确保卷已装载到 initContainer。

    在本教程中,您将使用带有 busybox 的单个 Init Container 来下载代码。 busybox 是一个包含 wget 实用程序的小图像,您将使用它来完成此操作。

    在 spec.template.spec 下,添加您的 initContainer 并指定 busybox 图像:

    ...
          initContainers:
          - name: install
            image: busybox
    

    您的 Init Container 需要访问 code 卷,以便它可以下载该位置的代码。在 spec.template.spec.initContainers 下,将卷 code 挂载到 /code 路径:

    ...
            volumeMounts:
            - name: code
              mountPath: /code
    

    每个 Init Container 都需要运行一个 command。您的 Init Container 将使用 wget 将 Github 下载到 /code 工作目录中。 -O 选项为下载的文件命名,您将把这个文件命名为 index.php。

    注意:请务必信任您提取的代码。在将它拉到您的服务器之前,请检查源代码以确保您对代码的作用感到满意。

    在 spec.template.spec.initContainers 的 install 容器下,添加以下行:

    ...
            command:
            - wget
            - "-O"
            - "/code/index.php"
            - https://raw.githubusercontent.com/do-community/php-kubernetes/master/index.php
    

    您完成的 php_deployment.yaml 文件将如下所示:

    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 创建 PHP-FPM 部署:

    1. kubectl apply -f php_deployment.yaml

    创建部署后,您将看到以下输出:

    Output
    deployment.apps/php created

    总而言之,此 Deployment 将从下载指定的图像开始。然后它将从您的 PersistentVolumeClaim 请求 PersistentVolume 并连续运行您的 initContainers。完成后,容器将运行并将 volumes 挂载到指定的挂载点。完成所有这些步骤后,您的 pod 将启动并运行。

    您可以通过运行以下命令查看您的 Deployment:

    1. kubectl get deployments

    您将看到输出:

    Output
    NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE php 1 1 1 0 19s

    此输出可以帮助您了解 Deployment 的当前状态。 Deployment 是 Kubernetes 部署文档。

    您可以使用以下命令查看此 Deployment 启动的 pod:

    1. kubectl get pods

    此命令的输出取决于自创建 Deployment 以来经过的时间。如果您在创建后不久运行它,输出可能如下所示:

    Output
    NAME READY STATUS RESTARTS AGE php-86d59fd666-bf8zd 0/1 Init:0/1 0 9s

    这些列代表以下信息:

    • Ready:运行此 pod 的replicas 数量。
    • Status:pod 的状态。 Init 表示 Init 容器正在运行。在此输出中,1 个初始容器中有 0 个已完成运行。
    • Restarts:此进程重新启动了多少次以启动 pod。如果您的任何 Init Container 失败,这个数字将会增加。 Deployment 将重新启动它,直到它达到所需的状态。

    根据启动脚本的复杂程度,状态更改为 podInitializing 可能需要几分钟时间:

    Output
    NAME READY STATUS RESTARTS AGE php-86d59fd666-lkwgn 0/1 podInitializing 0 39s

    这意味着 Init Containers 已经完成并且容器正在初始化。如果在所有容器都在运行时运行该命令,您将看到 pod 状态更改为 Running。

    Output
    NAME READY STATUS RESTARTS AGE php-86d59fd666-lkwgn 1/1 Running 0 1m

    您现在看到您的 pod 正在成功运行。如果您的 pod 没有启动,您可以使用以下命令进行调试:

    • 查看一个pod的详细信息:

    1. kubectl describe pods pod-name

    • 查看 pod 生成的日志:

    1. kubectl logs pod-name

    • 查看 pod 中特定容器的日志:

    1. kubectl logs pod-name container-name

    您的应用程序代码已安装,PHP-FPM 服务现在已准备好处理连接。您现在可以创建 Nginx 部署。

    第 5 步 — 创建 Nginx 部署

    在此步骤中,您将使用 ConfigMap 来配置 Nginx。 ConfigMap 以键值格式保存您的配置,您可以在其他 Kubernetes 对象定义中引用该格式。如果需要,这种方法将使您能够灵活地重用图像或将图像与不同的 Nginx 版本交换。更新 ConfigMap 会自动将更改复制到安装它的任何 pod。

    使用编辑器为您的 ConfigMap 创建一个 nginx_configMap.yaml 文件:

    1. nano nginx_configMap.yaml

    将 ConfigMap 命名为 nginx-config 并将其分组到 tier: backend 微服务中:

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: nginx-config
      labels:
        tier: backend
    

    接下来,您将为 ConfigMap 添加 data。将键命名为 config 并将 Nginx 配置文件的内容添加为值。您可以使用本教程中的示例 Nginx 配置。

    因为 Kubernetes 可以将请求路由到服务的适当主机,所以您可以在 fastcgi_pass 参数中输入 PHP-FPM 服务的名称,而不是其 IP 地址。将以下内容添加到您的 nginx_configMap.yaml 文件中:

    ...
    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 文件将如下所示:

    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;
            }
        }
    

    保存文件并退出编辑器。

    创建配置映射:

    1. kubectl apply -f nginx_configMap.yaml

    您将看到以下输出:

    Output
    configmap/nginx-config created

    您已经完成了 ConfigMap 的创建,现在可以构建您的 Nginx Deployment。

    首先在编辑器中打开一个新的 nginx_deployment.yaml 文件:

    1. nano nginx_deployment.yaml

    将部署命名为 nginx 并添加标签 tier: backend:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx
      labels:
        tier: backend
    

    在部署 spec 中指定您需要一个 replicas。此 Deployment 将管理标签为 app: nginx 和 tier: backend 的 pod。添加以下参数和值:

    ...
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: nginx
          tier: backend
    

    接下来,添加 pod 模板。您需要使用为部署 selector.matchLabels 添加的相同标签。添加以下内容:

    ...
      template:
        metadata:
          labels:
            app: nginx
            tier: backend
    

    让 Nginx 访问您之前创建的 code PVC。在 spec.template.spec.volumes 下,添加:

    ...
        spec:
          volumes:
          - name: code
            persistentVolumeClaim:
              claimName: code
    

    Pod 可以将 ConfigMap 挂载为卷。指定文件名和键将创建一个文件,其值作为内容。要使用 ConfigMap,请将 path 设置为将保存 key 内容的文件的名称。您想要从密钥 config 创建一个文件 site.conf。在 spec.template.spec.volumes 下,添加以下内容:

    ...
          - name: config
            configMap:
              name: nginx-config
              items:
              - key: config
                path: site.conf
    

    警告:如果未指定文件,key 的内容将替换卷的 mountPath。这意味着如果未明确指定路径,您将丢失目标文件夹中的所有内容。

    接下来,您将指定用于创建 Pod 的图像。本教程将使用 nginx:1.7.9 图像以确保稳定性,但您可以在 Docker 商店中找到其他 Nginx 图像。此外,使 Nginx 在端口 80 上可用。在 spec.template.spec 下添加:

    ...
          containers:
          - name: nginx
            image: nginx:1.7.9
            ports:
            - containerPort: 80
    

    Nginx 和 PHP-FPM 需要在同一路径访问该文件,因此将 code 卷挂载到 /code:

    ...
            volumeMounts:
            - name: code
              mountPath: /code
    

    nginx:1.7.9 映像将自动加载 /etc/nginx/conf.d 目录下的任何配置文件。在此目录中安装 config 卷将创建文件 /etc/nginx/conf.d/site.conf。在 volumeMounts 下添加以下内容:

    ...
            - name: config
              mountPath: /etc/nginx/conf.d
    

    您的 nginx_deployment.yaml 文件将如下所示:

    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 部署:

    1. kubectl apply -f nginx_deployment.yaml

    以下输出表明您的 Deployment 现已创建:

    Output
    deployment.apps/nginx created

    使用此命令列出您的部署:

    1. kubectl get deployments

    您将看到 Nginx 和 PHP-FPM 部署:

    Output
    NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE nginx 1 1 1 0 16s php 1 1 1 1 7m

    列出由两个 Deployment 管理的 pod:

    1. kubectl get pods

    您将看到正在运行的 pod:

    Output
    NAME READY STATUS RESTARTS AGE nginx-7bf5476b6f-zppml 1/1 Running 0 32s php-86d59fd666-lkwgn 1/1 Running 0 7m

    现在所有 Kubernetes 对象都处于活动状态,您可以在浏览器上访问 Nginx 服务。

    列出正在运行的服务:

    1. kubectl get services -o wide

    获取 Nginx 服务的外部 IP:

    Output
    NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 39m <none> nginx ClusterIP 10.102.160.47 your_public_ip 80/TCP 27m app=nginx,tier=backend php ClusterIP 10.100.59.238 <none> 9000/TCP 34m app=php,tier=backend

    在您的浏览器上,通过输入 http://your_public_ip 访问您的服务器。您将看到 php_info() 的输出,并确认您的 Kubernetes 服务已启动并正在运行。

    结论

    在本指南中,您将 PHP-FPM 和 Nginx 服务容器化,以便您可以独立管理它们。随着您的成长,这种方法不仅可以提高项目的可扩展性,还可以让您有效地使用资源。您还将应用程序代码存储在一个卷上,以便将来可以轻松更新您的服务。

©2015-2025 艾丽卡 support@alaica.com