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,且访问成功

k8s实践13:traefik配置https访问_第1张图片