traefik添加路由

axing
2025-06-08 / 0 评论 / 3 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2025年06月08日,已超过7天没有更新,若内容或图片失效,请留言反馈。

一、路由配置(IngressRouteTCP)
1、TCP路由(不带TLS证书)

#在yaml文件中添加端口
        ports:
        - name: metrics
          containerPort: 9100
          protocol: TCP
        - name: traefik
          containerPort: 9000
          protocol: TCP
        - name: web
          containerPort: 8000
          protocol: TCP
        - name: websecure
          containerPort: 8443
          protocol: TCP
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            drop:
            - ALL
            - NET_BIND_SERVICE
          readOnlyRootFilesystem: false
        volumeMounts:
          - name: data
            mountPath: /data
            readOnly: false   # 允许写入
        args:
          - "--global.checknewversion"
          - "--global.sendanonymoususage"
          - "--entryPoints.metrics.address=:9100/tcp"
          - "--entryPoints.traefik.address=:9000/tcp"
          - "--entryPoints.web.address=:8000/tcp"
          - "--entryPoints.websecure.address=:8443/tcp"
          - "--api.dashboard=true"
          - "--entryPoints.redistcp.address=:6379/tcp"  #添加端口
          - "--ping=true"
          - "--metrics.prometheus=true"
          - "--metrics.prometheus.entrypoint=metrics"
          - "--providers.kubernetescrd"
          - "--providers.kubernetescrd.allowEmptyServices=true"
          - "--providers.kubernetesingress"
          - "--providers.kubernetesingress.allowEmptyServices=true"
          - "--providers.kubernetesingress.ingressendpoint.publishedservice=traefik/traefik-release"
          - "--entryPoints.websecure.http.tls=true"
          - "--log.level=INFO"
#实例
root@k8s01:~/helm/traefik/test# cat redis.yaml 
# redis.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis
spec:
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
      - name: redis
        image: registry.cn-guangzhou.aliyuncs.com/xingcangku/redis:1.0
        resources:
          limits:
            memory: "128Mi"
            cpu: "500m"
        ports:
        - containerPort: 6379
          protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
  name: redis
spec:
  selector:
    app: redis
  ports:
  - port: 6379
    targetPort: 6379

root@k8s01:~/helm/traefik/test# cat redis-IngressRoute.yaml 
apiVersion: traefik.io/v1alpha1
kind: IngressRouteTCP
metadata:
  name: redis
  namespace: default  # 确保在 Redis 的命名空间
spec:
  entryPoints:
    - redistcp  # 使用新定义的入口点
  routes:
  - match: HostSNI(`*`)  # 正确语法
    services:
    - name: redis
      port: 6379

#redis_Ingress.yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRouteTCP
metadata:
  name: redis
  namespace: default  # 确保在 Redis 的命名空间
spec:
  entryPoints:
    - redistcp  # 使用新定义的入口点
  routes:
  - match: HostSNI(`*`)  # 正确语法
    services:
    - name: redis
      port: 6379
#可以查询6379映射的端口
kubectl -n traefik get endpoints
#集群外部客户端配置hosts解析192.168.93.128 redis.test.com(域名可以随意填写,只要能解析到traefik所在节点即可),然后通过redis-cli工具访问redis,记得指定tcpep的端口。
# redis-cli -h redis.test.com -p 上面查询映射的端口
redis.test.com:9200> set key_a value_a
OK
redis.test.com:9200> get key_a
"value_a"
redis.test.com:9200> 

mbmojdul.png

2、TCP路由(带TLS证书)

有时候为了安全要求,tcp传输也需要使用TLS证书加密,redis从6.0开始支持了tls证书通信。
root@k8s01:~/helm/traefik/test/redis-ssl# openssl genrsa -out ca.key 4096
Generating RSA private key, 4096 bit long modulus (2 primes)
..........................................................................................................................................................................................................................................................++++
................++++
e is 65537 (0x010001)
root@k8s01:~/helm/traefik/test/redis-ssl# ls
ca.key
root@k8s01:~/helm/traefik/test/redis-ssl# openssl req -x509 -new -nodes -sha256 -key ca.key -days 3650 -subj '/O=Redis Test/CN=Certificate Authority' -out ca.crt
root@k8s01:~/helm/traefik/test/redis-ssl# ls
ca.crt  ca.key
root@k8s01:~/helm/traefik/test/redis-ssl# openssl genrsa -out redis.key 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
..........................................................+++++
...................................................................+++++
e is 65537 (0x010001)
root@k8s01:~/helm/traefik/test/redis-ssl# openssl req -new -sha256 -key redis.key -subj '/O=Redis Test/CN=Server' | openssl x509 -req -sha256 -CA ca.crt -CAkey ca.key -CAserial ca.txt -CAcreateserial -days 365 -out redis.crt
Signature ok
subject=O = Redis Test, CN = Server
Getting CA Private Key
root@k8s01:~/helm/traefik/test/redis-ssl# openssl dhparam -out redis.dh 2048
Generating DH parameters, 2048 bit long safe prime, generator 2
This is going to take a long time
...............................................+..................................................................................................................................................................................................+................+..........................................+...........+.............+..............................................................+................................................................+.+....................................................................................................................................................................................................................................................................................................+..............+................................................................................................................................................................................................+...................................................................................................................................................................................................................................................................................+...........................................................................................................................................................................+........................................+.+.............................+....................................................................................................................................................+.............................................................................+.++*++*++*++*
root@k8s01:~/helm/traefik/test/redis-ssl# ll
total 24
drwxr-xr-x 2 root root   98 Jun  8 06:57 ./
drwxr-xr-x 3 root root  249 Jun  8 06:55 ../
-rw-r--r-- 1 root root 1895 Jun  8 06:56 ca.crt
-rw------- 1 root root 3243 Jun  8 06:55 ca.key
-rw-r--r-- 1 root root   41 Jun  8 06:57 ca.txt
-rw-r--r-- 1 root root 1407 Jun  8 06:57 redis.crt
-rw-r--r-- 1 root root  424 Jun  8 06:57 redis.dh
-rw------- 1 root root 1679 Jun  8 06:56 redis.key
root@k8s01:~/helm/traefik/test/redis-ssl# 
ca.crt       # 根证书 (公开)
ca.key       # CA 私钥 (绝密)
ca.txt       # 证书序列号记录
redis.key    # Redis 服务器私钥 (绝密)
redis.crt    # Redis 服务器证书 (公开)
redis.dh     # Diffie-Hellman 参数 (公开)
#生成 CA 私钥​
openssl genrsa -out ca.key 4096
作用​​:创建根证书颁发机构(CA)的私钥
genrsa:生成 RSA 私钥
-out ca.key:输出到文件 ca.key
4096:密钥长度(4096 位高安全级别)
​​输出文件​​:ca.key(CA 私钥,需严格保密)
#生成 CA 根证书​
openssl req -x509 -new -nodes -sha256 -key ca.key -days 3650 -subj '/O=Redis Test/CN=Certificate Authority' -out ca.crt
下面是对您生成 Redis SSL/TLS 证书的每一步命令的解析:

​​1. 生成 CA 私钥​​
openssl genrsa -out ca.key 4096
​​作用​​:创建根证书颁发机构(CA)的私钥
genrsa:生成 RSA 私钥
-out ca.key:输出到文件 ca.key
4096:密钥长度(4096 位高安全级别)
​​输出文件​​:ca.key(CA 私钥,需严格保密)
​​2. 生成 CA 根证书​​
openssl req -x509 -new -nodes -sha256 -key ca.key -days 3650 -subj '/O=Redis Test/CN=Certificate Authority' -out ca.crt
​​作用​​:创建自签名的根证书
req -x509:创建自签名证书(而不是证书请求)
-new:生成新证书
-nodes:不加密私钥(No DES,明文存储)
-sha256:使用 SHA-256 哈希算法
-key ca.key:指定 CA 私钥
-days 3650:有效期 10 年
-subj:证书主题信息
/O=Redis Test:组织名称
/CN=Certificate Authority:通用名称(标识为 CA)
-out ca.crt:输出到 ca.crt
​​输出文件​​:ca.crt(受信任的根证书)
#生成 Redis 服务器私钥​
openssl genrsa -out redis.key 2048
作用​​:创建 Redis 服务器的私钥
与步骤 1 类似,但密钥长度 2048 位(更短,性能更好)
​​输出文件​​:redis.key(服务器私钥,需保密)
#生成并签署 Redis 服务器证书​
openssl req -new -sha256 -key redis.key -subj '/O=Redis Test/CN=Server' | openssl x509 -req -sha256 -CA ca.crt -CAkey ca.key -CAserial ca.txt -CAcreateserial -days 365 -out redis.crt
#前半部分(生成证书请求)​
openssl req -new -sha256 -key redis.key -subj '/O=Redis Test/CN=Server'
req -new:创建证书签名请求(CSR)
-subj '/O=Redis Test/CN=Server':主题信息
CN=Server:标识为 Redis 服务器
#后半部分(签署证书)​
openssl x509 -req ... -out redis.crt
x509 -req:签署证书请求
-CA ca.crt:指定 CA 证书
-CAkey ca.key:指定 CA 私钥
-CAserial ca.txt:指定序列号记录文件
-CAcreateserial:如果序列号文件不存在则创建
-days 365:有效期 1 年
​​输出文件​​:
redis.crt:Redis 服务器证书
ca.txt:证书序列号记录文件(首次生成)
#生成 Diffie-Hellman 参数​
openssl dhparam -out redis.dh 2048
作用​​:创建安全密钥交换参数
dhparam:生成 Diffie-Hellman 参数
2048:密钥长度
​​输出文件​​:redis.dh(用于前向保密 PFS)
创建secret资源,使用tls类型,包含redis.crt和redis.key
root@k8s01:~/helm/traefik/test/redis-ssl# kubectl create secret tls redis-tls --key=redis.key --cert=redis.crt
secret/redis-tls created
root@k8s01:~/helm/traefik/test/redis-ssl# kubectl describe secrets redis-tls 
Name:         redis-tls
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  kubernetes.io/tls

Data
====
tls.crt:  1407 bytes
tls.key:  1679 bytes
root@k8s01:~/helm/traefik/test/redis-ssl# 
创建secret资源,使用generic类型,包含ca.crt
root@k8s01:~/helm/traefik/test/redis-ssl# kubectl create secret generic redis-ca --from-file=ca.crt=ca.crt
secret/redis-ca created
root@k8s01:~/helm/traefik/test/redis-ssl# kubectl describe secrets redis-ca 
Name:         redis-ca
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
ca.crt:  1895 bytes
root@k8s01:~/helm/traefik/test/redis-ssl# 
修改redis配置,启用tls证书,并挂载证书文件
apiVersion: v1
kind: ConfigMap
metadata:
  name: redis
  labels:
    app: redis
data:
  redis.conf : |-
    port 0
    tls-port 6379
    tls-cert-file   /etc/tls/tls.crt
    tls-key-file   /etc/tls/tls.key
    tls-ca-cert-file   /etc/ca/ca.crt
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis
spec:
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
      - name: redis
        image: registry.cn-guangzhou.aliyuncs.com/xingcangku/redis:1.0
        resources:
          limits:
            memory: "128Mi"
            cpu: "500m"
        ports:
        - containerPort: 6379
          protocol: TCP
        volumeMounts:
          - name: config
            mountPath: /etc/redis
          - name: tls
            mountPath: /etc/tls
          - name: ca
            mountPath: /etc/ca
        args:
        - /etc/redis/redis.conf
      volumes:
        - name:  config
          configMap:
            name: redis
        - name: tls
          secret:
            secretName: redis-tls
        - name: ca
          secret:
            secretName: redis-ca
---
apiVersion: v1
kind: Service
metadata:
  name: redis
spec:
  selector:
    app: redis
  ports:
  - port: 6379
    targetPort: 6379
root@k8s01:~/helm/traefik/test# kubectl apply -f redis.yaml 
configmap/redis created
deployment.apps/redis configured
service/redis unchanged

mbncrcov.png

root@k8s01:~/helm/traefik/test/redis-ssl# # 生成客户端证书
root@k8s01:~/helm/traefik/test/redis-ssl# openssl req -newkey rsa:4096 -nodes \
>   -keyout client.key \
>   -subj "/CN=redis-client" \
>   -out client.csr
rt \
  -days 365Generating a RSA private key
...........................................++++
.........................................................................................................++++
writing new private key to 'client.key'
-----
root@k8s01:~/helm/traefik/test/redis-ssl# 
root@k8s01:~/helm/traefik/test/redis-ssl# # 用同一CA签发
root@k8s01:~/helm/traefik/test/redis-ssl# openssl x509 -req -in client.csr \
>   -CA ca.crt \
>   -CAkey ca.key \
>   -CAcreateserial \
>   -out client.crt \
>   -days 365
Signature ok
subject=CN = redis-client
Getting CA Private Key
root@k8s01:~/helm/traefik/test/redis-ssl# scp {client.crt,client.key,ca.crt} root@192.168.3.131:/tmp/redis-ssl/
root@192.168.3.131's password: 
client.crt                                                                                         100% 1732   308.5KB/s   00:00    
client.key                                                                                         100% 3272   972.0KB/s   00:00    
ca.crt                                                                                             100% 1895     1.0MB/s   00:00 
root@k8s01:~/helm/traefik/test# cat redis-IngressRoute-tls.yaml
# redis-IngressRoute-tls.yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRouteTCP
metadata:
  name: redis
spec:
  entryPoints:
    - tcpep
  routes:
    - match: HostSNI(`redis.test.com`)
      services:
        - name: redis
          port: 6379
  tls:
    passthrough: true  # 重要:这里是启用透传的正确位置
root@k8s01:~/helm/traefik/test# 
#到集群意外的机器测试redis连接 低版本不支持TLS,需要编译安装6.0以上版本,并在编译时开启TLS
root@ubuntu02:~/redis-stable# ./src/redis-cli -h redis.test.com -p 31757 --tls --sni redis.test.com --cert /tmp/redis-ssl/client.crt --key /tmp/redis-ssl/client.key --cacert /tmp/redis-ssl/ca.crt
redis.test.com:31757> get key
"1"
redis.test.com:31757> 

root@ubuntu02:~/redis-stable# ./src/redis-cli \
>   -h redis.test.com \
>   -p 31757 \
>   --tls \
>   --sni redis.test.com \
>   --cert /tmp/redis-ssl/client.crt \
>   --key /tmp/redis-ssl/client.key \
>   --cacert /tmp/redis-ssl/ca.crt
redis.test.com:31757> set v1=1
(error) ERR wrong number of arguments for 'set' command
redis.test.com:31757> set key 1
OK

mbnwqj5d.png

#配置对比
# redis-IngressRoute-tls.yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRouteTCP
metadata:
  name: redis
spec:
  entryPoints:
    ◦ tcpep

  routes:
    ◦ match: HostSNI(`redis.test.com`)

      services:
        ▪ name: redis

          port: 6379
  tls:
    passthrough: true

#上面的配置可以用 下面的配置用不了
# redis-IngressRoute-tls.yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRouteTCP
metadata:
  name: redis
spec:
  entryPoints:
    ◦ tcpep

  routes:
    ◦ match: HostSNI(`redis.test.com`)

      services:
        ▪ name: redis

          port: 6379
  tls:
    secretName: redis-tls
工作配置:
客户端 → [TLS握手] → Traefik (透传) → Redis服务器
                         │
                         └─ 直接处理TLS

失败配置:
客户端 → [TLS握手] → Traefik (终止TLS) → Redis服务器
             │                      │
             ├─验证Traefik证书       └─ 接收明文连接但期望加密
             └─客户端CA不信任Traefik证书
因为第一个配置是不经过Traefik直接到redis认证证书
工作原理​​:Traefik 不处理TLS流量,直接透传加密数据到Redis服务器
​​证书使用​​:客户端直接与Redis服务器进行TLS握手,使用Redis服务器自身的证书
​​验证过程​​:客户端用自有的ca.crt验证Redis服务器证书(CN=redis.test.com)

第二个是需要先和Traefik认证
工作原理​​:Traefik 在入口处终止TLS连接,然后以明文转发到Redis服务器
​​证书使用​​:
客户端验证 Traefik 的证书(来自 redis-tls secret)
Redis 服务器接收非加密流量
​​验证过程​​:客户端验证的是 Traefik 的证书,而不是Redis服务器证书

失败的核心原因
​​证书不匹配问题​​:
当使用 secretName: redis-tls 时,Traefik 使用该 Secret 中的证书
但是客户端配置的CA证书是用于验证Redis服务器证书(CN=redis.test.com)的
Traefik 的证书(CN=TRAEFIK DEFAULT CERT)无法通过客户端CA验证
0

评论 (0)

取消