从零开始部署在 Kubernetes 中部署 Laravel应用(0)
Kubernetes(简称 K8s)是一个用于自动化部署、扩展和管理容器化应用程序的开源平台。它提供了一系列强大的功能,使得开发人员和运维团队能够更轻松地管理容器化应用程序。以下是 Kubernetes 的一些优点:
自动化部署和扩展:Kubernetes 提供了丰富的自动化功能,能够快速、可靠地部署和扩展应用程序。它支持自动扩展、自动故障恢复和自动负载均衡等功能,可以根据应用程序的需求自动调整资源。
高可用性:Kubernetes 架构设计具有高可用性,能够确保应用程序在节点故障或者其他故障情况下保持可用。它支持故障转移、自动重启和自动恢复等功能,可以有效地保障应用程序的可用性。
弹性和可伸缩性:Kubernetes 提供了强大的弹性和可伸缩性功能,能够根据应用程序的负载自动调整资源。它支持水平扩展和垂直扩展,并且能够根据需求动态地调整容器的数量和资源分配。
灵活性和可移植性:Kubernetes 提供了灵活的部署和管理模型,能够在各种环境中运行,包括公有云、私有云和混合云环境。它支持多种容器运行时,包括 Docker、containerd 和 CRI-O,能够容易地迁移和跨平台运行应用程序。
自我修复:Kubernetes 提供了自我修复的功能,能够自动检测和处理容器和节点的故障。它支持自动重启、自动替换和自动缩容等功能,能够有效地减少人工干预并提高系统的可靠性。
资源管理和优化:Kubernetes 提供了丰富的资源管理和优化功能,能够有效地管理和优化应用程序的资源。它支持资源配额、调度策略和资源限制等功能,可以提高资源利用率并降低成本。
生态系统丰富: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应用。
本作品采用《CC 协议》,转载必须注明作者和本文链接
先关注一手,应该是干货
定时任务和队列如何执行