使用 Kubernetes 来部署你的 Laravel 程序

Laravel 是开发 PHP 应用程序的优秀框架。 无论您是需要构建新想法的原型,开发 MVP(最小可行产品)还是发布成熟的企业系统,Laravel 都可以促进所有开发任务和工作流程。

如何处理部署应用程序是一个很有选择性的问题。 Vagrant 非常适合搭建类似于远程服务器的本地环境。 但是,在生产环境中,您很可能需要的不仅仅是一个 Web 主机和一个数据库。 您可能会针对多个要求提供单独的服务。 您还需要有适当的机制来确保应用程序始终在线运行,并且服务器可以有效地均衡负载。

在本文中,我将解释如何在 Kubernetes 上搭建一个简单的 Laravel 应用程序的环境。

Kubernetes 是什么?为什么使用它?

Kubernetes 是一款由 Google 发起的开源系统,目的在于提高集群环境下管理容器化应用的效率。有些人将其称为容器编排平台,而 Kubernetes 并非唯一的此类平台。不过,相比其它对手,其享誉已盛,且知名度仍在不断提高;更别说你一旦习惯上它,就会发现它真的十分易用。

如果你依然好奇为何有人能够愉快地和 Kubernetes 玩耍,答案就是——简单。Kubernetes 能够让部署、管理多个项目所需的大量集群变得更加容易。

将 Laravel 应用部署到 Minikube

正如我之前提到的,我将会在本文展示如何部署一个简单、无状态的 Laravel 应用到 Kubernetes。我将详细说明此过程中涉及到的步骤,同时向大家解释为何需要执行某项操作。此外,我还将展示如何快速横向扩展应用,并使用 Ingress Controller 使其能够通过特定域名或 IP 访问。

你可以在多个云平台上面运行 Kubernetes ,例如 Google Cloud Engine 和 Amazon Web Services。在这个例子中,你会使用 Minikube 运行你的程序,Minikube 是一个让你在本地更容易运行 Kubernetes 的工具。

与 Vagrant 类似,Minikube 仅仅是一个包含了 Kubernetes 运行平台和 Docker 的虚拟机。如果使用真正的 Kubernetes 的话,你需要使用 Docker 部署你的应用,同时你需要将运行平台扩展到三个节点。

应用

我已经准备了一个简单的 Laravel 程序,你可以从 GitHub 克隆下来。它只是一个全新的 Laravel 安装程序。因此,你可以使用本例中的演示程序,也可以自己创建一个新的 Laravel 程序。如果使用本例中的演示程序,请按照下面的命令将其克隆到项目目录里面。

cd /to/your/working/directory
git clone [email protected]:learnk8s/laravel-kubernetes-demo.git .
复制代码

预备条件

要实现本示例,你需要在你的本地系统中安装如下软件:

1) Docker

2) Kubectl

3) Minikube

如果你在Windows系统中安装上述软件遇到问题,请查阅 Windows 10 中 Docker 和 Kubernetes 入门教程,这是一个手把手教学的入门教程。

Docker 镜像

Kubernetes 部署容器化的应用,因此首先你需要为示例应用创建一个 Dcoker 镜像。由于本例中你在本地运行 Minikube,因此你只能用示例代码中的 Dockerfile 文件创建一个本地 Docker 镜像。

FROM composer:1.6.5 as build 
WORKDIR /app 
COPY . /app 
RUN composer install
复制代码
FROM php:7.1.8-apache 
EXPOSE 80 
COPY --from=build /app /app 
COPY vhost.conf /etc/apache2/sites-available/000-default.conf 
RUN chown -R www-data:www-data /app \ 
  && a2enmod rewrite
复制代码

该 Dockerfile 文件由两部分组成:

  • 第一部分扩展了一个 PHP 的 composer 镜像,因此你能够安装应用依赖。
  • 第二部分创建了一个包含 Apache 服务的镜像, Apache 服务将会为示例应用服务。

在测试 Docker 镜像前,你需要使用如下的命令创建镜像:

cd /to/your/project/directory 
docker build -t yourname/laravel-kubernetes-demo .
复制代码

然后使用下面的命令运行示例程序:

docker run -ti \ 
  -p 8080:80 \ 
  -e APP_KEY=base64:cUPmwHx4LXa4Z25HhzFiWCf7TlQmSqnt98pnuiHmzgY= \     
  laravel-kubernetes-demo
复制代码

示例程序可以通过 http://localhost:8080 访问。

在这个安装中,容器是通用的,同时 APP_KEY 并不是写死或共享的。

在 Minikube 中创建镜像

cd /to/your/project/directory
eval $(minikube docker-env)
docker build -t yourname/laravel-kubernetes-demo .
复制代码

别忘记执行上面的 eval 命令。 要在虚拟机中创建镜像,执行上面的 eval 命令是必须的。你只需要在当前的终端中执行一次这个命令。

部署镜像

现在示例应用的镜像已经创建完成,并且在 Minikube 中是可用的,因此你可以接下来继续部署这个镜像。

我总是一开始就要确保 kubectl 在正确的上下文环境中。在这个例子中,上下文环境是 Minikube。你可以使用下面的命令快速的切换上下文环境:

kubectl config use-context minikube
复制代码

然后你可以部署容器镜像:

kubectl run laravel-kubernetes-demo \   
        --image=yourname/laravel-kubernetes-demo \   
        --port=80 \   
        --image-pull-policy=IfNotPresent \   
        --env=APP_KEY=base64:cUPmwHx4LXa4Z25HhzFiWCf7TlQmSqnt98pnuiHmzgY=
复制代码

上述的命令告诉 kubectl 从 Docker 镜像中运行我们的示例程序。上述命令的第一个参数告诉 kubectl 如果在本地存在镜像,就不要去登记处(例如 Docker Hub)拉取镜像。请注意,你仍然需要登录到 Docker 中,因为这样 kubectl 才能检查镜像是否是最新的。

通过下面的命令,你会看到有一个 Pod 是为示例程序而创建的:

kubectl get pods
复制代码

该命令会返回类似如下的输出:

NAME                                     READY STATUS RESTARTS AGE
laravel-kubernetes-demo-7dbb9d6b48-q54wp 1/1   Running 0       18m
复制代码

你也可以使用 Minikube 的 GUI 控制面板来监控集群。GUI 还有助于可视化大多数经常讨论的指标。要查看该控制面板,请执行下属命令:

minikube dashboard
复制代码

或者获取控制面板的 URL 地址:

minikube dashboard --url=true
复制代码

暴露一个服务

到目前为止,你已经创建了一个运行示例程序容器的部署。在集群中运行的 Pod 有一个动态的 IP。如果你使用该 IP 并直接把流量路由到那里,在每次重启 Pod 的时候,你可能每次都要更新路由表。事实上,在每次部署或者容器重启的时候,一个新的 IP 会关联到这个 Pod 中。为了避免需要手动的管理 IP 地址,你需要使用服务。服务在 Pods 集合中充当负载均衡器的角色。所以,尽管一个 Pod 的 IP 地址改变了,但是服务总是指向该 Pod。同时,由于服务总是拥有一个固定的 IP,因此你不需要手动更新任何东西。

你可以使用下面的命令创建一个服务:

kubectl expose deployment laravel-kubernetes-demo --type=NodePort --port=80
复制代码

倘若一切顺利,你会看到一个与下面信息相似的确认信息:

service "laravel-kubernetes-demo" exposed
复制代码

执行下面的命令:

kubectl get services
复制代码

上述命令显示了正在运行中的服务列表。你也可以通过控制面板中的 「服务」 导航菜单查看正在运行中的服务。很显然,一个更加令人兴奋的验证部署和服务暴露的方法就是在浏览器中运行示例程序。 ?

要获取应用(服务)的URL地址,你可以使用下面的命令:

minikube service --url=true laravel-kubernetes-demo
复制代码

上述命令会输出 IP 地址和端口号,例如:

http://192.168.99.101:31399
复制代码

或者直接在浏览器中启动程序:

minikube service laravel-kubernetes-demo
复制代码

*不想错过接下来的故事,实验或者小提示。 **如果你欣赏这篇文章,敬请期待接下来更多的文章内容。 希望新的内容直接发到你的邮箱并提升在 Kubernetes 方面的专业技能。 * 现在请订阅

扩展

你已经成功在 Kubernetes 中部署了应用。这是令人兴奋的。但是做这一切的重点是什么?你只是在一个 Pod 中做了一个部署,在一个节点上面暴露了网页服务。让我们把目前的应用多部署两个实例。

现在你应该明白你正在处于什么位置,执行下面的命令获取希望得到的和现在已有的 Pod 列表:

kubectl get deployment
复制代码
NAME                    DESIRED CURRENT UP-TO-DATE AVAILABLE
AGE laravel-kubernetes-demo 1       1       1          1         57m
复制代码

上面的输出中,每一项都是「1」。你希望获得三个 Pod。因此,我们通过下面的命令进行扩展:

kubectl scale --replicas=3 deployment/laravel-kubernetes-demo deployment "laravel-kubernetes-demo" scaled
复制代码

命令执行完成。你已经将第一个 Pod 复制另外两个,系统为你提供了三个 Pod 来运行这个服务。执行 get deployment 可以检验这一切:

kubectl get deployment
复制代码
NAME                    DESIRED CURRENT UP-TO-DATE AVAILABLE
AGE laravel-kubernetes-demo 3       3       3          3         59m
复制代码

你也可以在控制面板中的 Pods 页面或服务页面查看这些内容。

现在,你正在使用三个 Pod 运行三个应用实例。

想象一下这种场景,你的应用越来越受欢迎。成千上万的访客使用你的网页或软件。过去,你可能都焦头烂额在编写脚本创建更多实例的事情上。但是在 Kubernetes 中,您可以快速扩展出多个实例:

kubectl scale --replicas=10 deployment/laravel-kubernetes-demo deployment "laravel-kubernetes-demo" scaled
复制代码

你看看使用 Kubernetes 扩展你的网站是何其便捷。

Ingress

你已经实现了不错的功能,部署了应用并扩展之。当你指向群集的(Minikube)IP地址和节点的端口号时,你就已经可见浏览器中正在运行的程序了。 现在,你将看到如果通过指定的 URL 访问应用程序,就如同之前部署到云端那样。

为了在 Kubernetes 中使用 URL,你需要一个 Ingress。 Ingress 是一组允许入站连接到达 Kubernetes 集群的规则。Ingress 是非常必要的,因为在 Kubernetes 中,诸如 Pod 之类的资源仅具有可在集群内和集群内路由的IP地址。也就是说它们是无法进出外部环境的。

我在演示应用源码中包含了一个有如下内容的 ingress.yaml 文件:

apiVersion: extensions/v1beta1 kind: Ingress metadata:   name: laravel-kubernetes-demo-ingress   annotations: ingress.kubernetes.io/rewrite-target: / spec:   backend:     serviceName: default-http-server     servicePort: 80   rules:   - host: laravel-kubernetes.demo   - http:       paths:       - path: /         backend:           serviceName: laravel-kubernetes-demo           servicePort: 80
复制代码

在你所期望的 Kubernetes 资源文件基本内容里,该文件定义了一组路由流量入站的规则。 laravel-kubernetes.demo URL 会指向应用运行的 Service ,就像之前在 8181 端口上标记 laravel-kubernetes-demo 那样。

没有集成 Ingress 资源, Ingress 控制器是无法使用的,因此您需要创建一个新的控制器或使用现有控制器。 本教程使用的是 Nginx Ingress 控制器来管理路由资源。 Minikube(v0.14及以上版本) 附带 Nginx 设置作为插件,您需要手动启用这个插件:

minikube addons enable ingress
复制代码

注意,Minikube 可能需要几分钟才能下载并安装 Nginx 作为 Ingress 路由控制器。

启用 Ingress 插件后,您可以通过这种方式来创建 Ingress 实例:

kubectl create -f path-to-your-ingress-file.yaml
复制代码

您可以通过运行以下命令来验证并获取 Ingress 的实例信息:

kubectl describe ing laravel-kubernetes-demo-ingress
复制代码

输出一些配置相关的信息:

Name: laravel-kubernetes-demo-ingress 
Namespace: default 
Address: 192.168.99.101 
Default backend: default-http-server:80 () 
Rules:   
  Host Path Backends   
  ---- ---- --------
  *        
       / laravel-kubernetes-demo:8181 (172.17.0.6:8181) 
Annotations:
  rewrite-target: / 
Events: 
Type   Reason Age  From                     Message 
----   ------ ---- ----                     ------- 
Normal CREATE 39s  nginx-ingress-controller Ingress default/laravel-kubernetes-demo-ingress

Normal UPDATE 20s  nginx-ingress-controller Ingress default/laravel-kubernetes-demo-ingress
复制代码

您现在可以通过 minikube IP地址访问应用程序,如上所示。 要通过 URL https://laravel-kubernetes.demo 访问网站应用,您需要在 hosts 文件中添加一条解析记录。

结论

希望这篇文章能帮助您熟悉 Kubernetes 的部署和搭建。 根据我自己的经验,如果你经常进行类似的环境搭建,这会让你的搭建过程更加得心应手且有趣。

转自 PHP / Laravel 开发者社区 laravel-china.org/topics/2201…

你可能感兴趣的:(php,运维,git)