One service manages multiple deployment instances. Service uses nodePort type. Uneven traffic load

24 views Asked by At

Due to business requirements, a single Service is needed to manage multiple deployments for a simple grayscale scheme. When I associated a deployment tag change to an existing Service, I found that the traffic was skewed. Traffic access path: nginx --> Service nodePort --> deployment1 |--> deployment2

It was found that when grayscale a new deployment pod, severe traffic skew occurred. Recurrence scheme first run with deployment-1, the traffic is load balanced, but when deployment-2 is enabled, the traffic will tilt. Simulation request

for i in seq 1 10000;do sleep 1 ; curl -s http://10.4.83.27:8081/ ;done | tee /tmp/1.log

First time cat /tmp/12.log | grep http-deployment-1 | wc -l 94 cat /tmp/12.log | grep http-deployment-2 | wc -l 6

Try again cat /tmp/13.log | grep http-deployment-2 | wc -l 378 cat /tmp/13.log | grep http-deployment-1 | wc -l 622

Upstream load balancing configuration

upstream backend {
    server 10.4.87.33:33632;
    server 10.4.87.34:33632;
    server 10.4.87.35:33632;
    keepalive 300;
}

server {
    listen 8081;
    server_name ljohn.com;

    location / {
        proxy_pass http://backend;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
    }
}

deployment-1

Deployment 2

apiVersion: apps/v1
kind: Deployment
metadata:
  annotations: {}
  name: http-deployment-1
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
      deployment: one
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: nginx
        deployment: one
    spec:
      containers:
        - image: nginx:1.20.1
          imagePullPolicy: IfNotPresent
          name: http
          ports:
            - containerPort: 80
              protocol: TCP
          volumeMounts:
            - name: nginx-config
              mountPath: /etc/nginx/conf.d
            - name: html-files
              mountPath: /usr/share/nginx/html
      volumes:
        - name: nginx-config
          configMap:
            name: nginx-config
        - name: html-files
          configMap:
            name: html-files-config-one
---
# ConfigMap for NGINX configuration
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-config
data:
  default.conf: |
    server {
      listen 80;
      server_name localhost;

      access_log /var/log/nginx/access.log;
      error_log /var/log/nginx/error.log;

      location / {
        root /usr/share/nginx/html;
        index index.html;
      }
    }
---
# ConfigMap for HTML file
apiVersion: v1
kind: ConfigMap
metadata:
  name: html-files-config-one
data:
  index.html: |
    <!DOCTYPE html>
    <html>
    <head>
      <title>Deployment Name</title>
    </head>
    <body>
      <h1>Deployment Name: http-deployment-1</h1>
    </body>
    </html>
---
# Service
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: NodePort

deployment-2

# Deployment 2
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations: {}
  name: http-deployment-2
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
      deployment: two
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: nginx
        deployment: two
    spec:
      containers:
        - image: nginx:1.20.1
          imagePullPolicy: IfNotPresent
          name: http
          ports:
            - containerPort: 80
              protocol: TCP
          volumeMounts:
            - name: nginx-config
              mountPath: /etc/nginx/conf.d
            - name: html-files
              mountPath: /usr/share/nginx/html
      volumes:
        - name: nginx-config
          configMap:
            name: nginx-config
        - name: html-files
          configMap:
            name: html-files-config-two
---
# ConfigMap for NGINX configuration
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-config
data:
  default.conf: |
    server {
      listen 80;
      server_name localhost;

      access_log /var/log/nginx/access.log;
      error_log /var/log/nginx/error.log;

      location / {
        root /usr/share/nginx/html;
        index index.html;
      }
    }
---
# ConfigMap for HTML file
apiVersion: v1
kind: ConfigMap
metadata:
  name: html-files-config-two
data:
  index.html: |
    <!DOCTYPE html>
    <html>
    <head>
      <title>Deployment Name</title>
    </head>
    <body>
      <h1>Deployment Name: http-deployment-2</h1>
    </body>
    </html>
---
# Service
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: NodePort
0

There are 0 answers