Skip to main content

Blogs

kubeopsctl - Seamlessly Master Kubernetes Clusters without Downtime

Kubernetes has taken the cloud computing world by storm, but managing a Kubernetes cluster can be a daunting task. That's why we developed kubeopsctl, a CLI tool aimed at simplifying the process of setting up and maintaining your Kubernetes clusters. With kubeopsctl, you can bring up an entire Kubernetes cluster, complete with worker nodes, master nodes, monitoring, storage system, logging stack, private image registry, also common tools like NGINX controller, Keycloak, all through a single YAML configuration file.

 

Introduction

In the world of cloud computing, Kubernetes has become crucial. But managing a Kubernetes cluster is not always easy. That's where kubeopsctl comes in. This CLI tool helps make it simple to set up and manage your Kubernetes clusters. With just one YAML file, kubeopsctl lets you create a complete cluster, including worker nodes, master nodes, also monitoring stack, storage, logging, private image registry, OPA (Open Policy Agent) and also common tools like NGINX Ingress Controller Keycloak, and more.

What is kubeopsctl?

kubeopsctl is a command-line interface (CLI) tool designed to simplify the process of deploying and managing Kubernetes clusters. Whether you're new to Kubernetes or have experience, kubeopsctl is designed to help.

Main Features

  • Single Configuration: With just one YAML file, you can set up your whole cluster. This includes master and worker nodes, extra tools, ports, storage size etc.

  • Upgrade without outage: The zone configuration feature allows you to upgrade your cluster without any downtime. You can place the master/worker nodes you want in different zones and perform operations at the zone level. In this way, you can perform cluster operations with zero outage.

  • Personalization: You can easily set up both master and worker nodes, and specify requirements for each.

  • Extra Tools: You can also add software like Prometheus for monitoring, Keycloak for added security, Certman for certificate management and more. When you deploy these tools also you can configure values in YAML.

  • Security: kubeopsctl has built-in security settings, like pre-defined port numbers, SSL-force options, password and secret configuration.

 

Sample Configuration: A Detailed Look

The YAML file is the cornerstone of kubeopsctl's functionality. Please turn to the end of this page to find an example of the file, helping you gain a deeper understanding of its components:

Cluster and User Information: At the very beginning of the YAML file, basic but critical information about your Kubernetes cluster is defined. This includes the desired name of the cluster, the version of Kubernetes you're planning to install, and the credentials for accessing the cluster.

Master and Worker Nodes: This is where the topology of your cluster takes shape. Within the zones designated, you can specify whether the nodes are master or worker versions, and further provide details about their IP addresses, system configurations, and even resource quotas.

Optional Components: kubeopsctl offers you the luxury to pick and choose additional services like rook-ceph for storage, harbor for container registry, and even opensearch for distributed search as well as analytics. You can also enable NGINX Ingress Controller, Keycloak etc. These can be toggled on or off based on the project’s needs.

Advanced Settings: For those looking to delve deeper, kubeopsctl permits advanced configurations such as custom storage classes, specific volume size, using existing secrets, predefined password etc. This provides a granular level of control for those who need it.

Security Features: Beyond basic firewall settings, kubeopsctl offers an array of options for setting up nftables and container runtimes like containerd, predefined port numbers, giving you a good approach to security.

 

Code example:

apiVersion: kubeops/kubeopsctl/alpha/v1  # mandatory
kubeOpsUser: "demo" # mandatory,  change to your username
kubeOpsUserPassword: "Password" # mandatory,  change to your password
kubeOpsUserMail: "This email address is being protected from spambots. You need JavaScript enabled to view it." # change to your email
imagePullRegistry: "registry1.kubernative.net/lima" # mandatory
localRegistry: false # mandatory
### Values for setup configuration ###
clusterName: "testkubeopsctl"  # mandatory
clusterUser: "mnyuser"  # mandatory
kubernetesVersion: "1.26.4" # mandatory, check lima documentation
#masterHost: optional if you have an hostname, default value in "masterIP"
masterIP: 10.2.10.11 # mandatory
firewall: "nftables" # mandatory, default "nftables"
pluginNetwork: "calico" # mandatory, default "nftables"
containerRuntime: "containerd" # mandatory, default "containerd"
limaRoot: "/home/myuser/kubeops/lima" # optional, default: "/var/lima" 
clusterOS: "Red Hat Enterprise Linux" # optional, can be "Red Hat Enterprise Linux" or "openSUSE Leap", remove this line if you want to use default installed OS on admin machine but it has to be "Red Hat Enterprise Linux" or "openSUSE Leap"
### Additional values for cluster configuration
useInsecureRegistry: false # optional, default is false
ignoreFirewallError: false # optional, default is false
serviceSubnet: 192.168.128.0/17 # optional, default "192.168.128.0/17"
podSubnet: 192.168.0.0/17 # optional, default "192.168.0.0/17"
debug: true # optional, default is true
logLevel: vvvvv # optional, default "vvvvv"
systemCpu: "1" # optional, default "1"
systemMemory: "2G" # optional, default "2G"
sudo: true # optional, default is true
# at least 3 masters and 3 workers are needed
zones:
  - name: zone1
    nodes:
      master:
        - name: cluster1master1
          ipAdress: 10.2.10.11
          user: myuser
          systemCpu: 100m
          systemMemory: 100Mi 
          status: active
          kubeversion: 1.26.4
        - name: cluster1master2
          ipAdress: 10.2.10.12
          user: myuser
          systemCpu: 100m
          systemMemory: 100Mi 
          status: active
          kubeversion: 1.27.2
      worker:
        - name: cluster1worker1
          ipAdress: 10.2.10.14
          user: myuser
          systemCpu: 100m
          systemMemory: 100Mi 
          status: active
          kubeversion: 1.26.4
        - name: cluster1worker2
          ipAdress: 10.2.10.15
          systemCpu: 100m
          systemMemory: 100Mi 
          status: active
          kubeversion: 1.27.2
  - name: zone2
    nodes:
      master:
        - name: cluster1master3
          ipAdress: 10.2.10.13
          user: myuser
          systemCpu: 100m
          systemMemory: 100Mi 
          status: drained
          kubeversion: 1.26.4  
      worker:
        - name: cluster1worker1
          ipAdress: 10.2.10.16
          user: myuser
          systemCpu: 100m
          systemMemory: 100Mi 
          status: active
          kubeversion: 1.26.4

# set to true if you want to install it into your cluster
rook-ceph: false # mandatory
harbor: false # mandatory
opensearch: false # mandatory
opensearch-dashboards: false # mandatory
logstash: false # mandatory
filebeat: false # mandatory
prometheus: false # mandatory
opa: false # mandatory
headlamp: false # mandatory
certman: false # mandatory
ingress: false # mandatory
keycloak: false # mandatory

nameSpace: "kubeops" #optional, the default value is different for each application
storageClass: "rook-cephfs" # optional, default value is "rook-cephfs"

###Values for Rook-Ceph###
rookValues:
  namespace: kubeops
  nodePort: 31931 # optional, default: 31931
  cluster:
    spec:
      dataDirHostPath: "/var/lib/rook" # optional, The path on the host where configuration files will be persisted. Default value: "/var/lib/rook"
    removeOSDsIfOutAndSafeToRemove: true # optional, default is true
    storage:
      useAllNodes: true # optional, default value: true
      useAllDevices: true # optional, default value: true
      # Global filter to only select certain devicesnames. This example matches names starting with sda or sdb.
      # Will only be used if useAllDevices is set to false and will be ignored if individual devices have been specified on a node.
      deviceFilter: "^sd[a-b]"
      # This setting can be used to store metadata on a different device. Only recommended if an additional metadata device is available.
      # Optional, will be overwritten by the corresponding node-level setting.
      config:
        metadataDevice: "sda"
      # Names of individual nodes in the cluster that should have their storage included.
      # Will only be used if useAllNodes is set to false.
      nodes:
        - name: "<ip-adress of node_1>"
          devices:
            - name: "sdb" 
        - name: "<ip-adress of node_2>"
          deviceFilter: "^sd[a-b]"
          config:
            metadataDevice: "sda" # optional
    # This setting allows the request of ressources for mgr, mon and osd pods.
    resources:
      mgr:
        requests:
          cpu: "500m" # optional, default is 500m
          memory: "1Gi" # optional, default is 1Gi
      mon:
        requests:
          cpu: "2" # optional, default is 2
          memory: "4Gi" # optional, default is 4Gi
      osd:
        requests:
          cpu: "2" # optional, default is 2
          memory: "4Gi" # optional, default is 4Gi
  operator:
    data:
      rookLogLevel: "DEBUG" # optional, default is DEBUG
  # Specify the filesystem type of the volume. Default value: "ext4"
  blockStorageClass:
    parameters:
      fstype: "ext4" # optional, default value is ext4
#-------------------------------------------------------------------------------------------------------------------------------
### Values for Postgres ###
postgrespass: "password" # mandatory, set password for harbor postgres access 
postgres:
  storageClassName: "rook-cephfs" # optional, default is rook-cephfs
  volumeMode: "Filesystem" # optional, default is  Filesystem
  accessModes: ["ReadWriteMany"] #optional, default is [ReadWriteMany]
  resources:
    requests:
      storage: 2Gi # mandatory, depending on storage capacity
#-------------------------------------------------------------------------------------------------------------------------------
### Values for Redis ###
redispass: "password" # mandatory set password for harbor redis access 
redis:
  storageClassName: "rook-cephfs" # optional, default is rook-cephfs
  volumeMode: "Filesystem" # optional, default is  Filesystem
  accessModes: ["ReadWriteMany"] #optional, default is [ReadWriteMany]
  resources:
    requests:
      storage: 2Gi # mandatory depending on storage capacity
#-------------------------------------------------------------------------------------------------------------------------------
### Values for Harbor deployment ###
## For detailed explaination for each key see: https://artifacthub.io/packages/helm/harbor/harbor/1.8.1#configuration ##
harborValues: 
  namespace: kubeops # optional, default is kubeops
  harborpass: "password" # mandatory: set password for harbor access 
  externalURL: https://10.2.10.13 # mandatory, the ip address, from which harbor is accessable outside of the cluster
  nodePort: 30003
  harborPersistence:
    persistentVolumeClaim:
      registry:
        size: 5Gi # mandatory, depending on storage capacity
        storageClass: "rook-cephfs" #optional, default is rook-cephfs
      chartmuseum:
        size: 5Gi # mandatory, depending on storage capacity
        storageClass: "rook-cephfs" #optional, default is rook-cephfs
      jobservice:
        jobLog:
          size: 1Gi # mandatory: Depending on storage capacity
          storageClass: "rook-cephfs" #optional, default is rook-cephfs
        scanDataExports:
          size: 1Gi # mandatory: Depending on storage capacity
          storageClass: "rook-cephfs" #optional, default is rook-cephfs
      database:
        size: 1Gi # mandatory, depending on storage capacity
        storageClass: "rook-cephfs" #optional, default is rook-cephfs
      redis:
        size: 1Gi # mandatory, depending on storage capacity
        storageClass: "rook-cephfs" #optional, default is rook-cephfs
      trivy: 
        size: 5Gi # mandatory, depending on storage capacity
        storageClass: "rook-cephfs" #optional, default is rook-cephfs
#--------------------------------------------------------------------------------------------------------------------------------------
###Values for filebeat deployment###
filebeatValues:
  namespace: kubeops # optional, default is kubeops   
#--------------------------------------------------------------------------------------------------------------------------------
###Values for Logstash deployment###
##For detailed explaination for each key see: https://github.com/elastic/helm-charts/releases/tag/v7.16.3###
logstashValues:
  namespace: kubeops
  volumeClaimTemplate:
    resources:
      requests:
        storage: 1Gi # mandatory, depending on storage capacity
    accessModes: 
      - ReadWriteMany #optional, default is [ReadWriteMany]
    storageClassName: "rook-cephfs" #optional, default is rook-cephfs
#--------------------------------------------------------------------------------------------------------------------------------------
###Values for OpenSearch-Dashboards deployment###
##For detailed explaination for each key see: https://github.com/opensearch-project/helm-charts/tree/main/charts/opensearch-dashboards###
openSearchDashboardValues:
  namespace: kubeops
  nodePort: 30050
#--------------------------------------------------------------------------------------------------------------------------------
###Values for OpenSearch deployment###
##For detailed explaination for each key see: https://github.com/opensearch-project/helm-charts/tree/main/charts/opensearch###
openSearchValues:
  namespace: kubeops
  opensearchJavaOpts: "-Xmx512M -Xms512M" # optional, default is -Xmx512M -Xms512M
  resources:
    requests:
      cpu: "250m" # optional, default is 250m
      memory: "1024Mi" # optional, default is 1024Mi
    limits:
      cpu: "300m" # optional, default is 300m
      memory: "3072Mi" # optional, default is 3072Mi
  persistence:
    size: 4Gi # mandatory
    enabled: "true" # optional, default is true
    enableInitChown: "false" # optional, default is false
    labels:
      enabled: "false" # optional, default is false
    storageClass: "rook-cephfs" # optional, default is rook-cephfs
    accessModes:
      - "ReadWriteMany" # optional, default is {ReadWriteMany}
  securityConfig:
    enabled: false # optional, default value: false
    ### Additional values can be set, if securityConfig is enabled:
    # path: "/usr/share/opensearch/plugins/opensearch-security/securityconfig"
    # actionGroupsSecret:
    # configSecret:
    # internalUsersSecret: internal-users-config-secret
    # rolesSecret:
    # rolesMappingSecret:
    # tenantsSecret:
    # config:
    #   securityConfigSecret: ""
    #   dataComplete: true
    #   data: {}
  replicas: "3" # optional, default is 3
#--------------------------------------------------------------------------------------------------------------------------------
###Values for Prometheus deployment###
prometheusValues:
  namespace: kubeops # optional, default is kubeops
  privateRegistry: false # optional, default is false
  grafanaUsername: "user" # optional, default is user
  grafanaPassword: "password" # optional, default is password
  grafanaResources:
    storageClass: "rook-cephfs" # optional, default is rook-cephfs
    storage: 5Gi # optional, default is 5Gi
    nodePort: 30211 # optional, default is 30211

  prometheusResources:
    storageClass: "rook-cephfs" # optional, default is rook-cephfs
    storage: 25Gi # optional, default is 25Gi
    retention: 10d # optional, default is 10d
    retentionSize: "24GB" # optional, default is 24GB
    nodePort: 32090
#--------------------------------------------------------------------------------------------------------------------------------
###Values for OPA deployment###
opaValues:
  namespace: kubeops

#--------------------------------------------------------------------------------------------------------------------------------
###Values for Headlamp deployment###
headlampValues:
  service:
    nodePort: 30007
#--------------------------------------------------------------------------------------------------------------------------------
###Values for cert-manager deployment###
certmanValues:
  namespace: kubeops
  replicaCount: 3
  logLevel: 2
#--------------------------------------------------------------------------------------------------------------------------------
###Values for ingress-nginx deployment###
ingressValues:
  namespace: kubeops
keycloakValues:
  namespace: "kubeops" # Optional, default is "keycloak"
  storageClass: "rook-cephfs" # Optional, default is "rook-cephfs"
  keycloak:
    auth:
      adminUser: admin # Optional, default is admin
      adminPassword: admin # Optional, default is admin
      existingSecret: "" # Optional, default is ""
  postgresql:
    auth:
      postgresPassword: "" # Optional, default is ""
      username: bn_keycloak # Optional, default is "bn_keycloak"
      password: "" # Optional, default is ""
      database: bitnami_keycloak # Optional, default is "bitnami_keycloak"
      existingSecret: "" # Optional, default is ""

Check out our latest blogpost


Kubernetes 1.32 is here! With enhancements in scalability, security, and network performance, this release takes your clusters to the next level. Support up to 20,000 nodes, secure sensitive data with TLS 1.3, and leverage optimized storage and routing features.