K8S implementation of gray-scale publishing based on ingress nginx

Previously introduced Gray publishing with ambassador , how to use the implementation of ingre nginx.

introduce

Ingress nginx is a K8S ingress tool, which supports the configuration of Ingress Annotations to achieve gray-scale publishing and testing in different scenarios.   Nginx Annotations Four Canary rules are supported:

  • nginx.ingress.kubernetes.io/canary-by-header: traffic segmentation based on Request Header, applicable to gray-scale publishing and A/B testing. When the Request Header is set to always, the request will be sent all the way to the Canary version; when the Request Header is set to never, the request will not be sent to the Canary entry; for any other Header value, the Header will be ignored, and the request will be compared with other Canary rules by priority.
  • nginx.ingress.kubernetes.io/canary-by-header-value: the value of the request header to be matched, which is used to inform Ingress to route the request to the service specified in Canary Ingress. When the request header is set to this value, it is routed to the Canary entry. This rule allows the user to customize the value of the Request Header and must be used with the previous annotation (i.e., canary-by-header).
  • nginx.ingress.kubernetes.io/canary-weight: traffic segmentation based on service weight, which is applicable to blue-green deployment, and the weight range is 0-100 to route the request to the service specified in Canary Ingress by percentage. A weight of 0 means that the Canary rule does not send any requests to the service at the Canary portal. 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 gray-scale publishing and A/B testing. A cookie used to notify Ingress to route requests to the service specified in Canary Ingress. When the cookie value is set to always, it will be routed to the Canary entry; when the cookie value is set to never, the request will not be sent to the Canary entry; for any other value, the cookie will be ignored and the request will be compared with the priority of other Canary rules.

Note: Canary rules are sorted in the following order of priority:

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

We can divide the above four annotation rules into the following two categories as a whole:

  • Canary rule based on weight

  • Canary rule based on user request

Note: ingress nginx is the Canary function introduced in version 0.21.0, so make sure that the version of ingress is OK

test

Application preparation

Two versions of service, normal version:

import static java.util.Collections.singletonMap;

@SpringBootApplication
@Controller
public class RestPrometheusApplication {

	@Autowired
	private MeterRegistry registry;

	@GetMapping(path = "/", produces = "application/json")
	@ResponseBody
	public Map<String, Object> landingPage() {
		Counter.builder("mymetric").tag("foo", "bar").register(registry).increment();
		return singletonMap("hello", "ambassador");
	}

	public static void main(String[] args) {
		SpringApplication.run(RestPrometheusApplication.class, args);
	}

}

Access will output:

{"hello":"ambassador"}	

Grayscale version:

import static java.util.Collections.singletonMap;

@SpringBootApplication
@Controller
public class RestPrometheusApplication {

	@Autowired
	private MeterRegistry registry;

	@GetMapping(path = "/", produces = "application/json")
	@ResponseBody
	public Map<String, Object> landingPage() {
		Counter.builder("mymetric").tag("foo", "bar").register(registry).increment();
		return singletonMap("hello", "ambassador, this is a gray version");
	}

	public static void main(String[] args) {
		SpringApplication.run(RestPrometheusApplication.class, args);
	}

}

Access will output:

{"hello":"ambassador, this is a gray version"}	

ingress configuration

We have deployed two services. Springboot rest demo is a normal service, and springboot rest demo gray is a gray-scale service. Let's configure ingress and implement it through Canary by header:

Normal service:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: springboot-rest-demo
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: springboot-rest.jadepeng.com
    http:
      paths:
      - backend:
          serviceName: springboot-rest-demo
          servicePort: 80

canary's:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: springboot-rest-demo-gray
  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: "true"
spec:
  rules:
  - host: springboot-rest.jadepeng.com
    http:
      paths:
      - backend:
          serviceName: springboot-rest-demo-gray
          servicePort: 80

Execute the above file:

kubectl -n=default apply -f ingress-test.yml 
ingress.extensions/springboot-rest-demo created
ingress.extensions/springboot-rest-demo-gray created

Execute the test without adding the header. The default access is the official version:

# curl http://springboot-rest.jadepeng.com; echo
{"hello":"ambassador"}
# curl http://springboot-rest.jadepeng.com; echo
{"hello":"ambassador"}

Add a header. You can see that the gray version is accessed

# curl -H "canary: true" http://springboot-rest.jadepeng.com; echo
{"hello":"ambassador, this is a gray version"}

Multi instance Ingress controllers

reference resources

Keywords: Programming Nginx SpringBoot REST Kubernetes

Added by 1042 on Wed, 13 May 2020 09:58:48 +0300