Exposing Your App
In this scenario you will learn how to expose Kubernetes applications outside the cluster using the kubectl expose command. You will also learn how to view and apply labels to objects with the kubectl label command.
Create a new service
kubectl get pods
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-5c69669756-vdwgm 1/1 Running 0 22m
List the current Services from our cluster
kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 28m
Use the expose command with NodePort as parameter (minikube does not support the LoadBalancer option yet)
kubectl expose deployment/kubernetes-bootcamp --type="NodePort" --port 8080
service "kubernetes-bootcamp" exposed
To find out what port was opened externally
kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 29m
kubernetes-bootcamp NodePort 10.110.44.165 <none> 8080:30099/TCP 16s
kubectl describe services/kubernetes-bootcamp
Name: kubernetes-bootcamp
Namespace: default
Labels: run=kubernetes-bootcamp
Annotations: <none>
Selector: run=kubernetes-bootcamp
Type: NodePort
IP: 10.110.44.165
Port: <unset> 8080/TCP
TargetPort: 8080/TCP
NodePort: <unset> 30099/TCP
Endpoints: 172.17.0.4:8080
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
export NODE_PORT=$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports 0).nodePort}}')
echo NODE_PORT=$NODE_PORT
NODE_PORT=30099
Test that the app is exposed outside of the cluster
curl $(minikube ip):$NODE_PORT
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-5c69669756-vdwgm | v=1
The Service is exposed
Using labels
You can see the name of the label with describe deployment
kubectl describe deployment
Name: kubernetes-bootcamp
Namespace: default
CreationTimestamp: Sun, 10 Jun 2018 15:08:14 +0000
Labels: run=kubernetes-bootcamp
Annotations: deployment.kubernetes.io/revision=1
Selector: run=kubernetes-bootcamp
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=kubernetes-bootcamp
Containers:
kubernetes-bootcamp:
Image: gcr.io/google-samples/kubernetes-bootcamp:v1
Port: 8080/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: kubernetes-bootcamp-5c69669756 (1/1 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 29m deployment-controller Scaled up replica set kubernetes-bootcamp-5c69669756 to 1
Use this label to query our list of Pods
kubectl get pods -l run=kubernetes-bootcamp
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-5c69669756-vdwgm 1/1 Running 0 31m
List the existing services
kubectl get services -l run=kubernetes-bootcamp
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes-bootcamp NodePort 10.110.44.165 <none> 8080:30099/TCP 8m
export POD_NAME=$(kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}')
echo Name of the Pod: $POD_NAME
Name of the Pod: kubernetes-bootcamp-5c69669756-vdwgm
Apply a new label
kubectl label pod $POD_NAME app=v1
pod "kubernetes-bootcamp-5c69669756-vdwgm" labeled
kubectl describe pods $POD_NAME
Name: kubernetes-bootcamp-5c69669756-vdwgm
Namespace: default
Node: minikube/10.0.2.15
Start Time: Sun, 10 Jun 2018 15:08:15 +0000
Labels: app=v1
pod-template-hash=1725225312
run=kubernetes-bootcamp
Annotations: <none>
Status: Running
IP: 172.17.0.4
Controlled By: ReplicaSet/kubernetes-bootcamp-5c69669756
Containers:
kubernetes-bootcamp:
Container ID: docker://b3c882ba24392b8b1417e420ac45c351959098cacc82fe59a64dff9d6e3859d6
Image: gcr.io/google-samples/kubernetes-bootcamp:v1
Image ID: docker-pullable://gcr.io/google-samples/kubernetes-bootcamp@sha256:0d6b8ee63bb57c5f5b6156f446b3bc3b3c143d233037f3a2f00e279c8fcc64af
Port: 8080/TCP
Host Port: 0/TCP
State: Running
Started: Sun, 10 Jun 2018 15:08:48 +0000
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-x5428 (ro)
Conditions:
Type Status
Initialized True
Ready True
PodScheduled True
Volumes:
default-token-x5428:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-x5428
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 34m default-scheduler Successfully assigned kubernetes-bootcamp-5c69669756-vdwgm to minikube
Normal SuccessfulMountVolume 34m kubelet, minikube MountVolume.SetUp succeeded for volume "default-token-x5428"
Normal Pulling 34m kubelet, minikube pulling image "gcr.io/google-samples/kubernetes-bootcamp:v1"
Normal Pulled 34m kubelet, minikube Successfully pulled image "gcr.io/google-samples/kubernetes-bootcamp:v1"
Normal Created 34m kubelet, minikube Created container
Normal Started 34m kubelet, minikube Started container
We can query now the list of pods using the new label
kubectl get pods -l app=v1
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-5c69669756-vdwgm 1/1 Running 0 35m
Deleting a service
kubectl delete service -l run=kubernetes-bootcamp
service "kubernetes-bootcamp" deleted
kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 42m
curl $(minikube ip):$NODE_PORT
curl: (7) Failed to connect to 192.168.99.100 port 30099: Connection refused
This proves that the app is not reachable anymore from outside of the cluster.
You can confirm that the app is still running with a curl inside the pod
kubectl exec -ti $POD_NAME curl localhost:8080
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-5c69669756-vdwgm | v=1