This commit is contained in:
loveuer
2026-01-28 10:28:13 +08:00
parent 507a67e455
commit 3ee0c9c098
29 changed files with 2852 additions and 0 deletions

View File

@@ -0,0 +1,59 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-cache-demo
namespace: redis-demo
labels:
app: redis-cache-demo
spec:
replicas: 2
selector:
matchLabels:
app: redis-cache-demo
template:
metadata:
labels:
app: redis-cache-demo
spec:
containers:
- name: app
image: redis-cache-demo:latest
ports:
- containerPort: 8080
env:
- name: PORT
value: "8080"
- name: REDIS_ADDR
value: "redis-headless.redis-demo.svc.cluster.local:6379"
- name: REDIS_PASSWORD
value: ""
- name: REDIS_RECONNECT
value: "true"
- name: REDIS_RECONNECT_INTERVAL
value: "10s"
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 10
periodSeconds: 30
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
name: redis-cache-demo
namespace: redis-demo
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 8080
name: http
selector:
app: redis-cache-demo

View File

@@ -0,0 +1,105 @@
apiVersion: v1
kind: Pod
metadata:
name: k8s-discovery-test
namespace: redis-demo
spec:
containers:
- name: test
image: alpine:latest
command: ["sh", "-c"]
args:
- |
echo "=== Installing Go ==="
apk add --no-cache go
echo "=== Building discovery tool ==="
mkdir -p /app/discovery
cat > /app/discovery/main.go << 'EOF'
package main
import (
"fmt"
"net"
"strings"
)
func main() {
fmt.Println("=== Kubernetes Service Discovery Test ===")
headlessAddr := "redis-headless.redis-demo.svc.cluster.local"
fmt.Printf("🔍 Discovering service: %s\n", headlessAddr)
serviceInfo, err := parseHeadlessServiceAddr(headlessAddr)
if err != nil {
fmt.Printf("❌ Failed to discover service: %v\n", err)
return
}
fmt.Println("\n📋 Service Information:")
fmt.Printf(" Name: %s\n", serviceInfo.Name)
fmt.Printf(" Namespace: %s\n", serviceInfo.Namespace)
if len(serviceInfo.All) > 0 {
fmt.Printf("\n🌐 All Pod IPs (%d):\n", len(serviceInfo.All))
for idx, ip := range serviceInfo.All {
podName := fmt.Sprintf("%s-%d", serviceInfo.Name, idx)
if idx == 0 {
fmt.Printf(" 📌 Master: %s -> %s\n", podName, ip)
} else {
fmt.Printf(" 📊 Replica: %s -> %s\n", podName, ip)
}
}
}
fmt.Println("\n🎉 Service discovery completed successfully!")
}
type ServiceInfo struct {
Name string
All []string
}
func parseHeadlessServiceAddr(headlessAddr string) (*ServiceInfo, error) {
resolver := &net.Resolver{PreferGo: true}
addrs, err := resolver.LookupIPAddr(headlessAddr)
if err != nil {
return nil, fmt.Errorf("DNS query failed: %v", err)
}
if len(addrs) == 0 {
return nil, fmt.Errorf("no records found")
}
var podIPs []string
for _, addr := range addrs {
podIPs = append(podIPs, addr.String())
}
parts := strings.Split(headlessAddr, ".")
if len(parts) < 4 {
return nil, fmt.Errorf("invalid format")
}
serviceName := parts[0]
namespace := parts[1]
return &ServiceInfo{
Name: serviceName,
All: podIPs,
}, nil
}
EOF
echo "=== Running discovery tool ==="
cd /app/discovery && go run main.go
echo "=== Sleeping for 30s ==="
sleep 30
volumeMounts:
- name: app-volume
mountPath: /app
volumes:
- name: app-volume
emptyDir: {}
restartPolicy: Never

View File

@@ -0,0 +1,37 @@
apiVersion: v1
kind: Pod
metadata:
name: redis-internal-test
namespace: redis-demo
spec:
containers:
- name: test
image: redis:7-alpine
command: ["sh", "-c"]
args:
- |
echo "=== Testing Redis from inside cluster ==="
echo "1. Testing DNS resolution..."
nslookup redis-headless.redis-demo.svc.cluster.local
echo ""
echo "2. Testing individual pod DNS..."
nslookup redis-0.redis-headless.redis-demo.svc.cluster.local
nslookup redis-1.redis-headless.redis-demo.svc.cluster.local
nslookup redis-2.redis-headless.redis-demo.svc.cluster.local
echo ""
echo "3. Testing Redis connectivity..."
redis-cli -h redis-0.redis-headless.redis-demo.svc.cluster.local ping
redis-cli -h redis-1.redis-headless.redis-demo.svc.cluster.local ping
redis-cli -h redis-2.redis-headless.redis-demo.svc.cluster.local ping
echo ""
echo "4. Testing Redis operations..."
redis-cli -h redis-headless.redis-demo.svc.cluster.local set test-key "from-cluster"
VALUE=$(redis-cli -h redis-headless.redis-demo.svc.cluster.local get test-key)
echo "SET/GET result: $VALUE"
echo ""
echo "=== Internal test completed ==="
sleep 3600

View File

@@ -0,0 +1,74 @@
apiVersion: v1
kind: Namespace
metadata:
name: redis-demo
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: redis
namespace: redis-demo
spec:
serviceName: redis-headless
replicas: 3
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: redis:7-alpine
ports:
- containerPort: 6379
command:
- redis-server
- --bind
- "0.0.0.0"
- --port
- "6379"
- --replica-announce-ip
- $(POD_NAME).redis-headless.redis-demo.svc.cluster.local
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
volumeMounts:
- name: redis-data
mountPath: /data
volumes:
- name: redis-data
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: redis-headless
namespace: redis-demo
labels:
app: redis
spec:
clusterIP: None
ports:
- port: 6379
name: redis
selector:
app: redis
---
apiVersion: v1
kind: Service
metadata:
name: redis
namespace: redis-demo
labels:
app: redis
spec:
ports:
- port: 6379
name: redis
selector:
app: redis

View File

@@ -0,0 +1,13 @@
apiVersion: v1
kind: Pod
metadata:
name: redis-test
namespace: redis-demo
spec:
containers:
- name: redis-test
image: redis:7-alpine
command: ["sh", "-c", "echo 'Testing Redis connection...'; redis-cli -h redis-headless.redis-demo.svc.cluster.local ping || echo 'Connection failed'; sleep 3600"]
env:
- name: REDIS_ADDR
value: "redis-headless.redis-demo.svc.cluster.local:6379"

View File

@@ -0,0 +1,66 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: test-script
namespace: redis-demo
data:
test.sh: |
#!/bin/sh
echo "=== Redis Cache Demo Test ==="
echo "Testing Redis connectivity..."
# 测试 Redis 连接
redis-cli -h redis-headless.redis-demo.svc.cluster.local ping
echo ""
echo "Testing basic cache operations..."
# 设置值
redis-cli -h redis-headless.redis-demo.svc.cluster.local set test-key "hello-world"
echo "SET test-key 'hello-world'"
# 获取值
VALUE=$(redis-cli -h redis-headless.redis-demo.svc.cluster.local get test-key)
echo "GET test-key: $VALUE"
# 设置 Hash
redis-cli -h redis-headless.redis-demo.svc.cluster.local hset user:1 name "张三"
redis-cli -h redis-headless.redis-demo.svc.cluster.local hset user:1 age "25"
echo "HSET user:1 name '张三', age '25'"
# 获取 Hash
NAME=$(redis-cli -h redis-headless.redis-demo.svc.cluster.local hget user:1 name)
AGE=$(redis-cli -h redis-headless.redis-demo.svc.cluster.local hget user:1 age)
echo "HGET user:1 name: $NAME, age: $AGE"
# 获取所有 Hash 字段
ALL_HASH=$(redis-cli -h redis-headless.redis-demo.svc.cluster.local hgetall user:1)
echo "HGETALL user:1: $ALL_HASH"
# 计数器测试
redis-cli -h redis-headless.redis-demo.svc.cluster.local set counter 0
COUNTER1=$(redis-cli -h redis-headless.redis-demo.svc.cluster.local incr counter)
COUNTER2=$(redis-cli -h redis-headless.redis-demo.svc.cluster.local incrby counter 5)
echo "COUNTER: initial=0, +1=$COUNTER1, +5=$COUNTER2"
# 测试过期
redis-cli -h redis-headless.redis-demo.svc.cluster.local set expire-key "will-expire" EX 5
echo "SET expire-key 'will-expire' with TTL 5s"
sleep 2
EXPIRED=$(redis-cli -h redis-headless.redis-demo.svc.cluster.local get expire-key)
echo "GET expire-key after 2s: $EXPIRED"
sleep 4
EXPIRED2=$(redis-cli -h redis-headless.redis-demo.svc.cluster.local get expire-key)
echo "GET expire-key after 6s: $EXPIRED2 (should be nil)"
echo ""
echo "=== Test Summary ==="
echo "✅ Basic SET/GET operations"
echo "✅ Hash operations (HSET/HGET/HGETALL)"
echo "✅ Counter operations (INCR/INCRBY)"
echo "✅ TTL operations"
echo "✅ Redis cluster connectivity"
echo ""
echo "All tests completed successfully!"

View File

@@ -0,0 +1,21 @@
apiVersion: v1
kind: Pod
metadata:
name: redis-cache-test
namespace: redis-demo
spec:
restartPolicy: Never
containers:
- name: test-runner
image: redis:7-alpine
command: ["sh"]
args: ["/scripts/test.sh"]
volumeMounts:
- name: test-scripts
mountPath: /scripts
readOnly: true
volumes:
- name: test-scripts
configMap:
name: test-script
defaultMode: 0755