Install Zenko on MetalK8s

Note

This installation procedure is performed on a single node.

Prerequisites

Partition your disk as follows:

Partition # Size Service
1 300 GiB Mongo
2 100 GiB Kafka
3 100 GiB S3Data
4 10 GiB Redis
5 10 GiB ZooKeeper

Use this syntax to partition your disk :

DISK_NAME=/dev/vdb
parted -a none ${DISK_NAME} --script \
    mklabel gpt \
    mkpart primary ext4 1MiB 320GiB \
    mkpart primary ext4 320GiB 420GiB \
    mkpart primary ext4 420GiB 520GiB \
    mkpart primary ext4 520GiB 530GiB \
    mkpart primary ext4 530GiB 540GiB \
    mkpart primary ext4 540GiB 550GiB \
    mkpart primary ext4 550GiB 560GiB \
    mkpart primary ext4 560GiB 570GiB \
    mkpart primary ext4 570GiB 580GiB

Deploy MetalK8s

Refer to MetalK8s Installation for its deployment details.

Deploy Zenko Operator

  1. From your terminal, create an environment for Zenko:

    /srv/scality/metalk8s-{{version-number}}/solutions.sh create-env --name zenko
    
  2. Install Zenko Base:

    /srv/scality/metalk8s-{{version-number}}/solutions.sh import --archive $ZENKO_BASE_ISO
    sed "s/SOLUTION_ENV/zenko/g" /srv/scality/zenko-base-2.0.1/deploy/kubedb.yaml | kubectl apply -f -
    kubectl -n zenko rollout status --timeout 10m deploy kubedb-operator
    kubectl apply -f /srv/scality/zenko-base-2.0.1/deploy/kubedb-catalogs.yaml
    sed "s/SOLUTION_ENV/zenko/g" /srv/scality/zenko-base-2.0.1/deploy/kafka.yaml | kubectl apply -f -
    sed "s/SOLUTION_ENV/zenko/g" /srv/scality/zenko-base-2.0.1/deploy/zookeeper.yaml | kubectl apply -f -
    
  3. Install Zenko Operator:

    /srv/scality/metalk8s-{{version-number}}/solutions.sh import --archive $ZENKO_ISO
    /srv/scality/metalk8s-{{version-number}}/solutions.sh activate --name zenko --version 2.0.1
    /srv/scality/metalk8s-{{version-number}}/solutions.sh add-solution --name zenko --solution zenko --version 2.0.1
    kubectl -n zenko rollout status --timeout 10m deploy zenko-operator
    

Deploy Zenko

  1. Create a Keycloak realm for Zenko:

    REALM_NAME="zenko-realm"
    CLIENT_ID="zenko-ui"
    UI_ENDPOINT="http://ui.zenko.local"
    
    kubectl -n ringx-auth exec -i keycloak-0 -- /opt/jboss/keycloak/bin/kcadm.sh       config credentials --server http://localhost:8080/auth --realm master --user       admin --password password
    cat <<EOF | kubectl -n ringx-auth exec -i keycloak-0 -- /opt/jboss/keycloak/      bin/kcadm.sh create realms -f -
    {
      "realm" : "${REALM_NAME}",
      "enabled" : true,
      "groups" : [ ],
      "defaultRoles" : [ "uma_authorization", "offline_access" ],
      "requiredCredentials" : [ "password" ],
      "users" : [ ],
      "clients" : [ {
        "clientId" : "${CLIENT_ID}",
        "rootUrl" : "${UI_ENDPOINT}",
        "adminUrl" : "${UI_ENDPOINT}",
        "surrogateAuthRequired" : false,
        "enabled" : true,
        "alwaysDisplayInConsole" : false,
        "clientAuthenticatorType" : "client-secret",
        "secret" : "",
        "redirectUris" : [ "${UI_ENDPOINT}/*" ],
        "webOrigins" : [ "${UI_ENDPOINT}" ],
        "notBefore" : 0,
        "bearerOnly" : false,
        "consentRequired" : false,
        "standardFlowEnabled" : true,
        "implicitFlowEnabled" : false,
        "directAccessGrantsEnabled" : true,
        "serviceAccountsEnabled" : false,
        "publicClient" : true,
        "frontchannelLogout" : false,
        "protocol" : "openid-connect",
        "attributes" : { },
        "authenticationFlowBindingOverrides" : { },
        "fullScopeAllowed" : true,
        "nodeReRegistrationTimeout" : -1,
        "protocolMappers" : [ {
          "name" : "instanceids_mapper",
          "protocol" : "openid-connect",
          "protocolMapper" : "oidc-usermodel-attribute-mapper",
          "consentRequired" : false,
          "config" : {
            "multivalued" : "true",
            "userinfo.token.claim" : "true",
            "user.attribute" : "instanceIds",
            "id.token.claim" : "true",
            "access.token.claim" : "true",
            "claim.name" : "instanceIds"
          }
        }, {
          "name" : "role_mapper",
          "protocol" : "openid-connect",
          "protocolMapper" : "oidc-usermodel-attribute-mapper",
          "consentRequired" : false,
          "config" : {
            "user.attribute" : "role",
            "id.token.claim" : "true",
            "access.token.claim" : "true",
            "claim.name" : "role",
            "userinfo.token.claim" : "true"
          }
        } ]
      } ]
    }
    EOF
    
  2. Check the Keycloak realm:

    kubectl -n ringx-auth exec keycloak-0 -- curl http://keycloak.zenko.local/auth/realms/zenko-realm
    
  3. Create a .yaml file for the new Zenko version:

    kubectl apply --namespace zenko -f /srv/scality/zenko-2.0.1/zenkoversion.yaml
    
  4. Create storage classes:

    cat <<EOF | kubectl apply -f -
    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: sc-300-g
      labels:
        zenko: storageclass
    mountOptions:
    - rw
    - discard
    parameters:
      fsType: ext4
      mkfsOptions: '["-m", "0"]'
    provisioner: kubernetes.io/no-provisioner
    reclaimPolicy: Retain
    volumeBindingMode: WaitForFirstConsumer
    ---
    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: sc-100-g
      labels:
        zenko: storageclass
    mountOptions:
    - rw
    - discard
    parameters:
      fsType: ext4
      mkfsOptions: '["-m", "0"]'
    provisioner: kubernetes.io/no-provisioner
    reclaimPolicy: Retain
    volumeBindingMode: WaitForFirstConsumer
    ---
    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: sc-10-g
      labels:
        zenko: storageclass
    mountOptions:
    - rw
    - discard
    parameters:
      fsType: ext4
      mkfsOptions: '["-m", "0"]'
    provisioner: kubernetes.io/no-provisioner
    reclaimPolicy: Retain
    volumeBindingMode: WaitForFirstConsumer
    ---
    EOF
    
  5. Refer to MetalK8s Operation to create volumes for Zenko.

  6. Create a resource for Zenko:

    cat <<EOF | kubectl apply -n zenko -f -
    apiVersion: zenko.io/v1alpha1
    kind: Zenko
    metadata:
      name: zenko-instance
    spec:
      version: 2.0.1
      replicas: 1
      mongodb:
        provider: KubeDB
        persistence:
          volumeClaimTemplate:
            size: 300Gi
            storageClassName: sc-300-g
      redis:
        provider: KubeDB
        persistence:
          volumeClaimTemplate:
            size: 10Gi
            storageClassName: sc-10-g
      kafka:
        provider: Managed
        persistence:
          volumeClaimTemplate:
            size: 100Gi
            storageClassName: sc-100-g
      zookeeper:
        provider: Managed
        persistence:
          volumeClaimTemplate:
            size: 10Gi
            storageClassName: sc-10-g
      localData:
        persistence:
          volumeClaimTemplate:
            size: 100Gi
            storageClassName: sc-100-g
      vault:
        enable: true
        iamIngress:
          hostname: iam.zenko.local
        stsIngress:
          hostname: sts.zenko.local
      management:
        provider: InCluster
        ui:
          ingress:
            hostname: ui.zenko.local
        oidc:
          provider: 'http://keycloak.zenko.local/auth/realms/zenko-realm'
          uiClientId: zenko-ui
          vaultClientId: zenko-ui
        api:
          ingress:
            hostname: management.zenko.local
          allowFrom:
          - 172.16.0.0/12
          - 10.0.0.0/8
      ingress:
        workloadPlaneClass: 'nginx'
        controlPlaneClass: 'nginx'
        annotations:
          nginx.ingress.kubernetes.io/proxy-body-size: 0m
    EOF
    kubectl wait --for condition=Available --timeout 10m -n zenko zenko/
    zenko-instance
    
  7. Create a Keycloak user for the Zenko instance:

    OIDC_USER="zenko-tester"
    INSTANCE_ID=$(kubectl -n zenko get zenko/zenko-instance -o jsonpath='{.      status.instanceID}')
    REALM_NAME="zenko-realm"
    
    kubectl -n ringx-auth exec -i keycloak-0 -- /opt/jboss/keycloak/bin/kcadm.sh       config credentials --server http://localhost:8080/auth --realm master --user       admin --password password
    cat <<EOF | kubectl -n ringx-auth exec -i keycloak-0 -- /opt/jboss/keycloak/      bin/kcadm.sh create users -r "${REALM_NAME}" -f -
    {
        "username": "${OIDC_USER}",
        "enabled": true,
        "totp": false,
        "emailVerified": true,
        "firstName": "zenko",
        "lastName": "tester",
        "email": "${OIDC_USER}@zenko.local",
        "attributes": {
            "instanceIds": [
                "${INSTANCE_ID}"
            ],
            "role": [
            "user"
            ]
        },
        "credentials": [],
        "disableableCredentialTypes": [],
        "requiredActions": [],
        "realmRoles": [
            "uma_authorization",
            "offline_access"
        ],
        "clientRoles": {
            "account": [
            "view-profile",
            "manage-account"
            ]
        },
        "notBefore": 0,
        "groups": []
    }
    EOF
    
    kubectl -n ringx-auth exec -i keycloak-0 -- /opt/jboss/keycloak/bin/kcadm.sh       set-password -r ${REALM_NAME} --username ${OIDC_USER}
    

Testing

From the GUI

Add the following hosts to your etc/hosts file, resolving them to the MetalK8s node’s IP address:

  • management.zenko.local
  • keycloak.zenko.local
  • ui.zenko.local
  • s3.zenko.local

Note

If port 80 is open, you can access the user interface through http://ui.zenko.local.

Important

The user interface is limited to creating accounts and locations.