Github: https://github.com/blazingraptor/getting-started-k8s.git
Docker Hub: https://hub.docker.com/repository/docker/blazingraptor/getting-started-k8s/general
Clone the repo
blazingraptor@galactica:~/docker/scale-example$ git clone https://github.com/blazingraptor/getting-started-k8s.git Cloning into 'getting-started-k8s'... remote: Enumerating objects: 102, done. remote: Counting objects: 100% (37/37), done. remote: Compressing objects: 100% (27/27), done. remote: Total 102 (delta 16), reused 10 (delta 10), pack-reused 65 (from 1) Receiving objects: 100% (102/102), 71.75 KiB | 1.84 MiB/s, done. Resolving deltas: 100% (33/33), done.
Apply the LoadBalancer
blazingraptor@galactica:~/docker/getting-started-k8s$ cd Services/ blazingraptor@galactica:~/docker/getting-started-k8s/Services$ kubectl apply -f svc-lb.yml service/ps-lb created
Now the LoadBalancer is running
blazingraptor@galactica:~/docker/scale-example/getting-started-k8s/Services$ kubectl get services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 211d ps-lb LoadBalancer 10.107.92.89 localhost 80:31789/TCP 52s
Apply deployment
blazingraptor@galactica:~/docker/scale-example/getting-started-k8s/Deployments$ kubectl apply -f deploy.yml deployment.apps/web-deploy created
See replicas
blazingraptor@galactica:~/docker/scale-example/getting-started-k8s/Deployments$ kubectl get pods NAME READY STATUS RESTARTS AGE web-deploy-55bdf4c5d5-2vt78 1/1 Running 0 20m web-deploy-55bdf4c5d5-k92lh 1/1 Running 0 20m web-deploy-55bdf4c5d5-n5kgp 1/1 Running 0 20m web-deploy-55bdf4c5d5-r7fzx 1/1 Running 0 20m web-deploy-55bdf4c5d5-xxgrk 1/1 Running 0 20m
Deployments are API resources
Inspect them
blazingraptor@galactica:~/docker/scale-example/getting-started-k8s/Deployments$ kubectl get deploy NAME READY UP-TO-DATE AVAILABLE AGE web-deploy 5/5 5 5 39m blazingraptor@galactica:~/docker/scale-example/getting-started-k8s/Deployments$ kubectl get deployments.apps NAME READY UP-TO-DATE AVAILABLE AGE web-deploy 5/5 5 5 39m
Get Replica Sets
blazingraptor@galactica:~/docker/scale-example/getting-started-k8s/Deployments$ kubectl get rs NAME DESIRED CURRENT READY AGE web-deploy-55bdf4c5d5 5 5 5 47m blazingraptor@galactica:~/docker/scale-example/getting-started-k8s/Deployments$ kubectl get replicasets.apps NAME DESIRED CURRENT READY AGE web-deploy-55bdf4c5d5 5 5 5 47m
See the file that set the replica sets
blazingraptor@galactica:~/docker/scale-example/getting-started-k8s/Deployments$ cat deploy.yml;echo
# Simple deployment used to deploy and manage the app in nigelpoulton/getting-started-k8s:1.0
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-deploy
labels:
app: web
spec:
replicas: 5
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
terminationGracePeriodSeconds: 1
containers:
- name: hello-pod
image: nigelpoulton/getting-started-k8s:1.0
imagePullPolicy: Always
ports:
- containerPort: 8080
Hash is based on this
We have 5 pods running. To connect to them, we need a service...
blazingraptor@galactica:~/docker/getting-started-k8s/Deployments$ kubectl get services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 10d ps-lb LoadBalancer 10.99.228.61 localhost 80:31787/TCP 58m ps-nodeport NodePort 10.100.201.228 <none> 80:31111/TCP 40h
It's actually this
blazingraptor@galactica:~/docker/scale-example/getting-started-k8s/Deployments$ kubectl get services | grep ps-lb ps-lb LoadBalancer 10.99.228.61 localhost 80:31789/TCP 58m
Describe it
blazingraptor@galactica:~/docker/getting-started-k8s/Deployments$ kubectl describe services ps-lb Name: ps-lb Namespace: default Labels: <none> Annotations: <none> Selector: app=web Type: LoadBalancer IP Family Policy: SingleStack IP Families: IPv4 IP: 10.99.228.61 IPs: 10.99.228.61 LoadBalancer Ingress: localhost Port: <unset> 80/TCP TargetPort: 8080/TCP NodePort: <unset> 31787/TCP Endpoints: 10.1.0.19:8080,10.1.0.20:8080,10.1.0.21:8080 + 2 more... Session Affinity: None External Traffic Policy: Cluster Events: <none>
blazingraptor@galactica:~/docker/getting-started-k8s/Deployments$ kubectl describe services ps-lb | grep Selector Selector: app=web
* Says send traffic to all pods in the cluster with the "app=web" label
Check label on the 5 replicas we have running
blazingraptor@galactica:~/docker/getting-started-k8s/Deployments$ kubectl get pods --show-labels NAME READY STATUS RESTARTS AGE LABELS web-deploy-55bdf4c5d5-252qn 1/1 Running 0 55m app=web,pod-template-hash=55bdf4c5d5 web-deploy-55bdf4c5d5-czcfc 1/1 Running 0 55m app=web,pod-template-hash=55bdf4c5d5 web-deploy-55bdf4c5d5-hj65t 1/1 Running 0 55m app=web,pod-template-hash=55bdf4c5d5 web-deploy-55bdf4c5d5-pjr6w 1/1 Running 0 55m app=web,pod-template-hash=55bdf4c5d5 web-deploy-55bdf4c5d5-t95hq 1/1 Running 0 55m app=web,pod-template-hash=55bdf4c5d5
Same label here as well
Labels are dynamic
See the endpoints
blazingraptor@galactica:~/docker/getting-started-k8s/Deployments$ kubectl get endpoints ps-lb NAME ENDPOINTS AGE ps-lb 10.1.0.19:8080,10.1.0.20:8080,10.1.0.21:8080 + 2 more... 80m
Describe endpoints
blazingraptor@galactica:~/docker/getting-started-k8s/Deployments$ kubectl describe endpoints ps-lb
Name: ps-lb
Namespace: default
Labels: <none>
Annotations: endpoints.kubernetes.io/last-change-trigger-time: 2024-06-01T18:01:13Z
Subsets:
Addresses: 10.1.0.19,10.1.0.20,10.1.0.21,10.1.0.22,10.1.0.23
NotReadyAddresses: <none>
Ports:
Name Port Protocol
---- ---- --------
<unset> 8080 TCP
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedToUpdateEndpoint 60m endpoint-controller Failed to update endpoint default/ps-lb: Operation cannot be fulfilled on endpoints "ps-lb": the object has been modified; please apply your changes to the latest version and try again
The fix
blazingraptor@galactica:~/docker/getting-started-k8s/Deployments$ kubectl apply -f deploy.yml
deployment.apps/web-deploy unchanged
blazingraptor@galactica:~/docker/getting-started-k8s/Deployments$ kubectl describe endpoints ps-lb
Name: ps-lb
Namespace: default
Labels: <none>
Annotations: endpoints.kubernetes.io/last-change-trigger-time: 2024-06-01T18:01:13Z
Subsets:
Addresses: 10.1.0.19,10.1.0.20,10.1.0.21,10.1.0.22,10.1.0.23
NotReadyAddresses: <none>
Ports:
Name Port Protocol
---- ---- --------
<unset> 8080 TCP
Events: <none>
Get the public IP
blazingraptor@galactica:~/docker/getting-started-k8s/Deployments$ kubectl get services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 10d ps-lb LoadBalancer 10.99.228.61 localhost 80:31787/TCP 92m ps-nodeport NodePort 10.100.201.228 <none> 80:31111/TCP 40h blazingraptor@galactica:~/docker/getting-started-k8s/Deployments$ kubectl get services | grep ps-lb ps-lb LoadBalancer 10.99.228.61 localhost 80:31787/TCP 93m
localhost
Turn off Windows Firewall
I can load
172.16.0.12:31111
from ironman6 in Firefox
That means, I can port forward it to my router and visit it from any computer in the World.
Scale Up
blazingraptor@galactica:~/docker/scale-example/getting-started-k8s/Deployments$ grep replicas deploy.yml replicas: 5 blazingraptor@galactica:~/docker/scale-example/getting-started-k8s/Deployments$ vim deploy.yml blazingraptor@galactica:~/docker/scale-example/getting-started-k8s/Deployments$ grep replicas deploy.yml replicas: 7 blazingraptor@galactica:~/docker/scale-example/getting-started-k8s/Deployments$ kubectl apply -f deploy.yml deployment.apps/web-deploy configured blazingraptor@galactica:~/docker/scale-example/getting-started-k8s/Deployments$ kubectl get pods --show-labels NAME READY STATUS RESTARTS AGE LABELS web-deploy-55bdf4c5d5-2vt78 1/1 Running 0 6d2h app=web,pod-template-hash=55bdf4c5d5 web-deploy-55bdf4c5d5-6s57x 1/1 Running 0 7s app=web,pod-template-hash=55bdf4c5d5 web-deploy-55bdf4c5d5-k92lh 1/1 Running 0 6d2h app=web,pod-template-hash=55bdf4c5d5 web-deploy-55bdf4c5d5-n5kgp 1/1 Running 0 6d2h app=web,pod-template-hash=55bdf4c5d5 web-deploy-55bdf4c5d5-r7fzx 1/1 Running 0 6d2h app=web,pod-template-hash=55bdf4c5d5 web-deploy-55bdf4c5d5-sjvxr 1/1 Running 0 7s app=web,pod-template-hash=55bdf4c5d5 web-deploy-55bdf4c5d5-xxgrk 1/1 Running 0 6d2h app=web,pod-template-hash=55bdf4c5d5
Scale Down
blazingraptor@galactica:~/docker/scale-example/getting-started-k8s/Deployments$ grep replicas deploy.yml replicas: 7 blazingraptor@galactica:~/docker/scale-example/getting-started-k8s/Deployments$ vim deploy.yml blazingraptor@galactica:~/docker/scale-example/getting-started-k8s/Deployments$ grep replicas deploy.yml replicas: 4 blazingraptor@galactica:~/docker/scale-example/getting-started-k8s/Deployments$ kubectl apply -f deploy.yml deployment.apps/web-deploy configured blazingraptor@galactica:~/docker/scale-example/getting-started-k8s/Deployments$ kubectl get pods --show-labels NAME READY STATUS RESTARTS AGE LABELS web-deploy-55bdf4c5d5-2vt78 1/1 Running 0 6d2h app=web,pod-template-hash=55bdf4c5d5 web-deploy-55bdf4c5d5-k92lh 1/1 Running 0 6d2h app=web,pod-template-hash=55bdf4c5d5 web-deploy-55bdf4c5d5-n5kgp 1/1 Running 0 6d2h app=web,pod-template-hash=55bdf4c5d5 web-deploy-55bdf4c5d5-r7fzx 1/1 Running 0 6d2h app=web,pod-template-hash=55bdf4c5d5
Retag it
blazingraptor@galactica:~/docker/scale-example/getting-started-k8s/Deployments$ docker tag nigelpoulton/getting-started-k8s:1.0 blazingraptor/getting-started-k8s:1.0
See the image
blazingraptor@galactica:~$ docker images | grep blazingraptor | grep -E '(getting-started-k8s)' blazingraptor/getting-started-k8s 1.0 dc81d8418e19 21 months ago 263MB
Push the image
blazingraptor@galactica:~/docker/scale-example/getting-started-k8s/Deployments$ docker push blazingraptor/getting-started-k8s:1.0 The push refers to repository [docker.io/blazingraptor/getting-started-k8s] 12ea4114bca0: Mounted from nigelpoulton/getting-started-k8s 5489c358f90b: Mounted from nigelpoulton/getting-started-k8s 70a5915a62dd: Mounted from nigelpoulton/getting-started-k8s de6bcbc6ed42: Mounted from nigelpoulton/getting-started-k8s daed7950b4bd: Mounted from nigelpoulton/getting-started-k8s 6f7801354ad0: Mounted from nigelpoulton/getting-started-k8s ac4d164fef90: Mounted from nigelpoulton/getting-started-k8s 1.0: digest: sha256:259aca2f1c980dd44e77e84ee686c7bff59c030f1d08a0b99609e072cad3c5c0 size: 1787
Prepare to delete the cluster (see it)
blazingraptor@galactica:~/docker/mysql-repl-k8s$ kubectl describe deployment web-deploy
Name: web-deploy
Namespace: default
CreationTimestamp: Sat, 15 Feb 2025 11:47:59 -0500
Labels: app=web
Annotations: deployment.kubernetes.io/revision: 1
Selector: app=web
Replicas: 4 desired | 4 updated | 4 total | 4 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=web
Containers:
hello-pod:
Image: nigelpoulton/getting-started-k8s:1.0
Port: 8080/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Node-Selectors: <none>
Tolerations: <none>
Conditions:
Type Status Reason
---- ------ ------
Progressing True NewReplicaSetAvailable
Available True MinimumReplicasAvailable
OldReplicaSets: <none>
NewReplicaSet: web-deploy-55bdf4c5d5 (4/4 replicas created)
Events: <none>
Delete the cluster
blazingraptor@galactica:~/docker/scale-example/getting-started-k8s$ kubectl delete all -l app=web pod "web-deploy-55bdf4c5d5-2vt78" deleted pod "web-deploy-55bdf4c5d5-k92lh" deleted pod "web-deploy-55bdf4c5d5-n5kgp" deleted pod "web-deploy-55bdf4c5d5-r7fzx" deleted deployment.apps "web-deploy" deleted replicaset.apps "web-deploy-55bdf4c5d5" deleted