Fehlerbehebung bei Jobs, die PersistentVolumeClaims (PVC) verwenden - Amazon EMR

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Fehlerbehebung bei Jobs, die PersistentVolumeClaims (PVC) verwenden

Wenn Sie einen Job erstellen, auflisten oder löschen PersistentVolumeClaims (PVC) müssen, aber der Kubernetes-Standardrolle emr-containers keine PVC Berechtigungen hinzufügen, schlägt der Job fehl, wenn Sie ihn einreichen. Ohne diese Berechtigungen kann die Rolle emr-containers keine erforderlichen Rollen für den Spark-Treiber oder den Spark-Client erstellen. Es reicht nicht aus, den Spark-Treiber oder Client-Rollen-Berechtigungen hinzuzufügen, wie es in den Fehlermeldungen angedeutet wird. Die primäre Rolle emr-container muss auch die erforderlichen Berechtigungen enthalten. In diesem Abschnitt wird erklärt, wie Sie der primären Rolle emr-containers die erforderlichen Berechtigungen hinzufügen.

Verifizierung

Um zu überprüfen, ob Ihre Rolle emr-containers über die erforderlichen Berechtigungen verfügt, setzen Sie die NAMESPACE Variable mit Ihrem eigenen Wert und führen Sie dann den folgenden Befehl aus:

export NAMESPACE=YOUR_VALUE kubectl describe role emr-containers -n ${NAMESPACE}

Führen Sie außerdem den folgenden Befehl aus, um zu überprüfen, ob die Rollen Spark und Client über die erforderlichen Berechtigungen verfügen:

kubectl describe role emr-containers-role-spark-driver -n ${NAMESPACE} kubectl describe role emr-containers-role-spark-client -n ${NAMESPACE}

Wenn die Berechtigungen nicht vorhanden sind, fahren Sie mit dem Patch wie folgt fort.

Patch

  1. Wenn die Aufträge ohne die Berechtigungen gerade ausgeführt werden, beenden Sie diese Aufträge.

  2. Erstellen Sie eine Datei mit dem Namen RBAC_Patch.py wie folgt:

    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"] }, { "apiGroups": [""], "resources": ["services"], "verbs": ["get", "list", "describe", "create", "delete", "watch"] } ] 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)
  3. Führen Sie das Python-Skript aus:

    python3 RBAC_Patch.py -n ${NAMESPACE}
  4. Ein kubectl-Unterschied zwischen den neuen und den alten Berechtigungen wird angezeigt. Drücken Sie Y, um die Rolle zu patchen.

  5. Überprüfen Sie die drei Rollen mit zusätzlichen Berechtigungen wie folgt:

    kubectl describe role -n ${NAMESPACE}
  6. Führen Sie das Python-Skript aus:

    python3 RBAC_Patch.py -n ${NAMESPACE}
  7. Nach dem Ausführen des Befehls wird ein kubectl-Unterschied zwischen den neuen und den alten Berechtigungen angezeigt. Drücken Sie Y, um die Rolle zu patchen.

  8. Überprüfen Sie die drei Rollen mit zusätzlichen Berechtigungen:

    kubectl describe role -n ${NAMESPACE}
  9. Reichen Sie den Auftrag erneut ein.

Manuelles Patchen

Wenn die für Ihre Anwendung erforderliche Berechtigung für etwas anderes als die PVC Regeln gilt, können Sie nach Bedarf manuell Kubernetes-Berechtigungen für Ihren EMR virtuellen Amazon-Cluster hinzufügen.

Anmerkung

Die Rolle emr-containers ist eine primäre Rolle. Das bedeutet, dass sie alle erforderlichen Berechtigungen bereitstellen muss, bevor Sie Ihre zugrunde liegenden Treiber- oder Clientrollen ändern können.

  1. Laden Sie die aktuellen Berechtigungen in Yaml-Dateien herunter, indem Sie die folgenden Befehle ausführen:

    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
  2. Bearbeiten Sie jede Datei auf der Grundlage der für Ihre Anwendung erforderlichen Berechtigungen und fügen Sie zusätzliche Regeln hinzu, z. B. die folgenden:

    • 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 - apiGroups: - "" resources: - services verbs: - get - list - describe - create - delete - watch
    • client-role-patch.yaml

      - apiGroups: - "" resources: - persistentvolumeclaims verbs: - list - create - delete - patch
  3. Entfernen Sie die folgenden Attribute mit ihren Werten. Dies ist erforderlich, um das Update anzuwenden.

    • creationTimestamp

    • resourceVersion

    • uid

  4. Führen Sie abschließend den Patch aus:

    kubectl apply -f emr-containers-role-patch.yaml kubectl apply -f driver-role-patch.yaml kubectl apply -f client-role-patch.yaml