最近把一套K8S集群的Nginx Ingress Controller从v0.33升级到了v1.0.5,属于主版本升级,在这里整理一下升级的过程和遇到的问题。 这套k8s集群的信息如下:

  • k8s版本为v1.21.5
  • 使用Ingress将集群外部http流量接入到集群内部,当前集群中共有三十多个Ingress资源
  • ingress controller使用的是https://github.com/kubernetes/ingress-nginx/,版本是v0.33,基于yaml文件格式的Manifest部署

升级前的准备工作

修改集群中的Ingress资源使其与1.x版本的Nginx Ingress Controller以及后续版本的k8s(>=1.22)兼容,修改主要涉及两个方面:

  • 将集群中Ingress资源还在使用apiVersion: networking.k8s.io/v1beta1的API版本修改到apiVersion: networking.k8s.io/v1networking.k8s.io/v1beta1 API从k8s 1.19被标记为废弃,将在k8s 1.22被移除。借着这次升级ingress controller的机会,将集群中的Ingress的API版本统一更新一下。
  • 将集群中所有Ingress资源的Manifest的spec下加入: ingressClassName: nginx。从Nginx Ingress Controller 1.0.0开始,安装Nginx Ingress Controller需要一个IngressClass对象,这样集群中的Ingress资源就可以配置使用不同的Ingress Controller。

下面是一个具体的Ingress示例,apiVersion指定了networking.k8s.io/v1了,ingressClassName: nginx指定了这个Ingress将使用名称为nginx的IngressClass对应的Ingress Controller:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: kubernetes-dashboard
  namespace: kube-system
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - k8s.example.com
    secretName: example-com-tls-secret
  rules:
  - host: k8s.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
           name: kubernetes-dashboard
           port:
             number: 443

升级Nginx Ingress Controller

因为旧的v0.33版本的Nginx Ingress Controller是基于yaml文件格式的Manifest部署,新的v1.0.5版本想用helm来部署。在升级前使用kubectl delete命令删除v0.33的资源,注意这会导致集群中的Ingress暴露的应用无法访问,所以升级操作在晚上进行,使用helm安装v1.0.5操作同步进行。

helm chart使用的是提前从https://github.com/kubernetes/ingress-nginx/releases下载的ingress-nginx-4.0.9.tgz。需要针对你的集群定制一个这个chart的Values文件values.yaml:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
imagePullSecrets: 
- name: regsecret

controller:
  config:
    use-forwarded-headers: "true"
    proxy-set-headers: "ingress-nginx/custom-headers"
  updateStrategy:
    rollingUpdate:
      maxUnavailable: 1
    type: RollingUpdate
  ingressClassResource:
    name: nginx
    enabled: true
    default: false
    controllerValue: "k8s.io/ingress-nginx"
  admissionWebhooks:
    enabled: false
  replicaCount: 3
  image:
    registry: registry.example.com
    image: image/nginx-ingress-controller
    tag: "v1.0.5"
    digest: sha256:bc30cb296e7548162afd9601f6b96261dcca8263e05b962694d1686b4d5a9584
  hostNetwork: true
  nodeSelector:
    node-role.kubernetes.io/edge: ''
  affinity:
    podAntiAffinity:
        requiredDuringSchedulingIgnoredDuringExecution:
        - labelSelector:
            matchExpressions:
            - key: app
              operator: In
              values:
              - nginx-ingress
            - key: component
              operator: In
              values:
              - controller
          topologyKey: kubernetes.io/hostname
  tolerations:
      - key: node-role.kubernetes.io/master
        operator: Exists
        effect: NoSchedule
      - key: node-role.kubernetes.io/master
        operator: Exists
        effect: PreferNoSchedule

定制的Values文件由以下基本分组成:

  • 1~2行为从私有镜像库registry.example.com拉取镜像的image pull secret的名称,对应的secret需要提前创建好
  • 5~7行为往nginx ingress controller的ConfigMap中添加的配置信息,更多的配置可以从https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/中找到
  • 12~16行为nginx ingress controller所需的IngressClass资源配置,这里配置表示创建了名称为nginx的IngressClass,并绑定k8s.io/ingress-nginxController即IngressClass nginx对应nginx ingress controller
  • 20~24行指定nginx ingress controller的私有镜像库及地址
  • 25行指定controller的网络使用hostNetwork。通过26行~48行调度相关的配置,在我们的集群中将3个controller的pod实例调度到集群中三台角色为edge的专门用来运行controller的k8s node上

安装命令如下:

1
helm install ingress-nginx ingress-nginx-4.0.9.tgz --history-max 5 --create-namespace -n ingress-nginx -f values.yaml

安装后,如果values.yaml有更新,使用下面的命令更新:

1
helm upgrade ingress-nginx ingress-nginx-4.0.9.tgz --history-max 5 -n ingress-nginx -f values.yaml

参考