Traefik实现Kubernetes集群服务外部https访问

时间:2022-04-23 00:53:57

转载请注明出处:http://www.cnblogs.com/wayneiscoming/p/7707942.html

  traefik 是一个前端http反向代理服务器以及负载均衡器,支持多种微服务后端(Docker,Swarm,Kubernetes,Marathon,Consul,Etcd,Rancher,Amazon ECS等);同 nginx 等相比,traefik 能够自动感知后端服务新增删除升级等变化,并实现自动配置。

一、Kubernetes 服务暴露介绍

  本节内容节选自漠然博客Traefik-kubernetes初试

  从 kubernetes 1.2 版本开始,kubernetes提供了 Ingress 对象来实现对外暴露服务;到目前为止 kubernetes 总共有三种暴露服务的方式:

  • LoadBlancer Service
  • NodePort Service
  • Ingress

1.1、LoadBlancer Service

  LoadBlancer Service 是 kubernetes 深度结合云平台的一个组件;当使用 LoadBlancer Service 暴露服务时,实际上是通过向底层云平台申请创建一个负载均衡器来向外暴露服务;目前 LoadBlancer Service 支持的云平台已经相对完善,比如国外的 GCE、DigitalOcean,国内的 阿里云,私有云 Openstack 等等,由于 LoadBlancer Service 深度结合了云平台,所以只能在一些云平台上来使用。

1.2、NodePort Service

  NodePort Service 顾名思义,实质上就是通过在集群的每个 node 上暴露一个端口,然后将这个端口映射到某个具体的 service 来实现的,虽然每个 node 的端口有很多(0~65535),但是由于安全性和易用性(服务多了就乱了,还有端口冲突问题)实际使用可能并不多。

1.3、Ingress

  Ingress 这个东西是 1.2 后才出现的,通过 Ingress 用户可以实现使用 nginx 等开源的反向代理负载均衡器实现对外暴露服务,以下详细说一下 Ingress,毕竟 traefik 用的就是 Ingress。

使用 Ingress 时一般会有三个组件:

  • 反向代理负载均衡器
  • Ingress Controller
  • Ingress

1.3.1、反向代理负载均衡器

  反向代理负载均衡器很简单,说白了就是 nginx、apache 什么的;在集群中反向代理负载均衡器可以*部署,可以使用 Replication Controller、Deployment、DaemonSet 等等,不过个人喜欢以 DaemonSet 的方式部署,感觉比较方便。

1.3.2、Ingress Controller

  Ingress Controller 实质上可以理解为是个监视器,Ingress Controller 通过不断地跟 kubernetes API 打交道,实时的感知后端 service、pod 等变化,比如新增和减少 pod,service 增加与减少等;当得到这些变化信息后,Ingress Controller 再结合下文的 Ingress 生成配置,然后更新反向代理负载均衡器,并刷新其配置,达到服务发现的作用。

1.3.3、Ingress

  Ingress 简单理解就是个规则定义;比如说某个域名对应某个 service,即当某个域名的请求进来时转发给某个 service;这个规则将与 Ingress Controller 结合,然后 Ingress Controller 将其动态写入到负载均衡器配置中,从而实现整体的服务发现和负载均衡。

有点懵逼,那就看图

Traefik实现Kubernetes集群服务外部https访问

  从上图中可以很清晰的看到,实际上请求进来还是被负载均衡器拦截,比如 nginx,然后 Ingress Controller 通过跟 Ingress 交互得知某个域名对应哪个 service,再通过跟 kubernetes API 交互得知 service 地址等信息;综合以后生成配置文件实时写入负载均衡器,然 后负载均衡器 reload 该规则便可实现服务发现,即动态映射。

二、Traefik 简介及部署

  由于微服务架构以及 Docker 技术和 kubernetes 编排工具最近几年才开始逐渐流行,所以一开始的反向代理服务器比如 nginx、apache 并未提供其支持,毕竟他们也不是先知;所以才会出现 Ingress Controller 这种东西来做 kubernetes 和前端负载均衡器如 nginx 之间做衔接;即 Ingress Controller 的存在就是为了能跟 kubernetes 交互,又能写 nginx 配置,还能 reload 它,这是一种折中方案;而最近开始出现的 traefik 天生就是提供了对 kubernetes 的支持,也就是说 traefik 本身就能跟 kubernetes API 交互,感知后端变化,因此可以得知: 在使用 traefik 时,Ingress Controller 已经无卵用了,所以整体架构如下:

Traefik实现Kubernetes集群服务外部https访问

2.1、部署 Traefik

  由于我们需要将外部对于kubernetes的http请求全都转换成https,不想更改服务的配置以及代码,那我们可以选择在traefik上配置域名证书,这样通过域名对服务的访问将会自动转换成https请求。我的Kubernetes集群是在微软云上部署的,Node前端使用Azure负载均衡器来均衡请求,所以Traefik我将使用NodePort方式暴露服务。

2.1.1、创建ClusterRole以及ClusterRoleBinding(Kubernetes1.6+)

  如果你的集群配置了RBAC,则需要赋予Traefik调用Kubernetes API的权限:

# kubectl create -f ./ClusterRole_Binding.yaml
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: traefik-ingress-controller
rules:
- apiGroups:
- ""
resources:
- services
- endpoints
- secrets
verbs:
- get
- list
- watch
- apiGroups:
- extensions
resources:
- ingresses
verbs:
- get
- list
- watch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: traefik-ingress-controller
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: traefik-ingress-controller
subjects:
- kind: ServiceAccount
name: traefik-ingress-controller
namespace: kube-system

ClusterRole_Binding.yaml

2.1.2、创建secret保存HTTPS证书

  若没有证书请先生成证书,我本次使用的是现有的域名证书。

# openssl req -newkey rsa:2048 -nodes -keyout domain.com.key  -x509 -days 365 -out domain.com.crt
# kubectl create secret generic traefik-cert --from-file=domain.com.crt --from-file=domain.com.key --namespace=kube-system

2.1.3、创建configmap保存Traefik配置文件

  我们这里只做HTTP请求转至HTTPS配置,关于Traefik详细配置请参考官方文档 https://docs.traefik.io/configuration/commons/

# kubectl create configmap traefik-conf --from-file=traefik.toml --namespace=kube-system
# 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 = "/ssl/domain.com.crt"
KeyFile = "/ssl/domain.com.key"

2.1.4、通过Deployment部署Traefik

# kubectl create -f ./traefik-deployment.yaml
# 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: 1
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: "/ssl"
name: "ssl"
- mountPath: "/config"
name: "config"
ports:
- containerPort: 80
- containerPort: 443
args:
- --configfile=/config/traefik.toml
- --web
- --kubernetes
---
kind: Service
apiVersion: v1
metadata:
name: traefik
namespace: kube-system
spec:
type: NodePort
ports:
- protocol: TCP
port: 80
name: http
- protocol: TCP
port: 443
name: https
selector:
k8s-app: traefik-ingress-lb

traefik-deployment.yaml

2.1.5、部署traefik-ui服务以及traefik-ui ingress

# kubectl create -f ./traefik-ui.yaml
# cat traefik-ui.yaml

apiVersion: v1
kind: Service
metadata:
name: traefik-web-ui
namespace: kube-system
spec:
selector:
k8s-app: traefik-ingress-lb
ports:
- port: 80
targetPort: 8080
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: traefik-web-ui
namespace: kube-system
annotations:
kubernetes.io/ingress.class: traefik
spec:
tls:
- secretName: traefik-cert
rules:
- host: traefik-ui.domain.com
http:
paths:
- backend:
serviceName: traefik-web-ui
servicePort: 80

traefik-ui.yaml

2.1.6、创建负载均衡规则后端绑定traefik端口,以及traefik域名解析到负载均衡前端公共IP

  通过traefik-ui.domain.com访问到traefik-ui服务,可以发现网址自动跳转至https协议。

  Traefik实现Kubernetes集群服务外部https访问

  Traefik实现Kubernetes集群服务外部https访问

  

2.1.7、基于路径访问服务的ingress举例

  先创建3个后端服务:svc1、svc2、svc3,我们希望通过abcd.domain.com/s*的方式来访问服务,因为这样我们只需要添加一个abcd.domain.com域名解析,以下是配置示例:

# RC for svc1
kind: ReplicationController
apiVersion: v1
metadata:
name: svc1
spec:
replicas: 1
selector:
template:
metadata:
labels:
app: svc1
spec:
containers:
- name: svc1
image: docker.io/patrickeasters/example-web-service
env:
- name: APP_SVC
value: svc1
ports:
- containerPort: 8080
protocol: TCP
---
# RC for svc2
kind: ReplicationController
apiVersion: v1
metadata:
name: svc2
spec:
replicas: 1
selector:
template:
metadata:
labels:
app: svc2
spec:
containers:
- name: svc2
image: docker.io/patrickeasters/example-web-service
env:
- name: APP_SVC
value: svc2
ports:
- containerPort: 8080
protocol: TCP
---
# RC for svc3
kind: ReplicationController
apiVersion: v1
metadata:
name: svc3
spec:
replicas: 1
selector:
template:
metadata:
labels:
app: svc3
spec:
containers:
- name: svc3
image: docker.io/patrickeasters/example-web-service
env:
- name: APP_SVC
value: svc3
ports:
- containerPort: 8080
protocol: TCP
---
# Service for svc1
kind: Service
apiVersion: v1
metadata:
labels:
app: svc1
name: svc1
spec:
type: ClusterIP
ports:
- port: 8080
name: http
selector:
app: svc1
---
# Service for svc2
kind: Service
apiVersion: v1
metadata:
labels:
app: svc2
name: svc2
spec:
type: ClusterIP
ports:
- port: 8080
name: http
selector:
app: svc2
---
# Service for svc3
kind: Service
apiVersion: v1
metadata:
labels:
app: svc3
name: svc3
spec:
type: ClusterIP
ports:
- port: 8080
name: http
selector:
app: svc3

svc-rc

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: example-web-app
annotations:
kubernetes.io/ingress.class: "traefik"
spec:
tls:
- secretName: traefik-cert
rules:
- host: abcs.domain.com
http:
paths:
- path: /s1
backend:
serviceName: svc1
servicePort: 8080
- path: /s2
backend:
serviceName: svc2
servicePort: 8080
- path: /
backend:
serviceName: svc3
servicePort: 8080
$ curl -k https://abcd.domain.com/s1
Hi, I'm the svc1 service!
Hostname: svc1-sd123
$ curl -k https://abcd.domain.com/s2
Hi, I'm the svc2 service!
Hostname: svc2-isdf3
$ curl -k https://abcd.domain.com/
Hi, I'm the svc3 service!
Hostname: svc3-r23r
$ curl -k https://abcd.domain.com/xxxx
Hi, I'm the svc3 service!
Hostname: svc3-r23r

本文参考:

https://mritd.me/2016/12/06/try-traefik-on-kubernetes

https://medium.com/@patrickeasters/using-traefik-with-tls-on-kubernetes-cb67fb43a948

官方文档:https://docs.traefik.io/

Traefik实现Kubernetes集群服务外部https访问的更多相关文章

  1. kubernetes集群内通过endpoint访问外部服务

    kubernetes内的服务访问集群外独立的服务最好通过endpoint方式,例如MySQL 1.创建mysql-service.yaml apiVersion: v1 kind: Service m ...

  2. 干货 | 京东云Kubernetes集群+Traefik实战

    摘要 Traefik支持丰富的annotations配置,可配置众多出色的特性,例如:自动熔断.负载均衡策略.黑名单.白名单.所以Traefik对于微服务来说简直就是一神器. 利用Traefik,并结 ...

  3. Kubernetes 从懵圈到熟练:集群服务的三个要点和一种实现

    作者 | 声东 阿里云售后技术专家 文章来源:Docker,点击查看原文. 以我的经验来讲,理解 Kubernetes 集群服务的概念,是比较不容易的一件事情.尤其是当我们基于似是而非的理解,去排查服 ...

  4. 实现Kubernetes跨集群服务应用的高可用

    在Kubernetes 1.3版本,我们希望降低跨集群跨地区服务部署相关的管理和运营难度.本文介绍如何实现此目标. 注意:虽然本文示例使用谷歌容器引擎(GKE)来提供Kubernetes集群,您可以在 ...

  5. 高可用Kubernetes集群-1. 集群环境

    参考文档: 部署kubernetes集群1:https://github.com/opsnull/follow-me-install-kubernetes-cluster 部署kubernetes集群 ...

  6. 阿里云-容器服务之集群服务 k8s(Jenkins+gitlab+k8s的devops)- 01

    由于docker官方停止更新Swarm,另外swarm在使用期间出现了很多bug,所以阿里云也在2019年7月发布公告:于2019年12月31日起停止技术支持,请您尽快迁移至容器服务Kubernete ...

  7. k8s教程:Kubernetes集群使用网络存储NFS

    NFS存储 NFS即网络文件系统Network File System,它是一种分布式文件系统协议,最初是由Sun MicroSystems公司开发的类Unix操作系统之上的一款经典网络存储方案,其功 ...

  8. 初试 Kubernetes 集群中使用 Traefik 反向代理

    初试 Kubernetes 集群中使用 Traefik 反向代理 2017年11月17日 09:47:20 哎_小羊_168 阅读数:12308    版权声明:本文为博主原创文章,未经博主允许不得转 ...

  9. 在kubernetes 集群内访问k8s API服务

    所有的 kubernetes 集群中账户分为两类,Kubernetes 管理的 serviceaccount(服务账户) 和 useraccount(用户账户).基于角色的访问控制(“RBAC”)使用 ...

随机推荐

  1. Maven(二)使用eclipse创建maven多模块项目

    maven作为一种自动化构建工具,在现在的企业应用开发中运用非常普遍. 企业项目一般都比较大,多采用maven管理的多模块项目,下面直接上创建步骤 一.创建一个maven项目

  2. Cocoapods配置

    这真是蛋疼的东西,配置了几次,每次都不同,每次都折腾半天.这一段时间应该不会变了,记录下来. 一 换源 看了教程都说官方源https://rubygems.org/不能访问,我特意点了一下,发现能访问 ...

  3. 关于C++中的类型转换

    C++中定义了四种类型转换操作符:static_cast.const_cast.dynamic_cast和reinterpret_cast. static_cast的用法类似于C语言中的强制类型转换, ...

  4. 第一套增删改查(htm+ashx完成)

    1.展示人员列表htm文件: <a href="PersonEditAddNew.ashx?action=addnew">添加</a> </p> ...

  5. &lbrack;021&rsqb;转 C&plus;&plus; Pimpl机制

    出处:http://www.cnblogs.com/gnuhpc/ 1.简介 这个机制是Private Implementation的缩写,我们常常听到诸如“不要改动你的公有接口”这样的建议,所以我们 ...

  6. Linux设备文件自动生成

    第一种是使用mknod手工创建:# mknod <devfilename> <devtype> <major> <minor> 第二种是自动创建设备节点 ...

  7. 将域名转移到 Google Domains

    之前存放域名用过 Godaddy.Dynadot.Namesilo 也有阿里云(万网)和腾讯云(新网),这回就用 Google Domains 啦! 话说 Google Domains 早已是 201 ...

  8. Oracle存储过程和函数使用方法

    一.存储过程(PROCEDURE) 使用过程, 不仅可以简化客户端应用程序的开发和维护,而且可以提高应用程序的运行性能.  CREATE [OR REPLACE] PROCUDURE procedur ...

  9. &lbrack;android学习&rsqb;&lowbar;&lowbar;使用百度地图开放api编写地图定位app

    前言 在前面我已经记录关于如何使用百度地图api,以及如何配置相关的androidstudio配置了,接下来将记录如何使用百度地图api开发简单的地图定位apk,我将决定不定期持续更新本篇笔记,在每个 ...

  10. wingide 远程调试

    1.首先你应该在本地安装wingide 6.1版本 2.大多数电脑.py文件都不能以wingide的形式打开(异常苦逼),无论是从“属性”或者是“设置”里面都不可以,无奈之下只能通过修改注册表的方式进 ...