169 lines
4.9 KiB
Markdown
169 lines
4.9 KiB
Markdown
# Assignment
|
||
|
||
The Nautilus DevOps teams is planning to set up a Grafana tool to collect and analyze analytics from some applications. They are planning to deploy it on Kubernetes cluster. Below you can find more details.
|
||
|
||
|
||
|
||
1.) Create a deployment named grafana-deployment-xfusion using any grafana image for Grafana app. Set other parameters as per your choice.
|
||
|
||
|
||
2.) Create NodePort type service with nodePort 32000 to expose the app.
|
||
|
||
|
||
You do not need to make any configuration changes inside the Grafana app once deployed; just make sure you can access the Grafana login page.
|
||
|
||
|
||
Note: The kubectl utility on the jump-host has been configured to work with the Kubernetes cluster.
|
||
|
||
# Solution
|
||
|
||
# Grafana on Kubernetes — `grafana-deployment-xfusion` + NodePort Service
|
||
|
||
A Grafana Deployment exposed via a NodePort Service on `32000`. Both objects in one
|
||
multi-document heredoc — no manifest file on disk.
|
||
|
||
## Apply (heredoc → kubectl)
|
||
|
||
```bash
|
||
kubectl apply -f - <<'EOF'
|
||
apiVersion: apps/v1
|
||
kind: Deployment
|
||
metadata:
|
||
name: grafana-deployment-datacenter
|
||
labels:
|
||
app: grafana
|
||
spec:
|
||
replicas: 1
|
||
selector:
|
||
matchLabels:
|
||
app: grafana
|
||
template:
|
||
metadata:
|
||
labels:
|
||
app: grafana
|
||
spec:
|
||
containers:
|
||
- name: grafana-container
|
||
image: grafana/grafana:latest
|
||
ports:
|
||
- containerPort: 32000
|
||
---
|
||
apiVersion: v1
|
||
kind: Service
|
||
metadata:
|
||
name: grafana-service
|
||
labels:
|
||
app: grafana
|
||
spec:
|
||
type: NodePort
|
||
selector:
|
||
app: grafana
|
||
ports:
|
||
- port: 32000
|
||
targetPort: 3000
|
||
nodePort: 32000
|
||
EOF
|
||
|
||
kubectl rollout status deployment/kubectl apply -f - <<'EOF'
|
||
apiVersion: apps/v1
|
||
kind: Deployment
|
||
metadata:
|
||
name: grafana-deployment-datacenter
|
||
labels:
|
||
app: grafana
|
||
spec:
|
||
replicas: 1
|
||
selector:
|
||
matchLabels:
|
||
app: grafana
|
||
template:
|
||
metadata:
|
||
labels:
|
||
app: grafana
|
||
spec:
|
||
containers:
|
||
- name: grafana-container
|
||
image: grafana/grafana:latest
|
||
ports:
|
||
- containerPort: 32000
|
||
---
|
||
apiVersion: v1
|
||
kind: Service
|
||
metadata:
|
||
name: grafana-service
|
||
labels:
|
||
app: grafana
|
||
spec:
|
||
type: NodePort
|
||
selector:
|
||
app: grafana
|
||
ports:
|
||
- port: 32000
|
||
targetPort: 3000
|
||
nodePort: 32000
|
||
EOF
|
||
|
||
kubectl rollout status deployment grafana-deployment-datacenter
|
||
|
||
```
|
||
|
||
## How it works
|
||
|
||
### The heredoc apply pattern
|
||
|
||
- **`kubectl apply -f -`** reads from **stdin**; `---` separates the two documents.
|
||
- **`<<'EOF'` (delimiter quoted)** keeps the manifest literal — the right default for k8s YAML.
|
||
|
||
### The Deployment
|
||
|
||
- **`name: grafana-deployment-xfusion`, `labels.app: grafana`** — the required name plus a label
|
||
used to tie the Service to the pods.
|
||
- **`image: grafana/grafana:latest`** — the official Grafana image. The task allows any Grafana
|
||
image; the official `grafana/grafana` is the standard pick.
|
||
- **`containerPort: 3000`** — Grafana's web UI listens on **3000** inside the container. This is
|
||
the detail that everything else keys off.
|
||
- **`replicas: 1`** and container name `grafana-container` — free-choice parameters, kept minimal.
|
||
- **`selector.matchLabels: app: grafana`** equals the template labels — the Deployment↔pod link.
|
||
|
||
### The Service — targetPort 3000 is the crux
|
||
|
||
- **`type: NodePort`** exposes Grafana outside the cluster.
|
||
- **`selector: app: grafana`** targets the deployment's pod by its label.
|
||
- **Port mapping:**
|
||
- `port: 3000` — the Service's ClusterIP port.
|
||
- **`targetPort: 3000`** — the container port. This **must** be 3000 because that's where
|
||
Grafana listens; pointing it elsewhere yields a Service with an endpoint but no response, and
|
||
the login page wouldn't load.
|
||
- `nodePort: 32000` — the external port on each node, exactly as required (in the valid
|
||
`30000–32767` range).
|
||
|
||
Path: `<node-ip>:32000` → Service `:3000` → Grafana pod `:3000`.
|
||
|
||
### Why no in-app config is needed
|
||
|
||
The task only requires reaching the **login page** — Grafana serves its login UI out of the box
|
||
on port 3000 with no configuration. So the whole job is: run the container and route a NodePort to
|
||
3000. Default admin credentials are `admin` / `admin`, but you don't need to log in — just confirm
|
||
the login screen renders.
|
||
|
||
## Verify
|
||
|
||
```bash
|
||
# Pod running
|
||
kubectl get deployment grafana-deployment-xfusion
|
||
kubectl get pods -l app=grafana
|
||
|
||
# Service exposed on 32000 with an endpoint
|
||
kubectl get service grafana-service
|
||
kubectl get endpoints grafana-service
|
||
|
||
# Grafana responding inside the cluster
|
||
kubectl exec deploy/grafana-deployment-xfusion -- \
|
||
sh -c 'wget -qO- http://localhost:3000/login >/dev/null && echo ok' 2>/dev/null || true
|
||
```
|
||
|
||
Expected — deployment `READY 1/1`, `grafana-service` NodePort `3000:32000/TCP` with one endpoint,
|
||
and the Grafana **login page** loading at `<node-ip>:32000` in the browser.
|
||
|
||
> If the page doesn't load, check `targetPort` is `3000` and the pod is Running. Grafana starts
|
||
> reasonably fast, but give it a few seconds after `rollout status` reports ready. |