kubernetes使用Træfik代理服务

一、简介

    Træfik是一个为了让部署微服务更加便捷而诞生的现代HTTP反向代理、负载均衡工具。 它支持多种后台 (Docker, Swarm mode, Kubernetes, Marathon, Consul, Etcd, Rancher, ...) 来自动化、动态的应用它的配置文件设置。

    Træfɪk 可以监听你的服务发现、管理API,并且每当你的微服务被添加、移除、杀死或更新都会被感知,并且可以自动生成它们的配置文件,指向到你服务的路由将会被直接创建出来。

traefik.png

如上图所示,kubernetes部署了一堆service,这里我们就可以通过在kubernetes上部署Træfik监听API,使用vhosts或者前缀路径配置反代:

  • 域名api.domain.com将指向您的私有网络中微服务api

  • 路径domain.com/web将指向您的私有网络的微服务Web

  • 域名backoffice.domain.com将指向您的私有网络中的微服务backoffice,并在您的多个实例之间负载


让我们放大Træfik并查看其内部架构:

internal.png

扫描二维码关注公众号,回复: 1495166 查看本文章
  • 顾名思义,传入的请求在入口点结束,它们是Træfik的网络入口点(监听端口,SSL,流量重定向...)。

  • 之后流量会被转发到匹配的前端。 前端定义从入口点到后端的路由。 路由是使用请求字段(Host, Path, Headers...)创建的,可以匹配或不匹配请求。

  • 前端会将请求发送到后端。 后端可以由一台或经由负载均衡策略配置的多台服务器组成。

  • 最后,服务器会将请求转发到私有网络中相应的微服务。


详细内容请查看官方文档:

https://docs.traefik.io/


二、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


三、配置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


四、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


猜你喜欢

转载自blog.51cto.com/wangzhijian/2125520
tr