我正在使用一个 Pod(Shiny Proxy),它与 Kubernetes API 通信以启动其他 Pod。我想让这个通用,所以不想硬编码命名空间(因为我打算有多个这样的,可能部署为 OpenShift 模板或类似的)。
我正在使用 Kustomize 在所有对象上设置命名空间。这是我的 kustomization.yaml 的叠加效果:
bases:
- ../../base
namespace: shiny
commonAnnotations:
technical_contact: A Local Developer <somedev@example.invalid>
运行 Shiny Proxy 并让它启动我需要的 Pod(我有服务帐户和 RBAC 已经排序)工作,只要在 Shiny Proxy 的配置中我指定(硬编码)新的命名空间应该在其中生成 pod。Shiny Proxy 将使用的默认命名空间是(不幸的是)'default',这不适合我的需要。
目前我正在使用 ConfigMap 进行配置(也许我应该改用 Kustomize ConfigMapGenerator)
有问题的 ConfigMap 目前如下所示:
apiVersion: v1
kind: ConfigMap
metadata:
name: shiny-proxy
data:
application_yml: |
...
container-backend: kubernetes
kubernetes:
url: https://kubernetes.default.svc.cluster.local:443
namespace: shiny
...
以上有效,但 'shiny' 是硬编码的;我希望能够执行以下操作:
namespace: { .metadata.namespace }
但这在 ConfigMap 中似乎不起作用,而且我在文档中没有看到任何可以让人相信它会起作用的内容,或者在 ConfigMap 机器中可能出现类似的事情。
查看 Kustomize 文档也没有让我感到清晰,特别是因为配置文件本质上是纯文本(就 ConfigMap 而言,它不是 YAML 文档)。我已经看到了一些 Vars 的用法,但 https://github.com/kubernetes-sigs/kustomize/issues/741 让人相信这不是入门。
有没有一种很好的声明方式来处理这个问题?或者我应该希望在容器内实现模板智能,这对我来说似乎有点错误,但我对 Kubernetes(和 OpenShift)还是个新手
我使用的是 CodeReady Containers 1.24 (OpenShift 4.7.2),它本质上是 Kubernetes 1.20 (IIRC)。我更愿意将其与 Kubernetes 保持良好的一致性,而不会过于特定于 OpenShift,但这还为时尚早。
谢谢, 卡梅伦
答案 0 :(得分:1)
如果您不想对清单文件中的特定数据进行硬编码,可以考虑使用 Kustomize plugins。在这种情况下,sedtransformer plugin 可能有用。这是一个示例插件,由 kustomize 维护者维护和测试,但不是 kustomize 内置的。
正如您在 Kustomize plugins guide 中看到的:
Kustomize 提供了一个插件框架,允许人们编写自己的资源生成器和转换器。
有关创建和使用 Kustomize 插件的更多信息,请参阅 Extending Kustomize。
我将创建一个示例来说明如何在您的案例中使用 sedtransformer
插件。
假设我有一个 shiny-proxy
ConfigMap
:
注意:我没有指定命名空间,而是使用 namespace: NAMESPACE
。
$ cat cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: shiny-proxy
data:
application_yml: |
container-backend: kubernetes
kubernetes:
url: https://kubernetes.default.svc.cluster.local:443
namespace: NAMESPACE
something_else:
something: something
要使用 sedtransformer
插件,我们首先需要创建插件的配置文件,其中包含一个 YAML 配置对象:
注意:在 argsOneLiner:
中,我指定 NAMESPACE
应替换为 shiny
。
$ cat sedTransformer.yaml
apiVersion: someteam.example.com/v1
kind: SedTransformer
metadata:
name: sedtransformer
argsOneLiner: s/NAMESPACE/shiny/g
接下来,我们需要将 SedTransformer Bash 脚本放在正确的位置。
<块引用>加载时,kustomize首先会寻找一个名为的可执行文件
$XDG_CONFIG_HOME/kustomize/plugin/${apiVersion}/LOWERCASE(${kind})/${kind}
我创建了必要的目录并从 Github 下载了 SedTransformer
脚本:
注意:下载的脚本必须是可执行的。
$ mkdir -p $HOME/.config/kustomize/plugin/someteam.example.com/v1/sedtransformer
$ cd $HOME/.config/kustomize/plugin/someteam.example.com/v1/sedtransformer
$ wget https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/plugin/someteam.example.com/v1/sedtransformer/SedTransformer
$ chmod a+x SedTransformer
最后,我们可以检查它是否按预期工作:
注意:要使用此插件,您需要提供 --enable-alpha-plugins
标志。
$ tree
.
├── cm.yaml
├── kustomization.yaml
└── sedTransformer.yaml
0 directories, 3 files
$ cat kustomization.yaml
resources:
- cm.yaml
transformers:
- sedTransformer.yaml
$ kustomize build --enable-alpha-plugins .
apiVersion: v1
data:
application_yml: |
container-backend: kubernetes
kubernetes:
url: https://kubernetes.default.svc.cluster.local:443
namespace: shiny
something_else:
something: something
kind: ConfigMap
metadata:
name: shiny-proxy
如果您想在多个位置替换 NAMESPACE
,使用 sedtransformer plugin 尤其有用。
答案 1 :(得分:0)
我发现最简单的方法是在容器中使用入口点脚本,该脚本收集挂载在容器中的向下 API (?) 服务凭据(特别是命名空间机密),并将其公开为环境变量.
export SHINY_K8S_NAMESPACE=`cat /run/secrets/kubernetes.io/serviceaccount/namespace`
cd /opt/shiny-proxy/working
exec java ${JVM_OPTIONS} -jar /opt/shiny-proxy/shiny-proxy.jar
在应用程序配置(shiny-proxy)中,它支持在其配置文件中使用环境变量,因此我可以使用 ${SHINY_K8S_NAMESPACE} 来引用 pod 的命名空间
虽然,我刚刚看到了 fieldRef 的想法(来自 https://docs.openshift.com/enterprise/3.2/dev_guide/downward_api.html),并且可以推广到名称空间以外的事物。
apiVersion: v1
kind: Pod
metadata:
name: dapi-env-test-pod
spec:
containers:
- name: env-test-container
image: gcr.io/google_containers/busybox
command: ["/bin/sh", "-c", "env"]
env:
- name: MY_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
restartPolicy: Never