Deployment
A Deployment manages a set of Pods to run an application workload, usually one that doesn't maintain state.
Create Simple App
First lets create a simple golang apps by following these steps below:
- Create new folder called
simple-go
. - Init Go Module using
go mod init
. - Create new sub folder called
cmd
. - Create
main.go
file. - Your folder structure should look like this:
simple-go
├── go.mod
└── main.go
- Then lets create a simple http server where it will return json response like
{"message":"success"}
. - You can copy paste the following code:
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
)
type Response struct {
Message string `json:"message"`
}
func main() {
srv := http.NewServeMux()
srv.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
res := Response{
Message: "Success",
}
err := json.NewEncoder(w).Encode(res)
if err != nil {
log.Fatal(err)
}
})
fmt.Println("Server is running on port 8080...")
err := http.ListenAndServe(":8080", srv)
if err != nil {
log.Fatal(err)
}
}
- Let's try to run the code by using command
go run main.go
. - You should see this output in your terminal:
Server is running on port 8080...
- Let's try to access is using
curl
to your localhost port8080
and it should return with response like this:
➜ curl http://127.0.0.1:8080
{"message":"Success"}
Build Docker Image
With the simple app running well the next step is to build a docker image for our app we previously built. Create a file called Dockerfile
in the root folder and for now you can copy paste the configuration below:
# Builder stage
FROM golang:1.22 AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o server .
# Runtime image stage
FROM alpine:latest
WORKDIR /app
COPY /app/server .
CMD [ "./server" ]
To build the image so it will available in Minikube we need these following steps.
- First is to Switch to Minikube's Docker Daemon using command
eval $(minikube docker-env)
. - Then we can build our docker image with tag
simple-go
like this:
docker build --tag simple-go .
- We can check using command
docker images
and the imagesimple-go
should be in the list:
➜ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
simple-go latest d47dfe963439 12 minutes ago 15.1MB
registry.k8s.io/kube-apiserver v1.31.0 cd0f0ae0ec9e 5 months ago 91.5MB
registry.k8s.io/kube-scheduler v1.31.0 fbbbd428abb4 5 months ago 66MB
registry.k8s.io/kube-controller-manager v1.31.0 fcb0683e6bdb 5 months ago 85.9MB
registry.k8s.io/kube-proxy v1.31.0 71d55d66fd4e 5 months ago 94.7MB
registry.k8s.io/etcd 3.5.15-0 27e3830e1402 6 months ago 139MB
registry.k8s.io/pause 3.10 afb61768ce38 8 months ago 514kB
registry.k8s.io/coredns/coredns v1.11.1 2437cf762177 17 months ago 57.4MB
kubernetesui/dashboard <none> 20b332c9a70d 2 years ago 244MB
kubernetesui/metrics-scraper <none> a422e0e98235 2 years ago 42.3MB
gcr.io/k8s-minikube/storage-provisioner v5 ba04bb24b957 3 years ago 29MB
Create Deployment
With our image ready in Minikube docker daemon we then can proceed creating kubernetes deployment config. Lets name it deployment.yaml
and you can copy paste the config below and break it down section by section so we know what it means.
apiVersion: apps/v1
kind: Deployment
metadata:
name: simple-go
labels:
app: simple-go
spec:
replicas: 3
selector:
matchLabels:
app: simple-go
template:
metadata:
labels:
app: simple-go
spec:
containers:
- name: server
image: simple-go:latest
imagePullPolicy: Never
ports:
- containerPort: 8080
General Structure
apiVersion: apps/v1
kind: Deployment
apiVersion: apps/v1
: Specifies the API version of the Deployment resource.apps/v1
is the most commonly used API version for Deployments in Kubernetes.kind: Deployment
: Defines the type of Kubernetes resource being created. Here, it’s a Deployment.
Metadata Section
metadata:
name: simple-go
labels:
app: simple-go
metadata:
: Contains metadata about the resource.name: simple-go
: The name of the Deployment. This must be unique within the namespace.labels:
: Key-value pairs used to tag the Deployment. These labels are useful for identifying and grouping resources.app: simple-go
: A label indicating this Deployment is related to thesimple-go
app.
Spec Section
spec:
replicas: 3
selector:
matchLabels:
app: simple-go
spec:
: Defines the desired state for the Deployment.replicas: 2
: Specifies the number of Pod replicas to maintain. Kubernetes will ensure three Pods are running at all times.selector:
: Defines how Kubernetes identifies Pods managed by this Deployment.matchLabels:
: Filters Pods by matching their labels.app: simple-go
: This matches Pods that have the labelapp: simple-go
.
Template Section
template:
metadata:
labels:
app: simple-go
template:
: Describes the Pods that will be created and managed by the Deployment.metadata:
: Metadata specific to the Pods.labels:
: Labels assigned to each Pod created by this Deployment.app: simple-go
: Ensures the Pods have the labelapp: simple-go
, which matches the selector.
Pod Spec Section
spec:
containers:
- name: simple-go
image: go-configurable-port
imagePullPolicy: Never
ports:
- containerPort: 8080
spec:
: Defines the configuration for the Pods.containers:
: Lists the containers to run in each Pod.- name: server
: The name of the container. This is used for identification within the Pod.image: simple-go
: Specifies the container image to use. Kubernetes will look for this image in the container registry or Minikube’s local Docker environment.imagePullPolicy: Never
: Because our minikube is local we need to specify image pull policy toNever
so it will not trying to pull from container registry but use local instead.ports:
: Lists the ports exposed by the container.- containerPort: 8080
: The port number the container listens on. This allows Kubernetes to route traffic to the correct port inside the container.
Apply
Lets apply our deployment configuration using command kubectl apply -f deployment.yaml
.
➜ kubectl apply -f deployment.yaml
deployment.apps/simple-go created
And the we can check our pods using kubectl get pods
. We should have 3
pods running like this.
➜ kubectl get pods
NAME READY STATUS RESTARTS AGE
simple-go-65d7fccbfc-4f7xk 1/1 Running 0 10s
simple-go-65d7fccbfc-bgqlt 1/1 Running 0 10s
simple-go-65d7fccbfc-ltzgv 1/1 Running 0 10s
Accessing the App
We successfully deploy our apps, it's not accessible yet. We will learn how to create a service
to make our app accessible, but for now we can port forward using command kubectl port-forward <pod-name> <source-port>:<target-port>
.
➜ kubectl port-forward simple-go-65d7fccbfc-4f7xk 8080:8080
Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from [::1]:8080 -> 8080
Try again using curl to localhost port 8080
and we should get response like this:
➜ curl http://127.0.0.1:8080
{"message":"Success"}