Kubernetes 服务入口管理 Traefik Ingress Controller

时间:2021-12-16 16:23:24

Kubernetes 服务入口管理 Traefik Ingress Controller

前面部署了 kubernetes/ingress-nginx 作为 Ingress Controller,使用 Nginx 反向代理与负载,通过 Ingress Controller 不断的跟 Kubernetes API 交互,实时获取后端 Service、Pod 等的变化,然后动态更新 Nginx 配置,并刷新使配置生效。Traefik 是一个用 Golang 开发的轻量级的 Http 反向代理和负载均衡器软件,由于可以自动化配置和刷新 backend 节点,目前可以被绝大部分容器平台与组件支持,例如 Docker, Swarm mode, Kubernetes,, Consul, Etcd, Rancher, Eureka 等。Traefik 设计的就能够实时跟 Kubernetes API 交互,感知后端 Service、Pod 等的变化,自动更新配置并热重载,使用上大体上差不多,但是 Traefik 更快速更方便,同时支持更多的特性,使反向代理、负载均衡更直接,更高效。

Traefik 特性

  • 自动化动态配置无需服务重启
  • 支持多个负载平衡算法
  • 支持 Let’s Encrypt (通配符支持) 向您的微服务提供 HTTPS
  • 支持熔断,重试
  • 集群模式的高可用性
  • 提供简洁的 UI 界面
  • 支持 Websocket, HTTP/2, GRPC 协议
  • 提供监控的服务(Rest、Prometheus、Datadog、Statsd、InfluxDB)
  • 保留访问日志(JSON,CLF)
  • 快速
  • 支持 Rest API
  • 使用二进制文件打包,并作为一个 docker 镜像提供

部署 Traefik

所有的配置文件可以在官方的 github 仓库中找到,按照官方文档来即可。

Role Based Access Control configuration (Kubernetes 1.6+ only)

---
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
---
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: kube-system

Deploy Traefik using a Deployment or DaemonSet

DaemonSet 会在每台 Node 节点上都创建 Pod 而 Deployment  是人为控制的副本数量(根据实际需求来取决),这里使用 DaemonSet 类型来部署 Traefik。

部署 Traefik(修改 hostNetwork: true)

#https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/traefik-ds.yamlvi traefik-ds.yaml

vi traefik-ds.yaml

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: traefik-ingress-controller
  namespace: kube-system
---
kind: DaemonSet
apiVersion: extensions/v1beta1
metadata:
  name: traefik-ingress-controller
  namespace: kube-system
  labels:
    k8s-app: traefik-ingress-lb
spec:
  template:
    metadata:
      labels:
        k8s-app: traefik-ingress-lb
        name: traefik-ingress-lb
    spec:
      serviceAccountName: traefik-ingress-controller
      terminationGracePeriodSeconds: 60
      hostNetwork: true
      restartPolicy: Always
      containers:
      - image: traefik
        name: traefik-ingress-lb
        ports:
        - name: http
          containerPort: 80
          hostPort: 80
        - name: admin
          containerPort: 8080
          hostPort: 8080
        securityContext:
          capabilities:
            drop:
            - ALL
            add:
            - NET_BIND_SERVICE
        args:
        - --api
        - --kubernetes
        - --logLevel=INFO
---
kind: Service
apiVersion: v1
metadata:
  name: traefik-ingress-service
  namespace: kube-system
spec:
  selector:
    k8s-app: traefik-ingress-lb
  ports:
    - protocol: TCP
      port: 80
      name: web
    - protocol: TCP
      port: 8080
      name: admin
部署查看
  
  
  
$ kubectl apply -f traefik-ds.yaml
serviceaccount/traefik-ingress-controller unchanged
daemonset.extensions/traefik-ingress-controller configured
service/traefik-ingress-service unchanged
$ kubectl apply -f traefik-ds.yaml
serviceaccount/traefik-ingress-controller unchanged
daemonset.extensions/traefik-ingress-controller unchanged
service/traefik-ingress-service unchanged
[root@kubernetes-master k8s]# kubectl -n kube-system get pod -o wide
NAME                                        READY   STATUS    RESTARTS   AGE   IP              NODE                NOMINATED NODE
traefik-ingress-controller-6fk9n            1/1     Running   0          41m   10.38.0.0       kubernetes-node-2   <none>
traefik-ingress-controller-f7kmc            1/1     Running   0          41m   10.40.0.1       kubernetes-node-1   <none>

备注:上述由于修改 hostNetwork: true ,其实已经在每个 Node 节点开放了 80 与 8080 端口,80 提供正常服务,8080 是其自带的 UI 界面。

Node 节点查看开放的端口

$  netstat -ntlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name      
tcp6       0      0 :::8080                 :::*                    LISTEN      10253/traefik       
tcp6       0      0 :::80                   :::*                    LISTEN      10253/traefik

Ingress 方式暴露 Traefik Web UI

#  https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/ui.yaml
vi traefik-web-ui.yaml

---
apiVersion: v1
kind: Service
metadata:
  name: traefik-web-ui
  namespace: kube-system
spec:
  selector:
    k8s-app: traefik-ingress-lb
  ports:
  - name: web
    port: 80
    targetPort: 8080
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: traefik-web-ui
  namespace: kube-system
  annotations:
    kubernetes.io/ingress.class: traefik
spec:
  rules:
  - host: traefik-ui.com
    http:
      paths:
      - backend:
          serviceName: traefik-web-ui
          servicePort: 80

部署查看

$ kubectl apply -f traefik-web-ui.yaml
service/traefik-web-ui created
ingress.extensions/traefik-web-ui created
$ kubectl get ingress -o wide --all-namespaces   
NAMESPACE     NAME             HOSTS            ADDRESS   PORTS   AGE
kube-system   traefik-web-ui   traefik-ui.com             80      18s

配置Host文件

172.23.216.49 k8s.dashboard.com
172.23.216.49 traefik-ui.com

访问 http://traefik-ui.com/dashboard/ 通过 80 端口转发。

Kubernetes 服务入口管理 Traefik Ingress Controller

模拟部署一个程序

下面模拟部署一个程序,已 Nginx  为例:

vi nginx-deployment.yaml

apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  template:
    metadata:
      labels:
        name: nginx-svc
        namespace: default
spec:
  selector:
    run: nginx-pod
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: nginx-pod
spec:
  replicas: 4
  template:
    metadata:
      labels:
        run: nginx-pod
    spec:
      containers:
      - name: nginx
        image: nginx:1.15.5
        ports:
        - containerPort: 80
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ngx-ing
  annotations:
    kubernetes.io/ingress.class: traefik
spec:
  rules:
  - host: k8s.nginx.com
    http:
      paths:
      - backend:
          serviceName: nginx-svc
          servicePort: 80

部署查看

$ kubectl apply -f nginx-deployment.yam
$  kubectl get pods  --all-namespaces
NAMESPACE     NAME                                        READY   STATUS    RESTARTS   AGE
default       nginx-pod-5b5bc94455-ndcl6                  1/1     Running   0          18m
default       nginx-pod-5b5bc94455-nptm5                  1/1     Running   0          18m
default       nginx-pod-5b5bc94455-ptvzp                  1/1     Running   0          18m
default       nginx-pod-5b5bc94455-vw667                  1/1     Running   0          18m

修改 Host 文件

172.23.216.49 k8s.dashboard.com
172.23.216.49 traefik-ui.com
172.23.216.49 k8s.nginx.com

访问 k8s.nginx.com 即可,查看 traefik-ui(对应 4个 Pod)。

Kubernetes 服务入口管理 Traefik Ingress Controller

HTTPS 证书配置

生成自签名证书

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=traefik-ui.com"
kubectl -n kube-system create secret tls traefik-ui-tls-cert --key=tls.key --cert=tls.crt

配置

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: traefik-web-ui
  namespace: kube-system
  annotations:
    kubernetes.io/ingress.class: traefik
spec:
  rules:
  - host: traefik-ui.com
    http:
      paths:
      - backend:
          serviceName: traefik-web-ui
          servicePort: 80
  tls:
   - secretName: traefik-ui-tls-cert

其他问题:

Basic Authentication

如果想让 traefik-web-ui 需要验证才能访问,可以配置 Basic Authentication,具体看官方文档。

https://docs.traefik.io/user-guide/kubernetes/#basic-authentication

GRpc 配置

https://docs.traefik.io/user-guide/grpc/

服务权重配置

https://docs.traefik.io/user-guide/kubernetes/#traffic-splitting

证书配置

https://docs.traefik.io/user-guide/examples/#http-redirect-on-https

REFER:
https://docs.traefik.io/user-guide/kubernetes/
https://github.com/containous/traefik/tree/master/examples/k8s
http://blog.leanote.com/post/criss_sun/K8S%E4%B9%8Btraefik
http://blog.51cto.com/ylw6006/2119784