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

results matching ""

    No results matching ""