K8S Ingress 之 traefik-ingress-controller
一、需求背景
在上篇 K8S HelloWord 一文中,我们已经实现了对 web 服务的部署和正常外部访问,但是你可能发现了,我们使用的端口是30001,采用了NodePort方式映射并固定了30001端口,使其可以固定对外提供服务。
但是,该端口默认范围是30000~32767,并且我们的web服务一般都是80、443端口对外,因此我们产生了如下几点需求和疑问:
1、如果想暴露80、443端口,你可以修改k8s apiserver的参数将端口设置为80~xxxx,但是不推荐这样做,因为k8s在一些场景需求的时候会自动在端口范围内生成一个端口使用,如果我们的端口访问包含了常用端口,可能会给其他本地服务带来麻烦。
2、如果你的系统服务增多,需要暴露更多的web服务的时候,那么也同样需要设置固定更多的NodePort端口,为了避免端口冲突你还要对使用的端口进行整理维护。
3、一个系统对外暴露的端口增多,就好比我们的园区开了更多的门一样,任何一个门有安全问题,都会导致整个园区产生安全风险,我们的系统同样如此。当这个问题在实现了下面第4点后就不是问题了。
4、还有一个最重要的是,我们是web服务,怎么能少了https证书呢。所以依然需要在增加一个独立的nginx、traefik等组件来配置证书。
针对如上问题,我们总是需要一个方向代理服务的。既然需要单独管理维护一个,不如用 k8s 为了提供了的ingress控制器方案,完美解决问题。
二、主要组件关系
Service: 后端真实服务的抽象,一个 Service 可以代表多个相同的后端服务,向下对应多个 Pod。
Ingress: 反向代理规则,用来规定 HTTP/S 请求应该被转发到哪个 Service 上,根据根据请求中不同的 Host 和 url 路径让请求落到不同的 Service 上。
Ingress Controller: 它是一个反向代理程序,也是一个具体的 Pod,它负责解析 Ingress 的反向代理规则,如果 Ingress 有增删改的变动,所有的 Ingress Controller 都会及时更新自己相应的转发规则,当 Ingress Controller 收到请求后就会根据这些规则将请求转发到对应的 Service。
Kubernetes 并没有自带 Ingress Controller,它只是一种标准,具体实现有多种,需要自己单独安装,常用的是 Nginx Ingress Controller 和 Traefik Ingress Controller。 所以 Ingress 是一种转发规则的抽象,Ingress Controller 的实现需要根据这些 Ingress 规则来将请求转发到对应的 Service,我画了一张图来描述它们之间的关系,然后本文也实现一个该图的实例:
三、实施部署
本例使用的 traefik-controller 版本为 traefik:1.7.20,现在官方最新版是 2.x 了,因为时间问题就直接拿本地 1.7.20 版本的配置来写文了,注意本文在上篇文章 K8S HelloWorld 的基础上配置。
1、文件 traefik.yml
--- apiVersion: v1 kind: Namespace metadata: name: traefik-ingress-controller --- # Source: traefik/templates/configmap.yaml apiVersion: v1 kind: ConfigMap metadata: name: traefik-ingress labels: app: traefik namespace: traefik-ingress-controller data: traefik.toml: | logLevel = "info" defaultEntryPoints = ["http", "https"] [entryPoints] [entryPoints.http] address = ":80" compress = true [entryPoints.https] address = ":443" compress = true [entryPoints.https.tls] [ping] entryPoint = "http" [kubernetes] [traefikLog] format = "json" --- # Source: traefik/templates/rbac.yaml kind: ServiceAccount apiVersion: v1 metadata: name: traefik-ingress namespace: traefik-ingress-controller --- # Source: traefik/templates/rbac.yaml kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: traefik-ingress rules: - apiGroups: - "" resources: - pods - services - endpoints - secrets verbs: - get - list - watch - apiGroups: - extensions resources: - ingresses verbs: - get - list - watch - apiGroups: - extensions resources: - ingresses/status verbs: - update --- # Source: traefik/templates/rbac.yaml kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: traefik-ingress roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: traefik-ingress subjects: - kind: ServiceAccount name: traefik-ingress namespace: traefik-ingress-controller --- # Source: traefik/templates/deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: traefik-ingress labels: app: traefik namespace: traefik-ingress-controller spec: replicas: 1 selector: matchLabels: app: traefik template: metadata: labels: app: traefik spec: hostNetwork: true serviceAccountName: traefik-ingress terminationGracePeriodSeconds: 60 containers: - image: traefik:1.7.20 name: traefik-ingress readinessProbe: httpGet: path: /ping port: "http" failureThreshold: 1 initialDelaySeconds: 10 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 2 livenessProbe: httpGet: path: /ping port: "http" failureThreshold: 3 initialDelaySeconds: 10 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 2 volumeMounts: - mountPath: /config name: config ports: - name: http containerPort: 80 protocol: TCP - name: https containerPort: 443 protocol: TCP args: - --configfile=/config/traefik.toml volumes: - name: config configMap: name: traefik-ingress
2、文件 ingress-traefik.yaml
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: traefik-ingress namespace: default annotations: kubernetes.io/ingress.class: traefik spec: tls: - hosts: - shanhy-k8s.com - "*.shanhy-k8s.com" secretName: ingress-secret rules: - host: www.shanhy-k8s.com http: paths: - path: / backend: serviceName: helloworld-nodejs servicePort: 20001
3、https 证书的生成
# 生成证书key openssl genrsa -out ingress-key.pem 2048 # 生成证书 openssl req -new -x509 -key ingress-key.pem -out ingress.pem -subj /C=CN/ST=BeiJing/L=BeiJing/O=Shanhy/OU=Shanhy/CN=www.shanhy-k8s.com -days 3650 # 查看证书信息 openssl x509 -in ingress.pem -text -noout
4、k8s 创建 secret
kubectl create secret tls ingress-secret --key cert/ingress-key.pem --cert cert/ingress.pem
5、运行
kubectl apply -f traefik.yml kubectl apply -f ingress-traefik.yaml # 查看运行结果 [root@server1 k8s]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE helloworld-nodejs ClusterIP 10.96.0.246 <none> 20001/TCP 45h kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d2h [root@server1 k8s]# kubectl get ingress NAME HOSTS ADDRESS PORTS AGE traefik-ingress www.shanhy-k8s.com 80, 443 108m [root@server1 k8s]# kubectl get pod -A NAMESPACE NAME READY STATUS RESTARTS AGE default helloworld-nodejs-5dfb48565d-4snbs 1/1 Running 0 2d15h default helloworld-nodejs-5dfb48565d-rxbcv 1/1 Running 0 2d15h default helloworld-nodejs-5dfb48565d-tp2qw 1/1 Running 0 2d15h traefik-ingress-controller traefik-ingress-558868f4db-swkr6 1/1 Running 0 4h12m [root@server1 k8s]# kubectl get secret NAME TYPE DATA AGE default-token-wlmkn kubernetes.io/service-account-token 3 23h ingress-secret kubernetes.io/tls
6、访问验证
在你电脑的C:\Windows\System32\drivers\etc\hosts
中添加192.168.0.223 www.shanhy-k8s.com
然后打开浏览器访问 http(s)://www.shanhy-k8s.com
可以看到输出结果 HelloWorld。
本文实例还有一个小结论:ingress
、service
、pod
、secret
都必须要在同一个 namespace
中,对 ingress-controller
的 namespace
没有要求。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
2020-01-15 Xtrabackup增量备份
2020-01-15 Xtrabackup安装与使用
2020-01-15 mysql5.7登录后报错
2020-01-15 Linux运维必会的MySql题之(四)
2020-01-15 Linux运维必会的MySql题之(三)
2020-01-15 Linux运维必会的MySql题之(二)
2020-01-15 Linux运维必会的MySql题之(一)