k8s05- Ingress Controller 的安装部署


IngressController 的安装部署是分为两步
第一步:安装,在 K8S 集群里安装这个组件;
第二步:部署,如何把这个集群里的组件暴露到外部以供调用
经过第一步和第二步,就在 K8S 集群的内外交界处搭起了一座沟通的桥梁。


1、IngressController 的实现方案

IngressController 只是一个抽象的统称,其主要的方案有如下(还有其他的方案):

  • Ingress NGINX:Kubernetes 官方维护的方案,也是本次安装使用的 Controller。
  • F5 BIG-IP Controller:F5 所开发的 Controller,它能够管理员通过 CLI 或 API 让 Kubernetes 与 OpenShift 管理 F5 BIG-IP 设备。
  • Ingress Kong: 著名的开源 API Gateway 方案所维护的 Kubernetes IngressController。
  • Traefik: 是一套开源的 HTTP 反向代理与负载均衡器,而它也支援了 Ingress。
  • Voyager: 一套以 HAProxy 为底的 IngressController。

具体的 IngressController 类型可查看官方文档:https://kubernetes.io/zh-cn/docs/concepts/services-networking/ingress-controllers/


NOTE:Ingress NGINX 是本文中安装部署的对象,以下所有的IngressController均指Ingress NGINX方案


2、安装

IngressController 官方文档:https://kubernetes.github.io/ingress-nginx/deploy/

部署非常简单,一行命令即可

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

这里做了一些的修改

  • 集群内有2个worker所以这里增加副本数为2
    image

最好提前拉取镜像,如果网络不能直接访问镜像,建议修改到私有仓库


知识点:

默认的镜像拉取策略是 IfNotPresent:
在镜像已经存在的情况下, kubelet 将不再去拉取镜像。 如果希望强制总是拉取镜像,你可以执行以下操作之一:
设置容器的 imagePullPolicy 为 Always。
省略 imagePullPolicy,并使用 :latest 作为要使用的镜像的标签。
省略 imagePullPolicy 和要使用的镜像标签。
启用 AlwaysPullImages 准入控制器(Admission Controller)。
如果 imagePullPolicy 未被定义为特定的值,也会被设置为 Always


3、部署

部署 IngressController 有多种方式,以下举例了三种常见的方式:

Deployment+Service(NodePort)
DaemonSet+HostNetwork+nodeSelector
Deployment+Service(LoadBalancer)


3.1 Deployment+Service(NodePort)

nodePort 的部署思路:

  • 首先在所有的节点之上提供一个 nodePort Service,
  • 然后在每个节点上开辟 nodePort 的端口(该端口为宿主机的端口),
  • 通过 nodePort Service 将流量引入进来到任意一个节点上,如果该节点没有部署 IngressController 容器,那么就通过 ipvs 将流量转发到 IngressController 容器中(图中的 nginx 容器),
  • 而后由 Nginx 根据 Ingress 的规则进行判断,将其转发到对应的应用容器中。

需要注意的是 IngressController 容器可以部署在其中一个 Node 节点或者 Master 节点上(不建议),也可以部署到所有的 Node 节点和 Master 节点上。
后者的好处是,可以减少一次 NAT 的网络流量转发,提高效率;缺点也显而易见,在资源有限的情况下无法在每个节点都部署一个 IngressController 容器。

该部署方式会在所有 Node 节点上开一个 30080 端口作为 nodePort,暴露给集群外部。

外部访问方式: http://nodeport_ip:30080/url


3.2、DaemonSet+HostNetwork+nodeSelector

hostNetwork 的部署思路:

  • 在每个节点创建一个 IngressController 容器
  • 将这些容器的网络模式设为 hostNetwork(这会导致每个节点的80和443端口都会被 IngressController 容器占用)
  • 当外部流量通过节点的 80/443 端口进来后,都会进入到 IngressController 容器里,而后 Nginx 根据 Ingress 规则再将流量转发到对应的容器。
    相较与 nodePort 模式,hostNetwork 模式不需要创建一个 Service 来统一收口流量,而是让各个节点自行转发流量。

该方案部署,需要修改 yaml 文件:

  • 删除 kind.Deployment.spec.replicas: 1
  • 修改 kind.Deployment 为 kind.DeamonSet
  • 添加 kind.DeamonSet.spec.template.spec.hostNetwork: true

外部访问方式:http://nodeport_ip/url


知识点:什么是 DeamonSet 部署?

DaemonSet 确保全部(或者某些)节点上运行一个 Pod 的副本。 当有节点加入集群时, 也会为他们新增一个 Pod 。 当有节点从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。


知识点:为什么要用 DeamonSet 部署?

结合 DaemonSet 的定义和 hostNetwork 的部署思路,我们可以看到,利用 DaemonSet 可以很方便的实现:
在所有的节点上都部署一个 IngressController 容器的副本。


当然,也可以利用 K8S 的标签选择器,在指定的一个或多个节点上部署 IngressController 容器的副本。操作如下:

  • 首先给需要部署 IngressController 容器的节点,如 vm21 打上标签
    $ kubectl label node vm21 isIngressController="true"

  • 修改 yaml:
    旧: kind.DeamonSet.spec.template.spec.NodeSelector: kubernetes.io/os: linux
    新: kind.DeamonSet.spec.template.spec.NodeSelector: isIngressController="true"


3.3 Nodeport 和 HostNetwork 方案的比较

项目 优缺点
容器资源消耗 nodePort:需要部署的 IngressController 容器较少,一个集群可以部署几个就可以了。
hostNetwork:需要在每个节点部署一个 IngressController 容器,因此总消耗资源较多。
对宿主机端口的占用 nodePort:主要占用的是svc的nodePort端口。
hostNetwork: 需要占用物理机的80和443端口
网络流量的流转 hostNetwork 访问: 每个 Node 节点都部署了IngressController容器,因此不需要对进入的流量进行转发
SourceIP追踪 通过 nodePort 访问: Nginx 接收到的 HTTP 请求中的 SourceIP 将会被转换为接受该请求的 node 节点的 IP,而非真正的 Client 端 IP。
使用 hostNetwork 访问:IngressController 将会使用的是物理机的 DNS 域名解析(即物理机的 /etc/resolv.conf )。而无法使用内部的比如 CoreDNS 的域名解析。

参考

https://kubernetes.github.io/ingress-nginx/deploy/baremetal/
https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/daemonset/

posted @ 2023-02-03 18:02  unchch  阅读(1705)  评论(0编辑  收藏  举报