Skip to content

Traefik暴露TCP服务

Traefik 2.0 新增了暴露 TCP 服务,我们这里以 Redis 为例。

部署 Redis

因为这里只是简单的实践以下暴露 TCP 服务,所以就用最简单的部署方式,YAML 文件如下:

redis.yaml

yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: redis
  namespace: kube-ops
spec:
  template:
    metadata:
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "9121"
      labels:
        app: redis
    spec:
      containers:
        - name: redis
          image: redis:4
          ports:
            - containerPort: 6379
        - name: redis-exporter
          image: oliver006/redis_exporter:latest
          resources:
            requests:
              cpu: 100m
              memory: 100Mi
          ports:
            - containerPort: 9121
---
kind: Service
apiVersion: v1
metadata:
  name: redis
  namespace: kube-ops
  annotations:
    prometheus.io/scrape: "true"
    prometheus.io/port: "9121"
    prometheus.io/http-probe: "true"
spec:
  selector:
    app: redis
  ports:
    - name: redis
      port: 6379
      targetPort: 6379
    - name: prom
      port: 9121
      targetPort: 9121

然后我们直接创建:

bash
# kubectl apply -f redis.yaml

暴露 TCP 服务

由于 Traefik 使用路由配置需要 SNI,而 SNI 又依赖 TLS,所以我们需要证书才行。但是如果没有证书的话,我们可以使用通配符  *  进行配置,我们这里创建一个 IngressRouteTCP 类型的 CRD 对象(ingress-redis.yaml):

yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP
metadata:
  name: redis
  namespace: kube-ops
spec:
  entryPoints:
    - redis
  routes:
    - match: HostSNI(`*`)
      services:
        - name: redis
          port: 6379

然后直接创建:

yaml
# kubectl apply -f ingress-redis.yaml

但是仅仅这样配置是不够的,我们注意到 entryPoints 部分,是根据我们启动的 Traefik 的静态配置中的 entryPoints 来决定的,比如我们可以自己添加一个用于 Redis 的专门的入口点,然后我们将 redis 暴露出来方便测试:

yaml
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: traefik
  namespace: kube-system
  labels:
    k8s-app: traefik-ingress-lb
spec:
  selector:
    matchLabels:
      k8s-app: traefik-ingress-lb
  template:
    metadata:
      labels:
        k8s-app: traefik-ingress-lb
        name: traefik-ingress-lb
    spec:
      serviceAccountName: traefik-ingress-controller
      tolerations:
        - operator: "Exists"
      nodeSelector:
        kubernetes.io/hostname: 172.16.0.33
      containers:
        - image: traefik:v2.0
          name: traefik-ingress-lb
          ports:
            - name: web
              containerPort: 80
            - name: websecure
              containerPort: 443
            - name: admin
              containerPort: 8080
            - name: redis
              containerPort: 6379
          args:
            - --entrypoints.web.Address=:80
            - --entrypoints.websecure.Address=:443
            - --entrypoints.redis.Address=:6379
            - --api.insecure=true
            - --providers.kubernetescrd
            - --api
            - --api.dashboard=true
            - --accesslog

---
kind: Service
apiVersion: v1
metadata:
  name: traefik
  namespace: kube-system
spec:
  type: NodePort
  selector:
    k8s-app: traefik-ingress-lb
  ports:
    - protocol: TCP
      port: 8080
      name: admin
    - name: web
      port: 80
      protocol: TCP
    - name: websecure
      port: 443
      protocol: TCP
    - name: redis
      port: 6379
      protocol: TCP

然后重新更新以下清单:

bash
# kubectl apply -f traefik.yaml

现在我们可以在管理界面看到已经配置成功了。

68893624e499b3307446b10fe5f316df MD5

dc380ac0f2f6051326dc0271e4c3c98c MD5

32e078d917ffc4730a2ebef3540e9f7c MD5

使用命令验证 redis:

6551511bee727876946de0692db466c8 MD5

可以看到 TCP 服务暴露成功。

最近更新