【问题标题】:Containerizing a Flask microservice in Kubernetes在 Kubernetes 中容器化 Flask 微服务
【发布时间】:2020-08-03 09:14:11
【问题描述】:

一段时间以来,我一直在使用Flask 编写微服务的Kubernetes 集群工作,我不确定我当前将它们容器化的方法是否正确。

我一直使用this 图像作为基础。

但我一直看到各种帖子说这样的事情可能有点矫枉过正。

我遇到的问题是,每当我查找有关使用FlaskKubernetes 的文章时,他们总是跳过实际容器的细节并专注于构建集群,这是我已经拥有的扎实的把柄。我想我想知道是否有更好的方法来为单个 Flask 应用程序构建 docker 映像,因为很难找到直接的答案。

【问题讨论】:

标签: python docker flask kubernetes microservices


【解决方案1】:

“更好”完全是相对的,但这是我使用的。

FROM python:3.7 AS build

ENV PYTHONFAULTHANDLER=1 \
    PYTHONUNBUFFERED=1 \
    PYTHONHASHSEED=random \
    PIP_NO_CACHE_DIR=off \
    PIP_DISABLE_PIP_VERSION_CHECK=on \
    PIP_DEFAULT_TIMEOUT=100

RUN pip install poetry==1.0.5

WORKDIR /app
COPY poetry.lock pyproject.toml /app/
RUN poetry config virtualenvs.create false && \
    poetry install --no-dev --no-interaction --no-ansi


FROM gcr.io/distroless/python3-debian10

WORKDIR /app
ENV PYTHONPATH=/usr/local/lib/python3.7/site-packages/
COPY --from=build /usr/local/lib/python3.7/site-packages/ /usr/local/lib/python3.7/site-packages/
COPY . /app

CMD ["-m", "myapp"]

-m 入口点看起来像:

from . import create_app

application = create_app()


def main() -> None:
    import sys
    from twisted import logger  # type: ignore
    from twisted.internet import reactor  # type: ignore
    from twisted.internet.endpoints import TCP4ServerEndpoint  # type: ignore
    from twisted.python import threadpool  # type: ignore
    from twisted.web.server import Site  # type: ignore
    from twisted.web.wsgi import WSGIResource  # type: ignore
    from prometheus_client.twisted import MetricsResource  # type: ignore

    observers = [logger.textFileLogObserver(sys.stdout)]
    logger.globalLogBeginner.beginLoggingTo(observers)
    logger.Logger().info("myapp starting on :8000")

    pool = threadpool.ThreadPool()
    reactor.callWhenRunning(pool.start)
    django_resource = WSGIResource(reactor, pool, application)
    django_site = Site(django_resource)
    django_endpoint = TCP4ServerEndpoint(reactor, 8000)
    django_endpoint.listen(django_site)
    metrics_resource = MetricsResource()
    metrics_site = Site(metrics_resource)
    metrics_endpoint = TCP4ServerEndpoint(reactor, 9000)
    metrics_endpoint.listen(metrics_site)
    reactor.run()
    pool.stop()


if __name__ == "__main__":
    main()

【讨论】:

  • 感谢您的回答!您能否详细介绍一下这里发生了什么?
  • 在什么情况下?它是一个 dockerfile 和一个使用 Twisted 的基于线程的 Web 服务器。
【解决方案2】:

我明白你的意思,你认为你的 docker 图像创建方法可能是错误的。

构建 docker 镜像时的主要思想。该图像应该只有您的依赖项。正如您所说,找到答案很难,因为我们不知道您的要求,也许您的 dockerfile 是唯一的方法。

我推荐你阅读这份文件。 我阅读了这份文档,我的 docker 图像确实得到了改进。我想它会对你有所帮助。

https://drive.google.com/file/d/16t_-DRTohzyVPJy6Cx8a3PxLQ-95CfYK/view

当我检查你的 dockerfile;我只注意到了,我想分享给你;

https://github.com/tiangolo/uwsgi-nginx-flask-docker/blob/master/docker-images/python3.7.dockerfile#L5

第 5 行不应该那样执行。 dockerfile 不应该经常更新,每个依赖都应该有版本。

我就是这样构建这个图像的。

我将所有依赖项都写入 req.txt 和版本。

req.txt

flask==1.1.1

Dockerfile

+ COPY req.txt .
+ RUN pip install -r req.txt

我还想在 bash 脚本中执行 5 到 28 之间的行。

重要信息;我的经理不想要 Dockerfile 中的注释行。当她读到它时,她想明白。她想要简单易读的 docker 文件。 :) 她是个聪明人。你应该让你的 dockerfile 保持简单,它应该在没有任何注释行的情况下被理解。

【讨论】:

    猜你喜欢
    • 2018-07-28
    • 2021-12-10
    • 2020-09-27
    • 2018-09-27
    • 2018-10-25
    • 2019-03-23
    • 1970-01-01
    • 2019-02-20
    • 1970-01-01
    相关资源
    最近更新 更多