DEV Community

Jasper Rodda
Jasper Rodda

Posted on • Edited on

Create and expose Services in Kubernetes

In Kubernetes, a service has following purposes/advantages.

  1. Expose Application to outside world.
  2. Service Discovery: Labels and Selectors.
  3. LoadBalancer or NodePort Mode.
  4. Install Kubeshark

Pre-requisites:

  • Create deploy.yml file
  • Create service.yml file
  • Deploy deploy.yml
  • Deploy service.yml

1. Expose Application to outside world

- a) Create deploy.yml file as below.
apiVersion: apps/v1 kind: Deployment metadata: name: sample-python-deployment labels: app: sample-python-app spec: replicas: 2 selector: matchLabels: app: sample-python-app template: metadata: labels: app: sample-python-app spec: containers: - name: python-app image: jasper475/d37-k8s-services-py-django-app:v2 ports: - containerPort: 8000 
Enter fullscreen mode Exit fullscreen mode
- b) Create service.yml file as below.
apiVersion: v1 kind: Service metadata: name: sample-python-service spec: type: NodePort selector: app: sample-python-app ports: - port: 80 targetPort: 8000 nodePort: 30007 
Enter fullscreen mode Exit fullscreen mode
- c) Deploy deploy.yml file as below.

kubectl apply -f deploy.yaml

$ kubectl apply -f deploy.yaml deployment.apps/sample-python-deployment created 
Enter fullscreen mode Exit fullscreen mode
- d) Deploy service.yml file as below.

kubectl apply -f service.yaml

$ kubectl apply -f deploy.yaml service/sample-python-service configured 
Enter fullscreen mode Exit fullscreen mode
- e) NodePort service Type: service deployed as NodePort type
kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 11d sample-python-service NodePort 10.103.136.137 <none> 80:30007/TCP 2s 
Enter fullscreen mode Exit fullscreen mode
- f) Notice IP Address of Pod: Notice IP below
$ kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES sample-python-deployment-5787bd6b9f-656fn 1/1 Running 0 3h54m 10.244.0.35 minikube <none> <none> sample-python-deployment-5787bd6b9f-t9ttj 1/1 Running 0 3h50m 10.244.0.36 minikube <none> <none> 
Enter fullscreen mode Exit fullscreen mode
- g) Access Application via IP Addr:Port: Note, Python application is exposed via Port 8000
$ minikube ssh curl -L http://10.244.0.35:8000/demo ####Access via Pod IP Address *** It works *** 
Enter fullscreen mode Exit fullscreen mode

2. Service Discovery: Labels and Selectors.

  • Edit 'service.yml' file

FROM:

 spec: type: NodePort selector: app: sample-python-app*** ports: - port: 80 
Enter fullscreen mode Exit fullscreen mode

TO

spec: type: NodePort selector: app: sample-python-a*** ports: - port: 80 
Enter fullscreen mode Exit fullscreen mode

Image description

3. LoadBalancer or NodePort Mode.

- a) get svc: kubectl get svc

$ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 11d sample-python-service NodePort 10.103.136.137 <none> 80:30007/TCP 33m 
Enter fullscreen mode Exit fullscreen mode

- b) SVC Type: NodePort

kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 11d sample-python-service NodePort 10.103.136.137 <none> 80:30007/TCP 2s 
Enter fullscreen mode Exit fullscreen mode

- c) Access SVC: via NodePort Mode

minikube ssh $ pwd /home/docker $ curl -L http://10.103.136.137:8000/demo ####Access via Cluster IP of svc on port 8000 - ******* Doesn't work********* curl: (28) Failed to connect to 10.103.136.137 port 8000 after 131079 ms: Connection timed out $ curl -L http://10.103.136.137:80/demo ####Access via Cluster IP of svc on port 80 - ******* Hurray, it works !!! ********* $ curl -L http://10.103.136.137:8000/demo ####Access via Pod IP Address _ _ _ _ ( ) ( ) ___ ___ (_) ___ (_)| |/') _ _ | |_ __ /' _ ` _ `\| |/' _ `\| || , < ( ) ( )| '_`\ /'__`\ | ( ) ( ) || || ( ) || || |\`\ | (_) || |_) )( ___/ (_) (_) (_)(_)(_) (_)(_)(_) (_)`\___/'(_,__/'`\____) $ curl -L http://10.103.136.137:80 <!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title>Page not found at /</title> <meta name="robots" content="NONE,NOARCHIVE"> <style type="text/css"> html * { padding:0; margin:0; } body * { padding:10px 20px; } body * * { padding:0; } body { font:small sans-serif; background:#eee; color:#000; } body>div { border-bottom:1px solid #ddd; } h1 { font-weight:normal; margin-bottom:.4em; } h1 span { font-size:60%; color:#666; font-weight:normal; } table { border:none; border-collapse: collapse; width:100%; } td, th { vertical-align:top; padding:2px 3px; } th { width:12em; text-align:right; color:#666; padding-right:.5em; } #info { background:#f6f6f6; } #info ol { margin: 0.5em 4em; } #info ol li { font-family: monospace; } #summary { background: #ffc; } #explanation { background:#eee; border-bottom: 0px none; } pre.exception_value { font-family: sans-serif; color: #575757; font-size: 1.5em; margin: 10px 0 10px 0; } </style> </head> <body> <div id="summary"> <h1>Page not found <span>(404)</span></h1> <table class="meta"> <tr> <th>Request Method:</th> <td>GET</td> </tr> <tr> <th>Request URL:</th> <td>http://10.103.136.137/</td> 
Enter fullscreen mode Exit fullscreen mode

- d) Edit svc: kubectl edit svc service-name

$ kubectl edit svc sample-python-service ------------------------------------------------------------------- # 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: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"sample-python-service","namespace":"default"},"spec":{"ports":[{"nodePort":30007,"port":80,"targetPort":8000}],"selector":{"app":"sample-python-app"},"type":"NodePort"}} creationTimestamp: "2024-01-11T02:51:02Z" name: sample-python-service namespace: default resourceVersion: "16469" uid: bd9bd510-e633-4dc1-adc1-1cc4704378d3 spec: allocateLoadBalancerNodePorts: true clusterIP: 10.103.136.137 clusterIPs: - 10.103.136.137 externalTrafficPolicy: Cluster internalTrafficPolicy: Cluster ipFamilies: - IPv4 ipFamilyPolicy: SingleStack ports: - nodePort: 30007 port: 80 protocol: TCP targetPort: 8000 selector: app: sample-python-app sessionAffinity: None type: ***LoadBalancer*** status: loadBalancer: {} ------------------------------------------------------------------- service/sample-python-service edited 
Enter fullscreen mode Exit fullscreen mode

SVC Type: LoadBalancer - notice EXTERNAL-IP is <pending> state. Because, in Minikube this won't be creating an IP address whereas, in any cloud providers such as AWS EC2 or Azure VM or GCP Engine - EXTERNAL-IP will be assigned via Cloud-Control Manager

kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 11d sample-python-service LoadBalancer 10.103.136.137 <pending> 80:30007/TCP 34m 
Enter fullscreen mode Exit fullscreen mode

Get `Minikube ip'


$ minikube ip
192.168.59.105

Access via browser http://192.168.59.105:30007/demo
or curl -L http://192.168.59.105:30007/demo

Image description

4. Install Kubeshark

- a) Install Kubeshark as below

git clone: git clone https://github.com/kubeshark/kubeshark


PS C:\Users\Jasper> git clone https://github.com/kubeshark/kubeshark
Cloning into 'kubeshark'...
remote: Enumerating objects: 20781, done.
remote: Counting objects: 100% (1668/1668), done.
remote: Compressing objects: 100% (262/262), done.
remote: Total 20781 (delta 1525), reused 1491 (delta 1406), pack-reused 19113
Receiving objects: 100% (20781/20781), 26.38 MiB | 19.53 MiB/s, done.
Resolving deltas: 100% (14618/14618), done.
PS C:\Users\Jasper>

Top comments (0)