Setup & Running First App

Setup on Azure

Please refer to this guide.

Running First App

  • Let's run an application on the new Kubernetes cluster
  • Before we can launch a container based on the image, we need to create a pod definition
    • A pod describes an application running on Kubernetes
    • A pod can contain one or more tightly coupled containers, that make up the app
      • Those apps can easily communicate with each other using their local
  • Our app has only one container

Create a Pod

Create a file pod-helloworld.yml with the pod definition:

apiVersion: v1
kind: Pod
metadata:
  name: nodehelloworld.example.com
  labels:
    app: helloworld
spec:
  containers:
    - name: k8s-demo
      image: wardviaene/k8s-demo
      ports:
        - containerPort: 3000

Use kubectl to create the pod on the kubernetes cluster:

$ kubectl create -f pod-helloworld.yml
pod "nodehelloworld.example.com" created

See pod status

$ kubectl get pod
NAME                         READY     STATUS    RESTARTS   AGE
nodehelloworld.example.com   1/1       Running   0          2m

See pod config

$ kubectl describe pod nodehelloworld.example.com
Name:		nodehelloworld.example.com
Namespace:	default
Node:		k8s-agent-7d111633-0/10.240.0.4
Start Time:	Sun, 29 Apr 2018 04:36:37 +0000
Labels:		app=helloworld
Annotations:	<none>
Status:		Running
IP:		10.244.1.7
Containers:
  k8s-demo:
    Container ID:	docker://dddf1e925faf9c3fee56b373244bb7227d7f4c139c76816dbafb8237d6d00515
    Image:		wardviaene/k8s-demo
    Image ID:		docker-pullable://wardviaene/k8s-demo@sha256:2c050f462f5d0b3a6430e7869bcdfe6ac48a447a89da79a56d0ef61460c7ab9e
    Port:		3000/TCP
    State:		Running
      Started:		Sun, 29 Apr 2018 04:37:46 +0000
    Ready:		True
    Restart Count:	0
    Environment:	<none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-lr576 (ro)
Conditions:
  Type		Status
  Initialized 	True
  Ready 	True
  PodScheduled 	True
Volumes:
  default-token-lr576:
    Type:	Secret (a volume populated by a Secret)
    SecretName:	default-token-lr576
    Optional:	false
QoS Class:	BestEffort
Node-Selectors:	<none>
Tolerations:	<none>
Events:
  FirstSeen	LastSeen	Count	From				SubObjectPath			Type		Reason		      	Message
  ---------	--------	-----	----				-------------			--------	------		      	-------
  4m		4m		1	default-scheduler						Normal		Scheduled	      	Successfully assigned nodehelloworld.example.com to k8s-agent-7d111633-0
  4m		4m		1	kubelet, k8s-agent-7d111633-0					Normal		SuccessfulMountVolume  	MountVolume.SetUp succeeded for volume "default-token-lr576"
  4m		4m		1	kubelet, k8s-agent-7d111633-0	spec.containers{k8s-demo}	Normal		Pulling		      	pulling image "wardviaene/k8s-demo"
  2m		2m		1	kubelet, k8s-agent-7d111633-0	spec.containers{k8s-demo}	Normal		Pulled		      	Successfully pulled image "wardviaene/k8s-demo"
  2m		2m		1	kubelet, k8s-agent-7d111633-0	spec.containers{k8s-demo}	Normal		Created		      	Created container
  2m		2m		1	kubelet, k8s-agent-7d111633-0	spec.containers{k8s-demo}	Normal		Started		      	Started container

Forward port

$ kubectl port-forward nodehelloworld.example.com 8081:3000
Forwarding from 127.0.0.1:8081 -> 3000
Forwarding from [::1]:8081 -> 3000

Create Service

Expose service

$ kubectl expose pod nodehelloworld.example.com --type=NodePort --name nodehelloworld-service
service "nodehelloworld-service" exposed

See list of service

$ kubectl get service
NAME                     CLUSTER-IP    EXTERNAL-IP   PORT(S)          AGE
kubernetes               10.0.0.1      <none>        443/TCP          7d
nodehelloworld-service   10.0.241.45   <nodes>       3000:30706/TCP   25s

Get service url

$ kubectl describe service nodehelloworld-service
Name:				nodehelloworld-service
Namespace:			default
Labels:				app=helloworld
Annotations:		<none>
Selector:			app=helloworld
Type:				NodePort
IP:			    	10.0.241.45
Port:				<unset>	3000/TCP
NodePort:			<unset>	30706/TCP
Endpoints:			10.244.1.7:3000
Session Affinity:	None
Events:				<none>

Try accessing app locally

$ curl 10.244.1.7:3000
Hello World!

Access From the Internet

Edit service with VI

$ kubectl edit service/nodehelloworld-service
service "nodehelloworld-service" edited

Change externalTrafficPolicy to Local and change type to LoadBalancer.

# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: 2018-04-29T04:44:16Z
  labels:
    app: helloworld
  name: nodehelloworld-service
  namespace: default
  resourceVersion: "109236"
  selfLink: /api/v1/namespaces/default/services/nodehelloworld-service
  uid: f8e985ab-4b67-11e8-9b4e-000d3aa08982
spec:
  clusterIP: 10.0.241.45
  externalTrafficPolicy: Local
  healthCheckNodePort: 31970
  ports:
  - nodePort: 30706
    port: 3000
    protocol: TCP
    targetPort: 3000
  selector:
    app: helloworld
  sessionAffinity: None
  type: LoadBalancer
status:
  loadBalancer:
    ingress:
    - ip: 52.163.120.220

VI Usage: Press i to enter edit mode. Once done, press ESC and type :wq to save and quite.

Check service using kubectl get service

$ kubectl get service
NAME                     CLUSTER-IP    EXTERNAL-IP   PORT(S)          AGE
kubernetes               10.0.0.1      <none>        443/TCP          7d
nodehelloworld-service   10.0.241.45   <pending>     3000:30706/TCP   56m

Wait for a few minutes until <pending> changing to an IP address

$ kubectl get service
NAME                     CLUSTER-IP    EXTERNAL-IP      PORT(S)          AGE
kubernetes               10.0.0.1      <none>           443/TCP          7d
nodehelloworld-service   10.0.241.45   52.163.120.220   3000:30706/TCP   59m

Try to access the app at the displayed IP:port e.g. http://52.163.120.220:3000

References

Useful Commands

Command

Description

kubectl get pod

Get information about all running pods

kubectl describe pod <pod>

Describe one pod

kubectl expose pod <pod> --port=444 --name=frontend

Expose the pod of a pod (creates a new service)

kubectl port-forward <pod> 8080

Pod forward the exposed pod port to your local machine

kubectl attach <pod> -i

Attach to the pod

kubectl exec <pod> -- <command>

Execute a command on the pod

kubectl label pod <pod> mylabel=awesome

Add a new label to a pod

kubectl run -i --tty busybox --image=busybox --restart=never -- sh

Run a shell in a pod, very useful for debugging

No Comments

Back to top