traefik 是一个前端负载均衡器,对于微服务架构尤其是 kubernetes 等编排工具具有良好的支持;同 nginx 等相比,traefik 能够自动感知后端容器变化,从而实现自动服务发现。

      traefix的架构如下

image.png

Traefix的部署使用

部署环境:

     k8s-node1(master):192.168.232.130

     k8s-node2(node): 192.168.232.131

     k8s-node2(node): 192.168.232.129

部署步骤:

一:创建ClusterRole以及ClusterRoleBinding。(在kubernets1.6之后启用了RBAC鉴权机制,因此需配置ClusterRole以及ClusterRoleBinding来对api-server的进行相应权限的鉴权)

#vi traefik-rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: ingress
  namespace: kube-system
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: ingress
subjects:
  - kind: ServiceAccount
    name: ingress
    namespace: kube-system
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io
  
  
# kubectl create -f traefik-rbac.yaml 
serviceaccount "ingress" created
clusterrolebinding.rbac.authorization.k8s.io "ingress" created
 

二:部署traefix,这里使用Deployment方式,定义2个副本,使每个node都运行traefix服务。

# vi traefik-deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: traefik-ingress-lb
  namespace: kube-system
  labels:
    k8s-app: traefik-ingress-lb
spec:
  replicas: 2
  template:
    metadata:
      labels:
        k8s-app: traefik-ingress-lb
        name: traefik-ingress-lb
    spec:
      terminationGracePeriodSeconds: 60
      hostNetwork: true
      restartPolicy: Always
      serviceAccountName: ingress
      containers:
      - image: traefik
        name: traefik-ingress-lb
        resources:
          limits:
            cpu: 200m
            memory: 30Mi
          requests:
            cpu: 100m
            memory: 20Mi
        ports:
        - name: http
          containerPort: 80
          hostPort: 80
        - name: admin
          containerPort: 8580
          hostPort: 8580
        args:
        - --web
        - --web.address=:8580
        - --kubernetes
        
        
# kubectl create -f traefik-deployment.yaml 
deployment.extensions "traefik-ingress-lb" created


# kubectl get deployment.extensions --all-namespaces
NAMESPACE     NAME                   DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
kube-system   kube-dns               1         1         1            0           6d
kube-system   kubernetes-dashboard   1         1         1            1           3d
kube-system   traefik-ingress-lb     2         2         2            2           23s


# kubectl get pods -n kube-system -l k8s-app=traefik-ingress-lb -o wide 
NAME                                  READY     STATUS    RESTARTS   AGE       IP                NODE
traefik-ingress-lb-756f5f956b-pmzlb   1/1       Running   0          6m        192.168.232.131   k8s-node2
traefik-ingress-lb-756f5f956b-xpmcl   1/1       Running   0          6m        192.168.232.129   k8s-node3
 

    这里创建了一个traefix的Deployment,设置了2个副本,使用hostport的方式在运行traefix的node上监听了80(traefix服务端口)和8050(traefix-ui界面)端口,并且两个node上都存在一个traefix的pod。

2.PNG

1.PNG

image.png

三:traefix ui界面。

    部署完traefix之后,就可以使用node上的8050端口来访问traefix的ui界面了,从两个node都可以访问,如下:

3.PNG

4.PNG

    这里我们可以发布一个traefix-web-ui的ingress,使我们可以通过域名的方式来访问traefix ui界面:

# vi traefik-ui.yaml
---
apiVersion: v1
kind: Service
metadata:
  name: traefik-web-ui 
  namespace: kube-system
spec:
  selector:
    k8s-app: traefik-ingress-lb
  ports:
  - name: web
    port: 80
    targetPort: 8580 
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: traefik-web-ui
  namespace: kube-system
spec:
  rules:
  - host: traefik-ui.k8s
    http:
      paths:
      - path: /
        backend:
          serviceName: traefik-web-ui
          servicePort: web
          
          
# kubectl create -f traefik-ui.yaml 
service "traefik-web-ui" created
ingress.extensions "traefik-web-ui" created


# kubectl describe ingress traefik-web-ui -n kube-system
Name:             traefik-web-ui
Namespace:        kube-system
Address:          
Default backend:  default-http-backend:80 (<none>)
Rules:
  Host            Path  Backends
  ----            ----  --------
  traefik-ui.k8s  
                  /   traefik-web-ui:web (192.168.232.129:8580,192.168.232.131:8580)
Annotations:
Events:  <none>
 

    我们发布了一个host,名为traefix-ui.k8s,后端traefix-web-ui的service,可以看到关联到了pod地址192.168.232.129:8580和192.168.232.131:8580。

    修改host,使我们可以通过traefix-ui.k8s域名来访问traefix-ui:

192.168.232.129 traefik-ui.k8s
192.168.232.131 traefik-ui.k8s
 

5.PNG

四:发布其他web服务。

      部署完traefix之后,就可以通过它来发布我们自己的web应用了。这里我有两个简单的tomcat服务镜像test1和test2。访问他们,分别返回字符串tomcat_test1和tomcat_test2。首先,我先创建tomcat-test1和tomcat-test2的pod和service,其中8080为tomcat的http端口,8443为tomcat的https端口,本例中仅使用http端口测试。

# vi tomcat-test1.yaml 
#-----Deployment----------------
apiVersion: apps/v1
kind: Deployment
metadata:
  name: tomcat-test1
  labels: 
    app: tomcat-test1
spec:
  replicas: 1 
  selector:
    matchLabels:
      app: tomcat-test1
  template:
    metadata:
      labels:
        app: tomcat-test1
    spec:
      containers:
      - name: tomcat-test1
        image: tomcat_test1:latest
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8443
        - containerPort: 8080
---
#------service---------------
apiVersion: v1
kind: Service
metadata:
  name: tomcat-test1
  labels:
    name: tomcat-test1
spec:
  ports:
  - port: 8443
    targetPort: 8443
  selector:
    app: tomcat-test1
  ports:
  - port: 8080 
    targetPort: 8080
  selector:
    app: tomcat-test1

    
# more tomcat-test2.yaml 
#-----Deployment----------------
apiVersion: apps/v1
kind: Deployment
metadata:
  name: tomcat-test2
  labels: 
    app: tomcat-test2
spec:
  replicas: 1 
  selector:
    matchLabels:
      app: tomcat-test2
  template:
    metadata:
      labels:
        app: tomcat-test2
    spec:
      containers:
      - name: tomcat-test2
        image: tomcat_test2:latest
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8443
        - containerPort: 8080
---
#------service---------------
apiVersion: v1
kind: Service
metadata:
  name: tomcat-test2
  labels:
    name: tomcat-test2
spec:
  ports:
  - port: 8443
    targetPort: 8443
  ports:
  - port: 8080 
    targetPort: 8080
  selector:
    app: tomcat-test2
  
  
# kubectl create -f tomcat-test1.yaml       
deployment.apps "tomcat-test1" created
service "tomcat-test1" created
# kubectl create -f tomcat-test2.yaml       
deployment.apps "tomcat-test2" created
service "tomcat-test2" created


# kubectl get deployment
NAME           DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
tomcat-test1   1         1         1            1           52m
tomcat-test2   1         1         1            1           47m
# kubectl get svc
NAME           TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
kubernetes     ClusterIP   10.96.0.1        <none>        443/TCP    6d
tomcat-test1   ClusterIP   10.103.134.175   <none>        8080/TCP   52m
tomcat-test2   ClusterIP   10.97.4.120      <none>        8080/TCP   47m
 

    创建test1的ingress,来发布tomcat-test1服务:

# vi ingress-tomcat1.yaml 
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: tomcat-test1-web
  namespace: default
  annotations:
    kubernetes.io/ingress.class: traefik
spec:
  rules:
  - host: tomcat.test1.k8s
    http:
      paths:
      - path: /
        backend:
          serviceName: tomcat-test1
          servicePort: 8080

# kubectl create -f ingress-tomcat.yaml 
ingress.extensions "tomcat-test1-web" created
 

    从traefix-ui界面上,可以看到已经有了一个tomcat.test1.k8s的域名规则。

6.PNG

    修改hosts,使用tomcat.test1.k8s来访问tomcat-test1应用:

192.168.232.129 tomcat.test1.k8s
192.168.232.131 tomcat.test1.k8s
 

7.PNG

五:ingress配置之,同域名分路径代理不同web应用。

     很多使用我们不想配置太多的域名来区别应用,使用同域名分路径的方式来区别应用就简洁方便很多。ingress也提供了相关的配置。

     从上文可以知道,我们有两个应用tomcat-test1和tomcat-test2。这里可配置域名tomcat.test.k8s,通过路径test1、test2来分别代理两个tomcat应用。其中,分路径配置需添加配置:traefik.frontend.rule.type: PathPrefixStrip

# vi ingress-tomcat.yaml 
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: tomcat-test-web
  namespace: default
  annotations:
    kubernetes.io/ingress.class: traefik
    traefik.frontend.rule.type: PathPrefixStrip
spec:
  rules:
  - host: tomcat.test.k8s
    http:
      paths:
      - path: /test1/
        backend:
          serviceName: tomcat-test1
          servicePort: 8080
      - path: /test2/
        backend:
          serviceName: tomcat-test2
          servicePort: 8080

          
# kubectl create -f ingress-tomcat.yaml                               
ingress.extensions "tomcat-test-web" created


# kubectl describe ingress tomcat-test-web
Name:             tomcat-test-web
Namespace:        default
Address:          
Default backend:  default-http-backend:80 (<none>)
Rules:
  Host             Path  Backends
  ----             ----  --------
  tomcat.test.k8s  
                   /test1/   tomcat-test1:8080 (<none>)
                   /test2/   tomcat-test2:8080 (<none>)
Annotations:
  kubernetes.io/ingress.class:  traefik
  traefik.frontend.rule.type:   PathPrefixStrip
Events:                         <none>
 

8.PNG

      从describe信息和ui界面上可以看到,tomcat.test.k8s分别有了/test1/和/test2/的域名代理以及相对应的后端,可以修改hosts测试一下分路径是否生效:

192.168.232.129 tomcat.test.k8s
192.168.232.131 tomcat.test.k8s
 

9.PNG

10.PNG

后记

     本章只是初步实现了traefix的http访问代理,如果开启traefix的https代理以及怎么对traefix进行更多的配置,将在后续的博文中来讨论。