package main
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
r.GET("/app", func(context *gin.Context) {
context.JSON(200, gin.H{"message": "app1"})
})
r.Run(":8080")
}
FROM golang:1.17.13
RUN mkdir -p /go/app/; \
cd /go/app/; \
go mod init app1;\
GOPROXY="https://goproxy.cn,direct" go get github.com/gin-gonic/gin@v1.6.3
WORKDIR /go/app/
COPY main.go /go/app
EXPOSE 8080
CMD go run main.go
apiVersion: apps/v1
kind: Deployment
metadata:
name: goapp1
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: goapp1
template:
metadata:
labels:
app: goapp1
spec:
containers:
- image: goapp1:v1
imagePullPolicy: IfNotPresent
name: goapp1
ports:
- containerPort: 80
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: goapp1
namespace: default
spec:
ports:
- port: 8080
protocol: TCP
targetPort: 8080
selector:
app: goapp1
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: goapp1
namespace: default
annotations:
kubernetes.io/ingress.class: nginx
spec:
rules:
- host: test.com
http:
paths:
- path: /app
pathType: Prefix
backend:
service:
name: goapp1
port:
number: 8080
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: goapp2
namespace: default
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-by-header: canary
spec:
rules:
- host: test.com
http:
paths:
- path: /app
pathType: Prefix
backend:
service:
name: goapp2
port:
number: 8080
for i in {1..20};
# ingress-nginx的NodePort请自行查看,替换下面的端口
do curl test.com:31132/app -H "canary: never"; # 路由至稳定版本的goapp1
echo -e "";
done
for i in {1..20};
do curl test.com:31132/app -H "canary: always"; # 路由至canary版本的goapp2
echo -e "";
done

kubectl edit cm ingress-nginx-controller
------------------
apiVersion: v1
data:
allow-snippet-annotations: "true"
# 添加下面这两个参数
enable-underscores-in-headers: "true"
ignore-invalid-headers: "false"
kind: ConfigMap
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.24.0
ports:
- containerPort: 80
volumeMounts:
- name: nginx
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
volumes:
- name: nginx
configMap:
name: nginx
items:
- key: nginx.conf
path: nginx.conf
---
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: default
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
---
apiVersion: v1
data:
nginx.conf: |
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
upstream upstream_server1 {
server goapp1:8080;
}
upstream upstream_server2 {
server goapp2:8080;
}
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" "$http_my_header"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
server {
underscores_in_headers on;
listen 80;
server_name test.com;
location /app {
if ($http_my_header = "value1") {
proxy_pass http://upstream_server1;
}
if ($http_my_header = "value2") {
proxy_pass http://upstream_server2;
}
}
}
}
kind: ConfigMap
metadata:
name: nginx
namespace: default
curl test.com/app -H "my_header:value1"
curl test.com/app -H "my_header:value2"
