Kubernetes中的层次命名空间:更灵活的资源管理方案

2024/11/5 21:03:23

本文主要是介绍Kubernetes中的层次命名空间:更灵活的资源管理方案,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

大家好!今天要来介绍并亲自示范一下!

在 Kubernetes 中,Namespace 是最基本的单元。它通过创建逻辑分区来组织和隔离资源。通过将资源划分到不同的命名空间中,管理员可以实施安全策略、限制资源的使用,并保持一个干净、有序的环境。

为了在 Kubernetes 中创建一个命名空间,可以按照以下步骤创建命名空间 -

  • 声明式的表达,

也就是说 -

    $ echo "apiVersion: v1
      kind: Namespace
      metadata:
          name: <在这里插入命名空间的名称>" > ns.yaml

    $ kubectl apply -f ns.yaml

或者用命令句式

    $ kubectl create namespace <填写命名空间名称>
Kubernetes命名空间的限制了解一下

命名空间确实非常有用——你可能会发现为每个集群创建很多命名空间。然而,在大规模部署时,众多命名空间可能会带来管理上的麻烦。

考虑以下场景,例如——

场景#1 — 你可能希望多个命名空间应用类似的策略,例如允许同团队成员访问。然而,由于角色绑定在每个命名空间的级别上运行,你将被迫在每个命名空间中单独创建这些角色绑定,这可能会很麻烦并且容易出错。同样的情况也适用于其他策略,例如网络策略和资源限制范围。

场景#2 — 你可能希望某些团队可以自行创建命名空间作为服务的隔离单元。然而,创建命名空间是一项需要集群级别特权的操作,你通常希望严格控制这一特权。

层次命名空间

这些是对 Kubernetes 命名空间的简单扩展,从而解决我们上面讨论的一些不足之处。它通过让用户能够将命名空间组织成树形结构、在这些树中创建新的命名空间以及将策略应用到这些树(或它们的子树)上来解决这些问题。

如下所示,每个都是命名空间

    acme-org  
    ├── 团队A  
    │   └── 服务1

这样做可以让管理具有相同所有权概念的命名空间的集合变得容易。这在多个团队共用但所有者不一定是人的集群中尤其有用。例如,你可能想让一个操作员担当一组命名空间的所有者。

HNC的关键特性

通过HNC(层次命名空间控制)可以实现的一些关键功能包括以下几点:

  • 命名空间层级关系 — HNC 允许在命名空间间创建父子层级关系,使资源管理更加有序和结构化。
  • 配置传播 — 使用 HNC,父命名空间中的配置和策略会自动传播到其子命名空间,无需手动干预。
  • 访问控制 — HNC 简化了层级命名空间设置中基于角色的访问控制(RBAC)的管理,使得在整个层级中执行安全策略更加简单直接。
搭建 HNC 环境

要使用HNC,你首先需要在你的Kubernetes集群中安装HNC扩展插件。

    #安装HNC扩展
    $ kubectl apply -f https://github.com/kubernetes-sigs/hierarchical-namespaces/releases/download/v1.1.0-rc2/default.yaml

    命名空间/hnc-system 创建成功
    自定义资源定义.apiextensions.k8s.io/hierarchicalresourcequotas.hnc.x-k8s.io 创建成功
    自定义资源定义.apiextensions.k8s.io/hierarchyconfigurations.hnc.x-k8s.io 创建成功
    自定义资源定义.apiextensions.k8s.io/hncconfigurations.hnc.x-k8s.io 创建成功
    自定义资源定义.apiextensions.k8s.io/subnamespaceanchors.hnc.x-k8s.io 创建成功
    角色.rbac.authorization.k8s.io/hnc-leader-election-role 创建成功
    集群角色.rbac.authorization.k8s.io/hnc-admin-role 创建成功
    集群角色.rbac.authorization.k8s.io/hnc-manager-role 创建成功
    角色绑定.rbac.authorization.k8s.io/hnc-leader-election-rolebinding 创建成功
    集群角色绑定.rbac.authorization.k8s.io/hnc-manager-rolebinding 创建成功
    秘钥/hnc-webhook-server-cert 创建成功
    服务/hnc-controller-manager-metrics-service 创建成功
    服务/hnc-webhook-service 创建成功
    部署.apps/hnc-controller-manager 创建成功
    变更挂钩配置.admissionregistration.k8s.io/hnc-mutating-webhook-configuration 创建成功
    验证挂钩配置.admissionregistration.k8s.io/hnc-validating-webhook-configuration 创建成功

如果没有安装 krew,请先安装它,接着安装 hns 的 kubectl 插件。

    $ (  
      set -x; cd "$(mktemp -d)" &&  
      OS="$(uname | tr '[:upper:]' '[:lower:]')" &&  
      ARCH="$(uname -m | sed -e 's/x86_64/amd64/' -e 's/\(arm\)\(64\)\?.*/\1\2/' -e 's/aarch64$/arm64/')" &&  
      KREW="krew-${OS}_${ARCH}" &&  
      curl -fsSLO "https://github.com/kubernetes-sigs/krew/releases/latest/download/${KREW}.tar.gz" &&  
      tar zxvf "${KREW}.tar.gz" &&  
      ./"${KREW}" install krew  
    )  

    +-zsh:590> mktemp -d  
    +-zsh:590> cd /var/folders/2l/fvc8dgl91yl9k6d3nxjhhykm0000gp/T/tmp.2LxeHmdC  
    +-zsh:591> OS=darwin  
    +-zsh:592> ARCH=amd64  
    +-zsh:593> KREW=krew-darwin_amd64  
    +-zsh:594> curl -fsSLO https://github.com/kubernetes-sigs/krew/releases/latest/download/krew-darwin_amd64.tar.gz  
    +-zsh:595> tar zxvf krew-darwin_amd64.tar.gz  
    x ./LICENSE  
    x ./krew-darwin_amd64  
    +-zsh:596> ./krew-darwin_amd64 install krew  
    添加来自的 'default' 插件索引: https://github.com/kubernetes-sigs/krew-index.git。  
    更新本地插件索引副本。  
    安装插件: krew  
    已安装插件: krew  
    \  
     | 使用此插件:  
     |  kubectl krew  
     | 文档:  
     |  https://krew.sigs.k8s.io/  
     | 注意事项:  
     | \  
     |  | krew 已安装!要开始使用 kubectl 插件,您需要将 krew 的安装目录添加到您的 PATH 中:  
     |  |  
     |  |   * macOS/Linux:  
     |  |     - 在您的 ~/.bashrc 或 ~/.zshrc 中添加以下内容:  
     |  |         export PATH="${KREW_ROOT:-$HOME/.krew}/bin:$PATH"  
     |  |     - 重新启动您的 shell。  
     |  |  
     |  |   * Windows: 将 %USERPROFILE%\.krew\bin 添加到您的 PATH 环境变量中  
     |  |  
     |  | 要列出 krew 命令并获取帮助,请运行:  
     |  |   $ kubectl krew  
     |  | 要查看所有可用的插件,请运行:  
     |  |   $ kubectl krew search  
     |  |  
     |  | 您可以在以下网址找到文档:  
     |  |   https://krew.sigs.k8s.io/docs/user-guide/快速入门/。  
     | /  
    /
    $ kubectl krew update && kubectl krew install hns  

    插件索引已更新。  
    正在安装插件:hns  

    插件 hns 已安装  
    \  
     | 使用此插件:  
     |  kubectl hns  
     | 文档:  
     |  https://github.com/kubernetes-sigs/hierarchical-namespaces/tree/master/docs/user-guide  
     | 重要提示:  
     |  | 效果最佳是在集群中使用HNC的最新小版本时。在以下位置获取最新版本的HNC,以及此插件的先前版本:  
     |  |  
     |  |   https://github.com/kubernetes-sigs/hierarchical-namespaces  
     |  |  
     |  | 请注意以下常见的误解:  
     |  |  
     |  | * 并非所有子命名空间都是子命名空间!  
     |  | * 默认情况下,仅传播RBAC角色和角色绑定,但您可以进行更多配置。  
     |  |  
     |  | 用户指南中有更多详细信息。  
     | /  
    /  
    警告:您从krew-index插件存储库中安装了插件 "hns"。  
       这些插件并未经过Krew维护者的安全审查。  
       自行承担风险运行它们。

抗议活动
设置父级与子级关系及RBAC的传播

假设你有一个叫“ _acme-org”的组织。我们会为它创建一个根命名空间。

$ kubectl create namespace acme-org  
namespace/acme-org 已创建

接下来,我们将为该组织中的一个团队创建一个命名空间,并将其命名为“team-a”。

    $ kubectl 创建一个命名空间 team-a  
    命名空间 team-a 创建成功

还有另一个命名空间用于该团队拥有的服务。默认情况下,它们之间没有任何关系。

    $ kubectl create namespace service-1  
    namespace/service-1 已创建

假设我们要让某人成为团队a的SRE(即站点可靠性工程师),因此我们需要创建一个RBAC角色。

    $ kubectl -n team-a create role team-a-sre --verb=update --resource=deployments  
    role.rbac.authorization.k8s.io/team-a-sre 创建完成.

以及绑定到该角色的RoleBinding。

    $ kubectl -n team-a create rolebinding team-a-sres --role team-a-sre --serviceaccount=team-a:default  
    rolebinding.rbac.authorization.k8s.io/team-a-sres 已创建

类似地,比如说,我们可能希望在整个组织中建立一个超级SRE小组,因此需要为相同的设置角色和相应角色绑定。

    $ kubectl -n acme-org create role org-sre --verb=update --resource=deployments  
    角色 'org-sre' 已创建  

    $ kubectl -n acme-org create rolebinding org-sres --role org-sre --serviceaccount=acme-org:default  
    角色绑定 'org-sres' 已创建

显然,这都不会对“service-1”产生影响,因为它是一个完全独立的命名空间,并且RBAC仅在命名空间级别起作用。

    $ kubectl -n service-1 get rolebindings  
    在 service-1 命名空间里找不到任何角色绑定。

这样 HNC 就派上用场了。我们把 “acme-org” 设置成 “team-a” 的上级。

    $ kubectl hns set team-a --parent acme-org  
    设置了团队 team-a 的父级为 acme-org  
    成功更新了团队 team-a 分层配置中的 1 个属性

其中“team-a”是“service-1”的父节点

kubectl hns set service-1 --parent team-a

把 service-1 的父级设置成 team-a  
成功更新了 service-1 的一个层级配置属性

现在让我们展示确保一切都如我们所愿的层级。

$ kubectl hns tree acme-org  

acme-org  
└── team-a  
    └── service-1

现在再检查一下“service-1”,我们会看到角色及其绑定已经从祖先命名空间传递到了子命名空间中。

    $ kubectl -n service-1 describe roles  
    名称:         org-sre  
    标签:         app.kubernetes.io/managed-by=hnc.x-k8s.io  
                  hnc.x-k8s.io/inherited-from=acme-org  
    注释:        <none>  
    规则:  
      资源                非资源URL         资源名         操作  
      ---------         -----------------  ---------  -----  
      deployments.apps  []                []         [更新]  

    名称:         team-a-sre  
    标签:         app.kubernetes.io/managed-by=hnc.x-k8s.io  
                  hnc.x-k8s.io/inherited-from=team-a  
    注释:        <none>  
    规则:  
      资源                非资源URL         资源名         操作  
      ---------         -----------------  ---------  -----  
      deployments.apps  []                []         [更新]  

    $ kubectl -n service-1 get rolebindings  
    名称          角色绑定              创建时间  
    org-sres      角色绑定/org-sre      25s  
    team-a-sres   角色绑定/team-a-sre   25s
层级修改,及子命名空间的创建

让我们在“acme-org”内创建一个新空间,名字叫“team-b”吧。

这次我们不自己创建命名空间,而是让HNC(Hierarchical Namespace Controller)来创建。如果你在管理一个子树,但没有在整个集群中创建命名空间的权限,这会非常有用。

    $ kubectl hns create team-b -n acme-org  
    成功在“acme-org”命名空间中创建了“team-b”子命名空间锚

以下是所需设置确认。我们期望的设置确认 -

(Note: Given the expert's suggestion to remove the hyphen and use a period, and also to avoid repetition, the final translation would ideally be: "以下是所需设置的确认。")

Thus, the most appropriate translation is:
以下是所需设置的确认。

$ kubectl hns tree acme-org  
acme-org  
├── team-a  
│   └── service-1  
└── [s] team-b ([s] 表示子命名空间)

比如说,“_team-b”有点奇怪,他们把他们的SRE称为“法师”,所以我们也将为他们的角色安排好。

    $ kubectl -n team-b create role team-b-wizard --verb=update --resource=deployments  
    role.rbac.authorization.k8s.io/team-b-wizard 已创建

    $ kubectl -n team-b create rolebinding team-b-wizard --role team-b-wizard --serviceaccount=team-b:default  
    rolebinding.rbac.authorization.k8s.io/team-b-wizard 已创建

现在,如果我们把这个服务(service-1)分配给新的团队(team-b)的话——

    $ kubectl hns set service-1 --parent team-b  
    将 service-1 的父级从 team-a 改为 team-b  
    成功更新了 service-1 的一个配置属性

而且可以验证角色及其角色绑定也已经更新了。

    $ kubectl -n service-1 get roles  
    NAME         创建日期  
    org-sre      2023-04-09T02:16:51Z  
    team-a-sre   2023-04-09T02:16:51Z  

    $ kubectl -n service-1 get rolebindings  
    NAME          角色         年龄  
    org-sre      角色:org-sre      84s  
    team-a-sre   角色:team-a-sre   84s
分享各类资源

HNC不仅限于RBAC。任何Kubernetes资源都可以配置为在层级中传播,默认情况下,只有RBAC对象会被传播。

比如说,“ service-1 ”中的工作负载需要一个名为my-creds的秘密凭证,每个团队的my-creds都不一样。

让我们在“团队-b”里创建那些凭据——

kubectl -n team-b create secret generic my-creds --from-literal=password=iamteamb, secret/my-creds 创建完毕

如果你使用这个命令检查“_service-1_”中存在的 secrets,你会发现 secret 并没有在 service-1 中显示出来,这个是因为我们还没有在 HNCConfiguration 中配置 HNC 来传播 secrets。

$ kubectl -n service-1 get secrets  
NAME                  TYPE                                  DATA   已运行时间  
default-token-7qvr8   kubernetes.io/service-account-token   3      40m
默认token-7qvr8 是 Kubernetes 服务账号的token,数据有3项,已经运行了40分钟。

为了让这个功能正常工作,你需要更新HNC的配置对象,这是HNC整体的一个集群范围内的配置。要做到这一点,只需使用config子命令即可。

$ kubectl hns config set-resource secrets --mode Propagate
# 设置secrets资源的模式为Propagate

现在,我们应该能够验证我的凭证是否已传递到服务-1。

$ kubectl -n service-1 get secrets  
NAME                  TYPE                                  DATA   AGE  
default-token-7qvr8   kubernetes.io/service-account-token   3      41m  
my-creds              Opaque                                1      7s
异常(比如在编程中遇到的问题)

(注:此处“异常”指技术或编程中的“异常”(cháoyí),而非更口语化的“异常”(yíchánɡ))

现在假设你的acme-org有一个秘密,你想和所有团队分享。我们创建这个秘密如下:

$ kubectl -n acme-org create secret generic my-secret --from-literal=password=iamacme  
secret/my-secret 已创建

你会发现“_my-secret_”会传递到“_team-a_”和“_team-b_”——

    $ kubectl -n team-a get secrets  
    NAME                  TYPE                                  DATA   AGE  
    default-token-n99bx   kubernetes.io/service-account-token   3      45m  
    my-secret             Opaque                                1      22s  

    $ kubectl -n team-b get secrets  
    NAME                  TYPE                                  DATA   AGE  
    default-token-gs449   kubernetes.io/service-account-token   3      42m  
    my-secret             Opaque                                1      24s

但现在我们在“_team-b”开始运行一个不可信的服务,因此我们不再与它分享那个秘密了。这样一来,我们可以通过设置秘密的传播选择器来实现。

$ kubectl annotate secret my-secret -n acme-org propagate.hnc.x-k8s.io/treeSelect='!team-b'  
secret/my-secret 已标注为

现在你看不到秘密可以从“ _team-b _”访问了。如果我们再在“ _team-b _”下添加任何孩子节点,秘密也不会传递给这些新添加的节点。

    $ kubectl -n team-b get secrets  # 此命令行输出展示了Kubernetes集群中team-b命名空间下的密钥信息。
    名称                  类型                                  数据项   存活时间  
    default-token-gs449   kubernetes.io/service-account-token   3      43m
    # 注:kubernetes.io/service-account-token 是Kubernetes中的一个特定术语,指服务账号令牌。
最后的思绪

在这篇博客中,我们探讨了 Kubernetes 中层级命名空间的强大功能,它简化了命名空间管理,并提供了一种更结构化的组织集群资源的方式。通过实施层级命名空间控制器 (HNC),管理员可以轻松管理命名空间的父子关系,传播配置和资源设置,并在整个层次结构中实施访问控制策略。

随着容器化应用程序复杂度的增加,采用层次化命名空间的理念可以有助于简化管理并增强您 Kubernetes 环境中的安全性。通过将 HNC(层次化命名空间控制器)集成到您的工作流程中,这将帮助您更好地管理大规模命名空间,从而实现更高效、更可扩展的部署。

一如既往地,紧跟 Kubernetes 及其生态系统最新进展对于保持 Kubernetes 和其生态系统的稳健和高效至关重要。继续探索、学习和实验,来充分发掘 Kubernetes 基础设施的潜力。祝您玩转容器化!

&#128075; 请点击下面的&#128079;赞按钮几下以支持作者&#128071;
&#128640;加入FAUN开发者社区吧!每周都能在邮箱里收到类似的故事。链接


这篇关于Kubernetes中的层次命名空间:更灵活的资源管理方案的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程