1.參考文檔
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,且訪問成功