Deploy GCP Resources and LogScale

Before creating your LogScaleenvironment you must create the required GCP platform:

Deploy GCP Infrastructure

You will need to create two Google Kubernetes Engine (GKE) clusters alongside suitable network access structures:

  • LogScale Cluster

    This should have a minimum of three nodes to support the high-availability for LogScale.

  • Kafka Cluster

    This should have a minimum of three nodes to support the high-availability and redundancy for Kafka.

  • A Google Cloud Service bucket where the LogScale data can be stored.

  • Virtual Private Cloud Network

    A VPC network, with subnet, firewall and bastion host to support the overall LogScale infrastructure.

Once this has been created

  1. To access the Bastion host and the cluster private nodes, user can generate ssh key pair by following this doc.

  2. Configure kubectl to point to the newly created GKE cluster:

    On the Google Cloud Console , go to your cluster in the Kubernetes EngineClusters make sure you have the right project selected. Click on the three vertical dots, then on the connect button corresponding to the cluster you want to connect to view the gcloud command. More info here

    shell
    $ gcloud container clusters get-credentials logscale-gke --region us-central1 --project logscale-deploy
  3. Now remotely access a private cluster using a bastion host. A template for this command would be:

    shell
    $ gcloud compute ssh INSTANCE_NAME \
        --tunnel-through-iap \
        --project=PROJECT_ID \
        --zone=COMPUTE_ZONE \
        --ssh-flag="-4 -L8888:localhost:8888 -N -q -f"

    For example:

    shell
    $ gcloud compute ssh gke-logscale-bastion-host --project=logscale-deploy --zone=us-central1-a  --tunnel-through-iap --ssh-flag="-4 -L8888:localhost:8888 -N -q -f"

    Also ensure you set the HTTPS proxy:

    shell
    $ export HTTPS_PROXY=localhost:8888
  4. And then verify you can authenticate with the GKE cluster and see pods:

    shell
    $ kubectl get pods -A
Prerequisites — Kafka and ZooKeeper

LogScale requires low latency access to a Kafka cluster to operate optimally, you must have an available Kafka cluster before deploying LogScale. Non-kafka systems that are similar are not supported, e.g. Google PubSub or Azure EventHub are not supported. Sub 50 millisecond ping times from the LogScale pods to the Kafka cluster will ensure data is ingested quickly and be available for search in less than a second. In its default configuration LogScale will automatically create the Kafka topics and partitions required to operate. This functionality can be disabled by setting the KAFKA_MANAGED_BY_HUMIO value to false.

Running Kafka on Kubernetes can be accomplished a variety of ways. The Strimzi Kafka Operator is one such way and uses the same operator patterns that the Humio Operator uses to manage the life-cycles of both Kafka and ZooKeeper nodes. In production setups, LogScale, Kafka, and Zookeeper should be run on separate worker nodes in the cluster. Both Kafka and ZooKeeper must use persistent volumes provided by the Kubernetes environment, and they should not use ephemeral disks in a production deployment. Kafka brokers and ZooKeeper instances should be deployed on worker nodes in different locations such as racks, data centers, or availability zone to ensure reliability. Kubernetes operators such, as the Strimzi operator, do not create worker nodes and label them, that task is left to the administrators.

This Terraform YAML represents a basic Kafka cluster with 3 brokers, each running on worker nodes with 16 cores and 64GB of memory. The cluster is configured to have three replicas by default with the minimum in sync replicas set to two. This allows for the upgrading of brokers with no downtime as there will always be 2 brokers with the data. For more information on configuring Strimzi please see their documentation.

yaml
apiVersion: kafka.strimzi.io/v1beta2
kind: Kafka
metadata:
  name: kafka-basic-cluster-1
spec:
  kafka:
    version: 3.4.0
    replicas: 3
    listeners:
      - name: tls
        port: 9093
        type: internal
        tls: true
    config:
      offsets.topic.replication.factor: 3
      transaction.state.log.replication.factor: 3
      transaction.state.log.min.isr: 2
      default.replication.factor: 3
      min.insync.replicas: 2
      inter.broker.protocol.version: "3.4"
    rack:
      topologyKey: topology.kubernetes.io/zone
    resources:
      requests:
        memory: 58Gi
        cpu: "8"
      limits:
        memory: 58Gi
        cpu: "14"   
    affinity:
      nodeAffinity:
        requiredDuringSchedulingIgnoredDuringExecution:
          nodeSelectorTerms:
          - matchExpressions:
            - key: kubernetes_worker_node_group
              operator: In
              values:
              - kafka-workers
            - key: kubernetes.io/arch
              operator: In
              values:
              - amd64
            - key: kubernetes.io/os
              operator: In
              values:
              - linux
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app.kubernetes.io/name
            operator: In
            values:
            - kafka
        topologyKey: kubernetes.io/hostname     
    storage:
      type: jbod
      volumes:
      - id: 0
        type: persistent-claim
        size: 500Gi
        deleteClaim: false
  zookeeper:
    replicas: 3
    storage:
      type: persistent-claim
      size: 100Gi
      deleteClaim: false
    resources:
      requests:
        memory: 8Gi
        cpu: "2"
      limits:
        memory: 8Gi
        cpu: "2"  
    affinity:
      nodeAffinity:
        requiredDuringSchedulingIgnoredDuringExecution:
          nodeSelectorTerms:
          - matchExpressions:
            - key: kubernetes_worker_node_group
              operator: In
              values:
              - zookeeper-workers
            - key: kubernetes.io/arch
              operator: In
              values:
              - amd64
            - key: kubernetes.io/os
              operator: In
              values:
              - linux
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app.kubernetes.io/name
            operator: In
            values:
            - zookeeper
  entityOperator:
    topicOperator: {}
    userOperator: {}
Install Humio Operator on GCP

For guidance on deploying Humio Operator, see Deploying LogScale with Operator on AWS.

Configure an nginx Proxy on GCP

Configure an Nginx proxy service to point to your LogScale cluster IP addresses.

This can be achieved using the Nginx Ingress Helm chart as provided here.

Once deployed, you will need to configure an external IP address within GCP to make it accessible to the outside world:

Validate the Logscale Cluster

Check the status of the HumioCluster by running:

shell
$ kubectl get humiocluster -n logging

Initially the cluster will go into the state Bootstrapping as it starts up, but once it starts all nodes it will go into the state of Running.