This is an old revision of the document!
Table of Contents
Kubernetes kind: complete reference
kind tells Kubernetes what type of object to create.
Each kind has its own controller, behavior, and lifecycle.
ConfigMap
Stores non-sensitive configuration data as key-value pairs. Injected into Pods as environment variables or mounted as files.
apiVersion: v1
apiVersion: v1 kind: ConfigMap metadata: name: app-config namespace: default data: APP_ENV: "production" LOG_LEVEL: "info" config.yaml: | timeout: 30 retries: 3 debug: false
Use as env vars:
envFrom: - configMapRef: name: app-config
Use as mounted file:
volumes: - name: config-vol configMap: name: app-config volumeMounts: - name: config-vol mountPath: /etc/config
config.yamlappears as a real file at/etc/config/config.yamlinside the container.
| Field | Purpose |
|---|---|
data | Plain text key-value pairs |
binaryData | Base64-encoded binary data |
Use case: app settings, feature flags, config files, environment differences (dev/staging/prod).
Secret
Stores sensitive data. Values are base64-encoded at rest. Works like ConfigMap but with access restrictions and audit logging.
apiVersion: v1
apiVersion: v1 kind: Secret metadata: name: db-secret namespace: default type: Opaque data: username: YWRtaW4= # echo -n "admin" | base64 password: c2VjcmV0MTIz # echo -n "secret123" | base64
Secret types:
| Type | Use case |
|---|---|
Opaque | General-purpose (default) |
kubernetes.io/tls | TLS certificates (tls.crt + tls.key) |
kubernetes.io/dockerconfigjson | Docker registry credentials |
kubernetes.io/service-account-token | ServiceAccount tokens |
kubernetes.io/basic-auth | Basic username/password |
kubernetes.io/ssh-auth | SSH private key |
TLS Secret example:
apiVersion: v1 kind: Secret metadata: name: tls-secret type: kubernetes.io/tls data: tls.crt: <base64-encoded-cert> tls.key: <base64-encoded-key>
Use in Pod:
env: - name: DB_PASSWORD valueFrom: secretKeyRef: name: db-secret key: password
Use case: passwords, API keys, TLS certs, Docker pull credentials.
<note warning> Base64 is encoding, NOT encryption. Use tools like Sealed Secrets or Vault for real encryption at rest. </note>
Namespace
Logical partition inside a cluster. Isolates resources between teams, environments, or projects.
apiVersion: v1
apiVersion: v1 kind: Namespace metadata: name: team-backend labels: team: backend env: production
Built-in namespaces:
| Namespace | Purpose |
|---|---|
default | Resources with no namespace specified go here |
kube-system | Core Kubernetes components (DNS, scheduler, controller-manager) |
kube-public | Publicly readable data (cluster info) |
kube-node-lease | Node heartbeat lease objects |
Deploy to a namespace:
metadata: name: my-app namespace: team-backend
Namespace-scoped vs cluster-scoped:
| Namespace-scoped | Cluster-scoped |
|---|---|
| Pod, Deployment, Service | Node, PersistentVolume |
| ConfigMap, Secret | ClusterRole, StorageClass |
| Role, RoleBinding | Namespace itself |
Use case: isolate dev/staging/prod, separate teams, apply ResourceQuota per namespace.
Job
Runs a Pod to completion. Guarantees the task finishes successfully. Retries automatically on failure.
apiVersion: batch/v1
apiVersion: batch/v1 kind: Job metadata: name: db-migration spec: completions: 1 # how many successful completions needed parallelism: 1 # how many Pods run at the same time backoffLimit: 4 # retry up to 4 times on failure template: spec: containers: - name: migrate image: myapp:v2 command: ["python", "manage.py", "migrate"] restartPolicy: OnFailure # required: Never or OnFailure
Parallel Job example (process 5 items, 2 at a time):
spec: completions: 5 parallelism: 2
| Field | Purpose |
|---|---|
completions | Total successful Pods needed to finish the Job |
parallelism | Max Pods running simultaneously |
backoffLimit | Max retries before Job is marked failed |
activeDeadlineSeconds | Kill Job if it runs longer than N seconds |
ttlSecondsAfterFinished | Auto-delete Job N seconds after completion |
Use case: database migrations, data imports, report generation, ML training runs, batch processing.
CronJob
Runs a Job on a time-based schedule. Same as Linux cron.
apiVersion: batch/v1
apiVersion: batch/v1 kind: CronJob metadata: name: nightly-backup spec: schedule: "0 2 * * *" # every day at 02:00 timeZone: "Asia/Ho_Chi_Minh" # optional, requires k8s 1.27+ concurrencyPolicy: Forbid # don't run if previous is still running successfulJobsHistoryLimit: 3 failedJobsHistoryLimit: 1 jobTemplate: spec: template: spec: containers: - name: backup image: backup-tool:latest command: ["sh", "-c", "/scripts/backup.sh"] restartPolicy: OnFailure
Cron syntax:
┌───── minute (0-59) │ ┌─── hour (0-23) │ │ ┌─ day of month (1-31) │ │ │ ┌ month (1-12) │ │ │ │ ┌ day of week (0-6, Sun=0) │ │ │ │ │ * * * * * Examples: "0 2 * * *" → every day at 02:00 "*/15 * * * *" → every 15 minutes "0 9 * * 1" → every Monday at 09:00 "0 0 1 * *" → first day of every month at midnight
concurrencyPolicy values:
| Value | Behavior |
|---|---|
Allow | Run overlapping Jobs (default) |
Forbid | Skip new Job if previous still running |
Replace | Cancel previous Job, start new one |
Use case: backups, log rotation, cleanup tasks, scheduled reports, cache warming.
Ingress
HTTP/HTTPS routing rules. Routes external traffic to internal Services based on hostname or URL path. Requires an Ingress Controller (nginx, traefik, etc.) to be installed.
apiVersion: networking.k8s.io/v1
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: main-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: ingressClassName: nginx tls: - hosts: - myapp.example.com secretName: tls-secret # Secret of type kubernetes.io/tls rules: - host: myapp.example.com http: paths: - path: /api pathType: Prefix backend: service: name: api-service port: number: 8080 - path: / pathType: Prefix backend: service: name: frontend-service port: number: 80
pathType values:
| Value | Behavior |
|---|---|
Exact | Match exact path only (e.g. /api only) |
Prefix | Match path and all sub-paths (e.g. /api/v1, /api/v2) |
ImplementationSpecific | Behavior depends on Ingress Controller |
Traffic flow:
Client
└── Ingress Controller (nginx/traefik)
└── Ingress rules
├── /api → api-service → api Pods
└── / → frontend-service → frontend Pods
Use case: expose multiple services under one domain, TLS termination, path-based routing, virtual hosting.
ClusterRole
Defines permissions that apply cluster-wide (all namespaces + cluster-scoped resources). Part of Kubernetes RBAC (Role-Based Access Control).
apiVersion: rbac.authorization.k8s.io/v1
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: pod-reader rules: - apiGroups: [""] # "" = core API group resources: ["pods", "pods/log"] verbs: ["get", "list", "watch"] - apiGroups: ["apps"] resources: ["deployments"] verbs: ["get", "list", "watch", "create", "update", "patch"] - apiGroups: [""] resources: ["nodes"] # cluster-scoped — only ClusterRole can grant this verbs: ["get", "list"]
All available verbs:
| Verb | HTTP method equivalent |
|---|---|
get | GET (single resource) |
list | GET (collection) |
watch | GET with ?watch=true (streaming) |
create | POST |
update | PUT |
patch | PATCH |
delete | DELETE |
deletecollection | DELETE (collection) |
Wildcard (grant all):
rules: - apiGroups: ["*"] resources: ["*"] verbs: ["*"]
ClusterRole vs Role:
| Role | ClusterRole | |
|---|---|---|
| Scope | Single namespace | All namespaces + cluster resources |
| Can access Nodes | No | Yes |
| Can access PersistentVolumes | No | Yes |
| Bound with | RoleBinding | ClusterRoleBinding (or RoleBinding) |
Use case: read-only cluster monitoring, CI/CD pipelines, operators, admin access.
<note>
ClusterRole alone does nothing. It must be bound via ClusterRoleBinding or RoleBinding.
</note>
ClusterRoleBinding
Grants a ClusterRole to a user, group, or ServiceAccount across the entire cluster.
apiVersion: rbac.authorization.k8s.io/v1
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: pod-reader-binding subjects: - kind: ServiceAccount name: monitoring-agent namespace: monitoring - kind: User name: jane@example.com apiGroup: rbac.authorization.k8s.io - kind: Group name: devops-team apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: pod-reader apiGroup: rbac.authorization.k8s.io
subjects kinds:
| Kind | Example |
|---|---|
ServiceAccount | Pod identity inside cluster |
User | Human user (managed externally) |
Group | Group of users |
Use case: grant monitoring agent read access to all Pods cluster-wide.
HorizontalPodAutoscaler
Automatically scales Pod count up or down based on metrics.
Watches a target (Deployment, StatefulSet) and adjusts replicas.
apiVersion: autoscaling/v2
apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: web-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: web-app minReplicas: 2 maxReplicas: 20 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 70 # scale up if avg CPU > 70% - type: Resource resource: name: memory target: type: AverageValue averageValue: 512Mi
Custom metrics example (requests per second):
metrics: - type: Pods pods: metric: name: requests_per_second target: type: AverageValue averageValue: "1000"
Scale behavior (control speed of scaling):
behavior: scaleUp: stabilizationWindowSeconds: 0 # scale up immediately policies: - type: Pods value: 4 periodSeconds: 60 # add max 4 pods per minute scaleDown: stabilizationWindowSeconds: 300 # wait 5 min before scaling down
| Field | Purpose |
|---|---|
minReplicas | Never go below this count |
maxReplicas | Never exceed this count |
averageUtilization | Target CPU/memory percentage across all Pods |
stabilizationWindowSeconds | Cooldown window to prevent flapping |
How it works:
Metrics Server
└── HPA checks metrics every 15s
├── CPU > 70% → scale UP (add Pods)
└── CPU < 70% → scale DOWN (remove Pods)
└── Deployment adjusts replicas
Use case: web traffic spikes, variable batch load, cost optimization (scale down at night).
<note important> HPA requires Metrics Server installed in the cluster. Resource requests must be set on containers for CPU/memory HPA to work. </note>
Quick comparison
| Kind | apiVersion | Scope | Controller |
|---|---|---|---|
ConfigMap | v1 | Namespace | — |
Secret | v1 | Namespace | — |
Namespace | v1 | Cluster | — |
Job | batch/v1 | Namespace | Job Controller |
CronJob | batch/v1 | Namespace | CronJob Controller |
Ingress | networking.k8s.io/v1 | Namespace | Ingress Controller |
ClusterRole | rbac.authorization.k8s.io/v1 | Cluster | — |
ClusterRoleBinding | rbac.authorization.k8s.io/v1 | Cluster | — |
HorizontalPodAutoscaler | autoscaling/v2 | Namespace | HPA Controller |
Key rule
<note important>
Every kind requires a matching apiVersion.
Wrong apiVersion = object creation fails, even if all other fields are correct.
</note>
