极客时间《Kubernetes 入门实战课》之《加餐分享 (2讲)》

📅 2026/8/20 14:58:49
极客时间《Kubernetes 入门实战课》之《加餐分享 (2讲)》
全笔记《开篇词 (2讲)》《入门篇 (8讲)》《初级篇 (9讲)》《中级篇 (8讲)》《高级篇 (10讲)》《加餐分享 (2讲)》Kubernetes英文博客考虑扩展学习Helm运维多个 k8s 集群OpenLens 、Rancher目录《加餐谈谈Kong Ingress Controller》《加餐尝鲜Gateway API更强大、更灵活、面向未来的Ingress》《加餐谈谈Kong Ingress Controller》认识 Kong Ingress Controller我们已经见过了 Nginx 官方开发的 Nginx Ingress Controller但它局限于 Nginx 自身的能力Ingress、Service 等对象更新时必须要修改静态的配置文件再重启进程reload在变动频繁的微服务系统里就会引发一些问题。而今天要说的 Kong Ingress Controller则是站在了 Nginx 这个巨人的肩膀之上基于 OpenResty 和内嵌的 LuaJIT 环境实现了完全动态的路由变更消除了 reload 的成本运行更加平稳而且还有很多额外的增强功能安装 Kong Ingress Controller下载wget https://github.com/Kong/kubernetes-ingress-controller/archive/refs/tags/v2.7.0.tar.gz然后解压缩可选择相对简单的无数据库部署方式在deploy目录下有一个 all-in-one-dbless.yaml。安装之后Kong Ingress Controller 会创建一个新的名字空间kong里面有一个默认的 Ingress Controller还有对应的 Service在 kubectl get pod 输出的READY列里显示的是“2/2”意思是这个 Pod 里有两个容器。尝试访问一下 Kong Ingress Controller我们还可以用 kubectl exec 命令进入 Pod查看它的内部信息《加餐尝鲜Gateway API更强大、更灵活、面向未来的Ingress》长期以来被关注的“下一代” Ingress 对象Gateway API在经过了近 4 年的讨论、测试和验证之后终于在 2023 年的 11 月正式发布可以用于生产环境也就是我们常说的 GAgenerally available。什么是 Gateway API同一个功能在不同的 Ingress Controller 之间用法差异极大迁移的成本非常高没有统一的标准导致 Ingress 使用起来相当麻烦。在 2023 年 11 月发布的Gateway API 1.0 版本里包括 3 个已经成熟稳定的对象Gateway Class、Gateway 和 HTTPRoute。Gateway API is an official Kubernetes project focused on L4 and L7 routing in Kubernetes.最上层的 Gateway Class 类似于 Ingress Class由各个云厂商提供中间的 Gateway 类似于 Ingress Controller由集群管理员管理下面的 HTTPRoute 类似于 Ingress由开发人员管理定义路由规则规定流量将如何被 Gateway 分发到集群里的 Service 和 Pod。下面以 Kong 为例来介绍 Gateway API 的用法。安装 Gateway APIGateway API 只支持较新的 Kubernetes比如1.28.3不能运行在 Kubernetes 1.23。升级minikube学习第9节时我在某台机器上安装过老版本的minikube。现在我回到这台机器下载更新版本的minikubecurl-Lominikube-linux-amd64 https://storage.googleapis.com/minikube/releases/v1.32.0/minikube-linux-amd64sudoinstallminikube-linux-amd64 /usr/local/bin/minikube# 覆盖安装替换旧版本minikube version#验证版本查看已有所有 minikube 集群minikube delete # 清理旧集群启动minikube很费了一番周折主要是minikube无法拉取kicbase镜像为此可以1先拉取国内镜像:docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kicbase:v0.0.42, 并将其填入随后启动命令中的--base-image参数启动时开启了科学上网不知是否有必要 minikube start\--base-imageregistry.cn-hangzhou.aliyuncs.com/google_containers/kicbase:v0.0.42\--registry-mirrorhttps://docker.m.daocloud.io,https://docker.mirrors.ustc.edu.cn,https://hub-mirror.c.163.com\--kubernetes-versionv1.28.3第一次启动还是很久比如在Creating docker container 这一行就卡了十几分钟。豆包说加参数--download-mirrorcn与--image-repositoryregistry.cn-hangzhou.aliyuncs.com/google_containers可加快速度未试。另外注意参数只在minikube集群第一次start时生效比如我第一次start时没有加–registry-mirror参数后面start时再加也设置不了镜像源了除非minikube delete再重来这样又是一个新的minikube集群了。所以本章从这里开始我全程开着科学上网可以看到不需要另外安装kubectl。而且之前我为minikube kubectl --配置的别名kubectl仍然有效。部署 Gateway API安装Gateway APIwgethttps://github.com/kubernetes-sigs/gateway-api/releases/download/v1.0.0/standard-install.yaml kubectl apply-fstandard-install.yaml创建实验用的 Gateway Class 和 Gateway 对象。这个 YAML 定义了一个叫 kong-gc 的 Gateway Class 对象指定使用的 Controller 是 konghq.com/kic-gateway-controller。然后 Gateway 对象的名字是 kong-gtw它关联了 kong-gc在 80 端口上处理 HTTP 协议apiVersion:gateway.networking.k8s.io/v1kind:GatewayClassmetadata:name:kong-gcannotations:konghq.com/gatewayclass-unmanaged:truespec:controllerName:konghq.com/kic-gateway-controller---apiVersion:gateway.networking.k8s.io/v1kind:Gatewaymetadata:name:kong-gtwspec:gatewayClassName:kong-gclisteners:-name:proxyport:80protocol:HTTP创建成功。Gateway Class 的缩写是 gcGateway 的缩写是 gtw 安装 Kong Ingress ControllerKong Ingress Controller 2.x 可以使用 YAML 文件直接安装但 3.0.0 已经废弃了这种方式只能够使用 Helm 或 Operator 来安装这里选用的是 Helm。Helm类似于 Linux 里的 yum、apt对复杂的云原生应用非常有用可以把众多的 YAML 文件组合成安装包的形式再轻松地把应用部署进 Kubernetes 集群。安装Helm:curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash:添加远端仓库Helm charts之后可以查看远端仓库里可用的安装包这里显示的 kong/ingress 就是 Kong Ingress Controller使用命令 helm install 安装 Kong Ingress ControllerKong Ingress Controller 默认安装在 kong 名字空间。注意kong-gateway-proxy 这个 Service它的类型是 LoadBalancer也就是对外的服务接口在实验环境里使用的端口是 32379后续我们要使用这个端口来测试。使用 curl 访问这个服务可以验证 Kong Ingress Controller 是否正常工作。curl -i $(minikube ip):32379的输出是 404这是因为我们还没有配置 HTTPRoute 资源没有路由规则所以 Gateway 无法处理流量这时再检查 Gateway Class 和 Gateway 对象会看到 ACCEPTED 和 PROGRAMMED 字段都已经变成了 True这就表示 Gateway 对象已经正确关联了 Kong Ingress Controller准备后端服务对以下yaml文件使用sed 命令就可以快速得到red-svc、green-svc、bule-svc、black-svc 4 个 ServiceapiVersion:v1kind:ConfigMapmetadata:name:ngx-confdata:default.conf:|server { listen 80; location / { default_type text/plain; return 200 ngx\nsrv : $server_addr:$server_port\nhost: $hostname\nuri : $request_method $host $request_uri\n; } }---apiVersion:apps/v1kind:Deploymentmetadata:name:ngx-deplabels:app:ngx-depspec:replicas:1selector:matchLabels:app:ngx-deptemplate:metadata:labels:app:ngx-depspec:volumes:-name:ngx-conf-volconfigMap:name:ngx-confcontainers:-image:nginx:alpinename:nginxports:-containerPort:80volumeMounts:-mountPath:/etc/nginx/conf.dname:ngx-conf-vol---apiVersion:v1kind:Servicemetadata:name:ngx-svcspec:selector:app:ngx-depports:-port:80protocol:TCPtargetPort:80seds/ngx/red/gbackend.yml|kubectl apply-f-seds/ngx/green/gbackend.yml|kubectl apply-f-seds/ngx/blue/gbackend.yml|kubectl apply-f-seds/ngx/black/gbackend.yml|kubectl apply-f-通过http访问每个Service url的流量会被转发至nginx Pod 的 80 端口, 得到有效响应。使用 Gateway API从最简单的路由开始只使用域名规则创建一个 HTTPRoute 对象。HTTPRoute 对象和 Ingress 很相似但要简洁一些。这里使用 parentRefs 指定了路由使用的 Gateway 对象用 hostnames 指定一个或多个域名用 backendRefs 指定后端 Service。合起来看就是要求 Gateway 把域名 gtw.test 的流量都转发到 red-svc apiVersion:gateway.networking.k8s.io/v1kind:HTTPRoutemetadata:name:ngx-host-routespec:parentRefs:-name:kong-gtwhostnames:-gtw.testrules:-backendRefs:-name:red-svcport:80验证我HTTPRoute.spec.hostnames 不是用来匹配 curl 请求的 URL 地址只是用来匹配HTTP请求头中host除端口部分比如下面就能成功QIngress.spec.rules.host, 是不是也像HTTPRoute.spec.hostnames 一样是为了匹配 curl -H ‘host:’ 部分而不是为了匹配 curl 的目标url? 豆包Yes再来编写两个路由规则分别测试HTTPRoute.spec.rules.matches.path type: PathPrefix 的路径匹配效果和HTTPRoute.spec.rules.matches.headers的头字段匹配效果apiVersion:gateway.networking.k8s.io/v1kind:HTTPRoutemetadata:name:ngx-path-routespec:parentRefs:-name:kong-gtwhostnames:-gtw.opsrules:-matches:-path:type:PathPrefixvalue:/hellobackendRefs:-name:green-svcport:80---apiVersion:gateway.networking.k8s.io/v1kind:HTTPRoutemetadata:name:ngx-header-routespec:parentRefs:-name:kong-gtwhostnames:-gtw.devrules:-matches:-headers:-type:Exactname:areavalue:northbackendRefs:-name:blue-svcport:80Gateway API 不仅支持路由转发它还能够轻松实现流量拆分比如常见的金丝雀部署和蓝绿部署。Q: HTTPRoute.spec.rules[]优先匹配哪条rule? 豆包Gateway API官方规范rules数组从上向下依次评估命中第一条matches匹配的rule即停止但是主流 Envoy 系网关Kong、Istio、Gloo实现不同matches.path约束更强(更具体的)的rule 优先匹配其次才看rules数组顺序。所以推荐把matches约束越精细的rule写在rules数组靠前位置泛匹配兜底rule放在最后。我改了下yaml因为原文应该搞反了蓝绿才是100%切换的。另外也是为了验证以下结论matches数组的每个数组元素之间的逻辑关系是OR数组元素内部的逻辑关系才是ANDapiVersion:gateway.networking.k8s.io/v1kind:HTTPRoutemetadata:name:ngx-blue-green-routespec:parentRefs:-name:kong-gtwhostnames:-blue-green.testrules:-backendRefs:-name:blue-svcport:80-matches:-headers:-name:trafficvalue:green1path:type:Exactvalue:/green1-headers:-name:trafficvalue:green2path:type:Exactvalue:/green2backendRefs:-name:green-svcport:80---apiVersion:gateway.networking.k8s.io/v1kind:HTTPRoutemetadata:name:ngx-canary-routespec:parentRefs:-name:kong-gtwhostnames:-canary.testrules:-backendRefs:-name:black-svcport:80weight:70-name:red-svcport:80weight:30我金丝雀发布灰度发布的weight是同一个rules[].backendRefs[]数组内各服务的比例。测试灰度效果curl $(minikube ip):32379 -H host: canary.test可以看到大部分流量7成打到了black-svc其它打到red-svc。最后我们再来看一下 Gateway API 的 filter 特性它可以对应到 Kong Gateway 的插件机制实现对流量的附加处理比如速率限制、改写数据、身份验证等等不过目前标准的 filter 还不多所以有的时候还是要依赖 CRD 资源定义 Plugin。下面的 YAML 添加了响应头和限速apiVersion:configuration.konghq.com/v1kind:KongPluginmetadata:name:kong-rate-limiting-pluginplugin:rate-limitingconfig:minute:2---apiVersion:gateway.networking.k8s.io/v1kind:HTTPRoutemetadata:name:ngx-filter-routeannotations:konghq.com/plugins:kong-rate-limiting-plugin#把上面的kong限流插件绑定到这条HTTPRoutespec:parentRefs:-name:kong-gtwhostnames:-filter.testrules:-backendRefs:-name:black-svcport:80filters:-type:ResponseHeaderModifier#GatewayAPI内置过滤器和Kong插件相互独立responseHeaderModifier:add:-name:A-New-Headervalue:k8s-gtw-api连续发送请求curl请求3次可以看到kong-rate-limiting-plugin的限速效果。响应头中红框是kong-rate-limiting-plugin造成的黄框是filter造成的小结Gateway API它是 Ingress 的继任者功能更强大、用法更灵活也是 Kubernetes 社区今后的重点发展方向。我画的图CSDN安装minikube无法拉取kicbase镜像 ↩︎