Skip to content

AI/ML Workloads Quiz

This quiz tests your understanding of running AI/ML workloads in Kubernetes.

Quiz Questions

1. What is the required resource request field for scheduling a pod that uses a GPU in Kubernetes?

A. resources.requests.gpu B. resources.requests.nvidia.com/gpu C. resources.requests.k8s.io/gpu D. resources.requests.compute/gpu

Show Answer

Answer: B. resources.requests.nvidia.com/gpu

Explanation: The required resource request field for scheduling a pod that uses a GPU in Kubernetes is resources.requests.nvidia.com/gpu. This is the standard way to request NVIDIA GPUs, and other GPU vendors may use their own namespaces (e.g., amd.com/gpu).

GPU resource request example:

yaml
apiVersion: v1
kind: Pod
metadata:
  name: gpu-pod
spec:
  containers:
  - name: gpu-container
    image: nvidia/cuda:11.0-base
    resources:
      limits:
        nvidia.com/gpu: 1  # Request 1 GPU
      requests:
        nvidia.com/gpu: 1  # Requests and limits must be the same

GPU resource characteristics:

  1. Integer allocation: GPUs can only be allocated in integer units (e.g., 1, 2, 3). Decimal values (e.g., 0.5) are not supported.
  2. Matching requests and limits: For GPU resources, requests and limits must be the same.
  3. Exclusive use: By default, GPUs are not shared between containers. Each GPU is assigned to only one container at a time.
  4. Node labels: Nodes with GPUs are typically labeled with nvidia.com/gpu.

Prerequisites for GPU usage:

  1. GPU hardware on node: Physical GPU must be installed on the node.
  2. GPU drivers: Appropriate GPU drivers must be installed on the node.
  3. NVIDIA Device Plugin: NVIDIA Device Plugin must be installed on the Kubernetes cluster.
  4. Container runtime support: Container runtime must support GPUs.

Installing NVIDIA Device Plugin:

bash
# Installation using Helm
helm repo add nvdp https://nvidia.github.io/k8s-device-plugin
helm repo update
helm install nvidia-device-plugin nvdp/nvidia-device-plugin

# Or direct installation
kubectl create -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.13.0/nvidia-device-plugin.yml

Checking GPU resources:

bash
# Check GPU resources on nodes
kubectl get nodes -o custom-columns=NAME:.metadata.name,GPU:.status.allocatable.nvidia\\.com/gpu

# Check pods using GPUs
kubectl get pods -A -o custom-columns=NAME:.metadata.name,GPU:.spec.containers[*].resources.limits.nvidia\\.com/gpu

Multi-GPU request:

yaml
apiVersion: v1
kind: Pod
metadata:
  name: multi-gpu-pod
spec:
  containers:
  - name: multi-gpu-container
    image: nvidia/cuda:11.0-base
    resources:
      limits:
        nvidia.com/gpu: 4  # Request 4 GPUs
      requests:
        nvidia.com/gpu: 4

GPU memory partitioning (NVIDIA MPS): NVIDIA Multi-Process Service (MPS) allows multiple processes to share the same GPU. This is not natively supported in Kubernetes and requires custom configuration.

Other GPU vendors: Other GPU vendors use their own namespaces:

  • AMD GPU: amd.com/gpu
  • Intel GPU: intel.com/gpu

Issues with other options:

  • A. resources.requests.gpu: This is not a valid Kubernetes resource field. GPU resources must use vendor-specific namespaces.
  • C. resources.requests.k8s.io/gpu: This is not a valid Kubernetes resource field. The k8s.io namespace is typically used for Kubernetes core resources.
  • D. resources.requests.compute/gpu: This is not a valid Kubernetes resource field.

2. What is the most suitable resource type for running distributed TensorFlow training jobs in Kubernetes?

A. Deployment B. StatefulSet C. Job D. TFJob (Kubeflow)

Show Answer

Answer: D. TFJob (Kubeflow)

Explanation: The most suitable resource type for running distributed TensorFlow training jobs in Kubernetes is TFJob. TFJob is part of the Kubeflow project and is a custom resource specifically designed for running TensorFlow training jobs on Kubernetes.

Key features of TFJob:

  1. Distributed training support: Supports TensorFlow's distributed training architecture including workers, parameter servers, and evaluators.
  2. Automatic recovery: Automatically restarts failed workers.
  3. Gang scheduling: Ensures all workers are scheduled simultaneously.
  4. TensorFlow-specific features: Automatically configures environment variables and settings needed for TensorFlow distributed training.
  5. Monitoring and logging: Provides features to monitor TensorFlow job status and logs.

TFJob example:

yaml
apiVersion: kubeflow.org/v1
kind: TFJob
metadata:
  name: mnist-training
spec:
  tfReplicaSpecs:
    Worker:
      replicas: 3
      restartPolicy: OnFailure
      template:
        spec:
          containers:
          - name: tensorflow
            image: tensorflow/tensorflow:2.6.0
            command:
            - python
            - /opt/model/train.py
            - --batch_size=64
            - --learning_rate=0.001
            resources:
              limits:
                nvidia.com/gpu: 1
    PS:
      replicas: 1
      restartPolicy: OnFailure
      template:
        spec:
          containers:
          - name: tensorflow
            image: tensorflow/tensorflow:2.6.0
            command:
            - python
            - /opt/model/train.py
            - --batch_size=64
            - --learning_rate=0.001
    Chief:
      replicas: 1
      restartPolicy: OnFailure
      template:
        spec:
          containers:
          - name: tensorflow
            image: tensorflow/tensorflow:2.6.0
            command:
            - python
            - /opt/model/train.py
            - --batch_size=64
            - --learning_rate=0.001
            resources:
              limits:
                nvidia.com/gpu: 1

TFJob components:

  1. Chief: The main worker responsible for saving model checkpoints and writing summaries.
  2. Worker: Workers that perform model training.
  3. PS (Parameter Server): Stores and updates model parameters.
  4. Evaluator: Performs model evaluation.

Installing TFJob:

bash
# Install Kubeflow
kubectl apply -f https://raw.githubusercontent.com/kubeflow/kubeflow/master/kfctl_k8s_istio.yaml

# Or install only the TFJob controller
kubectl apply -f https://raw.githubusercontent.com/kubeflow/tf-operator/master/deploy/v1/tf-operator.yaml

Monitoring TFJob:

bash
# Check TFJob status
kubectl get tfjobs

# Check specific TFJob details
kubectl describe tfjob mnist-training

# Check TFJob pods
kubectl get pods -l tf-job-name=mnist-training

Comparison with other resource types:

  1. Deployment:

    • Suitable for long-running services
    • Supports automatic recovery and rolling updates
    • Lacks coordination features for distributed training jobs
    • No TensorFlow-specific features
  2. StatefulSet:

    • Provides stable network identifiers and persistent storage
    • Ordered deployment and scaling
    • Lacks coordination features for distributed training jobs
    • No TensorFlow-specific features
  3. Job:

    • Suitable for one-time jobs
    • Guarantees job completion
    • Lacks coordination features for distributed training jobs
    • No TensorFlow-specific features
  4. TFJob:

    • Optimized for TensorFlow distributed training
    • Defines roles like workers, parameter servers
    • Automatically configures TensorFlow-specific environment variables and settings
    • Built-in job completion and failure handling logic

Kubeflow operators for other ML frameworks:

  • PyTorchJob: For PyTorch training jobs
  • MPIJob: For MPI-based distributed training like Horovod
  • XGBoostJob: For XGBoost training jobs

Issues with other options:

  • A. Deployment: Suitable for long-running services and doesn't handle the specific requirements of distributed TensorFlow training jobs.
  • B. StatefulSet: Suitable for applications requiring state persistence but lacks coordination features for distributed TensorFlow training jobs.
  • C. Job: Suitable for one-time jobs but doesn't handle the specific requirements of distributed TensorFlow training jobs.
### 3. What is the most important consideration when configuring persistent storage for AI/ML workloads in Kubernetes?

A. Storage capacity B. Storage class type C. Data access patterns and throughput requirements D. Storage provisioner

Show Answer

Answer: C. Data access patterns and throughput requirements

Explanation: The most important consideration when configuring persistent storage for AI/ML workloads in Kubernetes is data access patterns and throughput requirements. AI/ML workloads process large amounts of data and can have various access patterns (sequential reads, random reads, parallel access, etc.), often requiring high throughput. Choosing a storage solution that meets these requirements has a significant impact on performance and efficiency.

Common data access patterns in AI/ML workloads:

  1. Large dataset reads: Training datasets can range from several GB to several TB, requiring efficient read performance.
  2. Parallel access: Distributed training scenarios where multiple workers simultaneously access data are common.
  3. Sequential reads: Batch processing jobs that sequentially read entire datasets.
  4. Random access: Mini-batch training or online learning that accesses random parts of the dataset.
  5. Checkpoint saving: Write operations to save model checkpoints during training.

Storage solutions suitable for AI/ML workloads:

  1. Distributed file systems:

    • Amazon FSx for Lustre: High-performance file system optimized for high-performance computing and machine learning workloads
    • GlusterFS/Ceph: Open-source distributed file systems supporting scalability and parallel access
    • HDFS: Hadoop Distributed File System suitable for large-scale dataset processing
  2. High-performance block storage:

    • AWS EBS io2/io2 Block Express: SSD-based block storage providing high IOPS and throughput
    • GCP Persistent Disk SSD: SSD-based block storage providing high IOPS and throughput
    • Azure Ultra Disk: SSD-based block storage providing very high IOPS and throughput
  3. Object storage:

    • Amazon S3: Highly scalable object storage suitable for large-scale dataset storage
    • Google Cloud Storage: Highly scalable object storage suitable for large-scale dataset storage
    • Azure Blob Storage: Highly scalable object storage suitable for large-scale dataset storage

Storage configuration example (FSx for Lustre):

yaml
# StorageClass definition
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fsx-lustre
provisioner: fsx.csi.aws.com
parameters:
  subnetId: subnet-0eabfaa81fb22bcaf
  securityGroupIds: sg-068000ccf82dfba88
  deploymentType: SCRATCH_2
  automaticBackupRetentionDays: "0"
  dailyAutomaticBackupStartTime: "00:00"
  perUnitStorageThroughput: "200"
  dataCompressionType: "NONE"
mountOptions:
  - flock

---
# PersistentVolumeClaim definition
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: ml-dataset
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: fsx-lustre
  resources:
    requests:
      storage: 1200Gi

---
# Using in training job
apiVersion: kubeflow.org/v1
kind: TFJob
metadata:
  name: distributed-training
spec:
  tfReplicaSpecs:
    Worker:
      replicas: 4
      template:
        spec:
          containers:
          - name: tensorflow
            image: tensorflow/tensorflow:2.6.0-gpu
            command:
            - python
            - /opt/model/train.py
            volumeMounts:
            - name: dataset
              mountPath: /data
            resources:
              limits:
                nvidia.com/gpu: 1
          volumes:
          - name: dataset
            persistentVolumeClaim:
              claimName: ml-dataset

Performance metrics to consider when selecting storage:

  1. Throughput: Amount of data that can be read/written per second (MB/s or GB/s)
  2. IOPS (Input/Output Operations Per Second): Number of I/O operations that can be performed per second
  3. Latency: Response time for I/O requests
  4. Parallel access support: Ability for multiple clients to access simultaneously
  5. Scalability: Ability to maintain performance as data grows

Recommended storage by AI/ML workload type:

  1. Large-scale distributed training: FSx for Lustre, HDFS, Ceph
  2. Single-node training: High-performance SSD block storage
  3. Data preprocessing: Distributed file systems or object storage
  4. Model serving: High-performance SSD block storage or in-memory storage

Storage performance testing:

bash
# Storage performance test using FIO
kubectl run fio-test --image=nixery.dev/shell/fio --restart=Never -- \
  fio --name=benchmark --directory=/data --direct=1 --rw=randread --bs=4k \
  --size=1G --numjobs=16 --runtime=60 --group_reporting

Issues with other options:

  • A. Storage capacity: Important, but capacity alone cannot meet the performance requirements of AI/ML workloads.
  • B. Storage class type: Storage class defines the provisioning method but doesn't fully determine performance characteristics by itself.
  • D. Storage provisioner: Provisioner defines how storage is created but doesn't directly address workload performance requirements.

4. What is the most effective method for resource allocation for AI/ML workloads in Kubernetes?

A. Allocate the same resources to all pods B. Resource profiling and optimization based on workload characteristics C. Always request maximum resources D. Deploy without resource requests

Show Answer

Answer: B. Resource profiling and optimization based on workload characteristics

Explanation: The most effective method for resource allocation for AI/ML workloads in Kubernetes is resource profiling and optimization based on workload characteristics. AI/ML workloads have different resource requirements at various stages like training, inference, and data preprocessing, and understanding each workload's characteristics and allocating resources accordingly is important for optimizing performance and cost efficiency.

AI/ML workload resource profiling methods:

  1. Benchmarking: Run workloads with various resource configurations and measure performance.
  2. Monitoring: Monitor actual resource usage to identify patterns.
  3. Gradual adjustment: Start with initial estimates and gradually adjust resources.
  4. Auto-scaling: Automatically adjust resources based on workload demands.

Resource characteristics by AI/ML workload type:

  1. Model training:

    • CPU: Important for data preprocessing and feature engineering
    • GPU: Essential for deep learning model training
    • Memory: Needed for large datasets and model parameter storage
    • Storage: Needed for dataset and checkpoint storage
  2. Model inference:

    • CPU: Suitable for simple models or batch inference
    • GPU: Advantageous for complex models or real-time inference
    • Memory: Needed for model loading and input/output processing
    • Latency: Important for real-time inference
  3. Data preprocessing:

    • CPU: Parallel processing capability is important
    • Memory: Needed for large-scale dataset processing
    • Storage I/O: Data read/write performance is important

Resource optimization example:

yaml
# Training job - GPU and high memory requirements
apiVersion: kubeflow.org/v1
kind: TFJob
metadata:
  name: training-job
spec:
  tfReplicaSpecs:
    Worker:
      replicas: 4
      template:
        spec:
          containers:
          - name: tensorflow
            image: tensorflow/tensorflow:2.6.0-gpu
            resources:
              requests:
                cpu: 4
                memory: 16Gi
                nvidia.com/gpu: 1
              limits:
                cpu: 8
                memory: 32Gi
                nvidia.com/gpu: 1

---
# Inference service - low latency requirements
apiVersion: apps/v1
kind: Deployment
metadata:
  name: inference-service
spec:
  replicas: 3
  selector:
    matchLabels:
      app: inference
  template:
    metadata:
      labels:
        app: inference
    spec:
      containers:
      - name: inference
        image: tensorflow/serving:2.6.0-gpu
        resources:
          requests:
            cpu: 2
            memory: 4Gi
            nvidia.com/gpu: 1
          limits:
            cpu: 4
            memory: 8Gi
            nvidia.com/gpu: 1
        env:
        - name: TF_FORCE_GPU_ALLOW_GROWTH
          value: "true"

---
# Data preprocessing job - CPU and memory intensive
apiVersion: batch/v1
kind: Job
metadata:
  name: data-preprocessing
spec:
  template:
    spec:
      containers:
      - name: preprocessing
        image: python:3.9
        resources:
          requests:
            cpu: 8
            memory: 16Gi
          limits:
            cpu: 16
            memory: 32Gi

Resource monitoring and optimization tools:

  1. Prometheus + Grafana: Resource usage monitoring and visualization
  2. Kubernetes Metrics Server: Basic resource metric collection
  3. NVIDIA DCGM Exporter: GPU metric collection
  4. Vertical Pod Autoscaler: Automatic resource request adjustment
  5. Horizontal Pod Autoscaler: Automatic pod count adjustment

Resource optimization strategies:

  1. GPU sharing: Share GPUs between multiple jobs through NVIDIA MPS or time-sliced scheduling
  2. Memory optimization: Model quantization, lazy loading, memory-efficient algorithms
  3. Batch processing: Process inference requests in batches to improve throughput
  4. Auto-scaling: Automatically adjust resources based on load
  5. Node affinity: Place workloads on nodes with specific hardware characteristics

GPU memory optimization example:

yaml
apiVersion: v1
kind: Pod
metadata:
  name: gpu-memory-optimized
spec:
  containers:
  - name: tensorflow
    image: tensorflow/tensorflow:2.6.0-gpu
    env:
    - name: TF_FORCE_GPU_ALLOW_GROWTH
      value: "true"  # Allocate only as much GPU memory as needed
    - name: TF_GPU_ALLOCATOR
      value: "cuda_malloc_async"  # Use asynchronous memory allocator
    resources:
      limits:
        nvidia.com/gpu: 1

CPU and memory optimization example:

yaml
apiVersion: v1
kind: Pod
metadata:
  name: cpu-memory-optimized
spec:
  containers:
  - name: python
    image: python:3.9
    env:
    - name: OMP_NUM_THREADS
      value: "4"  # Limit OpenMP thread count
    - name: MKL_NUM_THREADS
      value: "4"  # Limit Intel MKL thread count
    resources:
      requests:
        cpu: 4
        memory: 8Gi
      limits:
        cpu: 8
        memory: 16Gi

Issues with other options:

  • A. Allocate the same resources to all pods: May cause resource waste or shortage by not considering different workload characteristics.
  • C. Always request maximum resources: Poor cost efficiency and low cluster resource utilization.
  • D. Deploy without resource requests: Can cause scheduling and resource contention issues, especially important for limited resources like GPUs.
### 5. What is the most suitable method for AI/ML model serving in Kubernetes?

A. Use regular Deployment resources B. Use specialized serving platforms like KServe (formerly KFServing) or Seldon Core C. Use StatefulSet resources D. Use CronJob resources

Show Answer

Answer: B. Use specialized serving platforms like KServe (formerly KFServing) or Seldon Core

Explanation: The most suitable method for AI/ML model serving in Kubernetes is to use specialized serving platforms like KServe (formerly KFServing) or Seldon Core. These platforms provide various features needed for model serving (model version management, A/B testing, canary deployment, auto-scaling, monitoring, etc.) and support various ML frameworks.

Key features of specialized model serving platforms:

  1. Various ML framework support: Supports models trained with various frameworks like TensorFlow, PyTorch, ONNX, scikit-learn
  2. Model version management: Manage multiple versions of models and enable rollback
  3. Traffic splitting: Traffic splitting features for A/B testing, canary deployment, etc.
  4. Auto-scaling: Auto-scaling based on request load
  5. Monitoring and logging: Monitoring of model performance, latency, throughput, etc.
  6. Pre and post-processing: Input data preprocessing and output data post-processing pipelines
  7. Batch inference: Support for batch inference on large amounts of data
  8. Model explainability: Features to explain model predictions

KServe example:

yaml
apiVersion: serving.kserve.io/v1beta1
kind: InferenceService
metadata:
  name: sklearn-iris
spec:
  predictor:
    sklearn:
      storageUri: "gs://kserve-examples/models/sklearn/iris"
      resources:
        requests:
          cpu: 100m
          memory: 256Mi
        limits:
          cpu: 1
          memory: 1Gi

Seldon Core example:

yaml
apiVersion: machinelearning.seldon.io/v1
kind: SeldonDeployment
metadata:
  name: iris-model
spec:
  name: iris
  predictors:
  - name: default
    replicas: 1
    graph:
      name: classifier
      implementation: SKLEARN_SERVER
      modelUri: "gs://seldon-models/sklearn/iris"
      envSecretRefName: seldon-init-container-secret
    engineResources:
      requests:
        cpu: 100m
        memory: 256Mi
      limits:
        cpu: 1
        memory: 1Gi

Advanced serving feature examples:

  1. Canary deployment (KServe):
yaml
apiVersion: serving.kserve.io/v1beta1
kind: InferenceService
metadata:
  name: sklearn-iris
spec:
  predictor:
    canaryTrafficPercent: 20
    sklearn:
      storageUri: "gs://kserve-examples/models/sklearn/iris-v2"
    containers:
    - name: sklearn-v1
      image: kserve/sklearnserver:latest
      args:
      - --model_dir=/mnt/models
      - --model_name=sklearn-iris
  1. Pre and post-processing pipeline (Seldon Core):
yaml
apiVersion: machinelearning.seldon.io/v1
kind: SeldonDeployment
metadata:
  name: iris-pipeline
spec:
  name: iris
  predictors:
  - name: default
    replicas: 1
    graph:
      name: preprocessor
      type: TRANSFORMER
      children:
      - name: model
        type: MODEL
        implementation: SKLEARN_SERVER
        modelUri: "gs://seldon-models/sklearn/iris"
        children:
        - name: postprocessor
          type: TRANSFORMER
          implementation: PYTHON
          modelUri: "gs://seldon-models/postprocessor"
  1. Multi-model serving (KServe):
yaml
apiVersion: serving.kserve.io/v1beta1
kind: InferenceService
metadata:
  name: multi-model-example
spec:
  predictor:
    triton:
      storageUri: "gs://kserve-examples/models/triton/multi-model"

Installing specialized serving platforms:

bash
# Install KServe
kubectl apply -f https://github.com/kserve/kserve/releases/download/v0.8.0/kserve.yaml

# Install Seldon Core (using Helm)
helm install seldon-core seldon-core-operator \
  --repo https://storage.googleapis.com/seldon-charts \
  --namespace seldon-system \
  --create-namespace

Model serving monitoring:

bash
# Check KServe service status
kubectl get inferenceservices

# Check Seldon Core service status
kubectl get seldondeployments

Comparison of regular Deployment and specialized serving platforms:

FeatureRegular DeploymentSpecialized Serving Platform
Basic servingSupportedSupported
Model version managementManual implementation requiredBuilt-in support
Traffic splittingManual implementation requiredBuilt-in support
Auto-scalingLimited support with HPAAdvanced scaling support
MonitoringManual implementation requiredBuilt-in support
Pre/post-processingManual implementation requiredBuilt-in support
Batch inferenceManual implementation requiredBuilt-in support
Model explainabilityManual implementation requiredBuilt-in support

Issues with other options:

  • A. Use regular Deployment resources: Basic serving is possible, but lacks features like model version management, traffic splitting, and advanced monitoring.
  • C. Use StatefulSet resources: Suitable for applications requiring state persistence but lacks specialized features for model serving.
  • D. Use CronJob resources: Suitable for periodic batch jobs and not suitable for real-time model serving.

6. What is the most suitable metric for configuring auto-scaling for AI/ML workloads in Kubernetes?

A. CPU utilization B. Memory utilization C. GPU utilization D. Custom metrics based on workload characteristics

Show Answer

Answer: D. Custom metrics based on workload characteristics

Explanation: The most suitable metric for configuring auto-scaling for AI/ML workloads in Kubernetes is custom metrics based on workload characteristics. AI/ML workloads may need scaling based on various factors beyond CPU, memory, and GPU utilization, such as request latency, queue length, and batch size. Selecting metrics that best reflect the workload characteristics is important.

Types of auto-scaling metrics for AI/ML workloads:

  1. Resource-based metrics:

    • CPU utilization
    • Memory utilization
    • GPU utilization
  2. Custom metrics:

    • Request latency
    • Request throughput
    • Queue length
    • Batch size
    • Model accuracy
    • Inference time
  3. External metrics:

    • Message queue length (Kafka, RabbitMQ, etc.)
    • Database query latency
    • API gateway request count

Recommended metrics by AI/ML workload type:

  1. Model inference service:

    • Request latency
    • Requests per second (RPS)
    • Number of queued requests
  2. Batch processing jobs:

    • Job queue length
    • Amount of data pending processing
    • Job completion time
  3. Streaming processing:

    • Stream processing latency
    • Event processing rate
    • Number of unprocessed events

Horizontal Pod Autoscaler (HPA) examples:

yaml
# CPU utilization-based HPA
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: inference-hpa-cpu
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: inference-service
  minReplicas: 1
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70

---
# Custom metric-based HPA
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: inference-hpa-custom
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: inference-service
  minReplicas: 1
  maxReplicas: 10
  metrics:
  - type: Pods
    pods:
      metric:
        name: inference_latency_milliseconds
      target:
        type: AverageValue
        averageValue: 100

---
# External metric-based HPA
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: inference-hpa-external
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: inference-service
  minReplicas: 1
  maxReplicas: 10
  metrics:
  - type: External
    external:
      metric:
        name: kafka_topic_lag
        selector:
          matchLabels:
            topic: inference-requests
      target:
        type: AverageValue
        averageValue: 100

Custom metric collection and exposure:

  1. Prometheus Adapter: Exposes metrics collected by Prometheus to the Kubernetes API
  2. Custom Metrics API: Exposes custom metrics to the Kubernetes API
  3. External Metrics API: Exposes external system metrics to the Kubernetes API

Prometheus Adapter configuration example:

yaml
# Prometheus Adapter configuration
apiVersion: v1
kind: ConfigMap
metadata:
  name: adapter-config
  namespace: monitoring
data:
  config.yaml: |
    rules:
    - seriesQuery: 'inference_latency_milliseconds{namespace!="",pod!=""}'
      resources:
        overrides:
          namespace: {resource: "namespace"}
          pod: {resource: "pod"}
      name:
        matches: "inference_latency_milliseconds"
      metricsQuery: 'avg(<<.Series>>{<<.LabelMatchers>>})'

KEDA (Kubernetes Event-driven Autoscaling) example:

yaml
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: inference-scaler
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: inference-service
  minReplicaCount: 1
  maxReplicaCount: 10
  triggers:
  - type: prometheus
    metadata:
      serverAddress: http://prometheus.monitoring.svc:9090
      metricName: inference_latency_milliseconds
      threshold: "100"
      query: avg(inference_latency_milliseconds{service="inference-service"})

GPU utilization-based scaling: GPU utilization-based scaling can be implemented using tools like NVIDIA DCGM Exporter.

yaml
# NVIDIA DCGM Exporter deployment
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: dcgm-exporter
  namespace: monitoring
spec:
  selector:
    matchLabels:
      app: dcgm-exporter
  template:
    metadata:
      labels:
        app: dcgm-exporter
    spec:
      containers:
      - name: dcgm-exporter
        image: nvidia/dcgm-exporter:2.3.1-2.6.1-ubuntu20.04
        ports:
        - containerPort: 9400
          name: metrics
        securityContext:
          runAsNonRoot: false
          runAsUser: 0
        volumeMounts:
        - name: docker-socket
          mountPath: /var/run/docker.sock
      volumes:
      - name: docker-socket
        hostPath:
          path: /var/run/docker.sock

---
# GPU utilization-based HPA
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: inference-hpa-gpu
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: inference-service
  minReplicas: 1
  maxReplicas: 10
  metrics:
  - type: Pods
    pods:
      metric:
        name: DCGM_FI_DEV_GPU_UTIL
      target:
        type: AverageValue
        averageValue: 70

Considerations when selecting auto-scaling strategy:

  1. Workload characteristics: Batch processing, real-time inference, streaming processing, etc.
  2. Performance requirements: Latency, throughput, accuracy, etc.
  3. Resource efficiency: Cost optimization, resource utilization, etc.
  4. Scalability: Ability to respond to load variations
  5. Stability: Preventing service disruption due to rapid scaling

Issues with other options:

  • A. CPU utilization: AI/ML workloads are often GPU-bound or memory-bound, so CPU utilization alone may not lead to appropriate scaling decisions.
  • B. Memory utilization: Memory utilization typically doesn't increase proportionally with workload increase, especially remaining relatively constant after model loading.
  • C. GPU utilization: GPU utilization is an important metric, but not all AI/ML workloads use GPUs, and even when they do, GPU utilization alone may not fully reflect service quality.
### 7. What is the most important consideration when configuring networking for AI/ML workloads in Kubernetes?

A. Network policy configuration B. Service mesh implementation C. High-performance networking and topology awareness for distributed training D. External accessibility configuration

Show Answer

Answer: C. High-performance networking and topology awareness for distributed training

Explanation: The most important consideration when configuring networking for AI/ML workloads in Kubernetes is high-performance networking and topology awareness for distributed training. Distributed AI/ML workloads need to exchange large amounts of data and model parameters between nodes, so network performance has a significant impact on overall training and inference performance. Recognizing network topology to ensure communication between nearby nodes is important for minimizing latency.

Network requirements for distributed AI/ML workloads:

  1. High bandwidth: High network bandwidth for exchanging large amounts of data and model parameters
  2. Low latency: Low network latency for fast communication between nodes
  3. RDMA (Remote Direct Memory Access) support: Reduces CPU overhead through direct data transfer between memory
  4. Topology awareness: Pod placement considering network topology
  5. GPU direct communication: Technology support for direct GPU-to-GPU communication like NVIDIA GPUDirect RDMA

High-performance networking configuration example:

yaml
# Node selector and affinity settings for high-performance networking
apiVersion: kubeflow.org/v1
kind: TFJob
metadata:
  name: distributed-training
spec:
  tfReplicaSpecs:
    Worker:
      replicas: 4
      template:
        spec:
          nodeSelector:
            network-type: high-performance
          affinity:
            podAntiAffinity:
              preferredDuringSchedulingIgnoredDuringExecution:
              - weight: 100
                podAffinityTerm:
                  labelSelector:
                    matchExpressions:
                    - key: tf-job-name
                      operator: In
                      values:
                      - distributed-training
                  topologyKey: kubernetes.io/hostname
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                - matchExpressions:
                  - key: topology.kubernetes.io/zone
                    operator: In
                    values:
                    - us-west-2a
          containers:
          - name: tensorflow
            image: tensorflow/tensorflow:2.6.0-gpu
            env:
            - name: TF_CONFIG
              valueFrom:
                configMapKeyRef:
                  name: tf-config
                  key: tf-config.json
            resources:
              limits:
                nvidia.com/gpu: 1

Network topology awareness configuration:

yaml
# Topology spread constraints setting
apiVersion: v1
kind: Pod
metadata:
  name: ml-worker
  labels:
    app: distributed-training
spec:
  topologySpreadConstraints:
  - maxSkew: 1
    topologyKey: kubernetes.io/hostname
    whenUnsatisfiable: DoNotSchedule
    labelSelector:
      matchLabels:
        app: distributed-training
  - maxSkew: 1
    topologyKey: topology.kubernetes.io/zone
    whenUnsatisfiable: ScheduleAnyway
    labelSelector:
      matchLabels:
        app: distributed-training
  containers:
  - name: ml-container
    image: ml-training:latest

High-performance network interface configuration:

yaml
# High-performance network interface configuration using Multus CNI
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: sriov-net
spec:
  config: '{
    "cniVersion": "0.3.1",
    "name": "sriov-net",
    "type": "sriov",
    "ipam": {
      "type": "host-local",
      "subnet": "192.168.1.0/24",
      "rangeStart": "192.168.1.10",
      "rangeEnd": "192.168.1.200"
    }
  }'

---
apiVersion: v1
kind: Pod
metadata:
  name: ml-worker
  annotations:
    k8s.v1.cni.cncf.io/networks: sriov-net
spec:
  containers:
  - name: ml-container
    image: ml-training:latest
    resources:
      limits:
        intel.com/sriov: 1

RDMA support configuration:

yaml
# Configuration for RDMA support
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: rdma-net
spec:
  config: '{
    "cniVersion": "0.3.1",
    "name": "rdma-net",
    "type": "rdma",
    "ipam": {
      "type": "host-local",
      "subnet": "192.168.2.0/24"
    },
    "deviceID": "0000:03:00.0"
  }'

---
apiVersion: v1
kind: Pod
metadata:
  name: rdma-pod
  annotations:
    k8s.v1.cni.cncf.io/networks: rdma-net
spec:
  containers:
  - name: rdma-container
    image: rdma-app:latest
    securityContext:
      capabilities:
        add: ["IPC_LOCK"]
    volumeMounts:
    - name: rdma-devices
      mountPath: /dev/infiniband
  volumes:
  - name: rdma-devices
    hostPath:
      path: /dev/infiniband

NVIDIA GPUDirect RDMA configuration:

yaml
# Configuration for NVIDIA GPUDirect RDMA support
apiVersion: v1
kind: Pod
metadata:
  name: gpudirect-pod
spec:
  containers:
  - name: gpudirect-container
    image: nvidia/cuda:11.0-base
    command: ["sleep", "infinity"]
    resources:
      limits:
        nvidia.com/gpu: 1
    securityContext:
      capabilities:
        add: ["IPC_LOCK"]
    volumeMounts:
    - name: nvidia-dev
      mountPath: /dev/nvidia0
    - name: nvidia-uvm
      mountPath: /dev/nvidia-uvm
    - name: nvidia-uvm-tools
      mountPath: /dev/nvidia-uvm-tools
    - name: nvidia-modeset
      mountPath: /dev/nvidia-modeset
  volumes:
  - name: nvidia-dev
    hostPath:
      path: /dev/nvidia0
  - name: nvidia-uvm
    hostPath:
      path: /dev/nvidia-uvm
  - name: nvidia-uvm-tools
    hostPath:
      path: /dev/nvidia-uvm-tools
  - name: nvidia-modeset
    hostPath:
      path: /dev/nvidia-modeset

Network performance optimization strategies:

  1. Node placement optimization: Place related pods on same rack or nearby nodes
  2. Network interface optimization: Improve network performance using technologies like SR-IOV, DPDK
  3. Network topology awareness: Use topology spread constraints for pod placement considering network topology
  4. Dedicated network use: Configure dedicated network interfaces for AI/ML workloads
  5. MTU optimization: MTU (Maximum Transmission Unit) optimization for large packet transmission

Network performance testing:

bash
# Network performance test using iperf3
kubectl run iperf3-server --image=networkstatic/iperf3 --port=5201 -- -s
kubectl expose pod iperf3-server --port=5201 --target-port=5201

kubectl run iperf3-client --image=networkstatic/iperf3 --rm -it -- -c iperf3-server -p 5201 -t 30

Issues with other options:

  • A. Network policy configuration: Important for security but doesn't directly impact AI/ML workload performance.
  • B. Service mesh implementation: Useful for microservices architecture but doesn't meet high-performance networking requirements for AI/ML workloads.
  • D. External accessibility configuration: Important for model serving but doesn't directly impact distributed training performance.

8. What is the most important consideration when configuring security for AI/ML workloads in Kubernetes?

A. Network policy configuration B. Access control and encryption for models and data C. Container image scanning D. Pod security policy configuration

Show Answer

Answer: B. Access control and encryption for models and data

Explanation: The most important consideration when configuring security for AI/ML workloads in Kubernetes is access control and encryption for models and data. AI/ML workloads often handle sensitive data and intellectual property models, so protecting these assets is most important. Data leaks or model theft can have serious business and regulatory impacts.

Key security risks for AI/ML workloads:

  1. Data leakage: Leakage of sensitive information like training data, inference data
  2. Model theft: Theft of intellectual property model files
  3. Model poisoning: Degradation of model performance or bias injection through adversarial attacks
  4. Inference manipulation: Inducing wrong predictions through input data manipulation
  5. Privilege escalation: System access through excessive privileges

Key strategies for model and data security:

  1. Access control:

    • Fine-grained permission management through RBAC (Role-Based Access Control)
    • Apply principle of least privilege
    • Service account separation
  2. Encryption:

    • Encryption at Rest
    • Encryption in Transit
    • Model file encryption
  3. Secret management:

    • Use Kubernetes Secrets or external secret management systems
    • Secure management of API keys, authentication tokens, etc.
  4. Container security:

    • Run containers with minimal privileges
    • Use read-only file system
    • Run as non-root user

RBAC configuration example:

yaml
# Role definition for model access
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: model-reader
  namespace: ml-models
rules:
- apiGroups: [""]
  resources: ["secrets", "configmaps"]
  verbs: ["get", "list"]
  resourceNames: ["model-weights", "model-config"]

---
# Model access role binding
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: model-reader-binding
  namespace: ml-models
subjects:
- kind: ServiceAccount
  name: inference-service
  namespace: ml-models
roleRef:
  kind: Role
  name: model-reader
  apiGroup: rbac.authorization.k8s.io

Encrypted model storage example:

yaml
# Secret for encrypted model storage
apiVersion: v1
kind: Secret
metadata:
  name: model-weights
  namespace: ml-models
type: Opaque
data:
  model.h5: <base64-encoded-encrypted-model>

---
# Pod using encrypted model
apiVersion: v1
kind: Pod
metadata:
  name: inference-pod
  namespace: ml-models
spec:
  serviceAccountName: inference-service
  containers:
  - name: inference
    image: ml-inference:latest
    volumeMounts:
    - name: model-volume
      mountPath: /models
      readOnly: true
    env:
    - name: MODEL_ENCRYPTION_KEY
      valueFrom:
        secretKeyRef:
          name: model-encryption-keys
          key: key1
  volumes:
  - name: model-volume
    secret:
      secretName: model-weights

External secret management system integration example (HashiCorp Vault):

yaml
# Secret injection using Vault Agent Injector
apiVersion: v1
kind: Pod
metadata:
  name: ml-training
  namespace: ml-workloads
  annotations:
    vault.hashicorp.com/agent-inject: "true"
    vault.hashicorp.com/agent-inject-secret-db-creds: "database/creds/ml-training-role"
    vault.hashicorp.com/role: "ml-training-role"
spec:
  serviceAccountName: ml-training
  containers:
  - name: training
    image: ml-training:latest

Data encryption configuration example:

yaml
# PersistentVolume with EBS encryption
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: encrypted-data
  namespace: ml-workloads
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: encrypted-storage
  resources:
    requests:
      storage: 100Gi

---
# Encrypted storage class
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: encrypted-storage
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp3
  encrypted: "true"
  kmsKeyId: arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab

Container security hardening example:

yaml
# Security-hardened pod configuration
apiVersion: v1
kind: Pod
metadata:
  name: secure-ml-pod
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
    runAsGroup: 1000
    fsGroup: 1000
  containers:
  - name: ml-container
    image: ml-image:latest
    securityContext:
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true
      capabilities:
        drop:
        - ALL
    volumeMounts:
    - name: tmp
      mountPath: /tmp
    - name: model-output
      mountPath: /output
  volumes:
  - name: tmp
    emptyDir: {}
  - name: model-output
    persistentVolumeClaim:
      claimName: model-output-pvc

Network policy example:

yaml
# Network policy for ML workloads
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: ml-network-policy
  namespace: ml-workloads
spec:
  podSelector:
    matchLabels:
      app: ml-inference
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: frontend
    - podSelector:
        matchLabels:
          app: api-gateway
    ports:
    - protocol: TCP
      port: 8080
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          name: monitoring
    ports:
    - protocol: TCP
      port: 9090
  - to:
    - namespaceSelector:
        matchLabels:
          name: logging
    ports:
    - protocol: TCP
      port: 8125

Additional strategies for model and data security:

  1. Model signing and verification: Apply digital signatures to model files and verify before use
  2. Model version management: Track model versions and changes
  3. Audit logging: Maintain audit logs for model and data access
  4. Data masking: Mask sensitive data fields
  5. Differential privacy: Apply differential privacy techniques for personal information protection

Issues with other options:

  • A. Network policy configuration: Important but doesn't directly guarantee model and data security itself.
  • C. Container image scanning: Important for vulnerability management but doesn't directly address model and data security.
  • D. Pod security policy configuration: Strengthens container execution environment security but doesn't directly guarantee model and data security itself.
### 9. What is the most important metric for logging and monitoring configuration for AI/ML workloads in Kubernetes?

A. Pod and node status B. Model performance metrics (accuracy, latency, etc.) and resource usage C. API call count D. Network traffic

Show Answer

Answer: B. Model performance metrics (accuracy, latency, etc.) and resource usage

Explanation: The most important metrics for logging and monitoring configuration for AI/ML workloads in Kubernetes are model performance metrics (accuracy, latency, etc.) and resource usage. These metrics directly reflect model quality, SLO (Service Level Objective) compliance, and resource efficiency, and help detect model performance degradation or resource bottlenecks early.

Key monitoring metrics:

  1. Model performance metrics:

    • Accuracy: Accuracy of model predictions
    • Precision: Ratio of actual positives among those predicted as positive
    • Recall: Ratio of predictions as positive among actual positives
    • F1 Score: Harmonic mean of precision and recall
    • AUC-ROC: Performance measurement for binary classification models
    • Mean Squared Error (MSE): Error measurement for regression models
  2. Service level metrics:

    • Latency: Time from request to response
    • Throughput: Number of requests processed per unit time
    • Error Rate: Ratio of failed requests
    • Availability: Ratio of time service responded normally
  3. Resource usage:

    • CPU utilization: CPU utilization of containers and nodes
    • Memory utilization: Memory utilization of containers and nodes
    • GPU utilization: GPU computation and memory utilization
    • Disk I/O: Storage read/write performance
    • Network I/O: Network send/receive performance

Monitoring stack configuration example:

yaml
# Prometheus configuration
apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus-config
  namespace: monitoring
data:
  prometheus.yml: |
    global:
      scrape_interval: 15s
    scrape_configs:
    - job_name: 'kubernetes-pods'
      kubernetes_sd_configs:
      - role: pod
      relabel_configs:
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
        action: keep
        regex: true
    - job_name: 'ml-metrics'
      kubernetes_sd_configs:
      - role: pod
        selectors:
        - role: pod
          label: "app=ml-inference"
      relabel_configs:
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
        action: replace
        target_label: __metrics_path__
        regex: (.+)
      - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
        action: replace
        regex: ([^:]+)(?::\d+)?;(\d+)
        replacement: $1:$2
        target_label: __address__

---
# Expose metrics from ML service
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ml-inference
spec:
  replicas: 3
  selector:
    matchLabels:
      app: ml-inference
  template:
    metadata:
      labels:
        app: ml-inference
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "8080"
        prometheus.io/path: "/metrics"
    spec:
      containers:
      - name: inference
        image: ml-inference:latest
        ports:
        - containerPort: 8080
          name: http
        - containerPort: 9090
          name: metrics

Custom metric exposure example (Python):

python
from prometheus_client import start_http_server, Summary, Counter, Gauge, Histogram
import time
import random

# Metric definitions
INFERENCE_LATENCY = Histogram('inference_latency_seconds', 'Inference latency in seconds',
                             ['model', 'version'])
INFERENCE_REQUESTS = Counter('inference_requests_total', 'Total number of inference requests',
                            ['model', 'version', 'status'])
MODEL_ACCURACY = Gauge('model_accuracy', 'Model accuracy',
                      ['model', 'version', 'dataset'])
GPU_MEMORY_USAGE = Gauge('gpu_memory_usage_bytes', 'GPU memory usage in bytes',
                        ['device'])

# Start metrics server
start_http_server(9090)

# Metric update example
def process_request(model_name, model_version, input_data):
    start_time = time.time()

    try:
        # Perform model inference
        result = model.predict(input_data)

        # Record latency
        latency = time.time() - start_time
        INFERENCE_LATENCY.labels(model=model_name, version=model_version).observe(latency)

        # Increment request count
        INFERENCE_REQUESTS.labels(model=model_name, version=model_version, status="success").inc()

        # Update GPU memory usage
        GPU_MEMORY_USAGE.labels(device="gpu0").set(get_gpu_memory_usage())

        return result
    except Exception as e:
        # Increment error request count
        INFERENCE_REQUESTS.labels(model=model_name, version=model_version, status="error").inc()
        raise e

# Periodically update model accuracy
def update_model_accuracy():
    while True:
        accuracy = evaluate_model_accuracy()
        MODEL_ACCURACY.labels(model="image_classifier", version="v1", dataset="validation").set(accuracy)
        time.sleep(3600)  # Update every hour

Grafana dashboard configuration example:

yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: ml-dashboard
  namespace: monitoring
  labels:
    grafana_dashboard: "1"
data:
  ml-dashboard.json: |
    {
      "title": "ML Model Monitoring",
      "panels": [
        {
          "title": "Inference Latency",
          "type": "graph",
          "datasource": "Prometheus",
          "targets": [
            {
              "expr": "histogram_quantile(0.95, sum(rate(inference_latency_seconds_bucket[5m])) by (le, model, version))",
              "legendFormat": "p95 - {{model}} - {{version}}"
            },
            {
              "expr": "histogram_quantile(0.50, sum(rate(inference_latency_seconds_bucket[5m])) by (le, model, version))",
              "legendFormat": "p50 - {{model}} - {{version}}"
            }
          ]
        },
        {
          "title": "Request Rate",
          "type": "graph",
          "datasource": "Prometheus",
          "targets": [
            {
              "expr": "sum(rate(inference_requests_total[5m])) by (model, version, status)",
              "legendFormat": "{{model}} - {{version}} - {{status}}"
            }
          ]
        },
        {
          "title": "Model Accuracy",
          "type": "gauge",
          "datasource": "Prometheus",
          "targets": [
            {
              "expr": "model_accuracy",
              "legendFormat": "{{model}} - {{version}} - {{dataset}}"
            }
          ],
          "options": {
            "min": 0,
            "max": 1,
            "thresholds": [
              { "color": "red", "value": 0 },
              { "color": "yellow", "value": 0.7 },
              { "color": "green", "value": 0.9 }
            ]
          }
        },
        {
          "title": "GPU Memory Usage",
          "type": "graph",
          "datasource": "Prometheus",
          "targets": [
            {
              "expr": "gpu_memory_usage_bytes",
              "legendFormat": "{{device}}"
            }
          ]
        }
      ]
    }

Logging configuration example:

yaml
# Fluent Bit configuration
apiVersion: v1
kind: ConfigMap
metadata:
  name: fluent-bit-config
  namespace: logging
data:
  fluent-bit.conf: |
    [SERVICE]
        Flush        5
        Daemon       Off
        Log_Level    info

    [INPUT]
        Name             tail
        Tag              kube.*
        Path             /var/log/containers/*.log
        Parser           docker
        DB               /var/log/flb_kube.db
        Mem_Buf_Limit    5MB
        Skip_Long_Lines  On
        Refresh_Interval 10

    [FILTER]
        Name                kubernetes
        Match               kube.*
        Kube_URL            https://kubernetes.default.svc:443
        Kube_CA_File        /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
        Kube_Token_File     /var/run/secrets/kubernetes.io/serviceaccount/token
        Kube_Tag_Prefix     kube.var.log.containers.
        Merge_Log           On
        Merge_Log_Key       log_processed
        K8S-Logging.Parser  On
        K8S-Logging.Exclude Off

    [FILTER]
        Name         grep
        Match        kube.var.log.containers.ml-*
        Regex        log ERROR|WARN|INFO

    [OUTPUT]
        Name            es
        Match           kube.var.log.containers.ml-*
        Host            elasticsearch
        Port            9200
        Index           ml-logs
        Type            _doc
        Logstash_Format On
        Logstash_Prefix ml-logs
        Time_Key        @timestamp
        Replace_Dots    On
        Retry_Limit     False

Additional tools for model performance monitoring:

  1. MLflow: Experiment tracking, model version management, model registry
  2. TensorBoard: TensorFlow model training process and performance visualization
  3. Weights & Biases: Experiment tracking, model performance comparison, hyperparameter optimization
  4. Seldon Core Metrics: Model serving metrics provided by Seldon Core
  5. KServe Metrics: Model serving metrics provided by KServe

Monitoring alert configuration example:

yaml
# Prometheus alert rules
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: ml-alerts
  namespace: monitoring
spec:
  groups:
  - name: ml.rules
    rules:
    - alert: HighInferenceLatency
      expr: histogram_quantile(0.95, sum(rate(inference_latency_seconds_bucket[5m])) by (le, model, version)) > 0.5
      for: 5m
      labels:
        severity: warning
      annotations:
        summary: "High inference latency"
        description: "Model {{ $labels.model }} version {{ $labels.version }} has p95 latency above 500ms"

    - alert: LowModelAccuracy
      expr: model_accuracy < 0.8
      for: 10m
      labels:
        severity: critical
      annotations:
        summary: "Low model accuracy"
        description: "Model {{ $labels.model }} version {{ $labels.version }} has accuracy below 80%"

    - alert: HighErrorRate
      expr: sum(rate(inference_requests_total{status="error"}[5m])) / sum(rate(inference_requests_total[5m])) > 0.05
      for: 5m
      labels:
        severity: critical
      annotations:
        summary: "High error rate"
        description: "Error rate is above 5%"

Issues with other options:

  • A. Pod and node status: Important for basic system status monitoring but doesn't directly reflect AI/ML workload performance and quality.
  • C. API call count: Useful for measuring system usage but doesn't directly indicate model performance or resource efficiency.
  • D. Network traffic: Important for distributed training or large-scale data transfers but doesn't directly reflect model performance or quality.

10. What is the most effective cost optimization strategy for AI/ML workloads in Kubernetes?

A. Always use the latest instance types B. Use Spot instances for all workloads C. Appropriate instance type selection and auto-scaling based on workload characteristics D. Minimize requests and limits for all resources

Show Answer

Answer: C. Appropriate instance type selection and auto-scaling based on workload characteristics

Explanation: The most effective cost optimization strategy for AI/ML workloads in Kubernetes is appropriate instance type selection and auto-scaling based on workload characteristics. AI/ML workloads have different resource requirements at various stages like training, inference, and data preprocessing, and selecting instance types that match each workload's characteristics and auto-scaling as needed is important for optimizing cost efficiency.

Instance type selection by workload characteristics:

  1. Model training:

    • GPU instances: Suitable for deep learning model training
    • Memory-optimized instances: Suitable for large-scale dataset processing
    • Compute-optimized instances: Suitable for compute-intensive algorithms
  2. Model inference:

    • GPU instances: Suitable for complex models or real-time inference
    • CPU instances: Suitable for simple models or batch inference
    • Inference-optimized instances (AWS Inferentia, Google TPU, etc.): Specialized instances for inference
  3. Data preprocessing:

    • Compute-optimized instances: Suitable for parallel processing
    • Memory-optimized instances: Suitable for large-scale dataset processing
    • Storage-optimized instances: Suitable for I/O-intensive jobs

Node group configuration example:

yaml
# Training node group (GPU instances)
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
  name: ml-cluster
  region: us-west-2
nodeGroups:
  - name: training-ng
    instanceType: p3.2xlarge  # GPU instance
    minSize: 0
    maxSize: 10
    labels:
      workload-type: training
    taints:
      - key: workload-type
        value: training
        effect: NoSchedule
    tags:
      k8s.io/cluster-autoscaler/enabled: "true"
      k8s.io/cluster-autoscaler/ml-cluster: "owned"

  # Inference node group (CPU instances)
  - name: inference-ng
    instanceType: c5.2xlarge  # Compute-optimized instance
    minSize: 1
    maxSize: 20
    labels:
      workload-type: inference
    tags:
      k8s.io/cluster-autoscaler/enabled: "true"
      k8s.io/cluster-autoscaler/ml-cluster: "owned"

  # Data preprocessing node group (Memory-optimized instances)
  - name: preprocessing-ng
    instanceType: r5.2xlarge  # Memory-optimized instance
    minSize: 0
    maxSize: 10
    labels:
      workload-type: preprocessing
    tags:
      k8s.io/cluster-autoscaler/enabled: "true"
      k8s.io/cluster-autoscaler/ml-cluster: "owned"

  # Spot instance node group (Cost-effective batch jobs)
  - name: spot-ng
    instanceTypes: ["m5.xlarge", "m5a.xlarge", "m5n.xlarge"]
    minSize: 0
    maxSize: 20
    spot: true
    labels:
      workload-type: batch
    tags:
      k8s.io/cluster-autoscaler/enabled: "true"
      k8s.io/cluster-autoscaler/ml-cluster: "owned"

Workload placement example:

yaml
# Training job (Place on GPU nodes)
apiVersion: batch/v1
kind: Job
metadata:
  name: training-job
spec:
  template:
    spec:
      nodeSelector:
        workload-type: training
      containers:
      - name: training
        image: training:latest
        resources:
          limits:
            nvidia.com/gpu: 1

# Inference service (Place on CPU nodes)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: inference-service
spec:
  replicas: 3
  selector:
    matchLabels:
      app: inference
  template:
    metadata:
      labels:
        app: inference
    spec:
      nodeSelector:
        workload-type: inference
      containers:
      - name: inference
        image: inference:latest
        resources:
          requests:
            cpu: 1
            memory: 2Gi
          limits:
            cpu: 2
            memory: 4Gi

# Data preprocessing job (Place on memory-optimized nodes)
apiVersion: batch/v1
kind: Job
metadata:
  name: preprocessing-job
spec:
  template:
    spec:
      nodeSelector:
        workload-type: preprocessing
      containers:
      - name: preprocessing
        image: preprocessing:latest
        resources:
          requests:
            memory: 16Gi
          limits:
            memory: 32Gi

# Batch inference job (Place on Spot instances)
apiVersion: batch/v1
kind: Job
metadata:
  name: batch-inference
spec:
  template:
    spec:
      nodeSelector:
        workload-type: batch
      tolerations:
      - key: spot
        operator: Exists
      containers:
      - name: batch-inference
        image: batch-inference:latest

Auto-scaling configuration example:

yaml
# Cluster Autoscaler configuration
apiVersion: v1
kind: ConfigMap
metadata:
  name: cluster-autoscaler-config
  namespace: kube-system
data:
  config.yaml: |
    expendablePodsPriorityCutoff: -10
    scaleDownUtilizationThreshold: 0.5
    scaleDownUnneededTime: 5m
    scaleDownDelayAfterAdd: 5m
    scaleDownDelayAfterDelete: 0s
    scaleDownDelayAfterFailure: 3m
    maxNodeProvisionTime: 15m

# HPA configuration (Inference service)
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: inference-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: inference-service
  minReplicas: 2
  maxReplicas: 20
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  - type: Pods
    pods:
      metric:
        name: inference_latency_milliseconds
      target:
        type: AverageValue
        averageValue: 100

Cost optimization strategies:

  1. Appropriate instance type selection:

    • Select instance types that match workload characteristics
    • Select optimal instances through cost vs performance analysis
    • Utilize specialized instances (GPU, TPU, etc.)
  2. Spot instance utilization:

    • Use Spot instances for fault-tolerant workloads
    • Improve availability by specifying various instance types
    • Implement interruption tolerance strategies
  3. Auto-scaling:

    • Automatically adjust node count through Cluster Autoscaler
    • Automatically adjust pod count through HPA
    • Custom metric-based scaling
  4. Resource request and limit optimization:

    • Set resource requests based on actual usage
    • Automatically adjust resource requests through Vertical Pod Autoscaler
    • Resource usage monitoring and optimization
  5. Job schedule optimization:

    • Run batch jobs during lower cost time periods
    • Place lower priority jobs on low-cost resources
    • Job queue and priority settings

Cost monitoring and optimization tools:

  1. Kubecost: Cost monitoring and optimization for Kubernetes clusters
  2. AWS Cost Explorer: AWS resource cost analysis
  3. Google Cloud Cost Management: GCP resource cost analysis
  4. Azure Cost Management: Azure resource cost analysis
  5. Prometheus + Grafana: Custom cost dashboard configuration

Issues with other options:

  • A. Always use the latest instance types: Latest instances aren't always the most cost-effective, and selecting instances that match workload characteristics is more important.
  • B. Use Spot instances for all workloads: Spot instances can be interrupted, so they're not suitable for critical workloads that are sensitive to interruption.
  • D. Minimize requests and limits for all resources: Excessively minimizing resource requests can cause performance issues, and appropriate resource allocation matching workload characteristics is important.