traefik篇- 理论介绍、安装配置以及使用详解

1 traefik理论概览

https://docs.traefik.io/
https://docs.traefik.cn/user-guide/kubernetes

假设你已经在你的基础设施上部署了一堆微服务。你可能使用了一个服务发现系统(例如 etcd 或 consul)或者一个资源管理框架(swarm,Mesos/Marathon)来管理所有这些服务。

如果你想让你的用户去从互联网访问你的某些微服务, 你就必需使用虚拟hosts或前缀路径来配置一个反向代理:

  • 域名 api.domain.com 将指向你的私有网络中的微服务 api
  • 路径 domain.com/web 将指向你的私有网络中的微服务 web
  • 域名 backoffice.domain.com 将指向你的私有网络中的微服务 backoffice ,在你的多台实例之间负载均衡

但是,微服务在会经常被添加、移除、杀死或更新,可能一天之内就会发生许多次。
传统的反向代理原生不支持动态配置。你不可能轻易的通过热更新更改它们的配置。
这时,Træfɪk就诞生了。

2 安装配置

https://docs.traefik.io/getting-started/install-traefik/#use-the-binary-distribution

2.1 二进制安装

wget https://github.com/containous/traefik/releases/download/v2.2.8/traefik_v2.2.8_linux_amd64.tar.gz
tar xvfz traefik_v2.2.8_linux_amd64.tar.gz
./traefik --help

2.2 docker安装

docker run -d -p 8080:8080 -p 80:80 \
    -v $PWD/traefik.toml:/etc/traefik/traefik.toml traefik:v2.2

2.3 helm3安装traefik v1

  • 前提:k8s集群1.14+,helm 3.X
helm repo add stable https://kubernetes-charts.storage.googleapis.com/
helm repo update
helm install traefik stable/traefik --set dashboard.enabled=true,serviceType=NodePort,dashboard.domain=dashboard.traefik,rbac.enabled=true  --namespace kube-system

在这里插入图片描述
在这里插入图片描述

查看service的端口
在这里插入图片描述
在本机的/etc/hosts中添加解析
172.16.212.11 dashboard.traefik
访问 http://dashboard.traefik:12577即可!

在这里插入图片描述

此时,无法访问https

2.4 helm3安装traefik v2

  • 安装
helm repo add traefik https://containous.github.io/traefik-helm-chart
helm repo update
helm install traefik traefik/traefik
  • 修改service端口暴露方式
kubectl edit service traefik
spec:
  clusterIP: 192.168.255.168
  externalTrafficPolicy: Cluster
  ports:
 - name: web
    nodePort: 30080
    port: 80
    protocol: TCP
    targetPort: web
 - name: websecure
    nodePort: 30443
    port: 443
    protocol: TCP
    targetPort: websecure
  selector:
    app.kubernetes.io/instance: traefik
    app.kubernetes.io/name: traefik
  sessionAffinity: None
  type: NodePort
  • 转发dashboard
# dashboard.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: dashboard
spec:
  entryPoints:
    - web
  routes:
    - match: Host(`traefik.guici.com`) && (PathPrefix(`/dashboard`) || PathPrefix(`/api`))
      kind: Rule
      services:
        - name: api@internal
          kind: TraefikService
          
kubectl apply -f dashboard.yaml

在本机的/etc/hosts中添加解析
172.16.212.11 traefik.guici.com
访问 http://traefik.guici.com:30080/dashboard/ 即可!

在这里插入图片描述

此时无法访问https
在这里插入图片描述

2.5 yaml方式部署traefik v2

详见https://www.qikqiak.com/post/traefik-2.1-101/

  • 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: 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: 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: traefikservices.traefik.containo.us
spec:
  group: traefik.containo.us
  version: v1alpha1
  names:
    kind: TraefikService
    plural: traefikservices
    singular: traefikservice
  scope: Namespaced
  • rbac.yaml
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: traefik
rules:
  - apiGroups:
      - ""
    resources:
      - pods
      - 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:
      - ingressroutes
      - ingressroutetcps
      - middlewares
      - tlsoptions
      - traefikservices
    verbs:
      - get
      - list
      - watch

---
kind: ServiceAccount
apiVersion: v1
metadata:
  name: traefik
  namespace: kube-system

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

  • deployment.yaml (使用了下面提到的使用阿里云dns作为获取证书的途径,需要创建secret)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: traefik
  namespace: kube-system
  labels:
    app: traefik
spec:
  selector:
    matchLabels:
      app: traefik
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: traefik
    spec:
      serviceAccountName: traefik
      tolerations:
      - operator: "Exists"
      nodeSelector:
        kubernetes.io/hostname: node-name
      volumes:
      - name: acme
        hostPath:
          path: /data/k8s/traefik/acme
      containers:
      - image: traefik:2.2.1
        name: traefik
        ports:
        - name: web
          containerPort: 80
          hostPort: 80
        - name: websecure
          containerPort: 443
          hostPort: 443
        - name: mongo
          hostPort: 27017
          containerPort: 27017
        - name: postgres
          hostPort: 5432
          containerPort: 5432
        - name: redis
          hostPort: 6379
          containerPort: 6379
        args:
        - --entryPoints.web.address=:80
        - --entryPoints.websecure.address=:443
        - --entryPoints.mongo.address=:27017
        - --entryPoints.postgres.address=:5432
        - --entryPoints.redis.address=:6379
        - --api=true
        - --api.dashboard=true
        - --ping=true
        - --providers.kubernetesingress
        - --providers.kubernetescrd
        - --serversTransport.insecureSkipVerify=true
        # - --providers.file.filename=/config/traefik-tls.toml
        - --log.level=INFO
        - --accesslog
        # 使用 dns 验证方式
        - --certificatesResolvers.ali.acme.dnsChallenge.provider=alidns
        # 邮箱配置
        - --certificatesResolvers.ali.acme.email=ych_1024@163.com
        # 保存 ACME 证书的位置
        - --certificatesResolvers.ali.acme.storage=/etc/acme/acme.json
        # 下面是用于测试的ca服务,如果https证书生成成功了,则移除下面参数
        # - --certificatesresolvers.ali.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory
        envFrom:
        - secretRef:
            name: traefik-alidns-secret    #这个secret是需要手动创建的,详见2.6.1
            # ALICLOUD_ACCESS_KEY
            # ALICLOUD_SECRET_KEY
            # ALICLOUD_REGION_ID
        volumeMounts:
        - name: acme
          mountPath: /etc/acme
        # - name: config
        #   mountPath: /config
        # - name: certs
        #   mountPath: /certs
        resources:
          requests:
            cpu: "50m"
            memory: "50Mi"
          limits:
            cpu: "200m"
            memory: "100Mi"
        securityContext:
          allowPrivilegeEscalation: true
          capabilities:
            drop:
            - ALL
            add:
            - NET_BIND_SERVICE
        readinessProbe:
          httpGet:
            path: /ping
            port: 8080
          failureThreshold: 1
          initialDelaySeconds: 10
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 2
        livenessProbe:
          httpGet:
            path: /ping
            port: 8080
          failureThreshold: 3
          initialDelaySeconds: 10
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 2
        
  • dashboard.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: traefik-dashboard
spec:
  routes:
  - match: Host(`traefik.guici.com`)
    kind: Rule
    services:
    - name: api@internal
      kind: TraefikService

---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: traefik-dashboard-tls
spec:
  entryPoints:
    - websecure
  routes:
  - match: Host(`traefik.qikqiak.com`)
    kind: Rule
    services:
    - name: api@internal
      kind: TraefikService
  tls:
    certResolver: ali
    domains:
    - main: "*.qikqiak.com"
  # tls:
  #   secretName: who-tls
# ---
# apiVersion: traefik.containo.us/v1alpha1
# kind: Middleware
# metadata:
#   name: auth
# spec:
#   basicAuth:
#     secret: secretName # Kubernetes secret named "secretName"

在这里插入图片描述

2.6 配置支持https访问

用 HTTPS 访问应用必然就需要证书

2.6.1 使用阿里云的dns提供商获取证书——这种方式是生产常用方式

  • 准备工作

需要api接口的accesskey,secretkey和阿里云区域名称;

  • 1)创建secret
kubectl -n default create secret generic traefik-alidns-secret \
--from-literal=ALICLOUD_ACCESS_KEY=<your-access-key> \
--from-literal=ALICLOUD_SECRET_KEY=<your-secret-key> \
--from-literal=ALICLOUD_REGION_ID=<aliyun-region>
  • 2)编辑deploy
  template:
    metadata:
      labels:
        app: traefik
    spec:
      serviceAccountName: traefik
      tolerations:
      - operator: "Exists"
      nodeSelector:
        traefik: "true"
      containers:
      - image: traefik:v2.1.9
        name: traefik
        ports:
        - name: web
          containerPort: 80
          hostPort: 80
        - name: websecure
          containerPort: 443
          hostPort: 443
        - name: metrics
          hostPort: 8082
          containerPort: 8082
        args:
        - --entryPoints.web.address=:80
        - --entryPoints.websecure.address=:443
        - --api=true
        - --api.dashboard=true
        - --ping=true
        - --providers.kubernetesingress
        - --providers.kubernetescrd
        - --log.level=INFO
        - --accesslog
        - --accesslog.filepath=/logs/access.log
        - --log
        - --log.filepath=/logs/traefik.log
        - --serverstransport.insecureskipverify=true
        - --certificatesResolvers.ali.acme.dnsChallenge.provider=alidns   	#1
        - --certificatesResolvers.ali.acme.email=example@qq.com				#2
        - --certificatesResolvers.ali.acme.storage=/etc/acme/acme.json		#3
        - --entryPoints.metrics.address=:8082
        - --metrics.prometheus=true
        - --metrics.prometheus.buckets=0.100000, 0.300000, 1.200000, 5.000000
        - --metrics.prometheus.addEntryPointsLabels=true
        - --metrics.prometheus.addServicesLabels=true
        - --metrics.prometheus.entryPoint=metrics
        - --metrics.prometheus.manualrouting=true
        envFrom:
        - secretRef:
            name: traefik-alidns-secret				#4

2.6.2 也可以使用自签名的证书——一般只在测试时用

#创建证书
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout traefik-tls.key -out traefik-tls.crt -subj "/CN=traefik.qikqiak.com"

#通过 Secret 对象来引用证书文件
kubectl create secret tls traefik-tls --cert=traefik-tls.crt --key=traefik-tls.key

#修改 ingressroute
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: traefik-dashboard-tls
spec:
  entryPoints:
    - websecure
  routes:
  - match: Host(`traefik.qikqiak.com`)
    kind: Rule
    services:
    - name: api@internal
      kind: TraefikService
  tls:
    secretName: traefik-tls

在这里插入图片描述

由于用的是自签名证书,所以不受信任

3 ingressroute代理设置

3.1 http

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: ingressroute # 修改名称
  namespace: default           # 修改namespace
spec:
  entryPoints:
    - web
  routes:
  - match: Host(`name.domain.com`) # 域名
    kind: Rule
    services:
    - name: nginx  # ServiceName
      port: 80     # ServicePort

3.2 https

  • 阿里dns
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: ingressroute-tls # 修改名称
  namespace: default           # 修改namespace
spec:
  entryPoints:
    - websecure
  routes:
  - match: Host(`name.domain.com`) # 域名
    kind: Rule
    services:
    - name: nginx  # ServiceName
      port: 80     # ServicePort
  tls:
    certResolver: ali
    domains:
    - main: "*.domain.com"
  • 自签名证书
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: ingressroute-tls # 修改名称
  namespace: default           # 修改namespace
spec:
  entryPoints:
    - websecure
  routes:
  - match: Host(`name.domain.com`) # 域名
    kind: Rule
    services:
    - name: nginx  # ServiceName
      port: 80     # ServicePort
  tls:
    secretName: traefik-tls   #创建方式见 2.6.2

4 中间件的使用

4.1 如果只希望用户通过 https 来访问应用

  • 创建中间件
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: redirect-https
spec:
  redirectScheme:
    scheme: https
  • 在ingressroute中使用即可
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: ingressroutetls-http
spec:
  entryPoints:
    - web	#这里指的是http,websecure指的是https
  routes:
  - match: Host(`myapp.domain.com`) && PathPrefix(`/tls`)
    kind: Rule
    services:
    - name: myapp
      port: 80
    middlewares: 
    - name: redirect-https
  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鬼刺

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值