Ingress-nginx is a K8S Ingress controller that supports configuring Ingress Annotations for grayscale publishing and testing in different scenarios. Nginx Annotations support the following four Canary rules:

  • nginx.ingress.kubernetes.io/canary-by-header: Traffic segmentation based on Request Header, suitable for grayscale publishing and A/B testing. When Request Header is set toalwaysThe request will be sent all the way to the Canary version; When Request Header is set toneverThe request is not sent to the Canary inlet; For any other Header values, the Header is ignored and the request is compared to the other Canary rules by priority.
  • nginx.ingress.kubernetes.io/canary-by-header-value: The value of the Request Header to match to notify the Ingress to route the Request to the service specified in the Canary Ingress. When the Request Header is set to this value, it will be routed to the Canary entry. This rule allows the user to customize the value of the Request Header, which must be used in conjunction with the previous annotation (that is, canary-by- Header).
  • nginx.ingress.kubernetes.io/canary-weight: Traffic segmentation based on service weight, applicable to blue-green deployment. The weight range is 0 to 100. Requests are routed to the service specified in Canary Ingress in percentage. A weight of 0 means that the Canary rule does not send any requests to the service that Canary enters. A weight of 100 means that all requests will be sent to the Canary entry.
  • nginx.ingress.kubernetes.io/canary-by-cookie: Cookie-based traffic segmentation, suitable for grayscale publishing and A/B testing. Cookie used to notify the Ingress to route the request to the service specified in the Canary Ingress. When cookie value is set toalways“, it will be routed to the Canary entry; When cookie value is set toneverThe request is not sent to the Canary inlet; For any other value, the cookie is ignored and the request is compared to the other canary rules in priority.

Note: The Canary rules are arranged in the following order of priority:

canary-by-header - > canary-by-cookie - > canary-weight

Minikube configuration

Open the nginx – ingress

Since I am using minikube to set up the cluster environment, I first need to enable the nginx-ingress controller in minikube. You can run the following command

minikube addons enable ingress
Copy the code

Add docker private repository access credentials

First, our K8S needs to pull the image under its own domain from Docker Hub, and we must generate a credential.

  • Login docker
Docker login -u User nameCopy the code
  • Create Secret for the K8S cluster
Kubectl -n default create secret docker-registry registry-key \ kubectl -n default create secret docker-registry registry-key \ --docker-server=hub.docker.com --docker-username=docker account --docker-password=docker account password [email protected]Copy the code

Notice -n default indicates the specified namespace. You are advised to create a namespace to isolate resources when building a K8S cluster.

Then, in the K8S console, you can see the Secret we just created, see Pulling the mirror from the private repository for details

Then configure imagePullSecrets as registry-key in our Deplyment

The normal version

  • Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: product-app
spec:
  selector:
    matchLabels:
      app: product-app
  replicas: 1
  template:
    metadata:
      labels:
        app: product-app
    spec:
      imagePullSecrets:
        - name: registry-key
      containers:
        - name: product-app
          image: djlxs/gray-app:v2
          ports:
            - containerPort: 80
Copy the code
  • Service
apiVersion: v1
kind: Service
metadata:
  name: product-app
spec:
  selector:
    app: product-app
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: NodePort
Copy the code
  • Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
 name: product-app
 annotations:
   kubernetes.io/ingress.class: nginx
spec:
 rules:
   - host: app-ingress.info
     http:
       paths:
       - backend:
           service:
             name: product-app
             port:
               number: 80
         path: /
         pathType: Prefix
Copy the code

Grayscale version

  • Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: gray-app
spec:
  selector:
    matchLabels:
      app: gray-app
  replicas: 1
  template:
    metadata:
      labels:
        app: gray-app
    spec:
      imagePullSecrets:
        - name: registry-key
      containers:
        - name: gray-app
          image: djlxs/gray-app:v1
          ports:
            - containerPort: 80
Copy the code
  • Service
apiVersion: v1
kind: Service
metadata:
  name: gray-app
spec:
  selector:
    app: gray-app
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: NodePort
Copy the code
  • Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: gray-app
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-header: "canary"
    nginx.ingress.kubernetes.io/canary-by-header-value: "canary"
spec:
  rules:
    - host: app-ingress.info
      http:
        paths:
        - backend:
            service:
              name: gray-app
              port:
                number: 80
          path: /
          pathType: Prefix
Copy the code

test

curl http://app-ingress.info
Copy the code
curl http://app-ingress.info -H "canary:canary"
Copy the code

The resources

Nginx Annotations pulls a mirror from a private repository