在Kubernetes上使用Traefik

本節內容:前端

  • Traefik介紹
  • 部署測試用的兩個服務
  • Role Based Access Control configuration (Kubernetes 1.6+ only)
  • 部署Traefik
  • 部署 Ingress
  • 部署Traefik UI
  • 訪問測試
  • 健康檢查

 

1、Traefik介紹

traefik 是一個前端負載均衡器,對於微服務架構尤爲是 kubernetes 等編排工具具備良好的支持;同 nginx 等相比,traefik 可以自動感知後端容器變化,從而實現自動服務發現。node

因爲微服務架構以及 Docker 技術和 kubernetes 編排工具最近幾年纔開始逐漸流行,因此一開始的反向代理服務器好比 nginx、apache 並未提供其支持,畢竟他們也不是先知;因此纔會出現 Ingress Controller 這種東西來作 kubernetes 和前端負載均衡器如 nginx 之間作銜接;即 Ingress Controller 的存在就是爲了能跟 kubernetes 交互,又能寫 nginx 配置,還能 reload 它,這是一種折中方案;而 traefik 天生就是提供了對 kubernetes 的支持,也就是說 traefik 自己就能跟 kubernetes API 交互,感知後端變化,所以能夠得知: 在使用 traefik 時,Ingress Controller 已經沒什麼用了,總體架構以下:nginx

 

 

2、部署測試用的兩個服務

部署兩個服務nginx1-7和nginx1-8,後面用Traefik去負載這兩個服務:web

apiVersion: v1
kind: Service
metadata:
  name: frontend
spec:
  ports:
    - port: 80
      targetPort: 80
  selector:
    app: nginx1-7
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: nginx1-7-deployment
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx1-7
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80
nginx1-7.yaml
apiVersion: v1
kind: Service
metadata:
  name: my-nginx
spec:
  ports:
    - port: 80
      targetPort: 80
  selector:
    app: nginx1-8
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: nginx1-8-deployment
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx1-8
    spec:
      containers:
      - name: nginx
        image: nginx:1.8
        ports:
        - containerPort: 80
nginx1-8.yaml

運行兩個服務:apache

[root@node1 nginx_ingress]# kubectl create -f nginx1-7.yaml
service "frontend" created
deployment "nginx1-7-deployment" created
[root@node1 nginx_ingress]# kubectl create -f nginx1-8.yaml
service "my-nginx" created
deployment "nginx1-8-deployment" created

 

3、Role Based Access Control configuration (Kubernetes 1.6+ only)

我這裏部署的是1.6.0集羣,開啓了RBAC,受權須要使用角色和綁定角色。vim

[root@node1 traefik]# pwd
/opt/traefik
[root@node1 traefik]# vim ingress-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
ingress-rbac.yaml

 

4、部署Traefik

[root@node1 traefik]# pwd
/opt/traefik
[root@node1 traefik]# vim traefik-deploy.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: traefik-ingress-lb
  namespace: kube-system
  labels:
    k8s-app: traefik-ingress-lb
spec:
  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
traefik-deploy.yaml

其中 traefik 監聽 node 的 80 和 8580 端口,80 提供正常服務,8580 是其自帶的 UI 界面,本來默認是 8080,由於環境裏端口衝突了,因此這裏臨時改一下。後端

【注意】:這裏用的是Deploy類型,沒有限定該pod運行在哪一個主機上。api

 

5、部署 Ingress

[root@node1 traefik]# cat traefik.yaml 
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: traefik-ingress
  namespace: default
spec:
  rules:
  - host: traefik.nginx.io
    http:
      paths:
      - path: /
        backend:
          serviceName: my-nginx
          servicePort: 80
  - host: traefik.frontend.io
    http:
      paths:
      - path: /
        backend:
          serviceName: frontend
          servicePort: 80
traefik.yaml

其中的backend中要配置default namespace中啓動的service名字,若是你沒有配置namespace名字,默認使用default namespace,若是你在其餘namespace中建立服務想要暴露到kubernetes集羣外部,能夠建立新的ingress.yaml文件,同時在文件中指定該namespace,其餘配置與上面的文件格式相同。path就是URL地址後的路徑,如traefik.frontend.io/path,service將會接受path這個路徑,host最好使用service-name.filed1.filed2.domain-name這種相似主機名稱的命名方式,方便區分服務。瀏覽器

根據實際環境中部署的service的名字和端口自行修改,有新service增長時,修改該文件後可使用kubectl replace -f traefik.yaml來更新。bash

 

6、部署Traefik UI

traefik 自己還提供了一套 UI 供咱們使用,其一樣以 Ingress 方式暴露,只須要建立一下便可。

[root@node1 traefik]# cat traefik-ui-service.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.local
    http:
      paths:
      - path: /
        backend:
          serviceName: traefik-web-ui
          servicePort: web
traefik-ui-service.yaml

最後一塊兒建立:

[root@node1 traefik]# kubectl create -f .
serviceaccount "ingress" created
clusterrolebinding "ingress" created
deployment "traefik-ingress-lb" created
service "traefik-web-ui" created
ingress "traefik-web-ui" created
ingress "traefik-ingress" created

 

7、訪問測試

查看traefik pod被分配到了哪臺主機上: 

[root@node1 traefik]# kubectl get pods -n kube-system -l k8s-app=traefik-ingress-lb -o wide                       
NAME                                  READY     STATUS    RESTARTS   AGE       IP             NODE
traefik-ingress-lb-4237248072-1dg9n   1/1       Running   0          2m        172.16.7.152   172.16.7.152

瀏覽器輸入http://172.16.7.152:8580/,將能夠看到dashboard。

左側黃色部分部分列出的是全部的rule,右側綠色部分是全部的backend。

 

在Kubernetes集羣的任意一個節點上執行。假如如今我要訪問nginx的"/"路徑。

curl -H Host:traefik.nginx.io http://172.16.7.152/

若是須要在kubernetes集羣之外訪問就須要設置DNS,或者修改本機的hosts文件。

172.16.7.152 traefik.nginx.io
172.16.7.152 traefik.frontend.io

全部訪問這些地址的流量都會發送給172.16.7.152這臺主機,就是咱們啓動traefik的主機。

Traefik會解析http請求header裏的Host參數將流量轉發給Ingress配置裏的相應service。

修改hosts後就就能夠在kubernetes集羣外訪問以上兩個service。

 

8、健康檢查

關於健康檢查,測試可使用 kubernetes 的 Liveness Probe 實現,若是 Liveness Probe檢查失敗,則 traefik 會自動移除該 pod。

【示例】:咱們定義一個 test-health 的 deployment,健康檢查方式是 cat /tmp/health,容器啓動 2 分鐘後會刪掉這個文件,模擬健康檢查失敗。

test-health的deployment:

[root@node1 traefik]# cat test-health-deploy.yaml 
apiVersion: v1
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: test
  namespace: default
  labels:
    test: alpine
spec:
  replicas: 1
  selector:
    matchLabels:
      test: alpine
  template:
    metadata:
      labels:
        test: alpine
        name: test
    spec:
      containers:
      - image: mritd/alpine:3.4
        name: alpine
        resources:
          limits:
            cpu: 200m
            memory: 30Mi
          requests:
            cpu: 100m
            memory: 20Mi
        ports:
        - name: http
          containerPort: 80
        args:
        command:
        - "bash"
        - "-c"
        - "echo ok > /tmp/health;sleep 120;rm -f /tmp/health"
        livenessProbe:
          exec:
            command:
            - cat
            - /tmp/health
          initialDelaySeconds: 20
test-health-deploy.yaml

test-health 的 service:

[root@node1 traefik]# vim test-health-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: test 
  labels:
    name: test
spec:
  ports:
  - port: 8123
    targetPort: 80
  selector:
    name: test
test-health-service.yaml

test-health的 Ingress:

[root@node1 traefik]# vim test-health-ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test
spec:
  rules:
  - host: test.com
    http:
      paths:
      - path: /
        backend:
          serviceName: test
          servicePort: 8123
test-health-ingress.yaml

所有建立好之後,進入 traefik ui 界面,能夠觀察到每隔 2 分鐘健康檢查失敗後,kubernetes 重建 pod,同時 traefik 會從後端列表中移除這個 pod。

相關文章
相關標籤/搜索