Kubernetes 集群部署 Traefik 2.0

Posted by     Aeric on Saturday, October 5, 2019

TOC

以前简单介绍了一下 Traefik 2.0 的新特性,这里我试着在已经存在的 Kubernetes 集群中部署 Traefik 2.0 ,需要注意的是新版本的 Traefik 在配置 Ingress 的路由规则的时候是通过自定义的 CRD 对象来实现的,并不像 1.0+ 版本使用 Kubernetes 的 annotations来完成路由规则配置。下面将介绍如何在 Kubernetes 环境下部署并配置 Traefik v2.0。

Traefik 2.0 部署环境说明

本次部署的 Traefik 2.0 的 Kubernetes 集群版本及其版本如下:

Traefik 版本:     2.0.6
Kubernetes 版本:  v1.15.3

Kubernetes 部署 Traefik

为了方便大家参考,我整理了一下配置清单文件,并上传到了 GitHub 上,具体地址可以参考: https://github.com/yeaheo/traefik2.0 欢迎大家借鉴。

本次部署的 namespace 我选择的是 traefik,可以根据自己实际情况做修改

创建 CRD 资源

在 Traefik 2.0 版本以后后,它开始使用 CRD(Custom Resource Definition)来完成路由规则配置,所以需要提前创建 CRD 资源

这里我贴出我之前整理的 yaml 文件(traefik-crd.yaml),直接应用即可:

# IngressRoute
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

---
# IngressRouteTCP
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

---
# MiddleWares
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

---
# TLSOption
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

部署:

➜ kubectl apply -f traefik-crd.yaml

创建 Traefik 配置文件

由于 Traefik 配置很多,通过 CLI 定义不是很方便,一般时候选择将其配置选项放到配置文件中,然后存入 ConfigMap,将其挂入 Traefik 中。

这里我贴出我之前整理的 yaml 文件(traefik-config.yaml),直接应用即可:

kind: ConfigMap
apiVersion: v1
metadata:
  name: traefik-config
  namespace: traefik
data:
  traefik.yaml: |-
    serversTransport:
      insecureSkipVerify: true
    api:
      insecure: true
      dashboard: true
      debug: true
    metrics:
      prometheus: ""
    entryPoints:
      web:
        address: ":80"
      websecure:
        address: ":443"
    providers:
      kubernetesCRD: ""
    log:
      filePath: ""
      level: error
      format: json
    accessLog:
      filePath: ""
      format: json
      bufferingSize: 0
      filters:
        retryAttempts: true
        minDuration: 20
      fields:
        defaultMode: keep
        names:
          ClientUsername: drop
        headers:
          defaultMode: keep
          names:
            User-Agent: redact
            Authorization: drop
            Content-Type: keep

部署:

➜ kubectl apply -f traefik-config.yaml

如果需要修改 Traefik 的配置,可以通过修改此文件再 apply 即可

创建 RBAC 资源

Kubernetes 在 1.6 版本中引入了基于角色的访问控制(RBAC)策略,方便对 Kubernetes 资源和 API 进行细粒度控制。Traefik 需要一定的权限,所以这里提前创建好 Traefik ServiceAccount 并分配一定的权限。

这里我贴出我之前整理的 yaml 文件(traefik-config.yaml),直接应用即可:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: traefik-ingress-controller
  namespace: traefik
---
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
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - traefik.containo.us
    resources:
      - ingressroutes
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - traefik.containo.us
    resources:
      - ingressroutetcps
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - traefik.containo.us
    resources:
      - tlsoptions
    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: traefik

部署:

➜ kubectl apply -f traefik-rbac.yaml

执行 Traefik 部署文件

需要说明的是,我部署时用的是 DaemonSet 的方式部署,并且将其指定到了带有 app=traefik-ingress 的节点上,部署时需要根据实际情况而定,要谨慎

设置节点标签:

➜ kubectl label nodes node-10.200.100.215 app=traefik-ingress

如果需要删除节点标签可以使用如下命令:

➜ kubectl label nodes node-10.200.100.215 app-

用 DaemonSet 方式部署,便于在多服务器间扩展,用 hostport 方式占用服务器 80、443 端口,方便流量进入。

这里我贴出我之前整理的 yaml 文件(traefik-deploy.yaml),直接应用即可:

---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: traefik-ingress-controller
  namespace: traefik
  labels:
    k8s-app: traefik
spec:
  selector:
    matchLabels:
      k8s-app: traefik
  template:
    metadata:
      name: traefik
      labels:
        k8s-app: traefik
    spec:
      serviceAccountName: traefik-ingress-controller
      terminationGracePeriodSeconds: 1
      containers:
        - image: traefik:latest
          name: traefik-ingress-lb
          ports:
            - name: web
              containerPort: 80
              hostPort: 80
            - name: websecure
              containerPort: 443
              hostPort: 443
            - name: admin
              containerPort: 8080
          resources:
            limits:
              cpu: 500m
              memory: 512Mi
            requests:
              cpu: 500m
              memory: 512Mi
          securityContext:
            capabilities:
              drop:
                - ALL
              add:
                - NET_BIND_SERVICE
          args:
            - --configfile=/config/traefik.yaml
          volumeMounts:
            - mountPath: "/config"
              name: "config"
      volumes:
        - name: config
          configMap:
            name: traefik-config 
      tolerations:
        - operator: "Exists"
      nodeSelector:
        app: "traefik-ingress"

部署:

➜ kubectl apply -f traefik-deploy.yaml

部署 SVC 文件

这里我贴出我之前整理的 yaml 文件(traefik-svc.yaml),直接应用即可:

apiVersion: v1
kind: Service
metadata:
  name: traefik
  namespace: traefik
spec:
  ports:
    - name: web
      port: 80
    - name: websecure
      port: 443
    - name: admin
      port: 8080
  selector:
    k8s-app: traefik

部署:

➜ kubectl apply -f traefik-svc.yaml

至此, Traefik 2.0 就部署完成了,接下来就是对其特性进行简单测试了。

➜ kubectl -n traefik get pods
NAME                               READY   STATUS    RESTARTS   AGE
traefik-ingress-controller-cx788   1/1     Running   1          1d

上述所有资源的配置情况均已测试为主,如果需要上生产需要根据实际情况做资源优化配置和取舍


comments powered by Disqus