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>

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay