关于kubernetes:Kubernetes-1205-安装traefik在腾讯云下的实践

75次阅读

共计 12862 个字符,预计需要花费 33 分钟才能阅读完成。

背景

集体应用 traefik 有差不多 1 - 2 年工夫,kubernetes ingress controller 代理有很多种形式 例如 ingress-nginx kong istio 等等。集体比拟习惯 traefik。从 19 年就开始应用。最早应用 traefik 不间接应用腾讯云私有云的 slb 是因为过后 slb 不能挂载多个证书,而我 kubernetes 的自建集群切实不想挂载多个 slb. 就偷懒用了 slb udp 绑定运行 traefik 节点的 80 443 端口。证书 tls 的 secret 间接挂载在 traefik 代理层下面。hsts http 跳转 https 的个性都配置在了 traefik 代理层下面。利用比拟少。qps 也没有那么高,这样的简略利用就满足了我的需要了

对于 traefik 的结缘

最早接触 traefik 是 Google 下面看 ingress controller 找到的 而后再阳明大佬的博客看到了 traefik 的实际 https://www.qikqiak.com/post/traefik2-ga/,还有超级小豆丁的博客 http://www.mydlq.club/article/41。两位大佬的博客是 kubernetes 初学者的宝藏博客值得珍藏拜读。
顺便吐个糟,用的 traefik2.4 版本 … 抄的豆丁大佬的..http://www.mydlq.club/article/107/ 哈哈哈

ingress controller 比照:

参照 https://zhuanlan.zhihu.com/p/109458069。

1. Kubernetes Gateway API 

v2.4 版本的扭转(在 Traefik v2.4 版本中减少了对 Kubernetes Gateway API 的反对)一下局部抄自豆丁大佬与官网文档 https://gateway-api.sigs.k8s.io/。

1、Gateway API 是什么

Gateway API 是由 SIG-NETWORK 社区治理的一个开源我的项目。它是在 Kubernetes 中对服务网络建模的资源的汇合。这些资源 -,GatewayClassGatewayHTTPRouteTCPRouteService等 - 旨在通过表现力,可扩大和面向角色由很多供应商实现的,并具备宽泛的行业反对接口演进 Kubernetes 服务网络。
留神:此我的项目以前被称为“服务 API”,直到 2021 年 2 月被重命名为“_Gateway API _”。

2、Gateway API 的指标

Gateway API 旨在通过提供可表白的,可扩大的,面向角色的接口来改善服务网络,这些接口已由许多供应商施行并取得了宽泛的行业反对。
网关 API 是 API 资源(服务、网关类、网关、HTTPRoute、TCPRoute 等)的汇合。这些资源独特为各种网络用例建模。

Gateway API 如何依据 Ingress 等以后规范进行改良?

  • 以下设计指标驱动了 Gateway API 的概念。这些证实了 Gateway 如何旨在改良 Ingress 等以后规范。
  • 面向角色- 网关由 API 资源组成,这些 API 资源对应用和配置 Kubernetes 服务网络的组织角色进行建模。
  • 便携式- 这不是改良,而是应该放弃不变。就像 Ingress 是具备许多实现的通用标准一样,Gateway API 也被设计为受许多实现反对的可移植标准。
  • 富裕表现力- 网关 API 资源反对外围性能,例如基于标头的匹配,流量加权以及其余只能通过自定义批注在 Ingress 中实现的性能。
  • 可扩大- 网关 API 容许在 API 的各个层上链接自定义资源。这样就能够在 API 构造内的适当地位进行精密的自定义。

其余一些值得注意的性能包含:

  • GatewayClasses -GatewayClasses 形式化负载平衡实现的类型。这些类使用户能够轻松,明确地理解通过 Kubernetes 资源模型能够应用的性能。
  • 共享网关和跨命名空间反对- 通过容许独立的 Route 资源绑定到同一网关,它们能够共享负载平衡器和 VIP。这容许团队(甚至跨命名空间)在没有间接协调的状况下平安地共享根底构造。
  • 类型化路由和类型化后端- 网关 API 反对类型化路由资源以及不同类型的后端。这使 API 能够灵便地反对各种协定(例如 HTTP 和 gRPC)和各种后端指标(例如 Kubernetes Services,存储桶或函数)。

如果想理解更多内容,能够拜访 Kubernetes Gateway API 文档。

2. traefik on kubernetes 实际

部署玩 Traefik 利用后,创立内部拜访 Kubernetes 外部利用的路由规定,能力从内部拜访 kubernetes 外部利用。Traefik 目前反对三种形式创立路由规定形式,一种是创立 Traefik 自定义 Kubernetes CRD 资源,另一种是创立 Kubernetes Ingress 资源,还有就是 v2.4 版本对 Kubernetes 扩大 API Kubernetes Gateway API 适配的一种形式,创立 GatewayClassGateway 与 HTTPRoute 资源
留神:这里 Traefik 是部署在 kube-system namespace 下,如果不想部署到配置的 namespace,须要批改上面部署文件中的 namespace 参数。当然了也能够新建一个独自的 namespace 去部署 traefik

1. 创立 CRD

参照 https://doc.traefik.io/traefik/reference/dynamic-configuration/kubernetes-crd/

traefik-crd.yaml

cat <<EOF >  traefik-crd.yaml 
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

---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: serverstransports.traefik.containo.us

spec:
  group: traefik.containo.us
  version: v1alpha1
  names:
    kind: ServersTransport
    plural: serverstransports
    singular: serverstransport
  scope: Namespaced
EOF
kubectl apply -f traefik-crd.yaml
  

2. 创立 RBAC 权限

cat <<EOF > traefik-rbac.yaml
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: traefik-ingress-controller
  namespace: kube-system

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
  - apiGroups:
      - traefik.containo.us
    resources:
      - middlewares
      - ingressroutes
      - traefikservices
      - ingressroutetcps
      - ingressrouteudps
      - tlsoptions
      - tlsstores
      - serverstransports
    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
EOF
 kubectl apply -f traefik-rbac.yaml 

3. 创立 Traefik 配置文件

# 号后为正文,跟 2.X 前几个版本一样。减少了 kubernetesIngress  kubernetesGateway 两种路由形式,过来只部署了 CRD 的形式。
cat <<EOF > traefik-config.yaml
kind: ConfigMap
apiVersion: v1
metadata:
  name: traefik-config
  namespace: kube-system
data:
  traefik.yaml: |-
    ping: ""                    ## 启用 Ping
    serversTransport:
      insecureSkipVerify: true  ## Traefik 疏忽验证代理服务的 TLS 证书
    api:
      insecure: true            ## 容许 HTTP 形式拜访 API
      dashboard: true           ## 启用 Dashboard
      debug: false              ## 启用 Debug 调试模式
    metrics:
      prometheus: ""            ## 配置 Prometheus 监控指标数据,并应用默认配置
    entryPoints:
      web:
        address: ":80"          ## 配置 80 端口,并设置入口名称为 web
      websecure:
        address: ":443"         ## 配置 443 端口,并设置入口名称为 websecure
    providers:
      kubernetesCRD: ""         ## 启用 Kubernetes CRD 形式来配置路由规定
      kubernetesIngress: ""     ## 启用 Kubernetes Ingress 形式来配置路由规定
      kubernetesGateway: ""     ## 启用 Kubernetes Gateway API
    experimental:               
      kubernetesGateway: true   ## 容许应用 Kubernetes Gateway API
    log:
      filePath: ""              ## 设置调试日志文件存储门路,如果为空则输入到控制台
      level: error              ## 设置调试日志级别
      format: json              ## 设置调试日志格局
    accessLog:
      filePath: ""              ## 设置拜访日志文件存储门路,如果为空则输入到控制台
      format: json              ## 设置拜访调试日志格局
      bufferingSize: 0          ## 设置拜访日志缓存行数
      filters:
        #statusCodes: ["200"]   ## 设置只保留指定状态码范畴内的拜访日志
        retryAttempts: true     ## 设置代理拜访重试失败时,保留拜访日志
        minDuration: 20         ## 设置保留申请工夫超过指定持续时间的拜访日志
      fields:                   ## 设置拜访日志中的字段是否保留(keep 保留、drop 不保留)defaultMode: keep       ## 设置默认保留拜访日志字段
        names:                  ## 针对拜访日志特地字段特地配置保留模式
          ClientUsername: drop  
        headers:                ## 设置 Header 中字段是否保留
          defaultMode: keep     ## 设置默认保留 Header 中字段
          names:                ## 针对 Header 中特地字段特地配置保留模式
            User-Agent: redact
            Authorization: drop
            Content-Type: keep
    #tracing:                     ## 链路追踪配置, 反对 zipkin、datadog、jaeger、instana、haystack 等 
    #  serviceName:               ## 设置服务名称(在链路追踪端收集后显示的服务名)#  zipkin:                    ## zipkin 配置
    #    sameSpan: true           ## 是否启用 Zipkin SameSpan RPC 类型追踪形式
    #    id128Bit: true           ## 是否启用 Zipkin 128bit 的跟踪 ID
    #    sampleRate: 0.1          ## 设置链路日志采样率(能够配置 0.0 到 1.0 之间的值)#    httpEndpoint: http://localhost:9411/api/v2/spans     ## 配置 Zipkin Server 端点
EOF
kubectl apply -f traefik-config.yaml

4. 设置节点 label 标签

Traefix 采纳 DaemonSet 形式构建,在须要装置的节点下面打上标签,这里在三个 work 节点都装置上了默认:

kubectl label nodes {sh-work-01,sh-work-02,sh-work-02} IngressProxy=true
kubectl get nodes --show-labels



留神:如果想删除标签,能够应用 kubectl label nodes k8s-node-03 IngressProxy- 命令。哈哈哈偶然须要去掉标签,不调度。

5、装置 Kubernetes Gateway CRD 资源

因为目前 Kubernetes 集群上默认没有装置 Service APIs,咱们须要提前装置 Gateway API 的 CRD 资源,须要确保在 Traefik 装置之前启用 Service APIs 资源。

kubectl apply -k "github.com/kubernetes-sigs/service-apis/config/crd?ref=v0.2.0"

不过因为 github 网络问题,根本无奈装置的。我是间接把 github 上包下载到本地采纳本地装置的形式装置
进入

进入 base 目录间接全副装置:

kubectl  apply  -f .

 6. Kubernetes 部署 Traefik

其实我就能够疏忽 443 了 …. 因为我想在 slb 哦 对也叫 clb. 间接做限度。对外只保留 80 端口。

cat <<EOF > traefik-deploy.yaml
apiVersion: v1
kind: Service
metadata:
  name: traefik
  namespace:kube-system
spec:
  ports:
    - name: web
      port: 80
    - name: websecure
      port: 443
    - name: admin
      port: 8080
  selector:
    app: traefik
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  namespace:kube-system
  name: traefik-ingress-controller
  labels:
    app: traefik
spec:
  selector:
    matchLabels:
      app: traefik
  template:
    metadata:
      name: traefik
      labels:
        app: traefik
    spec:
      serviceAccountName: traefik-ingress-controller
      terminationGracePeriodSeconds: 1
      containers:
        - image: ccr.ccs.tencentyun.com/XXXX/traefik:v2.4.3 
          name: traefik-ingress-lb
          ports:
            - name: web
              containerPort: 80
              hostPort: 80     
            - name: websecure
              containerPort: 443
              hostPort: 443        
            - name: admin
              containerPort: 8080  
          resources:
            limits:
              cpu: 2000m
              memory: 1024Mi
            requests:
              cpu: 1000m
              memory: 1024Mi
          securityContext:
            capabilities:
              drop:
                - ALL
              add:
                - NET_BIND_SERVICE
          args:
            - --configfile=/config/traefik.yaml
          volumeMounts:
            - mountPath: "/config"
              name: "config"
          readinessProbe:
            httpGet:
              path: /ping
              port: 8080
            failureThreshold: 3
            initialDelaySeconds: 10
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 5
          livenessProbe:
            httpGet:
              path: /ping
              port: 8080
            failureThreshold: 3
            initialDelaySeconds: 10
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 5    
      volumes:
        - name: config
          configMap:
            name: traefik-config 
      tolerations:              ## 设置容忍所有污点,避免节点被设置污点
        - operator: "Exists"
      nodeSelector:             ## 设置 node 筛选器,在特定 label 的节点上启动
        IngressProxy: "true
EOF
kubectl apply -f traefik-deploy.yaml 

kubectl get pods -n kube-system 验证

3. 配置路由规定,与腾讯云 clb 整合

1. slb 绑定 traefik http 端口

对于腾讯云负载平衡 slb or clb 能够参照文档 https://cloud.tencent.com/document/product/214 理解。过来应用 slb 用的 tcp 代理形式有一下起因:

  1. 过来的腾讯云 slb 不反对一个负载平衡挂载多个证书,集体不想启用多个 slb 绑定。
  2. 在 slb 下面配置域名比拟麻烦 ….. 没有再 traefik 配置文件外面写对我集体来说不便。

那我当初怎么就用 slb http https 代理形式了呢?

  1. 当然了 首先是能够挂载多个证书了
  2. 我在 slb 下面间接绑定了泛域名,前面的具体域名解析还是在我的 traefik 配置。然而我不必绑定证书了 ….
  3. http https 的形式我能够把日志间接写入他的 cos 对象存储和腾讯云本人的日志服务(感觉也是一个 kibana)能够间接剖析日志啊 …..


综上所述,来实现一下我集体的过程与思路

  1. 创立 slb .slb 绑定 work 节点 80 端口(这里我用的是负载平衡型,没有用传统型),没有问题吧?老老实实 ipv4 了没有启用 ipv6 这个就看集体具体需要吧。



应用了极度不要脸的形式 泛域名 …. 因为我罕用的也就这两个域名,具体的解析都还是我本人在 traefik 配置了。

对于证书 我这里可是扔好了 两个主二级域名,泛域名证书间接扔上了 ……

四个前面配置我都绑定了 80 交给 traefik 解决吧。权重我都设置的一样的,有其余需要的能够依据本人须要设置呢。

2. 配置路由规定

  Traefik 利用曾经部署实现,并且和 slb 负载平衡集成也大抵实现了。然而想让内部拜访 Kubernetes 外部服务,还须要配置路由规定,下面部署 Traefik 时开启了 traefik dashboard,这是 Traefik 提供的视图看板,所以,首先配置基于 http 的 Traefik Dashboard 路由规定,使内部可能拜访 Traefik Dashboard。这里别离应用 CRDIngress 和 Kubernetes Gateway API 三种形式进行演示,过来版本罕用的是 CRD 的形式。https 的形式我就疏忽了交给 slb 负载平衡层了。

1. CRD 形式

过来我集体部署利用都是 crd 形式,本人老把这种形式叫做 ingressroute 形式。

cat <<EOF> traefik-dashboard-route-http.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: traefik-dashboard-route
  namespaces: kube-system
spec:
  entryPoints:
  - web
  routes:
  - match: Host(\`traefik.saynaihe.com\`)
    kind: Rule
    services:
      - name: traefik
        port: 8080
EOF
kubectl apply -f traefik-dashboard-route-http.yaml       


对于 match: Host(\`traefik.saynaihe.com\`) 加本义符应该都能看明确了,不加本义符会是这样的

我貌似又忘了加 namespace 截图中,理论我可是加上了 … 老容易往事。哎,我不是两个泛域名吗?特意做了两个 ingressoute 做下测试

而后绑定本地 hosts 绑定 host

C:\Windows\System32\drivers\etc


遮挡的有点多 …. 然而 这就是两个都路由过去了啊

对于 https 能够疏忽了间接挂载在 slb 层了啊。而后 http 强制跳转 https 也能够在 slb 层下面配置了

流氓玩法强跳 …. 测试也是胜利的 ….

2. Ingress 形式

ingress 的形式根本就是 https://kubernetes.io/zh/docs/concepts/services-networking/ingress/ kubernetes 常见的 ingress 形式吧?
持续拿 dashboard 做演示

cat <<EOF> traefik-dashboard-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: traefik-dashboard-ingress
  namespace: kube-system
  annotations:
    kubernetes.io/ingress.class: traefik  
    traefik.ingress.kubernetes.io/router.entrypoints: web
spec:
  rules:
  - host: traefik1.saynaihe.com
    http:
      paths:
      - pathType: Prefix
        path: /
        backend:
          service:
            name: traefik
            port:
              number: 8080
EOF
kubectl apply -f traefik-dashboard-ingress.yaml


因为端口强制跳转了设置,间接 https 了哈哈哈验证实现

3、形式三:应用 Kubernetes Gateway API

对于Kubernetes Gateway API 能够通过CRD 形式创立路由规定

          CRD  自定义资源强调一下
详情能够参考:[https://doc.traefik.io/traefik/v2.4/routing/providers/kubernetes-gateway/](https://doc.traefik.io/traefik/v2.4/routing/providers/kubernetes-gateway/)
  • GatewayClass: GatewayClass 是根底构造提供程序定义的群集范畴的资源。此资源示意能够实例化的网关类。个别该资源是用于反对多个基础设施提供商用处的,这里咱们只部署一个即可。
  • Gateway: Gateway 与基础设施配置的生命周期是 1:1。当用户创立网关时,GatewayClass 控制器会提供或配置一些负载平衡基础设施。
  • HTTPRoute: HTTPRoute 是一种网关 API 类型,用于指定 HTTP 申请从网关侦听器到 API 对象(即服务)的路由行为。

1. 创立 GatewayClass

*#创立 GatewayClass 资源 kubernetes-gatewayclass.yaml 文件 *
参照:https://doc.traefik.io/traefik/v2.4/routing/providers/kubernetes-gateway/#kind-gatewayclass

cat <<EOF> kubernetes-gatewayclass.yaml
kind: GatewayClass
apiVersion: networking.x-k8s.io/v1alpha1
metadata:
  name: traefik
spec:
  # Controller is a domain/path string that indicates
  # the controller that is managing Gateways of this class.
  controller: traefik.io/gateway-controller
EOF
kubectl apply -f kubernetes-gatewayclass.yaml

2 配置 HTTP 路由规定(Traefik Dashboard 为例)

创立 Gateway 资源 http-gateway.yaml 文件

cat <<EOF> http-gateway.yaml
apiVersion: networking.x-k8s.io/v1alpha1
kind: Gateway
metadata: 
  name: http-gateway
  namespace: kube-system
spec: 
  gatewayClassName: traefik
  listeners: 
    - protocol: HTTP
      port: 80
      routes: 
        kind: HTTPRoute
        namespaces:
          from: All
        selector:
          matchLabels:
            app: traefik
EOF
kubectl apply -f http-gateway.yaml            

创立 HTTPRoute 资源 traefik-httproute.yaml 文件

cat <<EOF> traefik-httproute.yaml
apiVersion: networking.x-k8s.io/v1alpha1
kind: HTTPRoute
metadata:
  name: traefik-dashboard-httproute
  namespace: kube-system
  labels:
    app: traefik
spec:
  hostnames:
    - "traefi2.saynaihe.com"
  rules:
    - matches:
        - path:
            type: Prefix
            value: /
      forwardTo:
        - serviceName: traefik
          port: 8080
          weight: 1
EOF
kubectl apply -f traefik-httproute.yaml            

这里就出问题了 …..,无法访问,认真看了下文档 https://doc.traefik.io/traefik/providers/kubernetes-gateway/

全副删除一次重新部署吧将 2.5 中版本变成 v0.1.0 就好了 …. 图就不上了根本步骤是一样的。

注:都没有做域名解析,本地绑定了 host。saynaihe.com 域名只是做演示。没有理论搞 …. 因为我没有做备案。当初不备案的根本绑上就被扫描到封了。用正式域名做的试验。另外养成的习惯用 CRD 习惯了 … 部署利用根本集体都用了 CRD 的形式 —ingressroute。ingress 的形式是更适宜从 ingress-nginx 迁徙到 traefik 应用了。至于 Kubernetes Gateway API 集体还是图个陈腐,没有整明确。v0.2.0 不能用 … 就演示下了.

正文完
 0