从零开始部署在 Kubernetes 中部署 Laravel应用(0)

Kubernetes(简称 K8s)是一个用于自动化部署、扩展和管理容器化应用程序的开源平台。它提供了一系列强大的功能,使得开发人员和运维团队能够更轻松地管理容器化应用程序。以下是 Kubernetes 的一些优点:

  1. 自动化部署和扩展:Kubernetes 提供了丰富的自动化功能,能够快速、可靠地部署和扩展应用程序。它支持自动扩展、自动故障恢复和自动负载均衡等功能,可以根据应用程序的需求自动调整资源。

  2. 高可用性:Kubernetes 架构设计具有高可用性,能够确保应用程序在节点故障或者其他故障情况下保持可用。它支持故障转移、自动重启和自动恢复等功能,可以有效地保障应用程序的可用性。

  3. 弹性和可伸缩性:Kubernetes 提供了强大的弹性和可伸缩性功能,能够根据应用程序的负载自动调整资源。它支持水平扩展和垂直扩展,并且能够根据需求动态地调整容器的数量和资源分配。

  4. 灵活性和可移植性:Kubernetes 提供了灵活的部署和管理模型,能够在各种环境中运行,包括公有云、私有云和混合云环境。它支持多种容器运行时,包括 Docker、containerd 和 CRI-O,能够容易地迁移和跨平台运行应用程序。

  5. 自我修复:Kubernetes 提供了自我修复的功能,能够自动检测和处理容器和节点的故障。它支持自动重启、自动替换和自动缩容等功能,能够有效地减少人工干预并提高系统的可靠性。

  6. 资源管理和优化:Kubernetes 提供了丰富的资源管理和优化功能,能够有效地管理和优化应用程序的资源。它支持资源配额、调度策略和资源限制等功能,可以提高资源利用率并降低成本。

  7. 生态系统丰富:Kubernetes 拥有一个庞大的生态系统,提供了丰富的第三方工具和服务,能够满足不同应用场景的需求。它支持容器编排、监控和日志管理等功能,为开发人员和运维团队提供了丰富的选择。

Kubernetes 核心概念#

k8s 系统本身比较复杂,本文目的是零基础快速上手部署一个 laravel 应用,为了便于理解,本文采用的是通熟易懂的方式介绍相关概念,不追求精确。

快速使用 k8s 需求了解以下概念:

  • cluster 集群,整个 k8s 系统就是一个集群,它由 control plane 和 node 组成。

  • control plane,控制节点,负责整个集群的管理,是集群的大脑。

  • node,节点,是运行容器的地方,可以是虚拟机也可以是物理机。

  • pod,容器的最小单元,一个 pod 可以包含一个或多个容器。

  • workload,工作负载,用于定义 pod 的运行方式,按照运行项目的类型不同,可以分为:

    • deployment,用于部署无状态应用,例如 web 服务。

    • statefulset,用于部署有状态应用,例如数据库。

    • daemonset,用于部署系统级别的服务,例如监控。

    • job,用于执行一次性任务,例如数据迁移。

    • cronjob,用于定时执行任务,例如备份。

  • service,服务,用于暴露 pod 的访问方式。

  • ingress,入口,用于定义外部访问服务的规则,可以简单理解为 k8s 中的 nginx。

本地操作环境#

  • docker,作为容器运行时。安装 docker
  • minikube,用于本地快速部署 k8s 集群。k8s 集群的部署比较复杂,minikube 提供了一个简单的方式在本地快速部署一个 k8s 集群。安装 minikube
  • kubectl,用于操作 k8s 集群。 安装 kubectl

上述环境安装完成后,通过以下命令启动 minikube 集群:

minikube start

如果一切正常,可以通过以下命令查看集群状态:

minikube status

正常情况下,输出如下:

minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured

部署 laravel 应用#

在 k8s 中部署一个应用,需要以下步骤:

  • 构建 docker 镜像,将应用打包成一个 docker 镜像。为了简化操作,镜像我已经构建好了(laravel11 应用),registry.cn-shenzhen.aliyuncs.com/what/laravel:0.1
  • 创建 deployment,定义应用的运行方式。
  • 创建 service,暴露应用的访问方式。
  • 创建 ingress,定义外部访问服务的规则。

有 2 种操作 k8s 集群的风格:

  • imperative 风格,直接操作 k8s 集群,适合临时在 k8s 上执行一些操作,例如:kubectl run
  • declarative 风格,通过 yaml 文件定义操作,文本管理起来更方便,例如:kubectl apply -f

通常情况下,我们使用 declarative 风格操作 k8s 集群。也是就是通常 yaml 配置文件的方式。管理 k8s 的运维被笑称为 “yaml 工程师”。

创建 deployment#

deployment 用于定义应用的运行方式。

deployment.yaml 文件内容如下:

apiVersion: apps/v1  
kind: Deployment  # 资源的类型,Deployment,表示无状态应用
metadata:
  name: laravel-deployment  # deployment的名称
  labels:
    app: laravel-deployment  # 资源的标签,用于被其它资源关联,例如service
spec:
  replicas: 2  # 运行的pod数量
  selector:
    matchLabels:
      app: laravel-pod  # 选择器,用于选择关联的pod
  template:
    metadata:
      labels:
        app: laravel-pod  # pod的标签,用于被其它资源关联,例如deployment
    spec:
      containers:
      - name: laravel  # 容器的名称
        image: registry.cn-shenzhen.aliyuncs.com/what/laravel:0.1  # 容器的镜像
        ports:
        - containerPort: 9000  # 容器的端口,镜像中php-fpm监听的端口为9000  

k8s 通过 metadata 下面的自定义 labels 来关联不同的资源。要重点关注。

使用 kubectl apply -f deployment.yaml 命令创建 deployment。

通过 kubectl get -f deployment.yaml 命令查看 deployment 状态。如果一切正常,输出如下:

NAME                 READY   UP-TO-DATE   AVAILABLE   AGE

laravel-deployment   2/2     2            2           4m18s
  • NAME 表示 deployment 的名称,
  • READY 表示当前运行的 pod 数量,
  • UP-TO-DATE 表示 deployment 的更新状态,
  • AVAILABLE 表示可用的 pod 数量,
  • AGE 表示 deployment 存在的时间。

虽然 deployment 已经创建,但是我们还不能访问应用,因为 deployment 只是定义了应用的运行方式,还需要创建 service 暴露应用的访问方式。

创建 service#

service 用于暴露应用的访问方式。

service.yaml 文件内容如下:

apiVersion: v1
kind: Service  # 资源的类型,Service,表示服务
metadata:
  name: laravel-service  # service的名称
  labels:
    app: laravel-service  # 资源的标签,用于被其它资源关联,例如ingress
spec:
  selector:
    app: laravel-pod  # 选择器,用于选择关联的pod
  ports:
  - protocol: TCP  # 端口的协议
    port: 9000  # service的端口
    targetPort: 9000  # pod的端口

执行 kubectl apply -f service.yaml 命令创建 service。

通过 kubectl get -f service.yaml 命令查看 service 状态。如果一切正常,输出如下:

NAME              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE

laravel-service   ClusterIP   10.110.252.32   <none>        9000/TCP   3m11s

输出字段的含义如下:

  • NAME 表示 service 的名称,
  • TYPE 表示 service 的类型,ClusterIP 表示集群内部访问,
  • CLUSTER-IP 表示 service 的 IP 地址,
  • EXTERNAL-IP 表示 service 的外部 IP 地址,
  • PORT (S) 表示 service 的端口,
  • AGE 表示 service 存在的时间。

service 创建完成后,我们可以通过 service 的 CLUSTER-IP 访问应用,但是这样不够友好,我们还需要创建 ingress 定义外部访问服务的规则。

创建 ingress#

ingress 用于定义外部访问服务的规则。

在使用 minikube 时,需要先启用 ingress 插件,执行以下命令:

minikube addons enable ingress # 启动ingress插件

ingress.yaml 文件内容如下:

apiVersion: networking.k8s.io/v1
kind: Ingress  # 资源的类型,Ingress,表示入口
metadata: 
  name: laravel-ingress  # ingress的名称
  annotations: # ingress的注解
   nginx.ingress.kubernetes.io/backend-protocol: "FCGI" # 后端协议
   nginx.ingress.kubernetes.io/fastcgi-index: "index.php" # fastcgi的索引文件
   nginx.ingress.kubernetes.io/fastcgi-params-configmap: "fastcgi-params" # fastcgi的参数,需要提前创建configmap

spec:
  ingressClassName: nginx # ingress的类名
  rules: # ingress的规则
  - http: # http协议
      paths: # 路径
      - path: / # /路径
        pathType: Prefix # 路径类型 prefix 前缀
        backend: # 后端
          service: # 后端服务
            name: laravel-service  # service的名称
            port:
              number: 9000  # service的端口

由于 ingress 的 annotations 中使用了 fastcgi-params-configmap,需要提前创建 configmap。

fastcgi-params.yaml 文件内容如下:

apiVersion: v1
kind: ConfigMap # 资源的类型,ConfigMap,表示配置
metadata:
  name: fastcgi-params # configmap的名称
data:
  SCRIPT_FILENAME:  /laravel-app/public/index.php

执行 kubectl apply -f fastcgi-params.yaml 命令创建 configmap。

执行 kubectl apply -f ingress.yaml 命令创建 ingress。

访问应用#

现在我们已经完成了 laravel 应用的部署,可以通过 ingress 的 CLUSTER-IP 访问应用。

由于我们使用 minikube,全部的资源都是在 minikube 集群的虚拟机中,所以我们需要执行 minikube tunnel 命令创建一个虚拟机到本地的隧道,这样我们就可以通过本地访问 minikube 集群中的资源。

然后可以通过 localhost 访问 laravel 应用。

从零开始部署在 Kubernetes 中部署 Laravel应用(0)

本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 1年前 自动加精
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。