1. 程式人生 > >kubernetes traefik配置https實踐操作記錄

kubernetes traefik配置https實踐操作記錄

實驗環境 rate 解決 操作 總結 cert spec setting -a

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@kubernetes1 ~]# cd /etc/kubernetes/ssl/
[root@kubernetes1 ssl]# ls
admin.csr? ? ? apiserver-key.pem? ca.srl? ? ? ? ? ? ? ? ? ? ? kubernetes2-worker.csr? ? ? kubernetes3-worker-key.pem
admin-key.pem? apiserver.pem? ? ? kubernetes1-worker.csr? ? ? kubernetes2-worker-key.pem? kubernetes3-worker.pem
admin.pem? ? ? ca-key.pem? ? ? ?? kubernetes1-worker-key.pem? kubernetes2-worker.pem? ? ? openssl.cnf
apiserver.csr? ca.pem? ? ? ? ? ?? kubernetes1-worker.pem? ? ? kubernetes3-worker.csr? ? ? worker-openssl.cnf
[root@kubernetes1 ssl]#

註意操作目錄,如果不是在此目錄下操作,須指定絕對路徑

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

5.創建configmap,保存traefik的配置

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

[root@kubernetes1 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/ssl/ca.pem"
? ? ? keyFile = "/etc/kubernetes/ssl/ca-key.pem"
[root@kubernetes1 config]# kubectl create configmap traefik-conf --from-file=traefik.toml -n kube-system
configmap "traefik-conf" created
[root@kubernetes1 config]# kubectl get cm -n kube-system
NAME? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? DATA? ? ? AGE
extension-apiserver-authentication?? 6? ? ? ?? 70d
kube-flannel-cfg? ? ? ? ? ? ? ? ? ?? 2? ? ? ?? 70d
kube-proxy? ? ? ? ? ? ? ? ? ? ? ? ?? 2? ? ? ?? 70d
kubeadm-config? ? ? ? ? ? ? ? ? ? ?? 1? ? ? ?? 70d
kubernetes-dashboard-settings? ? ? ? 1? ? ? ?? 61d
mysql1.v1? ? ? ? ? ? ? ? ? ? ? ? ? ? 1? ? ? ?? 28d
traefik-conf? ? ? ? ? ? ? ? ? ? ? ?? 1? ? ? ?? 12s
[root@kubernetes1 config]#``

6.部署Traefik,這裏主要是要關聯創建的secret和configMap,並掛載相對應的主機目錄。

備份下原有文件

[root@kubernetes1 k8s]# cp traefik-deployment.yaml traefik-deployment.yaml.bk
[root@kubernetes1 k8s]# ll

配置好的參考見下:

[root@kubernetes1 k8s]# cat traefik-deployment.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:
? 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
? ? ? hostNetwork: true
? ? ? volumes:
? ? ? - name: ssl
? ? ? ? secret:
? ? ? ? ? secretName: traefik-cert
? ? ? - name: config
? ? ? ? configMap:
? ? ? ? ? name: traefik-conf
? ? ? containers:
? ? ? - image: traefik
? ? ? ? name: traefik-ingress-lb
? ? ? ? volumeMounts:
? ? ? ? - mountPath: "/etc/kubernetes/ssl"
? ? ? ? ? name: "ssl"
? ? ? ? - mountPath: "/config"
? ? ? ? ? name: "config"
? ? ? ? ports:
? ? ? ? - name: http
? ? ? ? ? containerPort: 80
? ? ? ? - name: https
? ? ? ? ? containerPort: 443
? ? ? ? - name: admin
? ? ? ? ? containerPort: 8080
? ? ? ? args:
? ? ? ? - --api
? ? ? ? - --kubernetes
? ? ? ? - --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: 443
? ? ? name: https
? ? - protocol: TCP
? ? ? port: 8080
? ? ? name: admin
? type: NodePort
[root@kubernetes1 k8s]#

關於配置文件參數的一些解釋和說明:

本操作記錄是基於上一篇的操作環境,traefik-rbac.yaml這個是已經配置好了的。如果沒有配置這個,請先配置。

kind: DaemonSet 官方默認是使用Deployment
hostNetwork: true 關於這個基礎篇有解釋

? ? ? 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]#

其實就是執行
&lt;missing&gt;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? 3 weeks ago? ? ? ?? /bin/sh -c #(nop)? ENTRYPOINT ["/traefik"] ??
時的參數

執行部署

[root@kubernetes1 k8s]# kubectl apply -f traefik-deployment.yaml
serviceaccount "traefik-ingress-controller" created
daemonset.extensions "traefik-ingress-controller" created
service "traefik-ingress-service" created
[root@kubernetes1 k8s]# kubectl get po -n kube-system
NAME? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? READY? ?? STATUS? ? RESTARTS?? AGE
etcd-kubernetes1? ? ? ? ? ? ? ? ? ? ? ? 1/1? ? ?? Running?? 39? ? ? ?? 70d
kube-apiserver-kubernetes1? ? ? ? ? ? ? 1/1? ? ?? Running?? 43? ? ? ?? 70d
kube-controller-manager-kubernetes1? ?? 1/1? ? ?? Running?? 42? ? ? ?? 70d
kube-dns-b4bd9576-db5hh? ? ? ? ? ? ? ?? 3/3? ? ?? Running?? 117? ? ? ? 70d
kube-flannel-ds-27wrd? ? ? ? ? ? ? ? ?? 1/1? ? ?? Running?? 73? ? ? ?? 70d
kube-flannel-ds-6lnj9? ? ? ? ? ? ? ? ?? 1/1? ? ?? Running?? 66? ? ? ?? 70d
kube-flannel-ds-xz87r? ? ? ? ? ? ? ? ?? 1/1? ? ?? Running?? 63? ? ? ?? 70d
kube-proxy-hhghb? ? ? ? ? ? ? ? ? ? ? ? 1/1? ? ?? Running?? 39? ? ? ?? 70d
kube-proxy-hwvs9? ? ? ? ? ? ? ? ? ? ? ? 1/1? ? ?? Running?? 39? ? ? ?? 70d
kube-proxy-jcxbz? ? ? ? ? ? ? ? ? ? ? ? 1/1? ? ?? Running?? 39? ? ? ?? 70d
kube-scheduler-kubernetes1? ? ? ? ? ? ? 1/1? ? ?? Running?? 40? ? ? ?? 70d
kubernetes-dashboard-7d5dcdb6d9-5zkkl?? 1/1? ? ?? Running?? 6? ? ? ? ? 6d
tiller-deploy-5c688d5f9b-kfqwx? ? ? ? ? 1/1? ? ?? Running?? 12? ? ? ?? 14d
traefik-ingress-controller-8jxsb? ? ? ? 1/1? ? ?? Running?? 0? ? ? ? ? 6s
traefik-ingress-controller-h5wrh? ? ? ? 1/1? ? ?? Running?? 0? ? ? ? ? 6s

可能出現的錯誤

[root@kubernetes1 k8s]# 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/ssl/ca.pem"
? ? ? keyFile = "/etc/kubernetes/ssl/ca-key.pem"

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

?```
volumeMounts:
? ? ? ? - mountPath: "/etc/kubernetes/ssl"
? ? ? ? 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已經部署成功。

7.traefik飛起來1

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

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

先測試這個
簡單介紹,在k8s集群中部署了wordpress(這是基於http80端口的服務),現在通過traefik https跳轉訪問wordpress

svc,po情況

[root@kubernetes1 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
httpd-svc ClusterIP 10.106.13.46 <none> 80/TCP 13d
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 72d
mysql ClusterIP 10.97.84.51 <none> 3306/TCP 2d
wordpress ClusterIP 10.111.234.225 <none> 8080/TCP 2d
[root@kubernetes1 ~]#

[root@kubernetes1 ~]# kubectl get po
NAME READY STATUS RESTARTS AGE
httpd-749bf8c6f4-bfjfw 1/1 Running 0 2h
httpd-749bf8c6f4-ghpzl 1/1 Running 0 2h
httpd-749bf8c6f4-xvrn4 1/1 Running 0 2h
mysql-5bbbf49b4f-wjw47 1/1 Running 4 2d
nginx-deployment-6b5c99b6fd-pscr6 1/1 Running 0 2h
nginx-deployment-6b5c99b6fd-zr2p7 1/1 Running 0 2h
node-exporter-4gbh9 1/1 Running 24 35d
node-exporter-8h9vp 1/1 Running 25 35d
wordpress-pod-7dd7659959-hc7mr 1/1 Running 4 2d
[root@kubernetes1 ~]#


ingress文件

[root@kubernetes1 ~]# cat wp/wordpress.ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
? name: wordpress-ingress
? namespace: default
spec:
? rules:
? - host: wordpress.ingress
? ? http:
? ? ? paths:
? ? ? - path: /
? ? ? ? backend:
? ? ? ? ? serviceName: wordpress
? ? ? ? ? servicePort: 8080
[root@kubernetes1 ~]#


執行部署

[root@kubernetes1 wp]# kubectl apply -f wordpress.ingress.yaml
ingress.extensions "wordpress-ingress" created

[root@kubernetes1 ~]# kubectl get ing
NAME? ? ? ? ? ? ? ? HOSTS? ? ? ? ? ? ?? ADDRESS?? PORTS? ?? AGE
httpd-svc-ingress?? httpd-svc.ingress? ? ? ? ? ?? 80? ? ? ? 5d
wordpress-ingress?? wordpress.ingress? ? ? ? ? ?? 80? ? ? ? 4d
[root@kubernetes1 ~]#



在訪問的主機解析好域名,訪問正常

8.traefik飛起來2

kubernetes traefik配置https實踐操作記錄