ingress在物理机上的nodePort和hostNetwork两种部署方式解析及比较

标签: kubernetes | 发表时间:2019-06-11 16:00 | 作者:
出处:https://xuxinkun.github.io/

ingress controller在物理机上的两种部署方式

ingress controller(ingress-nginx)负责k8s中的7层负载均衡。其在物理机中有多种部署方式。本文中主要选择了nodePort和hostNetwork两种部署方式进行介绍。主要原因是这两种部署方式不需要借助于其他组件,直接使用的是k8s的基础组件和使用方式,较为容易理解和排障。

注:本文中的kube-proxy使用的是iptables

本文使用的ingress-nginx的commit版本是51ad0bc54b1475384b67bee9e8a8e41e26b18bc4。该版本的部署方式是在NGINX: 0.24.1版本后重构了deploy文件夹中的ingress-nginx的部署相关文件。采用了kustomize进行部署配置。因此推荐使用kubectl 1.14以上的版本。且特别注意,下面的命令都是使用了 kubectl apply -k的方式运行,而不是 -f参数。

deploy各个文件夹走读

ingress-nginx项目deploy文件夹下有多个文件夹,为不同的环境提供支持。这里我们主要介绍的是与在物理机部署相关的几个文件夹。

cluster-wide
    ├── cluster-wide
│   ├── cluster-role-binding.yaml
│   ├── cluster-role.yaml
│   └── kustomization.yaml

cluster-wide文件夹主要用于创建cluster-role和cluster-role-binding,为ingress-controller提供apiserver的cluster访问权限。这里cluster-role-binding.yaml要作一下修改,指定 namespace: ingress-nginx。因为在后面创建的ServiceAccount等其他资源都是默认在该namespace下。

    [root@local cluster-wide]# cat cluster-role-binding.yaml
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: nginx-ingress-clusterrole-nisa-binding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: nginx-ingress-clusterrole
subjects:
  - kind: ServiceAccount
    name: nginx-ingress-serviceaccount
    namespace: ingress-nginx
cloud-generic
    ├── cloud-generic
│   ├── deployment.yaml
│   ├── kustomization.yaml
│   ├── role-binding.yaml
│   ├── role.yaml
│   ├── service-account.yaml
│   └── service.yaml

cloud-generic文件夹提供了通用的一些部署文件。其中deployment.yaml是负责创建ingress-controller的deployment,默认副本数为1,可以进行调节。service.yaml是为ingress-controller创建的service。其他的主要是与账户相关的内容。

baremetal
    ├── baremetal
│   ├── kustomization.yaml
│   └── service-nodeport.yaml

baremetal文件夹主要是创建了一个NodePort类型的svc,然后向ingress-controller的容器进行导流的。因为该部署方式需要依赖cloud-generic里的资源,因此在kustomization.yaml中描述了对cloud-generic的依赖。可以参看kustomization.yaml中的bases。

    [root@local baremetal]# cat deploy/baremetal/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
bases:
- ../cloud-generic
patchesStrategicMerge:
- service-nodeport.yaml

大致了解了相关部署文件的功能,那么结合具体的两种部署图(部署图来自官网),来进行一下具体介绍。

nodePort部署

nodePort

nodePort的部署思路就是通过在每个节点上开辟nodePort的端口,将流量引入进来,而后通过iptables首先转发到ingress-controller容器中(图中的nginx容器),而后由nginx根据ingress的规则进行判断,将其转发到对应的应用web容器中。因此采用nodePort部署较为简单,直接使用以下命令即可。

    kubectl apply -k deploy/baremetal/
kubectl apply -k deploy/cluster-wide/

hostNetwork部署

hostNetwork

相比较起来,hostNetwork模式不再需要创建一个nodePort的svc,而是直接在每个节点都创建一个ingress-controller的容器,而且将该容器的网络模式设为hostNetwork。也就是说每个节点物理机的80和443端口将会被ingress-controller中的nginx容器占用。当流量通过80/443端口进入时,将直接进入到nginx中。而后nginx根据ingress规则再将流量转发到对应的web应用容器中。

这里需要对cloud-generic/deployment.yaml进行一下改动,将其资源类型从deployment改为daemonset,并且在spec中添加 hostNetwork: true,从而使其可以使用物理机网络。

    [root@local deploy]# cat cloud-generic/deployment.yaml 
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  name: nginx-ingress-controller
spec:
  template:
    metadata:
      annotations:
        prometheus.io/port: "10254"
        prometheus.io/scrape: "true"
      labels:
        nginx-ingress-controller: 0.24.1
    spec:
      serviceAccountName: nginx-ingress-serviceaccount
      hostNetwork: true
      ...

修改完成后,使用以下命令即可完成hostNetwork模式的部署。

    kubectl apply -k deploy/cloud-generic/
kubectl apply -k deploy/cluster-wide/

两种部署方式的比较

相比较起来,nodePort部署模式中需要部署的ingress-controller容器较少。一个集群可以部署几个就可以了。而hostNetwork模式需要在每个节点部署一个ingress-controller容器,因此总起来消耗资源较多。另外一个比较直观的区别,nodePort模式主要占用的是svc的nodePort端口。而hostNetwork则需要占用物理机的80和443端口。

从网络流转来说,通过nodePort访问时,该node节点不一定部署了ingress-controller容器。因此还需要iptables将其转发到部署有ingress-controller的节点上去,多了一层流转。

另外,通过nodePort访问时,nginx接收到的http请求中的source ip将会被转换为接受该请求的node节点的ip,而非真正的client端ip。

而使用hostNetwork的方式,ingress-controller将会使用的是物理机的DNS域名解析(即物理机的/etc/resolv.conf)。而无法使用内部的比如coredns的域名解析。

因此具体使用哪种部署方式,需要根据实际情况和需求进行选择。

ingress controller试用

在部署好ingress controller后,可以通过一个样例进行测试使用。首选创建一个应用容器和以及一个对应的svc。

    kubectl run web --image=gcr.azk8s.cn/google-samples/hello-app:1.0 --port=8080
kubectl expose deployment web --target-port=8080

然后创建ingress,将通过hello-world.info域名访问ingress的请求转发到该容器中去。

    apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
 rules:
 - host: hello-world.info
   http:
     paths:
     - path: /*
       backend:
         serviceName: web
         servicePort: 8080

这一切完成后,在/etc/hosts里绑定域名, 127.0.0.1 hello-world.info

    sed -i '$a 127.0.0.1 hello-world.info' /etc/hosts

然后通过curl命令进行测试。

    root@i-5i2mhmaus9v67pz19zmahp07u:~# curl 127.0.0.1
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.15.10</center>
</body>
</html>

root@i-5i2mhmaus9v67pz19zmahp07u:~# curl hello-world.info 
Hello, world!
Version: 1.0.0
Hostname: web-77f97c6cc7-g7qft

这里可以看到,我们访问本地127.0.0.1的时候,会返回404错误。而访问绑定的域名,就可以正确导流了,返回正确结果。

参考资料

相关 [ingress 物理 nodeport] 推荐:

ingress在物理机上的nodePort和hostNetwork两种部署方式解析及比较

- - Xinkun Blog
ingress controller在物理机上的两种部署方式. ingress controller(ingress-nginx)负责k8s中的7层负载均衡. 本文中主要选择了nodePort和hostNetwork两种部署方式进行介绍. 主要原因是这两种部署方式不需要借助于其他组件,直接使用的是k8s的基础组件和使用方式,较为容易理解和排障.

kubernetes NodePort网络踩坑 - 三木燕 - 博客园

- -
系统:centos7.6     . IP地址:192.168.1.1. 因为需要跑一个nginx的应用叫做http-proxy做流量转发,公网入口是阿里云的SLB然转发到http-proxy的NodePor 端口上,也就是192.168.1.1:30285. 刚配好一切正常,过了几分钟SLB开始报健康检查错误,手动检查了一下发现3、4请求之后必然会有一次timeout.

使用 Kubernetes Ingress 对外暴露服务

- - DockOne.io
本文主要介绍如何通过 Kubernetes Ingress 资源对象实现从外部对 Kubernetes 集群中服务的访问,介绍了 Kubernetes 对外暴露服务的多种方法、Ingress 及 Ingress Controller 的概念. Kubernetes 对外暴露服务的方法. 向 Kubernetes 集群外部暴露服务的方式有三种: nodePort,LoadBalancer 和本文要介绍的 Ingress.

浅谈 k8s ingress controller 选型 - 知乎

- -
大家好,先简单自我介绍下,我叫厉辉,来自腾讯云. 业余时间比较喜欢开源,现在是Apache APISIX PPMC. 今天我来简单给大家介绍下 K8S Ingress 控制器的选型经验,今天我讲的这些内容需要大家对 K8S 有一定的了解,下面是我的分享. 阅读本文需要熟悉以下基本概念:. 集群:是指容器运行所需云资源的集合,包含了若干台云服务器、负载均衡器等云资源.

现实中的虚拟战场——Ingress 初体验

- - 极客公园-GeekPark
对Android Design了解深入, 热爱Metro UI, 曾在美亚柏科实习, 现在在美国读大学. [核心提示]Ingress 是 Google 出品的增强现实多人 RPG 游戏. 我们的观察家 NovaDNG 对这款游戏进行了初步体验. “你身边的世界,并不只是你看到的那个样子. Ingress 是 Google 旗下的 NianticLabs 的作品.

Kubernetes的负载均衡问题(Nginx Ingress) - ericnie - 博客园

- -
Kubernetes关于服务的暴露主要是通过NodePort方式,通过绑定minion主机的某个端口,然后进行pod的请求转发和负载均衡,但这种方式下缺陷是. Service可能有很多个,如果每个都绑定一个node主机端口的话,主机需要开放外围一堆的端口进行服务调用,管理混乱. 无法应用很多公司要求的防火墙规则.

Kubernetes Nginx Ingress 教程 - 漠然的博客 | mritd Blog

- -
一、Ingress 介绍. Kubernetes 暴露服务的方式目前只有三种:LoadBlancer Service、NodePort Service、Ingress;前两种估计都应该很熟悉,具体的可以参考下  这篇文章;下面详细的唠一下这个 Ingress. 1.1、Ingress 是个什么玩意.

以图形化的方式简单介绍Kubernetes Ingress

- - DockOne.io
【编者的话】原文地址: here. 本文主要介绍了 Kubernetes Ingress 的内部原理,以及一些 Ingress 的用法示例. 第一部分: 以图形化的方式简单介绍Kubernetes Service. 第二部分:以图形化的方式简单介绍Kubernetes Ingress,即这篇文章.

浅谈Kubernetes Ingress控制器的技术选型

- - DockOne.io
【编者的话】在Kubernetes的实践、部署中,为了解决 Pod 迁移、Node Pod 端口、域名动态分配等问题,需要开发人员选择合适的 Ingress 解决方案. 面对市场上众多Ingress产品,开发者该如何分辨它们的优缺点. 又该如何结合自身的技术栈选择合适的技术方案呢. 在本文中,腾讯云中间件核心研发工程师厉辉将为你介绍如何进行Kubernates Ingress 控制器的技术选型.

如何理解 Istio Ingress, 它与 API Gateway 有什么区别?

- - Jimmy Song - 云原生|开源|社区 – 博客
API 网关作为客户端访问后端的入口,已经存在很长时间了,它主要是用来管理”南北向“的流量;近几年服务网格开始流行,它主要是管理系统内部,即“东西向”流量,而像 Istio 这样的服务网格还内置了网关,从而将系统内外部的流量纳入了统一管控. 这经常给初次接触 Istio 的人带来困惑——服务网格与 API 网关之间是什么关系.