kubernetes ingress 在物理机上的nodePort和hostNetwork两种部署方式解析及比较
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的端口,将流量引入进来,而后通过iptables首先转发到ingress-controller容器中(图中的nginx容器),而后由nginx根据ingress的规则进行判断,将其转发到对应的应用web容器中。因此采用nodePort部署较为简单,直接使用以下命令即可。
kubectl apply -k deploy/baremetal/
kubectl apply -k deploy/cluster-wide/
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-nginx https://github.com/kubernetes/ingress-nginx
- Bare-metal considerations https://github.com/kubernetes/ingress-nginx/blob/master/docs/deploy/baremetal.md
- https://github.com/kubernetes/ingress-nginx/blob/51ad0bc54b1475384b67bee9e8a8e41e26b18bc4/deploy
kubernetes ingress 在物理机上的nodePort和hostNetwork两种部署方式解析及比较的更多相关文章
- [转帖]kubernetes ingress 在物理机上的nodePort和hostNetwork两种部署方式解析及比较
kubernetes ingress 在物理机上的nodePort和hostNetwork两种部署方式解析及比较 https://www.cnblogs.com/xuxinkun/p/11052646 ...
- aliyun添加数据盘后的物理分区和lvm逻辑卷两种挂载方式
一.普通磁盘分区管理方式 1.对磁盘进行分区 列出磁盘 # fdisk -l # fdisk /dev/vdb Welcome to fdisk (util-linux 2.23.2). Change ...
- 在 Kubernetes Ingress 中支持 Websocket/Socket 服务
Kubernetes Ingress 可将集群内部的 Service 通过 HTTP/HTTPS 的方式暴露供外部访问,并通过路径匹配规则定义服务的路由.但是 Ingress 对 TCP/UDP 的服 ...
- Kubernetes 深入学习(一) —— 入门和集群安装部署
一.简介 1.Kubernetes 是什么 Kubernetes 是一个全新的基于容器技术的分布式架构解决方案,是 Google 开源的一个容器集群管理系统,Kubernetes 简称 K8S. Ku ...
- Kubernetes集群的部署方式及详细步骤
一.部署环境架构以及方式 第一种部署方式 1.针对于master节点 将API Server.etcd.controller-manager.scheduler各组件进行yum install.编译安 ...
- Kubernetes Ingress Controller的使用及高可用落地
Kubernetes Ingress Controller的使用及高可用落地 看懂本文要具备一下知识点: Service实现原理和会应用 知道反向代理原理,了解nginx和apache的vhost概念 ...
- Kubernetes Ingress实战
本节内容: 服务发现与负载均衡 Ingress实战 一.服务发现与负载均衡 在前面的安装部署kubernetes集群中已经简单用示例来演示了Pod和Service,Kubernetes通过Servic ...
- Kubernetes 学习11 kubernetes ingress及ingress controller
一.上集回顾 1.Service 3种模型:userspace,iptables,ipvs 2.Service类型 ClusterIP,NodePort NodePort:client -> N ...
- Kubernetes Ingress 学习
Kubernetes 中暴露服务的方式有三种 Loadbalancer 这种方式往往需要云供应商支持,或者本地F5等设备支持 NodePort 这种方式调用方通过NodeIP:NodePort 的方式 ...
随机推荐
- yii2.0 模块的使用
以高级模板为例 1.复制目录 frontend或backend 为一个新目录pro修改advanced\common\config\bootstrap.php 添加一行,加载刚才的路劲Yii::set ...
- 设计一个树型目录结构的文件系统,其根目录为 root,各分支可以是目录,也可以是文件,最后的叶子都是文件。
设计一个树型目录结构的文件系统,其根目录为 root,各分支可以是目录,也可以是文件,最后的叶子都是文件. 我实现的功能是提供父目录(兄弟目录),输入文件名,创建树型目录结构,文本文件不可以再有子目录 ...
- 在SpringMVC中操作Session、Request、Response对象
示例 @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper user ...
- C++标准库分析总结(五)——<Deque、Queue、Stack设计原则>
本节主要总结标准库Deque的设计方法和特性以及相关迭代器内部特征 1.Deque基本结构 Deque(双向队列)也号称连续空间(其实是给使用者一个善意的谎言,只是为了好用),其实它使用分段拼接起来的 ...
- 分布式的一致性(分布式事物)-------2PC详述
英文名:Two Phase Commit(2PC) 算法目的:实现分布式事物 算法概述: 有两类节点: -----协调者 -----事务参与者 流程阶段: -----请求阶段 -----提交阶段 算法 ...
- 手动制作BIOS和EFI多启动U盘
原文链接:https://www.lainme.com/doku.php/blog/2017/07/%E5%88%B6%E4%BD%9Cbios%E5%92%8Cefi%E5%A4%9A%E5%90% ...
- [APIO2018]铁人两项——圆方树+树形DP
题目链接: [APIO2018]铁人两项 对于点双连通分量有一个性质:在同一个点双里的三个点$a,b,c$,一定存在一条从$a$到$c$的路径经过$b$且经过的点只被经过一次. 那么我们建出原图的圆方 ...
- CSS绘制三角形—border法
1. 实现一个简单的三角形 使用CSS盒模型中的border(边框)即可实现如下所示的三角形: CSS实现简单三角形 实现原理: 首先来看在为元素添加border时,border的样子:假设有如下 ...
- 深入理解JVM虚拟机1:JVM内存的结构与永久代的消失
所有的Java开发人员可能会遇到这样的困惑?我该为堆内存设置多大空间呢?OutOfMemoryError的异常到底涉及到运行时数据的哪块区域?该怎么解决呢?其实如果你经常解决服务器性能问题,那么这些问 ...
- Spring家族主流成员介绍
摘 要:Spring 就像一个大家族,有众多衍生产品例如 Boot,Security,JPA等等.但他们的基础都是Spring 的 IOC 和 AOP,IOC提供了依赖注入的容器,而AOP解决了面向切 ...