traefik2.0

时间:July 2, 2020 分类:

目录:

部署方式

CRD

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: 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: ingressroutetcps.traefik.containo.us

spec:
  group: traefik.containo.us
  version: v1alpha1
  names:
    kind: IngressRouteTCP
    plural: ingressroutetcps
    singular: ingressroutetcp
  scope: Namespaced

configmap

apiVersion: v1
data:
  traefik.yml: |
    global:
      checkNewVersion: true
      sendAnonymousUsage: true
    serversTransport:
      forwardingTimeouts:
        dialTimeout: 30
      maxIdleConnsPerHost: 42
    accessLog:
      filePath: /var/log/traefik/access.log
      format: json
    log:
      filePath: /var/log/traefik/traefik.log
      level: debug
    api:
      insecure: true
      dashboard: true
      debug: true
    entryPoints:
      EntryPoint0:
        address: 0.0.0.0:80
        transport:
          lifeCycle:
            requestAcceptGraceTimeout: 42
            graceTimeOut: 42
          respondingTimeouts:
            readTimeout: 42
            writeTimeout: 42
            idleTimeout: 42
    metrics:
      prometheus:
        buckets:
        - 20
        - 42
        addEntryPointsLabels: true
        addServicesLabels: true
    providers:
      kubernetesCRD:
        endpoint: https://kubemaster.cluster:6443
kind: ConfigMap
metadata:
  name: traefik-config-v2
  namespace: kube-system

serviceaccount

kubectl create serviceaccount traefik-ingress-v2 --namespace=kube-system

RBAC

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: traefik-ingress-v2
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-v2
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: traefik-ingress-v2
subjects:
  - kind: ServiceAccount
    name: traefik-ingress-v2
    namespace: default

镜像认证

kubectl create  secret docker-registry aliyun-registry --docker-server=registry-vpc.cn-beijing.aliyuncs.com  --docker-username=xxxxxx --docker-password=xxxxxx --namespace=kube-system

daemonset

apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  labels:
    app: traefik-ingress
  name: traefik-ingress
  namespace: kube-system
spec:
  selector:
    matchLabels:
      app: traefik-ingress
  template:
    metadata:
      labels:
        app: traefik-ingress
    spec:
      containers:
      - args:
        - --configfile=/etc/traefik/traefik.yml
        image: reg.hualala.com/ops/traefik:v2.2.0
        imagePullPolicy: IfNotPresent
        name: traefik-ingress
        ports:
        - containerPort: 80
          hostPort: 80
          name: http
          protocol: TCP
        - containerPort: 8080
          hostPort: 8080
          name: admin
          protocol: TCP
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
        - mountPath: /var/log
          name: volume-image-0
        - mountPath: /etc/traefik
          name: config
      dnsPolicy: ClusterFirstWithHostNet
      hostNetwork: true
      nodeSelector:
        node-role.kubernetes.io/ingress: "true"
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      serviceAccount: traefik-ingress-controller
      serviceAccountName: traefik-ingress-controller
      terminationGracePeriodSeconds: 30
      volumes:
      - hostPath:
          path: /home/logs
          type: ""
        name: volume-image-0
      - configMap:
          defaultMode: 420
          name: traefik-config
        name: config
  templateGeneration: 12
  updateStrategy:
    rollingUpdate:
      maxUnavailable: 1
    type: OnDelete

ingress配置

在traefik2.0版本抛弃了kubernetes自带的ingress,使用了CRD,分别是四个自定义的CRD

  • ingressroutes http/h2c服务配置
  • ingressroutetcps tcp服务配置
  • tlsoptions 证书配置
  • middlewares 中间件配置

http/grpc配置

apiVersion: traefik.containo.us/v1alpha1
# 采用crd自定义资源
kind: IngressRoute
metadata:
  creationTimestamp: null
  name: online-store-api-http
  # 资源属于namespace资源
  namespace: pre
spec:
  # entrypoints 采用默认就可以,只有非80端口才需要配置
  entryPoints: []
  routes:
  - kind: Rule
    # Host 名字就是域名 PathPrefix就是Path
    match: Host(`pre.onlinestore.api.hualala.com`) && PathPrefix(`/`)
    middlewares: []
    priority: 0
    services:
      # 对应svc的名字
    - name: online-store-api
      # 服务端口号,注意在traefik1.x时可以使用portName在2.0的时候只能使用端口号
      port: 8080
      # 协议,已知只能增加http跟h2c(grpc)
      scheme: http

在1.0版本的时候traefik只能使用http/h2c服务配置,官方提供了可以将1.0配置转换为2.0配置的工具traefik-migration-tool

不过在1.0版本ingress的port可以为svc的port_name,而在2.0版本ingress的port是端口号,如果在1.0写的port_name会被转化为0,所以还是自行解析yaml吧

tcp配置

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP
metadata:
  name: redis
spec:
  entryPoints:
    - Tcp
  routes:
   # HOSTSNI 这个是根据证书来确认,如果不走证书,只能设置成*
  - match: HostSNI(`*`)
    services:
    - name: zxl-redis
      port: 6379

中间件

重试

apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: retry
spec:
  retry:
    attempts: 4

中间件重试的时候不会记录在traefik日志里RetryAttempts字段

限速

策略

  • average 在指定时间单位内,可以访问的速率
  • period 指定的时间,默认为1s
  • burst 排队数量

分组

可以根据特性把部分相同的特征划分为一个组里,组里共享资源 顺序为ipStrategy,requestHeaderName,requestHost

示例,根据限制相同header User-Agent请求30s内请求为1,排队数量为1

apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: limit
  namespace: op
spec:
  rateLimit:
    average: 1
    burst: 1
    period: 30s
    sourceCriterion:
      requestHeaderName: User-Agent

熔断

熔断是当后端服务发生错误时服务会屏蔽掉不健康的节点

错误码熔断测试

ResponseCodeRatio

认证

日志字段

{
    #DROP
    "ClientAddr": "172.16.47.235:61084",
    "ClientHost": "172.16.47.235",
    "ClientPort": "61084",

     # DROP
    "ClientUsername": "-",

     # DROP
     # Content-Length字段长度
    "DownstreamContentSize": 0,
    "DownstreamStatus": 200,
    "Duration": 30014915206,
     # DROP
    "OriginContentSize": 0,
    "OriginDuration": 30014687343,
    "OriginStatus": 200,

     # 自身耗时
    "Overhead": 227863,

     # HTTP Host header
    "RequestAddr": "pre.whoami.hualala.com",

     # 请求的body大小
    "RequestContentSize": 0,

     #  DROP
     # traefik在启动后处理的请求数量
    "RequestCount": 1,
    "RequestHost": "pre.whoami.hualala.com",
    "RequestMethod": "HEAD",
    "RequestPath": "/",

     # DROP
    "RequestPort": "-",
    "RequestProtocol": "HTTP/1.1",
    "RequestScheme": "http",

     # 重试次数,当中间件里使用重试时不会在这个里边显示
    "RetryAttempts": 0,
    "RouterName": "op-whoami-http-6877f32dc7cd09d60019@kubernetescrd",

     # DROP  字段跟ServiceURL.Host相同
    "ServiceAddr": "10.33.15.161:80",
    "ServiceName": "op-whoami-http-6877f32dc7cd09d60019@kubernetescrd",
    "ServiceURL": {
        "Scheme": "http",
        "Opaque": "",
        "User": null,
        "Host": "10.33.15.161:80",
        "Path": "",
        "RawPath": "",
        "ForceQuery": false,
        "RawQuery": "",
        "Fragment": ""
    },
    "StartLocal": "2020-05-19T16:00:22.414362357+08:00",
     //DROP
    "StartUTC": "2020-05-19T08:00:22.414362357Z",
    "entryPointName": "EntryPoint0",
    "level": "info",
    "msg": "",
    "time": "2020-05-19T16:00:52+08:00"
}