Jenkins Interview Questions

Docker and Kubernetes Build Agents

questions
Scroll to track progress

You're running Jenkins with Kubernetes plugin. Builds are slow because agents take 2-3 minutes to spawn. Developers complain about queue delays. Investigation reveals that each pod pulls a 4GB Docker image. Design a solution to reduce agent startup time.

Multi-prong approach: (1) Use image caching: set `imagePullPolicy: IfNotPresent` in Jenkins K8s config, enable local image caching on nodes. (2) Pre-stage images: use DaemonSet to pre-pull common images on all nodes. (3) Reduce image size: use slim/alpine base images, multi-stage Docker builds, remove build tools from final layer. (4) Use pod templates with init containers that cache layers. (5) Pod warm-up: keep agents in "warm pool" state via kubelet node-local-cache. (6) Split agent types: dedicated node pools for build/test/deploy to co-locate images. (7) Use image registry with local mirror: private Docker registry on cluster to reduce external pulls. (8) Enable aggressive image compression: use image registry v2 with delta sync. Target: sub-30-second startup. Benchmark before/after via Jenkins metrics API.

Follow-up: A developer's build requires a custom image that's 10GB. How do you handle this without bloating your cluster?

Jenkins Kubernetes plugin is running on your cluster. During a traffic spike, agents spawn uncontrollably, consuming all cluster resources and causing evictions. Other workloads are affected. How do you prevent resource exhaustion?

Implement resource limits at multiple levels: (1) Jenkins level: set max concurrent builds (Manage Jenkins > Configure System > Executors). (2) Pod-level: define CPU/memory requests and limits in pod templates. Example: `requests: {cpu: "500m", memory: "512Mi"}, limits: {cpu: "2", memory: "2Gi"}`. (3) Namespace-level: create ResourceQuota for total pods/CPU/memory in Jenkins namespace. (4) Kubernetes-level: use PodDisruptionBudget to prevent cascading evictions. (5) Dynamic throttling: use autoscaling with max-pods threshold. (6) Queue management: prioritize builds, reject low-priority jobs when resources constrained. (7) Monitoring: set up alerts for approaching resource limits. (8) Pod Anti-Affinity: spread agents across multiple nodes to avoid single-node overload. Use QoS classes: high-priority builds as Guaranteed, low-priority as BestEffort. Implement admission webhooks to validate pod specs before creation.

Follow-up: How do you balance resource limits with ensuring builds don't get stuck in queue indefinitely?

You're migrating Jenkins agents from Docker Swarm to Kubernetes. Your Swarm setup uses node labels to route jobs (e.g., `label=gpu`, `label=high-memory`). How do you replicate this in K8s?

Kubernetes uses node affinity/taints instead of simple labels. Strategy: (1) Label K8s nodes: `kubectl label nodes node-1 workload=gpu workload=high-memory`. (2) In Jenkins pod template, add nodeSelector: `nodeSelector: { workload: gpu }`. (3) Use node affinity for more complex routing: `nodeAffinity: requiredDuringScheduling: nodeSelectorTerms: [{ matchExpressions: [{ key: "workload", operator: "In", values: ["gpu", "high-memory"] }] }]`. (4) Use taints/tolerations for exclusive node pools: taint nodes `kubectl taint nodes gpu-node workload=gpu:NoSchedule`, add toleration to pod template. (5) In Jenkins, create separate pod templates per workload type (gpu, high-memory, standard). (6) Migrate label-based job routing: map Swarm labels to K8s node selectors in job definitions. (7) Validate: test jobs on K8s cluster to ensure proper node routing. Use node affinity combined with pod topology spread constraints for optimal distribution.

Follow-up: A critical build needs GPU, but all GPU nodes are occupied. How do you handle this without affecting other builds?

Jenkins Kubernetes plugin agents are failing intermittently with "ImagePullBackOff" errors. Investigation shows your image registry is rate-limiting pulls. How do you reduce pull load while maintaining agent responsiveness?

Implement image caching and registry strategies: (1) Use ImagePullBackOff handling: add exponential backoff retry in pod template spec. (2) Set up private Docker registry mirror on cluster using Harbor or Docker Distribution. (3) Pre-pull images on all nodes via DaemonSet: runs on every node, keeps images fresh. (4) Use `imagePullSecrets` with higher rate limits or dedicated service account for Jenkins. (5) Implement image garbage collection: clean unused layers to reduce total registry load. (6) Use image tagging strategy: tag images by date, rotate old images to reduce registry bloat. (7) Compress images further: reduce FROM image size, use alpine/distroless bases. (8) Batch image pulls: if multiple builds need same image, queue them to share pull. (9) Use registry webhook to notify cluster when image updated, trigger pre-pull. (10) Monitor registry latency: alert when pulls exceed threshold. Cache images on local NFS volume, mounted to all nodes for fast access.

Follow-up: Your registry mirror goes down. How do you gracefully handle agent creation failures?

Kubernetes cluster scales down during off-hours, but Jenkins is in the middle of provisioning agents. Pods are terminating prematurely, causing build failures. Design a safe cluster downscaling strategy.

Implement graceful termination: (1) Use PodDisruptionBudget (PDB) to prevent evictions during build: `minAvailable: N` ensures N replicas survive. (2) Set terminationGracePeriodSeconds to 300+ so Jenkins has time to pause/checkpoint builds. (3) In Jenkins pod spec, add preStop hook: gracefully shut down agent, notify Jenkins, drain queue. (4) Use drain-before-shutdown pattern: when node is marked for removal, mark Jenkins agent as "offline," wait for builds to complete. (5) Cluster autoscaler: don't scale down nodes with running pods (enable skip-nodes-with-local-storage). (6) Schedule downscaling during off-peak: use cluster autoscaling policies to scale only after build queues empty. (7) Implement build affinity: high-priority/long-running builds run on non-expendable nodes. (8) Use node affinity to pin critical workloads. (9) Enable Jenkins metrics to monitor agent count; alert if agents are being killed mid-build. Set scale-down delay to 10+ minutes to allow builds to complete. Use Spot instances for non-critical builds, reserved nodes for critical paths.

Follow-up: A 2-hour load test is running when autoscaling triggers. How do you prevent interruption?

Your Jenkins Kubernetes setup uses Docker-in-Docker (DinD) agents to build container images. Network policies block direct image registry access. Builds fail when pushing images. How do you enable secure image pushes?

DinD requires special handling for network policies: (1) Use unprivileged DinD: specify `securityContext: { privileged: false }` and use `--userns-remap` in Docker daemon. (2) Add network policy rules allowing Jenkins namespace to reach image registry. (3) For image push: use `docker login` with credentials from Jenkins secrets, inject as environment variable. (4) Better: replace DinD with Kaniko (builds without Docker daemon) - runs as non-root, no privileged access, faster: `kaniko -f Dockerfile -c . --destination=myregistry/image:tag`. (5) Use BuildKit for secure image building: expose via socket, not daemon. (6) For private registries: mount secret as volume containing `.docker/config.json`. (7) Set pod securityContext: `runAsNonRoot: true, fsGroup: 65534`. (8) Use egress network policies to allow only specific registries. (9) Implement image signing: push signed images only. (10) Audit image operations: log all registry accesses. Kaniko is recommended for K8s; no container runtime needed, smaller attack surface.

Follow-up: A build pipeline needs to push images to three different registries with different credentials. How do you manage this securely?

You're running Jenkins agents on Kubernetes with persistent volume claims (PVCs) for caching build artifacts. One build generates 500GB of cache, filling the entire storage pool. Other jobs fail due to disk pressure. How do you implement quota enforcement and auto-cleanup?

Implement storage management: (1) Set PVC storage limits: define max size per pod template. (2) Use StorageClass with quotas: enforce namespace-level storage limits via ResourceQuota. (3) Implement cache expiration: run cleanup job that deletes unused caches older than N days. (4) Use ephemeral volumes for builds: set emptyDir with size limit, data is discarded post-build. (5) Implement cache tiering: fast SSD for hot data, slower storage for archives. (6) Quota enforcement: script that monitors PVC usage, alerts at 70%/80%, force-cleanup at 90%. (7) Use Jenkins artifact manager to push old artifacts to S3/GCS instead of local PVC. (8) Implement per-build cache limits: Jenkinsfile contains `cache.maxSize: 50GB` constraint. (9) Garbage collection: post-build cleanup script runs `docker system prune` on agents. (10) Monitor disk usage: Prometheus/Grafana dashboard showing storage trends per namespace. Use DiskPressure eviction thresholds to auto-cleanup before pods evicted.

Follow-up: A critical build needs 200GB cache, but your storage quota is 100GB per namespace. How do you handle this?

You're designing a multi-region Jenkins setup on Kubernetes. Agents are deployed across regions, but build artifact storage is centralized in a single region. Network latency for artifact upload is causing timeouts. Design a geo-distributed artifact strategy.

Implement distributed artifact management: (1) Use S3/GCS with cross-region replication: build completes in US region, artifact replicated to EU/APAC regions. (2) Deploy local artifact caches per region: Nexus/Artifactory proxy in each region, cache artifacts locally. (3) Use CloudFront/CloudFlare CDN for artifact distribution: builds download from nearest edge. (4) Implement async artifact upload: build completes before artifact fully replicated. (5) Use rsync/rclone in background to sync artifacts after build. (6) Store artifacts in region-local object storage, sync metadata to central index. (7) Implement artifact expiration: old artifacts purged from regional caches, fetched on-demand from central. (8) Use multipart uploads with adaptive concurrency: upload faster if latency low, slower if high. (9) Compress artifacts before transfer: gzip reduces size by 70%+ for logs. (10) Monitor artifact upload latency per region; alert if exceeds SLA. Use edge caching for frequently-accessed artifacts to reduce upstream load. Implement parallel uploads to multiple regions for critical builds.

Follow-up: A region's artifact storage becomes unavailable. How do you maintain build continuity?

Want to go deeper?