如何为 Web 应用程序构建 Kubernetes 项目?

How to structure a Kubernetes Project for a Web Application?

我喜欢用 kubernetes 创建一个应用程序。

我应该如何构建我的项目?
每个应用程序应该在它自己的存储库中还是应该使用 monorepo?
我应该把 k8s.yaml 放在哪里(因为它涉及所有项目)?
我应该在哪里应用 k8s 配置?它应该在每次部署时发生吗? 如何轻松为每个服务配置域名?

这实际上取决于您的用例,但我会建议一些让生活更轻松的做法:

I'd like to put the api and the frontend in the same pod, and all the scrapers in other pod.

不要在同一个 pod 中放置多个容器(除非它是 sidecar,例如 conduit、istio 等...),因为很难对您的 pods 执行健康检查(如果一个容器已关闭而另一个容器已启动,则 pod 是...半健康状态?)

I'd like to be able to deploy a single project, only the api for example or a specific scraper.

Where should I keep the k8s.yaml (since it relates to all projects)?

将 yaml 文件分离到它们自己的项目目录中,以便您可以独立部署它们并提高可读性。

使用 monorepo 有它的优势,代码在一个地方,等等......但是如果你有 CI,随着 repo 变大,你的构建可能会变慢,所以你要么需要优化(使用构建缓存等)或为您可能拥有的每个业务域或逻辑组设置单独的 CI。

How should I structure my project?

将基础架构与应用程序分开,这样如果有一天您想要从 GCE 切换到 AWS 或 Azure,并且还可以提高可读性。

Where should I apply the k8s configurations? Should it happen on each deploy? How can I config domain names for each service easily?

Kubernetes 有一个非常广泛的示例列表,介绍了您可以将配置注入应用程序的所有方式,这实际上取决于您的用例。 不需要为每个服务都配置域名,只需要对外暴露的就可以了。您可以使用 Ingress 对象或代理。

您需要考虑的事项:

Logging - 这是一个非常重要的主题,因为具有可扩展性 pods 可能是一件棘手的事情。我真的会花时间部署一些紧密的分布式日志记录。

环境 - Develop/Production 或 Develop/Staging/Production 或...?无论您选择什么,请确保它们之间的差异最小,并且每个步骤都可以轻松部署。

有几点:

I'd like to put the api and the frontend in the same pod, and all the scrapers in other pod.

没关系。只要它们在同一个 pod 中的不同容器上。多容器 pods 可以通过本地主机地址相互访问。和 pods 可以通过 DNS 相互查看。 (是的,一半健康意味着不健康)

How should I structure my project?

我对不同的容器使用不同的回购协议。但它对每个 pod = 1 repo 没问题。 这种方式更易于维护,并且您拥有单独的 CI/CD 版本,可以让您分别更新每个应用程序。将每个部署清单 YAML 文件存储在存储库的根目录中是个好主意。因为一个 Deployment 意味着 1 个应用程序(一组 pods)。

Where should I apply the k8s configurations? Should it happen on each deploy? How can I config domain names for each service easily?

在部署清单文件中,您可以将配置存储在 ENV 中或使用配置映射。您不需要为每个部署使用 kubectl apply。 在您的 CI 中,您可以为每个部署执行此操作:

- docker build -t {registry}:{version} .
- docker push {registry}:{version}
- kubectl set image deployment/{API_NAME} {containername}={registry}:{version} -n {NAMESPACE}

您需要在 API 前面设置一个反向代理作为网关,最好的选择是易于部署和配置的 Ingress。它知道你的 pods。 入口配置可以是这样的:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: api
  namespace: production
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: api.yourdomain.com
    http:
      paths:
      - path: /application1
        backend:
          serviceName: app1-production
          servicePort: 80 
      - path: /application2
        backend:
          serviceName: app2-production
          servicePort: 80 

或每个 api 使用一个子域,随您喜欢。