DEV Community

Jasper Rodda
Jasper Rodda

Posted on • Updated 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)