
Kubernetes | Ingress Controller
最近工作在折腾阿里云上的K8S。公司的Git仓库开始逼近Gitee的容量限制了,而且两个公司的仓库计划分开,所以打算把很多设施都需要在新的K8S上面部署一遍。云服务上的K8S太贵了,也没自己买过,也算是可贵的学习经历了。
这篇Post主要是针对部署nginx ingress controller后的东西。
拓扑
现状
新的k8s集群是阿里云的标准托管版,不需要管master,只要管三个worker就好。用的是最基本的配置,没有太多插件,也没有ingress controller,最主要的定制就是阿里的网络集成。研发团队因为对apisix存在依赖,所以有一个apisix+etcd的小集群,通过tcp负载均衡代理到了阿里云的TCP负载均衡上,手工对路由进行配置。
计划
考虑到运维和业务可能打架,但是成本又不能太高。所以还是用同一个集群,只是分成不同的入口。在apisix之外加一个load balancer,指向nginx ingress controller。
为了解决证书的问题,还需要加一个cert manager。毕竟没必要自己再造一个轮子。
添加nginx ingress controller
在阿里云上比较简单。点点鼠标就行。能找到一个指向nginx、类型是load balancer、有公网ip的service就算是成了。
如果是自己的机器上,没有阿里云集成的话,也可以直接用NodePort。其实和之前的APISIX差不多。
添加cert manager
官方有两种安装途径,结果差不多。一个是helm,一个是直接用yaml。问题不是很大。
我在用的时候唯一遇到的问题就是,遇到之前学着前辈在ingress上加annotation kubernetes.io/tls-acme: 'true'
就可以自动生成、刷新证书(毕竟官方文档直接写的方法还要用CustomResource,太麻烦了),但是实际出问题的情况。
看日志发现Unable to find issuer类似的提示。看了一眼文档大致是需要指定一个CA签发机构。需要新建一个类似于这样的签发机构:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
# You must replace this email address with your own.
# Let's Encrypt will use this to contact you about expiring
# certificates, and issues related to your account.
email: blablabla...
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
# Secret resource that will be used to store the account's private key.
name: issuer-account-key
# Add a single challenge solver, HTTP01 using nginx
solvers:
- http01:
ingress:
class: nginx
新建以后,如果要用这个Issuer,要么启动cert-manager的时候需要指定--default-issuer-name=letsencrypt-prod --default-issuer-kind=ClusterIssuer
这两个参数,也就是默认用这个issuer。要么每次ingress需要签发证书,就多加一个annotation: cert-manager.io/cluster-issuer: "letsencrypt-prod"
验证
负载均衡会有个IP,直接访问一下80端口,看看是不是nginx的404,是404就说明ok了。
Ingress本质
入口
创建Ingress Controller后,我们会发现入口其实就是一个可以被公网访问到的Service,这个Service可能是NodePort暴露出去,也可能是LoadBalancer集成云平台,由云平台创建资源把流量倒进来。
K8S并没有什么魔法可以把发到主机上的流量直接丢给集群,还是需要有一个东西把流量放进去的。
后端
Service的后面就是一个ReplicaSet(Deployment也是ReplicaSet)。这个ReplicaSet负责处理请求,把请求路由到其他的Service上。
在Nginx Ingress Controller中,Go的部分先启动,配置好集群环境(K8S啊,自己的选举啊blablabla)以后启动nginx,由nginx处理请求。
监听K8S API
我自己之前也配置了一个APISIX作为gateway,但是并没有叫它ingress controller,是因为nginx ingress controller可以监听k8s中ingress的变动从而更新路由,但是单独的apisix。
ingress controller很重要的一部分功能就是监听k8s api,由此更新配置,也就是说controller是《用k8s的资源》《自动配置代理服务》的工具,是k8s资源和代理的一个前端。除了nginx为核心的nginx ingress controller、kong以外,也有很多其他的ingress controller,比如说以envoy为核心的ambassadar、gloo,还有自成一体的traefik,本质都是类似的。