Skip to main content
Version: 2.8

Add service accounts

Prerequisites

  • A cluster admin role on your Kubernetes cluster

  • Stork deployed or upgraded on all application clusters

To add a cluster in Portworx Backup, you must first create a service account. This account enables you to retrieve the kubeconfig and token necessary to add a cluster in Portworx Backup.

Perform the following steps to add a service account:

  1. Create a yaml spec called pxbackup-sa.yaml with the following content:

    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
    name: pxbackup-sa
    namespace: kube-system
    ---
    apiVersion: v1
    kind: Secret
    type: kubernetes.io/service-account-token
    metadata:
    name: pxbackup-sa
    namespace: kube-system
    annotations:
    kubernetes.io/service-account.name: pxbackup-sa
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
    name: pxbackup-sa-clusterrolebinding
    subjects:
    - kind: ServiceAccount
    name: pxbackup-sa
    namespace: kube-system
    roleRef:
    apiGroup: rbac.authorization.k8s.io
    kind: ClusterRole
    name: cluster-admin
  2. Apply the spec file:

    kubectl apply -f pxbackup-sa.yaml
  3. You need to update the server URL before running the script. Execute the following command to update the URL:

    kubectl cluster-info
  4. Create a shell script kubeconfig-sa.sh with the following content. If you have a valid certificate, follow step a, otherwise go to step b.

    a. If you have a valid certificate, use the below content. This creates a certificate-based service account:

    #!/bin/bash
    SERVICE_ACCOUNT=pxbackup-sa
    NAMESPACE=kube-system
    SERVER=https://<SERVER-ADDRESS:PORT>

    SERVICE_ACCOUNT_TOKEN_COUNT=$(kubectl -n ${NAMESPACE} get secret -o=jsonpath='{.items[?(@.metadata.annotations.kubernetes\.io/service-account\.name=="'${SERVICE_ACCOUNT}'")].metadata.name}' | wc -w)
    if [ ${SERVICE_ACCOUNT_TOKEN_COUNT} -gt 1 ]
    then
    SERVICE_ACCOUNT_TOKEN_NAME=$(kubectl -n ${NAMESPACE} get secret -o=jsonpath='{.items[?(@.metadata.annotations.kubernetes\.io/service-account\.name=="'${SERVICE_ACCOUNT}'")].metadata.name}' | awk '{for(i=1;i<=NF;i++){ if($i ~ /-token/){print $i} } }' | head -n 1)
    else
    SERVICE_ACCOUNT_TOKEN_NAME=$(kubectl -n ${NAMESPACE} get secret -o=jsonpath='{.items[?(@.metadata.annotations.kubernetes\.io/service-account\.name=="'${SERVICE_ACCOUNT}'")].metadata.name}')
    fi

    SERVICE_ACCOUNT_TOKEN=$(kubectl -n ${NAMESPACE} get secret ${SERVICE_ACCOUNT_TOKEN_NAME} -o "jsonpath={.data.token}" | base64 --decode)
    SERVICE_ACCOUNT_CERTIFICATE=$(kubectl -n ${NAMESPACE} get secret ${SERVICE_ACCOUNT_TOKEN_NAME} -o "jsonpath={.data['ca\.crt']}")

    cat <<END
    apiVersion: v1
    kind: Config
    clusters:
    - name: default-cluster
    cluster:
    certificate-authority-data: $ {SERVICE_ACCOUNT_CERTIFICATE}
    server: ${SERVER}
    contexts:
    - name: default-context
    context:
    cluster: default-cluster
    namespace: ${NAMESPACE}
    user: ${SERVICE_ACCOUNT}
    current-context: default-context
    users:
    - name: ${SERVICE_ACCOUNT}
    user:
    token: ${SERVICE_ACCOUNT_TOKEN}
    END

    b. If you do not have valid certificate, use the following content:

    #!/bin/bash
    SERVICE_ACCOUNT=pxbackup-sa
    NAMESPACE=kube-system
    SERVER=https://<SERVER-ADDRESS:PORT>

    SERVICE_ACCOUNT_TOKEN_COUNT=$(kubectl -n ${NAMESPACE} get secret -o=jsonpath='{.items[?(@.metadata.annotations.kubernetes\.io/service-account\.name=="'${SERVICE_ACCOUNT}'")].metadata.name}' | wc -w)
    if [ ${SERVICE_ACCOUNT_TOKEN_COUNT} -gt 1 ]
    then
    SERVICE_ACCOUNT_TOKEN_NAME=$(kubectl -n ${NAMESPACE} get secret -o=jsonpath='{.items[?(@.metadata.annotations.kubernetes\.io/service-account\.name=="'${SERVICE_ACCOUNT}'")].metadata.name}' | awk '{for(i=1;i<=NF;i++){ if($i ~ /-token/){print $i} } }' | head -n 1)
    else
    SERVICE_ACCOUNT_TOKEN_NAME=$(kubectl -n ${NAMESPACE} get secret -o=jsonpath='{.items[?(@.metadata.annotations.kubernetes\.io/service-account\.name=="'${SERVICE_ACCOUNT}'")].metadata.name}')
    fi

    SERVICE_ACCOUNT_TOKEN=$(kubectl -n ${NAMESPACE} get secret ${SERVICE_ACCOUNT_TOKEN_NAME} -o "jsonpath={.data.token}" | base64 --decode)
    SERVICE_ACCOUNT_CERTIFICATE=$(kubectl -n ${NAMESPACE} get secret ${SERVICE_ACCOUNT_TOKEN_NAME} -o "jsonpath={.data['ca\.crt']}")

    cat <<END
    apiVersion: v1
    kind: Config
    clusters:
    - name: default-cluster
    cluster:
    insecure-skip-tls-verify: true
    server: ${SERVER}
    contexts:
    - name: default-context
    context:
    cluster: default-cluster
    namespace: ${NAMESPACE}
    user: ${SERVICE_ACCOUNT}
    current-context: default-context
    users:
    - name: ${SERVICE_ACCOUNT}
    user:
    token: ${SERVICE_ACCOUNT_TOKEN}
    END
  5. Run the shell script and save the kubeconfig file you obtain. You need this file later to add a cluster in the Portworx Backup web console.

    chmod 755 kubeconfig-sa.sh
    ./kubeconfig-sa.sh

    By default, the steps in the above task do not set any expiry to the service account token. Portworx by Pure Storage recommends not to set any expiry to the service account token. Also, refrain from using existing service accounts that have token expiry set to avoid cluster failure related issues.