如何在Kubernetes 上部署安装PHP + Nginx 多容器应用

引言

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

要运行一个PHP应用程序,Nginx充当PHP-FPM的代理。将此设置打包到单个容器中可能是一个繁琐的过程,但Kubernetes将帮助在不同的容器中管理这两个服务。使用Kubernetes将允许你保持容器的可重用性和可交换性,并且不必在每次有新版本的Nginx或PHP时重新构建容器镜像。

在本教程中,你将在Kubernetes集群上部署一个PHP7应用程序,其中Nginx和PHP-FPM运行在不同的容器中。你还将学习如何使用CSDN 开发云的对象存储系统将配置文件和应用程序代码保存在容器映像之外。这种方法将允许你通过传递配置卷,为任何需要Web的应用程序重用Nginx镜像,而不是重新构建镜像。

点击下图观看一条命令部署安装过程
如何在Kubernetes 上部署安装PHP + Nginx 多容器应用_第1张图片

先决条件

  • 对 Kubernetes 有初步了解。如果你没有接触过 k8s,也完全可以按照教程完成php程序部署,在通过学习k8s官方文档 了解 k8s 的各个组件
  • 有一个装有 k8s 的 ubuntu 主机 。CSDN 开发云提供了k8s学习环境,可按小时付费使用,每小时仅 0.07元。学习完毕后可以释放主机资源即会停止计费。 点这里一键拥有 k8s 环境

整个教程大概用时 10 分钟 至 30 分钟。

第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接口版本
  • kind: 该文件所代表的Kubernetes对象,例如:pod 或 service
  • metadata: 它包含对象的名称以及你可能想要应用到它的任何Labels
  • spec: 它包含一个特定的配置,具体取决于你创建的对象的类型,例如容器镜像或容器将从其上访问的端口。

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

通过SSH连接到你的主节点,并创建存放你的Kubernetes对象定义的definitions目录。

mkdir definitions

导航到新创建的definitions目录:

cd definitions

创建php_service.yaml文件来创建你的PHP-fpm服务:

vi php_service.yaml

设置kindService,表示该对象为服务:

apiVersion: v1
  kind: Service

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

php_service.yaml

...
metadata:
  name: php

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

...
  labels:
    tier: backend

服务使用`选择器‘标签来确定要访问哪些实例。无论Pod是在服务之前还是之后创建的,都将服务与这些标签匹配的Pod。在本教程的后面部分,你将为Pod添加标签。

使用tier:backend标签将实例分配到后端层。你还需要添加app:php标签,以指定该实例运行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

命令输出如下:

service/php created

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

kubectl get svc

你将看到你的PHP-fpm服务正在运行:

Output
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
kubernetes   ClusterIP   10.43.0.1               443/TCP    10m
php          ClusterIP   10.43.76.123           9000/TCP   5m

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

现在已经准备好了PHP-fpm服务,你将创建nginx服务。使用编辑器创建并打开一个名为nginx_service.yaml的新文件:

nano nginx_service.yaml

此服务针对的是Nginx实例,因此你将其命名为nginx。你还需要添加一个tier:backend标签,因为它属于后端层:

nginx_service.yaml

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

php服务类似,使用选择器标签app:nginxtier:backend来定位实例。使此服务可以在默认的HTTP端口80上访问。

nginx_service.yaml

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

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

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    tier: backend
spec:
  selector:
    app: nginx
    tier: backend
  ports:
  - protocol: TCP
    port: 80
 

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

kubectl apply -f nginx_service.yaml

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

service/nginx created

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

kubectl get svc

你将在输出中看到列出的PHP-fpm和nginx服务:

NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
kubernetes   ClusterIP   10.43.0.1                 443/TCP    5d19h
php          ClusterIP   10.43.76.123              9000/TCP   104s
nginx        ClusterIP   10.43.42.97    116.196.125.86   80/TCP     7s

请注意,如果要删除可以运行的服务:

kubectl delete svc/service_name

现在你已经创建了PHP-fpm和nginx服务,接下来需要指定存储应用程序代码和配置文件的位置。

步骤2 - 创建持久卷

Kubernetes提供了不同的存储插件,可以为你的环境创建存储空间。在节中,您将创建一个hostPath PersistentVolume。Kubernetes 支持 hostPath 在单节点集群上进行开发和测试。hostPath PersistentVolume 使用节点上的文件或目录来模拟网络附加存储。

在生产集群中,您不会使用 hostPath,集群管理员会预置网络资源,例如 NFS 共享或 对象存储卷。集群管理员还可以使用StorageClasses 来动态供应存储。

这是 hostPath PersistentVolume 的配置文件,文件名为 code_volume.yaml:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: code
  labels:
    type: local
spec:
  storageClassName: manual
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/mnt/data"    

配置文件指定卷位于/mnt/data集群的节点上。该配置还指定大小为 10 gibibytes 和访问模式ReadWriteOnce,这意味着该卷可以被单个节点以读写方式安装。它定义了PersistentVolume 的StorageClass 名称 manual,它将用于将 PersistentVolumeClaim 请求绑定到此 PersistentVolume。

创建存储:

kubectl apply -f code-volume.yaml

你将看到以下输出:

persistentvolume/code created

你可以使用以下命令查看 PersistentVolume:

kubectl get pv

输出将如下所示:

NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM          STORAGECLASS   REASON   AGE
code    1Gi        RWO            Retain           Bound       default/code   manual                  90m

现在你已经创建了一个持久卷,你可以创建存储来保存应用程序代码和配置文件。

第3步-创建 PersistentVolumeClaim

准备好密码并安装数据块存储插件后,你现在就可以创建永久卷了。持久卷是指定大小的存储,独立于Pod的生命周期而存在。使用永久卷将允许你管理或更新你的Pod,而不必担心丢失应用程序代码。永久卷通过PersistentVolumeClaim访问,它将PV挂载到所需的路径。

用你的编辑器打开一个名为code_claim.yaml的文件:

nano code_claim.yaml

将以下参数和值添加到你的文件 code_claim.yaml 中,将PVC命名为code

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: code

PVC的spec包含以下几项:

  • accessModes 根据用例的不同而不同。分别为::
    • ReadWriteOnce – 单节点挂载为读写卷
    • ReadOnlyMany – 多节点挂载为只读
    • ReadWriteMany – 多节点挂载为读写卷
  • resources – 你需要的存储空间

本教程你将添加少量的应用程序代码,因此在此用例中1 GB就足够了。如果你计划在卷上存储更多的代码或数据,你可以修改storage参数以满足你的需求。你可以在创建卷后增加存储量,但不支持收缩磁盘。storageClassName指定Kubernetes将用于调配卷的存储类。

code_claim.yaml

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

最终,你的code_claim.yaml文件如下所示:

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

保存并退出该文件。

使用kubectl创建codepvc:

kubectl apply -f code_claim.yaml

下面的输出告诉你对象已成功创建,并且你已经准备好将1 GB的PVC挂载为卷。

persistentvolumeclaim/code created

要查看PersistentVolumeClaim,请执行以下操作:

kubectl get pvc

你将看到列出了你的PVC:

NAME   STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
code   Bound    code     1Gi        RWO            manual         105m

你已经成功创建了持久卷,你将使用Deployment创建你的Pod。

步骤4 - 创建一个PHP-FPM部署

在本步骤中,你将学习如何使用 Deployment 来创建你的PHP-FPM Pod。Deployments 提供了使用ReplicaSet 来创建、更新和管理Pod的统一方式。如果更新未按预期工作,部署将自动将其Pod回滚到以前的映像。

Deployment spec.selector键将列出它要管理的实例的标签。它还将使用template键创建所需的Pod。

本步骤还将介绍Init容器的使用。在实例的template键下指定的常规容器之前,init容器运行一个或多个命令。在本教程中,你的Init容器将使用wget从gitcode 获取一个示例index.php文件。以下是示例文件的内容:

index.php

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

nano php_deployment.yaml

该部署将管理你的PHP-FPM Pod,因此你将把部署对象命名为php。实例属于后端层,因此你需要使用tier:backend标签将部署分组:

php_deployment.yaml

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

对于部署spec,你将使用replicas参数指定要创建多少个该实例的副本。replicas的数量会根据你的需求和可用资源而有所不同。在本教程中,你将创建一个复制副本:

php_deployment.yaml

...
spec:
  replicas: 1

该部署将管理与app:phptier:backend标签匹配的实例。在selector键下添加:

php_deployment.yaml

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

接下来,部署spec需要实例对象定义的template。此模板将定义用于创建Pod的规范。首先,你需要添加为php服务选择器和部署的matchLabels指定的标签。在template.metadata.labels下添加app:phptier:backend

php_deployment.yaml

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

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

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

php_deployment.yaml

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

接下来,指定要在此Pod中运行的容器。你可以在Docker hub找到各种镜像,在本教程中,你将使用php:7-fpm 这个镜像。

spec.template.spec.tainers下,添加以下内容:

php_deployment.yaml

Php_ployment.yaml

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

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

在文件 php_deployment.yaml spec.template.spec.tainers.volumemount下,添加:

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

现在你已经挂载了卷,你需要将应用程序代码放到卷上。你可能以前使用过FTP/SFTP或通过SSH连接复制代码来完成此任务,但本步骤将向你展示如何使用Init容器复制代码。

根据安装过程的复杂程度,你可以使用单个initContainer来运行构建应用程序的脚本,也可以每个命令使用一个initContainer。请确保卷已挂载到initContainer

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

Under spec.template.spec, add your initContainer and specify the busybox image:

在文件 php_deployment.yaml spec.template.spec下,添加你的initContainer,并指定busybox镜像:

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

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

php_deployment.yaml 文件相关内容

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

每个Init容器都需要运行一个命令。你的Init容器将使用wget将代码从gitcode下载到/code工作目录。-o选项为下载的文件命名,你可以将该文件命名为index.php

注意:请确保信任你提取的代码。在将其放到服务器上之前,请检查源代码,以确保你对代码的功能感到满意。

在文件php_deployment.yaml spec.template.spec.initContainers中的install容器下,添加以下行:

...
        command:
        - wget
        - "-O"
        - "/code/index.php"
        - https://gitcode.net/hjue/k8s-samples/-/raw/master/php-k8s/index.php

完成的php_ployment.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://gitcode.net/hjue/k8s-samples/-/raw/master/php-k8s/index.php

保存文件并退出编辑器。

使用kubectl创建PHP-fpm部署:

kubectl apply -f php_deployment.yaml

命令执行后,你将看到以下输出:

deployment.apps/php created

此部署将从下载指定的映像,然后向你的PersistentVolumeClaim请求PersistentVolume,并运行你的initContainers。完成后,容器将运行并将volumes挂载到指定的挂载点。一旦完成所有这些步骤,你的Pod就可以启动并运行了。

你可以通过运行以下命令来查看:

kubectl get deployments

你将看到输出:

NAME   READY   UP-TO-DATE   AVAILABLE   AGE
php    0/1     1            0           7s

以上输出可以帮助你了解部署的当前状态。Deployment 是保持所需状态的控制器之一。你创建的template指定DESIRED状态将有一个名为php的实例的副本CURRENT字段表示有多少副本正在运行,因此这应该与DESIRED状态匹配。你可以阅读Kubernetes部署文档中的了解其余字段的说明。

你可以使用以下命令查看此部署启动的Pod:

kubectl get pods

此命令的输出会根据创建 Deployment 后经过的时间而有所不同。如果在创建后不久运行它,输出可能如下所示:

NAME                   READY     STATUS     RESTARTS   AGE
php-6b4d5555d4-dknb4   0/1       Init:0/1   0          9s

这些列表示以下信息:

  • Ready: 运行该实例的副本个数。

  • Status: 实例的状态。Init表示Init容器正在运行。在此输出中,1个Init容器中有0个已经运行完毕。

  • Restarts: 该进程重新启动Pod的次数。如果你的任何Init容器出现故障,这个数字将会增加。部署将重新启动它,直到它达到所需的状态。

根据启动脚本的复杂程度,状态可能需要几分钟才能变为podInitializing

Output
NAME                   READY     STATUS            RESTARTS   AGE
php-6b4d5555d4-dknb4   0/1       podInitializing   0          39s

这意味着Init容器已完成,容器正在初始化。如果在所有容器都在运行的情况下运行该命令,你会看到实例状态变为Running

NAME                   READY     STATUS            RESTARTS   AGE
php-6b4d5555d4-dknb4   1/1       Running   0          1m

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

  • 查看 pod 的详细信息,用实际的pod-name代替:
kubectl describe pods <pod-name>

  • 查看 pod 日志:
kubectl logs <pod-name>

  • 查看pod 中指定container的日志
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

文件nginx_configMap.yaml中将ConfigMap命名为nginx-config,并分组到tier:backend微服务中:

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

接下来,你将为ConfigMap添加data。将密钥命名为config,并添加你的Nginx配置文件的内容作为该值。

由于Kubernetes可以将请求路由到服务的相应主机,因此你可以在fast cgi_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;
        }
    }

保存文件并退出编辑器。

创建ConfigMap:

kubectl apply -f nginx_configMap.yaml

你将看到以下输出:

configmap/nginx-config created

你已经完成了ConfigMap的创建,现在可以构建你的Nginx部署了。

首先,在编辑器中创建一个新的nginx_ployment.yaml文件:

nano nginx_deployment.yaml

文件nginx_deployment.yaml 中 将Deployment命名为nginx,并添加标签tier:backend

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

文件 nginx_deployment.yaml 中指定在部署spec中需要一个副本。该部署将管理标签为app:nginxtier:backend的实例。添加以下参数和值:

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

接下来,文件nginx_deployment.yaml中添加Podtemplate。你需要使用你为部署seletor.matchLabels添加的相同标签。添加以下内容:

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

将你之前创建的codepvc的访问权限授予nginx。在nginx_deployment.yaml中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 hub中找到其他版本的nginx镜像。另外,让nginx在80端口可用。在文件nginx_deployment.yaml中spec.template.spec`下添加:

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

Nginx和php-fpm需要访问同一路径下的文件,因此需要在文件nginx_deployment.yaml中挂载code卷:

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

The nginx:1.7.9 image will automatically load any configuration files under the /etc/nginx/conf.d directory. Mounting the config volume in this directory will create the file /etc/nginx/conf.d/site.conf. Under volumeMounts add the following:

nginx:1.7.9镜像会自动加载/etc/nginx/conf.d目录下的所有配置文件。在该目录下挂载config卷,将创建/etc/nginx/conf.d/site.conf文件。在volumeMounts下添加以下内容:

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

你的nginx_ployment.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.apps/nginx created

使用以下命令列出你的部署:

kubectl get deployments

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

NAME    READY   UP-TO-DATE   AVAILABLE   AGE
php     1/1     1            1           35m
nginx   1/1     1            1           60s

列出这两种部署管理的Pod:

kubectl get pods

你将看到正在运行的Pod:

NAME                     READY   STATUS    RESTARTS   AGE
php-6b4d5555d4-dknb4     1/1     Running   0          35m
nginx-6bc5d4dfc7-xdb6m   1/1     Running   0          87s

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

列出正在运行的服务:

kubectl get services -o wide

获取你的Nginx服务的外部IP:

NAME         TYPE        CLUSTER-IP     EXTERNAL-IP      PORT(S)    AGE     SELECTOR
kubernetes   ClusterIP   10.43.0.1                 443/TCP    5d20h   
php          ClusterIP   10.43.76.123              9000/TCP   72m     app=php,tier=backend
nginx        ClusterIP   10.43.42.97    116.196.125.86   80/TCP     71m     app=nginx,tier=backend

此时已完成了 php 和 nginx 的部署 ,你可以使用curl命令访问nginx cluster-ip ,你将看到php_info()的输出。

这时你还不能在公网访问 nginx 服务。你可以尝试在你的浏览器上,访问你的服务器的ip 地址,你将看到 404 page not found的输出。

接下来你将配置 ingress 完成最终的公网访问。

步骤6 - 创建Ingress 资源

Ingress使用路由规则配置Traefik。这个示例将使用基于路径的路由规则。通过检查传入网址的上下文来评估基于路径的路由规则。此处,路径前缀为**/。路径/**捕捉所有传入的流量。将以下内容保存为文件ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx
  annotations:
    kubernetes.io/ingress.class: traefik
spec:
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx
            port:
              number: 80

执行命令创建ingress 资源

kubectl create -f ingress.yaml

使用 get 命令查看ingress资源

kubectl get ingress

你将看到你刚刚创建的ingress,172.28.0.48 是我们 k8s 集群的INTERNAL-IP

NAME    CLASS    HOSTS   ADDRESS       PORTS   AGE
nginx      *       172.28.0.48   80      15s

在你的浏览器上,输入http://your_public_ip以访问你的服务器,你将看到php_info()的输出。

步骤 7 - 扩展练习

删除以上部署php 应用的所有资源

kubectl delete -f code_volume.yaml -f code_claim.yaml \
   -f php_deployment.yaml  -f php_service.yaml  \
   -f nginx_configMap.yaml -f nginx_deployment.yaml -f nginx_service.yaml \
   -f ingress.yaml

一条命令重新部署php 应用

kubectl create -f code_volume.yaml -f code_claim.yaml \
   -f php_deployment.yaml  -f php_service.yaml  \
   -f nginx_configMap.yaml -f nginx_deployment.yaml -f nginx_service.yaml \
   -f ingress.yaml

扩容,使用如下命令将Deployment php 的副本数增加到 3

kubectl scale --replicas=3  deployment/php

可以看到如下输出

deployment.apps/php scaled

你立即使用 kubectl get pod -o wide查看 pods,可以看到k8s集群增加了两个 php Pod,当前状态是开始初始化容器

image-20220712111834977

再次使用 kubectl get pod -o wide查看 pods,新建的 pod 状态变为PodInitializing

image-20220712113128536

几秒钟后,再次使用 kubectl get pod -o wide查看 pods,可以看到 两个新增的pod,已经完成初始化,处于运行状态

image-20220712112537676

结论

本文所有代码的 git 仓库地址: https://gitcode.net/hjue/k8s-samples

在本教程中,你掌握了创建PHP-fpm和nginx服务,并独立管理它们。这种方法不仅可以随着你应用的发展提高项目的可伸缩性,还可以让你高效地使用资源。你还将应用程序代码存储在卷上,以便将来可以轻松更新你的服务。

你可能感兴趣的