Getting started with k8s on Docker for Mac / Windows
I'm using zsh, so all I need to do is add kubectl to plugins section
So now we are ready to go with k8s!
Let's run nginx:
➜ ~ kubectl run --image nginx:alpine web
deployment.apps "web" created
Check available deployments:
➜ ~ kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
web 1 1 1 1 2m
Replication set:
➜ ~ kubectl get replicaset
NAME DESIRED CURRENT READY AGE
web-bbcdd5f4 1 1 1 4m
And finally get pods where created:
➜ ~ kubectl get pod
NAME READY STATUS RESTARTS AGE
web-bbcdd5f4-zqq5x 1/1 Running 0 5m
Let's get more information about our nginx web deployment
➜ ~ kubectl describe deployment web
Name: web
Namespace: default
CreationTimestamp: Sun, 04 Nov 2018 15:14:38 +0200
Labels: run=web
Annotations: deployment.kubernetes.io/revision=1
Selector: run=web
Replicas: 1 desired | 1 updated | 1 total | 1 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 1 max unavailable, 1 max surge
Pod Template:
Labels: run=web
Containers:
web:
Image: nginx:alpine
Port: <none>
Host Port: <none>
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: web-bbcdd5f4 (1/1 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 7m deployment-controller Scaled up replica set web-bbcdd5f4 to 1
Let's test our nginx web app. We can access web deployment via it's pod, so let's do that!
First of all we need to get nginx web pod name
➜ ~ kubectl get pod
NAME READY STATUS RESTARTS AGE
web-bbcdd5f4-zqq5x 1/1 Running 0 9m
Now we can forward nginx pod port exposed by default (80) to for example local port 8080 just like so:
➜ ~ kubectl port-forward web-bbcdd5f4-zqq5x 8080:80
Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80
Now, let's test if it's working...
With that we make sure that nginx web container is running and handling traffic
➜ ~ kubectl expose deployment web --port 80 --type NodePort
service "web" exposed
Let's get services we currently have:
➜ ~ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 1h
web NodePort 10.110.125.231 <none> 80:30906/TCP 50s
As you ca nsee port 80 of nginx web deploymemnt locally exposed on port 30906. Let's test this time if port 30906 is actually working:
➜ ~ http :30906
HTTP/1.1 200 OK
Accept-Ranges: bytes
Connection: keep-alive
Content-Length: 612
Content-Type: text/html
Date: Sun, 04 Nov 2018 14:18:30 GMT
ETag: "5bb3c541-264"
Last-Modified: Tue, 02 Oct 2018 19:21:37 GMT
Server: nginx/1.15.5
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
and it does.
Now I would like to use reverse-engineering principle to get current kubernetes service definition into yaml file:
➜ ~ kubectl get service web -o yaml > /tmp/web-service.yaml
Not let's correct our service definition like so:
➜ ~ cat /tmp/web-service.yaml
apiVersion: v1
kind: Service
metadata:
labels:
run: web
name: web
namespace: default
selfLink: /api/v1/namespaces/default/services/web
spec:
externalTrafficPolicy: Cluster
ports:
- nodePort: 30000
port: 80
protocol: TCP
targetPort: 80
selector:
run: web
sessionAffinity: None
type: NodePort
status:
loadBalancer:
ingress:
- hostname: localhost
Now we can re-create web service:
➜ ~ kubectl apply -f /tmp/web-service.yaml
Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply
service "web" configured
Verify service was updated as expected:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 1h
web NodePort 10.104.17.108 <none> 80:30000/TCP 10m
Now we can use out app on http://localhost:30000
If you will try set in /tmp/web-service.yaml
file: spec.ports[0].nodePort = 8080
, or any other < 30000 value, during kubectl apply you will get an error like this:
➜ ~ kubectl apply -f /tmp/web-service.yaml
Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply
The Service "web" is invalid: spec.ports[0].nodePort: Invalid value: 8080: provided port is not in the valid range. The range of valid ports is 30000-32767
TODO: Investigate how we can fix it...
Setup:
➜ kubectl apply -f /tmp/app.yaml
secret "postgres-password-secret" created
persistentvolumeclaim "db-pvc" created
deployment.apps "postgres" created
service "postgres-node-port-dev-svc" created
service "postgres-clister-ip-svc" created
deployment.apps "web" created
service "web-node-port-dev-svc" created
service "web-cluster-ip-svc" created
Verify:
➜ kubectl get -f /tmp/app.yaml
NAME TYPE DATA AGE
secret/postgres-password-secret Opaque 1 2m
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/db-pvc Bound pvc-f6161902-e0a4-11e8-93d4-025000000001 1Gi RWO hostpath 2m
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
deployment.apps/postgres 1 1 1 1 2m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/postgres-node-port-dev-svc NodePort 10.107.237.57 <none> 5432:32345/TCP 2m
service/postgres-clister-ip-svc ClusterIP 10.110.232.11 <none> 5432/TCP 2m
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
deployment.apps/web 2 2 2 2 2m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/web-node-port-dev-svc NodePort 10.97.202.253 <none> 80:30000/TCP 2m
service/web-cluster-ip-svc ClusterIP 10.96.135.4 <none> 80/TCP 2m