【问题标题】:kubernetes - How best to isolate resources based on environment, labels and selectors or namespacing?kubernetes - 如何最好地根据环境、标签和选择器或命名空间隔离资源?
【发布时间】:2021-07-10 19:23:20
【问题描述】:

我在使用 k8s 时遇到了一个相当新手的问题。我对 k8s 尤其陌生,并为集群中的 Django - celery - redis 应用程序设置登台和生产服务/部署。然而。兴奋地发现我确实设法让某些东西发挥作用,我没有检查它是否 100% 正确。

基本上,我注意到预生产的 Django 应用程序在调度周期性任务时并不关心它引用了哪个 celery 部署。它可能会进入暂存阶段,它可能会尝试预生产部署。 这很糟糕。

所以,我一直在研究标签和选择器,以及命名空间。

但是,我可能应该放慢速度——我的第一个问题是,我将如何使用 k8s 原生的东西来运行不同的部署环境,以使它们彼此隔离。所以预生产的 Django 应用程序只能与预生产的 celery-worker 或预生产的 celery-beat 部署对话......

*我觉得我的答案是使用标签和选择器?但是……最好使用命名空间吗?

围绕这个主题的任何专业指导都会令人惊叹。

【问题讨论】:

    标签: kubernetes


    【解决方案1】:

    您可以为每个环境使用一个命名空间,然后确保在调用另一个服务时始终使用单个服务名称的 dns 简写。

    但是,这不会限制特定服务在另一个命名空间/环境中调用另一个服务。如果您是唯一的开发者,或者信任所有其他人,这可能没问题。

    另一种选择是运行不同的集群,但运行方式相同。当您的部署数量增加时,您可能最终还是会遇到这种情况。 这样一来,您可以为每个团队或每个域拥有一个命名空间,并且它在所有环境中看起来都相同。

    【讨论】:

    • 我应该提到的是,目前还没有为每个环境运行一个集群是一项成本要求。我的后续问题可能与问题相同 - 因此,我如何将部署限制为仅与实际中的其他特定服务/部署进行对话?
    • 是不是跟指定命名空间一样简单?
    • 如果您不需要任何 k8s 保护,您可以直接为每个环境创建一个命名空间,然后在其中运行您的部署和服务。
    • 如果您确实需要在命名空间之间实施保护,我建议您查看kubernetes.io/docs/concepts/services-networking/…
    【解决方案2】:

    除了为每个环境创建一个新集群外,您还可以按命名空间或仅在一个命名空间中的不同堆栈来分离部署。最后一种情况(你现在使用的那个)是最容易击中腿部的,因为你必须改变很多东西才能使它孤立。至少您需要一组不同的资源名称(在清单和配置中)和标签来匹配。

    在这三种方法中,我认为命名空间分离是最简单的;它适用于基于 DNS 的服务发现。假设您在两个不同的命名空间(例如dev 和prod)中有一个redis 和您的应用程序的副本。应用程序的两个实例都配置为使用redis:6379 的r​​edis。当他们调用 DNS 来解析主机名时,CoreDNS(内部 DNS 服务)会根据请求来自哪个命名空间来响应不同的答案。因此,dev 命名空间中的应用程序将在 dev 命名空间中获得 redis 的 IP 地址,并且来自 prod 命名空间的应用程序将联系来自 prod 命名空间的 redis。此方法不施加任何限制,如果您希望您可以专门使这两个应用程序使用相同的 redis 副本。为此,您必须使用完整的服务 DNS 名称,而不是 redis:6379,如下所示:

    redis.<namespace>.svc.cluster.local:6379

    无论您选择哪种方法,我强烈建议您熟悉Kustomize、Helm,或两者兼而有之。这些工具旨在帮助您避免重复资源清单,从而减少生成和管理实例的时间。我会给你一个Kustomize 的最小示例,因为它是在kubectl 中构建的。考虑以下目录结构:

    .
    ├── bases
    │   └── my-app
    │       ├── deployment.yml # your normal deployment manifest
    │       └── kustomization.yml
    └── instances
        ├── prod
        │   ├── kustomization.yml
        │   └── namespace.yml # a manifest that creates 'prod' namespace
        └── test
            ├── kustomization.yml
            └── namespace.yml # a manifest that creates 'test' namespace
    

    bases 是您保留应用程序非特定骨架的位置。这并不意味着要部署,就像必须实例化的类一样。 instances 用于描述应用程序的各种实例。实例是用来部署的。

    bases/my-app/kustomization.yml:

    # which manifests to pick up
    resources:
      - deployment.yml
    

    instances/prod/kustomization.yml:

    # refer what we deploy
    bases:
      - ../../bases/my-app
    resources:
      - namespace.yml
    # and this overrides namespace attribute for all manifests referenced above
    namespace: prod
    

    instances/test/kustomization.yml:

    # the same as above, only the namespace is different
    bases:
      - ../../bases/my-app
    resources:
      - namespace.yml
    namespace: test
    

    现在,如果您进入instances 目录并使用kubectl apply -k prod,您将部署deployment.yml 到prod 命名空间。同样kubectl apply -k test 会将其部署到test 命名空间。

    这就是您如何在不同的命名空间中创建应用程序堆栈的多个相同副本的方法。除非涉及来自其他命名空间的一些共享资源,否则它应该是相当隔离的。换句话说,如果您为每个命名空间部署每个组件(例如数据库),并且这些组件未配置为从其他命名空间访问组件 - 它将按预期工作。

    我鼓励您阅读更多关于 Kustomize 和 Helm 的内容,因为命名空间覆盖只是它们可以做的基本事情。您可以管理标签、配置、名称、堆栈组件等。

    【讨论】:

      猜你喜欢
      • 2017-09-23
      • 2018-05-20
      • 2021-02-13
      • 1970-01-01
      • 2019-10-27
      • 2015-12-21
      • 1970-01-01
      • 1970-01-01
      • 2021-12-11
      相关资源
      最近更新 更多