Creating the EKS cluster

This document walks you through the creation of an EKS cluster.

Before you begin

Before you proceed with the installation, complete these steps:
  1. Verify that your environment meets the System requirements and prerequisites and Hardware cluster requirements.
  2. Prepare for installation.
  3. Log in to the OpenShift® command-line interface.
  4. Downloading the Guardium Insights CASE file and set up your environment for dependencies.

Procedure

  1. In the EKS console, click Create:
  2. Configure the cluster details by setting the cluster name, Kubernetes version (1.29 or 1.30), and IAM role. If a role is not created, make sure that it has the correct permissions.
    1. Click Create a role in IAM console:
    2. Select AWS service and then set the Service or use case to EKS and EKS - Cluster:
    3. Click Next.
    4. Confirm and click Next and then provide a Role name. Add all the required tags, and then click Create role.
  3. Select Allow cluster administrator access and EKS API and ConfigMap. If needed, you can also add tags.
  4. To configure subnets, use the default selection, choose IPv4, and set the Cluster endpoint access to Public and private:
  5. Select Prometheus, if needed. Set Send Prometheus metrics to Amazon Managed Service for Prometheus to on and select API server:
  6. To finalize cluster setup, proceed through the add-on and version pages by clicking Next and then click Create and wait for the status to become Active:
  7. Create EC2 instances for the EKS cluster:
    1. Verify that your EKS cluster is Active.
    2. Click Compute.
    3. If you already have the IAM policy for your node group, skip Step 8 and proceed to Step 9.
    4. Confirm these settings and then click Next:
  8. Configure the node group:
    1. Set the Name and IAM policy for the cluster nodes. If you have not yet set the IAM nodes policy, create one with the following properties.
    2. Create a role.
    3. Click Next and then search for these permission policies in the IAM console and add them to the IAM role:
      • AmazonEBSCSIDriverPolicy
      • AmazonEC2ContainerRegistryReadOnly
      • AmazonEKS_CNI_Policy
      • AmazonEKSWorkerNodePolicy
      • aws-loadbalancer-policy

      If you do not have the aws-loadbalancer-policy policy, you need to manually create it in your IAM:

      {
          "Version": "2012-10-17",
          "Statement": [
              {
                  "Effect": "Allow",
                  "Action": [
                      "iam:CreateServiceLinkedRole"
                  ],
                  "Resource": "*",
                  "Condition": {
                      "StringEquals": {
                          "iam:AWSServiceName": "elasticloadbalancing.amazonaws.com"
                      }
                  }
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "ec2:DescribeAccountAttributes",
                      "ec2:DescribeAddresses",
                      "ec2:DescribeAvailabilityZones",
                      "ec2:DescribeInternetGateways",
                      "ec2:DescribeVpcs",
                      "ec2:DescribeVpcPeeringConnections",
                      "ec2:DescribeSubnets",
                      "ec2:DescribeSecurityGroups",
                      "ec2:DescribeInstances",
                      "ec2:DescribeNetworkInterfaces",
                      "ec2:DescribeTags",
                      "ec2:GetCoipPoolUsage",
                      "ec2:DescribeCoipPools",
                      "elasticloadbalancing:DescribeLoadBalancers",
                      "elasticloadbalancing:DescribeLoadBalancerAttributes",
                      "elasticloadbalancing:DescribeListeners",
                      "elasticloadbalancing:DescribeListenerCertificates",
                      "elasticloadbalancing:DescribeSSLPolicies",
                      "elasticloadbalancing:DescribeRules",
                      "elasticloadbalancing:DescribeTargetGroups",
                      "elasticloadbalancing:DescribeTargetGroupAttributes",
                      "elasticloadbalancing:DescribeTargetHealth",
                      "elasticloadbalancing:DescribeTags",
                      "elasticloadbalancing:DescribeTrustStores"
                  ],
                  "Resource": "*"
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "cognito-idp:DescribeUserPoolClient",
                      "acm:ListCertificates",
                      "acm:DescribeCertificate",
                      "iam:ListServerCertificates",
                      "iam:GetServerCertificate",
                      "waf-regional:GetWebACL",
                      "waf-regional:GetWebACLForResource",
                      "waf-regional:AssociateWebACL",
                      "waf-regional:DisassociateWebACL",
                      "wafv2:GetWebACL",
                      "wafv2:GetWebACLForResource",
                      "wafv2:AssociateWebACL",
                      "wafv2:DisassociateWebACL",
                      "shield:GetSubscriptionState",
                      "shield:DescribeProtection",
                      "shield:CreateProtection",
                      "shield:DeleteProtection"
                  ],
                  "Resource": "*"
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "ec2:AuthorizeSecurityGroupIngress",
                      "ec2:RevokeSecurityGroupIngress"
                  ],
                  "Resource": "*"
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "ec2:CreateSecurityGroup"
                  ],
                  "Resource": "*"
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "ec2:CreateTags"
                  ],
                  "Resource": "arn:aws:ec2:*:*:security-group/*",
                  "Condition": {
                      "StringEquals": {
                          "ec2:CreateAction": "CreateSecurityGroup"
                      },
                      "Null": {
                          "aws:RequestTag/elbv2.k8s.aws/cluster": "false"
                      }
                  }
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "ec2:CreateTags",
                      "ec2:DeleteTags"
                  ],
                  "Resource": "arn:aws:ec2:*:*:security-group/*",
                  "Condition": {
                      "Null": {
                          "aws:RequestTag/elbv2.k8s.aws/cluster": "true",
                          "aws:ResourceTag/elbv2.k8s.aws/cluster": "false"
                      }
                  }
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "ec2:AuthorizeSecurityGroupIngress",
                      "ec2:RevokeSecurityGroupIngress",
                      "ec2:DeleteSecurityGroup"
                  ],
                  "Resource": "*",
                  "Condition": {
                      "Null": {
                          "aws:ResourceTag/elbv2.k8s.aws/cluster": "false"
                      }
                  }
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "elasticloadbalancing:CreateLoadBalancer",
                      "elasticloadbalancing:CreateTargetGroup"
                  ],
                  "Resource": "*",
                  "Condition": {
                      "Null": {
                          "aws:RequestTag/elbv2.k8s.aws/cluster": "false"
                      }
                  }
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "elasticloadbalancing:CreateListener",
                      "elasticloadbalancing:DeleteListener",
                      "elasticloadbalancing:CreateRule",
                      "elasticloadbalancing:DeleteRule"
                  ],
                  "Resource": "*"
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "elasticloadbalancing:AddTags",
                      "elasticloadbalancing:RemoveTags"
                  ],
                  "Resource": [
                      "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*",
                      "arn:aws:elasticloadbalancing:*:*:loadbalancer/net/*/*",
                      "arn:aws:elasticloadbalancing:*:*:loadbalancer/app/*/*"
                  ],
                  "Condition": {
                      "Null": {
                          "aws:RequestTag/elbv2.k8s.aws/cluster": "true",
                          "aws:ResourceTag/elbv2.k8s.aws/cluster": "false"
                      }
                  }
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "elasticloadbalancing:AddTags",
                      "elasticloadbalancing:RemoveTags"
                  ],
                  "Resource": [
                      "arn:aws:elasticloadbalancing:*:*:listener/net/*/*/*",
                      "arn:aws:elasticloadbalancing:*:*:listener/app/*/*/*",
                      "arn:aws:elasticloadbalancing:*:*:listener-rule/net/*/*/*",
                      "arn:aws:elasticloadbalancing:*:*:listener-rule/app/*/*/*"
                  ]
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "elasticloadbalancing:ModifyLoadBalancerAttributes",
                      "elasticloadbalancing:SetIpAddressType",
                      "elasticloadbalancing:SetSecurityGroups",
                      "elasticloadbalancing:SetSubnets",
                      "elasticloadbalancing:DeleteLoadBalancer",
                      "elasticloadbalancing:ModifyTargetGroup",
                      "elasticloadbalancing:ModifyTargetGroupAttributes",
                      "elasticloadbalancing:DeleteTargetGroup"
                  ],
                  "Resource": "*",
                  "Condition": {
                      "Null": {
                          "aws:ResourceTag/elbv2.k8s.aws/cluster": "false"
                      }
                  }
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "elasticloadbalancing:AddTags"
                  ],
                  "Resource": [
                      "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*",
                      "arn:aws:elasticloadbalancing:*:*:loadbalancer/net/*/*",
                      "arn:aws:elasticloadbalancing:*:*:loadbalancer/app/*/*"
                  ],
                  "Condition": {
                      "StringEquals": {
                          "elasticloadbalancing:CreateAction": [
                              "CreateTargetGroup",
                              "CreateLoadBalancer"
                          ]
                      },
                      "Null": {
                          "aws:RequestTag/elbv2.k8s.aws/cluster": "false"
                      }
                  }
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "elasticloadbalancing:RegisterTargets",
                      "elasticloadbalancing:DeregisterTargets"
                  ],
                  "Resource": "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*"
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "elasticloadbalancing:SetWebAcl",
                      "elasticloadbalancing:ModifyListener",
                      "elasticloadbalancing:AddListenerCertificates",
                      "elasticloadbalancing:RemoveListenerCertificates",
                      "elasticloadbalancing:ModifyRule"
                  ],
                  "Resource": "*"
              }
          ]
      }
    4. Click Next and choose a role name. You can also add a description and tags, and then click Create role.
    5. Return to the node creation page and choose the role name that you created.
  9. Configure the node tags.

    When you add tags for your EKS nodes, the minimum node specification must be 5 different EC2 m6a.4xlarge instances to support both Guardium Insights and IBM Cloud Pak® foundational services. The Disk size must be at least 100 GiB.

  10. Use the Specify networking page to verify that the nodes can communicate with the cluster and that the VPC that you choose is NFC-enabled.
    1. Select any of the subnet names and click Next.
      For example, subnet-0fXXX.

      In a separate browser tab or window, open http://console.aws.amazon.com/vpcconsole/. Then copy the subnet name that you retrieved from the console (for example, 'subnet-05757b5b55bf78109 | gi-eks-vpc-subnet-private1-us-east-la), and search for it in the VPC console within your AWS account.

    2. In the Subnets tab, select your subnet and go to its Route table.
    3. In the Route tables page, click Edit routes:
    4. Add the NAT Gateway (NGW) to your VPC so your EKS cluster can communicate with your EC2 instances:
  11. Review all settings and then click Create.
    Note: The EKS cluster takes between 5 and 15 minutes to create.
  12. Version 3.4.x Complete the following steps in your terminal.
    1. Set the access key and secret key credentials for your AWS account:
      sudo vi~/.aws/credentials
      [default] 
      
      aws_access_key_id= 
      
      aws_secret_access_key= 
      
      aws_session_token= 

      For more information, see https://docs.aws.amazon.com/cli/v1/userguide/cli-authentication-user.html#cli-authentication-user-get.

    2. Get the cluster information.
      aws sts get-caller-identity
    3. Set the environment for your cluster.
      aws eks update-kubeconfig --region us-east-2 --name cluster-name

      Update the fileSystemId in this manifest.

      export efs_file_system_id=fs-xxxxxxxxxxxxxxx
      cat <<EOF | kubectl apply -f -
      apiVersion: storage.k8s.io/v1
      kind: StorageClass
      metadata:
        name: efs-sc
      parameters:
        directoryPerms: "777"
        fileSystemId: $efs_file_system_id
        gid: "0"
        provisioningMode: efs-ap
        uid: "0"
      provisioner: efs.csi.aws.com
      reclaimPolicy: Delete
      volumeBindingMode: Immediate
      EOF

      To confirm that the environment is set, issue this command:

      oc get sc

      The results should be similar to:

      
      NAME                                PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE    ALLOWVOLUMEEXPANSION AGE 
      efs-sc efs.csi.aws.com                          Delete        Immediate            false                123m
      gp2 (default) kubernetes.io/aws-ebs             Delete        WaitForFirstConsumer false                39h
      In addition, ensure that these parameters (777 permission) are included in the EFS claim storage class:
      Parameters: directoryPerms=777,fileSystemId=fs-005891f4dab28cd06,gid=0,provisioningMode=efs-ap,uid=0
      For example:
      oc describe sc efs-sc 
      Provisioner:           efs.csi.aws.com 
      Parameters: 
      directoryPerms=777,fileSystemId=fs-088163fcae75a1740,gid=0,provisioningMode=efs-ap,uid=0 
      AllowVolumeExpansion:  <unset> 
      MountOptions:          <none> 
      ReclaimPolicy:         Delete 
      VolumeBindingMode:     Immediate 
      Events:                <none>
      apiVersion: gi.ds.isc.ibm.com/v1
      kind: GuardiumInsights
      metadata:
        name: GI_INSTANCE_NAME #gi-sample
        namespace: NAMESPACE #staging
      spec:
        dependency-security:
          networkPolicy:
            egresses:
              enabled: false
              egress-required-allow:
                egress:
                  - ports:
                    - protocol: UDP
                      port: 443
                    - protocol: TCP
                      port: 443
                    - protocol: UDP
                      port: 53
                    - protocol: TCP
                      port: 53
                    - port: 5353
                      protocol: UDP
                    - port: 5353
                      protocol: TCP
        version: 3.5.0
        license:
          accept: true
          licenseType: "L-YRPR-ZV3BA6"
        dependency-postgres:
          podContainerSecurityContextParams:
            fsGroup: 0
            runAsUser: 1000
            runAsNonRoot: true
        dependency-kafka:
          podContainerSecurityContextParams:
            fsGroup: 0
            runAsUser: 1000
            runAsNonRoot: true
        dependency-redis:
          podContainerSecurityContextParams:
            fsGroup: 0
            runAsUser: 1000
            runAsNonRoot: true
        guardium-agent-cert-generator:
          podContainerSecurityContextParams:
            fsGroup: 0
            runAsUser: 1000
        mini-snif:
          podContainerSecurityContextParams:
            allowPrivilegeEscalation: false
            capabilities:
              drop:
              - ALL
            privileged: false
            readOnlyRootFilesystem: false
            runAsNonRoot: false
          replicaCount: 1
        dependency-db2:
          db2instance:
            nodes: 2
            storage:
              - name: meta
                spec:
                  accessModes:
                  - ReadWriteMany
                  resources:
                    requests:
                      storage: 100Gi
                    limits:
                      storage: 1000Gi
      
      storageClassName: efs-sc
      
      type: create
      
      - name: data
      
      spec:
      
      accessModes:
      
      - ReadWriteOnce
      
      resources:
      
      requests:
      
      storage: 100Gi
      
      storageClassName: gp2
      
      type: template
      
      - name: backup
      
      spec:
      
      accessModes:
      
      - ReadWriteMany
      
      resources:
      
      requests:
      
      storage: 100Gi
      
      limits:
      
      storage: 2000Gi
      
      storageClassName: efs-sc
      
      type: create
      
      - name: tempts
      
      spec:
      
      accessModes:
      
      - ReadWriteOnce
      
      resources:
      
      requests:
      
      storage: 100Gi
      
      limits:
      
      storage: 1000Gi
      
      storageClassName: gp2
      
      type: template
      
      - name: archivelogs
      
      spec:
      
      accessModes:
      
      - ReadWriteMany
      
      resources:
      
      requests:
      
      storage: 200Gi
      
      limits:
      
      storage: 1000Gi
      
      storageClassName: efs-sc
      
      type: create
      
      guardiumInsightsGlobal:
      
      deploymentOptions:
      
      prometheusType: disabled
      
      fsGroupGid: 0
      
      networkPolicyPodToPod:
      
      enabled: false
      
      backupsupport:
      
      enabled: "false"
      
      name: backup-pvc-support
      
      image:
      
      insightsPullSecret: ibm-entitlement-key
      
      repository: cp.icr.io/cp/ibm-guardium-insights
      
      size: GI_SIZE
      
      insights:
      
      ingress:
      
      hostName: HOST_NAME #example - namespace.apps.cluster_name.guardium-insights.com
      
      domainName: DOMAIN_NAME #example - apps.cluster_name.guardium-insights.com
      
      ics:
      
      namespace: NAMESPACE #staging
      
      registry: common-service
      
      storageClassName: efs-sc
      
      storageClassNameRWO: gp2
      
      deploySettings:
      
      nonOCP: true
      
      ensureDb2InstallPlacement: true
      
      ssh-service:
      
      serviceAnnotations:
      
      service.beta.kubernetes.io/aws-load-balancer-internal: "false"
      echo ${file_system_id}

      Apply the StorageClass using envsubst for substitution.

      Create a file named efs.yaml and update these parameters:

      • Change the storage_class_name to efs-sc.
      • Replace the fileSsystemId parameter with the output of echo ${file_system_id}.
      Apply the YAML file:
      oc apply -f efs.yaml

      Sample EFS storage class manifest:

      apiVersion: storage.k8s.io/v1
      kind: StorageClass
      metadata:
        name: ${storage_class_name}
      parameters:
        directoryPerms: "777"
        fileSystemId: ${file_system_id}
        gid: "0"
        provisioningMode: efs-ap
        uid: "0"
      provisioner: efs.csi.aws.com
      reclaimPolicy: Delete
      volumeBindingMode: Immediate
      
      oc get sc
      NAME              PROVISIONER             RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
      efs-sc            efs.csi.aws.com         Delete          Immediate              false                  123m
      gp2 (default)     kubernetes.io/aws-ebs   Delete          WaitForFirstConsumer   false                  39h
      Note: By default, you might have a gp2 storage class on your EKS cluster - however, it is recommended that you use gp3 for improved performance and deployment. For more information, see Migrating Amazon EKS clusters from gp2 to gp3 EBS volumes.

      If you keep the gp2 storage cluster and the default value is not in front of it, patch it with this command:

      kubectl patch storageclass gp2 -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'