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
3 weeks ago /bin/sh -c #(nop) ENTRYPOINT ["/traefik"] 0 B
3 weeks ago /bin/sh -c #(nop) EXPOSE 80/tcp 0 B
3 weeks ago /bin/sh -c #(nop) COPY file:ba6114281de19b8e363e82ed5b30471e264464b79049c538a86b7eae309ab46e in / 52.2 MB
6 weeks ago /bin/sh -c #(nop) COPY file:d8282341d1fb7d2cc3d5d3523d0d4126066cc1ba8abe3f0047a459b3a63a5653 in /etc/ssl/certs/ 275 kB
[root@kubernetes1 k8s]#
其实就是执行
` 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 53/UDP,53/TCP 23h
service/kubernetes-dashboard ClusterIP 10.254.219.111 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 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 80:8768/TCP 1d
service/kubernetes ClusterIP 10.254.0.1 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,且访问成功