【问题标题】:From Local Docker Setup to Kubernetes Production从本地 Docker 设置到 Kubernetes 生产
【发布时间】:2020-04-23 10:01:01
【问题描述】:

我有一个由四个容器组成的本地 Docker 设置:一个烧瓶网络应用程序、MySQL、Redis 和一个 RQ 工作器。

设置与 Miguel Grinberg 的 Flask Mega-Tutorial 基本相同。这是他的tutorialcode 的链接。

就我而言,唯一的不同是我已经将他在 rq-worker 上运行的导出博客文章功能替换为另一个计算密集型且运行时间长(30 分钟)的功能。

对我来说,将此应用程序部署到生产环境的最佳方式是什么?

我只希望一次只有一两个人访问它,并且他们每周只访问一次或两次。

我一直在研究 Kubernetes 示例,但在将它们转换为我的设置以及弄清楚如何部署到 GCP 时遇到了困难。我对其他部署选项持开放态度。

以下是教程中的 docker run 命令:

docker run --name redis -d -p 6379:6379 redis:3-alpine

docker run --name mysql -d -e MYSQL_RANDOM_ROOT_PASSWORD=yes \
    -e MYSQL_DATABASE=flaskapp -e MYSQL_USER=flaskapp \
    -e MYSQL_PASSWORD=mysqlpassword \
    mysql/mysql-server:5.7
docker run --name rq-worker -d --rm -e SECRET_KEY=my-secret-key \
    -e MAIL_SERVER=smtp.googlemail.com -e MAIL_PORT=587 -e MAIL_USE_TLS=true \
    -e MAIL_USERNAME=example@gmail.com -e MAIL_PASSWORD=mysqlpassword \
    --link mysql:dbserver --link redis:redis-server \
    -e DATABASE_URL=mysql+pymysql://flaskapp:mypassword@dbserver/flaskapp \
    -e REDIS_URL=redis://redis-server:6379/0 \
    --entrypoint venv/bin/rq \
    flaskapp:latest worker -u redis://redis-server:6379/0 dyson-tasks
docker run --name flaskapp -d -p 8000:5000 --rm -e SECRET_KEY=my_secret_key \
    -e MAIL_SERVER=smtp.googlemail.com -e MAIL_PORT=587 -e MAIL_USE_TLS=true \
    -e MAIL_USERNAME=example@gmail.com -e MAIL_PASSWORD=mypassword \
    --link mysql:dbserver --link redis:redis-server  \
    -e DATABASE_URL=mysql+pymysql://flaskapp:mysqlpassword@dbserver/flaskapp \
    -e REDIS_URL=redis://redis-server:6379/0 \
    flaskapp:latest 

【问题讨论】:

  • 您需要将这些 docker run 命令转换为 Kubernetes YAML 文件。不会完全转移的一件事是那些 --link 选项,但无论如何你可能不应该在现代 Docker 中使用该选项。翻译的某个特定部分是否有问题?
  • 我是 Kubernetes 和 Docker 的新手,所以总的来说我不确定我的下一步是什么。考虑到我的用例,我假设 Kubernetes 是一个不错的选择,但我对其他解决方案持开放态度。就 Kubernetes 的发展而言,下一步是将 docker run 命令转换为 YAML 文件是很有帮助的。我知道 --link 选项对于确保容器可以相互通信很重要。我不确定如何使用 Kubernetes 来实现这一目标。

标签: docker flask kubernetes google-cloud-platform production-environment


【解决方案1】:

由于您使用 Kubernetes 和 Google Cloud Platform 标记问题,我希望这是您想要的方向。

部署到云平台时,请考虑使用云就绪存储/数据库解决方案。单节点 MySQL 不是开箱即用的云就绪存储。考虑使用例如Google Cloud SQL 代替。

您的“flask web 应用”可以完美地部署为DeploymentGoogle Kubernetes Engine - 但这要求您的应用是无状态并遵循the twelve-factor app principles

您的 Redis 也可以部署到 Kubernetes,但您需要考虑可用性要求的重要性。如果你不想考虑这个,你也可以使用谷歌管理的 Redis,例如Google memorystore - Redis 的完全托管的内存数据存储服务。

如果您决定使用完全托管的缓存,您可能会使用Google Cloud Run 将您的“flask Web 应用程序”部署为容器 - 这是一个比完整的 Kubernetes 集群更托管的解决方案,但也更受限制。但这里的好处是您只需为请求付费。

【讨论】:

  • 我愿意接受任何部署选项。
  • 越简单/好用越好。 “烧瓶网络应用程序”是无状态的。 Google Cloud Run 的 maximum memory allocation 看起来好像是 2GB。该函数需要 30 分钟才能运行,并在我的本地计算机上使用 >4GB 的 RAM。
【解决方案2】:

我为 GCP/GKE 上的 rq 创建了一个入门项目,该项目应该大致满足您的需求。 https://github.com/crispyDyne/GKE-rq

它由三个工作负载组成:

  • Leader:接收外部流量并将作业排入队列的烧瓶应用。
  • Worker:启动一个 rq worker。
  • 仪表板:提供用于监控队列的仪表板。

一个谷歌内存存储实例用于 redis 服务器。如果您希望以便宜的方式执行此操作,则应该将其换成运行 redis 的容器(但我很懒)。

如何创建内存存储redis实例:https://cloud.google.com/memorystore/docs/redis/quickstart-gcloud

另外,我使用节点端口来公开领导者应用程序,而不是负载均衡器。负载均衡器非常昂贵。对于小型/廉价项目,节点端口应该可以正常工作。


对于新手(比如我)来说,有几个不明显的步骤可以让一切都说清楚。

如何将“Leader”连接到redis队列。

从 GCP 控制台或gcloud redis instances describe ... 获取 redis IP。

在您的烧瓶应用中:

redis_conn = Redis(host={redisIP}, port=6379, db=0)
q = Queue('rq-server', connection=redis_conn)

如何将“Follower”连接到redis队列。

Docker 文件:

FROM python:3
COPY . /app
WORKDIR /app
RUN pip install --no-cache-dir -r requirements.txt
ENV PORT 6379
CMD [ "rq", "worker","--url", "redis://{redisIP}:6379", "rq-server" ]

如何将“Dashboard”连接到redis队列。

Docker 文件:

FROM python:3
COPY . /app
WORKDIR /app
RUN pip install --no-cache-dir -r requirements.txt
ENV PORT 9181
CMD [ "rq-dashboard","-u", "redis://{redisIP}:6379"]

如何通过节点端口公开领导者(或类似的仪表板)。

注意目标端口。对于烧瓶应用程序应该是 8080,对于 rq-dashboard 应该是 9181。

kubectl expose deployment rq-leader --name rq-leader-service /
 --type NodePort --port 80 --target-port 8080

然后打开 {NodePort}。在 GCP 控制台或使用kubectl get services ... 获取节点端口。

gcloud compute firewall-rules create node-port-leader--allow tcp:{NodePort}

【讨论】:

    猜你喜欢
    • 2016-10-10
    • 1970-01-01
    • 2014-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-05
    • 2021-10-30
    • 2013-12-30
    相关资源
    最近更新 更多