问题描述
我要把一个helm chart在多个namespace中部署,但是我的模板中包含了clusterrole资源,这个资源我们知道,是集群级别,也就是所有namespace共享它。如果在多个namespace中进行helm安装就会导致资源重复创建报错
报错如下:
Error: rendered manifests contain a resource that already exists. Unable to continue with install: ClusterRole "xxxxx" in namespace ""
解决办法
通过helm提供的lookup方法,在安装前判断资源是否存在,存在就忽略掉,不存在则创建
{{ $clusterrolefind := (lookup "./v1" "ClusterRole" "" "xxxx") }}
{{ if not $clusterrolefind }}
apiVersion: ./v1
kind: ClusterRole
metadata:
name: xxxx #需要创建的ClusterRole的名称
rules:
- apiGroups:
- ""
resources:
- services
- endpoints
verbs:
- get
- list
- watch
{{ end }}
这个办法可以解决问题,但是有一定的限制,可以参考官方文档对于lookup的描述,大家可以根据场景来决定是否采用
官方描述(helm版本:v3.9.0)
lookup 函数可以用于在运行的集群中 查找 资源。lookup函数简述为查找 apiVersion, kind, namespace,name -> 资源或者资源列表。
parameter | type |
---|---|
apiVersion | string |
kind | string |
namespace | string |
name | string |
name 和 namespace 都是选填的,且可以传空字符串(“”)作为空。
以下是可能的参数组合:
命令 | Lookup 函数 |
---|---|
kubectl get pod mypod -n mynamespace | lookup “v1” “Pod” “mynamespace” “mypod” |
kubectl get pods -n mynamespace | lookup “v1” “Pod” “mynamespace” “” |
kubectl get pods --all-namespaces | lookup “v1” “Pod” “” “” |
kubectl get namespace mynamespace | lookup “v1” “Namespace” “” “mynamespace” |
kubectl get namespaces | lookup “v1” “Namespace” “” “” |
当lookup返回一个对象,它会返回一个字典。这个字典可以进一步被引导以获取特定值。
下面的例子将返回mynamespace对象的annotations属性:
(lookup "v1" "Namespace" "" "mynamespace").
当lookup返回一个对象列表时,可以通过items字段访问对象列表:
{{ range $index, $service := (lookup "v1" "Service" "mynamespace" "").items }}
{{/* do something with each service */}}
{{ end }}
当对象未找到时,会返回空值。可以用来检测对象是否存在。
lookup函数使用Helm已有的Kubernetes连接配置查询Kubernetes。当与调用API服务交互时返回了错误 (比如缺少资源访问的权限),helm 的模板操作会失败。
请记住,Helm在helm template或者helm install|update|delete|rollback --dry-run时, 不应该请求请求Kubernetes API服务。由此,lookup函数在该案例中会返回空列表(即字典)。