K8s exposed port and proxy mode

Posted by optiplex on Sun, 26 Dec 2021 06:31:10 +0100

K8s exposed port and proxy mode

How kubernetes exposes ports

Method 1: clusterIP
This type provides a virtual IP within the cluster (not in the same network segment as the pod) for communication between pods within the cluster. clusterIP is also the default type of kubernetes service
The following components are required to work together
apiservice: when creating a service, apiserver stores the data in etcd after receiving the request.
Kube proxy: each node of k8s has this process, which is responsible for realizing the service function. This process is responsible for sensing the changes of service and pod and writing the changed information into the local iptables
iptables: use NAT and other technology awards to transfer the traffic of virtuallp to the endpoint

Mode 2: NodePort
In addition to using cluster ip, the nodeport mode also maps the port of the service to a specified internal port of each node. The mapped internal ports of each node are the same. Expose a port for each node. You can access this service through nodeIP+nodeport. At the same time, the service will still have cluster type ip+port. Internal access is through clusterip and external access is through nodeport

Method 3: loadbalancer
On the basis of nodeport, k8s the loadbalancer can request the underlying cloud platform to create a load balancer, and use each node as the back end for service distribution. This mode requires the support of the underlying cloud platform (such as GCE)

Mode 4: lngress
lngress is an http routing and forwarding mechanism, which is composed of lngress controller and http proxy server. The instance of lngress controller monitors kubernetes api and updates the forwarding rules of http proxy server in real time. http proxy server has GCE load balancer, haproxy, nginx and other open source solutions

Service is an abstract concept, which defines the logical collection of multiple pods of a service and the policy of accessing pod. Generally, service is called micro service For example, a service runs three pods. How does service b access the pod of service a? The ip address of the pod is not persistent. It will change after restart. At this time, service b can access the service bound to service a. the service information is fixed. Just tell b in advance. The service is bound to the pod of service a through the Label Selector. No matter how the pod of service a changes, it is transparent to b

kubernetes proxy mode

Each node in the k8s cluster runs a Kube proxy component, which is actually a proxy layer responsible for implementing services There are two Kube proxy modes:

Proxy mode: userspace

The client access service IP (clusterIP) request will first go from the user space to iptables in the kernel, and then return to the user space Kube proxy, which is responsible for the proxy work. Specific details:
For each service, Kube proxy will set up a random proxy port on the node node. iptables will capture the port (targetPort) traffic on the clusterIP and redirect the proxy port. Any connection accessing the proxy port will be proxy to a pod at the back end of the service. By default, polling is selected for the back-end pod

Picture 1

Proxy mode: iptables

Client access service IP (clusterIP) requests will be redirected directly to the back end by iptables. Specific details: each service will generate a set of iptables rules by Kube proxy. Iptables will capture the port (targetPort) traffic on the clusterIP and redirect a pod at the back end. By default, the selection of pod is random

Picture 2

​ Kubernetes v1.2 before, the default is userspace, followed by iptables mode. Iptables mode has better performance and reliability, but iptables mode depends on health check. If one pod does not respond without health check, iptables mode will not switch to another pod

Type of service

  • ClusterIP is the default mode and can only be accessed within the cluster
  • NodePort listens to the same port number (30000-32767) on each node, and ClusterIP and routing rules will be created automatically.
  • LoadBalancer uses external load balancing. In fact, it is also a NodePort, but it will automatically add: to the load balancing of the public cloud
  • ExternalName creates a dns alias to the service name, which is mainly used to prevent the service name from changing. It should be used in conjunction with the dns plug-in

Practical operation

1. Create a deployment replica with 3 copies, then scroll to update the image version, record the update record, and finally roll back to the previous version

[root@master kubenetres]# vim test.yml 
[root@master kubenetres]# cat test.yml 
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: test01
  name: test
spec:
  replicas: 3
  selector:
    matchLabels:
      app: test01
  template:
    metadata:
      labels:
        app: test01
    spec:
      containers:
      - image: 1225514226/httpd
        name: test
        
#Create a pod of type deployment
[root@master kubenetres]# kubectl apply -f test.yml 
deployment.apps/test created

#see
[root@master kubenetres]# kubectl get pod
NAME                   READY   STATUS    RESTARTS   AGE
test-c9dcccb69-tz8zj   1/1     Running   0          2m54s
test-c9dcccb69-v9jjw   1/1     Running   0          2m54s
test-c9dcccb69-xf4gl   1/1     Running   0          2m54s

#Upgrade (kubectl set image deployment.apps/{deployment name} {image name}: = {image name}: {version})
[root@master kubenetres]# kubectl set image deploy/test test=nginx:v0.1 
deployment.apps/test image updated

#See if you are upgrading
[root@master kubenetres]# kubectl get pod
NAME                    READY   STATUS              RESTARTS   AGE
test-7b9f664684-ddllz   1/1     Running             0          107s
test-7b9f664684-hcfqp   0/1     ContainerCreating   0          10s
test-c9dcccb69-4clhj    1/1     Terminating         0          9m
test-c9dcccb69-dqlg2    1/1     Running             0          9m
test-c9dcccb69-w8q7c    1/1     Running             0          9m

[root@master kubenetres]# kubectl get deployment
NAME   READY   UP-TO-DATE   AVAILABLE   AGE
test   3/3     2            3           10m

#RollBACK 
#By default, the online records of the Deployment will be kept in the system so that you can roll back at any time and view the online history of the Deployment:
[root@master kubenetres]# kubectl rollout history deployment test
deployment.apps/test 
REVISION  CHANGE-CAUSE
1         <none>
2         <none>

#View a version
[root@master kubenetres]# kubectl rollout history deployment test --revision=2
deployment.apps/test with revision #2
Pod Template:
  Labels:       app=test01
        pod-template-hash=7b9f664684
  Containers:
   test:
    Image:      best2001/httpd:v0.1
    Port:       <none>
    Host Port:  <none>
    Environment:        <none>
    Mounts:     <none>
  Volumes:      <none>
  
#Rollback to previous version
[root@master kubenetres]# kubectl rollout undo deployment test --to-revision=1
deployment.apps/test rolled back
[root@master kubenetres]# kubectl rollout history deployment test
deployment.apps/test 
REVISION  CHANGE-CAUSE
2         <none>
3         <none>

2. The number of replicas for an application is 3

[root@master kubenetres]# kubectl scale deploy/test --replicas=3
[root@master kubenetres]# kubectl get pod
NAME                   READY   STATUS        RESTARTS   AGE
test-c9dcccb69-9zvc9   1/1     Running       0          8m3s
test-c9dcccb69-gd94h   1/1     Running       0          7m44s
test-c9dcccb69-jdmhl   1/1     Running       0          7m38s
test-c9dcccb69-l6wg5   1/1     Terminating   0          119s
test-c9dcccb69-wqjfk   1/1     Terminating   0          119s

3. Create a pod with three containers running nginx, redis and memcached

[root@master kubenetres]# vim test.yml 
[root@master kubenetres]# cat test.yml 
apiVersion: v1
kind: Pod
metadata:
  name: test
  labels:
    app: test01
spec:
  containers:
  - image: nginx
    name: nginx
  - image: redis
    name: redis
  - image: memcached
    name: memcached
[root@master kubenetres]# kubectl apply -f test.yml 
pod/test created
[root@master kubenetres]# kubectl get pod
NAME   READY   STATUS    RESTARTS   AGE
test   3/3     Running   0          47s

4. Create a service for a pod and access it through ClusterlP/NodePort

[root@master kubenetres]# vim test.yml 
[root@master kubenetres]# cat test.yml 
---
apiVersion: v1
kind: Pod
metadata:
  name: test
  labels:
    app: test01
spec:
  containers:
  - image: 1225514226/nginx:v0.3 
    name: nginx

---
apiVersion: v1
kind: Service
metadata:
  name: nginx
  namespace: default
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: test01
  type: NodePort
  
[root@master kubenetres]# kubectl apply -f test.yml 
pod/test created
service/nginx created
[root@master kubenetres]# kubectl get pod,svc
NAME       READY   STATUS    RESTARTS   AGE
pod/test   1/1     Running   0          16s

NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
service/nginx        NodePort    10.100.135.23   <none>        80:31762/TCP   16s

#ClusterIP access
[root@master kubenetres]# curl 10.100.135.23
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
···Omitted part····

#NodePort access
[root@master kubenetres]# curl 192.168.240.30:31762
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
···Omitted part····

5. Create deployment and service, and use busybox container nslookup to resolve the service

[root@master kubenetres]# kubectl run test1  --image=busybox:1.28.4 -- sleep 24h
pod/test1 created
[root@master kubenetres]# kubectl get pods
NAME    READY   STATUS    RESTARTS   AGE
test    1/1     Running   0          10m

[root@master kubenetres]# kubectl exec -it test1 -- /bin/sh
/ # nslookup kubernetes
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      kubernetes
Address 1: 10.96.0.1 kubernetes.default.svc.cluster.local

[root@master kubenetres]# kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP        3d21h

Topics: Operation & Maintenance Docker Kubernetes