k8s實踐13:traefik配置https訪問

1.參考文檔

http://traefik.cn/

2.訪問方式簡易說明

參考文檔
https://tonybai.com/2018/06/25/the-kubernetes-ingress-practice-for-https-service/

前面一篇:traefik基礎部署記錄,介紹了最簡單的http訪問traefik,訪問過程參考見下:

client --- (via http) ---> traefik ---- (via http) ---->  services

現在要實踐的是更安全也更復雜的https訪問traefik,有兩種訪問過程,參考見下:

後端service是普通http的
即client與traefik間採用https加密通信,但traefik與svc間則是明文的http通信

client --- (via https) ---> traefik ---- (via http) ---->  services

後端service是https的
即client與traefik間採用https加密通信,但traefik與svc也是採用https通信

client --- (via https) ---> traefik ---- (via https) ---->  services

3.部署前需要了解的https基礎知識

參考文檔:
http://blog.jobbole.com/110354/

能不能用一句話總結HTTPS?
答案是不能,因爲HTTPS本身實在太複雜。但是我還是嘗試使用一段話來總結HTTPS:

HTTPS要使客戶端與服務器端的通信過程得到安全保證,必須使用的對稱加密算法,但是協商對稱加密算法的過程,需要使用非對稱加密算法來保證安全,然而直接使用非對稱加密的過程本身也不安全,會有中間人篡改公鑰的可能性,所以客戶端與服務器不直接使用公鑰,而是使用數字證書籤發機構頒發的證書來保證非對稱加密過程本身的安全。這樣通過這些機制協商出一個對稱加密算法,就此雙方使用該算法進行加密解密。從而解決了客戶端與服務器端之間的通信安全問題。

爲什麼需要引入證書,上面那篇文章說得很棒。
進行ssl通訊,必須需要一個權威機構認證的證書(這個需要Money),我們是實驗環境,自己建一個證書玩玩。除了證書,還需要web軟件(這裏是traefik)開啓ssl支持並採用我們建立的證書。

4.配置證書

實驗環境用現有的證書,用k8s集羣的證書。

[root@k8s-master1 ~]# cd /etc/kubernetes/cert/
[root@k8s-master1 cert]# ls
ca-config.json  ca.pem                            kube-controller-manager.pem            kubelet.key          kubernetes.pem
ca.csr          kube-controller-manager.csr      kubelet-client-2019-02-28-11-16-44.pem  kubernetes.csr
ca-csr.json    kube-controller-manager-csr.json  kubelet-client-current.pem              kubernetes-csr.json
ca-key.pem      kube-controller-manager-key.pem  kubelet.crt                            kubernetes-key.pem
[root@k8s-master1 cert]# 

注意操作目錄,如果不是在此目錄下操作,須指定絕對路徑
創建secret,後面部署時通過掛載volume的方式,掛載進pod.

[root@k8s-master1 cert]# kubectl create secret generic traefik-cert --from-file=ca-key.pem --from-file=ca.pem -n kube-system
secret "traefik-cert" created
[root@k8s-master1 cert]# 

5.創建預讀取的配置文件並用它創建configmap

這裏的traefik中配置了把所有http請求全部rewrite爲https的規則,並配置相應的證書位置:

[root@k8s-master1 config]# pwd
/config
[root@k8s-master1 config]# ls
traefik.toml
[root@k8s-master1 config]# 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 = "/etc/kubernetes/cert/ca.pem"
      keyFile = "/etc/kubernetes/cert/ca-key.pem"
[root@k8s-master1 config]# 
[root@k8s-master1 config]# kubectl create configmap traefik-conf --from-file=traefik.toml -n kube-system
configmap "traefik-conf" created

6.

修改traefik配置文件
掛載前面配置的證書secret:traefik-cert
掛載預讀取的配置文件configmap:traefik-conf
增加ports:443(svc和pod)

[root@k8s-master1 traefik]# cat traefik-deployment.yaml
---
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: 3
  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
      volumes:
      - name: ssl
        secret:
         secretName: traefik-cert
      - name: config
        configMap:
         name: traefik-conf
      containers:
      - image: traefik
        name: traefik-ingress-lb
        volumeMounts:
        - mountPath: "/etc/kubernetes/cert"
          name: "ssl"
        - mountPath: "/config"
          name: "config"
        ports:
        - name: http
          containerPort: 80
        - name: https
          containerPort: 443
        - name: admin
          containerPort: 8080
        args:
        - --api
        - --kubernetes
        - --logLevel=INFO
        - --configfile=/config/traefik.toml
---
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
  externalIPs:
    - 192.168.32.127
 args:
        - --api
        - --kubernetes
        - --configfile=/config/traefik.toml 

這個參數是用來幹嘛的呢?
這是參數,這裏是容器啓動時執行ENTRYPOINT命令引用的參數
看看traefik鏡像的history

[root@kubernetes1 k8s]# docker history --no-trunc=true docker.io/traefik
IMAGE                                                                     CREATED             CREATED BY                                                                                                                                                                                                                                                         SIZE                COMMENT
sha256:11569c00178041f0502a3251a2d33196c9a153c564814bc9f712c704a85200c2   3 weeks ago         /bin/sh -c #(nop)  LABEL org.label-schema.vendor=Containous org.label-schema.url=https://traefik.io org.label-schema.name=Traefik org.label-schema.description=A modern reverse-proxy org.label-schema.version=v1.6.5 org.label-schema.docker.schema-version=1.0   0 B                
<missing>                                                                 3 weeks ago         /bin/sh -c #(nop)  ENTRYPOINT ["/traefik"]                                                                                                                                                                                                                         0 B                
<missing>                                                                 3 weeks ago         /bin/sh -c #(nop)  EXPOSE 80/tcp                                                                                                                                                                                                                                   0 B                
<missing>                                                                 3 weeks ago         /bin/sh -c #(nop) COPY file:ba6114281de19b8e363e82ed5b30471e264464b79049c538a86b7eae309ab46e in /                                                                                                                                                                  52.2 MB            
<missing>                                                                 6 weeks ago         /bin/sh -c #(nop) COPY file:d8282341d1fb7d2cc3d5d3523d0d4126066cc1ba8abe3f0047a459b3a63a5653 in /etc/ssl/certs/                                                                                                                                                    275 kB             
[root@kubernetes1 k8s]#

其實就是執行

`<missing>                                                                 3 weeks ago         /bin/sh -c #(nop)  ENTRYPOINT ["/traefik"]   `

時的參數

7.
執行部署

[root@k8s-master1 traefik]# vi traefik-deployment.yaml
[root@k8s-master1 traefik]# kubectl apply -f traefik-deployment.yaml
serviceaccount "traefik-ingress-controller" created
deployment.extensions "traefik-ingress-controller" created
service "traefik-ingress-service" created
[root@k8s-master1 traefik]#
[root@k8s-master1 traefik]# kubectl get svc,pod -n kube-system
NAME                              TYPE        CLUSTER-IP      EXTERNAL-IP      PORT(S)                  AGE
service/kube-dns                  ClusterIP  10.254.0.2      <none>          53/UDP,53/TCP            23h
service/kubernetes-dashboard      ClusterIP  10.254.219.111  <none>          443/TCP                  1h
service/traefik-ingress-service  ClusterIP  10.254.98.177    192.168.32.127  80/TCP,443/TCP,8080/TCP  31s
service/traefik-web-ui            ClusterIP  10.254.124.127  <none>          80/TCP                    1d

NAME                                              READY    STATUS    RESTARTS  AGE
pod/coredns-779ffd89bd-wmzhf                      1/1      Running  2          6h
pod/kubernetes-dashboard-65c76f6c97-m29nl        1/1      Running  1          1h
pod/traefik-ingress-controller-846c7dbd96-4mjl2  0/1      Unknown  0          1h
pod/traefik-ingress-controller-c6978f9f7-lmcpm    1/1      Running  0          31s
pod/traefik-ingress-controller-c6978f9f7-vd8g9    1/1      Running  0          31s
pod/traefik-ingress-controller-c6978f9f7-vsq4v    1/1      Running  0          31s

8.
可能出現的錯誤

[root@k8s-master1 traefik]#kubectl logs traefik-ingress-controller-gpgss -n kube-system
time="2018-08-01T03:06:30Z" level=error msg="Unable to add a certificate to the entryPoint \"https\" : unable to generate TLS certificate : tls: failed to find any PEM data in certificate input"
time="2018-08-01T03:06:30Z" level=error msg="Error creating TLS config: No certificates found for TLS entrypoint https"
time="2018-08-01T03:06:30Z" level=fatal msg="Error preparing server: No certificates found for TLS entrypoint https"  

這是路徑問題導致:
見下面的配置參數

traefik.toml文件的路徑

[[entryPoints.https.tls.certificates]]
      certFile = "/etc/kubernetes/cert/ca.pem"
      keyFile = "/etc/kubernetes/cert/ca-key.pem"

##這個證書是存放在k8s node上的目錄

volumeMounts:
        - mountPath: "/etc/kubernetes/cert"
         name: "ssl"
        - mountPath: "/config"
          name: "config"

##爲什麼這個目錄要配置成和traefik.toml裏的路徑一樣呢?思考下.注意這個掛載路徑是會自動建立的

        args:
        - --api
        - --kubernetes
        - --configfile=/config/traefik.toml

##原因就是因爲這個引用,如果上面mountPath配置的路徑不正確,將找不到配置的證書.configfile引用traefik.toml,traefik.toml引用的路徑是前面node上的,在容器裏如果不建立一樣的路徑,traefik.toml在容器裏去哪讀取證書呢?

traefik已經部署成功.

9.

看看前面提到的訪問過程示圖:

client --- (via https) ---> traefik ---- (via http) ---->  services

先測試這個

svc,po情況

[root@k8s-master1 traefik]# kubectl get svc,pod
NAME                TYPE        CLUSTER-IP      EXTERNAL-IP  PORT(S)      AGE
service/httpd-svc    NodePort    10.254.33.250  <none>        80:8768/TCP  1d
service/kubernetes  ClusterIP  10.254.0.1      <none>        443/TCP      1d

NAME                            READY    STATUS    RESTARTS  AGE
pod/httpd-app-bbcbfb6cd-k764q  1/1      Running  3          1d
[root@k8s-master1 traefik]#

ingress文件

[root@k8s-master1 traefik]# cat ../httpd-svc-ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: httpd-svc-ingress
  namespace: default
spec:
  rules:
  - host: httpd-svc.ingress
    http:
      paths:
      - path: /
        backend:
          serviceName: httpd-svc
          servicePort: 80
[root@k8s-master1 traefik]#

執行部署

[root@k8s-master1 traefik]# kubectl apply -f  ../httpd-svc-ingress.yaml
ingress.extensions "httpd-svc-ingress" created
[root@k8s-master1 traefik]# kubectl get ing
NAME                HOSTS              ADDRESS  PORTS    AGE
httpd-svc-ingress  httpd-svc.ingress            80        5s
[root@k8s-master1 traefik]#

測試,已經自動切換成https,且訪問成功

k8s實踐13:traefik配置https訪問

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章