20_1.服务暴露-ingress (traefik)

一.ingress 简介

Ingress是建立在Service之上的L7访问入口。
Ingress是K8S API的标准资源类型之一,也是一种核心资源,基于域名和URL路径,把用户的请求(可以来源于集群外部)转发至指定Service的资源,从而实现服务暴露
Ingress控制器 可以为Ingress资源监听某套接字,根据Ingress规则路由调度流量
常用的Ingress控制器的实现软件有:Ingress-nginx、HAProxy、Traefik等
下面以Traefik为例

二.traefik

https://github.com/traefik/traefik
Kubernetes 中使用 Traefik 2.1
Kubernetes部署Ingress Traefik v2.2

1. 简介

Traefik 是一个开源的可以使服务发布变得轻松有趣的边缘路由器。它负责接收你系统的请求,然后使用合适的组件来对这些请求进行处理。
在这里插入图片描述

除了众多的功能之外,Traefik 的与众不同之处还在于它会自动发现适合你服务的配置。当 Traefik 在检查你的服务时,会找到服务的相关信息并找到合适的服务来满足对应的请求。
Traefik 兼容所有主流的集群技术,比如 Kubernetes,Docker,Docker Swarm,AWS,Mesos,Marathon,等等;并且可以同时处理多种方式。(甚至可以用于在裸机上运行的比较旧的软件。)
使用 Traefik,不需要维护或者同步一个独立的配置文件:因为一切都会自动配置,实时操作的(无需重新启动,不会中断连接)。使用 Traefik,你可以花更多的时间在系统的开发和新功能上面,而不是在配置和维护工作状态上面花费大量时间。

2. 核心概念

Traefik 是一个边缘路由器,是你整个平台的大门,拦截并路由每个传入的请求:它知道所有的逻辑和规则,这些规则确定哪些服务处理哪些请求;传统的反向代理需要一个配置文件,其中包含路由到你服务的所有可能路由,而 Traefik 会实时检测服务并自动更新路由规则,可以自动服务发现。
traefik architecture overview

首先,当启动 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, …),中间件被附件到路由上,是一种在请求发送到你的服务之前(或者在服务的响应发送到客户端之前)调整请求的一种方法。
三.k8s部署traefik

参考资料:
Kubernetes 中使用 Traefik 2.1
Kubernetes部署Ingress Traefik v2.2

0.部署准备

由于 Traefik 2.X 版本和之前的 1.X 版本不兼容,我们这里选择功能更加强大的 2.X 版本来和大家进行讲解,我们这里使用的镜像是 traefik:2.2。
在 Traefik 中的配置可以使用两种不同的方式:

  • 静态配置:启动配置
    静态配置中的元素(这些元素不会经常更改)连接到 providers 并定义 Treafik 将要监听的 entrypoints。
    在 Traefik 中有三种方式定义静态配置:在配置文件中、在命令行参数中、通过环境变量传递
  • 动态配置:完全动态的路由配置
    动态配置包含定义系统如何处理请求的所有配置内容,这些配置是可以改变的,而且是无缝热更新的,没有任何请求中断或连接损耗。

准备镜像:
docker pull traefik:v2.2
docker tag traefik:v2.2 harbor.hzwod.com/k8s/traefik:v2.2
docker push harbor.hzwod.com/k8s/traefik:v2.2

1. 资源配置清单

https://github.com/traefik/traefik/tree/v1.7/examples/k8s
参考官网文档-CRD定义https://doc.traefik.io/traefik/user-guides/crd-acme/

  • config list
    配置详细内容见文末附录
    traefik_crd.yaml 查看
    traefik_rbac.yaml 查看
    traefik_dp.yaml 查看
    添加demo服务用于演示效果
    whoami_ingressRoute.yaml 查看
    whoami_dp.yaml 查看
    traefik_dp.yaml 部分args说明:
# 创建一个名为 api@internal 的特殊 service,在 dashboard 中可以直接使用这个 service 来访问
 - --api=true
# 定义 web 入口
- --entrypoints.web.Address=:8000
# 定义websecure 入口
- --entrypoints.websecure.Address=:4443
# 开启 k8s ingress provider
- --providers.kubernetesingress
# 开启 k8s CRD provider
- --providers.kubernetescrd
# 指定k8s入口(貌似traefik pod固定在master节点上就不需要指定??)
- --kubernetes.endpoint=https://172.10.10.10:7443

  • 应用资源到k8s
kubectl apply -f traefik_crd.yaml         
kubectl apply -f traefik_rbac.yaml        
kubectl apply -f traefik_dp.yaml          
kubectl apply -f whoami_ingressRoute.yaml 
kubectl apply -f whoami_dp.yaml       
  • 查看资源
    在这里插入图片描述

  • 访问traefik dashbord
    在这里插入图片描述

  • 服务访问测试
    在这里插入图片描述在这里插入图片描述

附录
# All resources definition must be declared
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: ingressroutes.traefik.containo.us
spec:
  group: traefik.containo.us
  version: v1alpha1
  names:
    kind: IngressRoute
    plural: ingressroutes
    singular: ingressroute
  scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: middlewares.traefik.containo.us
spec:
  group: traefik.containo.us
  version: v1alpha1
  names:
    kind: Middleware
    plural: middlewares
    singular: middleware
  scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: ingressroutetcps.traefik.containo.us
spec:
  group: traefik.containo.us
  version: v1alpha1
  names:
    kind: IngressRouteTCP
    plural: ingressroutetcps
    singular: ingressroutetcp
  scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: ingressrouteudps.traefik.containo.us
spec:
  group: traefik.containo.us
  version: v1alpha1
  names:
    kind: IngressRouteUDP
    plural: ingressrouteudps
    singular: ingressrouteudp
  scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: tlsoptions.traefik.containo.us
spec:
  group: traefik.containo.us
  version: v1alpha1
  names:
    kind: TLSOption
    plural: tlsoptions
    singular: tlsoption
  scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: tlsstores.traefik.containo.us
spec:
  group: traefik.containo.us
  version: v1alpha1
  names:
    kind: TLSStore
    plural: tlsstores
    singular: tlsstore
  scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: traefikservices.traefik.containo.us
spec:
  group: traefik.containo.us
  version: v1alpha1
  names:
    kind: TraefikService
    plural: traefikservices
    singular: traefikservice
  scope: Namespaced
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: traefik-ingress-controller
rules:
  - apiGroups:
      - ""
    resources:
      - services
      - endpoints
      - secrets
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - extensions
    resources:
      - ingresses
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - extensions
    resources:
      - ingresses/status
    verbs:
      - update
  - apiGroups:
      - traefik.containo.us
    resources:
      - middlewares
      - ingressroutes
      - traefikservices
      - ingressroutetcps
      - ingressrouteudps
      - tlsoptions
      - tlsstores
    verbs:
      - get
      - list
      - watch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: traefik-ingress-controller
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: traefik-ingress-controller
subjects:
  - kind: ServiceAccount
    name: traefik-ingress-controller
    namespace: default

这里注意namespace要和traefik容器运行的namespace保持一致,否则traefik访问apiserver时会没有授权

---
kind: ServiceAccount
apiVersion: v1
metadata:
  name: traefik-ingress-controller
---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: traefik
  labels:
    app: traefik
spec:
  replicas: 2
  selector:
    matchLabels:
      app: traefik
  template:
    metadata:
      labels:
        app: traefik
    spec:
      serviceAccountName: traefik-ingress-controller
      containers:
        - name: traefik
          image: harbor.hzwod.com/k8s/traefik:v2.2
          args:
            - --log.level=DEBUG
            - --api
            - --api.insecure
            - --entrypoints.web.address=:80
            - --entrypoints.tcpep.address=:8000
            - --entrypoints.udpep.address=:9000/udp
            - --providers.kubernetesingress
            - --providers.kubernetescrd
          ports:
            - name: web
              containerPort: 80
            - name: admin
              containerPort: 8080
            - name: tcpep
              containerPort: 8000
            - name: udpep
              containerPort: 9000
---
apiVersion: v1
kind: Service
metadata:
  name: traefiktcp
spec:
  type: LoadBalancer
  selector:
    app: traefik
  ports:
    - protocol: TCP
      port: 80
      name: web
      targetPort: 80
    - protocol: TCP
      port: 8080
      name: admin
      targetPort: 8080
    - protocol: TCP
      port: 8000
      name: tcpep
      targetPort: 8000
---
apiVersion: v1
kind: Service
metadata:
  name: traefikudp
spec:
  type: LoadBalancer
  selector:
    app: traefik
  ports:
    - protocol: UDP
      port: 9000
      name: udpep
      targetPort: 9000
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: whoamiingressroute
spec:
  entryPoints:
    - web
  routes:
  #- match: Host(`foo`) && PathPrefix(`/bar`)
  - match: PathPrefix(`/bar`)
    kind: Rule
    services:
    - name: whoami
      port: 80
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP
metadata:
  name: ingressroute.tcp
spec:
  entryPoints:
    - tcpep
  routes:
  - match: HostSNI(`bar`)
    kind: Rule
    services:
      - name: whoamitcp
        port: 8080
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteUDP
metadata:
  name: ingressroute.udp
spec:
  entryPoints:
    - udpep
  routes:
  - kind: Rule
    services:
      - name: whoamiudp
        port: 8080
kind: Deployment
apiVersion: apps/v1
metadata:
  name: whoami
  labels:
    app: myapp
    name: whoami
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp
      task: whoami
  template:
    metadata:
      labels:
        app: myapp
        task: whoami
    spec:
      containers:
        - name: whoami
          image: harbor.hzwod.com/k8s/traefik/whoami
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: whoami
spec:
  ports:
    - name: http
      port: 80
  selector:
    app: myapp
    task: whoami
---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: whoamitcp
  labels:
    app: myapp
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp
      task: whoamitcp
  template:
    metadata:
      labels:
        app: myapp
        task: whoamitcp
    spec:
      containers:
        - name: whoamitcp
          image: harbor.hzwod.com/k8s/traefik/whoamitcp
          ports:
            - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: whoamitcp
spec:
  ports:
    - protocol: TCP
      port: 8080
  selector:
    app: myapp
    task: whoamitcp
---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: whoamiudp
  labels:
    app: myapp
    name: whoamiudp
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp
      task: whoamiudp
  template:
    metadata:
      labels:
        app: myapp
        task: whoamiudp
    spec:
      containers:
        - name: whoamiudp
          image: harbor.hzwod.com/k8s/traefik/whoamiudp
          ports:
            - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: whoamiudp
spec:
  ports:
    - port: 8080
  selector:
    app: myapp
    task: whoamiudp
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐