The module lifecycle stagePreview

Administrator Guide

This guide is intended for Deckhouse Kubernetes Platform cluster administrators who manage Memcached infrastructure for users.

The primary tool for administrators is the MemcachedClass resource. This cluster-scoped Custom Resource defines what Memcached configurations can be deployed by users, establishes resource policies, constraints, and validation rules. All user Memcached instances are created based on classes that you define as an administrator.

Table of Contents

Overview

MemcachedClass is a cluster-scoped Custom Resource that defines policies and constraints for user-created Memcached resources.

Essentially, MemcachedClass serves as a constructor (template) for managed-service Memcached — it defines a set of rules and default values based on which specific Memcached instances will be created. Every Memcached resource created by a user must reference one of the existing classes via the memcachedClassName field.

The cluster administrator creates and manages classes to control what Memcached configurations can be deployed in the cluster.

Purpose of MemcachedClass

The MemcachedClass resource allows administrators to:

  • Define acceptable CPU and memory ranges for Memcached instances
  • Set default Memcached configuration
  • Restrict parameters that users can override
  • Configure pod placement rules (node affinity, tolerations, node selector)
  • Define topology policies for high availability
  • Set custom validation rules using CEL (Common Expression Language)

MemcachedClass Structure

Basic Example (default class from module)

apiVersion: managed-services.deckhouse.io/v1alpha2
kind: MemcachedClass
metadata:
  name: default
spec:
  topology:
    allowedTopologies:
      - Zonal
      - TransZonal
      - Ignored
    defaultTopology: "Ignored"
  overridableConfiguration:
    - maxItemSize
    - slabMinSize
  validations:
    - message: "max item size must be smaller than 1/2 memory size"
      rule: "configuration.maxItemSize <= (instance.memory.size / 2)"
    - message: "maxItemSize must be greater than 512k"
      rule: "configuration.maxItemSize >= (1024 * 512)"
    - message: "maxItemSize must divisible by slabChunkMax (default 524288 bytes 512kB)"
      rule: "(configuration.maxItemSize % (1024 * 512)) == 0"
  configuration:
    threads: 5
    maxConnections: 2000
    maxItemSize: "4Mi"
    slabMinSize: "Short"
    lockMemory: false
  sizingPolicies:
    - cores:
        min: 1
        max: 4
      memory:
        min: 100Mi
        max: 1Gi
        step: 1Mi
      coreFraction:
        - "1%"
        - "5%"
        - "10%"
    - cores:
        min: 5
        max: 10
      memory:
        min: 400Mi
        max: 10Gi
      coreFraction:
        - "5%"
        - "10%"
        - "15%"

Specification Fields

1. sizingPolicies (required)

Defines acceptable CPU and memory combinations. User’s Memcached resource must match one of the defined sizing policies.

sizingPolicies:
  - cores:
      min: 1          # Minimum number of cores
      max: 4          # Maximum number of cores
    memory:
      min: 256Mi      # Minimum memory size
      max: 8Gi        # Maximum memory size
      step: 256Mi     # Memory increment step (optional)
    coreFraction:     # Allowed coreFraction values (optional)
      - "5%"
      - "10%"
      - "25%"

Validation Rules:

  • User instance’s CPU and memory must fall within the range of one of the sizing policies
  • If coreFraction is specified, user’s value must be in the list
  • If step is specified, user’s memory size must be a multiple of this step
  • CPU ranges of different sizing policies must not overlap

Example Error:

If a user creates a Memcached with 3 cores and 16Gi memory with the above sizing policy:

haven't found matching size policy in class default

2. configuration (optional)

Default Memcached configuration. These values are used if the user doesn’t specify their own or if the user is not allowed to override them via overridableConfiguration.

configuration:
  threads: 4                    # Number of Memcached worker threads (administrator only)
  maxConnections: 1024          # Maximum number of concurrent connections (administrator only)
  maxItemSize: "4Mi"           # Maximum cache item size
  slabMinSize: "Medium"        # Slab size (Short: 50 bytes, Medium: 100 bytes, Long: 200 bytes)
  lockMemory: false            # Memory locking (mlockall)

Important: The threads and maxConnections parameters are administrator-only and cannot be added to overridableConfiguration. Users cannot override these parameters.

Parameters:

Parameter Type Description Values Availability
threads integer Number of Memcached server worker threads Positive number Administrator only
maxConnections integer Maximum number of concurrent connections Positive number Administrator only
maxItemSize Quantity Maximum size of a cache item E.g.: “512k”, “1Mi”, “4Mi” Can be in overridableConfiguration
slabMinSize string Minimum slab page size “Short” (50 bytes), “Medium” (100 bytes), “Long” (200 bytes) Can be in overridableConfiguration
lockMemory boolean Lock memory (use mlockall) true/false Can be in overridableConfiguration

3. overridableConfiguration (optional)

List of configuration parameters that users can override in their Memcached resource.

overridableConfiguration:
  - maxItemSize
  - slabMinSize
  - lockMemory

Allowed Values:

  • lockMemory
  • slabMinSize
  • maxItemSize

Important: If a user tries to override a parameter not listed in overridableConfiguration, validation will fail with an error:

ValidationError: configuration field [<field_name>] is not allowed to be overridden by user

4. validations (optional)

Custom validation rules based on CEL (Common Expression Language).

Important: The default default class already includes CEL rules that prevent starting Memcached configurations that are guaranteed to fail (for example, when maxItemSize is too large or not a multiple of the required value). These rules are based on Memcached server limitations and help avoid configuration errors.

Recommendation: When creating your own classes, it is highly recommended to copy these validation rules from the default class into your custom classes. This ensures basic configuration correctness checks and prevents creating instances with invalid parameters.

validations:
  - message: "max item size must be smaller than 1/2 memory size"
    rule: "configuration.maxItemSize <= (instance.memory.size / 2)"
  - message: "maxItemSize must be greater than 512k"
    rule: "configuration.maxItemSize >= (1024 * 512)"
  - message: "maxItemSize must be divisible by 512k"
    rule: "(configuration.maxItemSize % (1024 * 512)) == 0"

Available Variables in CEL:

Variable Type Description
instance.memory.size int Memory size in bytes
instance.cpu.cores int Number of CPU cores
configuration.maxItemSize int Maximum item size in bytes
configuration.lockMemory bool Memory lock flag
configuration.cpu.coreFraction int CPU core fraction (1-100)
configuration.slabMinSize string Slab size (“Short”, “Medium”, “Long”)
configuration.maxConnections int Maximum number of connections
configuration.threads int Number of threads

Example Rules:

# Check that maxItemSize doesn't exceed half of memory
- message: "maxItemSize too large"
  rule: "configuration.maxItemSize <= (instance.memory.size / 2)"

# Check thread to core ratio
- message: "threads should not exceed cores * 2"
  rule: "configuration.threads <= (instance.cpu.cores * 2)"

5. topology (required)

Defines topology policies for high availability.

topology:
  allowedTopologies:
    - Zonal
    - TransZonal
    - Ignored
  defaultTopology: "TransZonal"
  allowedZones:
    - zone-a
    - zone-b
    - zone-c

Parameters:

  • allowedTopologies — list of allowed topologies:

    • Zonal: all cluster pods are placed in one zone (requires exactly 1 zone in allowedZones)
    • TransZonal: cluster pods are placed in different zones (requires at least 2 zones)
    • Ignored: pods are placed without zone consideration, using standard k8s rules
  • defaultTopology — default topology (if user doesn’t specify)

  • allowedZones — list of allowed availability zones (optional)

Validation Rules:

  1. For TransZonal:

    • At least 2 zones required in allowedZones
    • Group size (group.size) must not exceed the number of zones
  2. For Zonal:

    • Exactly 1 zone required in allowedZones
  3. defaultTopology must be in the allowedTopologies list

Example Errors:

ValidationError: topology TransZonal not allowed by class default
TransZonal Topology can't be used with less than 2 AllowedZones in selected memcachedClass
You need to have at least 3 allowed zones in memcached class default. You have only 2

6. Pod Placement Rules

Important about Pod Placement Rule Merging:

Pod placement rules from the class (affinity, tolerations, topologySpreadConstraints, nodeSelector, etc., and topology parameters) are merged with rules from the user’s Memcached resource:

  • Standard behavior: Both class rules (defined by the administrator) and user resource rules are applied simultaneously. This allows administrators to establish baseline placement requirements that users can supplement with their specific requirements.

  • Special case (Ignored topology): If a user explicitly specifies Ignored topology in their resource, and this is allowed in the class’s allowedTopologies, only the administrator’s rules from the class (affinity, tolerations, topologySpreadConstraints) will be applied for placement, without automatic zone distribution.

nodeSelector (optional)

Allows placing Memcached pods only on nodes with specific labels.

nodeSelector:
  node-role.kubernetes.io/memcached: ""
  disktype: ssd

affinity (optional)

Configure node affinity for more flexible placement control.

affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
        - matchExpressions:
            - key: node.deckhouse.io/group
              operator: In
              values:
                - memcached

tolerations (optional)

Allows pods to be placed on nodes with taints.

tolerations:
  - key: "memcached"
    operator: "Equal"
    value: "true"
    effect: "NoSchedule"
  - key: "high-memory"
    operator: "Exists"
    effect: "NoSchedule"

How MemcachedClass Constrains User Resources

Important Note About Non-Existent Classes

Important: If a user specifies a class in memcachedClassName that doesn’t exist in the cluster, the Memcached resource will be successfully created, but the service will not be deployed until the specified class appears in the cluster.

When an administrator creates the required class:

  1. All validations of the user’s resource will automatically run
  2. If validation errors are found, they will be recorded in the status.conditions of the Memcached resource
  3. The user will be able to see these errors via kubectl describe memcached <name> or by checking conditions in the status

This allows users to create resources in advance while waiting for the required class, but administrators should inform users about creating new classes.

Validation Process

When a user creates or updates a Memcached resource, the operator performs the following checks:

  1. Sizing Policy Validation

    • Verifies CPU and memory fall within one of the sizingPolicies
    • Checks coreFraction if specified in policy
    • Checks memory step if specified in policy
  2. User Configuration Validation

    • Verifies user only overrides fields from overridableConfiguration
  3. Topology Validation

    • Checks selected topology is in allowedTopologies
    • Verifies zone count matches topology requirements
  4. CEL Validations

    • Executes all rules from validations

Validation Examples

Example 1: Sizing Policy Mismatch

MemcachedClass:

sizingPolicies:
  - cores:
      min: 1
      max: 4
    memory:
      min: 256Mi
      max: 8Gi

Memcached (error):

spec:
  instance:
    cpu:
      cores: 8        # Exceeds max: 4
    memory:
      size: 16Gi

Error: haven't found matching size policy in class

Example 2: Attempt to Override Forbidden Parameter

MemcachedClass:

configuration:
  threads: 4
  maxItemSize: "4Mi"
overridableConfiguration:
  - maxItemSize

Memcached (error):

spec:
  configuration:
    maxItemSize: "2Mi"  # OK - in overridableConfiguration list
    lockMemory: true    # ERROR - not in overridableConfiguration list

Error: configuration field [lockMemory] is not allowed to be overridden by user

Example 3: CEL Rule Violation

MemcachedClass:

validations:
  - message: "maxItemSize must be less than half of memory"
    rule: "configuration.maxItemSize <= (instance.memory.size / 2)"

Memcached (error):

spec:
  instance:
    memory:
      size: 1Gi
  configuration:
    maxItemSize: "600Mi"  # More than 512Mi (half of 1Gi)

Error: ValidationError: maxItemSize must be less than half of memory

Configuration Examples

Example 1: Class for Development Environment

apiVersion: managed-services.deckhouse.io/v1alpha2
kind: MemcachedClass
metadata:
  name: dev
spec:
  sizingPolicies:
    - cores:
        min: 1
        max: 2
      memory:
        min: 128Mi
        max: 2Gi
      coreFraction:
        - "5%"
        - "10%"
  
  configuration:
    threads: 2
    maxConnections: 500
    maxItemSize: "1Mi"
    slabMinSize: "Short"
    lockMemory: false
  
  overridableConfiguration:
    - maxItemSize
    - slabMinSize
  
  topology:
    allowedTopologies:
      - Ignored
    defaultTopology: "Ignored"
  
  validations:
    - message: "maxItemSize must be smaller than 1/2 memory size"
      rule: "configuration.maxItemSize <= (instance.memory.size / 2)"

Example 2: Class for Production Environment

apiVersion: managed-services.deckhouse.io/v1alpha2
kind: MemcachedClass
metadata:
  name: production
spec:
  sizingPolicies:
    - cores:
        min: 4
        max: 16
      memory:
        min: 4Gi
        max: 64Gi
        step: 4Gi
      coreFraction:
        - "50%"
        - "100%"
  
  configuration:
    threads: 8
    maxConnections: 4096
    maxItemSize: "8Mi"
    slabMinSize: "Medium"
    lockMemory: true
  
  overridableConfiguration:
    - maxItemSize
    - slabMinSize
  
  nodeSelector:
    node-role.kubernetes.io/memcached: ""
  
  tolerations:
    - key: "memcached"
      operator: "Equal"
      value: "true"
      effect: "NoSchedule"
  
  topology:
    allowedTopologies:
      - TransZonal
    defaultTopology: "TransZonal"
    allowedZones:
      - zone-a
      - zone-b
      - zone-c
  
  validations:
    - message: "maxItemSize must be smaller than 1/2 memory size"
      rule: "configuration.maxItemSize <= (instance.memory.size / 2)"
    - message: "maxItemSize must be greater than 1Mi"
      rule: "configuration.maxItemSize >= (1024 * 1024)"
    - message: "maxItemSize must be divisible by 512k"
      rule: "(configuration.maxItemSize % (1024 * 512)) == 0"
    - message: "production requires minimum 4 cores"
      rule: "instance.cpu.cores >= 4"

Example 3: Class with Multiple Sizing Policies

apiVersion: managed-services.deckhouse.io/v1alpha2
kind: MemcachedClass
metadata:
  name: flexible
spec:
  sizingPolicies:
    # Policy for small instances
    - cores:
        min: 1
        max: 4
      memory:
        min: 256Mi
        max: 4Gi
        step: 256Mi
      coreFraction:
        - "5%"
        - "10%"
        - "25%"
    
    # Policy for medium instances
    - cores:
        min: 5
        max: 8
      memory:
        min: 4Gi
        max: 16Gi
        step: 1Gi
      coreFraction:
        - "25%"
        - "50%"
    
    # Policy for large instances
    - cores:
        min: 9
        max: 16
      memory:
        min: 16Gi
        max: 64Gi
        step: 4Gi
      coreFraction:
        - "50%"
        - "100%"
  
  configuration:
    threads: 4
    maxConnections: 2048
    maxItemSize: "4Mi"
    slabMinSize: "Medium"
    lockMemory: false
  
  overridableConfiguration:
    - maxItemSize
    - slabMinSize
    - lockMemory
  
  topology:
    allowedTopologies:
      - Zonal
      - TransZonal
      - Ignored
    defaultTopology: "TransZonal"
    allowedZones:
      - zone-a
      - zone-b
      - zone-c
  
  validations:
    - message: "maxItemSize must be smaller than 1/2 memory size"
      rule: "configuration.maxItemSize <= (instance.memory.size / 2)"
    - message: "maxItemSize must be at least 512k"
      rule: "configuration.maxItemSize >= (1024 * 512)"

Managing Classes

Creating a Class

kubectl apply -f memcached-class.yaml

Viewing Classes

kubectl get memcachedclass
kubectl get memcachedclass default -o yaml

Updating a Class

Important: The spec field in MemcachedClass is immutable. This means that once a class is created, its specification cannot be changed.

If you need to modify a class:

  1. Create a new class with a different name
  2. Switch user resources to the new class
  3. Delete the old class

Deleting a Class

kubectl delete memcachedclass <name>

Warning: Before deleting a class, ensure there are no active Memcached resources using it.

Best Practices

For Production Environment

  1. Use Strict Sizing Policies

    • Define clear CPU and memory ranges
    • Use step to control granularity
    • Limit coreFraction to reasonable values
  2. Minimize overridableConfiguration

    • Allow overriding only critical parameters
    • Keep control of threads and maxConnections
  3. Use CEL Validations

    • Add rules to check parameter relationships
    • Prevent incorrect configurations
  4. Configure Topology

    • Use TransZonal for critical services
    • Specify concrete allowedZones
  5. Use Node Placement

    • Isolate Memcached on dedicated nodes
    • Use nodeSelector and tolerations

For Development Environment

  1. Use Flexible Sizing Policies

    • Wide CPU and memory ranges
    • Don’t restrict coreFraction
  2. Allow More overridableConfiguration

    • Let developers experiment with settings
  3. Simple Topology

    • Use Ignored for simplicity
  4. Minimal Validations

    • Only basic safety checks

Troubleshooting

Checking Validation

If a user’s Memcached isn’t being created, check events:

kubectl describe memcached <name> -n <namespace>

Look for the ConfigurationValid condition:

status:
  conditions:
    - type: ConfigurationValid
      status: "False"
      message: "ValidationError: max item size must be smaller than 1/2 memory size"