Back to skills
SKILL.md
K8s Workflow
CSecurityKubernetes core workflow rules, manifest conventions, security best practices, and version considerations. Includes managed K8s providers (EKS, AKS, GKE), autoscaling (KEDA, Knative, event-driven scaling), networking (Ingress, Gateway API, NetworkPolicy, Service Mesh), storage (PV/PVC, StatefulSet), RBAC, and deployment strategies (Rolling, Blue-Green, Canary). Use for Kubernetes operations and manifest authoring.
- 4 stars
- 0 votes
- 0 copies
- 6 views
- Added September 12, 2026
Works with
Security analysis
64/100- Pipes output to a shell interpreter
- Uses curl or wget to download content
- Performs destructive filesystem operations
- Downloads and executes remote scripts — classic supply chain attack
Pro scans all 2 files and shows the line behind each finding
npx -y skills add aibot88/sec_skill_store --skill k8s-workflow --agent claude-codeAre you the author of K8s Workflow?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/aibot88-k8s-workflow)---
name: k8s-workflow
description: >-
Kubernetes core workflow rules, manifest conventions, security best practices,
and version considerations. Includes managed K8s providers (EKS, AKS, GKE),
autoscaling (KEDA, Knative, event-driven scaling), networking (Ingress,
Gateway API, NetworkPolicy, Service Mesh), storage (PV/PVC, StatefulSet),
RBAC, and deployment strategies (Rolling, Blue-Green, Canary).
Use for Kubernetes operations and manifest authoring.
license: MIT
metadata:
author: iceflower
version: "1.1"
last-reviewed: "2026-04"
compatibility: Requires kubectl and Kubernetes cluster access
---
# Kubernetes Workflow Rules
## 1. Resource Naming
### Conventions
| Element | Convention | Example |
| --- | --- | --- |
| Namespace | lowercase kebab | `myapp-prod`, `myapp-dev` |
| Deployment | `{app}-{component}` | `myapp-api`, `myapp-worker` |
| Service | Same as Deployment | `myapp-api` |
| ConfigMap | `{app}-{purpose}-config` | `myapp-api-app-config` |
| Secret | `{app}-{purpose}-secret` | `myapp-api-db-secret` |
| Ingress | `{app}-ingress` | `myapp-api-ingress` |
| CronJob | `{app}-{action}` | `myapp-cleanup-logs` |
---
## 2. Labels and Annotations
### Required Labels
```yaml
metadata:
labels:
app.kubernetes.io/name: myapp-api
app.kubernetes.io/component: backend
app.kubernetes.io/part-of: myapp
app.kubernetes.io/managed-by: kubectl
app.kubernetes.io/version: "1.2.0"
environment: production
```
### Label Usage
| Label | Purpose |
| --- | --- |
| `app.kubernetes.io/name` | Application name (used in selectors) |
| `app.kubernetes.io/component` | Component role (backend, frontend, worker, db) |
| `app.kubernetes.io/part-of` | Parent application group |
| `environment` | Deployment environment (dev, staging, production) |
---
## 3. Resource Limits
### Always Set requests and limits
```yaml
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
```
### Sizing Guidelines
| Workload Type | CPU Request | CPU Limit | Memory Request | Memory Limit |
| --- | --- | --- | --- | --- |
| API server | 100m–500m | 500m–2000m | 256Mi–512Mi | 512Mi–1Gi |
| Background worker | 50m–200m | 200m–1000m | 128Mi–256Mi | 256Mi–512Mi |
| CronJob | 50m–100m | 200m–500m | 128Mi–256Mi | 256Mi–512Mi |
- Set `requests` based on steady-state usage
- Set `limits` at 2–4x requests for burst capacity
- Always set memory limits to prevent OOM kills affecting other pods
---
## 4. Environment-Specific Management
### Directory Structure (Kustomize)
```text
k8s/
├── base/ # Common manifests
│ ├── deployment.yaml
│ ├── service.yaml
│ └── kustomization.yaml
├── overlays/
│ ├── dev/
│ │ ├── kustomization.yaml
│ │ └── patches/
│ ├── staging/
│ │ ├── kustomization.yaml
│ │ └── patches/
│ └── prod/
│ ├── kustomization.yaml
│ └── patches/
```
### Environment Differences
| Config | Dev | Staging | Prod |
| --- | --- | --- | --- |
| Replicas | 1 | 2 | 3+ |
| Resource limits | Low | Medium | Full |
| Log level | DEBUG | INFO | INFO |
| Ingress TLS | Optional | Yes | Yes |
### 4.1 Kustomize base/overlays 패턴
**base 디렉토리에 공통 리소스, overlays/{env}에 환경별 patch 작성.**
- `kustomization.yaml`의 `namespace:` 필드로 대상 네임스페이스 지정
- `images:` 필드로 컨테이너 이미지 태그 교체 (newTag, newName, digest 지원)
- YAML 예제 작성 시 필드 순서는 의도적으로 재배열 — 원본 순서와 다르게 구성할 것
**base/kustomization.yaml 예제:**
```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
images:
- name: order-service
newTag: "1.4.2"
namespace: ecommerce
```
**overlays/prod/kustomization.yaml 예제:**
```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
namespace: ecommerce-prod
images:
- name: order-service
newName: ghcr.io/myorg/order-service
newTag: "1.4.2"
patches:
- path: patches/replica-scale.yaml
- path: patches/resource-limits.yaml
```
### 4.2 patches를 통한 임의 필드 업데이트
**strategic merge patch와 JSON patch 두 가지 방식 중 선택.**
**strategic merge patch (전체 YAML 조각으로 교체):**
```yaml
# patches/replica-scale.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service
spec:
replicas: 5
```
**JSON patch (op/path/value 형식):**
```yaml
# patches/add-annotation.yaml
- op: add
path: /metadata/annotations/service.beta.kubernetes.io~1aws-load-balancer-type
value: nlb
```
**적용 대상 필드 예시:**
| 변경 항목 | patch 유형 | 예시 |
| --- | --- | --- |
| replicas 조정 | strategic merge | `spec.replicas: 3` |
| labels 추가 | strategic merge | `metadata.labels.team: backend` |
| annotations 추가 | JSON patch 또는 strategic merge | `metadata.annotations` |
| env 변수 주입 | strategic merge | `spec.template.spec.containers[0].env` |
### 4.3 namePrefix / nameSuffix
**리소스 이름에 환경별 접두사/접미사 자동 부여. cross-reference(selector, volume, secretKeyRef 등)는 Kustomize가 자동 업데이트.**
```yaml
# overlays/staging/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
namePrefix: staging-
# 결과: order-service → staging-order-service
# Service selector, Deployment volume 참조 모두 자동 갱신
```
```yaml
# overlays/prod/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
nameSuffix: -prod
# 결과: order-service → order-service-prod
```
**namePrefix/nameSuffix 규칙:**
- 환경 분리가 명확해야 할 때 namePrefix 권장 (예: `dev-`, `staging-`, `prod-`)
- 다중 클러스터에서 동일 환경 운영 시 nameSuffix 권장 (예: `-eu`, `-ap`)
- cross-reference 자동 업데이트 대상: `selector.matchLabels`, `volume.secretName`, `configMapKeyRef.name`
### 4.4 configMapGenerator
**ConfigMap 생성 시 literals, files, envs 세 가지 소스 유형 지원. 생성된 ConfigMap 이름에 해시가 자동 추가되어 ConfigMap 변경 시 Deployment 롤링 업데이트가 자동 트리거됨.**
```yaml
# base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
configMapGenerator:
- name: order-service-config
literals:
- LOG_LEVEL=info
- MAX_CONNECTIONS=100
files:
- application.properties
envs:
- order-service.env
# 기존 ConfigMap에 병합
- name: existing-config
behavior: merge
literals:
- NEW_KEY=new-value
# 기존 ConfigMap 완전 교체
- name: legacy-config
behavior: replace
literals:
- REPLACED=true
```
**configMapGenerator 규칙:**
- `behavior` 미지정 시 기본 생성 (동일 이름 존재 시 에러)
- `behavior: merge` — 기존 ConfigMap에 키 추가/업데이트
- `behavior: replace` — 기존 ConfigMap 전체 교체
- Deployment에서 `configMapKeyRef` 또는 `configMapRef`로 참조 시, 해시 포함된 이름이 **자동 업데이트**되므로 수동 수정 불필요
- ConfigMap 내용 변경 → 해시 변경 → pod template hash 변경 → 자동 롤링 업데이트
---
## 5. Security Best Practices
### Pod Security
```yaml
securityContext:
runAsNonRoot: true
runAsUser: 1000
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
```
### Secrets Management
- Never store plaintext secrets in manifests
- Use `SealedSecret`, `ExternalSecret`, or cloud provider secret manager
- Reference secrets via `secretKeyRef`, not environment variable literals
- Rotate secrets regularly without pod restart (use volume mounts for auto-reload)
---
## 6. Health Checks
### Always Define Probes
```yaml
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
failureThreshold: 3
startupProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
failureThreshold: 30
```
### Probe Guidelines
| Probe | Purpose | Failure Action |
| --- | --- | --- |
| Startup | App initialization complete | Kill and restart pod |
| Liveness | App still running | Kill and restart pod |
| Readiness | App ready for traffic | Remove from Service endpoints |
---
## 7. Version Support (2026-03-14)
### Kubernetes Release Cadence
Kubernetes releases a new minor version approximately every 4 months.
### Current Versions
| Version | Status | Latest Patch | End of Support |
| --- | --- | --- | --- |
| 1.35 | Supported | 1.35.2 | Dec 2026 |
| 1.34 | Supported | 1.34.5 | Feb 2027 |
| 1.33 | Supported | 1.33.9 | Jun 2026 |
| 1.32 | EOL | 1.32.13 | Feb 2026 |
| 1.31 | EOL | 1.31.14 | Dec 2025 |
### Key Features in Recent Versions
#### Kubernetes 1.35 (Dec 2025)
- **In-Place Pod Resize (GA)**: CPU/memory adjustments without pod restart
- **PreferSameNode Traffic Distribution**: Local endpoint priority for reduced latency
- **Image Volumes**: Deliver data artifacts using OCI container images
#### Kubernetes 1.34 (Aug 2025)
- **Finer-grained Authorization**: Field/label selector-based decisions
- **Anonymous Request Restrictions**: Limit unauthenticated access to specific endpoints
- **Ordered Namespace Deletion**: Structured deletion order for security
#### Kubernetes 1.33 (Apr 2025)
- **Sidecar Containers (GA)**: Native sidecar lifecycle management
- **Recursive Read-Only Mounts (GA)**: Full read-only volume mounts
- **Bound ServiceAccount Token Improvements**: Unique token IDs, node binding
### Upgrade Planning
1. **Review deprecation notices** before each minor version upgrade
2. **Test in non-production** environments first
3. **Check API compatibility** using `kubectl deprecations` or `pluto`
4. **Update CRDs and webhooks** before control plane upgrade
5. **Node pools**: Drain and upgrade incrementally
---
## 8. Managed Kubernetes Services
For provider-specific managed Kubernetes services, see dedicated skills:
- **AWS EKS**: EKS section in `k8s-providers` rules
- **Azure AKS**: AKS section in `k8s-providers` rules
- **GCP GKE**: GKE section in `k8s-providers` rules
### Quick Comparison
| Feature | EKS | AKS | GKE |
| --- | --- | --- | --- |
| Latest K8s | 1.35 | 1.34 | 1.35 |
| Control Plane | Free | Free | Free |
| Node Autoscaling | Karpenter/MNG | Cluster Autoscaler | GKE Autopilot |
| Service Mesh | App Mesh (deprecated) | Istio (add-on) | Anthos Service Mesh |
| Secrets | AWS Secrets Manager | Azure Key Vault | Secret Manager |
---
## 9. Anti-Patterns
- Using `latest` tag for container images — always pin to specific version
- Defining resources without `requests`/`limits`
- Running containers as root
- Hardcoding config values in manifests — use ConfigMap/Secret
- Single replica for production workloads
- Missing health check probes
- Using `NodePort` in production — use `ClusterIP` + Ingress
- Ignoring deprecation warnings before upgrades
- Not testing upgrades in non-production first
## Related Skills
- For GitOps deployment with Argo CD, see [gitops-argocd](../gitops-argocd/) skill
- For Helm chart management, see [helm-workflow](../helm-workflow/) skill
- For Karpenter node provisioning, see [karpenter-workflow](../karpenter-workflow/) skill
---
## 10. k3s (Lightweight Kubernetes)
### When to Use k3s
- Edge computing, IoT, home lab, or resource-constrained environments
- Raspberry Pi clusters (ARM64)
- CI/CD ephemeral clusters
- Development environments where full k8s overhead is unnecessary
### k3s vs Full Kubernetes
| Feature | k3s | Full Kubernetes |
|---------|-----|-----------------|
| Control plane | Single binary (~100MB) | Multiple components |
| Datastore | SQLite (default), etcd, external | etcd required |
| Resource usage | ~500MB RAM | ~1-2GB RAM |
| ARM64 support | First-class, native | Supported, more setup |
| Built-in addons | CoreDNS, ServiceLB, local-path-provisioner | All external |
### Install k3s Server
```bash
# Standard install (Traefik + ServiceLB enabled)
curl -sfL https://get.k3s.io | sh -
# Disable Traefik (to use Envoy Gateway instead)
curl -sfL https://get.k3s.io | sh -s - server --disable traefik
# Pin specific version
curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION=v1.31.6+k3s1 sh -s - server --disable traefik
```
> **Important**: Do NOT use `--disable servicelb` if you plan to use Gateway API with Envoy Gateway. ServiceLB provides LoadBalancer IPs for Gateway resources.
### Install k3s Agent
```bash
# Get token from server
sudo cat /var/lib/rancher/k3s/server/node-token
# On agent node
curl -sfL https://get.k3s.io | \
K3S_URL=https://<server-ip>:6443 \
K3S_TOKEN=<node-token> \
sh -
```
### k3s-Specific Gotchas
#### Metrics Server Requires `--kubelet-insecure-tls`
k3s uses self-signed kubelet certificates. The standard Metrics Server manifest will fail with TLS errors:
```bash
# After installing Metrics Server, patch the deployment:
kubectl patch deployment metrics-server -n kube-system --type='json' \
-p='[{"op":"add","path":"/spec/template/spec/containers/0/args/-","value":"--kubelet-insecure-tls"}]'
```
#### Helm is Not Pre-installed
k3s does not include Helm by default. Install the release binary directly:
```bash
HELM_VERSION="v3.20.2"
curl -fsSL https://get.helm.sh/helm-${HELM_VERSION}-linux-arm64.tar.gz -o /tmp/helm.tar.gz
tar -zxvf /tmp/helm.tar.gz -C /tmp linux-arm64/helm
sudo mv /tmp/linux-arm64/helm /usr/local/bin/helm
rm -rf /tmp/linux-arm64 /tmp/helm.tar.gz
```
For other architectures, replace `linux-arm64` with `linux-amd64`, `linux-386`, or `linux-ppc64le`.
#### Container Images on ARM64
Not all container images support `arm64`. Verify before deploying:
```yaml
# NOT arm64 compatible (will fail with "exec format error")
image: kennethreitz/httpbin
# ARM64 compatible alternative
image: docker.io/kong/httpbin:latest
```
Use `docker manifest inspect <image>` to verify multi-arch support.
### Reinstalling k3s Server (Preserving State)
To change server flags (e.g., add `--disable servicelb` back):
```bash
# Stop k3s
sudo systemctl stop k3s
# Reinstall with new flags (existing SQLite DB and workloads are preserved)
curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION=v1.31.6+k3s1 sh -s - server --disable traefik
# Restart
sudo systemctl restart k3s
```
---
## 11. Gateway API
### Overview
Gateway API is the next-generation Kubernetes API for traffic management, replacing Ingress. It provides richer routing, multi-tenancy, and role separation.
| Resource | Purpose |
|----------|---------|
| `GatewayClass` | Defines the controller (e.g., Envoy Gateway, Istio) |
| `Gateway` | Configures listeners (ports, protocols, TLS) |
| `HTTPRoute` | HTTP routing rules to backend services |
| `GRPCRoute` | gRPC routing rules |
| `TLSRoute` | TCP/TLS routing rules |
| `ReferenceGrant` | Cross-namespace route attachments |
### Install Gateway API CRDs
```bash
# Standard channel (stable, recommended)
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.1/standard-install.yaml
# Experimental channel (includes additional features)
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.1/experimental-install.yaml
```
### Install Envoy Gateway
Envoy Gateway is the CNCF reference implementation for Gateway API.
```bash
# 1. Download install YAML
# Check latest release: https://github.com/envoyproxy/gateway/releases
curl -sfL https://github.com/envoyproxy/gateway/releases/download/v1.7.2/install.yaml > /tmp/install.yaml
# 2. Install without CRDs (CRDs are installed separately above)
# Note: install.yaml CRDs have annotations exceeding kubectl's 262144-byte limit
# Option A: Requires python3-yaml (sudo apt install python3-yaml)
python3 -c "
import yaml, sys
with open('/tmp/install.yaml') as f:
docs = list(yaml.safe_load_all(f))
for doc in docs:
if doc and doc.get('kind') == 'CustomResourceDefinition':
continue
print('---')
yaml.safe_dump(doc, sys.stdout, default_flow_style=False)
" | kubectl apply -f -
# Option B: No dependencies required (awk-based)
# awk '/^---$/{p=1;next} /^kind: CustomResourceDefinition$/{p=0} p' /tmp/install.yaml | kubectl apply -f -
# 3. Create GatewayClass
kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: envoy-gateway-class
spec:
controllerName: gateway.envoyproxy.io/gatewayclass-controller
EOF
```
### Gateway API + LoadBalancer
Gateway resources of type `LoadBalancer` require a LoadBalancer controller:
| Environment | Controller |
|-------------|------------|
| k3s | ServiceLB (built-in, keep enabled) |
| Cloud (AWS/GCP/Azure) | Cloud provider controller |
| Bare metal | MetalLB |
> **Warning**: If `--disable servicelb` is used in k3s, Gateway resources will show `AddressNotAssigned` status.
### Verify Gateway API
```bash
# Check GatewayClass
kubectl get gatewayclass
# Check Gateway status
kubectl get gateway -A
kubectl describe gateway <name> -n <namespace>
# Check HTTPRoute attachment
kubectl get httproute -A
# Test connectivity
curl http://<gateway-external-ip>/headers
```
### Gateway API Quick Start
```yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: my-gateway
spec:
gatewayClassName: envoy-gateway-class
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: Same
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: my-route
spec:
parentRefs:
- name: my-gateway
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: my-service
port: 8080
```
---
## Additional References
- For managed Kubernetes providers (EKS, AKS, GKE), see [references/providers.md](references/providers.md)
- For autoscaling (KEDA, Knative, event-driven), see [references/autoscaling.md](references/autoscaling.md)
- For networking (Ingress, Gateway API, Network Policies, Service Mesh), see [references/networking.md](references/networking.md)
- For storage, RBAC, and deployment strategies, see [references/storage-and-rbac.md](references/storage-and-rbac.md)
- For Kustomize patterns (Helm comparison, overlays, generators, patches), see [references/kustomize.md](references/kustomize.md)
Files in this skill
- SKILL.md
- source.json
Attribution
Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.