算法艺术创作
algorithmic-art
通过代码和可调参数创作生成艺术与交互式视觉效果。
devops-kubernetes-for-data【设计与创意】Use this skill when running data workloads on Kubernetes: Spark on K8s, Airflow on K8s, Kafka on K8s, Strimzi, Spark Operator, Volcano, GPU scheduling, node pools, Karpenter, CSI storage for data workloads. This skill enforces: resource management for Spark executors, GPU scheduling config, node pool design, storage class selection, operator configur…
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Configures Kubernetes for data-intensive workloads: Spark, Airflow, Kafka, with GPU scheduling, node pools, and storage optimization.
User request includes: Kubernetes for data, Spark on K8s, Airflow on K8s, Kafka on K8s, Strimzi, Spark Operator, Volcano, GPU scheduling, node pools, data workloads K8s, Karpenter.
Kubernetes configuration for data workloads with Spark/Airflow/Kafka setup, GPU strategy, storage plan.
## Data Workloads on Kubernetes
### Workload Configuration
Spark Operator: {enabled/disabled} | Version: {N}
Airflow Executor: {KubernetesExecutor / CelacyKubernetesExecutor}
Kafka Operator: {Strimzi / custom}
### Node Pools
- compute-spot: {instance type} | {min-max} nodes | {spot/on-demand}
- compute-gpu: {instance type} | {GPU count} | {min-max} nodes
- storage-optimized: {instance type} | local SSD: {N GB}
### Resource Management
Spark Driver: {CPU: N, memory: N, memoryOverhead: N}
Spark Executor: {CPU: N, memory: N, instances: N}
Airflow Worker: {CPU: N, memory: N}
Kafka Broker: {CPU: N, memory: N, storage: N GB}
### GPU Scheduling
Runtime: {nvidia/cuda}
Node Selector: {node label}
Volcano Queue: {name}
### Storage
Spark Shuffle: {local SSD / PVC / emptyDir}
Kafka: {CSI driver} | {storage class} | {replication}
Airflow Logs: {S3/GCS/EFS}
No preamble. No postamble. No explanations. No filler/hedging/transitions. Compress output — why use many token when few do trick.
Driver: 1 CPU, 4GB memory, 512MB overhead. Executors: right-size based on data volume. Dynamic allocation with min/max bounds. Use nodeSelector for spot pool. Local SSD for shuffle.
apiVersion: sparkoperator.k8s.io/v1beta2
kind: SparkApplication
metadata:
name: spark-etl
spec:
type: Scala
mode: cluster
image: gcr.io/spark-operator/spark:v3.5.0
imagePullPolicy: Always
mainClass: com.example.ETLJob
mainApplicationFile: local:///opt/spark/jobs/etl.jar
sparkVersion: "3.5.0"
restartPolicy:
type: Never
driver:
cores: 1
coreLimit: "1200m"
memory: "4g"
serviceAccount: spark
labels:
version: 3.5.0
tolerations:
- key: workload-type
operator: Equal
value: data
effect: NoSchedule
executor:
instances: 10
cores: 2
coreLimit: "2200m"
memory: "8g"
memoryOverhead: "2g"
labels:
version: 3.5.0
tolerations:
- key: workload-type
operator: Equal
value: spark
effect: NoSchedule
dynamicAllocation:
enabled: true
initialExecutors: 5
minExecutors: 1
maxExecutors: 50
sparkConf:
spark.shuffle.service.enabled: "false"
spark.dynamicAllocation.enabled: "true"
spark.kubernetes.allocation.driver.requests.cores: "1"
spark.kubernetes.allocation.executor.requests.cores: "2"
spark.sql.adaptive.enabled: "true"
spark.sql.adaptive.coalescePartitions.enabled: "true"
Install NVIDIA GPU Operator. Define GPU-enabled node pool with taint. Use Volcano for batch GPU scheduling with queue management. Set GPU memory and count in pod spec.
# GPU pod spec
resources:
limits:
nvidia.com/gpu: 1
# Volcano GPU job with queue management
apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata:
name: gpu-training
spec:
queue: gpu-queue
minAvailable: 2
schedulerName: volcano
tasks:
- replicas: 4
name: trainer
template:
spec:
containers:
- name: trainer
image: pytorch/pytorch:2.1.0-cuda12.1
command: ["python", "train.py"]
resources:
requests:
cpu: "8"
memory: "32Gi"
nvidia.com/gpu: 1
limits:
cpu: "8"
memory: "32Gi"
nvidia.com/gpu: 1
tolerations:
- key: nvidia.com/gpu
operator: Exists
effect: NoSchedule
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: kafka-ssd
provisioner: ebs.csi.aws.com
parameters:
type: gp3
iops: "3000"
throughput: "125"
encrypted: "true"
reclaimPolicy: Retain
volumeBindingMode: WaitForFirstConsumer
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: kafka-data
labels:
app: kafka
spec:
accessModes:
- ReadWriteOnce
storageClassName: kafka-ssd
resources:
requests:
storage: 500Gi
Configure Karpenter provisioners per workload type. Set consolidation for cost. TTL for empty nodes. Node template with AMI, security group, subnet.
apiVersion: karpenter.sh/v1beta1
kind: NodePool
metadata:
name: spark-executor
spec:
template:
spec:
requirements:
- key: kubernetes.io/arch
operator: In
values: ["amd64"]
- key: karpenter.sh/capacity-type
operator: In
values: ["spot"]
- key: node.kubernetes.io/instance-type
operator: In
values: ["c5.4xlarge", "c5.8xlarge", "m5.4xlarge"]
- key: karpenter.k8s.aws/instance-family
operator: In
values: ["c5", "c6i", "m5", "m6i"]
nodeClassRef:
name: spark-executor-class
taints:
- key: workload-type
value: spark
effect: NoSchedule
limits:
cpu: 4000
memory: 16000Gi
disruption:
consolidationPolicy: WhenUnderutilized
expireAfter: 168h
---
apiVersion: karpenter.k8s.aws/v1beta1
kind: EC2NodeClass
metadata:
name: spark-executor-class
spec:
amiFamily: Bottlerocket
role: KarpenterNodeRole
subnetSelector:
karpenter.sh/discovery: data-cluster
securityGroupSelector:
karpenter.sh/discovery: data-cluster
tags:
Environment: production
WorkloadType: spark
blockDeviceMappings:
- deviceName: /dev/xvda
ebs:
volumeSize: 100Gi
volumeType: gp3
apiVersion: kafka.strimzi.io/v1beta2
kind: Kafka
metadata:
name: data-cluster
spec:
kafka:
version: 3.7.0
replicas: 3
listeners:
- name: plain
port: 9092
type: internal
tls: false
- name: tls
port: 9093
type: internal
tls: true
authorization:
type: simple
config:
offsets.topic.replication.factor: 3
transaction.state.log.replication.factor: 3
transaction.state.log.min.isr: 2
default.replication.factor: 3
min.insync.replicas: 2
log.retention.hours: 168
log.segment.bytes: "1073741824"
log.retention.bytes: "-1"
storage:
type: jbod
volumes:
- id: 0
type: persistent-claim
size: 500Gi
deleteClaim: false
class: kafka-ssd
rack:
topologyKey: topology.kubernetes.io/zone
template:
pod:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
- kafka-cluster
topologyKey: kubernetes.io/hostname
tolerations:
- key: workload-type
operator: Equal
value: kafka
effect: NoSchedule
zookeeper:
replicas: 3
storage:
type: persistent-claim
size: 50Gi
class: kafka-ssd
template:
pod:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
- kafka-zookeeper
topologyKey: kubernetes.io/hostname
entityOperator:
topicOperator: {}
userOperator: {}
# values.yaml for airflow Helm chart
config:
core:
executor: KubernetesExecutor
load_examples: "False"
kubernetes_executor:
worker_container_repository: apache/airflow
worker_container_tag: 2.9.0
namespace: airflow
delete_worker_pods: true
worker_pods_creation_batch_size: "10"
worker_pods_pending_timeout: "300"
kube_image_pull_policy: IfNotPresent
dags_in_image: "False"
logging:
remote_logging: "True"
remote_task_handler_args:
s3_log_server: "True"
s3_bucket: airflow-logs-prod
s3_region: us-east-1
s3_url: https://s3.us-east-1.amazonaws.com
executor: KubernetesExecutor
logs:
persistence:
enabled: false # Use S3/GCS instead
dags:
persistence:
enabled: true
storageAccessMode: ReadWriteMany
size: 10Gi
gitSync:
enabled: true
repo: https://github.com/org/airflow-dags.git
branch: main
subPath: dags
wait: 60
maxFailures: 5
workers:
replicas: 0 # K8sExecutor creates pods dynamically
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 2
memory: 4Gi
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: data-critical
value: 1000000
globalDefault: false
description: "Critical data pipeline tasks"
---
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: data-best-effort
value: 1000
globalDefault: false
description: "Best-effort Spark executors"
---
apiVersion: v1
kind: ResourceQuota
metadata:
name: data-quota
namespace: data
spec:
hard:
requests.cpu: "200"
requests.memory: "800Gi"
requests.nvidia.com/gpu: 16
persistentvolumeclaims: 50
count/priorityclasses.scheduling.k8s.io/data-critical: "4"
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: kafka-ingress
namespace: kafka
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: kafka-cluster
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: spark
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: airflow
ports:
- protocol: TCP
port: 9092
- protocol: TCP
port: 9093
apiVersion: tuned.openshift.io/v1
kind: Tuned
metadata:
name: data-workloads
spec:
profile:
- data: |
[sysctl]
vm.swappiness = 1
vm.dirty_ratio = 40
vm.dirty_background_ratio = 10
net.core.rmem_max = 134217728
net.core.wmem_max = 134217728
net.ipv4.tcp_rmem = 4096 87380 134217728
net.ipv4.tcp_wmem = 4096 65536 134217728
name: data-workloads
recommend:
- match:
- label: tuned.openshift.io/data
value: "true"
priority: 10
profile: data-workloads
cluster-autoscaler.kubernetes.io/safe-to-evict: "true".spark.dynamicAllocation.enabled, verify shuffle service.For data pipeline orchestration, hand off to etl-pipeline. For streaming infrastructure, hand off to streaming.