使用helm在Kubernetes集群中部署Kong
2020-06-03
本文将使用helm在Kubernetes集群中部署微服务API网关kong,并将其用作Kubernetes的Ingress Controller。
Kong官方单独维护了一个项目叫Kong for Kubernetes
,项目的地址是https://github.com/Kong/kubernetes-ingress-controller。
Kong for Kubernetes
是一个Kubernetes的Ingress Controller,通过插件架构提供API管理能力。
Kong官方另外提供了一个Helm Chart,使用Helm安装这个Chart可以在Kubernetes集群上运行Kong所需的所有组件。
使用helm部署在Kubernetes集群中部署kong for kubernetes,需要先添加kong的chart repo:
1helm repo add kong https://charts.konghq.com
2helm repo update
接下来需要针对所部署的Kubernetes环境定制配置,可以参考kong helm chart的配置文档https://github.com/Kong/charts/blob/main/charts/kong/README.md, 也可以使用下面的命令打印chart的默认配置再参考默认配置结合部署环境做出定制:
1helm show values kong/kong
这里先做最基本的安装,目标是基本实现与nginx ingress controller相同的功能,kong对API管理的高级功能后边再单独详细介绍。
根据最基本安装的目标对配置定制如下,创建kong-values.yaml
文件:
1ingressController:
2 ingressClass: kong
3postgresql:
4 enabled: false
5
6proxy:
7 http:
8 hostPort: 80
9 tls:
10 hostPort: 443
11
12nodeSelector:
13 node-role.kubernetes.io/edge: ''
14affinity:
15 podAntiAffinity:
16 requiredDuringSchedulingIgnoredDuringExecution:
17 - labelSelector:
18 matchExpressions:
19 - key: app.kubernetes.io/instance
20 operator: In
21 values:
22 - kong
23 - key: app.kubernetes.io/name
24 operator: In
25 values:
26 - kong
27 topologyKey: kubernetes.io/hostname
28tolerations:
29 - key: node-role.kubernetes.io/master
30 operator: Exists
31 effect: NoSchedule
32 - key: node-role.kubernetes.io/master
33 operator: Exists
34 effect: PreferNoSchedule
上面的配置指定kong以dbless模式部署,并指定ingressClass为空,另外做了Pod调度相关配置。
使用下面的命令安装:
1helm install ingress-kong kong/kong --create-namespace -n ingress-kong -f kong-values.yaml
安装完成后,查看可以看出默认以Deployment部署,同时创建了Type为LoadBalancer的service kong-kong-proxy并暴露了30444和30079两个NodePort分别对应http和https协议, 由云提供商外部负载均衡器将流量路由到自动创建的两个NodePort上。
1kubectl get all -n ingress-kong
2NAME READY STATUS RESTARTS AGE
3pod/ingress-kong-kong-554f65c956-44xlq 2/2 Running 0 2m11s
4
5NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
6service/ingress-kong-kong-proxy LoadBalancer 10.98.63.185 <pending> 80:31374/TCP,443:32492/TCP 2m11s
7
8NAME READY UP-TO-DATE AVAILABLE AGE
9deployment.apps/ingress-kong-kong 1/1 1 1 2m11s
10
11NAME DESIRED CURRENT READY AGE
12replicaset.apps/ingress-kong-kong-554f65c956 1 1 1 2m11s
因为这里使用的Kubernetes集群并没有cloud provider,所以上面ingress-kong-kong-proxy
的EXTERNAL-IP
一直处于pending
状态,不过没有关系,helm在安装时的定制配置中开启了
http和https的两个hostPort,而且通过podAntiAffinity限制Pod在调度时相同的两个Pod不会调度到同一个Node上,所以我们可以使用http//edgeNodeIp
和https//edgeNodeIp
的形式来访问kong的proxy服务。
ingress-kong-kong-554f65c956-44xlq这个Pod中有两个容器,一个是Proxy即kong本身,另一个是kong ingress controller。
1curl http://192.168.100.101
2{"message":"no Route matched with those values"}
在node上使用netstat -nltp
查看发现并没有监听80和443端口,而可以使用hostPort直接访问的原因是因为,是k8s帮我们创建了hostPort到containerPort的nat,可以下面的命令查看:
1kubectl get pod -n ingress-kong -o wide
2NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
3ingress-kong-kong-554f65c956-44xlq 2/2 Running 0 14m 10.244.166.136 node1 <none> <none>
4
5iptables -nvL -t nat | grep DNAT | grep 10.244.166.136
6 2 120 DNAT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 to:10.244.166.136:8000
7 2 128 DNAT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:443 to:10.244.166.136:8443
我们已经完成kong ingress controller的安装,注意这里使用的Kubernetes集群中并没有安装其他的ingress controller(如nginx ingress controller),如果需要在集群中安装多个不同的ingress controller 还需要做特别的配置和避免冲突,k8s的ingress文档https://kubernetes.io/docs/concepts/services-networking/ingress/中有这部分内容描述(例如IngressClass资源),这里不再展开,后边有机会再详细介绍。
到目前为止我们已经在Kubernetes集群中部署了Kong for Kubernetes
这个Ingress Controller,下面我们来创建Ingress尝试使用它。
我们使用它来将k8s的dashbaord暴露到集群外部,创建k8s dashbaord的ingress如下:
1apiVersion: networking.k8s.io/v1
2kind: Ingress
3metadata:
4 annotations:
5 kubernetes.io/ingress.class: kong
6 konghq.com/protocols: "https"
7 name: kubernetes-dashboard
8 namespace: kube-system
9spec:
10 rules:
11 - host: k8s.example.com
12 http:
13 paths:
14 - backend:
15 service:
16 name: kubernetes-dashboard
17 port:
18 number: 443
19 path: /
20 pathType: Prefix
21 tls:
22 - hosts:
23 - k8s.example.com
24 secretName: example-com-tls-secret
因为后端k8s dashboard使用的是https,所以还需要修改k8s dashbaord的service加入konghq.com/protocol: https
这个annotation。
关于kong ingress的配置注解可以查看文档。完成以上配置后,访问https://k8s.example.com
可以正常打开k8s dashboard。k8s dashboard的由kong暴露到k8s集群外部。
到这里,我们已经完成Kong for Kubernetes
最简单的基本部署,实现了与nginx ingress controller相同的功能,kong对API管理的高级功能这是nginx ingress controller不具备的,后边单独展开。