一、路由配置(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>
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
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
#配置对比
# 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)