k8s可以通过三种方式将集群内服务暴露到外网,分别是NodePort、LoadBalancer、Ingress,其中NodePort作为基础通信形式我们在《k8s网络模型与集群通信》中进行了介绍,这里我们主要关注LoadBalancer和Ingress

LoadBalancer


loadbalancer是服务暴露到因特网的标准形式,和nodeport一样我们只需在创建service是指定type为loadbalancer即可,接着Service 的通过status.loadBalancer字段将需要创建的负载均衡器信息发布供负载均衡服务创建。不过loadbalancer是云服务商”专属“,像腾讯云CLB、阿里云SLB,这样在创建service时会自动帮我们创建一个负载均衡器。

大多数云上负载均衡也是基于nodeport,他们的结构如下:

如果要在本地创建一个负载均衡器如何实现呢?

MetalLB,一个CNCF沙箱项目,使用标准路由协议(ARP/BGP),实现裸机K8s集群的负载均衡器。

安装方式可参考官方文档:installation

L2(子网)模式的结构,图源

安装后我们获得如下两个组件:

  • metallb-system/controller deployment。用于处理IP分配的控制器。
  • metallb-system/speakerdaemonset。集群中每个节点启动一个协议服务守护进程。

接着添加一个configmap配置metallb IP池。

apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: default
protocol: layer2
addresses:
- 192.168.1.240-192.168.1.250

这样当我们创建一个loadbalancer类型的service时,EXTERNAL-IP将会从地址池中获取一个用于外部访问的IP 192.168.1.243 当外部流量进入时,ARP将我们的请求地址广播获取所属的service,接着k8s内部 通过iptables 规则和 kube-proxy,将流量从服务端点引导到后端。

#nginx_deployment_service.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: metallb-system
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- name: http
containerPort: 80 ---
apiVersion: v1
kind: Service
metadata:
namespace: metallb-system
name: nginx
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
type: LoadBalancer

查看service kubectl get svc

NAME     TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)        AGE
nginx LoadBalancer 10.96.243.159 192.168.1.243 80:31052/TCP 40h

测试访问:curl 192.168.1.243

# curl 192.168.1.243
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>

负载均衡可以建立在 OSI 网络模型的不同级别上,主要是在 L4(传输层,例如 TCP/UDP)和 L7(应用层,例如 HTTP)上。在 Kubernetes 中,Services是 L4 的抽象,LoadBalancer类型负载均衡依然有局限性,同时我们看到每创建一个service对应的负载均衡器都会消耗一个静态IP,这并不合理。当然k8s中的另一种资源对象ingress可工作在 L7 层实现应用程序协议(HTTP/HTTPS)的负载均衡。

Ingress


Ingress 公开了从集群外部到集群内服务的 HTTP 和 HTTPS 路由。 流量路由由 Ingress 资源上定义的规则控制。我们可以将 Ingress 配置为服务提供外部可访问的 URL、负载均衡流量、终止 SSL/TLS,以及提供基于名称的虚拟主机等能力。

我们所说的Ingress包含两个部分:

  • ingress k8s资源对象:流量路由规则的控制
  • ingress-controller控制器:控制器的实现有非常多,可参考官方文档中列表Ingress 控制器,这里我们使用k8s官方维护的控制器NGINX Ingress Controller

外部流量进入集群时先经过ingress-controller,然后根据ingress配置的路由规则将请求转发到后端service。

ingress-controller

ingress-controller其实就是守护进程加一个反向代理的应用,守护进程不断监听集群中资源的变化,将ingress中的配置信息生成反向代理配置。在nginx-ingress controller中即生成nginx.conf的配置文件。

在本文中因为我们上面已经配置好了loadbalancer的服务,这样我们创建一个type为LoadBalancer的service关联这组pod,再把域名解析指向该地址,就实现了集群服务的对外暴露。当然你也可以使用NodePortHostnetwork的方式,感兴趣的小伙伴可以进行测试。

ingress-controller不是k8s内部组件,可以通过helm或资源清单方式安装,可查看ingress-nginx deploy

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.0/deploy/static/provider/cloud/deploy.yaml

然后我们编辑service

kubectl edit service/ingress-nginx-controller -n ingress-nginx

修改spec.type为LoadBalancer即可。

这样我们创建好了nginx-ingress controller,下一步就要配置ingress路由规则。

ingress规则

host:k8s.com

基于url的路由:

  • /api/v1
  • /api/v2

这两个url分别路由到不同的service中

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test
namespace: training
annotations:
ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: k8s.com
http:
paths:
- path: /api/v1
backend:
serviceName: service-apiv1
servicePort: 80
- path: /api/v2
backend:
serviceName: service-apiv2
servicePort: 80

ingress.kubernetes.io/rewrite-target是nginx-ingress controller的一个注解,当后端服务中暴露的 URL 与 Ingress 规则中指定的路径不同时可以通过此重定向。

查看svc可以看到此时控制器已经获得了一个EXTERNAL-IP

#kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller LoadBalancer 10.96.87.23 192.168.1.245 80:32603/TCP,443:31906/TCP 621d
ingress-nginx-controller-admission ClusterIP 10.96.109.70 <none> 443/TCP 621d

现在nginx-ingress controller和ingress路由规则都有了。

我们可以进入到nginx-ingress controller pod中查看nginx.conf可以看到此时我们的ingress配置已经被生成为路由规则。

接下来就是指定我们的backend,即上面的server-apiv1/2

我们添加两个用于暴露的service和deployment,和loadbalancer中测试清单一样,我们稍稍修改一下名称即可。

apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-apiv1
namespace: training
spec:
selector:
matchLabels:
app: nginx-apiv1
template:
metadata:
labels:
app: nginx-apiv1
spec:
containers:
- name: nginx-apiv1
image: nginx:latest
ports:
- name: http
containerPort: 80 ---
apiVersion: v1
kind: Service
metadata:
namespace: training
name: service-apiv1
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx-apiv1
type: NodePort

将nginx-apiv1换成nginx-apiv2创建出另一个service和deployment。

最后修改hosts解析k8s.com

192.168.1.245 k8s.com

使用curl命令测试url路由(记得在pod中添加测试文件,否则虽然url进行了路由但会出现404)。

# curl k8s.com/api/v1/index.html
api v1
# curl k8s.com/api/v2/index.html
api v2

这样我们对ingress有了初步了解,ingress的路由规则可自定项较多也比较繁杂,可通过官方文档进一步学习。


希望小作文对你有些许帮助,如果内容有误请指正。

您可以随意转载、修改、发布本文,无需经过本人同意。

k8s loadbalancer与ingress实践的更多相关文章

  1. [转帖]在 k8s 中通过 Ingress 配置域名访问

    在 k8s 中通过 Ingress 配置域名访问 https://juejin.im/post/5db8da4b6fb9a0204520b310 在上篇文章中我们已经使用 k8s 部署了第一个应用,此 ...

  2. k8s 中的 ingress 使用细节

    k8s中的ingress 什么是ingress Ingress 如何使用 ingress 使用细节 参考 k8s中的ingress 什么是ingress k8s 中使用 Service 为相同业务的 ...

  3. Kubernetes的三种外部访问方式:NodePort、LoadBalancer和Ingress(转发)

    原文 http://cloud.51cto.com/art/201804/570386.htm Kubernetes的三种外部访问方式:NodePort.LoadBalancer和Ingress 最近 ...

  4. Kubernetes的三种外部访问方式:NodePort、LoadBalancer和Ingress

    NodePort,LoadBalancer和Ingress之间的区别.它们都是将集群外部流量导入到集群内的方式,只是实现方式不同. ClusterIP ClusterIP服务是Kubernetes的默 ...

  5. 转载NodePort,LoadBalancer还是Ingress?我该如何选择 - kubernetes

    原文:http://mp.weixin.qq.com/s/dHaiX3H421jBhnzgCCsktg ClusterIP ClusterIP服务是Kuberntets的默认服务.它在集群内部生成一个 ...

  6. NodePort,LoadBalancer还是Ingress?我该如何选择 - kubernetes

    原文:http://mp.weixin.qq.com/s/dHaiX3H421jBhnzgCCsktg 当我们使用k8s集群部署好应用的Service时,默认的Service类型是ClusterIP, ...

  7. K8S生产环境中实践高可靠的配置和技巧都有哪些?

    K8S环境中实践高可靠的配置和技巧都有哪些? 磁盘类型及大小 磁盘类型: 推荐使用ssd 磁盘 对于worker节点,创建集群时推荐使用挂载数据盘.这个盘是专门给/var/lib/docker 存放本 ...

  8. Kubernetes笔记(三):Gitlab+Jenkins Pipeline+Docker+k8s+Helm自动化部署实践(干货分享!)

    通过前面两篇文章,我们已经有了一个"嗷嗷待哺"的K8s集群环境,也对相关的概念与组件有了一个基本了解(前期对概念有个印象即可,因为只有实践了才能对其有深入理解,所谓"纸上 ...

  9. 一文看懂 K8s 日志系统设计和实践

    上一篇中我们介绍了为什么需要一个日志系统.为什么云原生下的日志系统如此重要以及云原生下日志系统的建设难点,相信DevOps.SRE.运维等同学看了是深有体会的.本篇文章单刀直入,会直接跟大家分享一下如 ...

随机推荐

  1. mybatis-扩展

    分页插件 使用pageHelper参考官方https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse. ...

  2. Spring Cloud中,如何解决Feign整合Hystrix第一次请求失败的问题

    Spring Cloud中,Feign和Ribbon在整合了Hystrix后,可能会出现首次调用失败的问题,要如何解决该问题呢? 造成该问题的原因 Hystrix默认的超时时间是1秒,如果超过这个时间 ...

  3. CSS font-size: 0去除内联元素空白间隙

    我们在编写HTML标签的时候,通常会使用换行,缩进来保证代码的可读性.同时,在编写CSS样式的时候,也会需要把一些元素设置为inline或inline-block.这样一来,有时在页面中会出现意外的空 ...

  4. Python模块和函数

    目录 一.基础 二.特殊函数 一.基础 #导入模块 import xxx #调用 xxx.dd() from xxx import xx  as dd #导入某个函数,as给函数加别名,调用xx() ...

  5. CentOS7学习笔记(四) 常用命令记录

    查看命令的帮助信息 man 命令查看帮助信息 在想要获取帮助信息的命令前面加上man即可,例如查看ls命令的帮助信息 [root@localhost ~]# man ls help 命令查看帮助信息 ...

  6. .net 程序通过 crontab 无法启动,手动执行脚本可以启动

    一.问题描述 .net 网关程序需要设置定时重启,按照日常操作先把正在运行的 PID kill 掉后,再执行启动服务. 把脚本放到 crontab 计划任务上,可以把服务 PID kill 掉,但无法 ...

  7. Centos7使用Docker启动elasticsearch服务秒退

    首先查看docker启动日志 docker logs -f 容器id 查看报错信息 OpenJDK 64-Bit Server VM warning: Option UseConcMarkSweepG ...

  8. 如何下载哔哩哔哩、爱奇艺、腾讯视频、优酷、斗鱼、TED、YouTube网页视频

    这里使用you-get工具进行下载 github地址:https://github.com/soimort/you-get/ github项目文档:https://github.com/soimort ...

  9. vue中的数据代理原理

    const vm = new Vue({ data:{ name:'boos' } }) // 注意 :使用构造函数构建vue实例时,传入的是一个option对象,它包含了data,computed等 ...

  10. Simple16 字符压缩

    #define S16_NUMSIZE 16 #define S16_BITSSIZE 28 #define Simple16_Mask 0x7FFFFFFF extern int S16_NUM[] ...