在k8s中部署Traefik Ingress控制器

如果没有实现Ingress控制器仅仅定义Ingress资源是没有任何效果的。在本文中我们选择Traefik作为Ingress的控制器。

以下所有操作均是在K8S 1.19版本的集群下完成的,在低版本的集群中apiVersion可能会略有不同。

首先我们重建一个ingress-system的namespace(kubectl create namespace ingress-system),以下所有的操作都在这个namespace中进行。

Step#1 启用RBAC

我们首先需要向Traefik授予一些权限,以访问集群中运行的Pod、Endpoint和Service。为此,我们将使用ClusterRole和ClusterRoleBinding。

首先,创建一个新的ServiceAccount,为Traefik提供集群中的身份。

traefik-sa.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  namespace: ingress-system
  name: traefik-ingress-controller

接下来,创建一个ClusterRole,该权限将应用于Traefik的ServiceAccount。ClusterRole将允许Traefik在集群中的所有命名空间中管理和监视诸如Service、Endpoint、Secret和Ingress之类的资源。

traefik-cr.yaml
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: ingress-system
  name: traefik-ingress-controller
rules:
  - apiGroups:
      - ""
    resources:
      - services
      - endpoints
      - secrets
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - extensions
      - networking.k8s.io
    resources:
      - ingresses
      - ingressclasses
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - extensions
    resources:
      - ingresses/status
    verbs:
      - update

最后,要启用这些权限,我们应该将ClusterRole绑定到Traefik的ServiceAccount。这可以使用ClusterRoleBinding清单来完成:

traefik-crb.yaml
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: ingress-system
  name: traefik-ingress-controller
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: traefik-ingress-controller
subjects:
  - kind: ServiceAccount
    name: traefik-ingress-controller
    namespace: ingress-system

Step#2 部署Traefik

接下来,我们将Traefik部署到Kubernetes集群。 Traefik官方文档支持三种类型的部署:使用Deployment、使用DaemonSet或使用Helm图表。

在本文中,我们将使用Deployment部署。与其他选项相比,Deployment具有许多优势。例如,Deployment能确保更好的可伸缩性(向上和向下缩放),并为滚动更新提供良好的支持。

traefik-deployment.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
  namespace: ingress-system
  name: traefik
  labels:
    k8s-app: traefik
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s-app: traefik
  template:
    metadata:
      labels:
        k8s-app: traefik
    spec:
      serviceAccountName: traefik-ingress-controller
      terminationGracePeriodSeconds: 60
      hostNetwork: true
      nodeSelector:
        edge-node: "ingress"
      containers:
      - name: traefik
        image: traefik:v2.3.2
        imagePullPolicy: IfNotPresent
        ports:
        - name: web
          containerPort: 80
          hostPort: 80
        - name: admin
          containerPort: 8080
          hostPort: 8080
        args:
        - --api
        - --api.insecure
        - --api.dashboard
        - --log
        - --log.level=INFO
        - --entrypoints.web.address=:80
        - --providers.kubernetesingress

Step#3 编辑Ingress配置

traefik-ingress.yaml
kind: Ingress
apiVersion: networking.k8s.io/v1
metadata:
  name: myingress
  annotations:
    traefik.ingress.kubernetes.io/router.entrypoints: web

spec:
  rules:
    - host: example.com
      http:
        paths:
          - path: /bar
            pathType: Prefix
            backend:
              service:
                name: whoami
                port:
                  number: 80

Step#4 部署测试POD

apiVersion: v1
kind: Service
metadata:
  name: whoami

spec:
  ports:
    - name: http
      port: 80
  selector:
    app: traefiklabs
    task: whoami