Note_Tech

All technological notes.


Project maintained by simonangel-fong Hosted on GitHub Pages — Theme by mattgraham

Kubernetes Networking: Service - ClusterIP

Back


ClusterIP


sep:
  env:
    - name: SVC_DNS
      value: http://svc_name

How It Works

apiVersion: v1
kind: Service
metadata:
  name: nginx-clusterip
spec:
  type: ClusterIP # Default service type
  selector: # selector to match pod with labels
    app: nginx
  ports:
    - protocol: TCP
      port: 80 # Service port (ClusterIP virtual port)
      targetPort: 80 # Pod’s container port
  1. Service Creation
    • cmd: kubectl apply -f nginx-clusterip.yaml
    • The API Server
      • assigns a virtual IP (ClusterIP) to each pod
      • stores the Service in etcd, including the ClusterIP
      • push update to kube-proxy on each node
    • kube-proxy Configures Rules
      • installs iptables/IPVS rules
  2. Service Discovery
    • CoreDNS registers the Service with a DNS name
      • nginx-clusterip.default.svc.cluster.local
  3. Client request Inside the cluster
    • cmd: curl http://nginx-clusterip:80


Service Discovery


Declarative Manifest



Imperative Command

Command DESC
kubectl create svc clusterip svc_name --tcp=port Create a ClusterIP service
kubectl expose deploy deploy_name --name=svc_name --type=ClusterIP --port=80 --target-port=8080 Expose a deploy
kubectl expose pod pod_name --name=svc_name --type=ClusterIP --port=80 --target-port=8080 Expose a pod
kubectl run nginx --image=nginx --port=80 --expose=true Create a pod and a ClusterIP service
kubectl set selector service SERVICE KEY=VALUE Update service selector

Lab: Explore default ClusterIP

kubectl get svc
# NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
# kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   18h

kubectl describe svc kubernetes
# Name:                     kubernetes
# Namespace:                default
# Labels:                   component=apiserver
#                           provider=kubernetes
# Annotations:              <none>
# Selector:                 <none>
# Type:                     ClusterIP
# IP Family Policy:         SingleStack
# IP Families:              IPv4
# IP:                       10.96.0.1
# IPs:                      10.96.0.1
# Port:                     https  443/TCP
# TargetPort:               6443/TCP
# Endpoints:                192.168.65.3:6443
# Session Affinity:         None
# Internal Traffic Policy:  Cluster
# Events:                   <none>

Lab: Create ClusterIP

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      name: nginx-pod
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx-con
          image: nginx
apiVersion: v1
kind: Service
metadata:
  name: service-clusterip
spec:
  type: ClusterIP
  selector:
    app: nginx
  ports:
    - port: 80
      targetPort: 80
# create
kubectl create -f .
# deployment.apps/deploy-nginx created
# service/service-clusterip created

# confirm
kubectl get all
# NAME                                READY   STATUS    RESTARTS   AGE
# pod/deploy-nginx-5f9767d954-jjm9q   1/1     Running   0          2m21s
# pod/deploy-nginx-5f9767d954-wbrfr   1/1     Running   0          2m21s
# pod/deploy-nginx-5f9767d954-xbtn8   1/1     Running   0          2m21s

# NAME                        TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
# service/kubernetes          ClusterIP   10.96.0.1        <none>        443/TCP   18h
# service/service-clusterip   ClusterIP   10.106.146.103   <none>        80/TCP    2m21s

# NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
# deployment.apps/deploy-nginx   3/3     3            3           2m21s

# NAME                                      DESIRED   CURRENT   READY   AGE
# replicaset.apps/deploy-nginx-5f9767d954   3         3         3       2m21s

# get info
kubectl describe svc service-clusterip
# Name:                     service-clusterip
# Namespace:                default
# Labels:                   <none>
# Annotations:              <none>
# Selector:                 app=nginx
# Type:                     ClusterIP
# IP Family Policy:         SingleStack
# IP Families:              IPv4
# IP:                       10.106.146.103
# IPs:                      10.106.146.103
# Port:                     <unset>  80/TCP
# TargetPort:               80/TCP
# Endpoints:                10.1.2.158:80,10.1.2.159:80,10.1.2.160:80
# Session Affinity:         None
# Internal Traffic Policy:  Cluster
# Events:                   <none>

# create a pod to test clusterIP
kubectl run curlpod --rm -it --image=busybox:1.36 --restart=Never -- sh
# test dns name
wget -qO- http://service-clusterip:80
# test clusterIP/virtual IP
wget -qO- http://10.106.146.103:80
exit

# remove
kubectl delete -f .
# deployment.apps "deploy-nginx" deleted
# service "service-clusterip" deleted

Lab: Create ClusterIP for nginx

# create index.html
tee index.html<<EOF
<html>
<title>Home</title>

<body>
    <h1>Home</h1>
    <p>this is the home page</p>
</body>

</html>
EOF

# create cm with index.html
kubectl create configmap nginx-file --from-file=index.html -o yaml
# configmap/nginx-file created

# confirm
kubectl describe cm nginx-file
# Name:         nginx-file
# Namespace:    default
# Labels:       <none>
# Annotations:  <none>

# Data
# ====
# index.html:
# ----
# <html>\r
# <title>Home</title>\r
# \r
# <body>\r
#     <h1>Home</h1>\r
#     <p>this is the home page</p>\r
# </body>\r
# \r
# </html>

tee nginx-pod.yaml<<EOF
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  volumes:
    - name: nginx-file
      configMap:
        name: nginx-file
        optional: true
  containers:
    - name: nginx
      image: nginx
      volumeMounts:
        - name: nginx-file
          mountPath: /usr/share/nginx/html
EOF

kubectl apply -f nginx-pod.yaml
# pod/nginx configured

kubectl get pod -o wide -L app
# NAME    READY   STATUS    RESTARTS   AGE   IP         NODE             NOMINATED NODE   READINESS GATES   APP
# nginx   1/1     Running   0          14m   10.1.3.1   docker-desktop   <none>           <none>            nginx

# confirm home page
kubectl port-forward nginx 8080:80
curl localhost:8080
# <html>
# <title>Home</title>

# <body>
#     <h1>Home</h1>
#     <p>this is the home page</p>
# </body>

# </html>
tee nginx-svc.yaml<<EOF
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  type: ClusterIP
  selector:
    app: nginx
  ports:
  - name: http
    protocol: TCP
    port: 8080
    targetPort: 80
EOF

kubectl apply -f nginx-svc.yaml
# service/nginx-svc created

# confirm
kubectl get svc -o wide
# NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE     SELECTOR
# nginx-svc    ClusterIP   10.111.110.150   <none>        8080/TCP   9m11s   app=nginx

kubectl describe svc nginx-svc
# Name:                     nginx-svc
# Namespace:                default
# Labels:                   <none>
# Annotations:              <none>
# Selector:                 app=nginx
# Type:                     ClusterIP
# IP Family Policy:         SingleStack
# IP Families:              IPv4
# IP:                       10.111.110.150
# IPs:                      10.111.110.150
# Port:                     http  8080/TCP
# TargetPort:               80/TCP
# Endpoints:                10.1.3.1:80
# Session Affinity:         None
# Internal Traffic Policy:  Cluster
# Events:                   <none>

# update selector
kubectl set selector service nginx-svc app=nginx,backend=none
# service/nginx-svc selector updated

kubectl get svc -o wide
# NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE     SELECTOR
# kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP    6d17h   <none>
# nginx-svc    ClusterIP   10.111.110.150   <none>        8080/TCP   10m     app=nginx,backend=none

# update selector
kubectl set selector service nginx-svc app=nginx
# service/nginx-svc selector updated

kubectl get svc -o wide
# NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE     SELECTOR
# kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP    6d17h   <none>
# nginx-svc    ClusterIP   10.111.110.150   <none>        8080/TCP   11m     app=ngin
# with ip
kubectl exec -it nginx -- curl 10.111.110.150:8080
# <html>
# <title>Home</title>

# <body>
#     <h1>Home</h1>
#     <p>this is the home page</p>
# </body>

# </html>

# with dns: all the same
kubectl exec -it nginx -- curl nginx-svc:8080
kubectl exec -it nginx -- curl nginx-svc.default:8080
kubectl exec -it nginx -- curl nginx-svc.default.svc:8080
kubectl exec -it nginx -- curl nginx-svc.default.svc.cluster.local:8080
# <html>
# <title>Home</title>

# <body>
#     <h1>Home</h1>
#     <p>this is the home page</p>
# </body>

# </html>
# dns resolve point to nameserver
kubectl exec -it nginx -- cat /etc/resolv.conf
# nameserver 10.96.0.10
# search default.svc.cluster.local svc.cluster.local cluster.local
# options ndots:5

# confirm: pod dns point to 10.96.0.10 which is kube-dns
kubectl get svc -A
# NAMESPACE              NAME                                   TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                  AGE
# kube-system            kube-dns                               ClusterIP   10.96.0.10       <none>        53/UDP,53/TCP,9153/TCP   52d
kubectl exec -it nginx -- env | sort
# NGINX_SVC_PORT_8080_TCP_ADDR=10.111.110.150
# NGINX_SVC_PORT_8080_TCP_PORT=8080
# NGINX_SVC_PORT_8080_TCP_PROTO=tcp
# NGINX_SVC_PORT_8080_TCP=tcp://10.111.110.150:8080
# NGINX_SVC_PORT=tcp://10.111.110.150:8080
# NGINX_SVC_SERVICE_HOST=10.111.110.150
# NGINX_SVC_SERVICE_PORT_HTTP=8080
# NGINX_SVC_SERVICE_PORT=8080

Lab: Use ClusterIP as Env var

tee ping-pod.yaml<<EOF
apiVersion: v1
kind: Pod
metadata:
  name: ping-pod
spec:
  env:
    - name: NGINX_SVC_URL
      value: http://nginx-svc:8080
  containers:
    - name: busybox
      image: busybox
      command:
        - "sh"
      args:
        - "-c"
        - |
         echo "ping-pod"
         wget $NGINX_SVC_URL

         sleep 500
EOF

kubectl apply -f ping-pod.yaml
# pod/ping-pod created

# confirm log
kubectl logs pod/ping-pod
# ping-pod
# Connecting to nginx-svc:8080 (10.111.110.150:8080)
# writing to stdout
# -                    100% |********************************|   110  0:00:00 ETA
# written to stdout
# <html>
# <title>Home</title>

# <body>
#     <h1>Home</h1>
#     <p>this is the home page</p>
# </body>

# service ip: 10.111.110.150
kubectl get svc -A
# NAMESPACE              NAME                                   TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                  AGE
# default                nginx-svc                              ClusterIP   10.111.110.150   <none>        8080/TCP                 43m

# env var: set the service ip
kubectl exec -it nginx -- env | sort
# NGINX_SVC_PORT_8080_TCP_ADDR=10.111.110.150
# NGINX_SVC_PORT_8080_TCP_PORT=8080
# NGINX_SVC_PORT_8080_TCP_PROTO=tcp
# NGINX_SVC_PORT_8080_TCP=tcp://10.111.110.150:8080
# NGINX_SVC_PORT=tcp://10.111.110.150:8080
# NGINX_SVC_SERVICE_HOST=10.111.110.150
# NGINX_SVC_SERVICE_PORT_HTTP=8080
# NGINX_SVC_SERVICE_PORT=8080
# kube-dns ip: 10.96.0.10
kubectl get svc -A
# NAMESPACE              NAME                                   TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                  AGE
# kube-system            kube-dns                               ClusterIP   10.96.0.10       <none>        53/UDP,53/TCP,9153/TCP   52d

# resolve sets nameserver==dns
kubectl exec -it nginx -- cat /etc/resolv.conf
# nameserver 10.96.0.10
# search default.svc.cluster.local svc.cluster.local cluster.local
# options ndots:5