Nesta página, descrevemos como fazer modificações nos recursos do Kubernetes durante o processo de restauração usando regras de transformação. As regras de transformação são uma melhoria em relação a um recurso anterior chamado regras de substituição. Como elas não são compatíveis com versões anteriores das regras de substituição, a interface de regras de substituição descontinuadas ainda está disponível.
Para conferir a documentação sobre as regras de substituição, consulte Modificar recursos durante a restauração.
Visão geral
Há vários motivos para modificar recursos do Kubernetes como parte do processo de restauração:
Convém criar um PersistentVolumeClaim (PVC) usando um provisionador de armazenamento diferente. Por exemplo, você quer migrar do driver em árvore do Kubernetes para o driver CSI.
Talvez você queira restaurar um namespace com um nome diferente.
Talvez você queira adicionar, alterar ou excluir o valor associado a um rótulo ou uma chave ConfigMap.
Talvez você queira alterar uma contagem de réplicas em uma implantação ou StatefulSet.
O Backup para GKE fornece um mecanismo para fazer essas alterações, chamado regras de transformação, que
podem ser definidos como parte de um RestorePlan
.
No processo de restauração, as regras de transformação funcionam da seguinte maneira:
As regras são organizadas em uma lista ordenada.
Todos os recursos, exceto os
CustomResourceDefinition
, para os quais as transformações não estão disponíveis, são restaurados em sequência por essa lista de regras.Cada regra contém uma breve descrição, critérios correspondentes e edições de recursos.
Se um recurso não corresponder aos critérios de uma regra, ele será movido para a próxima regra na lista sem modificações.
Se um recurso corresponder aos critérios de uma regra, as edições dela serão aplicadas ao recurso antes de passar para a próxima regra na lista.
Se várias regras forem definidas, os critérios de correspondência de cada regra serão avaliados em relação à versão do recurso modificada pelas regras anteriores.
Depois que as edições de regras correspondentes forem aplicadas, a versão final do recurso vai ser criada no cluster.
Parâmetros da regra de transformação
Você cria uma regra de transformação fornecendo as seguintes informações:
description
: esta é uma breve descrição da regra de transformação.resourceFilter
: este filtro é usado para corresponder a recursos. Se nenhumresourceFilter
for fornecido, todos os recursos corresponderão a essa regra.fieldActions
: esta é uma lista de edições a serem feitas nos recursos que correspondem aresourceFilter
. As edições são fornecidas como uma lista ordenada de ações. A ordem é importante aqui porque o resultado de uma ação pode afetar a próxima ação na lista. Se alguma ação falhar, toda a restauração falhará.
Filtro de recurso (resourceFilter
)
Para definir um filtro de recurso, você fornece os seguintes parâmetros:
Parâmetro | Obrigatório | Descrição |
---|---|---|
namespaces |
opcional | Essa é uma lista de namespaces. Para que um recurso corresponda a essa regra, ele precisa ser um recurso com namespace e ter um dos namespaces fornecidos. Se nada for fornecido para esse parâmetro, todos os recursos serão correspondentes (todos os recursos com namespace e com escopo de cluster). |
groupKinds |
opcional |
Esta é uma lista das tuplas Group/Kind do recurso do Kubernetes:
|
jsonPath |
opcional | Essa é uma expressão JSONPath usada para correspondência com recursos. |
JSONPath (jsonPath
)
Uma expressão JSONPath é usada para corresponder aos recursos. Se o resultado da expressão não estiver vazio em um recurso, esse recurso será considerado correspondente.
Considere o seguinte recurso:
YAML
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql-cm
labels:
app: mysql
app.kubernetes.io/name: mysql
data:
primary.cnf: |
# Apply this config only on the primary.
[mysqld]
log-bin
replica.cnf: |
# Apply this config only on replicas.
[mysqld]
super-read-only
JSON
{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": {
"name": "mysql-cm",
"labels": {
"app": "mysql",
"app.kubernetes.io/name": "mysql"
}
},
"data": {
"primary.cnf": "# Apply this config only on the primary.\n[mysqld]\nlog-bin\n",
"replica.cnf": "# Apply this config only on replicas.\n[mysqld]\nsuper-read-only\n"
}
}
Exemplo de como usar expressões JSONPath:
Expressão | Descrição | Result |
---|---|---|
.metadata[?(@.name == 'mysql-cm')] |
O objeto metadata contém a chave name , e o valor dele é "mysql-cm" |
[ |
.metadata.labels['app\.kubernetes\.io/name'] |
O valor da string da chave "app.kubernetes.io/name" em metadata.labels |
[ |
.data['primary\.cnf'] |
O valor do objeto da chave "primary.cnf" em data |
[ |
.metadata[?(@.name =~ /^mysql-.*/i)] |
O objeto metadata contém a chave name , e o valor dele corresponde à expressão regular "/^mysql-.*/i".As barras / são usadas para delimitar o padrão de expressão regular. O i no final da expressão regular é a flag de correspondência que não diferencia maiúsculas de minúsculas. |
[ |
Contanto que a saída da expressão JSONPath não esteja vazia, o recurso correspondente vai corresponder a essa regra.
Assim, .metadata[?(@.name == 'mysql-cm')]
e .metadata[?(@.name == 'mysql-cm')].name
resultam no mesmo resultado
correspondente, que corresponde ao recurso em que .metadata.name
é "mysql-cm"
.
Quando o filtro é usado no JSONPath para fazer a correspondência com uma chave em um mapa no console do Google Cloud, é necessário que .
(ponto) tenha escape usando uma \
(barra invertida). Se o JSONPath for fornecido no contexto do YAML usando a CLI gcloud
ou a Terraform Language, será necessário usar \\
(barras invertidas duplas).
Por exemplo, .metadata.labels['app\.kubernetes\.io/name']
é equivalente a .metadata.labels['app\\.kubernetes\\.io/name']
no YAML ou no Terraform.
Recomendamos o uso de uma ferramenta de avaliador JSONPath com compatibilidade com expressões regulares para testar a expressão antes do uso.
Também é possível usar kubectl
para verificar o resultado das expressões JSONPath.
Consulte a página de suporte do JSONPath para mais exemplos.
Ação de campo (fieldActions
)
As ações de campo são modeladas com base em JSON Patch, que define uma estrutura de documento JSON para expressar uma operação a ser aplicada a um documento JSON. Para definir uma ação de campo, os seguintes parâmetros são obrigatórios:
path
: é um valor de Ponteiro JSON que faz referência ao local nos recursos de destino em que a operação é realizada. Os ponteiros JSON sempre começam com uma/
(barra). Os nomes de propriedades (chaves) que descem em elementos filhos também são separados por uma/
(barra).op
: esse é o tipo da operação realizada nos recursos. Cinco operações são aceitas:add
insere um novo objeto ou valor nopath
especificado, dependendo do que opath
referencia.remove
remove o valor dopath
especificado.replace
substitui o valor nopath
especificado por um novo valor.move
remove o valor de um local e o adiciona aopath
especificado.copy
copia o valor de um local para opath
especificado.
Encontre exemplos de cada operação usando a seguinte definição de pod:
YAML
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: ns
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
env:
- name: PROTOCOL
value: "https"
resources:
limits:
cpu: "250m"
memory: "64Mi"
initContainers:
- name: install
image: busybox:stable
command:
- wget
- "-O"
- "/tmp/index.html"
- http://info.cern.ch
JSON
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": "nginx",
"namespace": "ns",
"labels": {
"app": "nginx"
}
},
"spec": {
"containers": [
{
"name": "nginx",
"image": "nginx:latest",
"ports": [
{
"containerPort": 80
}
],
"env": [
{
"name": "PROTOCOL",
"value": "https"
}
],
"resources": {
"limits": {
"cpu": "250m",
"memory": "64Mi"
}
}
}
],
"initContainers": [
{
"name": "install",
"image": "busybox:stable",
"command": [
"wget",
"-O",
"/tmp/index.html",
"http://info.cern.ch"
]
}
]
}
}
Adicionar
value
é sempre obrigatório para operações add
e precisa ser um elemento JSON legal.
A ação a seguir adiciona uma nova variável de ambiente "PORT"
com o valor "80"
ao contêiner nginx
.
op: add
path: "/spec/containers/0/env/0"
value: >
{
"name": "PORT",
"value": "80"
}
Original
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: ns
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
env:
- name: PROTOCOL
value: "https"
resources:
limits:
cpu: "250m"
memory: "64Mi"
initContainers:
- name: install
image: busybox:stable
command:
- wget
- "-O"
- "/tmp/index.html"
- http://info.cern.ch
Transformado
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: ns
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
env:
- name: PROTOCOL
value: "https"
- name: PORT # newly added
value: "80" # newly added
resources:
limits:
cpu: "250m"
memory: "64Mi"
initContainers:
- name: install
image: busybox:stable
command:
- wget
- "-O"
- "/tmp/index.html"
- http://info.cern.ch
A ação a seguir agrega valor a um novo rótulo app.kubernetes.io/name: nginx
no pod.
op: add
path: "/metadata/labels/app.kubernetes.io~1name"
value: "nginx"
Original
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: ns
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
env:
- name: PROTOCOL
value: "https"
resources:
limits:
cpu: "250m"
memory: "64Mi"
initContainers:
- name: install
image: busybox:stable
command:
- wget
- "-O"
- "/tmp/index.html"
- http://info.cern.ch
Transformado
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: ns
labels:
app: nginx
app.kubernetes.io/name: nginx # newly added
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
env:
- name: PROTOCOL
value: "https"
resources:
limits:
cpu: "250m"
memory: "64Mi"
initContainers:
- name: install
image: busybox:stable
command:
- wget
- "-O"
- "/tmp/index.html"
- http://info.cern.ch
A ação a seguir substitui a imagem do contêiner nginx
, mudando de "nginx:latest"
para "nginx:stable"
.
op: add
path: "/spec/containers/0/image"
value: nginx:stable
Original
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: ns
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
env:
- name: PROTOCOL
value: "https"
resources:
limits:
cpu: "250m"
memory: "64Mi"
initContainers:
- name: install
image: busybox:stable
command:
- wget
- "-O"
- "/tmp/index.html"
- http://info.cern.ch
Transformado
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: ns
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:stable # replaced
ports:
- containerPort: 80
env:
- name: PROTOCOL
value: "https"
resources:
limits:
cpu: "250m"
memory: "64Mi"
initContainers:
- name: install
image: busybox:stable
command:
- wget
- "-O"
- "/tmp/index.html"
- http://info.cern.ch
Remover
A ação a seguir remove os requisitos de recursos do contêiner nginx
.
op: remove
path: "/spec/containers/0/resources"
Original
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: ns
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
env:
- name: PROTOCOL
value: "https"
resources:
limits:
cpu: "250m"
memory: "64Mi"
initContainers:
- name: install
image: busybox:stable
command:
- wget
- "-O"
- "/tmp/index.html"
- http://info.cern.ch
Transformado
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: ns
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
env:
- name: PROTOCOL
value: "https"
# resource requirements are removed
initContainers:
- name: install
image: busybox:stable
command:
- wget
- "-O"
- "/tmp/index.html"
- http://info.cern.ch
Substituir
value
é necessário para a operação replace
e precisa ser um elemento JSON.
A ação a seguir substitui a imagem do contêiner nginx
de nginx:latest
para nginx:stable
.
op: replace
path: "/spec/containers/0/image"
value: nginx:stable
Original
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: ns
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
env:
- name: PROTOCOL
value: "https"
resources:
limits:
cpu: "250m"
memory: "64Mi"
initContainers:
- name: install
image: busybox:stable
command:
- wget
- "-O"
- "/tmp/index.html"
- http://info.cern.ch
Transformado
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: ns
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:stable # replaced
ports:
- containerPort: 80
env:
- name: PROTOCOL
value: "https"
resources:
limits:
cpu: "250m"
memory: "64Mi"
initContainers:
- name: install
image: busybox:stable
command:
- wget
- "-O"
- "/tmp/index.html"
- http://info.cern.ch
Mover
fromPath
é necessário para a operação move
.
A ação a seguir remove as variáveis de ambiente do contêiner nginx
e as adiciona ao contêiner init install
.
op: move
fromPath: "/spec/containers/0/env"
path: "/spec/initContainers/0/env"
Original
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: ns
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
env:
- name: PROTOCOL
value: "https"
resources:
limits:
cpu: "250m"
memory: "64Mi"
initContainers:
- name: install
image: busybox:stable
command:
- wget
- "-O"
- "/tmp/index.html"
- http://info.cern.ch
Transformado
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: ns
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
# "env" is moved to "install" container
resources:
limits:
cpu: "250m"
memory: "64Mi"
initContainers:
- name: install
image: busybox:stable
command:
- wget
- "-O"
- "/tmp/index.html"
- http://info.cern.ch
env: # moved "from" nginx container
- name: PROTOCOL
value: https
Copiar
fromPath
é necessário para a operação copy
.
A ação a seguir copia variáveis de ambiente do contêiner nginx
para o contêiner init install
.
op: copy
fromPath: "/spec/containers/0/env"
path: "/spec/initContainers/0/env"
Original
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: ns
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
env:
- name: PROTOCOL
value: "https"
resources:
limits:
cpu: "250m"
memory: "64Mi"
initContainers:
- name: install
image: busybox:stable
command:
- wget
- "-O"
- "/tmp/index.html"
- http://info.cern.ch
Transformado
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: ns
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
env:
- name: PROTOCOL
value: "https"
resources:
limits:
cpu: "250m"
memory: "64Mi"
initContainers:
- name: install
image: busybox:stable
command:
- wget
- "-O"
- "/tmp/index.html"
- http://info.cern.ch
env: # copy from "nginx" container
- name: PROTOCOL
value: https
Para saber mais sobre como definir regras de transformação no console do Google Cloud, consulte Planejar um conjunto de restaurações.
Para definir regras de transformação com a CLI gcloud, crie um arquivo contendo uma matriz YAML
de transformationRules
e inclua o parâmetro --transformation-rules-file=
no
comando gcloud beta container backup-restore restore-plans create
.
Exemplos de regras de transformação
Os exemplos a seguir são fornecidos no formato YAML usado pela CLI gcloud ou pela linguagem de configuração do Terraform.
Mudar o StorageClass de PVCs
Este exemplo muda o StorageClass em todos os recursos PersistentVolumeClaim restaurados de
standard
para premium-rwo
:
YAML
transformationRules:
- description: Change StorageClass in PVC from standard to premium-rwo
resourceFilter:
namespaces: []
jsonPath: ".spec[?(@.storageClassName == 'standard')]"
groupKinds:
- resourceGroup: ""
resourceKind: PersistentVolumeClaim
fieldActions:
- op: REPLACE
path: "/spec/storageClassName"
value: "premium-rwo"
Terraform
transformation_rules {
description = "Change StorageClass in PVC from standard to premium-rwo"
resource_filter {
json_path = ".spec[?(@.storageClassName == 'standard')]"
group_kinds {
resource_kind = "PersistentVolumeClaim"
}
}
field_actions {
op = "REPLACE"
path = "/spec/storageClassName"
value = "premium-rwo"
}
}
Clonar um namespace
Este exemplo clona um namespace de Alfa para Beta, criando um novo
namespace "beta"
e restaurando todos os recursos de "alpha"
para o novo namespace
"beta"
. Este exemplo requer duas regras de transformação: uma
para o próprio namespace e outra para os recursos dentro do namespace.
YAML
transformationRules:
- description: Rename namespace name from alpha to beta
resourceFilter:
namespaces: []
jsonPath: ".metadata[?(@.name == 'alpha')]"
groupKinds:
- resourceGroup: ""
resourceKind: Namespace
fieldActions:
- op: REPLACE
path: "/metadata/name"
value: "beta"
- description: Clone all resources from namespace alpha to beta
resourceFilter:
namespaces: ["alpha"]
fieldActions:
- op: REPLACE
path: "/metadata/namespace"
value: "beta"
Terraform
transformation_rules {
description = "Rename namespace name from alpha to beta"
resource_filter {
json_path = ".metadata[?(@.name == 'alpha')]"
group_kinds {
resource_kind = "Namespace"
}
}
field_actions {
op = "REPLACE"
path = "/metadata/name"
value = "beta"
}
}
transformation_rules {
description = "Clone all resources from namespace alpha to beta"
resource_filter {
namespaces = ["alpha"]
}
field_actions {
op = "REPLACE"
path = "/metadata/namespace"
value = "beta"
}
}
Alterar o StorageClass de PVCs e a contagem de réplicas em um namespace clonado
Este exemplo clona um namespace e, em seguida, aplica um conjunto de alterações aos recursos no novo namespace:
Altere o StorageClass em PVCs de
standard
parapremium-rwo
Altere a contagem de réplicas da implantação
nginx
para3
YAML
transformationRules:
- description: Rename the namespace from alpha to beta
resourceFilter:
namespaces: []
jsonPath: ".metadata[?(@.name == 'alpha')]"
groupKinds:
- resourceGroup: ""
resourceKind: Namespace
fieldActions:
- op: REPLACE
path: "/metadata/name"
value: "beta"
- description: Change all resources from namespace alpha to beta
resourceFilter:
namespaces: ["alpha"]
fieldActions:
- op: REPLACE
path: "/metadata/namespace"
value: "beta"
- description: Change the StorageClass on PVCs from standard to premium-rwo
resourceFilter:
namespaces: ["beta"]
jsonPath: ".spec[?(@.storageClassName == 'standard')]"
groupKinds:
- resourceGroup: ""
resourceKind: PersistentVolumeClaim
fieldActions:
- op: REPLACE
path: "/spec/storageClassName"
value: "premium-rwo"
- description: Change the replica count of the Deployment nginx from 7 to 3
resourceFilter:
namespaces: ["beta"]
jsonPath: ".metadata[?(@.name == 'nginx')]"
groupKinds:
- resourceGroup: apps
resourceKind: Deployment
fieldActions:
- op: REPLACE
path: "/spec/replicas"
value: "3"
Terraform
transformation_rules {
description = "Rename the namespace from alpha to beta"
resource_filter {
json_path = ".metadata[?(@.name == 'alpha')]"
group_kinds {
resource_kind = "Namespace"
}
}
field_actions {
op = "REPLACE"
path = "/metadata/name"
value = "beta"
}
}
transformation_rules {
description = "Change all resources from namespace alpha to beta"
resource_filter {
namespaces = ["alpha"]
}
field_actions {
op = "REPLACE"
path = "/metadata/namespace"
value = "beta"
}
}
transformation_rules {
description = "Change the StorageClass on PVCs from standard to premium-rwo"
resource_filter {
namespaces = ["beta"]
json_path = ".spec[?(@.storageClassName == 'standard')]"
group_kinds {
resource_kind = "PersistentVolumeClaim"
}
}
field_actions {
op = "REPLACE"
path = "/spec/storageClassName"
value = "premium-rwo"
}
}
transformation_rules {
description = "Change the replica count of the Deployment nginx from 7 to 3"
resource_filter {
namespaces = ["beta"]
json_path = ".metadata[?(@.name == 'nginx')]"
group_kinds {
resource_group = "apps"
resource_kind = "Deployment"
}
}
field_actions {
op = "REPLACE"
path = "/spec/replicas"
value = "3"
}
}
Alterar, inserir e remover entradas do ConfigMap
Este exemplo modifica o ConfigMap
que contém a chave de rótulo "app.kubernetes.io/name"
no namespace "mysql"
para:
Mudar o valor da entrada
"endpoint"
para"192.0.2.127"
.Inserir uma nova entrada
"connection-timeout"
com o valor"30s"
.Remover a entrada com a chave
"read-timeout"
.
YAML
transformationRules:
- description: Change, insert, remove `ConfigMap` entres
resourceFilter:
namespaces: ["mysql"]
jsonPath: ".metadata.labels['app\\.kubernetes\\.io/name']"
groupKinds:
- resourceGroup: ""
resourceKind: ConfigMap
fieldActions:
- op: REPLACE
path: "/data/endpoint"
value: "192.0.2.127"
- op: ADD
path: "/data/connection-timeout"
value: "30s"
- op: REMOVE
path: "/data/read-timeout"
Terraform
transformation_rules {
description = "Change, insert, remove `ConfigMap` entres"
resource_filter {
namespaces = ["mysql"]
json_path = ".metadata.labels['app\\.kubernetes\\.io/name']"
group_kinds {
resource_kind = "ConfigMap"
}
}
field_actions {
op = "REPLACE"
path = "/data/endpoint"
value = "192.0.2.127"
}
field_actions {
op = "ADD"
path = "/data/connection-timeout"
value = "30s"
}
field_actions {
op = "REMOVE"
path = "/data/read-timeout"
}
}
Adiciona um rótulo app.kubernetes.io/name
aos recursos com nomes que começam com mysql-;
Este exemplo adiciona um rótulo app.kubernetes.io/name
com o valor mysql
a todos os recursos com nomes que começam com mysql-:
YAML
transformationRules:
- description: Add a label to resources whose name starts with
resourceFilter:
namespaces: []
jsonPath: ".metadata[?(@.name =~ /^mysql-.*/i)]"
fieldActions:
- op: ADD
path: "/metadata/labels/app.kubernetes.io~1name"
value: "mysql"
Terraform
transformation_rules {
description = "Add a label to resources whose name starts with"
resource_filter {
json_path = ".metadata[?(@.name =~ /^mysql-.*/i)]"
}
field_actions {
op = "ADD"
path = "/metadata/labels/app.kubernetes.io~1name"
value = "mysql"
}
}
Atribuir um endereço IP estático a um serviço do tipo LoadBalancer
Neste exemplo, um endereço IP estático é atribuído ao serviço "nginx-svc"
no namespace "nginx"
:
YAML
transformationRules:
- description: Assign a static IP to Service nginx-svc
resourceFilter:
namespaces: ["nginx"]
jsonPath: ".metadata[?(@.name == 'nginx-svc')]"
groupKinds:
- resourceGroup: ""
resourceKind: Service
fieldActions:
- op: ADD
path: "/spec/loadBalancerIP"
value: "192.0.2.127"
Terraform
transformation_rules {
description = "Assign a static IP to Service nginx-svc"
resource_filter {
namespaces = ["nginx"]
json_path = ".metadata[?(@.name == 'nginx-svc')]"
group_kinds {
resource_kind = "Service"
}
}
field_actions {
op = "ADD"
path = "/spec/loadBalancerIP"
value = "192.0.2.127"
}
}