k8s loadbalancer与ingress实践
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/speaker
daemonset。集群中每个节点启动一个协议服务守护进程。
接着添加一个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,再把域名解析指向该地址,就实现了集群服务的对外暴露。当然你也可以使用NodePort
、Hostnetwork
的方式,感兴趣的小伙伴可以进行测试。
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实践的更多相关文章
- [转帖]在 k8s 中通过 Ingress 配置域名访问
在 k8s 中通过 Ingress 配置域名访问 https://juejin.im/post/5db8da4b6fb9a0204520b310 在上篇文章中我们已经使用 k8s 部署了第一个应用,此 ...
- k8s 中的 ingress 使用细节
k8s中的ingress 什么是ingress Ingress 如何使用 ingress 使用细节 参考 k8s中的ingress 什么是ingress k8s 中使用 Service 为相同业务的 ...
- Kubernetes的三种外部访问方式:NodePort、LoadBalancer和Ingress(转发)
原文 http://cloud.51cto.com/art/201804/570386.htm Kubernetes的三种外部访问方式:NodePort.LoadBalancer和Ingress 最近 ...
- Kubernetes的三种外部访问方式:NodePort、LoadBalancer和Ingress
NodePort,LoadBalancer和Ingress之间的区别.它们都是将集群外部流量导入到集群内的方式,只是实现方式不同. ClusterIP ClusterIP服务是Kubernetes的默 ...
- 转载NodePort,LoadBalancer还是Ingress?我该如何选择 - kubernetes
原文:http://mp.weixin.qq.com/s/dHaiX3H421jBhnzgCCsktg ClusterIP ClusterIP服务是Kuberntets的默认服务.它在集群内部生成一个 ...
- NodePort,LoadBalancer还是Ingress?我该如何选择 - kubernetes
原文:http://mp.weixin.qq.com/s/dHaiX3H421jBhnzgCCsktg 当我们使用k8s集群部署好应用的Service时,默认的Service类型是ClusterIP, ...
- K8S生产环境中实践高可靠的配置和技巧都有哪些?
K8S环境中实践高可靠的配置和技巧都有哪些? 磁盘类型及大小 磁盘类型: 推荐使用ssd 磁盘 对于worker节点,创建集群时推荐使用挂载数据盘.这个盘是专门给/var/lib/docker 存放本 ...
- Kubernetes笔记(三):Gitlab+Jenkins Pipeline+Docker+k8s+Helm自动化部署实践(干货分享!)
通过前面两篇文章,我们已经有了一个"嗷嗷待哺"的K8s集群环境,也对相关的概念与组件有了一个基本了解(前期对概念有个印象即可,因为只有实践了才能对其有深入理解,所谓"纸上 ...
- 一文看懂 K8s 日志系统设计和实践
上一篇中我们介绍了为什么需要一个日志系统.为什么云原生下的日志系统如此重要以及云原生下日志系统的建设难点,相信DevOps.SRE.运维等同学看了是深有体会的.本篇文章单刀直入,会直接跟大家分享一下如 ...
随机推荐
- Function overloading and const keyword
Predict the output of following C++ program. 1 #include<iostream> 2 using namespace std; 3 4 c ...
- spring下春注解的声明式事务控制
package com.hope.test;import com.hope.domain.Account;import com.hope.service.IAccountService;import ...
- java通过JDBC访问数据库(最基本的查询)
一.步骤介绍 1.通过Class.forName()加载驱动: 2.通过DriverManager.getConnection()获取Conncetion连接对象: 3.创建Statement对象传递 ...
- minkube在deban10上的安装步骤
环境准备: 所用机器为4c 16g i3 4170 1t机械硬盘 系统 debian 10 安装docker 如果已经安装并配置好可直接跳过 安装ssl sudo apt-get install ...
- Redis哨兵日常维护
目录 一.日常操作 指定一个从做新主 添加一个从节点 添加一个Setinel节点 一.日常操作 指定一个从做新主 有时候需要将当前主节点机器下线,并指定一个高一些性能的从节点接替 将其它从节点的sla ...
- Gitlab-CICD实践篇
一.背景 随着公司项目使用gitlab越来越多,业务发布的次数越来越频繁,对于发布效率提出了更高的要求.从2012开始,Gitlab官方开始集成了Continuous Integration (CI) ...
- 转:Android preference首选项框架
详解Android首选项框架ListPreference 探索首选项框架 在 深入探讨Android的首选项框架之前,首先构想一个需要使用首选项的场景,然后分析如何实现这一场景.假设你正在编写一个应用 ...
- [Java Web 王者归来]读书笔记3
第四章 JSP JSP基本语法 1 JSP中嵌入Java 代码 <% Java code %> 2 JSP中输出 <%= num %> 3 JSP 中的注释 <%-- - ...
- mysql的MVCC多版本并发控制机制
MVCC多版本并发控制机制 全英文名:Multi-Version Concurrency Control MVCC不会通过加锁互斥来保证隔离性,避免频繁的加锁互斥. 而在串行化隔离级别为了保证较高的隔 ...
- 日历共享(Project)
<Project2016 企业项目管理实践>张会斌 董方好 编著 为了某一个项目,我们建好了一整套的日历,除了标准日历里加上了所有的假期以外,其他来自火星的水星的金星的土星的木星的BT的不 ...