开篇
本文主要介绍 Kubernetes采用Traefik做ingress代理服务时,TCP服务和HTTP服务的最基础代理方式。
介绍
先附上traefik deployment.yaml配置文件
kind: DeploymentapiVersion: apps/v1metadata:namespace: defaultname: traefiklabels:app: traefikspec:replicas: 5selector:matchLabels:app: traefiktemplate:metadata:labels:app: traefikspec:serviceAccountName: traefik-ingress-controllerterminationGracePeriodSeconds: 60hostNetwork: truerestartPolicy: Alwayscontainers:- name: traefikimage: traefik:v2.0args:- --api- --api.insecure- --entrypoints.http.Address=:80- --entrypoints.https.Address=:443- --entrypoints.redis.Address=:6379- --providers.kubernetescrd- --ping- --accesslog=true- --log.level=ERROR- --serversTransport.insecureSkipVerify- --serversTransport.maxIdleConnsPerHost=5000- --global.checkNewVersion=false- --global.sendAnonymousUsage=false- --providers.file.directory=/config/- --metrics.prometheus=true- --providers.file.watch=trueports:- name: httpcontainerPort: 80- name: httpscontainerPort: 443- name: admincontainerPort: 8080- name: rediscontainerPort: 6379resources:limits:cpu: 500mmemory: 1Girequests:cpu: 100mmemory: 20MivolumeMounts:- mountPath: configname: config- mountPath: config/tlsname: tlsvolumes:- name: configconfigMap:name: traefik-conf- name: tlspersistentVolumeClaim:claimName: tls
从yaml配置配置文件中,我们可以看到有三个entrypoints:[http]、[https]、[redis],采用hostNetwork的方式,将80,443,6379及8080端口暴露到host主机上。并且有一个configMap配置文件和tls-pvc数据盘挂载到pods上。
# traefik-configmap.yamlkind: ConfigMapapiVersion: v1metadata:name: traefik-confnamespace: defaultdata:traefik.toml: |[providers]providersThrottleDuration = "2s"[tls.stores][tls.stores.default][tls.stores.default.defaultCertificate]certFile = "/config/tls/cert.crt"keyFile = "/config/tls/privkey.pem"
在configmap中,指定了ssl证书放置位置。
Traefik Routers
traefik routers主要有HTTP和TCP两种,k8s api kind分别为IngressRoute和IngressRouteTCP,负责将传入请求连接到可以处理这些请求的服务。按照我司现有架构,数据传输顺序为:client --> aliyun SLB --> traefik --> services --> pods。
HTTP Routers
apiVersion: traefik.containo.us/v1alpha1kind: IngressRoutemetadata:name: simpleingressroutenamespace: defaultspec:entryPoints:- httproutes:- match: Host(`your.domain.com`) && PathPrefix(`/notls`)kind: Ruleservices:- name: whoamiport: 80---apiVersion: traefik.containo.us/v1alpha1kind: IngressRoutemetadata:name: ingressroutetlsnamespace: defaultspec:entryPoints:- httpsroutes:- match: Host(`your.domain.com`) && PathPrefix(`/tls`)kind: Ruleservices:- name: whoamiport: 80tls:certResolver: defaultpassthrough: true
创建两个HTTP IngressRoute,simpleingressroute 为无tls访问,ingressroutetls 为tls访问。
在此介绍HTTPS & TLS的一点小知识。从之前介绍的configmap配置中,有一项为:
[tls.stores][tls.stores.default][tls.stores.default.defaultCertificate]certFile = "/config/tls/cert.crt"keyFile = "/config/tls/privkey.pem"
在此,设置了tls的默认stores为default,默认Certificate为certFile与keyFile定义的证书。所以IngressRoute ingressroutetls的tls certResolver设置为default,且passthrough为true,允许无证书也可访问。更多内容,可去官网阅读 https://docs.traefik.io/https/tls/ 。
TCP Routers
TCP Routers的介绍,将通过redis的实例来详解。
# redis.yamlapiVersion: extensions/v1beta1kind: Deploymentmetadata:name: redisspec:template:metadata:labels:app: redisspec:containers:- name: redisimage: redis:3.2.11ports:- containerPort: 6379protocol: TCP---apiVersion: v1kind: Servicemetadata:name: redisspec:ports:- port: 6379targetPort: 6379selector:app: redis
新建一个redis服务,端口指向为6379。并生成一个IngressRouteTCP,将entryPoints为redis(即host 6379端口)指向services-redis-6379。
apiVersion: traefik.containo.us/v1alpha1kind: IngressRouteTCPmetadata:name: redisspec:entryPoints:- redisroutes:- match: HostSNI(`*`)services:- name: redisport: 6379
就可以通过host 6379端口访问,如:redis-cli -h hostip -p 6379
。
TCP Routers与HTTP Routers的routes有所不同:
TCP Routers match采用HostSNI,而HTTP Routers match直接匹配Host。 TCP Routers只能定位TCP服务(不能定位HTTP服务)。 如果HTTP Routers和TCP Routers都侦听相同的入口点,则TCP Routers将在HTTP Routers之前应用。如果找不到与TCP Routers匹配的路由,则HTTP Routers将接管。
参考链接
https://docs.traefik.io/
https://www.qikqiak.com/post/expose-redis-by-traefik2/
历史文章
k8s traefik配置custom headers: AccessControlAllowHeaders CORS问题
Traefik - Kubernetes 配置服务basic auth验证




