Kubernetes:Ingress - Traefik
Ingress
对外暴露集群服务
前面我们学习了在 Kubernetes 集群内部使用 kube-dns 实现服务发现的功能,那么我们部署在 Kubernetes 集群中的应用如何暴露给外部的用户使用呢?我们知道可以使用NodePort和LoadBlancer类型的 Service 可以把应用暴露给外部用户使用,除此之外,Kubernetes 还为我们提供了一个非常重要的资源对象可以用来暴露服务给外部用户,那就是Ingress。对于小规模的应用我们使用 NodePort 或许能够满足我们的需求,但是当你的应用越来越多的时候,你就会发现对于 NodePort 的管理就非常麻烦了,这个时候使用 Ingress 就非常方便了,可以避免管理大量的端口。
Ingress 其实就是从 Kuberenets 集群外部访问集群的一个入口,将外部的请求转发到集群内不同的 Service 上,其实就相当于 nginx、haproxy 等负载均衡代理服务器,可能你会觉得我们直接使用 nginx 就实现了,但是只使用 nginx 这种方式有很大缺陷,每次有新服务加入的时候怎么改 Nginx 配置?不可能让我们去手动更改或者滚动更新前端的 Nginx Pod 吧?那我们再加上一个服务发现的工具比如 consul 如何?貌似是可以,对吧?Ingress 实际上就是这样实现的,只是服务发现的功能自己实现了,不需要使用第三方的服务了,然后再加上一个域名规则定义,路由信息的刷新依靠 Ingress Controller 来提供。
Ingress Controller 可以理解为一个监听器,通过不断地监听 kube-apiserver,实时的感知后端 Service、Pod 的变化,当得到这些信息变化后,Ingress Controller 再结合 Ingress 的配置,更新反向代理负载均衡器,达到服务发现的作用。其实这点和服务发现工具 consul、 consul-template 非常类似。
现在可以供大家使用的 Ingress Controller 有很多,比如 traefik、nginx-controller、Kubernetes Ingress Controller for Kong、HAProxy Ingress controller,当然你也可以自己实现一个 Ingress Controller,现在普遍用得较多的是 traefik 和 nginx-controller,traefik 的性能较 nginx-controller 差,但是配置使用要简单许多,我们这里会重点给大家介绍 traefik 的使用。
Traefik
Traefik是一个开源的可以使服务发布变得轻松有趣的边缘路由器。它负责接收你系统的请求,然后使用合适的组件来对这些请求进行处理
除了众多的功能之外,Traefik 的与众不同之处还在于它会自动发现适合你服务的配置。当 Traefik 在检查你的服务时,会找到服务的相关信息并找到合适的服务来满足对应的请求。
Traefik 兼容所有主流的集群技术,比如 Kubernetes,Docker,Docker Swarm,AWS,Mesos,Marathon,等等;并且可以同时处理多种方式。(甚至可以用于在裸机上运行的比较旧的软件。)
使用 Traefik,不需要维护或者同步一个独立的配置文件:因为一切都会自动配置,实时操作的(无需重新启动,不会中断连接)。使用 Traefik,你可以花更多的时间在系统的开发和新功能上面,而不是在配置和维护工作状态上面花费大量时间。
核心概念:
Traefik 是一个边缘路由器,是你整个平台的大门,拦截并路由每个传入的请求:它知道所有的逻辑和规则,这些规则确定哪些服务处理哪些请求;传统的反向代理需要一个配置文件,其中包含路由到你服务的所有可能路由,而 Traefik 会实时检测服务并自动更新路由规则,可以自动服务发现。
架构图:
首先,当启动 Traefik 时,需要定义 entrypoints(入口点),然后,根据连接到这些 entrypoints 的路由来分析传入的请求,来查看他们是否与一组规则相匹配,如果匹配,则路由可能会将请求通过一系列中间件转换过后再转发到你的服务上去。在了解 Traefik 之前有几个核心概念我们必须要了解:
- Providers 用来自动发现平台上的服务,可以是编排工具、容器引擎或者 key-value 存储等,比如 Docker、Kubernetes、File
- Entrypoints 监听传入的流量(端口等…),是网络入口点,它们定义了接收请求的端口(HTTP 或者 TCP)。
- Routers 分析请求(host, path, headers, SSL, …),负责将传入请求连接到可以处理这些请求的服务上去。
- Services 将请求转发给你的应用(load balancing, …),负责配置如何获取最终将处理传入请求的实际服务。
- Middlewares 中间件,用来修改请求或者根据请求来做出一些判断(authentication, rate limiting, headers, …),中间件被附件到路由上,是一种在请求发送到你的服务之前(或者在服务的响应发送到客户端之前)调整请求的一种方法。
安装traefik
由于 Traefik 2.X 版本和之前的 1.X 版本不兼容,我们这里选择功能更加强大的 2.X 版本来和大家进行讲解,我们这里使用的是最新的镜像traefik:2.3.6。
在 Traefik 中的配置可以使用两种不同的方式:
- 动态配置:完全动态的路由配置
- 静态配置:启动配置
静态配置中的元素(这些元素不会经常更改)连接到 providers 并定义 Treafik 将要监听的 entrypoints。
在 Traefik 中有三种方式定义静态配置:在配置文件中、在命令行参数中、通过环境变量传递
动态配置包含定义系统如何处理请求的所有配置内容,这些配置是可以改变的,而且是无缝热更新的,没有任何请求中断或连接损耗。
这里我们还是使用 Helm 来快速安装 traefik,首先获取 Helm Chart 包:
➜ git clone https://github.com/traefik/traefik-helm-chart
创建一个定制的 values 配置文件 比如我们命名为values-prod.yaml:
# values-prod.yaml
# Create an IngressRoute for the dashboard
ingressRoute:dashboard:enabled: false # 禁用helm中渲染的dashboard,我们自己手动创建# Configure ports
ports:web:port: 8000hostPort: 80 # 使用 hostport 模式# Use nodeport if set. This is useful if you have configured Traefik in a# LoadBalancer# nodePort: 32080# Port Redirections# Added in 2.2, you can make permanent redirects via entrypoints.# https://docs.traefik.io/routing/entrypoints/#redirection# redirectTo: websecurewebsecure:port: 8443hostPort: 443 # 使用 hostport 模式# Options for the main traefik service, where the entrypoints traffic comes
# from.
service: # 使用 hostport 模式就不需要Service了enabled: false# Logs
# https://docs.traefik.io/observability/logs/
logs:general:level: DEBUGtolerations: # kubeadm 安装的集群默认情况下master是有污点,需要容忍这个污点才可以部署
- key: "node-role.kubernetes.io/master"operator: "Equal"effect: "NoSchedule"nodeSelector: # 固定到master1节点(该节点才可以访问外网)kubernetes.io/hostname: "master1"
针对上边的yaml资源清单我们需要解释一下:
其中提到了:
web:port: 8000hostPort: 80 # 使用 hostport 模式
意思就是tracefik会是对外暴露80端口 通过80端口映射到容器内的8000端口 443也是一样的道理!
另外
- key: "node-role.kubernetes.io/master"operator: "Equal"effect: "NoSchedule"
可以通过命令kubectl describe node master1获取到里面的Taints: node-role.kubernetes.io/master:NoSchedule就是上边的值
另外
nodeSelector: # 固定到master1节点(该节点才可以访问外网)kubernetes.io/hostname: "master1"
可以通过kubectl get nodes --show-labels来获取到里面的具体的值
然后就是通脱helm安装即可,我们提供一下目录结构:
然后在该目录下执行:helm install --namespace kube-system traefik ./traefik -f ./values-pod.yaml
等待执行成功即可!
➜ helm install --namespace kube-system traefik ./traefik -f ./values-prod.yaml
NAME: traefik
LAST DEPLOYED: Thu Dec 24 11:23:51 2020
NAMESPACE: kube-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
➜ kubectl get pods -n kube-system -l app.kubernetes.io/name=traefik
NAME READY STATUS RESTARTS AGE
traefik-78ff486794-64jbd 1/1 Running 0 3m15s
注意点:
因为前边我们部署过ingress-controller 所以需要先卸载掉ingress-controller 因为它占着443和80端口呢!
helm uninstall ingress-nginx -n ingress-nginx
然后再卸载刚才安装的traefik:helm uninstall traefik -n kube-system
再次进行helm的安装即可:helm install --namespace kube-system traefik ./traefik -f ./values-pod.yaml
安装完成后我们可以通过查看 Pod 的资源清单来了解 Traefik 的运行方式
➜ kubectl get pods traefik-78ff486794-64jbd -n kube-system -o yaml
apiVersion: v1
kind: Pod
metadata:
......
spec:containers:- args:- --global.checknewversion- --global.sendanonymoususage- --entryPoints.traefik.address=:9000/tcp- --entryPoints.web.address=:8000/tcp- --entryPoints.websecure.address=:8443/tcp- --api.dashboard=true- --ping=true- --providers.kubernetescrd- --providers.kubernetesingress- --accesslog=true- --accesslog.fields.defaultmode=keep- --accesslog.fields.headers.defaultmode=drop
其中 entryPoints属性定义了 web 和 websecure 这两个入口点的,并开启 kubernetesingress 和 kubernetescrd 这两个 provider,也就是我们可以使用 Kubernetes 原本的 Ingress 资源对象,也可以使用 Traefik 自己扩展的 IngressRoute 这样的 CRD 资源对象。并且可以看到 entryPoints.web.address=:8000/tcp 和 entryPoints.websecure.address=:8443/tcp tracfik占用了80和443端口号
k8s当中基于traefik创建一个用于Dashboard访问的资源清单
在上一篇文章安装部署好traefik之后,我们来创建一个用于 Dashboard 访问的 IngressRoute 资源清单,直接提供yaml资源清单:
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:name: traefik-dashboardnamespace: kube-system # 指定命名空间 因为我们的traefik安装到了kube-system命名空间 所以要保持一致
spec:entryPoints:- web # 如果是http服务那么就要写webroutes:- match: Host(`traefik.myidns.com`) # 指定域名 不要忘记 `` 符号哈kind: Ruleservices:- name: api@internal # traefik内部自带的dashaboard的服务的名称就是api@internalkind: TraefikService # 引用另外的 Traefik Service
然后创建就好了!
其中的 TraefikService 是 Traefik Service 的一个 CRD 实现,这里我们使用的 api@internal 这个 TraefikService,表示我们访问的是 Traefik 内置的应用服务。
部署完成后我们可以通过在本地 /etc/hosts 中添加上域名 traefik…com 的映射即可访问 Traefik 的 Dashboard 页面了:
这!这!只是一个小案例,请勿当真!并且还是不熟的traefik内置的一些服务!接下来我们部署我们自己的服务!
k8s当中利用traefik部署一个http请求的简单的小项目
没啥好讲的,主要就是traefik当中创建的是ingressRoute,直接看yaml资源清单当中的注释就好了,包好了service deployment pod ingressRoute:
apiVersion: v1
kind: Service
metadata:name: whoami
spec:ports:- protocol: TCPname: webport: 8001 # service当中的8001映射到了pod当中的80端口targetPort: 80 # service当中的targetPort必须要和pod当中容器里面的port=80保持一致selector:app: whoami # 表示选择whoami这个pod列表
---
kind: Deployment
apiVersion: apps/v1
metadata:name: whoamilabels:app: whoami
spec:replicas: 2 # 会有两个podselector:matchLabels:app: whoamitemplate:metadata:labels:app: whoamispec:containers:- name: whoamiimage: containous/whoamiports:- name: webcontainerPort: 80 # 容器当中的端口号
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:name: simpleingressroute
spec:entryPoints:- web # 如果是http就写web 如果是https就写websecureroutes:- match: Host(`who.myidns.com`) && PathPrefix(`/notls`) # 匹配规则 必须是访问 who.myidns.com/notls才能被转发到后边的service服务当中去kind: Rule # 规则 就要用Rule关键词services:- name: whoami # 要转发到的服务的名称port: 8001 # 要转发到的服务的端口号 必须和whoami这个服务的端口号保持一致才行!
然后执行这个yaml资源清单就好了!
通过 entryPoints 指定了我们这个应用的入口点是 web,也就是通过 80 端口访问,然后访问的规则就是要匹配 who.qikqiak.com 这个域名,并且具有 /notls 的路径前缀的请求才会被 whoami 这个 Service 所匹配!
那就访问一下试试看呗:
因为我们是部署了2个pod所以请求会自动路由到不同的pod当中去!
搞定!
不过这只是一个小小的测试!但是学习的是套路!套路!套路!
k8s当中利用traefik部署一个https请求的简单的小项目
在上一篇文章当中我们记录了如果在k8s当中通过traefik部署一个http请求的小项目还是比较简单的,如何搞一个自签名的证书让我们的项目实现https访问呢?
如果我们需要用 HTTPS 来访问我们这个应用的话,就需要监听 websecure 这个入口点,也就是通过 443 端口来访问,同样用 HTTPS 访问应用必然就需要证书,这里我们用 openssl 来创建一个自签名的证书:
➜ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=who.myidns.com"
然后通过 Secret 对象来引用证书文件:
# 要注意证书文件名称必须是 tls.crt 和 tls.key
➜ kubectl create secret tls who-tls --cert=tls.crt --key=tls.key
secret/who-tls created
这个时候我们就可以创建一个 HTTPS 访问应用的 IngressRoute 对象了,不过这里我们直接贴出来http和https的ingressRoute以及depolyment还有pods以及service的所有的yaml资源清单:
apiVersion: v1
kind: Service
metadata:name: whoami
spec:ports:- protocol: TCPname: webport: 8001 # service当中的8001映射到了pod当中的80端口targetPort: 80 # service当中的targetPort必须要和pod当中容器里面的port=80保持一致selector:app: whoami # 表示选择whoami这个pod列表
---
kind: Deployment
apiVersion: apps/v1
metadata:name: whoamilabels:app: whoami
spec:replicas: 2 # 会有两个podselector:matchLabels:app: whoamitemplate:metadata:labels:app: whoamispec:containers:- name: whoamiimage: containous/whoamiports:- name: webcontainerPort: 80 # 容器当中的端口号
---
# 这是针对http请求的
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:name: simpleingressroute
spec:entryPoints:- web # 如果是http就写web 如果是https就写websecureroutes:- match: Host(`who.myidns.com`) && PathPrefix(`/notls`) # 匹配规则 必须是访问 who.myidns.com/notls才能被转发到后边的service服务当中去kind: Rule # 规则 就要用Rule关键词services:- name: whoami # 要转发到的服务的名称port: 8001 # 要转发到的服务的端口号 必须和whoami这个服务的端口号保持一致才行!---
# 这是针对https请求的
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:name: ingressroutetls # 重新起一个IngressRoute的名称
spec:entryPoints:- websecure # 如果是https那么entryPoints必须是websecureroutes:- match: Host(`who.myidns.com`) && PathPrefix(`/tls`) # 跟上边一样只不过是换个后边的url地址kind: Ruleservices:- name: whoami # 同样我们在ingressRoute当中绑定的也是whoami这个service服务port: 8001 # 同样绑定的whoami这个service对外暴露的端口号是8001tls: # 必须绑定我们事前创建好的tls证书 写入到了secret当中去了secretName: who-tls # 这里直接写secret的名称即可
重点看最后的这个ingressRoute即可!其他的和上篇文章当中保持了一致!
k8s当中traefik里面实现使用 Let’s Encrypt 来进行自动化 HTTPS
上一篇文章当中我们记录了traefik当中配置https,相当于是自签名的,浏览器访问会提示不安全!
今天我们使用 Let’s Encrypt 来进行自动化 HTTPS,让浏览器认为它是安全的受信任的!
除了手动提供证书的方式之外 Traefik 同样也支持使用 Let’s Encrypt 自动生成证书,要使用 Let’s Encrypt 来进行自动化 HTTPS,就需要首先开启 ACME,开启 ACME 需要通过静态配置的方式,也就是说可以通过环境变量、启动参数等方式来提供;
ACME 有多种校验方式 tlsChallenge、httpChallenge 和 dnsChallenge 三种验证方式,之前更常用的是 http 这种验证方式,关于这几种验证方式的使用可以查看文档:https://www.qikqiak.com/traefik-book/https/acme/了解他们之间的区别。要使用 tls 校验方式的话需要保证 Traefik 的 443 端口是可达的,dns 校验方式可以生成通配符的证书,只需要配置上 DNS 解析服务商的 API 访问密钥即可校验。
我们这里用 DNS 校验的方式来为大家说明如何配置 ACME。
我们可以重新修改 Helm 安装的 values 配置文件,修改完成之后是这样的:
# values-prod.yaml
# Create an IngressRoute for the dashboard
ingressRoute:dashboard:enabled: false # 禁用helm中渲染的dashboard,我们自己手动创建# Configure ports
ports:web:port: 8000hostPort: 80 # 使用 hostport 模式# Use nodeport if set. This is useful if you have configured Traefik in a# LoadBalancer# nodePort: 32080# Port Redirections# Added in 2.2, you can make permanent redirects via entrypoints.# https://docs.traefik.io/routing/entrypoints/#redirection# redirectTo: websecurewebsecure:port: 8443hostPort: 443 # 使用 hostport 模式# Options for the main traefik service, where the entrypoints traffic comes
# from.
service: # 使用 hostport 模式就不需要Service了enabled: false# Logs
# https://docs.traefik.io/observability/logs/
logs:general:level: DEBUGtolerations: # kubeadm 安装的集群默认情况下master是有污点,需要容忍这个污点才可以部署
- key: "node-role.kubernetes.io/master"operator: "Equal"effect: "NoSchedule"nodeSelector: # 固定到master1节点(该节点才可以访问外网)kubernetes.io/hostname: "master1"# -------------------------相对以前新增加的------------------------
additionalArguments:# 使用 dns 验证方式- --certificatesResolvers.ali.acme.dnsChallenge.provider=alidns# 先使用staging环境进行验证,验证成功后再使用移除下面一行的配置
# - --certificatesResolvers.ali.acme.caServer=https://acme-staging-v02.api.letsencrypt.org/directory# 邮箱配置- --certificatesResolvers.ali.acme.email=ych_1024@163.com# 保存 ACME 证书的位置- --certificatesResolvers.ali.acme.storage=/data/acme.jsonenvFrom:- secretRef:name: traefik-alidns-secret# ALICLOUD_ACCESS_KEY# ALICLOUD_SECRET_KEY# ALICLOUD_REGION_IDpersistence:enabled: true # 开启持久化accessMode: ReadWriteOncesize: 128Mipath: /data# 由于上面持久化了ACME的数据,需要重新配置下面的安全上下文
securityContext:readOnlyRootFilesystem: falserunAsGroup: 0runAsUser: 0runAsNonRoot: false
继续往下看:
这样我们可以通过设置 --certificatesresolvers.ali.acme.dnschallenge.provider=alidns 参数来指定指定阿里云的 DNS 校验,要使用阿里云的 DNS 校验我们还需要配置3个环境变量:ALICLOUD_ACCESS_KEY、ALICLOUD_SECRET_KEY、ALICLOUD_REGION_ID,分别对应我们平时开发阿里云应用的时候的密钥,可以登录阿里云后台获取,由于这是比较私密的信息,所以我们用 Secret 对象来创建:
kubectl create secret generic traefik-alidns-secret --from-literal=ALICLOUD_ACCESS_KEY=LTAI5tSC1fKLpM2X33D --from-literal=ALICLOUD_SECRET_KEY=Z09kdksDWh8NSjVV1UI4k8C --from-literal=ALICLOUD_REGION_ID=cn-beijing -n kube-system
其中的access_key还有secret_key自己去https://ram.console.aliyun.com/manage/ak?accounttraceid=4d0eccb4ba9a4500a6f30f1f8e2e6913ognk自己的阿里云上搞就行的!
创建完成后将这个 Secret 通过环境变量配置到 Traefik 的应用中,还有一个值得注意的是验证通过的证书我们这里存到 /data/acme.json 文件中,我们一定要将这个文件持久化,否则每次 Traefik 重建后就需要重新认证,而 Let’s Encrypt 本身校验次数是有限制的。所以我们在 values 中重新开启了数据持久化,不过开启过后需要我们提供一个可用的 PV 存储,由于我们将 Traefik 固定到 master1 节点上的,所以我们可以创建一个 hostpath 类型的 PV(后面会详细讲解):
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolume
metadata:name: traefik
spec:accessModes:- ReadWriteOncecapacity:storage: 128MihostPath:path: /data/k8s/traefik
EOF
然后使用如下所示的命令更新 Traefik:
helm upgrade --install traefik --namespace=kube-system ./traefik -f ./values-prod.yaml
更新完成后现在我们来修改上面我们的 whoami 应用,这里我们贴出全部的 包括deployment pods service ingressRoute :
apiVersion: v1
kind: Service
metadata:name: whoami
spec:ports:- protocol: TCPname: webport: 8001 # service当中的8001映射到了pod当中的80端口targetPort: 80 # service当中的targetPort必须要和pod当中容器里面的port=80保持一致selector:app: whoami # 表示选择whoami这个pod列表
---
kind: Deployment
apiVersion: apps/v1
metadata:name: whoamilabels:app: whoami
spec:replicas: 2 # 会有两个podselector:matchLabels:app: whoamitemplate:metadata:labels:app: whoamispec:containers:- name: whoamiimage: containous/whoamiports:- name: webcontainerPort: 80 # 容器当中的端口号
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:name: ingressroutetls
spec:entryPoints:- websecureroutes:- match: Host(`who.myidns.com`) && PathPrefix(`/tls`) # 这里就不解释了 前边讲过kind: Ruleservices:- name: whoamiport: 8001tls:certResolver: ali # 这里一定要填写alidomains:- main: "*.myidns.com" # 配置通配符域名
然后重新部署即可!
访问https://who.myidns.com就是浏览器受信任的了!
如果遇到不行 那就去看traefik这个pod的日志 里面会报错的!kubectl logs -f traefik这个pod的名称 -n kube-system
k8s当中traefik当中的中间件讲解
中间件是 Traefik2.x 中一个非常有特色的功能,我们可以根据自己的各种需求去选择不同的中间件来满足服务,Traefik 官方已经内置了许多不同功能的中间件,其中一些可以修改请求,头信息,一些负责重定向,一些添加身份验证等等,而且中间件还可以通过链式组合的方式来适用各种情况!
我们提供一下traefik的官网中间件的地址:https://doc.traefik.io/traefik/middlewares/http/overview/#available-http-middlewares
里面的中间件我们都可以使用!
具体使用方法:
只是简单描述一下如何使用,具体看下边的详细描述信息!
比如我们利用中间件将我们之前搞的whoami的http自动跳转到https!
我们直接上yaml资源清单,全套的,包括service deployment pod ingressroute middleware 仔细看里面的注释信息即可,前提是你已经掌握了traefik当中acme的正确配置https哈!:
# service服务
apiVersion: v1
kind: Service
metadata:name: whoami
spec:ports:- protocol: TCPname: webport: 8001 # service当中的8001映射到了pod当中的80端口targetPort: 80 # service当中的targetPort必须要和pod当中容器里面的port=80保持一致selector:app: whoami # 表示选择whoami这个pod列表
---
# deployment
kind: Deployment
apiVersion: apps/v1
metadata:name: whoamilabels:app: whoami
spec:replicas: 2 # 会有两个podselector:matchLabels:app: whoamitemplate:metadata:labels:app: whoamispec:containers:- name: whoamiimage: containous/whoamiports:- name: webcontainerPort: 80 # 容器当中的端口号
---
# 从http自动跳转到https的ingressRoute
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:name: redirect-https # 给这个从http自动跳转到https的中间件起个名字,这里我们叫做redirect-https
spec:# 这里就是造着抄写traefik官网文档里面的https://doc.traefik.io/traefik/middlewares/http/redirectscheme/redirectScheme:scheme: https
---
# http的ingressRoute
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:name: ingressroute-http
spec:entryPoints:- webroutes:- match: Host(`who.myidns.com`) && PathPrefix(`/tls`) # 这里就不解释了 前边讲过 因为我们需要从http自动跳转到https 所以要保持url地址一致 http://who.myidns.com/tls 我们要求自动跳转到https://who.myidns.com/tlskind: Ruleservices:- name: whoamiport: 8001middlewares: # 在http这个ingressRoute当中一定要绑定我们上边创建好的中间件 写上名字就完事!- name: redirect-https
---
# https的ingressRoute 当然要结合traefik其他的配置 前边我们讲过的
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:name: ingressroute-https
spec:entryPoints:- websecure # https一定要使用websecureroutes:- match: Host(`who.myidns.com`) && PathPrefix(`/tls`) # 这里就不解释了 前边讲过kind: Ruleservices:- name: whoamiport: 8001tls:certResolver: ali # 这里一定要填写alidomains:- main: "*.myidns.com" # 配置通配符域名
重点看里面的kind: Middleware还有http的ingressRoute的里面的注释!注释里面已经写的很详细了,自己去看吧!运行起来你就会发现请求http://who.myidns.com/tls会自动跳转到https://who.myidns.com/tls当中去!
k8s当中traefik当中的灰度发布
今天我们来记录一下traefik当中实现灰度发布的流程;
Traefik2.0 的一个更强大的功能就是灰度发布,灰度发布我们有时候也会称为金丝雀发布(Canary),主要就是让一部分测试的服务也参与到线上去,经过测试观察看是否符号上线要求;
这里我们直接提供使用到的yaml资源清单
appv1.yaml资源清单:
# 正常的deployment pod service服务
apiVersion: apps/v1
kind: Deployment
metadata:name: appv1
spec:selector:matchLabels:app: appv1template:metadata:labels:use: testapp: appv1spec:containers:- name: whoamiimage: containous/whoamiports:- containerPort: 80name: portv1
---
apiVersion: v1
kind: Service
metadata:name: appv1
spec:selector:app: appv1ports:- name: httpport: 8002 # service的集群内的端口号我们定义为8002 这个8002其他的service服务也可以使用 集群内的无所谓的 但是nodePort不行哈!targetPort: portv1
appv2.yaml资源清单:
# 正常的deployment pod service服务
apiVersion: apps/v1
kind: Deployment
metadata:name: appv2
spec:selector:matchLabels:app: appv2template:metadata:labels:use: testapp: appv2spec:containers:- name: nginximage: nginxports:- containerPort: 80name: portv2
---
apiVersion: v1
kind: Service
metadata:name: appv2
spec:selector:app: appv2ports:- name: httpport: 8002 # service的集群内的端口号我们定义为8002 这个8002其他的service服务也可以使用 集群内的无所谓的 但是nodePort不行哈!targetPort: portv2
wrr.yaml资源清单和ingressroute.yaml资源清单合并一个文件了:
# 在 Traefik2.1 中新增了一个 TraefikService 的 CRD 资源 我们利用它来进行灰度发布的路由分发操作
apiVersion: traefik.containo.us/v1alpha1
kind: TraefikService # 必须是这个关键词 TraefikService
metadata:name: app-wrr # 随便起个名字
spec:weighted: # 权重配置services: # services服务的权重分配- name: appv1 # 第一个service的名称 也就是前边我们创建好的service的名称appv1weight: 3 # 这个service的所占权重为3 3/4port: 8002 # appv1这个service的端口号kind: Service # kind绑定的服务类型是Service服务- name: appv2 # 第二个service的名称appv2weight: 1 # 第二个服务所占的权重为1 那么就是1/4port: 8002 # 第二个service的端口号8002---# 最终我们还是需要ingressRoute来对外暴露我们的服务
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:name: wrringressroutenamespace: default # 一切都是在default命名空间下玩的哈
spec:entryPoints: # 入口点 还是web- webroutes:- match: Host(`wrr.myidns.com`) # 前边讲过kind: Ruleservices:- name: app-wrr # 这里要在ingressRoute当中绑定的是我们上边创建好的TraefikService服务 名称就是这个app-wrrkind: TraefikService # 绑定的service的类型就是TraefikService 上边我们创建的那个TraefikService服务
需要注意的是现在我们配置的 Service 不再是直接的 Kubernetes 对象了,而是上面我们定义的 TraefikService 对象,直接创建上面的两个资源对象,这个时候我们对域名 wrr.qikqiak.com 做上解析,去浏览器中连续访问 4 次,我们可以观察到 appv1 这应用会收到 3 次请求,而 appv2 这个应用只收到 1 次请求,符合上面我们的 3:1 的权重配置
k8s当中traefik当中的流量复制
除了灰度发布之外,Traefik 2.0 还引入了流量镜像服务,是一种可以将流入流量复制并同时将其发送给其他服务的方法,镜像服务可以获得给定百分比的请求同时也会忽略这部分请求的响应。
我们直接提供yaml资源清单!
ziyuan.yaml:
apiVersion: v1
kind: Service
metadata:name: v1
spec:ports:- protocol: TCPname: webport: 80selector:app: v1
---
kind: Deployment
apiVersion: apps/v1
metadata:name: v1labels:app: v1
spec:selector:matchLabels:app: v1template:metadata:labels:app: v1spec:containers:- name: v1image: nginxports:- name: webcontainerPort: 80---
apiVersion: v1
kind: Service
metadata:name: v2
spec:ports:- protocol: TCPname: webport: 80selector:app: v2
---
kind: Deployment
apiVersion: apps/v1
metadata:name: v2labels:app: v2
spec:selector:matchLabels:app: v2template:metadata:labels:app: v2spec:containers:- name: v2image: nginxports:- name: webcontainerPort: 80
mirror-ingress-route.yaml:
# 在 Traefik2.1 中新增了一个 TraefikService 的 CRD 资源 我们利用它来进行流量复制的分发操作
apiVersion: traefik.containo.us/v1alpha1
kind: TraefikService
metadata:name: app-mirror #随便起个名字就叫app-mirror吧
spec:mirroring:name: v1 # 发送 100% 的请求到 K8S 的 Service "v1"port: 80 # v1的端口号是80mirrors:- name: v2 # 然后复制 50% 的请求到 v2percent: 50 # 写个50就表示50%的流量请求port: 80 # v2服务的端口号
---
# 我们依然离不了IngressRoute对外暴露服务
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:name: mirror-ingress-route # 给这个ingressRoute起个名字namespace: default # 一切都是在default命名空间下玩的哈
spec:entryPoints:- webroutes:- match: Host(`mirror.qikqiak.com`)kind: Ruleservices: # 这里一定要写services 而不是service 哈!!!- name: app-mirror # 写上边我们写好的TraefikService服务的名称kind: TraefikService # 使用声明的 TraefikService 服务,而不是 K8S 的 Service
然后直接提出手册 自己去看吧 很简单!