kubernets Traefik 的HTTP 和HTTPS

weixin_33728268發表於2018-01-04

k8s 的ingress+traefik原理細說

ingress 本質上就是一個nginx或者traefik 代理。 他將使用者的請求該域名的請求轉發到後端的service。

做LB 實際上是kubernets的Service。

部署原理

daemonset 方式部署 traffic或者nginx,讓其監聽在80埠和443埠,預設是隨機埠,通過hostport可以指定埠

K8S 中必須 Create Role Based Access 蛋疼,

---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: traefik-ingress-controller
rules:
  - apiGroups:
      - ""
    resources:
      - services
      - endpoints
      - secrets
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - extensions
    resources:
      - ingresses
    verbs:
      - get
      - list
      - watch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: traefik-ingress-controller
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: traefik-ingress-controller
subjects:
- kind: ServiceAccount
  name: traefik-ingress-controller
  namespace: kube-system

daemonset 例子

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: traefik-ingress-controller
  namespace: kube-system
---
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: traefik-ingress-controller
  namespace: kube-system
  labels:
    k8s-app: traefik-ingress-lb
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s-app: traefik-ingress-lb
  template:
    metadata:
      labels:
        k8s-app: traefik-ingress-lb
        name: traefik-ingress-lb
    spec:
      serviceAccountName: traefik-ingress-controller
      terminationGracePeriodSeconds: 60
      containers:
      - image: traefik
        name: traefik-ingress-lb
        args:
        - --web
        - --kubernetes
---
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: 8080
      name: admin
  type: NodePort

建立DaemonSet

Kubectl create -f ds.yaml

kubectl --namespace=kube-system get pods

NAME                                         READY     STATUS    RESTARTS   AGE
kube-addon-manager-minikubevm                1/1       Running   0          4h
kubernetes-dashboard-s8krj                   1/1       Running   0          4h
traefik-ingress-controller-678226159-eqseo   1/1       Running   0          7m

構建UI

apiVersion: v1
kind: Service
metadata:
  name: traefik-web-ui
  namespace: kube-system
spec:
  selector:
    k8s-app: traefik-ingress-lb
  ports:
  - port: 80
    targetPort: 8080
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: traefik-web-ui
  namespace: kube-system
  annotations:
    kubernetes.io/ingress.class: traefik
spec:
  rules:
  - host: traefik-ui.minikube
    http:
      paths:
      - backend:
          serviceName: traefik-web-ui
          servicePort: 80
轉發規則
---
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
 name: stilton
 labels:
   app: cheese
   cheese: stilton
spec:
 replicas: 2
 selector:
   matchLabels:
     app: cheese
     task: stilton
 template:
   metadata:
     labels:
       app: cheese
       task: stilton
       version: v0.0.1
   spec:
     containers:
     - name: cheese
       image: errm/cheese:stilton
       ports:
       - containerPort: 80
---
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
 name: cheddar
 labels:
   app: cheese
   cheese: cheddar
spec:
 replicas: 2
 selector:
   matchLabels:
     app: cheese
     task: cheddar
 template:
   metadata:
     labels:
       app: cheese
       task: cheddar
       version: v0.0.1
   spec:
     containers:
     - name: cheese
       image: errm/cheese:cheddar
       ports:
       - containerPort: 80
---
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
 name: wensleydale
 labels:
   app: cheese
   cheese: wensleydale
spec:
 replicas: 2
 selector:
   matchLabels:
     app: cheese
     task: wensleydale
 template:
   metadata:
     labels:
       app: cheese
       task: wensleydale
       version: v0.0.1
   spec:
     containers:
     - name: cheese
       image: errm/cheese:wensleydale
       ports:
       - containerPort: 80

基於https

沿用上文 的Role Based Access(RBAC)

首先得釐清幾個概念

  • Secret, 儲存金鑰檔案, 我們這次把pem,key等檔案通過這種方式傳入pod 內

    # 建立一個名為 ak-cert secret檔案
    kubectl create secret generic mjb-cert --from-file=/server.pem --from-file=server.key
    

  • ConfigMap,配置檔案,建立一個配置檔案,和secret一樣, 通過volumes方式掛載到容器內

    cat traefik.toml 
    defaultEntryPoints = ["http","https"]
    [entryPoints]
      [entryPoints.http]
      address = ":80"
        [entryPoints.http.redirect]
          entryPoint = "https"
      [entryPoints.https]
      address = ":443"
        [entryPoints.https.tls]
          [[entryPoints.https.tls.certificates]]
          CertFile = "/mjb/server.pem"
          KeyFile = "/mjb/server.key"
    

  • 掛載方法

    
    #定義volumes
    volumes:
          - name: mjb
            secret:
              secretName: ak-cert
          - name: config
            configMap:
              name: traefik-conf
          containers:
          - image: traefik
            name: traefik-ingress-lb
            ## 掛載
            volumeMounts:
            - mountPath: "/mjb"
              name: "mjb"
            - mountPath: "/config"
              name: "config"
    
  • 部署daemonset

    [root@master https]# cat dae.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
          volumes:
          - name: mjb
            secret:
              secretName: mjb-cert
          - name: config
            configMap:
              name: traefik-conf
          containers:
          - image: traefik
            name: traefik-ingress-lb
            volumeMounts:
            - mountPath: "/mjb"
              name: "mjb"
            - mountPath: "/config"
              name: "config"
            ports:
            - name: web
              containerPort: 80
              hostPort: 80
            - name: https
              containerPort: 443
              hostPort: 443
            - name: admin
              containerPort: 8580
            args:
            - --web
            - --kubernetes
            - --web.address=:8580
            - --configfile=/config/traefik.toml
    ---
    kind: Service
    apiVersion: v1
    metadata:
      name: traefik
      namespace: kube-system
    spec:
      selector:
        k8s-app: traefik-ingress-lb
      ports:
      - protocol: TCP
        port: 80
        name: http
      - protocol: TCP
        port: 443
        name: https
      - protocol: TCP
        port: 8580
        name: admin
      type: NodePort
    

  • 部署基於https的UI

    apiVersion: v1
    kind: Service
    metadata:
      name: traefik-web-ui
      namespace: kube-system
    spec:
      selector:
        k8s-app: traefik-ingress-lb
      ports:
      - port: 80
        targetPort: 8580
    ---
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: traefik-web-ui
      namespace: kube-system
      annotations:
        kubernetes.io/ingress.class: traefik
    spec:
      tls:
        - secretName: traefik-cert
      rules:
      - host: ui.domain.com
        http:
          paths:
          - backend:
              serviceName: traefik-web-ui
              servicePort: 80
    

    訪問測試 ui.domain.com, 對了上文的證書需自己準備,如果沒有可以生成

openssl req -newkey rsa:2048 -nodes -keyout domain.com.key  -x509 -days 365 -out domain.com.crt

相關文章