Homework
Three tasks that extend the lab exercises into production-grade Service patterns.
Complete all three lab exercises before starting the homework. These tasks build on the chart you created during the lab.
Task 1 — Dual-Service Chart: Public + Internal
Objective
Create a chart that deploys two Services for the same application: a public-facing LoadBalancer and an internal ClusterIP for health checks and metrics.
Instructions
- Add a second values block called
internalServiceinvalues.yaml:service: type: LoadBalancer port: 443 targetPort: 8443 externalTrafficPolicy: Local annotations: service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing internalService: enabled: true port: 9090 targetPort: 9090 - Create
templates/internal-service.yamlthat renders a ClusterIP Service only wheninternalService.enabledis true - The internal Service must use the same selector labels as the primary Service
- Name the internal Service with a
-internalsuffix - Verify with
helm templatethat both Services render correctly - Install the chart and confirm both Services appear in
kubectl get svc - Verify that a test Pod can reach both endpoints
Deliverable
The complete templates/internal-service.yaml and updated values.yaml. Output of helm template showing both Services.
✓ Self-check: Two Services appear. The public Service has type LoadBalancer. The internal Service has type ClusterIP. Setting internalService.enabled=false removes the internal Service entirely.
Task 2 — ExternalName Service for an External Database
Objective
Add a templated ExternalName Service so applications can reference an external database by a stable in-cluster DNS name.
Instructions
- Add the following to
values.yaml:externalDB: enabled: false name: app-database host: prod-db.c9abcdef.us-east-1.rds.amazonaws.com - Create
templates/external-db-service.yaml:- Kind: Service with
type: ExternalName externalNameset from.Values.externalDB.host- No selector, no ports
- Only renders when
externalDB.enabledis true
- Kind: Service with
- Verify the template renders correctly:
helm template . --set externalDB.enabled=true | grep -A 10 "external" - Install and verify DNS resolution:
kubectl run dns-test --image=busybox:1.36 --rm -it --restart=Never -- \ nslookup app-database.default.svc.cluster.local - The DNS lookup should return a CNAME pointing to the RDS hostname
Deliverable
The complete templates/external-db-service.yaml template and updated values.yaml. Output of the DNS lookup confirming the CNAME.
✓ Self-check: The ExternalName Service renders only when enabled. nslookup returns the CNAME record. No selector or ports appear in the rendered YAML.
Task 3 — Conditional Headless Service Toggle
Objective
Refactor the headless Service template so it can optionally replace the primary Service (not just supplement it) and expose configurable multi-port definitions.
Instructions
- Update
values.yaml:headless: enabled: false standalone: false # if true, skip the primary Service ports: - name: gossip port: 7946 targetPort: 7946 - name: client port: 9042 targetPort: 9042 - Update
templates/service.yamlto skip rendering whenheadless.standaloneis true:{{- if not (and .Values.headless.enabled .Values.headless.standalone) }} - Update
templates/headless-service.yamlto iterate over.Values.headless.portsinstead of using the primary Service ports - Verify all four scenarios with
helm template:headless.enabled=false— only primary Service rendersheadless.enabled=true, standalone=false— both Services renderheadless.enabled=true, standalone=true— only headless Service renders- Headless Service ports use the
headless.portsarray, not the primaryservice.ports
Deliverable
Updated templates/service.yaml, templates/headless-service.yaml, and values.yaml. Output of helm template for all four scenarios.
✓ Self-check: Each scenario produces the correct combination of Services. The headless Service ports match the headless.ports values. No rendering errors occur in any scenario.
Grading Rubric
| Criterion | Points | Description |
|---|---|---|
| Task 1: Dual-Service | 35 | Both Services render with correct types, selectors, and conditional logic |
| Task 2: ExternalName | 25 | ExternalName Service renders correctly, DNS resolves the CNAME, conditional toggle works |
| Task 3: Headless toggle | 30 | All four scenarios produce correct output, ports are independently configurable |
| Code quality | 10 | Consistent naming, proper use of helpers, clean YAML output with no extra whitespace |
Submission Checklist
- ✓ Task 1:
internal-service.yamltemplate and dual-Servicehelm templateoutput - ✓ Task 2:
external-db-service.yamltemplate and DNS lookup proof - ✓ Task 3: Updated headless template with standalone mode and four-scenario verification
- ✓ All templates pass
helm lintwithout warnings