如何在 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 对象定义。
- mkdir definitions
导航到新创建的 definitions
目录:
- cd definitions
通过创建一个 php_service.yaml
文件来创建您的 PHP-FPM 服务:
- 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
文件。
创建您的服务:
- kubectl apply -f php_service.yaml
此输出确认服务创建:
Outputservice/php created
验证您的服务是否正在运行:
- kubectl get svc
您将看到您的 PHP-FPM 服务正在运行:
OutputNAME 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
的新文件:
- 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 服务:
- kubectl apply -f nginx_service.yaml
当服务运行时,您将看到以下输出:
Outputservice/nginx created
您可以通过执行以下命令查看所有正在运行的服务:
- kubectl get svc
您将看到输出中同时列出了 PHP-FPM 和 Nginx 服务:
OutputNAME 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
请注意,如果你想删除一个服务,你可以运行:
- kubectl delete svc/service_name
现在您已经创建了 PHP-FPM 和 Nginx 服务,您需要指定存储应用程序代码和配置文件的位置。
第 2 步 — 安装 DigitalOcean 存储插件
Kubernetes 提供了不同的存储插件,可以为您的环境创建存储空间。在此步骤中,您将在 DigitalOcean 上安装块存储。安装完成后,它将添加一个名为 do-block-storage
的存储类,您将使用它来创建块存储。
您将首先配置一个 Kubernetes Secret 对象来存储您的 DigitalOcean API 令牌。秘密对象用于与同一命名空间内的其他 Kubernetes 对象共享敏感信息,例如 SSH 密钥和密码。命名空间提供了一种在逻辑上分离 Kubernetes 对象的方法。
使用编辑器打开名为 secret.yaml
的文件:
- 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
创建秘密:
- kubectl apply -f secret.yaml
您将在创建 Secret 时看到此输出:
Outputsecret/digitalocean created
您可以使用以下命令查看机密:
- kubectl -n kube-system get secret digitalocean
输出将类似于:
OutputNAME TYPE DATA AGE
digitalocean Opaque 1 41s
Opaque
类型意味着这个 Secret 是只读的,这是 stringData
Secrets 的标准。您可以在秘密设计规范中阅读更多相关信息。 DATA
字段显示存储在此 Secret 中的项目数。在本例中,它显示 1
因为您存储了一个密钥。
现在您的 Secret 已就位,请安装 DigitalOcean 块存储插件:
- kubectl apply -f https://raw.githubusercontent.com/digitalocean/csi-digitalocean/master/deploy/kubernetes/releases/csi-digitalocean-v0.3.0.yaml
您将看到类似于以下内容的输出:
Outputstorageclass.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
的文件:
- 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:- kubectl apply -f code_volume.yaml
以下输出告诉您对象已成功创建,您已准备好将 1GB PVC 作为卷安装。
Outputpersistentvolumeclaim/code created查看可用的持久卷 (PV):
- kubectl get pv
你会看到你的 PV 列出:
OutputNAME 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
的新文件:- 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 部署:- kubectl apply -f php_deployment.yaml
创建部署后,您将看到以下输出:
Outputdeployment.apps/php created总而言之,此 Deployment 将从下载指定的图像开始。然后它将从您的
PersistentVolumeClaim
请求PersistentVolume
并连续运行您的initContainers
。完成后,容器将运行并将volumes
挂载到指定的挂载点。完成所有这些步骤后,您的 pod 将启动并运行。您可以通过运行以下命令查看您的 Deployment:
- kubectl get deployments
您将看到输出:
OutputNAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE php 1 1 1 0 19s此输出可以帮助您了解 Deployment 的当前状态。
Deployment
是 Kubernetes 部署文档。您可以使用以下命令查看此 Deployment 启动的 pod:
- kubectl get pods
此命令的输出取决于自创建 Deployment 以来经过的时间。如果您在创建后不久运行它,输出可能如下所示:
OutputNAME 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
可能需要几分钟时间:OutputNAME READY STATUS RESTARTS AGE php-86d59fd666-lkwgn 0/1 podInitializing 0 39s这意味着 Init Containers 已经完成并且容器正在初始化。如果在所有容器都在运行时运行该命令,您将看到 pod 状态更改为
Running
。OutputNAME READY STATUS RESTARTS AGE php-86d59fd666-lkwgn 1/1 Running 0 1m您现在看到您的 pod 正在成功运行。如果您的 pod 没有启动,您可以使用以下命令进行调试:
- 查看一个pod的详细信息:
- kubectl describe pods pod-name
- 查看 pod 生成的日志:
- kubectl logs pod-name
- 查看 pod 中特定容器的日志:
- kubectl logs pod-name container-name
您的应用程序代码已安装,PHP-FPM 服务现在已准备好处理连接。您现在可以创建 Nginx 部署。
第 5 步 — 创建 Nginx 部署
在此步骤中,您将使用 ConfigMap 来配置 Nginx。 ConfigMap 以键值格式保存您的配置,您可以在其他 Kubernetes 对象定义中引用该格式。如果需要,这种方法将使您能够灵活地重用图像或将图像与不同的 Nginx 版本交换。更新 ConfigMap 会自动将更改复制到安装它的任何 pod。
使用编辑器为您的 ConfigMap 创建一个
nginx_configMap.yaml
文件:- 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; } }
保存文件并退出编辑器。
创建配置映射:
- kubectl apply -f nginx_configMap.yaml
您将看到以下输出:
Outputconfigmap/nginx-config created您已经完成了 ConfigMap 的创建,现在可以构建您的 Nginx Deployment。
首先在编辑器中打开一个新的
nginx_deployment.yaml
文件:- 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 部署:
- kubectl apply -f nginx_deployment.yaml
以下输出表明您的 Deployment 现已创建:
Outputdeployment.apps/nginx created使用此命令列出您的部署:
- kubectl get deployments
您将看到 Nginx 和 PHP-FPM 部署:
OutputNAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE nginx 1 1 1 0 16s php 1 1 1 1 7m列出由两个 Deployment 管理的 pod:
- kubectl get pods
您将看到正在运行的 pod:
OutputNAME READY STATUS RESTARTS AGE nginx-7bf5476b6f-zppml 1/1 Running 0 32s php-86d59fd666-lkwgn 1/1 Running 0 7m现在所有 Kubernetes 对象都处于活动状态,您可以在浏览器上访问 Nginx 服务。
列出正在运行的服务:
- kubectl get services -o wide
获取 Nginx 服务的外部 IP:
OutputNAME 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 服务容器化,以便您可以独立管理它们。随着您的成长,这种方法不仅可以提高项目的可扩展性,还可以让您有效地使用资源。您还将应用程序代码存储在一个卷上,以便将来可以轻松更新您的服务。