kubernetes使用Træfik代理服務

1、簡介html

    Træfik是一個爲了讓部署微服務更加便捷而誕生的現代HTTP反向代理、負載均衡工具。 它支持多種後臺 (Docker, Swarm mode, Kubernetes, Marathon, Consul, Etcd, Rancher, ...) 來自動化、動態的應用它的配置文件設置。前端

    Træfɪk 能夠監聽你的服務發現、管理API,而且每當你的微服務被添加、移除、殺死或更新都會被感知,而且能夠自動生成它們的配置文件,指向到你服務的路由將會被直接建立出來。node

traefik.png

如上圖所示,kubernetes部署了一堆service,這裏咱們就能夠經過在kubernetes上部署Træfik監聽API,使用vhosts或者前綴路徑配置反代:linux

  • 域名api.domain.com將指向您的私有網絡中微服務apigit

  • 路徑domain.com/web將指向您的私有網絡的微服務Webgithub

  • 域名backoffice.domain.com將指向您的私有網絡中的微服務backoffice,並在您的多個實例之間負載web


讓咱們放大Træfik並查看其內部架構:後端

internal.png

  • 顧名思義,傳入的請求在入口點結束,它們是Træfik的網絡入口點(監聽端口,SSL,流量重定向...)。api

  • 以後流量會被轉發到匹配的前端。 前端定義從入口點到後端的路由。 路由是使用請求字段(Host, Path, Headers...)建立的,能夠匹配或不匹配請求。瀏覽器

  • 前端會將請求發送到後端。 後端能夠由一臺或經由負載均衡策略配置的多臺服務器組成。

  • 最後,服務器會將請求轉發到私有網絡中相應的微服務。


詳細內容請查看官方文檔:

https://docs.traefik.io/


2、Kubernetes安裝Træfik

1.下載Træfik的yaml文件

# wget https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/traefik-rbac.yaml
# wget https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/traefik-ds.yaml
# wget https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/ui.yaml


2.更改DaemonSet文件中的端口

# cat traefik-ds.yaml 
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: traefik-ingress-controller
  namespace: kube-system
---
kind: DaemonSet
apiVersion: extensions/v1beta1
metadata:
  name: traefik-ingress-controller
  namespace: kube-system
  labels:
    k8s-app: traefik-ingress-lb
spec:
  template:
    metadata:
      labels:
        k8s-app: traefik-ingress-lb
        name: traefik-ingress-lb
    spec:
      serviceAccountName: traefik-ingress-controller
      terminationGracePeriodSeconds: 60
      hostNetwork: true
      containers:
      - image: 192.168.100.100/traefik/traefik:1.6.2
        name: traefik-ingress-lb
        ports:
        - name: http
          containerPort: 80
          hostPort: 80
        - name: admin
          containerPort: 8081
        securityContext:
          capabilities:
            drop:
            - ALL
            add:
            - NET_BIND_SERVICE
        args:
        #- --api
        - --web.address=:8081
        - --kubernetes
        - --logLevel=INFO
---
kind: Service
apiVersion: v1
metadata:
  name: traefik-ingress-service
  namespace: kube-system
spec:
  selector:
    k8s-app: traefik-ingress-lb
  ports:
    - protocol: TCP
      port: 80
      name: web
    - protocol: TCP
      port: 8081
      name: admin
  type: NodePort

注:因爲個人master節點同時也是node,而8080端口是kube-apiserver的端口,這產生了衝突,這裏我將該端口改成8081端口。

   同時去掉- --api選項並添加- --web.address=:8081選項。


3.更改鏡像爲私有鏡像倉庫(根據狀況配置)並配置Træfik Web UI域名

# sed -i "s/image: traefik/image: 192.168.100.100\/traefik\/traefik:1.6.2/g" traefik-ds.yaml
# sed -i "s/traefik-ui.minikube/traefik-ui.io/g" ui.yaml


4.運行yaml文件並查看

# kubectl create -f .
serviceaccount "traefik-ingress-controller" created
daemonset "traefik-ingress-controller" created
service "traefik-ingress-service" created
clusterrole "traefik-ingress-controller" created
clusterrolebinding "traefik-ingress-controller" created
service "traefik-web-ui" created
ingress "traefik-web-ui" created
# kubectl get pod -n kube-system | grep traefik
traefik-ingress-controller-sjmp2    1/1     Running   0     3d
traefik-ingress-controller-t5rgg    1/1     Running   0     3d
traefik-ingress-controller-tltvm    1/1     Running   0     3d
# kubectl exec -it traefik-ingress-controller-sjmp2 -n kube-system /traefik version
Version:      v1.6.2
Codename:     tetedemoine
Go version:   go1.10.2
Built:        2018-05-22_03:19:06PM
OS/Arch:      linux/amd64


4.登錄Træfik Web UI

# kubectl get service -n kube-system | grep traefik
traefik-ingress-service   NodePort    10.244.46.110    <none>        80:29484/TCP,8081:13879/TCP   3d
traefik-web-ui            ClusterIP   10.244.87.207    <none>        80/TCP                        3d
# kubectl get ing -n kube-system
NAME             HOSTS           ADDRESS   PORTS     AGE
traefik-web-ui   traefik-ui.io             80        3d

注:

80 對應服務端口,8080 對應 UI 端口

瀏覽器登錄http://<node_ip>:<node_port>訪問Træfik

這裏咱們在客戶端添加相應host來訪問Træfik Web UI,如:

192.168.100.103   traefik-ui.io

如今咱們可使用traefik-ui.io來登錄查看

01.PNG


5.配置訪問Prometheus

# cat prom.yaml 
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: grafana
  namespace: monitoring       ##根據狀況配置namespace
spec:
  rules:
  - host: prom.zhi.io      ##替換爲您集羣默認的服務訪問域名
    http:
      paths:
      - path: 
        backend:
          serviceName: grafana
          servicePort: 3000
# kubectl get ing -n monitoring
NAME      HOSTS         ADDRESS   PORTS     AGE
grafana   prom.zhi.io             80        3d


查看Traefik Web UI
02.PNG


配置hosts後使用相應域名登錄Prometheus

03.PNG


3、配置Basic身份驗證

1.使用htpasswd建立一個包含用戶名和MD5密碼文件

# yum -y install httpd
# htpasswd -c auth admin       ###建立祕鑰文件auth並添加用戶admin
New password: 
Re-type new password: 
Adding password for user admin
# cat auth 
admin:$apr1$h0.DZ9TF$6JN.FSka4Wdy5eUL4t1ut0


2.建立secret

# kubectl create secret generic mysecret --from-file auth --namespace=monitoring
secret "mysecret" created


3.將下面的註釋附加到 Ingress對象:

  • kubernetes.io/ingress.class: traefik             ----->聲明ingress後端採用traefik實現

  • ingress.kubernetes.io/auth-type: "basic"         ----->聲明認證模式爲basic模式

  • ingress.kubernetes.io/auth-secret: "mysecret"    ----->聲明namespace裏對應的secret


4.配置運行並確認

# cat prom.yaml 
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: grafana
  namespace: monitoring
  annotations:
    kubernetes.io/ingress.class: traefik
    ingress.kubernetes.io/auth-type: "basic"
    ingress.kubernetes.io/auth-secret: "mysecret"
spec:
  rules:
  - host: prom.zhi.io 
    http:
      paths:
      - path: 
        backend:
          serviceName: grafana
          servicePort: 3000
# kubectl apply -f prom.yaml 
ingress "grafana" configured

瀏覽器輸入prom.zhi.io,彈出身份驗證窗口,這裏輸入htpasswd命令建立的用戶名和密碼登陸

01.PNG


輸入用戶名和密碼並點擊登陸後便可進入該域名

02.PNG


4、Træfik添加TLS認證

1.使用openssl生成證書和密鑰

# openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=traefik-ui.io"
Generating a 2048 bit RSA private key
.................+++
................................................................+++
writing new private key to 'tls.key'
-----
# ls tls*
tls.crt  tls.key


2.建立Secret

# kubectl -n kube-system create secret tls traefik-ui-tls-cert --key=tls.key --cert=tls.crt
secret "traefik-ui-tls-cert" created
# kubectl get secret -n kube-system traefik-ui-tls-cert
NAME                  TYPE                DATA      AGE
traefik-ui-tls-cert   kubernetes.io/tls   2         1h


3.配置Entrypoints

Entrypoints是Træfɪk的網絡入口。它們能夠經過如下方式來定義:

a.一個端口 (80, 443...)

b.SSL (證書, 密鑰, 由受信任的CA簽名的客戶端證書的身份驗證...)

c.重定向到其餘的入口點 (重定向 HTTP 到 HTTPS)

# cat traefik.toml 
defaultEntryPoints = ["http","https"]
insecureskipverify = true
[entryPoints]
  [entryPoints.http]
  address = ":80"
    [entryPoints.http.redirect]
      entryPoint = "https"
  [entryPoints.https]
  address = ":443"
    [entryPoints.https.tls]
      [[entryPoints.https.tls.certificates]]
      CertFile = "/ssl/tls.crt"
      KeyFile = "/ssl/tls.key"

注:

a.如上定義了兩個入口點,http 和 https  

b.http 監聽 80 端口, https 監聽 443 端口

c.經過提供一個證書和一個密鑰在 https 中開啓SSL

d.轉發全部的 http 入口點請求到 https 入口點

e.insecureSkipVerify :

  若是設置爲true,則後端將接受無效的SSL證書。

  這將禁用中間人×××的檢測,所以只能用於安全的後端網絡。

  因爲這裏我但願traefik能代理Kubernetes dashboard(啓用了https),因此啓用了該選項



4.建立ConfigMap  

# kubectl -n kube-system create configmap traefik --from-file=traefik.toml
configmap "traefik" created
# kubectl get configmap -n kube-system traefik
NAME      DATA      AGE
traefik   1         1h
# kubectl get configmap  -n kube-system traefik -o yaml
apiVersion: v1
data:
  traefik.toml: |+
    defaultEntryPoints = ["http","https"]
    insecureskipverify = true
    [entryPoints]
      [entryPoints.http]
      address = ":80"
        [entryPoints.http.redirect]
        entryPoint = "https"
      [entryPoints.https]
      address = ":443"
        [entryPoints.https.tls]
          [[entryPoints.https.tls.certificates]]
          certFile = "/ssl/tls.crt"
          keyFile = "/ssl/tls.key"
kind: ConfigMap
metadata:
  creationTimestamp: 2018-06-04T05:55:44Z
  name: traefik
  namespace: kube-system
  resourceVersion: "10549957"
  selfLink: /api/v1/namespaces/kube-system/configmaps/traefik
  uid: eb9b845a-67bb-11e8-b7ff-000c297aff5d


5.配置DaemonSet

# cat traefik-ds.yaml 
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: traefik-ingress-controller
  namespace: kube-system
---
kind: DaemonSet
apiVersion: extensions/v1beta1
metadata:
  name: traefik-ingress-controller
  namespace: kube-system
  labels:
    k8s-app: traefik-ingress-lb
spec:
  template:
    metadata:
      labels:
        k8s-app: traefik-ingress-lb
        name: traefik-ingress-lb
    spec:
      serviceAccountName: traefik-ingress-controller
      terminationGracePeriodSeconds: 60
      hostNetwork: true
      volumes:
      - name: ssl
        secret:
          secretName: traefik-ui-tls-cert
      - name: config
        configMap:
          name: traefik
      containers:
      - image: 192.168.100.100/traefik/traefik:1.6.2
        name: traefik-ingress-lb
        volumeMounts:
        - mountPath: "/ssl"
          name: "ssl"
        - mountPath: "/config"
          name: "config"
        ports:
        - name: http
          containerPort: 80
          hostPort: 80
        - name: https
          containerPort: 443
          hostPort: 443
        - name: admin
          containerPort: 8081
        securityContext:
          capabilities:
            drop:
            - ALL
            add:
            - NET_BIND_SERVICE
        args:
        #- --api
        - --configfile=/config/traefik.toml
        - --web.address=:8081
        - --kubernetes
        - --logLevel=INFO
---
kind: Service
apiVersion: v1
metadata:
  name: traefik-ingress-service
  namespace: kube-system
spec:
  selector:
    k8s-app: traefik-ingress-lb
  ports:
    - protocol: TCP
      port: 80
      name: web
    - protocol: TCP
      port: 8081
      name: admin
  type: NodePort
# kubectl create -f traefik-ds.yaml 
serviceaccount "traefik-ingress-controller" created
daemonset "traefik-ingress-controller" created
service "traefik-ingress-service" created


6.配置UI

# cat 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: 8081
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: traefik-web-ui
  namespace: kube-system
  annotations:
    kubernetes.io/ingress.class: traefik
spec:
  rules:
  - host: traefik-ui.io
    http:
      paths:
      - path: /
        backend:
          serviceName: traefik-web-ui
          servicePort: web
  tls:
   - secretName: traefik-ui-tls-cert
# kubectl create -f ui.yaml 
service "traefik-web-ui" created
ingress "traefik-web-ui" created
# kubectl get ing -n kube-system traefik-web-ui
NAME             HOSTS           ADDRESS   PORTS     AGE
traefik-web-ui   traefik-ui.io             80, 443   1h


7.進行測試

瀏覽器輸入traefik-ui.io會自動跳轉至https://traefik-ui.io

01.PNG

瀏覽器輸入prom.zhi.io自動跳轉至https://prom.zhi.io,輸入用戶名、密碼便可進入

01.PNG

01.PNG


8.配置traefik代理kubernetes dashboard

a.配置並運行ingress


# cat k8s.yaml 
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: kubernetes-dashboard
  namespace: kube-system
  annotations:
    kubernetes.io/ingress.class: traefik
spec:
  rules:
  - host: "k8s.zhi.io"
    http:
      paths:
      - backend:
          serviceName: kubernetes-dashboard
          servicePort: 443
# kubectl create -f k8s.yaml 
ingress "kubernetes-dashboard" created
# kubectl -n kube-system get ing kubernetes-dashboard
NAME                   HOSTS        ADDRESS   PORTS     AGE
kubernetes-dashboard   k8s.zhi.io             80        6m


b.進行測試

01.PNG

01.PNG

01.PNG


注:

a.在配置TLS中我參考了該篇博文:https://www.cnblogs.com/ericnie/p/8856339.html

b.在配置中可參考官方文檔:https://docs.traefik.io

相關文章
相關標籤/搜索