As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.
Solução de problemas de trabalhos que usam PersistentVolumeClaims (PVC)
Se você precisar criar, listar ou excluir PersistentVolumeClaims (PVC) para um trabalho, mas não adicionar permissões de PVC aos contêineres emr-emr da função padrão do Kubernetes, o trabalho falhará quando você o enviar. Sem essas permissões, o perfil emr-containers não pode criar os perfis necessários para o driver do Spark ou para o cliente do Spark. Não é suficiente adicionar permissões ao driver do Spark ou aos perfis de clientes, conforme sugerido pelas mensagens de erro. O perfil primário emr-containers também deve incluir as permissões necessárias. Esta seção explica como adicionar as permissões necessárias ao perfil primário emr-containers.
Verificação
Para verificar se o perfil emr-containers tem ou não as permissões necessárias, defina a variável NAMESPACE com seu próprio valor e execute o seguinte comando:
export NAMESPACE=YOUR_VALUE kubectl describe role emr-containers -n ${NAMESPACE}
Além disso, para verificar se os perfis do Spark e dos clientes têm as permissões necessárias, execute o seguinte comando:
kubectl describe role emr-containers-role-spark-driver -n ${NAMESPACE} kubectl describe role emr-containers-role-spark-client -n ${NAMESPACE}
Se as permissões não existirem, prossiga com a aplicação de patch, como apresentado a seguir.
Patch
-
Se os trabalhos estiverem em execução no momento sem as permissões, interrompa-os.
-
Crie um arquivo chamado RBAC_Patch.py da seguinte forma:
import os import subprocess as sp import tempfile as temp import json import argparse import uuid def delete_if_exists(dictionary: dict, key: str): if dictionary.get(key, None) is not None: del dictionary[key] def doTerminalCmd(cmd): with temp.TemporaryFile() as f: process = sp.Popen(cmd, stdout=f, stderr=f) process.wait() f.seek(0) msg = f.read().decode() return msg def patchRole(roleName, namespace, extraRules, skipConfirmation=False): cmd = f"kubectl get role {roleName} -n {namespace} --output json".split(" ") msg = doTerminalCmd(cmd) if "(NotFound)" in msg and "Error" in msg: print(msg) return False role = json.loads(msg) rules = role["rules"] rulesToAssign = extraRules[::] passedRules = [] for rule in rules: apiGroups = set(rule["apiGroups"]) resources = set(rule["resources"]) verbs = set(rule["verbs"]) for extraRule in extraRules: passes = 0 apiGroupsExtra = set(extraRule["apiGroups"]) resourcesExtra = set(extraRule["resources"]) verbsExtra = set(extraRule["verbs"]) passes += len(apiGroupsExtra.intersection(apiGroups)) >= len(apiGroupsExtra) passes += len(resourcesExtra.intersection(resources)) >= len(resourcesExtra) passes += len(verbsExtra.intersection(verbs)) >= len(verbsExtra) if passes >= 3: if extraRule not in passedRules: passedRules.append(extraRule) if extraRule in rulesToAssign: rulesToAssign.remove(extraRule) break prompt_text = "Apply Changes?" if len(rulesToAssign) == 0: print(f"The role {roleName} seems to already have the necessary permissions!") prompt_text = "Proceed anyways?" for ruleToAssign in rulesToAssign: role["rules"].append(ruleToAssign) delete_if_exists(role, "creationTimestamp") delete_if_exists(role, "resourceVersion") delete_if_exists(role, "uid") new_role = json.dumps(role, indent=3) uid = uuid.uuid4() filename = f"Role-{roleName}-New_Permissions-{uid}-TemporaryFile.json" try: with open(filename, "w+") as f: f.write(new_role) f.flush() prompt = "y" if not skipConfirmation: prompt = input( doTerminalCmd(f"kubectl diff -f {filename}".split(" ")) + f"\n{prompt_text} y/n: " ).lower().strip() while prompt != "y" and prompt != "n": prompt = input("Please make a valid selection. y/n: ").lower().strip() if prompt == "y": print(doTerminalCmd(f"kubectl apply -f {filename}".split(" "))) except Exception as e: print(e) os.remove(f"./{filename}") if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument("-n", "--namespace", help="Namespace of the Role. By default its the VirtualCluster's namespace", required=True, dest="namespace" ) parser.add_argument("-p", "--no-prompt", help="Applies the patches without asking first", dest="no_prompt", default=False, action="store_true" ) args = parser.parse_args() emrRoleRules = [ { "apiGroups": [""], "resources": ["persistentvolumeclaims"], "verbs": ["list", "create", "delete", "patch"] } ] driverRoleRules = [ { "apiGroups": [""], "resources": ["persistentvolumeclaims"], "verbs": ["list", "create", "delete", "patch", "deletecollection"] }, { "apiGroups": [""], "resources": ["services"], "verbs": ["get", "list", "describe", "create", "delete", "watch", "deletecollection"] }, { "apiGroups": [""], "resources": ["configmaps", "pods"], "verbs": ["deletecollection"] } ] clientRoleRules = [ { "apiGroups": [""], "resources": ["persistentvolumeclaims"], "verbs": ["list", "create", "delete", "patch"] } ] patchRole("emr-containers", args.namespace, emrRoleRules, args.no_prompt) patchRole("emr-containers-role-spark-driver", args.namespace, driverRoleRules, args.no_prompt) patchRole("emr-containers-role-spark-client", args.namespace, clientRoleRules, args.no_prompt)
-
Execute o script do Python:
python3 RBAC_Patch.py -n ${NAMESPACE}
-
O comando “kubectl diff” apresentará as diferenças entre as permissões novas e as antigas. Pressione Y para aplicar patches ao perfil.
-
Verifique os três perfis com permissões adicionais, como o apresentado:
kubectl describe role -n ${NAMESPACE}
-
Execute o script do Python:
python3 RBAC_Patch.py -n ${NAMESPACE}
-
Após executar o comando, o comando “kubectl diff” apresentará as diferenças entre as permissões novas e as antigas. Pressione Y para aplicar patches ao perfil.
-
Verifique os três perfis com permissões adicionais:
kubectl describe role -n ${NAMESPACE}
-
Envie o trabalho novamente.
Aplicação manual de patches
Se a permissão requerida pela sua aplicação se aplicar a algo diferente das regras de PVC, você poderá adicionar manualmente as permissões do Kubernetes ao cluster virtual do Amazon EMR, conforme necessário.
nota
O perfil emr-containers é um perfil primário. Isso significa que ele deve fornecer todas as permissões necessárias antes que você possa alterar os perfis subjacentes do driver ou dos clientes.
-
Faça o download das permissões atuais em arquivos YAML ao executar os comandos abaixo:
kubectl get role -n ${NAMESPACE} emr-containers -o yaml >> emr-containers-role-patch.yaml kubectl get role -n ${NAMESPACE} emr-containers-role-spark-driver -o yaml >> driver-role-patch.yaml kubectl get role -n ${NAMESPACE} emr-containers-role-spark-client -o yaml >> client-role-patch.yaml
-
Com base na permissão requerida pela aplicação, edite cada arquivo e adicione regras adicionais, como as seguintes:
-
emr-containers-role-patch.yaml
- apiGroups: - "" resources: - persistentvolumeclaims verbs: - list - create - delete - patch
-
driver-role-patch.yaml
- apiGroups: - "" resources: - persistentvolumeclaims verbs: - list - create - delete - patch - deletecollection - apiGroups: - "" resources: - services verbs: - get - list - describe - create - delete - watch - deletecollection - apiGroups: - "" resources: - configmaps - pods verbs: - deletecollection
-
client-role-patch.yaml
- apiGroups: - "" resources: - persistentvolumeclaims verbs: - list - create - delete - patch
-
-
Remova os atributos a seguir em conjunto com os valores deles. Isso é necessário para aplicar a atualização.
-
creationTimestamp
-
resourceVersion
-
uid
-
-
Por fim, execute a aplicação de patches:
kubectl apply -f emr-containers-role-patch.yaml kubectl apply -f driver-role-patch.yaml kubectl apply -f client-role-patch.yaml