2.7. 模板处理
配置策略支持将 Golang 文本模板包含在对象定义中。这些模板在 hub 集群或目标受管集群的运行时使用与该集群相关的配置解决。这可让您使用动态内容定义配置策略,并通知或强制实施为目标集群自定义的 Kubernetes 资源。
配置策略定义可以包含 hub 集群和受管集群模板。hub 集群模板首先在 hub 集群中处理,然后将带有已解析 hub 集群模板的策略定义传播到目标集群。在受管集群中,ConfigurationPolicyController
处理策略定义中的任何受管集群模板,然后强制执行或验证完全解析的对象定义。
模板语法必须符合 Golang 模板语言规范,并且从解析的模板生成的资源定义必须是有效的 YAML。如需更多与 Package 模板相关的信息,请参阅 Golang 文档。模板验证中的任何错误都将识别为策略违反情况。当您使用自定义模板功能时,这些值会在运行时被替换。
重要: 如果您使用 hub 集群模板传播 secret 或其他敏感数据,则敏感数据存在于 hub 集群上的受管集群命名空间和发布该策略的受管集群中。模板内容在策略中扩展,策略不会由 OpenShift Container Platform ETCD 加密支持加密。要解决这个问题,请使用 fromSecret
或 copySecretData
,它会自动加密 secret 中的值,或 protect
加密其他值。
如需 hub 集群和受管集群模板的比较,请参阅下表:
2.7.1. hub 集群和受管集群模板的比较
模板 | hub 集群 | 受管集群(managed cluster) |
---|---|---|
Syntax | golang 文本模板规格 | golang 文本模板规格 |
Delimiter | {{hub … hub}} | {{ … }} |
Context |
| 没有上下文变量 |
Access control |
您只能引用与 | 您可以引用集群中的任何资源。 |
Functions | 组模板功能,支持对 Kubernetes 资源和字符串操作的动态访问。如需更多信息,请参阅模板功能。有关查询限制,请参阅 Access control 行。
hub 集群上的
等效的调用可能使用以下语法: | 组模板功能,支持对 Kubernetes 资源和字符串操作的动态访问。如需更多信息,请参阅模板功能。 |
Function output storage |
在与受管集群同步前,模板功能的输出存储在 hub 集群上每个适用的受管集群命名空间中的 | 模板功能的输出不存储在策略相关的资源对象中。 |
Processing | 在 hub 集群的运行时,处理会在复制策略传播到集群的过程中进行。只有在创建或更新模板时,策略中的策略和 hub 集群模板才会在 hub 集群中处理。 |
处理发生在受管集群上的 |
Processing errors | hub 集群模板中的错误显示为策略应用到的受管集群中的违反情况。 | 受管集群模板中的错误会在发生违反情况的特定目标集群中以违反的形式显示。 |
继续阅读以下主题:
2.7.2. 模板功能
模板功能(如特定于资源和通用的 lookup
模板功能)可用于引用 hub 集群上的 Kubernetes 资源(使用 {{hub … hub}}
分隔符)或受管集群(使用 {{ … }}
分隔符)。如需了解更多详细信息,请参阅模板处理。特定于资源的功能用于方便使用,并使资源内容更易于访问。如果您使用通用的函数 lookup
,它更为高级,请熟悉正在查找的资源的 YAML 结构。除了这些功能外,还提供 base64enc、
、base64
encindent
、autoindent
、toInt
、toBool
等实用程序功能。
要将模板符合 YAML 语法,必须使用引号或块字符(|
或 >
)在策略资源中以字符串的形式设置模板。这会导致解析的模板值也是字符串。要覆盖此功能,请使用 toInt
或 toBool
作为模板中的最终功能,以启动进一步处理,强制将值解释为整数或布尔值。继续阅读以查看支持的一些自定义模板功能的描述和示例:
2.7.2.1. fromSecret 功能
fromSecret
功能返回 secret 中给定 data 键的值。查看该功能的以下语法:
func fromSecret (ns string, secretName string, datakey string) (dataValue string, err error)
使用此功能时,请输入 Kubernetes Secret
资源的命名空间、名称和数据键。在 hub 集群模板中使用函数时,您必须使用用于策略的同一命名空间。如需了解更多详细信息,请参阅模板处理。
注: 当您将此功能与 hub 集群模板搭配使用时,输出会使用 protect 功能自动加密。
如果目标集群上不存在 Kubernetes Secret
资源,则会出现策略违反的情况。如果目标集群上不存在 data 键,则该值将变为空字符串。查看在目标集群上强制执行 Secret
资源的以下配置策略。PASSWORD
data 键的值是引用目标集群上 secret 的模板:
apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: demo-fromsecret namespace: test spec: namespaceSelector: exclude: - kube-* include: - default object-templates: - complianceType: musthave objectDefinition: apiVersion: v1 data: USER_NAME: YWRtaW4= PASSWORD: '{{ fromSecret "default" "localsecret" "PASSWORD" }}' kind: Secret metadata: name: demosecret namespace: test type: Opaque remediationAction: enforce severity: low
2.7.2.2. fromConfigmap 功能
fromConfigMap
功能返回 ConfigMap 中给定 data 键的值。查看该功能的以下语法:
func fromConfigMap (ns string, configmapName string, datakey string) (dataValue string, err Error)
使用此功能时,请输入 Kubernetes ConfigMap
资源的命名空间、名称和数据键。您必须使用 hub 集群模板中的功能用于策略的同一命名空间。如需了解更多详细信息,请参阅模板处理。如果目标集群上不存在 Kubernetes ConfigMap
资源,则会出现策略违反的情况。如果目标集群上不存在 data 键,则该值将变为空字符串。查看在目标受管集群中强制执行 Kubernetes 资源的以下配置策略。log-file
data 键的值是一个模板,它从 ConfigMap 获得 log-file
的值,从 default
命名空间获得 log-config
,log-level
被设置为 data 键 log-level
。
apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: demo-fromcm-lookup namespace: test-templates spec: namespaceSelector: exclude: - kube-* include: - default object-templates: - complianceType: musthave objectDefinition: kind: ConfigMap apiVersion: v1 metadata: name: demo-app-config namespace: test data: app-name: sampleApp app-description: "this is a sample app" log-file: '{{ fromConfigMap "default" "logs-config" "log-file" }}' log-level: '{{ fromConfigMap "default" "logs-config" "log-level" }}' remediationAction: enforce severity: low
2.7.2.3. fromClusterClaim 功能
fromClusterClaim
功能返回 ClusterClaim
资源中的 Spec.Value
的值。查看该功能的以下语法:
func fromClusterClaim (clusterclaimName string) (dataValue string, err Error)
使用此功能时,输入 Kubernetes ClusterClaim
资源的名称。如果 ClusterClaim
资源不存在,您会收到策略违反情况。查看在目标受管集群上强制执行 Kubernetes 资源的配置策略示例。platform
数据键的值是一个模板,它检索 platform.open-cluster-management.io
集群声明的值。同样,它从 ClusterClaim
获取产品
和版本
的值:
apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: demo-clusterclaims namespace: default spec: namespaceSelector: exclude: - kube-* include: - default object-templates: - complianceType: musthave objectDefinition: kind: ConfigMap apiVersion: v1 metadata: name: sample-app-config namespace: default data: # Configuration values can be set as key-value properties platform: '{{ fromClusterClaim "platform.open-cluster-management.io" }}' product: '{{ fromClusterClaim "product.open-cluster-management.io" }}' version: '{{ fromClusterClaim "version.openshift.io" }}' remediationAction: enforce severity: low
2.7.2.4. lookup 功能
lookup
功能将 Kubernetes 资源作为 JSON 兼容映射返回。如果请求的资源不存在,则返回空映射。如果资源不存在,并且值提供给另一个模板功能,您可能会得到以下错误: invalid value; expected string
。
注: 使用默认
模板功能,因此为后续模板功能提供了正确的类型。请参阅支持的 Sprig 开源功能部分。
查看该功能的以下语法:
func lookup (apiversion string, kind string, namespace string, name string, labelselector ...string) (value string, err Error)
使用此功能时,输入 Kubernetes 资源的 API 版本、类型、命名空间、名称和可选标签选择器。您必须在 hub 集群模板中使用与策略相同的命名空间。如需了解更多详细信息,请参阅模板处理。有关标签选择器示例,请参阅 Kubernetes 标签和选择器 文档的额外资源部分。查看在目标受管集群上强制执行 Kubernetes 资源的配置策略示例。metrics-url
数据键的值是一个模板,它从 default
命名空间中获取 v1/Service
Kubernetes metrics
资源,并设置为查询的资源中的 Spec.ClusterIP
的值:
apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: demo-lookup namespace: test-templates spec: namespaceSelector: exclude: - kube-* include: - default object-templates: - complianceType: musthave objectDefinition: kind: ConfigMap apiVersion: v1 metadata: name: demo-app-config namespace: test data: # Configuration values can be set as key-value properties app-name: sampleApp app-description: "this is a sample app" metrics-url: | http://{{ (lookup "v1" "Service" "default" "metrics").spec.clusterIP }}:8080 remediationAction: enforce severity: low
2.7.2.5. base64enc 功能
base64enc
功能返回以 base64
编码的输入 data string
值。查看该功能的以下语法:
func base64enc (data string) (enc-data string)
使用这个功能时,输入字符串值。查看以下使用 base64enc
功能的配置策略示例:
apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: demo-fromsecret namespace: test spec: namespaceSelector: exclude: - kube-* include: - default object-templates: - complianceType: musthave objectDefinition: ... data: USER_NAME: '{{ fromConfigMap "default" "myconfigmap" "admin-user" | base64enc }}'
2.7.2.6. base64dec 功能
base64dec
功能返回一个以 base64
解码的输入的 enc-data string
值。查看该功能的以下语法:
func base64dec (enc-data string) (data string)
使用这个功能时,输入字符串值。查看以下使用 base64enc
功能的配置策略示例:
apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: demo-fromsecret namespace: test spec: namespaceSelector: exclude: - kube-* include: - default object-templates: - complianceType: musthave objectDefinition: ... data: app-name: | "{{ ( lookup "v1" "Secret" "testns" "mytestsecret") .data.appname ) | base64dec }}"
2.7.2.7. indent 功能
indent
功能会返回经过 padded 的 data string
。查看该功能的以下语法:
func indent (spaces int, data string) (padded-data string)
使用这个功能时,输入带有特定空格数的数据字符串。查看以下使用 indent
功能的配置策略示例:
apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: demo-fromsecret namespace: test spec: namespaceSelector: exclude: - kube-* include: - default object-templates: - complianceType: musthave objectDefinition: ... data: Ca-cert: | {{ ( index ( lookup "v1" "Secret" "default" "mycert-tls" ).data "ca.pem" ) | base64dec | indent 4 }}
2.7.2.8. autoindent 功能
autoindent
函数的作用类似于 indent
函数,它根据模板前面的空格数自动决定前导空格的数量。查看以下使用 autoindent
函数的配置策略示例:
apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: demo-fromsecret namespace: test spec: namespaceSelector: exclude: - kube-* include: - default object-templates: - complianceType: musthave objectDefinition: ... data: Ca-cert: | {{ ( index ( lookup "v1" "Secret" "default" "mycert-tls" ).data "ca.pem" ) | base64dec | autoindent }}
2.7.2.9. toInt 功能
toInt
函数处理并返回输入值的整数值。另外,如果这是模板中的最后一个功能,也会进一步处理源内容。这是为了确保该值由 YAML 解释为整数。查看该功能的以下语法:
func toInt (input interface{}) (output int)
使用这个功能时,输入需要转换为整数的数据。查看以下使用 toInt
功能的配置策略示例:
apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: demo-template-function namespace: test spec: namespaceSelector: exclude: - kube-* include: - default object-templates: - complianceType: musthave objectDefinition: ... spec: vlanid: | {{ (fromConfigMap "site-config" "site1" "vlan") | toInt }}
2.7.2.10. toBool 功能
toBool
函数将输入字符串转换为布尔值,并返回布尔值。另外,如果这是模板中的最后一个功能,也会进一步处理源内容。这是为了确保该值被 YAML 解释为布尔值。查看该功能的以下语法:
func toBool (input string) (output bool)
使用此功能时,请输入需要转换为布尔值的字符串数据。查看以下使用 toBool
函数的配置策略示例:
apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: demo-template-function namespace: test spec: namespaceSelector: exclude: - kube-* include: - default object-templates: - complianceType: musthave objectDefinition: ... spec: enabled: | {{ (fromConfigMap "site-config" "site1" "enabled") | toBool }}
2.7.2.11. protect 功能
通过 protect
功能,您可以在 hub 集群策略模板中对字符串进行加密。评估策略时,它将在受管集群上自动解密。查看以下使用 protect
功能的配置策略示例:
apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: demo-template-function namespace: test spec: namespaceSelector: exclude: - kube-* include: - default object-templates: - complianceType: musthave objectDefinition: ... spec: enabled: | {{hub (lookup "v1" "Secret" "default" "my-hub-secret").data.message | protect hub}}
在前面的 YAML 示例中,定义了使用 lookup
功能的现有 hub 集群策略模板。在受管集群命名空间中的复制策略上,值可能类似以下语法 :$ocm_encrypted:okrrBqt72oI+3WT/0vxeI3vGa+wpLD7Z0ZxFMLvL204=
使用的每个加密算法是 256 位密钥的 AES-CBC。对于每个受管集群,每个加密密钥都需要是唯一的,每 30 天自动轮转。
这样可确保您的解密的值永不会存储在受管集群的策略中。
要强制立即轮转,在 hub 集群上删除 policy-encryption-key
Secret 上的 policy.open-cluster-management.io/last-rotated
注解。然后,会重新处理策略以使用新的加密密钥。
2.7.2.12. toLiteral 功能
toLiteral
函数会在处理模板字符串后删除任何引号。您可以使用此功能将 JSON 字符串从 ConfigMap 字段转换为清单中的 JSON 值。运行以下功能从 key
参数值中删除引号:
key: '{{ "[\"10.10.10.10\", \"1.1.1.1\"]" | toLiteral }}'
使用 toLiteral
功能后,会显示以下更新:
key: ["10.10.10.10", "1.1.1.1"]
2.7.2.13. copySecretData function
copySecretData
功能复制指定 secret 的所有数据
内容。查看以下函数示例:
complianceType: musthave objectDefinition: apiVersion: v1 kind: Secret metadata: name: my-secret-copy data: '{{ copySecretData "default" "my-secret" }}'
注: 当您将此功能与 hub 集群模板搭配使用时,输出会使用 protect 功能自动加密。
2.7.2.14. copyConfigMapData function
copyConfigMapData
功能复制指定 ConfigMap 的所有 data
内容。查看以下函数示例:
complianceType: musthave objectDefinition: apiVersion: v1 kind: ConfigMap metadata: name: my-secret-copy data: '{{ copyConfigMapData "default" "my-configmap" }}'
2.7.2.15. 支持的 Sprig 开源功能
另外,Red Hat Advanced Cluster Management 还支持 sprig
开源项目中包含的以下模板功能:
-
cat
-
contains
-
default
-
empty
-
fromJson
-
hasPrefix
-
hasSuffix
-
join
-
list
-
lower
-
mustFromJson
-
quote
-
replace
-
semver
-
semverCompare
-
split
-
splitn
-
ternary
-
trim
-
until
-
untilStep
-
upper
2.7.2.16. 其他资源
- 返回到模板处理
- 有关用例,请参阅配置策略中的高级模板处理。
- 有关标签选择器示例,请参阅 Kubernetes 标签和选择器 文档。
- 请参阅 Golang 文档 - 软件包模板
- 如需了解更多详细信息,请参阅 Sprig Function 文档。
2.7.3. 配置策略中的高级模板处理
使用受管集群和 hub 集群模板来减少在策略定义中为每个目标集群或硬代码配置值创建单独的策略的需求。为安全起见,hub 集群模板中的特定于资源和通用查询功能都仅限于 hub 集群上策略的命名空间。
重要: 如果您使用 hub 集群模板传播 secret 或其他敏感数据,则敏感数据存在于 hub 集群上的受管集群命名空间和发布该策略的受管集群中。模板内容在策略中扩展,策略不会由 OpenShift Container Platform ETCD 加密支持加密。要解决这个问题,请使用 fromSecret
或 copySecretData
,它会自动加密 secret 中的值,或 protect
加密其他值。
继续阅读高级模板用例:
2.7.3.1. 重新处理的特殊注解
hub 集群模板会在策略创建过程中或更新引用的资源时解析到引用资源中的数据。
如果您需要手动启动更新,请使用特殊注解 policy.open-cluster-management.io/trigger-update
来指示模板引用的数据的更改。对特殊注解值的任何更改都会自动启动模板处理。另外,引用资源的最新内容会在传播以在受管集群上处理的策略定义中读取和更新。使用此注解的方法是每次递增值。
2.7.3.2. 对象模板处理
使用 YAML 字符串表示设置对象模板。object-template-raw
参数是一个可选参数,它支持高级模板用例,如 if-else 和 range
功能。以下示例定义了将 species-category: mammal
标签添加到 default
命名空间中的任何 ConfigMap 中,其 name
键等于 Sea Otter
:
object-templates-raw: | {{- range (lookup "v1" "ConfigMap" "default" "").items }} {{- if eq .data.name "Sea Otter" }} - complianceType: musthave objectDefinition: kind: ConfigMap apiVersion: v1 metadata: name: {{ .metadata.name }} namespace: {{ .metadata.namespace }} labels: species-category: mammal {{- end }} {{- end }}
注: 虽然 spec.object-templates
和 spec.object-templates-raw
是可选的,但必须设置两个参数字段中的一个。
查看以下策略示例,它使用高级模板为您的受管集群创建和配置基础架构 MachineSet
对象。
apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: create-infra-machineset spec: remediationAction: enforce severity: low object-templates-raw: | {{- /* Specify the parameters needed to create the MachineSet */ -}} {{- $machineset_role := "infra" }} {{- $region := "ap-southeast-1" }} {{- $zones := list "ap-southeast-1a" "ap-southeast-1b" "ap-southeast-1c" }} {{- $infrastructure_id := (lookup "config.openshift.io/v1" "Infrastructure" "" "cluster").status.infrastructureName }} {{- $worker_ms := (index (lookup "machine.openshift.io/v1beta1" "MachineSet" "openshift-machine-api" "").items 0) }} {{- /* Generate the MachineSet for each zone as specified */ -}} {{- range $zone := $zones }} - complianceType: musthave objectDefinition: apiVersion: machine.openshift.io/v1beta1 kind: MachineSet metadata: labels: machine.openshift.io/cluster-api-cluster: {{ $infrastructure_id }} name: {{ $infrastructure_id }}-{{ $machineset_role }}-{{ $zone }} namespace: openshift-machine-api spec: replicas: 1 selector: matchLabels: machine.openshift.io/cluster-api-cluster: {{ $infrastructure_id }} machine.openshift.io/cluster-api-machineset: {{ $infrastructure_id }}-{{ $machineset_role }}-{{ $zone }} template: metadata: labels: machine.openshift.io/cluster-api-cluster: {{ $infrastructure_id }} machine.openshift.io/cluster-api-machine-role: {{ $machineset_role }} machine.openshift.io/cluster-api-machine-type: {{ $machineset_role }} machine.openshift.io/cluster-api-machineset: {{ $infrastructure_id }}-{{ $machineset_role }}-{{ $zone }} spec: metadata: labels: node-role.kubernetes.io/{{ $machineset_role }}: "" taints: - key: node-role.kubernetes.io/{{ $machineset_role }} effect: NoSchedule providerSpec: value: ami: id: {{ $worker_ms.spec.template.spec.providerSpec.value.ami.id }} apiVersion: awsproviderconfig.openshift.io/v1beta1 blockDevices: - ebs: encrypted: true iops: 2000 kmsKey: arn: '' volumeSize: 500 volumeType: io1 credentialsSecret: name: aws-cloud-credentials deviceIndex: 0 instanceType: {{ $worker_ms.spec.template.spec.providerSpec.value.instanceType }} iamInstanceProfile: id: {{ $infrastructure_id }}-worker-profile kind: AWSMachineProviderConfig placement: availabilityZone: {{ $zone }} region: {{ $region }} securityGroups: - filters: - name: tag:Name values: - {{ $infrastructure_id }}-worker-sg subnet: filters: - name: tag:Name values: - {{ $infrastructure_id }}-private-{{ $zone }} tags: - name: kubernetes.io/cluster/{{ $infrastructure_id }} value: owned userDataSecret: name: worker-user-data {{- end }}
2.7.3.3. 绕过模板处理
您可能会创建一个策略,其中包含不是由 Red Hat Advanced Cluster Management 处理的模板。默认情况下,Red Hat Advanced Cluster Management 会处理所有模板。
要绕过 hub 集群的模板处理,必须将 {{ template content }}
改为 {{ `{{ template content }}`
}}
。
另外,您还可以在 Policy
的 ConfigurationPolicy
部分添加以下注解:policy.open-cluster-management.io/disable-templates: "true"
。当包含此注解时,则不需要以前的临时解决方案。为 ConfigurationPolicy
绕过模板处理。
2.7.3.4. 其他资源
- 如需了解更多详细信息,请参阅模板功能。
- 返回到模板处理。
- 如需了解更多详细信息,请参阅 Kubernetes 配置策略控制器。
- 另请参阅 Red Hat OpenShift Container Platform etcd 加密文档。