如果 Kubernetes 命名空间不存在,如何创建它?

Rad*_*Rad 15 kubernetes

这是一个简单的问题,但我可以找到一个明确的答案。是否可以仅在命名空间不存在时创建命名空间。我的目标是创建一些服务帐户而不关心它们的命名空间是否存在(如果不存在,那么它们应该即时创建)。
问题是我正在使用 CDK 部署一些基本的 K8S 资源(包括服务帐户)。为了安全地做到这一点,我需要确保命名空间(在服务帐户清单中给出)已经存在。但是我找不到任何解决方案。
我试过了patch,但它似乎期望资源已经存在(即它失败并NotFound出现错误)。

两个限制:
一。我无法查询名称空间是否存在。
湾 我无法使用,apply因为我没有命名空间的确切定义。

有没有办法实现这一目标?

Man*_*uel 30

除了以下代码片段外,我不会寻求任何其他解决方案:

kubernetes 1.19 及以上(包含)

kubectl create namespace <add-namespace-here> --dry-run=client -o yaml | kubectl apply -f -
Run Code Online (Sandbox Code Playgroud)

kubernetes 1.18 及以下(包含)

kubectl create namespace <add-namespace-here> --dry-run -o yaml | kubectl apply -f -
Run Code Online (Sandbox Code Playgroud)

它在试运行中创建一个命名空间并将其输出为 yaml。输出将作为标准输入传递给 kubectl apply -f -

最后一个连字符在传递 kubectl 以从 stdin 读取时很重要。

另请参阅以下示例:

kubectl apply --help
Run Code Online (Sandbox Code Playgroud)

  • 也许,如果您感叹“除了我的解决方案之外,我不会寻求任何其他解决方案......”您应该提供一个原因。我们使用“helm Upgrade”进行部署,因此添加“--create-namespace”是最简单、最合适的解决方案。 (4认同)
  • --dry-run 已弃用,可以用 --dry-run=client 替换 (3认同)
  • 为什么我们在 2021 年会有如此大的开销? (2认同)
  • 请注意,如果您想要使用此命令处理现有的 NS,它会抛出“警告:资源命名空间/ccs-bapi 缺少 kubectl.kubernetes.io/last-applied-configuration 注释,这是 kubectl apply 所需的。” kubectl apply 只能用于通过 kubectl create --save-config 或 kubectl apply 以声明方式创建的资源。缺少的注释将自动修补。` - k8s 1.26 (2认同)

Cor*_*y P 12

我能够使用以下方法解决这个问题:

myNamespace="new-namespace"
kubectl get namespace | grep -q "^$myNamespace " || kubectl create namespace $myNamespace
Run Code Online (Sandbox Code Playgroud)

该命令kubectl get namespace给出如下输出:

NAME                STATUS   AGE
alpha               Active   29m
default             Active   112m
gatekeeper-system   Active   111m
kube-node-lease     Active   112m
kube-public         Active   112m
kube-system         Active   112m
some-branch         Active   26m
something           Active   7m28s
something-else      Active   5m7s
Run Code Online (Sandbox Code Playgroud)

然后, | grep -q "^$my-namespace "将在输出中查找您的名称空间。如果找到您的命名空间,这q将导致命令返回 a 。0否则它会返回一个1.

注意:开头^和结尾的空白很重要。这确保了整个命名空间的匹配,而不仅仅是其中的一部分。例如,如果您正在搜索名称空间something并且末尾不包含空格,则它将匹配上面示例中的something和。something-else

最后, || kubectl create namespace $my-namespace如果找到名称空间(即 grep 返回1),将创建名称空间。否则,将不会被创建。


Arg*_*dhu 6

鉴于限制,我只能想到一种方法,即在应用服务帐户 yaml 之前始终应用命名空间 yaml。如果命名空间已经存在,它会给你一条消息namespace already exists。你可以忽略该消息并继续。

apiVersion: v1
kind: Namespace
metadata:
  name: test
Run Code Online (Sandbox Code Playgroud)

所以在这里我们是声明性的,什么存在什么不重要都没有关系。您只需定义所需的状态应该是什么样子,kubernetes 将负责确保发生这种情况。


Mar*_*coK 5

@Panoptik 和 @Arghya Sadhu 突出显示的选项让我在部署管道中使用了这个衬垫:

echo -e "apiVersion: v1\nkind: Namespace\nmetadata:\n  name: ${NS_NAME}" | kubectl 
apply -f - 
Run Code Online (Sandbox Code Playgroud)

为什么是单衬:我需要避免管道中的换行。该代码在 Debian 和官方 Google Cloud Build 映像“gcloud”上进行了测试。