Deploying the first image
This guide will walk you through the process of rolling out your first application in your cluster – from deployment and release right through to testing.
Prerequisites
- A cluster with the status Running
- A downloaded configuration file and a verified connection; see Connecting to the cluster
kubectlinstalled
First, check that the connection is working:
kubectl get nodes
All nodes should have the status Ready.
1. Create a deployment
A deployment specifies which image is to run in how many instances. Create the file deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
labels:
app: web
spec:
replicas: 2
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginx:stable
ports:
- containerPort: 80
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 10
Key information:
replicas– Number of instances. Two replicas ensure that the application remains accessible during upgrades.resources.requests– Resources reserved by the scheduler for placement.resources.limits– Upper limit that a container must not exceed.readinessProbe– Ensures that only ready pods receive traffic.
Roll out the deployment:
kubectl apply -f deployment.yaml
2. Check the rollout
# Status des Rollouts
kubectl rollout status deployment web
# Laufende Pods
kubectl get pods -l app=web
Expected output:
NAME READY STATUS RESTARTS AGE
web-6d4cf56db6-8xk2p 1/1 Running 0 30s
web-6d4cf56db6-tz9vn 1/1 Running 0 30s
If a pod gets stuck in Pending or ImagePullBackOff, the following commands will reveal the cause:
kubectl describe pod <pod-name>
kubectl logs <pod-name>
3. Publish the application
A service makes the pods accessible via a fixed address.
Services of type LoadBalancer are currently not available – no Cloud Controller Manager has been set up to assign external addresses. Such a service remains permanently with EXTERNAL-IP: <pending>.
Instead, use NodePort for external access or kubectl port-forward for local testing.
Option A: NodePort for external access
A service of type NodePort opens the same port on every worker node. The application can then be accessed via the IP address of any node.
Create the file service.yaml:
apiVersion: v1
kind: Service
metadata:
name: web
spec:
type: NodePort
selector:
app: web
ports:
- port: 80
targetPort: 80
nodePort: 30080
protocol: TCP
How to use:
kubectl apply -f service.yaml
The selected port must be within the range 30000–32767. If nodePort is not specified, Kubernetes automatically assigns a free port from this range.
Check the service and the assigned port:
kubectl get service web
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
web NodePort 10.43.12.180 <none> 80:30080/TCP 10s
You will then need the IP address of a node:
kubectl get nodes -o wide
Access the application via its Node IP and port:
curl http://<node-ip>:30080
The node IP addresses are within the VPC network. The application is therefore only accessible from the internet if the node has a public address and the port is open in the firewall.
As each node opens the same port, if a node fails, its address is no longer available – without an upstream load balancer, you will need to take this into account in your client configuration or in the DNS.
Option B: Port forwarding for local testing
For a quick test, local port forwarding is sufficient. The service can be of type ClusterIP (the default if type is not specified):
kubectl port-forward service/web 8080:80
The application can then be accessed via http://localhost:8080. The redirection remains in place for as long as the command is running.
4. Scaling the application
kubectl scale deployment web --replicas=4
To ensure that the replicas are distributed across different nodes, add topologySpreadConstraints – see High Availability.
5. Tidying up
To remove test resources that are no longer required, use:
kubectl delete -f service.yaml
kubectl delete -f deployment.yaml
A NodePort occupies the selected port on all worker nodes. Delete any services that are no longer required so that the ports are freed up for other applications.
Next steps
- Install Ingress Controller – for running multiple HTTP services behind a single address
- Enable HTTPS – for encrypted connections
- Storage Features – storage options and stateful applications
- Horizontal Pod Autoscaling – for load-based scaling