Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
W tym artykule konfigurujemy i wdrażamy klaster Valkey w usłudze Azure Kubernetes Service (AKS), w tym utworzenie Valkey ConfigMap, zasobników klastra pierwotnego i replik, aby zapewnić nadmiarowość i replikację strefową, oraz Pod Disruption Budget (PDB) w celu zapewnienia wysokiej dostępności.
Uwaga
Ten artykuł zawiera odwołania do terminów master (primary) i slave (replica), które są terminami, których firma Microsoft już nie używa. Po usunięciu terminu z oprogramowania Valkey usuniemy go z tego artykułu.
Nawiązywanie połączenia z klastrem usługi AKS
Uwaga
Jeśli używasz narzędzia Terraform, pamiętaj, aby zastąpić symbole zastępcze w kodzie rzeczywistymi danymi wyjściowymi poleceń narzędzia Terraform podczas wdrażania infrastruktury.
Skonfiguruj
kubectl, aby połączyć się z klastrem AKS za pomocą poleceniaaz aks get-credentials.az aks get-credentials --resource-group $MY_RESOURCE_GROUP_NAME --name $MY_CLUSTER_NAME --overwrite-existing --output table
Tworzenie przestrzeni nazw
Utwórz przestrzeń nazw dla klastra Valkey przy użyciu
kubectl create namespacepolecenia .kubectl create namespace valkey --dry-run=client --output yaml | kubectl apply -f -Przykładowe wyjście:
namespace/valkey created
Tworzenie wpisów tajnych
Wygeneruj losowe hasło dla klastra Valkey przy użyciu biblioteki openssl i zapisz je w magazynie kluczy platformy Azure przy użyciu
az keyvault secret setpolecenia .export SECRET=$(openssl rand -base64 32) echo requirepass $SECRET > /tmp/valkey-password-file.conf echo primaryauth $SECRET >> /tmp/valkey-password-file.conf az keyvault secret set --vault-name $MY_KEYVAULT_NAME --name valkey-password-file --file /tmp/valkey-password-file.conf --output none rm /tmp/valkey-password-file.confUstaw zasady, aby zezwolić tożsamości przypisanej przez użytkownika na pobranie wpisu tajnego
az keyvault set-policyprzy użyciu polecenia .az keyvault set-policy --name $MY_KEYVAULT_NAME --object-id $userAssignedObjectID --secret-permissions get --output table
Pobieranie szczegółów tożsamości przypisanej przez użytkownika
Pobierz identyfikator tożsamości i identyfikator obiektu utworzony przez moduł Dostawcy tajemnic usługi Azure Key Vault przy użyciu polecenia
az aks show.export userAssignedIdentityID=$(az aks show --resource-group $MY_RESOURCE_GROUP_NAME --name $MY_CLUSTER_NAME --query addonProfiles.azureKeyvaultSecretsProvider.identity.clientId --output tsv) export userAssignedObjectID=$(az aks show --resource-group $MY_RESOURCE_GROUP_NAME --name $MY_CLUSTER_NAME --query addonProfiles.azureKeyvaultSecretsProvider.identity.objectId --output tsv)
Konfigurowanie dostępu do hasła valkey przechowywanego w usłudze Azure Key Vault
Utwórz zasób,
SecretProviderClassaby uzyskać dostęp do hasła Valkey przechowywanego w magazynie kluczy przy użyciukubectl applypolecenia .export TENANT_ID=$(az account show --query tenantId --output tsv) kubectl apply -f - <<EOF --- apiVersion: secrets-store.csi.x-k8s.io/v1 kind: SecretProviderClass metadata: name: valkey-password namespace: valkey spec: provider: azure parameters: usePodIdentity: "false" useVMManagedIdentity: "true" userAssignedIdentityID: "${userAssignedIdentityID}" keyvaultName: ${MY_KEYVAULT_NAME} # the name of the AKV instance objects: | array: - | objectName: valkey-password-file objectAlias: valkey-password-file.conf objectType: secret tenantId: "${TENANT_ID}" # the tenant ID of the AKV instance EOF
Tworzenie pliku konfiguracji Valkey
ConfigMapUtwórz zasób do przechowywania pliku konfiguracji Valkey.kubectl apply -f - <<EOF apiVersion: v1 kind: ConfigMap metadata: name: valkey-cluster namespace: valkey data: valkey.conf: |+ cluster-enabled yes cluster-node-timeout 15000 cluster-config-file /data/nodes.conf appendonly yes protected-mode yes dir /data port 6379 include /etc/valkey-password/valkey-password-file.conf EOFPrzykładowe wyjście:
configmap/valkey-cluster created
Stwórz podstawowe pody klastra Valkey
StatefulSetUtwórz zasób zspec.affinitycelem, aby zachować wszystkie prawybory w strefie 1 i strefie 2, najlepiej w różnych węzłach, przy użyciukubectl applypolecenia .kubectl apply -f - <<EOF --- apiVersion: apps/v1 kind: StatefulSet metadata: name: valkey-masters namespace: valkey spec: serviceName: "valkey-masters" replicas: 3 selector: matchLabels: app: valkey template: metadata: labels: app: valkey appCluster: valkey-masters spec: terminationGracePeriodSeconds: 20 affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: agentpool operator: In values: - valkey - key: topology.kubernetes.io/zone operator: In values: - ${MY_LOCATION}-1 - matchExpressions: - key: agentpool operator: In values: - valkey - key: topology.kubernetes.io/zone operator: In values: - ${MY_LOCATION}-2 podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchExpressions: - key: app operator: In values: - valkey topologyKey: topology.kubernetes.io/zone - weight: 90 podAffinityTerm: labelSelector: matchExpressions: - key: app operator: In values: - valkey topologyKey: kubernetes.io/hostname containers: - name: role-master-checker image: "${MY_ACR_REGISTRY}.azurecr.io/valkey:latest" command: - "/bin/bash" - "-c" args: [ "while true; do role=\$(valkey-cli --pass \$(cat /etc/valkey-password/valkey-password-file.conf | awk '{print \$2; exit}') role | awk '{print \$1; exit}'); if [ \"\$role\" = \"slave\" ]; then valkey-cli --pass \$(cat /etc/valkey-password/valkey-password-file.conf | awk '{print \$2; exit}') cluster failover; fi; sleep 30; done" ] volumeMounts: - name: valkey-password mountPath: /etc/valkey-password readOnly: true - name: valkey image: "${MY_ACR_REGISTRY}.azurecr.io/valkey:latest" env: - name: VALKEY_PASSWORD_FILE value: "/etc/valkey-password/valkey-password-file.conf" - name: MY_POD_IP valueFrom: fieldRef: fieldPath: status.podIP command: - "valkey-server" args: - "/conf/valkey.conf" - "--cluster-announce-ip" - "\$(MY_POD_IP)" resources: requests: cpu: "100m" memory: "100Mi" ports: - name: valkey containerPort: 6379 protocol: "TCP" - name: cluster containerPort: 16379 protocol: "TCP" volumeMounts: - name: conf mountPath: /conf readOnly: false - name: data mountPath: /data readOnly: false - name: valkey-password mountPath: /etc/valkey-password readOnly: true volumes: - name: valkey-password csi: driver: secrets-store.csi.k8s.io readOnly: true volumeAttributes: secretProviderClass: valkey-password - name: conf configMap: name: valkey-cluster defaultMode: 0755 volumeClaimTemplates: - metadata: name: data spec: accessModes: [ "ReadWriteOnce" ] storageClassName: managed-csi-premium resources: requests: storage: 20Gi EOFPrzykładowe wyjście:
statefulset.apps/valkey-masters created
Tworzenie zasobników repliki klastra Valkey
Utwórz drugi
StatefulSetzasób dla replik Valkey z celem utrzymania wszystkich replik w strefie 3, najlepiej w różnych węzłach, używając poleceniakubectl apply.kubectl apply -f - <<EOF --- apiVersion: apps/v1 kind: StatefulSet metadata: name: valkey-replicas namespace: valkey spec: serviceName: "valkey-replicas" replicas: 3 selector: matchLabels: app: valkey template: metadata: labels: app: valkey appCluster: valkey-replicas spec: terminationGracePeriodSeconds: 20 affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: agentpool operator: In values: - valkey - key: topology.kubernetes.io/zone operator: In values: - ${MY_LOCATION}-3 podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 90 podAffinityTerm: labelSelector: matchExpressions: - key: app operator: In values: - valkey topologyKey: kubernetes.io/hostname containers: - name: valkey image: "${MY_ACR_REGISTRY}.azurecr.io/valkey:latest" env: - name: VALKEY_PASSWORD_FILE value: "/etc/valkey-password/valkey-password-file.conf" - name: MY_POD_IP valueFrom: fieldRef: fieldPath: status.podIP command: - "valkey-server" args: - "/conf/valkey.conf" - "--cluster-announce-ip" - "\$(MY_POD_IP)" resources: requests: cpu: "100m" memory: "100Mi" ports: - name: valkey containerPort: 6379 protocol: "TCP" - name: cluster containerPort: 16379 protocol: "TCP" volumeMounts: - name: conf mountPath: /conf readOnly: false - name: data mountPath: /data readOnly: false - name: valkey-password mountPath: /etc/valkey-password readOnly: true volumes: - name: valkey-password csi: driver: secrets-store.csi.k8s.io readOnly: true volumeAttributes: secretProviderClass: valkey-password - name: conf configMap: name: valkey-cluster defaultMode: 0755 volumeClaimTemplates: - metadata: name: data spec: accessModes: [ "ReadWriteOnce" ] storageClassName: managed-csi-premium resources: requests: storage: 20Gi EOFPrzykładowe wyjście:
statefulset.apps/valkey-replicas created
Weryfikowanie rozmieszczenia zasobników i węzłów
Sprawdź, czy
master-Nireplica-Nsą uruchomione w różnych węzłach i strefach przy użyciu poleceńkubectl get nodesikubectl get pods.kubectl get pods -n valkey -o wide kubectl get node -o custom-columns=Name:.metadata.name,Zone:".metadata.labels.topology\.kubernetes\.io/zone"Przykładowe wyjście:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES valkey-masters-0 1/1 Running 0 2m55s 10.224.0.4 aks-valkey-18693609-vmss000004 <none> <none> valkey-masters-1 1/1 Running 0 2m31s 10.224.0.137 aks-valkey-18693609-vmss000000 <none> <none> valkey-masters-2 1/1 Running 0 2m7s 10.224.0.222 aks-valkey-18693609-vmss000001 <none> <none> valkey-replicas-0 1/1 Running 0 88s 10.224.0.237 aks-valkey-18693609-vmss000005 <none> <none> valkey-replicas-1 1/1 Running 0 70s 10.224.0.18 aks-valkey-18693609-vmss000002 <none> <none> valkey-replicas-2 1/1 Running 0 48s 10.224.0.242 aks-valkey-18693609-vmss000005 <none> <none> Name Zone aks-nodepool1-17621399-vmss000000 centralus-1 aks-nodepool1-17621399-vmss000001 centralus-2 aks-nodepool1-17621399-vmss000003 centralus-3 aks-valkey-18693609-vmss000000 centralus-1 aks-valkey-18693609-vmss000001 centralus-2 aks-valkey-18693609-vmss000002 centralus-3 aks-valkey-18693609-vmss000003 centralus-1 aks-valkey-18693609-vmss000004 centralus-2 aks-valkey-18693609-vmss000005 centralus-3Przed przejściem do następnego kroku poczekaj około trzech minut, aż wszystkie
master-Nireplica-Nzasobniki będą działać.
Tworzenie usług bezgłowych
Utwórz trzy zasoby bezgłowe
Service(pierwszy dla całego klastra, drugi dla głównych serwerów, a trzeci dla replik), które będą używane do uzyskiwania adresów IP zasobników Valkey przy użyciu poleceniakubectl apply.kubectl apply -f - <<EOF apiVersion: v1 kind: Service metadata: name: valkey-cluster namespace: valkey spec: clusterIP: None ports: - name: valkey-port port: 6379 protocol: TCP targetPort: 6379 selector: app: valkey sessionAffinity: None type: ClusterIP EOF kubectl apply -f - <<EOF apiVersion: v1 kind: Service metadata: name: valkey-masters namespace: valkey spec: clusterIP: None ports: - name: valkey-port port: 6379 protocol: TCP targetPort: 6379 selector: app: valkey appCluster: valkey-masters sessionAffinity: None type: ClusterIP EOF kubectl apply -f - <<EOF apiVersion: v1 kind: Service metadata: name: valkey-replicas namespace: valkey spec: clusterIP: None ports: - name: valkey-port port: 6379 protocol: TCP targetPort: 6379 selector: app: valkey appCluster: valkey-replicas sessionAffinity: None type: ClusterIP EOFPrzykładowe wyjście:
service/valkey-cluster created service/valkey-masters created service/valkey-replicas created
Tworzenie budżetu zakłóceń zasobnika (PDB)
Utwórz Pod Disruption Budget (PDB), aby zapewnić, że co najwyżej jeden zasobnik jest niedostępny podczas dobrowolnych zakłóceń, takich jak uaktualnienia lub konserwacja. Pomaga to zachować stabilność i dostępność aplikacji Valkey w klastrze Kubernetes.
kubectl apply -f - <<EOF apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: valkey namespace: valkey spec: maxUnavailable: 1 selector: matchLabels: app: valkey EOFPrzykładowe wyjście:
poddisruptionbudget.policy/valkey created
Uruchamianie klastra Valkey
W klastrze Valkey alokacja miejsca jest podstawową częścią sposobu dystrybucji danych między węzłami. Klastry Valkey (podobne do klastrów Redis) dzielą przestrzeń klucza na 16 384 gniazda skrótów, które są równomiernie rozłożone między węzły podstawowe w klastrze.
W poniższych sekcjach skonfigurujemy trzywęzłowy klaster Valkey z trzema replikami, zapewniając:
- Pełne pokrycie gniazda (wszystkie 16 384 gniazda).
- Wysoka dostępność za pośrednictwem replikacji.
- Prawidłowe przypisanie roli i weryfikacja kondycji klastra.
Inicjowanie klastra Valkey z węzłami podstawowymi w strefie 1 i 2 oraz konfigurowanie dystrybucji miejsc
Utwórz klaster z trzema węzłami głównymi w strefach 1 i 2 oraz równomiernie rozdziel wszystkie 16,384 gniazda skrótów pomiędzy nimi, używając polecenia
kubectl exec.kubectl exec -it -n valkey valkey-masters-0 -- valkey-cli --cluster create --cluster-yes --cluster-replicas 0 \ valkey-masters-0.valkey-masters.valkey.svc.cluster.local:6379 \ valkey-masters-1.valkey-masters.valkey.svc.cluster.local:6379 \ valkey-masters-2.valkey-masters.valkey.svc.cluster.local:6379 \ --pass ${SECRET}Przykładowe wyjście:
>>> Performing hash slots allocation on 3 nodes... Master[0] -> Slots 0 - 5460 Master[1] -> Slots 5461 - 10922 Master[2] -> Slots 10923 - 16383 M: ee6ac1d00d3f016b6f46c7ce11199bc1a7809a35 valkey-masters-0.valkey-masters.valkey.svc.cluster.local:6379 slots:[0-5460] (5461 slots) master M: fd1fb98db83976478e05edd3d2a02f9a13badd80 valkey-masters-1.valkey-masters.valkey.svc.cluster.local:6379 slots:[5461-10922] (5462 slots) master M: ea47bf57ae7080ef03164a4d48b662c7b4c8770e valkey-masters-2.valkey-masters.valkey.svc.cluster.local:6379 slots:[10923-16383] (5461 slots) master >>> Nodes configuration updated >>> Assign a different config epoch to each node >>> Sending CLUSTER MEET messages to join the cluster Waiting for the cluster to join ... >>> Performing Cluster Check (using node valkey-masters-0.valkey-masters.valkey.svc.cluster.local:6379) M: ee6ac1d00d3f016b6f46c7ce11199bc1a7809a35 valkey-masters-0.valkey-masters.valkey.svc.cluster.local:6379 slots:[0-5460] (5461 slots) master M: ea47bf57ae7080ef03164a4d48b662c7b4c8770e 10.224.0.176:6379 slots:[10923-16383] (5461 slots) master M: fd1fb98db83976478e05edd3d2a02f9a13badd80 10.224.0.247:6379 slots:[5461-10922] (5462 slots) master [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered.
Dodaj repliki Valkey w strefie 3, aby umożliwić wysoką dostępność
Dodaj jedną replikę na każdy główny węzeł w innej strefie, aby zapewnić odporność na uszkodzenia i automatyczną zdolność do przełączenia awaryjnego, używając następujących poleceń
kubectl exec.kubectl exec -ti -n valkey valkey-masters-0 -- valkey-cli --cluster add-node \ valkey-replicas-0.valkey-replicas.valkey.svc.cluster.local:6379 \ valkey-masters-0.valkey-masters.valkey.svc.cluster.local:6379 --cluster-slave \ --pass ${SECRET} kubectl exec -ti -n valkey valkey-masters-0 -- valkey-cli --cluster add-node \ valkey-replicas-1.valkey-replicas.valkey.svc.cluster.local:6379 \ valkey-masters-1.valkey-masters.valkey.svc.cluster.local:6379 --cluster-slave \ --pass ${SECRET} kubectl exec -ti -n valkey valkey-masters-0 -- valkey-cli --cluster add-node \ valkey-replicas-2.valkey-replicas.valkey.svc.cluster.local:6379 \ valkey-masters-2.valkey-masters.valkey.svc.cluster.local:6379 --cluster-slave \ --pass ${SECRET}Przykładowe wyjście:
>>> Adding node valkey-replicas-0.valkey-replicas.valkey.svc.cluster.local:6379 to cluster valkey-masters-0.valkey-masters.valkey.svc.cluster.local:6379 >>> Performing Cluster Check (using node valkey-masters-0.valkey-masters.valkey.svc.cluster.local:6379) M: ee6ac1d00d3f016b6f46c7ce11199bc1a7809a35 valkey-masters-0.valkey-masters.valkey.svc.cluster.local:6379 slots:[0-5460] (5461 slots) master M: ea47bf57ae7080ef03164a4d48b662c7b4c8770e 10.224.0.176:6379 slots:[10923-16383] (5461 slots) master M: fd1fb98db83976478e05edd3d2a02f9a13badd80 10.224.0.247:6379 slots:[5461-10922] (5462 slots) master [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered. Automatically selected master valkey-masters-0.valkey-masters.valkey.svc.cluster.local:6379 >>> Send CLUSTER MEET to node valkey-replicas-0.valkey-replicas.valkey.svc.cluster.local:6379 to make it join the cluster. Waiting for the cluster to join >>> Configure node as replica of valkey-masters-0.valkey-masters.valkey.svc.cluster.local:6379. [OK] New node added correctly. >>> Adding node valkey-replicas-1.valkey-replicas.valkey.svc.cluster.local:6379 to cluster valkey-masters-1.valkey-masters.valkey.svc.cluster.local:6379 >>> Performing Cluster Check (using node valkey-masters-1.valkey-masters.valkey.svc.cluster.local:6379) M: fd1fb98db83976478e05edd3d2a02f9a13badd80 valkey-masters-1.valkey-masters.valkey.svc.cluster.local:6379 slots:[5461-10922] (5462 slots) master S: 0ebceb60cbcc31da9040159440a1f4856b992907 10.224.0.224:6379 slots: (0 slots) slave replicates ee6ac1d00d3f016b6f46c7ce11199bc1a7809a35 M: ea47bf57ae7080ef03164a4d48b662c7b4c8770e 10.224.0.176:6379 slots:[10923-16383] (5461 slots) master M: ee6ac1d00d3f016b6f46c7ce11199bc1a7809a35 10.224.0.14:6379 slots:[0-5460] (5461 slots) master 1 additional replica(s) [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered. Automatically selected master valkey-masters-1.valkey-masters.valkey.svc.cluster.local:6379 >>> Send CLUSTER MEET to node valkey-replicas-1.valkey-replicas.valkey.svc.cluster.local:6379 to make it join the cluster. Waiting for the cluster to join >>> Configure node as replica of valkey-masters-1.valkey-masters.valkey.svc.cluster.local:6379. [OK] New node added correctly. >>> Adding node valkey-replicas-2.valkey-replicas.valkey.svc.cluster.local:6379 to cluster valkey-masters-2.valkey-masters.valkey.svc.cluster.local:6379 >>> Performing Cluster Check (using node valkey-masters-2.valkey-masters.valkey.svc.cluster.local:6379) M: ea47bf57ae7080ef03164a4d48b662c7b4c8770e valkey-masters-2.valkey-masters.valkey.svc.cluster.local:6379 slots:[10923-16383] (5461 slots) master S: 0ebceb60cbcc31da9040159440a1f4856b992907 10.224.0.224:6379 slots: (0 slots) slave replicates ee6ac1d00d3f016b6f46c7ce11199bc1a7809a35 S: fa44edff683e2e01ee5c87233f9f3bc35c205dce 10.224.0.103:6379 slots: (0 slots) slave replicates fd1fb98db83976478e05edd3d2a02f9a13badd80 M: ee6ac1d00d3f016b6f46c7ce11199bc1a7809a35 10.224.0.14:6379 slots:[0-5460] (5461 slots) master 1 additional replica(s) M: fd1fb98db83976478e05edd3d2a02f9a13badd80 10.224.0.247:6379 slots:[5461-10922] (5462 slots) master 1 additional replica(s) [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered. Automatically selected master valkey-masters-2.valkey-masters.valkey.svc.cluster.local:6379 >>> Send CLUSTER MEET to node valkey-replicas-2.valkey-replicas.valkey.svc.cluster.local:6379 to make it join the cluster. Waiting for the cluster to join >>> Configure node as replica of valkey-masters-2.valkey-masters.valkey.svc.cluster.local:6379. [OK] New node added correctly.
Zweryfikuj role zasobników i stan replikacji
Upewnij się, że każda podstawowa i replika jest poprawnie skonfigurowana i że relacje replikacji są ustanowione przy użyciu następujących
kubectl execpoleceń.for x in $(seq 0 2); do echo "valkey-masters-$x"; kubectl exec -n valkey valkey-masters-$x -- valkey-cli --pass ${SECRET} role; echo; done for x in $(seq 0 2); do echo "valkey-replicas-$x"; kubectl exec -n valkey valkey-replicas-$x -- valkey-cli --pass ${SECRET} role; echo; donePrzykładowe wyjście:
valkey-masters-0 master 84 10.224.0.224 6379 84 valkey-masters-1 master 84 10.224.0.103 6379 84 valkey-masters-2 master 70 10.224.0.200 6379 70 valkey-replicas-0 slave 10.224.0.14 6379 connected 98 valkey-replicas-1 slave 10.224.0.247 6379 connected 98 valkey-replicas-2 slave 10.224.0.176 6379 connected 84
Następne kroki
Aby dowiedzieć się więcej na temat wdrażania oprogramowania typu open source w usłudze Azure Kubernetes Service (AKS), zobacz następujące artykuły:
- Wdrażanie bazy danych PostgreSQL o wysokiej dostępności w usłudze AKS
- Tworzenie i wdrażanie potoków danych i uczenia maszynowego za pomocą usługi Flyte w usłudze AKS
Współautorzy
Firma Microsoft utrzymuje ten artykuł. Następujący współautorzy pierwotnie to napisali:
- Nelly Kiboi | Inżynier usługi
- Saverio Proto | Główny inżynier środowiska klienta
- Don High | Główny inżynier klienta
- LaBrina Loving | Główny inżynier usługi
- Ken Kilty | Moduł TPM podmiotu zabezpieczeń
- Russell de Pina | Moduł TPM podmiotu zabezpieczeń
- Colin Mixon | Menedżer produktu
- Ketan Chawda | Starszy inżynier klienta
- Naveed Kharadi | Inżynier środowiska klienta
- Erin Schaffer | Content Developer 2