Kubernetes的网络结构

K8s的网络相对比较复杂, 包含了如下几类IP地址:

Host Network

运行K8s集群的宿主服务器的内网IP, 其网段在配置宿主机时设置. 这些服务器可能是物理机, 也可能是ESXi或KVM虚机. 可以根据这个IP在K8s初始化时设置--apiserver-advertise-address, 配置外网访问时, 前端的负载均衡要通过这些IP访问服务.

Docker Bridge Network

运行Docker服务时启动的虚拟网卡docker0的IP, 通常为 172.17.0.1/16, 对应docker内部默认的bridge网段. 这个网络在K8s中不会用到.

Pod Network

K8s中Pod单元的IP, 其网段在K8s初始化时使用--pod-network-cidr设置, 此处使用172.16.0.0/16, 在每个宿主(node节点)上, 都会有一个对应的二级网段, 例如 172.16.1.0/24, 如果使用的是flannel, 那么在宿主机上会对应成对出现的两个虚拟网卡 cni0 和 flannel.1 (如果宿主机上还没部署pod, cni0可能不会出现)

Pod网络在集群内可以跨节点相互ping通, 在master和node主机上也可以直接访问Pod的IP

Service Network

K8s中Service单元的IP, 其网段在K8s初始化时使用--service-cidr设置, 在master和node主机上不能直接访问. 这里使用10.1.0.0/16.

Ingress的机制

要解决的问题

因为K8s中Pod是易变的, Pod IP在更新中会自动修改, 使用Service能使访问入口相对固定, 但是Service IP在集群外不能访问, 要对外提供访问, 只能把Service以NodePort, LoadBalancer这些方式Expose出去, 但是NodePort会与每一个Node主机绑定, 而LoadBalancer需要云服务商提供相应的服务(或自己安装).

原理

Ingress 启动一个独立的Pod来运行七层代理, 可以是 Nginx, Traefik 或者是 Envoy. Ingress Pod会直接代理后端提供服务的Pod, 为了能监听后端Pod的变化, 需要一个 Headless Service 通过Selector选择指定的Pod, 并收集到Pod对应的IP. 一旦后端Pod产生变化, Headless Service 会自动根据变化更改配置文件并重载.

如果使用的是 Nginx 类型的 Ingress Pod, 则每次变化后通过reload修改过的配置文件实现规则更新.

Ingress Controller

在kubernetes集群内节点上运行web七层代理所对应的Pod, 由此Pod代理集群内部的Service, Service再把流量转发给集群内部对应的Pod, 这就叫做 Ingress Controller, Ingress Controller 基于 DaemonSet 控制器实现, DaemonSet用于保证集群内部每个节点上都运行一个指定的Pod.

部署Ingress Nginx

软件版本

这里使用的环境是 K8s 1.17, Docker 18.06.3, Ingress Nginx 0.26.2

Ingress Nginx项目地址: https://github.com/kubernetes/ingress-nginx/

Ingress Nginx的安装文档: https://kubernetes.github.io/ingress-nginx/deploy/ 使用 https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/

安装前提

已经配置好K8s集群

部署公共部分

现在最新的标签是0.26.2, 使用部署模板

https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.26.2/deploy/static/mandatory.yaml

下载后在master主机上执行

kubectl apply -f mandatory.yaml

可以使用下面的命令查看部署的结果

kubectl get pods --all-namespaces -l app.kubernetes.io/name=ingress-nginx --watch
kubectl get services

部署Nodeport部分

因为不使用云服务商的服务, 所以要使用Nodeport的方式, 对应的部署模板在

https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.26.2/deploy/static/provider/baremetal/service-nodeport.yaml

这一步实际上是创建一个Nodeport将ingress-nginx服务发布到Node节点的Host Network上, 原模板中未指定端口, 创建后会随机设置端口, 可以修改一下, 只能使用端口范围 3000 ~ 32767. 修改后的service-nodeport.yaml, 将80端口映射到了30080, 443映射到了30443

apiVersion: v1
kind: Service
metadata:
name: ingress-nginx
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
type: NodePort
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP
nodePort: 30080
- name: https
port: 443
targetPort: 443
protocol: TCP
nodePort: 30443
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx

可以使用下面的命令查看发布的结果, 以及映射出去的实际端口

kubectl get services -n ingress-nginx

创建服务并测试

以下都是使用defalut的namespace. 都使用kubectl apply -f 模板名 命令进行发布

Deployment, 创建两个nginx的pod

# nginx-deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2 # tells deployment to run 2 pods matching the template
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: registry.cn-shanghai.aliyuncs.com/jovi/nginx:alpine
ports:
- containerPort: 80

Service, 将上面创建的两个Pod发布为Servce, 将Pod的80端口映射到Service的8080端口

# nginx-service.yml
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 8080
targetPort: 80

查看service详情

$ kubectl describe service my-service
Name: my-service
Namespace: default
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"my-service","namespace":"default"},"spec":{"ports":[{"port":8080,...
Selector: app=nginx
Type: ClusterIP
IP: 10.1.116.99
Port: <unset> 8080/TCP
TargetPort: 80/TCP
Endpoints: 172.16.1.6:80,172.16.1.7:80
Session Affinity: None
Events: <none>

  

Ingress, 将上面的Service的8080端口映射到Ingress的http

# ingress-test.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: test-ingress
annotations:
# use the shared ingress-nginx
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- http:
paths:
- backend:
serviceName: my-service
servicePort: 8080

查看Ingress详情

$ kubectl get services -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx NodePort 10.1.60.152 <none> 80:30080/TCP,443:30443/TCP 69m
milton@k8s00:~/backup$ kubectl describe ingress test-ingress
Name: test-ingress
Namespace: default
Address: 10.1.60.152
Default backend: default-http-backend:80 (<none>)
Rules:
Host Path Backends
---- ---- --------
*
my-service:8080 (172.16.1.6:80,172.16.1.7:80)
Annotations:
kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"networking.k8s.io/v1beta1","kind":"Ingress","metadata":{"annotations":{"kubernetes.io/ingress.class":"nginx"},"name":"test-ingress","namespace":"default"},"spec":{"rules":[{"http":{"paths":[{"backend":{"serviceName":"my-service","servicePort":8080}}]}}]}} kubernetes.io/ingress.class: nginx
Events: <none>

这时候, 就可以通过 http://宿主机IP:30080 访问到这两个Pod的Nginx默认页.

Kubernetes上使用Ingress Nginx将服务发布到外部IP的更多相关文章

  1. 为苹果ATS和微信小程序搭建 Nginx + HTTPS 服务

    昨天测试开发微信小程序,才发现微信也要求用HTTPS加密数据,想来是由于之前苹果的ATS审核政策的缘故吧,微信想在苹果上开放小程序必然也只能要求开发者必须使用HTTPS了,于是在服务器上测试安装Ngi ...

  2. 微服务开发有道之把项目迁移到Kubernetes上的5个小技巧

    我们将在本文中提供5个诀窍帮你将项目迁移到Kubernetes上,这些诀窍来源于过去12个月中OpenFaas社区的经验.下文的内容与Kubernetes 1.8兼容,并且已经应用于OpenFaaS ...

  3. Kubernetes 系列(三):Kubernetes使用Traefik Ingress暴露服务

    一.Kubernetes 服务暴露介绍 从 kubernetes 1.2 版本开始,kubernetes提供了 Ingress 对象来实现对外暴露服务:到目前为止 kubernetes 总共有三种暴露 ...

  4. 在k8s(kubernetes)上安装 ingress V1.1.3

    介绍 Ingress 公开了从集群外部到集群内服务的 HTTP 和 HTTPS 路由.流量路由由 Ingress 资源上定义的规则控制. 下面是一个将所有流量都发送到同一 Service 的简单 In ...

  5. 在k8s(kubernetes) 上安装 ingress V1.1.0

    Ingress 公开了从集群外部到集群内服务的 HTTP 和 HTTPS 路由.流量路由由 Ingress 资源上定义的规则控制. 下面是一个将所有流量都发送到同一 Service 的简单 Ingre ...

  6. 基于Nginx dyups模块的站点动态上下线并实现简单服务治理

    简介 今天主要讨论一下,对于分布式服务,站点如何平滑的上下线问题. 分布式服务 在分布式服务下,我们会用nginx做负载均衡, 业务站点访问某服务站点的时候, 统一走nginx, 然后nginx根据一 ...

  7. 使用Netsil监控Kubernetes上的微服务

    ubernetes是容器编排和调度领域的王者,它击败了竞争对手Docker Swarm和Apache Mesos,开启了闪耀的未来,微服务可以自修复,可以自动扩展,可以跨zone,region甚至跨云 ...

  8. 在Docker和Kubernetes上运行MongoDB微服务

    Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟.容器是完全使用沙箱机制,相互之间不会有任何接 ...

  9. Linux实战教学笔记37:企业级Nginx Web服务优化实战(上)

    一,Nginx基本安全优化 1.1 调整参数隐藏Nginx软件版本号信息 一般来说,软件的漏洞都和版本有关,这个很像汽车的缺陷,同一批次的要有问题就都有问题,别的批次可能就都是好的.因此,我们应尽量隐 ...

  10. 利用 istio 来对运行在 Kubernetes 上的微服务进行管理

    尝试在一个准生产环境下,利用 istio 来对运行在 Kubernetes 上的微服务进行管理. 这一篇是第一篇,将一些主要的坑和环境准备工作. 内容较多,因此无法写成手把手教程,希望读者有一定 Ku ...

随机推荐

  1. restful-接口风格

  2. 【scikit-learn基础】--『回归模型评估』之偏差分析

    模型评估在统计学和机器学习中具有至关重要,它帮助我们主要目标是量化模型预测新数据的能力. 本篇主要介绍模型评估时,如何利用scikit-learn帮助我们快速进行各种偏差的分析. 1. **R² ** ...

  3. Django应用中的静态文件处理

    在日常开发中,我们都是把Django的Debug模式打开,方便调试,在这个模式下,由Django内置的Web服务器提供静态文件服务,不过需要进行一些配置,才能正确访问. 配置settings # St ...

  4. [转帖]docker(一):docker pull指定运行平台架构

    https://zhuanlan.zhihu.com/p/539888862 1.概述 大家好,我是欧阳方超.某日要在服务器上部署docker服务,其中要用到nginx,nginx经过pull.sav ...

  5. [转帖]FIO使用说明

    FIO介绍: FIO是测试IOPS的非常好的工具,用来对磁盘进行压力测试和验证.磁盘IO是检查磁盘性能的重要指标,可以按照负载情况分成照顺序读写,随机读写两大类.FIO是一个可以产生很多线程或进程并执 ...

  6. [转帖]理解 postgresql.conf 的work_mem 参数配置

    https://developer.aliyun.com/article/401250 简介: 主要是通过具体的实验来理解 work_mem 今天我们着重来了解 postgresql.conf 中的 ...

  7. [转帖]ubuntu下配置iptables、ufw端口转发

    iptables 端口转发(CentOS) 注意:一来一去 在中转服务器操作 iptables -t nat -A PREROUTING -p tcp --dport [端口号] -j DNAT -- ...

  8. IBM Z15设备信息

     

  9. 【解决一个小问题】macbook m2 上交叉编译 gozstd

    作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 已知 zstd 是一个优秀的压缩库,gozstd封装了这个 ...

  10. Unity2019使用Gradle命令行(编译)出安卓包

    在我所经历的项目组中有这几种方法来生成APK 直接在Unity生成APK,可以接入SDK 使用Unity导出Android Studio工程手动生成APK 使用Unity导出Android Studi ...