Ingress Kubernetes

Ingress adalah salah satu teknik yang paling powerful untuk mengexpose services keluar. Ada banyak jenis ingress, seperti nginx ingress.

Instalasi nginx ingress

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/mandatory.yaml

Jika menggunakan kubeadm, jalankan setelah script diatas

https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/provider/baremetal/service-nodeport.yaml

Referensi untuk instalasi ingress-nginx yang lain : Deploy Ingress

Lab

dengan mereferensi ke tulisan pv & pvc sebelumnya, berhasil membuat sebuah deployment dengan PVC. sekarang buat sebuah ingress agar deployment tersebut dapat diakses dari luar.

Buat sebuah service dengan tipe ClusterIP, service ini akan merefer deployment dengan label app: nginx

kind: Service
apiVersion: v1
metadata:
  name: webserver
spec:
  ports:
  - port: 80
    protocol: TCP
  selector:
    app: nginx

Lalu buat sebuah ingress

kind:                                     Ingress
apiVersion:                               extensions/v1beta1
metadata:
  name:                                   nginx-public
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: wew.nginx.com 
    http:
      paths:
      - path: /web
        backend:
          serviceName: webserver
          servicePort: 80

Ingress diatas akan merefer ke service dengan nama webserver, lalu kita dapat mengaksesnya dengan url wew.nginx.com/web

ubuntu@master:~$ kubectl create -f service.yaml 
service "webserver" created
ubuntu@master:~$ kubectl get service
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP   5d
webserver    ClusterIP   10.104.117.30   <none>        80/TCP    6s
ubuntu@master:~$ kubectl create -f ingress.yaml 
ingress.extensions "nginx-public" created
ubuntu@master:~$ kubectl get ingress
NAME           HOSTS           ADDRESS   PORTS     AGE
nginx-public   wew.nginx.com             80        7s

Untuk mengakses ingress, terlebih dahulu tambahkan wew.nginx.com dan ip address kubernetes node (10.101.101.10) kedalam /etc/hosts

ubuntu@master:~$ kubectl get service --all-namespaces
NAMESPACE       NAME                   TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
default         kubernetes             ClusterIP   10.96.0.1        <none>        443/TCP                      5d
default         webserver              ClusterIP   10.104.117.30    <none>        80/TCP                       1m
ingress-nginx   default-http-backend   ClusterIP   10.105.156.163   <none>        80/TCP                       5d
ingress-nginx   ingress-nginx          NodePort    10.110.134.232   <none>        80:30303/TCP,443:32238/TCP   5d
kube-system     kube-dns               ClusterIP   10.96.0.10       <none>        53/UDP,53/TCP                5d
kube-system     kubernetes-dashboard   NodePort    10.100.102.181   <none>        443:30566/TCP                5d
ubuntu@master:~$ cat /etc/hosts
127.0.0.1       localhost
127.0.1.1       master
10.101.101.10 wew.nginx.com
# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

Lalu lakukan curl

ubuntu@master:~$ curl http://wew.nginx.com:30303/web
Index file from kubernetes ingress pvc

 

Services Kubernetes

Service adalah sebuah fitur didalam kubernetes yang mengizinkan sebuah pod atau deployment dapat diakses dari dalam cluster kubernetes sendiri atau diakses dari luar.

The service concept

Ada beberapa tipe services

  • ClusterIP

ClusterIP adalah tipe services yang memberikan ip address yang hanya dapat diakses didalam cluster kubernetes.

Buat sebuah deployment

buntu@master:~$ kubectl run nginx --image nginx
deployment.apps "nginx" created
ubuntu@master:~$ kubectl describe deploy nginx
Name:                   nginx
Namespace:              default
CreationTimestamp:      Wed, 27 Jun 2018 22:41:15 -0400
Labels:                 run=nginx
Annotations:            deployment.kubernetes.io/revision=1
Selector:               run=nginx
Replicas:               1 desired | 1 updated | 1 total | 0 available | 1 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  1 max unavailable, 1 max surge
Pod Template:
  Labels:  run=nginx
  Containers:
   nginx:
    Image:        nginx
    Port:         <none>
    Host Port:    <none>
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    ReplicaSetUpdated
OldReplicaSets:  <none>
NewReplicaSet:   nginx-65899c769f (1/1 replicas created)
Events:
  Type    Reason             Age   From                   Message
  ----    ------             ----  ----                   -------
  Normal  ScalingReplicaSet  13s   deployment-controller  Scaled up replica set nginx-65899c769f to 1

Buat sebuah services dengan menggunakan selector untuk label run=nginx

apiVersion:  v1
kind:        Service
metadata:
  name:      nginx
spec:
  selector:
    run:     nginx
  ports:
  - port:    80
  type: ClusterIP

Jalankan services tersebut

ubuntu@master:~$ nano clusterip.yaml
ubuntu@master:~$ kubectl create -f clusterip.yaml 
service "nginx" created
ubuntu@master:~$ kubectl describe svc nginx
Name:              nginx
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          run=nginx
Type:              ClusterIP
IP:                10.101.13.6
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.1.21:80
Session Affinity:  None
Events:            <none>
ubuntu@master:~$ curl http://10.101.13.6
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
  • NodePort

NodePort adalah cara yang paling mudah agar deployment yang kita deploy dapat diakses dari luar. NodePort akan membuka port spesifik dari sebuah node dan mengattachnya kedalam deployment, hampir mirip dengan konsep port forwarding.

Masih dengan deployment yang sama seperti ClusterIP, buat sebuah service dengan NodePort. NodePort dibawah akan membuka port 30036 dan akan melakukan forwarding kedalam deployment dengan port 80.

apiVersion: v1
kind: Service
metadata:  
  name: my-nodeport-service
spec:
  selector:    
    run: nginx
  type: NodePort
  ports:  
  - name: http
    port: 80
    targetPort: 80
    nodePort: 30036
    protocol: TCP

jalankan service tersebut

ubuntu@master:~$ nano nodeport.yaml
ubuntu@master:~$ kubectl create -f nodeport.yaml 
service "my-nodeport-service" created
ubuntu@master:~$ kubectl get svc
NAME                  TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes            ClusterIP   10.96.0.1        <none>        443/TCP        5d
my-nodeport-service   NodePort    10.107.138.137   <none>        80:30036/TCP   6s
ubuntu@master:~$ curl http://10.101.101.10:30036
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
ubuntu@master:~$
  • Load Balancer

Jika kita mendeploy kubernetes dengan kubeadm atau minikube, service load balancer tidak akan bisa digunakan karena service ini akan mengexpose external load balancer seperti lbaas di openstack. platfrom yang mendukung seperti aws, google cloud, atau openstack

Sumber :

  • https://docs.openstack.org/magnum/ocata/dev/kubernetes-load-balancer.html
  • https://kubernetes.io/docs/concepts/services-networking/service/

Kubernetes basic CLI

Kubernetes mempunyai sebuah CLI tools (kubectl) yang mengexpose API kubernetes via local.

Untuk melihat deployment

kubectl get deploy

Untuk melihat Pod

kubectl get pod

Untuk melihat services

kubectl get svc

Untuk melihat ingress

kubectl get ingress

Untuk melihat namespaces

kubectl get ns

Untuk melihat node

kubectl get nodes

Untuk melihat Persistance Volume

kubectl get pv

Untuk melihat Peristance Volume Claim

kubectl get pvc

Untuk melihat replica set

kubectl get rs

Untuk melihat configmap

kubectl get cm

Tips :

  • untuk melihat secara langsung perubahan resource, gunakan –watch
  • untuk mendelete sebuah resource, ubah get menjadi delete diikuti dengan nama resource yang akan didelete

Untuk membuat sebuah deployment, services, ingress, etc. dapat menggunakan sebuah files yaml manifest dan gunakan command

kubectl create -f files.yaml

Untuk lebih mengerti sebuah resource, gunakan explain. contoh :

$ kubectl explain svc
DESCRIPTION:
Service is a named abstraction of software service (for example, mysql)
consisting of local port (for example 3306) that the proxy listens on, and the
selector that determines which pods will answer requests sent through the proxy.
.
.

 

Setup Virtualenv Python

Install Virtualenv

sudo pip install virtualenv

buat sebauh environment baru dengan directory python berada didalam venv

virtualenv venv

Aktifkan virtualenv

source venv/bin/activate

Pastikan virtualenv jalan dengan mengambil module yang sudah terinstall (pastikan kosong)

(venv) zufar@zufar:~/Documents/Technology/Programming/Python/webserver$ pip freeze > modules.txt
(venv) zufar@zufar:~/Documents/Technology/Programming/Python/webserver$ cat modules.txt 
(venv) zufar@zufar:~/Documents/Technology/Programming/Python/webserver$

Coba install sebuah module

(venv) zufar@zufar:~/Documents/Technology/Programming/Python/webserver$ pip install jinja2
Collecting jinja2
  Using cached https://files.pythonhosted.org/packages/7f/ff/ae64bacdfc95f27a016a7bed8e8686763ba4d277a78ca76f32659220a731/Jinja2-2.10-py2.py3-none-any.whl
Collecting MarkupSafe>=0.23 (from jinja2)
Installing collected packages: MarkupSafe, jinja2
Successfully installed MarkupSafe-1.0 jinja2-2.10
(venv) zufar@zufar:~/Documents/Technology/Programming/Python/webserver$ pip freeze > modules.txt
(venv) zufar@zufar:~/Documents/Technology/Programming/Python/webserver$ cat modules.txt 
Jinja2==2.10
MarkupSafe==1.0

Log :

zufar@zufar:~/Documents/Technology/Programming/Python/webserver$ ls
zufar@zufar:~/Documents/Technology/Programming/Python/webserver$ virtualenv venv
Using base prefix '/usr'
New python executable in /home/zufar/Documents/Technology/Programming/Python/webserver/venv/bin/python3
Also creating executable in /home/zufar/Documents/Technology/Programming/Python/webserver/venv/bin/python
Installing setuptools, pip, wheel...done.
zufar@zufar:~/Documents/Technology/Programming/Python/webserver$ source venv/bin/activate
(venv) zufar@zufar:~/Documents/Technology/Programming/Python/webserver$

 

locale.Error: unsupported locale setting

Saat menginstall module python dengan pip, jika ada error seperti

locale.Error: unsupported locale setting

Dapat diperbaiki dengan

$ export LC_ALL=C

atau

export LC_ALL="en_US.UTF-8"
export LC_CTYPE="en_US.UTF-8"
sudo dpkg-reconfigure locales

 

PV & PVC Kubernetes

Persistance Volume (PV) adalah sebuah tipe volume dimana kita dapat mengambil beberapa sumber volume yang lain seperti network volume (nfs, cephfs, glusterfs) di node lain agar data yang kita attach kedalam pod tidak hilang saat pod restart.

Buat sebuah Persistance Volume :

kind:               PersistentVolume
apiVersion:         v1
metadata:
  name:             nfs-vol
  labels:
    type:           local
spec:
  storageClassName: manual
  capacity:
    storage:        10Gi
  accessModes:
  - ReadWriteMany
  nfs:
    server: 10.101.101.40
    path: /var/nfsshare

Cek PV tersebut :

ubuntu@master:~$ kubectl create -f pv.yaml 
persistentvolume "nfs-vol" created
ubuntu@master:~$ kubectl get pv nfs-vol
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM     STORAGECLASS   REASON    AGE
nfs-vol   10Gi       RWX            Retain           Available             manual                   10s
ubuntu@master:~$ kubectl describe pv/nfs-vol
Name:            nfs-vol
Labels:          type=local
Annotations:     <none>
Finalizers:      [kubernetes.io/pv-protection]
StorageClass:    manual
Status:          Available
Claim:           
Reclaim Policy:  Retain
Access Modes:    RWX
Capacity:        10Gi
Node Affinity:   <none>
Message:         
Source:
    Type:      NFS (an NFS mount that lasts the lifetime of a pod)
    Server:    10.101.101.40
    Path:      /var/nfsshare
    ReadOnly:  false
Events:        <none>

Persistance Volume Claim (PVC) adalah sesuatu yang akan mengkonsumsi PV yang dibuat. Jika pada konsep pod dan node worker, pod akan mengkonsumsi resource node worker, maka PVC akan mengkonsumsi resource dari PV.

Buat sebuah Persistance Volume Claim :

kind:               PersistentVolumeClaim
apiVersion:         v1
metadata:
  name:             nginxpvc
spec:
  storageClassName: manual
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage:      200Mi

PVC ini akan mengunakan resource dari PV sebesar 200 MB. lalu create dan cek PVC tersebut

ubuntu@master:~$ kubectl create -f pvc.yaml 
persistentvolumeclaim "nginxpvc" created
ubuntu@master:~$ kubectl get pvc
NAME       STATUS    VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS   AGE
nginxpvc   Bound     nfs-vol   10Gi       RWX            manual         6s
ubuntu@master:~$ kubectl describe pvc/nginxpvc
Name:          nginxpvc
Namespace:     default
StorageClass:  manual
Status:        Bound
Volume:        nfs-vol
Labels:        <none>
Annotations:   pv.kubernetes.io/bind-completed=yes
               pv.kubernetes.io/bound-by-controller=yes
Finalizers:    [kubernetes.io/pvc-protection]
Capacity:      10Gi
Access Modes:  RWX
Events:        <none>

PVC inilah yang akan kita gunakan sebagai volume saat membuat sebuah deployment. contohnya :

kind:                          Deployment
apiVersion:                    extensions/v1beta1
metadata:
  name:                        nginx-with-pv
spec:
  replicas:                    1
  template:
    metadata:
      labels:
        app:                   nginx
    spec:
      containers:
      - name:                  webserver
        image:                 nginx
        ports:
        - containerPort:       80
        volumeMounts:
        - mountPath:           "/usr/share/nginx/html"
          name:                webservercontent
      volumes:
      - name:                  webservercontent
        persistentVolumeClaim:
          claimName:           nginxpvc

Catatan :

Pastikan semua worker node sudah terinstall paket nfs-common, jika belum :

apt install nfs-common

Instalasi NFS Server

Berikut lingkungan yang digunakan untuk instalasi NFS Server :

  • Sistem Operasi Ubuntu 16.04
  • IP Address Statik Server (10.101.101.40)
  • IP Address Statik Clinet (10.101.101.10)

Proses Instalasi

Lakukan update serta install paket utama.

apt-get update
apt-get install nfs-kernel-server

Buat folder yang digunakan untuk melakukan sharing.

mkdir /var/nfsshare

Rubah Ownership dari folder tersebut.

chown nobody:nogroup /var/nfsshare

Tambahkan directory tersebut kedalam konfigurasi NFS.

nano /etc/exports
.
.
/var/nfsshare 10.101.101.10(rw,sync,no_subtree_check)

Lakukan update kedalam NFS table.

exportfs -a

Start NFS Services

service nfs-kernel-server start

Cek Status NFS

exportfs -u

 

1 8 9 10