使用 Kubernetes 来部署你的 Laravel 程序

file

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 git@github.com: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,因此你不需要手动更新任何东西。

file

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

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 中做了一个部署,在一个节点上面暴露了网页服务。让我们把目前的应用多部署两个实例。

file

现在你应该明白你正在处于什么位置,执行下面的命令获取希望得到的和现在已有的 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地址。也就是说它们是无法进出外部环境的。


file

我在演示应用源码中包含了一个有如下内容的 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 (<none>) 
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 开发者社区 https://laravel-china.org/topics/22017

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,386评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,142评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,704评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,702评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,716评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,573评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,314评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,230评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,680评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,873评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,991评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,706评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,329评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,910评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,038评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,158评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,941评论 2 355

推荐阅读更多精彩内容