trarfik配置访问https业务应用

参考文档

1.证书

测试环境,使用集群本身的证书

[root@k8s-node1 cert]# pwd
/etc/kubernetes/cert
[root@k8s-node1 cert]# ls
ca-config.json  ca-csr.json  ca.pem                           kube-controller-manager.pem             kubelet-client-current.pem  kubelet.key         kubernetes.pem
ca.csr          ca-key.pem   kube-controller-manager-key.pem  kubelet-client-2019-11-05-04-06-21.pem  kubelet.crt                 kubernetes-key.pem

注意操作目录,如果不是在此目录下操作,须指定绝对路径.

创建secret,后面部署时通过挂载volume的方式,挂载进pod.

kubectl create secret generic traefik-cert --from-file=ca-key.pem --from-file=ca.pem -n kube-system
secret/traefik-cert created

kubectl describe secret traefik-cert -n kube-system
Name:         traefik-cert
Namespace:    kube-system
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
ca-key.pem:  1675 bytes
ca.pem:      1338 bytes

2.创建预读取的配置文件并用它创建configmap

这里的traefik中配置了把所有http请求全部rewrite为https的规则,并配置相应的证书位置.

[root@k8s-node1 cert]# pwd
/etc/kubernetes/cert

[root@k8s-node1 cert]# 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-node1 cert]# kubectl create configmap traefik-conf --from-file=traefik.toml -n kube-system
configmap/traefik-conf created

3.修改traefik配置文件

挂载前面配置的证书secret:traefik-cert
挂载预读取的配置文件configmap:traefik-conf
增加ports:443(svc和pod)
[root@k8s-node1 traefik]# cat traefik-ds.yaml 
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: traefik-ingress-controller
  namespace: kube-system
---
kind: DaemonSet
apiVersion: apps/v1
metadata:
  name: traefik-ingress-controller
  namespace: kube-system
  labels:
    k8s-app: traefik-ingress-lb
spec:
  selector:
    matchLabels:
      k8s-app: traefik-ingress-lb
      name: 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:v1.7
        name: traefik-ingress-lb
        volumeMounts:
        - mountPath: "/etc/kubernetes/cert"
          name: "ssl"
        - mountPath: "/config"
          name: "config"
        ports:
        - name: http
          containerPort: 80
          hostPort: 80
        - name: admin
          containerPort: 8080
          hostPort: 8080
        - name: https
          containerPort: 443
          hostPort: 443
        securityContext:
          capabilities:
            drop:
            - ALL
            add:
            - NET_BIND_SERVICE
        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
    - protocol: TCP
[root@k8s-node1 traefik]# kubectl apply -f traefik-ds.yaml 
serviceaccount/traefik-ingress-controller created
daemonset.apps/traefik-ingress-controller created
service/traefik-ingress-service created

4.测试

访问之前部署的svc,已经自动切换成https访问,见下

5.traefik转发访问方式简易说明

参考文档

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

很明显,测试用的是client --- (via https) ---> traefik ---- (via http) ----> services方式.

client --- (via https) ---> traefik ---- (via https) ---->模式分为两种情况,

第一种:
是ssl-termination的安全配置模型,即client与svc8的https通信分为“两段”,client与traefik建立https连接后,traefik将client提交的加密请求解密后,
再向svc发起https请求,并重新加密请求数据.这种client端ssl的过程在反向代理或负载均衡器终结的https通信方式被称为“ssl-termination”.

第二种:
ssl-passthrough的安全配置模型,即traefik不会对client的https request进行解密,而是直接转发给svc服务,client端的ssl过程不会终结于traefik,
而是在svc对应的pod中终结.这种https通信方式被称为”ssl-passthrough”.这种配置模型尤其适合service对client端进行client certificate验证的情况.

使用client --- (via https) ---> traefik ---- (via https) ----> services方式.需要在配置文件里traefik-conf加一个参数,见下

insecureSkipVerify = true  

这个参数意思是,禁止traefik对service后端证书检查.

重新创建configmap,更新traefik,见下:

[root@k8s-node1 cert]# kubectl delete configmap traefik-conf -n kube-system
configmap "traefik-conf" deleted
[root@k8s-node1 cert]# kubectl create configmap traefik-conf --from-file=traefik.toml -n kube-system
configmap/traefik-conf created
[root@k8s-node1 cert]# cat traefik.toml 
insecureSkipVerify = true
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"

重新部署traefik

[root@k8s-node1 traefik]# kubectl delete -f traefik-ds.yaml 
serviceaccount "traefik-ingress-controller" deleted
daemonset.apps "traefik-ingress-controller" deleted
service "traefik-ingress-service" deleted
[root@k8s-node1 traefik]# kubectl apply  -f traefik-ds.yaml 
serviceaccount/traefik-ingress-controller created
daemonset.apps/traefik-ingress-controller created
service/traefik-ingress-service created

到这里就可以正常访问后端https架构的web了.