Contents

metallb

MetalLB

自建k8s的 loadbalancer

https://www.lixueduan.com/posts/cloudnative/01-metallb/

https://www.bboy.app/2021/01/11/metallb%E9%83%A8%E7%BD%B2%E4%BD%BF%E7%94%A8/

https://ieevee.com/tech/2019/06/30/metallb.html

https://cloud.tencent.com/developer/article/2146391#:~:text=%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85,Metallb%E6%94%AF%E6%8C%81%E9%80%9A%E8%BF%87Kuberntes%E6%B8%85%E5%8D%95%E3%80%81Helm%E5%92%8CKustomize%E6%96%B9%E5%BC%8F%E8%BF%9B%E8%A1%8C%E9%83%A8%E7%BD%B2%EF%BC%8C%E6%9C%AC%E6%96%87%E6%88%91%E4%BB%AC%E5%B0%86%E4%BB%A5Kuberntes%E6%B8%85%E5%8D%95%E4%B8%BA%E4%BE%8B%E4%BB%8B%E7%BB%8D%E4%BA%A7%E5%93%81%E7%9A%84%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85%EF%BC%8C%E9%83%A8%E7%BD%B2%E7%9A%84%E7%89%88%E6%9C%AC%E4%B8%BA%E6%9C%80%E6%96%B0%E7%9A%84v0.13.4%E3%80%82

简介

在Kubernetes部署完成服务后,我们经常需要将服务开放给到外部用户访问 。如果是使用云平台(阿里云、腾讯云、AWS等)的话,这个需求处理起来非常简单,可以通过云平台的LoadBalancer来实现。

但如果是自建的kubernetes裸机集群,那则要麻烦得多。祼机集群默认不支持负载均衡的方式,可用的方案不外乎Ingress、NodePort、ExternalIPs等方式来实现外部访问。可惜这些方案本身并不完美,他们或多或少都存在着一些缺点,这使得裸金属集群成为Kubernetes生态系统中的二等公民。

而MetalLB 旨在通过提供与标准网络设备集成的LoadBalancer来解决这个痛点,从而使裸机群集上的外部服务也尽可能“正常运行”,减少运维上的管理成本。

metallb支持两种工作模式,一种是layer 2 mode,也就是工作在2层来负责相应arp请求,对于局域网中的人来说仿佛就是给服务分配了一个ip,但是2层模式不是真正的负载均衡,因为所有的流量会经过集群中的一个节点,当这个节点挂了的话,metallb会迁移ip到另外一个节点上,另外一种是bgp模式,在bgp模式下,集群中每一个节点都会和路由器建立bgp会话,所以bgp模式是高可用的,但是需要你的路由器支持bgp。这边我的路由器是不支持bgp的,所以就采用二层模式

Layer 2 模式

Layer 2模式下,每个service会有集群中的一个node来负责。当服务客户端发起ARP解析的时候,对应的node会响应该ARP请求,之后,该service的流量都会指向该node(看上去该node上有多个地址)。

Layer 2模式并不是真正的负载均衡,因为流量都会先经过1个node后,再通过kube-proxy转给多个end points。如果该node故障,MetalLB会迁移 IP到另一个node,并重新发送免费ARP告知客户端迁移。现代操作系统基本都能正确处理免费ARP,因此failover不会产生太大问题。

Layer 2模式更为通用,不需要用户有额外的设备;但由于Layer 2模式使用ARP/ND,地址池分配需要跟客户端在同一子网,地址分配略为繁琐。

BGP模式

BGP模式下,集群中所有node都会跟上联路由器建立BGP连接,并且会告知路由器应该如何转发service的流量。

BGP模式是真正的LoadBalancer。

部署要求

MetalLB部署需要以下环境才能运行:

  • 运行Kubernetes 1.13.0或更高版本的群集,尚不具有网络负载平衡功能;
  • 一些用于MetalLB分配的IPv4地址;
  • 如果使用BGP模式,需要准备一台或多台支持BGP的路由器;
  • 如果使用layer 2模式时,集群节点间必须允许7946端口的访问 ,用户代理之间的通信;
  • 集群的网络类型需要支持MetalLB,详见下图
网络类型 兼容性
Antrea Yes
Calico Mostly
Canal Yes
Cilium Yes
Flannel Yes
Kube-ovn Yes
Kube-router Mostly
Weave Net Mostly

工作原理:

Metallb包含两个组件,Controller和Speaker,Controller为Deployment部署方式,而Speaker则采用Daemonset方式部署到集群内部各个Node节点。

具体的工作原理如下图所示,Controller负责监听Service变化,当Service配置为LoadBalancer模式时,从IP池分配给到相应的IP地址并对该IP的生命周期进行管理。Speaker则会依据选择的协议进行相应的广播或应答,实现IP地址的通信响应。当业务流量通过TCP/UDP协议到达指定的Node时,由Node上面运行的Kube-Proxy组件对流量进行处理,并分发到对应服务的Pod上面。

MetalLB支持两种模式,一种是Layer2模式,一种是BGP模式。

Layer2模式

在2层模式下,Metallb会在Node节点中选出一台作为Leader,与服务IP相关的所有流量都会流向该节点。在该节点上, kube-proxy将接收到的流量传播到对应服务的Pod。当leader节点出现故障时,会由另一个节点接管。从这个角度来看,2层模式更像是高可用,而不是负载均衡,因为同时只能在一个节点负责接收数据。

在二层模式中会存在以下两种局限性:单节点瓶颈和故障转移慢的情况。

由于Layer 2 模式会使用单个选举出来的Leader来接收服务IP的所有流量,这就意味着服务的入口带宽被限制为单个节点的带宽,单节点的流量处理能力将成为整个集群的接收外部流量的瓶颈。

在故障转移方面,目前的机制是MetalLB通过发送2层数据包来通知各个节点,并重新选举Leader,这通常能在几秒内完成。但如果是计划外的事故导致的,此时在有故障的客户端刷新其缓存条目之前,将无法访问服务IP。

BGP模式

BGP模式是真正的负载均衡,该模式需要路由器支持BGP协议 ,群集中的每个节点会与网络路由器建议基于BGP的对等会话,并使用该会话来通告负载均衡的IP。MetalLB发布的路由彼此等效,这意味着路由器将使用所有的目标节点,并在它们之间进行负载平衡。数据包到达节点后,kube-proxy负责流量路由的最后一跳,将数据包发送到对应服务的Pod。

负载平衡的方式取决于您特定的路由器型号和配置,常见的有基于数据包哈希对每个连接进行均衡,这意味着单个TCP或UDP会话的所有数据包都将定向到群集中的单个计算机。

BGP模式也存在着自身的局限性,该模式通过对数据包头中的某些字段进行哈希处理,并将该哈希值用作后端数组的索引,将给定的数据包分配给特定的下一跳。但路由器中使用的哈希通常不稳定,因此只要后端节点数量发生变化时,现有连接就会被随机地重新哈希,这意味着大多数现有连接将被转发到另一后端,而该后端并不清楚原有的连接状态。为了减少这种麻烦,建议使用更加稳定的BGP算法,如:ECMP散列算法。

安装使用

Metallb支持通过Kuberntes清单、Helm和Kustomize方式进行部署,本文我们将以Kuberntes清单为例介绍产品的部署安装,部署的版本为最新的v0.13.7。

注:由于Metallb从v0.13.0版本开始不再使用configmap而改用自定义资源方式配置,因此本示例与旧版本的配置方式会有所不同

1)确定ipvs集群开启strictARP

kubectl edit configmap -n kube-system kube-proxy
#设置strictARP值为true
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs"
ipvs:
  strictARP: true

2)安装metallb

wget https://raw.githubusercontent.com/metallb/metallb/v0.13.4/config/manifests/metallb-native.yaml

kubectl apply -f metallb-native.yaml


# helm
helm repo add metallb https://metallb.github.io/metallb
helm fetch metallb/metallb --version=0.13.7
helm install metallb metallb/metallb --version=0.13.7

3)配置模式

Layer2 模式

创建IPAddressPool,并指定用于分配的IP池。

[root@sugar metallb]# cat <<EOF > IPAdressPool.yaml 
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: ip-pool
  namespace: metallb-system
spec:
  addresses:
  - 192.168.214.50-192.168.214.80   #分配给LB的IP池,注意这里的addresses需要和k8s的节点处于同一个网段
EOF

创建广播声明,此处未指定IP池,则默认会使用所有IP池地址。

cat <<EOF > L2Advertisement.yaml
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: l2adver
  namespace: metallb-system
EOF  
  
  
# 也可以指定ip地址池
cat <<EOF > L2Advertisement.yaml
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: example
  namespace: metallb-system
spec:
  ipAddressPools:
  - ip-pool #上一步创建的 ip 地址池,通过名字进行关联
EOF

BGP模式配置

对于具有一个BGP路由器和一个IP地址范围的基本配置,您需要4条信息:

  • MetalLB应该连接的路由器IP地址,
  • 路由器的AS号,
  • MetalLB应该使用的AS号,
  • 以CIDR前缀表示的IP地址范围。(分配的LB ip)

示例:现在分配给MetalLB的AS编号为64500和192.168.10.0/24的IP地址池,并将其连接到AS编号为64501的地址为10.0.0.1的路由器,则配置如下所示:

创建BGPPeer

apiVersion: metallb.io/v1beta2
kind: BGPPeer
metadata:
  name: sample
  namespace: metallb-system
spec:
  myASN: 64500
  peerASN: 64501
  peerAddress: 10.0.0.1

配置IP地址池

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: first-pool
  namespace: metallb-system
spec:
  addresses:
  - 192.168.10.0/24
  - 172.16.78.141/32
  #   - 192.168.214.50-192.168.214.80

创建广播声明

apiVersion: metallb.io/v1beta1
kind: BGPAdvertisement
metadata:
  name: bgpadver
  namespace: metallb-system

测试

简单测试:

1)创建示例yaml文件并执行,包括svc与deployment。

apiVersion: v1
kind: Service
metadata:
  name: myapp
spec:
  selector:
    app: myapp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: LoadBalancer    #类型选择LoadBalancer
 
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
  labels:
    app: myapp
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80

2)查看创建的SVC状态,已获取到IP

[root@master-01 metalLB]# kubectl get svc
NAME         TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)        AGE
kubernetes   ClusterIP      10.96.0.1       <none>          443/TCP        3h47m
myapp-svc    LoadBalancer   10.99.108.212   172.16.78.141   80:31542/TCP   17m

3)访问测试

helm 测试:

https://artifacthub.io/packages/helm/bitnami/nginx

$ helm repo add bitnami https://charts.bitnami.com/bitnami
$ helm install my-release bitnami/nginx
[root@sugar metallb]# kubectl get svc 
NAME               TYPE           CLUSTER-IP       EXTERNAL-IP    PORT(S)        AGE
kubernetes         ClusterIP      10.96.0.1        <none>         443/TCP        36m
my-release-nginx   LoadBalancer   10.110.219.132   172.16.5.48   80:32026/TCP   27m
mysql              ClusterIP      10.109.126.5     <none>         3306/TCP       14m
mysql-headless     ClusterIP      None             <none>         3306/TCP       14m
nginx-svc          LoadBalancer   10.103.199.38    172.16.5.47   80:32559/TCP   31m
[root@ftp ~]# curl 172.16.5.48
<!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>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

工作流程

MetalLB 做的工作可以分为两个部分:

  • 1)地址分配:当创建 LoadBalancer Service 时,MetalLB 会为其分配 IP 地址。这个 IP 地址是从预先配置的 IP 地址库获取的。同样,当 Service 删除后,已分配的 IP 地址会重新回到地址库。
  • 2)对外广播:分配了 IP 地址之后,需要让集群外的网络知道这个地址的存在。MetalLB 使用了标准路由协议实现:ARP、NDP 或者 BGP。
    • 在 Layer 2 模式,使用 ARP(ipv4)/NDP(ipv6) 协议;
    • 在 BPG 模式,自然是使用 BGP 协议。

ARP(Address Resolution Protocol):是根据IP地址获取物理地址的一个TCP/IP协议。

NDP(neighbor Discovery protocol):是ICMPv6的子协议是IPV6协议体系中一个重要的基础协议,邻居发现协议替代了IPV4的ARP,ICMP路由器发现。它定义了使用ICMPv6报文实现地址解析,跟踪邻居状态,重复地址检测,路由器发现,以及重定向等功能。

同时 MetalLB 分别使用两个组件来实现了上述两个功能:

  • Controller:实现地址分配,以 Deployment 方式运行,用于监听 Service 的变更,分配/回收 IP 地址。
  • Speaker:实现地址对外广播,以 DaemonSet 方式运行,对外广播 Service 的 IP 地址。

具体的工作流如下:

  • Controller 负责监听 Service 变化并分配或回收 IP

    ,当 Service 配置为 LoadBalancer 模式时,从 IP 池分配给到相应的 IP 地址并对该 IP 的生命周期进行管理。

    • 创建 Service 时(或者从非 LoadBalancer 类型修改为 LoadBalancer 类型)时从 IP 池选择一个 IP 并分配,
    • 删除 Service (或者从 LoadBalancer 类型修改为非 LoadBalancer 类型)时回收该 IP 到 IP 池
  • Speaker 则会依据选择的协议进行相应的广播或应答,实现 IP 地址的通信响应

    。当业务流量通过 TCP/UDP 协议到达指定的 Node 时,由 Node 上面运行的 Kube-Proxy 组件对流量进行处理,并分发到对应服务的 Pod 上面。

    • 如果是 Layer2 模式 Speaker 就会响应 ARP(ipv4)/NDP(ipv6)请求
    • 如果是 BGP 模式 Speaker 则发送 BGP 广播,将路由规则同步给 peer。

Layer2 模式工作原理

METALLB IN LAYER 2 MODE

大致原理

Layer 2 中的 Speaker 工作负载是 DeamonSet 类型,在每个节点上都调度一个 Pod,首先,几个 Pod 会先进行选举,选举出 Leader。

由 Leader Pod 获取所有 LoadBalancer 类型的 Service,并将已分配的 IP 地址绑定到当前主机到网卡上。同时该 Leader 会响应对 ExternalIP 的 ARP(ipv4)/NDP(ipv6) 请求,因此从局域网层面来看,speaker 所在的机器是有多个 IP 地址的,当前其中也包含 ExternalIP。

从网络的角度来看,计算机的网络接口分配了多个IP地址,因为对不同 ip 地址的 arp 请求返回的都是这个节点的 mac 地址。

因此与 ExternalIP 相关的所有流量都会流向该节点。在该节点上, kube-proxy 将接收到的流量传播到对应 Service 的后端 Pod。

也就是说,所有 LoadBalancer 类型的 Service 的 IP 同一时间都是绑定在同一台节点的网卡上。

局限性

在 Layer2 模式中会存在以下两种局限性:单节点瓶颈故障转移慢

单节点瓶颈

由于 Layer 2 模式会使用单个选举出来的 Leader 来接收 ExternalIP 的所有流量,这就意味着服务的入口带宽被限制为单个节点的带宽,单节点的流量处理能力将成为整个集群的接收外部流量的瓶颈。

从这个角度来看,Layer2 模式更像是实现了故障转移,而不是负载均衡,因为同时只能在一个节点负责接收数据。

故障转移慢

在故障转移方面,MetalLB 也实现了自动故障转移。目前的机制是通过 memberlist 这个基于 gossip 协议的成员和故障检测的库,其他节点检测到 Leader 故障后自动重新选举出新 Leader,新的 Leader 自动接管所有 ExternalIP 并发送大量 二层数据包来通知客户端(也就是区域网中的其他节点) ExternalIP 的 MAC 地址变化。

大部分操作系统都能处理这部分 二层数据包并更新 neighbor caches,但是也有极少部分系统不能正确处理这个数据包,从而无法及时更新缓存,还会继续请求旧的 Leader 节点,这种情况下可以让旧 Leader 多存活几分钟,用于处理这部分客户端的请求。

根据官网文档描述故障转移正常情况下会在几秒内完成,一般不会超过 10 秒。但是在更新完成前 ExternalIP 会无法访问。

即:会出现几秒钟的服务中断

这个 10s 只是官方说的,可能经常测试或者是一个大概值,和这段 代码#announcer.go#L51 里的10s 的循环不是一回事

BGP 模式工作原理

METALLB IN BGP MODE

大致原理

在 BGP 模式下每个节点( 上的 Speaker Pod)都会和路由器建立一个 BGP peer session,并且通过这些 peer session 来告知外部网络 ExternalIPs 的存在。

BGP模式是以集群中的主机与对等体进行共享路由信息,从而实现集群外部的服务能够访问到集群内部的服务。

和 Layer2 模式不同,BGP模式真正的实现了负载均衡,不过具体的负载均衡行为和路由器以及配置有关系。一般默认的行为是根据数据包中的某些关键字段进行 hash,并更新 hash 值分配给其中某一个连接。

原文:but the common behavior is to balance per-connection, based on a packet hash.

关键字段常见选择为 三元组(协议、源IP、目的IP) 或者五元组(协议、源IP、目的IP、源端口、目的端口)

也就是说默认情况下一个连接里的所有数据包都会发送到固定的节点,这样能拥有更好的性能。

局限性

BGP 模式最大的弊端就是不能优雅的处理节点下线。当集群中某个节点下线时,所有客户端对这个节点的连接都会被主动断开。

客户端一般会出现一个 Connection reset by peer 错误

同时由于是对每个数据包基于 hash 值进行负载均衡,因此对后端节点数是非常敏感的,这也是 BGP 的一个优点,故障转移非常快。

正因为 BGP 故障转移很快,反而引发了一个 BGP 模式的最大缺点:由于 BGP 会对每个数据包做负载均衡,在主机发生故障时会快速切换到新的主机上,从而引发节点变动时同一连接的不同数据包可能会发送到不同主机上导致网络导致的网络重排问题

比如第一个包转发到节点 A,然后处理第二个包时添加或故障了一个节点,按照新的节点数进行负载均衡计算,可能第二个数据包就被分到节点 B 了,节点 B 很明显是不能正确处理这个数据包的。

对客户端来说就是这次请求直接失败了。

解决该弊端的方法没有太理想的解决办法,只能尽量采取一些优化手段:

  • 1)路由器配置更加稳定的 hash 算法,比如 “resilient ECMP” 或者 “resilient LAG”。使用这样的算法极大地减少了 后端节点更改时受影响的连接。
  • 2)尽量少的增删节点
  • 3)在流量少时变更节点,以降低影响
  • 4)使用 ingress 来对外暴露服务等等

二者实现原理

MetalLB 包括 Layer2 模式和 BGP 模式,主要区别在于 IP 通告部分的实现不一样:

  • Layer2 模式通过响应对 ExternalIP 的 ARP(ipv4)/NDP(ipv6) 请求来告知其他节点某个 IP 在这台机器上
    • arp 请求是在 二层的,这可能就是该模式为什么叫做 Layer2
  • BGP 模式则通过于路由器建立 BGP peer session,从而进行数据同步,让路由器知道某个 IP 在这台机器上

二者优缺点

Layer2 模式

  • 优点:通用性好,适用于任何网络环境,不需要特殊的硬件,甚至不需要花哨的路由器。
  • 缺点:单节点瓶颈和故障转移慢

Layer2 模式是一种基础、通用的实现,能用,而且易于使用,没有任何限制,但是局限性比较大。

BGP 模式:

  • 优点:使用 BGP 可以在多节点间负载均衡,没有单节点瓶颈,同时故障转移很快。
  • 缺点: 需要支持 BGP 路由协议的软路由或者硬件路由器设备。
    • 其实不能算缺点了,想要功能总得付出代价。

使用建议

BGP 模式则是比较理想的实现,除了依赖支持 BGP 的路由之外,其他方面则没有任何限制,并且没有可用性的问题

一句话总结:如果说 Layer2 模式为基础实现,那么 BGP 模式则是 LoadBalance 的终极实现,能用 BGP 模式就尽量用 BGP 模式,否则的话就只能用 Layer2 模式了,如果不知道用什么模式的话直接用 Layer2 模式即可。

Istio + MetalLB

基于helm

参考链接:https://www.jianshu.com/p/fe6e0911b71c

一、MetaLB

Kubernetes 不为裸机集群提供网络负载均衡器的实现(LoadBalancer 类型的服务)。 Kubernetes 附带的 Network LB 的实现都是调用各种 IaaS 平台(GCP,AWS,Azure 等)的粘合代码。 如果你未在受支持的 IaaS 平台(GCP,AWS,Azure 等)上运行,则 LoadBalancers 在创建后将无限期保持 “pending” 状态。

MetalLB 可以解决 istio ingress gateway EXTERNAL-IP “pending” 的问题.

安装:

1)确定ipvs集群开启strictARP

kubectl edit configmap -n kube-system kube-proxy
#设置strictARP值为true
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs"
ipvs:
  strictARP: true

2)安装metallb

[root@master-01 ~]# kubectl create ns metallb-system
[root@master-01 ~]# helm repo add metallb https://metallb.github.io/metallb
# 有需要可以下载chart
[root@master-01 ~]# helm fetch metallb/metallb --version=0.13.7
[root@master-01 ~]# helm install metallb metallb/metallb --version=0.13.7 -n metallb-system

3)配置模式

Layer2 模式

创建IPAddressPool,并指定用于分配的IP池。

[root@master-01 ~]# cat ip-pool.yaml 
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: ip-pool
  namespace: metallb-system
spec:
  addresses:
  - 192.168.214.50-192.168.214.80   #分配给LB的IP池,注意这里的addresses需要和k8s的节点处于同一个网段
  autoAssign: false # 不自动分配ip,默认为ture,若部署服务的LoadBalancer要指定ip的话需要设置为false

创建广播声明,此处未指定IP池,则默认会使用所有IP池地址。

apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: l2adver
  namespace: metallb-system

使用helm配置layer2

helm repo add serialt https://serialt.github.io/helm-charts
helm install metallb-config serialt/metallb-config --set "ipPoolRange=172.16.1.40-172.16.1.49" -n metallb-system  --version 0.0.1

BGP模式配置

对于具有一个BGP路由器和一个IP地址范围的基本配置,您需要4条信息:

  • MetalLB应该连接的路由器IP地址,
  • 路由器的AS号,
  • MetalLB应该使用的AS号,
  • 以CIDR前缀表示的IP地址范围。(分配的LB ip)

示例:现在分配给MetalLB的AS编号为64500和192.168.10.0/24的IP地址池,并将其连接到AS编号为64501的地址为10.0.0.1的路由器,则配置如下所示:

创建BGPPeer

apiVersion: metallb.io/v1beta2
kind: BGPPeer
metadata:
  name: sample
  namespace: metallb-system
spec:
  myASN: 64500
  peerASN: 64501
  peerAddress: 10.0.0.1

配置IP地址池

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: first-pool
  namespace: metallb-system
spec:
  addresses:
  - 192.168.10.0/24
  - 172.16.78.141/32
  #   - 192.168.214.50-192.168.214.80

创建广播声明

apiVersion: metallb.io/v1beta1
kind: BGPAdvertisement
metadata:
  name: bgpadver
  namespace: metallb-system

一、Istio

1)增加helm repo

[root@master-01 ~]# helm repo add istio https://istio-release.storage.googleapis.com/charts

# 有需求可以下载chart
[root@master-01 ~]# helm fetch istio/base --version 1.13.6
[root@master-01 ~]# helm fetch istio/istiod --version 1.13.6
[root@master-01 ~]# helm fetch istio/gateway --version 1.13.6

2)部署istio组件

[root@master-01 ~]# kubectl create namespace istio-system
[root@master-01 ~]# helm install istio-base istio/base -n istio-system --version 1.13.6
[root@master-01 ~]# helm install istiod istio/istiod -n istio-system --wait --version 1.13.6

若关闭了自动分配ip,这需要配置一下 gateway 的 annotations

参考链接:

annotations里指定IP

# istio-values.yaml
service:
  annotations:
    metallb.universe.tf/loadBalancerIPs: 172.16.78.143
autoscaling:
  enabled: true
  minReplicas: 3
[root@master-01 ~]# helm install istio-ingressgateway istio/gateway  -n istio-system  --version 1.13.6  --set replicaCount=3  --set autoscaling.enabled=false 

使用以下命令确认所有 Pod 都在运行。

$ kubectl get pod -n istio-system -w
NAME                                    READY   STATUS    RESTARTS   AGE
istio-ingressgateway-7cc49dcd99-c4mtf   1/1     Running   0          94s
istiod-687f965684-n8rkv                 1/1     Running   0          3m26s

3)安装多个istio gateway

[root@master-01 ~]# helm install istio-ingressgateway-mgt istio/gateway  -n istio-system  --version 1.13.6  --set replicaCount=3   --set autoscaling.enabled=false 
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: local-gateway-mgt
spec:
  selector:
    istio: ingressgateway-mgt # use istio ingressgateway-mgt
  servers:
    - port:
        number: 80
        name: http
        protocol: HTTP
      hosts:
        - "*.local.local.com"
    - hosts:
        - '*.local.imau.cc'
      port:
        name: https
        number: 443
        protocol: HTTPS
      tls:
        mode: PASSTHROUGH  

测试

apiVersion: v1
kind: Service
metadata:
  name: myapp-svc
spec:
  type: ClusterIP
  selector:
    app: myapp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
  labels:
    app: myapp
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: nginx
        image: nginx 
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
          limits:
            cpu: 100m
            memory: 100Mi    

---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: myapp-vs
spec:
  gateways:
  - local-gateway
  hosts:
  - myapp.local.com
  http:
  - route:
    - destination:
        host: myapp-svc
        port:
          number: 80
          
---
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: local-gateway
spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*.local.com"
    # tls:
    #   httpsRedirect: true # sends 301 redirect for http requests

  - port:
      number: 443
      name: https
      protocol: HTTPS
    tls:
      mode: SIMPLE
      credentialName: local-credential # must be the same as secret
    hosts:
    - "*.local.com"