k8s_day09_03
流量方向
pod 与pod、主机之间经由service 的通信的集群内部流量,叫东西向流量。
与集群外通信的流量叫南北向流量。南向流入、北向流出。
在Ingress与服务发布的语境中:
Ingress: 集群外部注入集群内部的流量。
Egress:集群内部流出到集群外部的流量
将集群外部的流量引入到集群内部中的方式:
有2种类型的方式:
- 借助特殊类型的 service: NodePort 、externalIP
- 借助节点当作跳板:hostPort、hostNetwork
而service 的代理模式有3种
- Userspace:iptables 结合用户空间的kube-proxy 进程
- iptables规则: 负责完成流量的地址转换、负载均衡
- ipvs
service 引入集群外部流量的缺点:
无论是ipvs 还是iptables 代理模式, 都是工作在传输层。 这种负载均衡的解决方案无法做到七层代理的功能, 比如识别客户端,基于url 做不同方向的路由 就不行。同时这2种代理模式,也无法实现ssl 的卸载。虽然在集群内部通信 使用http 很安全 ,但是想和集群外部通信时,卸载ssl 就无法实现。 因为它们都是工作在传输层
还有就是 service 引入集群外部流量时,暴露发布内部服务时,会有有多个无关联的端口,会在边界 打很多洞,无法统一管理。必须在每个名称空间当作一个一个找nodeport 类型的service
Ingress 概念
Ingress 就是被用来设计解决这种方案的:
是标准资源类型
在本质上来说,ingress 资源是基于http 虚拟主机或者url 路径的流量转发规则, 它把需要暴露给集群外部的每个service 对象,映射为 ingress 控制器上的一个虚拟主机或者虚拟主机上的一个path 路径
ingress 是用来 配置 七层ingress 控制器代理的 配置文件片段。因为一个ingress 只定义一个服务。而ingress 控制器通常只有一个。
虽然cm 也可以向ingress 控制器注入配置信息, 但是cm 配置无法描述规则的复杂性。
ingress 是描述性语言。ingress控制器虽然多种,但是ingress 规则不关心。
Ingress资源需要控制器自身能识别标准的ingress并且自动完成格式转发、动态重载
对于k8s 来说, 所有的基础设施都必须实现一种功能,可以通过资源类型定义出来

ingress 设置的请求路由,而不是地址路由。后端用 backend 标识service
ingress 控制器
ingress 只是一套流量控制规则。 让规则生效的是Ingress 控制器。工作在集群边缘, 也运行为一个pod, 把外部流量引入ingress 控制器上,通常使用那2种特殊类型的service
Ingress 控制器本身就是一类 以代理http/https 协议为主要功能的代理程序(兼具tcp/http)。它可以由任何反向代理功能的程序实现。比如nginx、haproxy。
Ingress资源需要控制器自身能识别标准的ingress并且自动完成格式转发、动态重载。 所以原生的nginx 程序无法实现此功能,ingress-nginx 才行。
常见的ingress 控制器
- Ingress-Nginx: 没落老贵族,只是迁移到k8s 环境上能运行而已。只不过有新干爹F5
- HAProxy
- Envoy:Contour 和Gloo Envoy… 天生支持,场景之一、功能强大
- Traefik: 专为ingress 控制器 而生
使用Ingress资源进行流量分发时,Ingress控制器可基于某Ingress资源定义的规则将客户端的请求流量直接转发至Service对应的后端Pod资源之上,这种转发机制会绕过Service资源,从而省去了由kube-proxy实现的端口代理开销。
ingress 使用的 serivice目的 仅仅是 识别后端pod.

Ingress 规范
老版本v1 beta1
apiVersion: extensions/v1beta1 # 资源所属的API群组和版本
kind: Ingress # 资源类型标识符
metadata: # 元数据
name <string> # 资源名称
annotations: # 资源注解,v1beta1使用下面的注解来指定要解析该资源的控制器类型
kubernetes.io/ingress.class: <string> # 适配的Ingress控制器类别
namespace <string> # 名称空间
spec:
rules <[]Object> # Ingress规则列表;
- host <string> # 虚拟主机的FQDN,支持“*”前缀通配,不支持IP,不支持指定端口
http <Object>
paths <[]Object> # 虚拟主机PATH定义的列表,由path和backend组成
- path <string> # 流量匹配的HTTP PATH,必须以/开头
pathType <string> # 匹配机制,支持Exact、Prefix和ImplementationSpecific
backend <Object> # 匹配到的流量转发到的目标后端
resource <Object> # 引用的同一名称空间下的资源,与下面两个字段互斥
serviceName <string> # 引用的Service资源的名称
servicePort <string> # Service用于提供服务的端口
tls <[]Object> # TLS配置,用于指定上rules中定义的哪些host需要工作HTTPS模式
- hosts <[]string> # 使用同一组证书的主机名称列表
secretName <string> # 保存于数字证书和私钥信息的secret资源名称
backend <Object> # 默认backend的定义,可嵌套字段及使用格式跟rules字段中的相同
ingressClassName <string> # ingress类名称,用于指定适配的控制器
新版本v1
apiVersion: networking.k8s.io/v1 # 资源所属的API群组和版本
kind: Ingress # 资源类型标识符
metadata: # 元数据
name <string> # 资源名称
annotations: # 资源注解,v1beta1使用下面的注解来指定要解析该资源的控制器类型
kubernetes.io/ingress.class: <string> # 适配的Ingress控制器类别
namespace <string> # 名称空间
spec:
rules <[]Object> # Ingress规则列表
- host <string> # 虚拟主机的FQDN,支持“*”前缀通配,不支持IP,不支持指定端口
http <Object>
paths <[]Object> # 虚拟主机PATH定义的列表,由path和backend组成
- path <string> # 流量匹配的HTTP PATH,必须以/开头
pathType <string> # 支持Exact、Prefix和ImplementationSpecific,必选
backend <Object> # 匹配到的流量转发到的目标后端
resource <Object> # 引用的同一名称空间下的资源,与下面两个字段互斥
service <object> # 关联的后端Service对象
name <string> # 后端Service的名称
port <object> # 后端Service上的端口对象
name <string> # 端口名称
number <integer> # 端口号
tls <[]Object> # TLS配置,用于指定上rules中定义的哪些host需要工作HTTPS模式
- hosts <[]string> # 使用同一组证书的主机名称列表
secretName <string> # 保存于数字证书和私钥信息的secret资源名称
backend <Object> # 默认backend的定义,可嵌套字段及使用格式跟rules字段中的相同
ingressClassName <string> # ingress类名称,用于指定适配的控制器
示例
如何使用ingress 规则
1、安装一个ingress 控制器
安装 ingress-nginx controller (github 页面 找 bare metal 裸金属那个)
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.41.2/deploy/static/provider/baremetal/deploy.yaml
ingress 控制器 还是要“打洞的” ,为了方便管理。用extenalip
name: ingress-nginx-controller
namespace: ingress-nginx
spec:
type: NodePort
externalIPs: [192.168.2.4]
ports:
查看结果
[root@node01 ~]# kubectl get pods -n ingress-nginx
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-49h6n 0/1 Completed 0 4m34s
ingress-nginx-admission-patch-79d2s 0/1 Completed 2 4m34s
ingress-nginx-controller-5dbd9649d4-hgv2c 1/1 Running 0 4m34s
[root@node01 ~]#
1.5 创建需要暴露的service/pod
[root@node01 ~]# cat /data/chapter8/deployment-demo.yaml
# VERSION: demoapp version
# Maintainer: MageEdu <mage@magedu.com>
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-demo
spec:
replicas: 4
selector:
matchLabels:
app: demoapp
release: stable
template:
metadata:
labels:
app: demoapp
release: stable
spec:
containers:
- name: demoapp
image: ikubernetes/demoapp:v1.0
ports:
- containerPort: 80
name: http
---
apiVersion: v1
kind: Service
metadata:
name: demoapp-deploy
spec:
selector:
app: demoapp
release: stable
ports:
- name: http
port: 80
targetPort: 80
2、v1beta1
[root@node01 ~]# cat demoapp-ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-demo
annotations:
kubernetes.io/ingress.class: "nginx"
namespace: ingress-nginx
spec:
rules:
- host: www.ik8s.io
http:
paths:
- path:
backend:
serviceName: demoapp-deploy
servicePort: 80
[root@node01 ~]# kubectl apply -f demoapp-ingress.yaml
Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
ingress.extensions/ingress-demo created
[root@node01 ~]# kubectl get ingress/ingress-demo
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress-demo <none> www.ik8s.io 80 3s
[root@node01 ~]# curl -H "Host: www.ik8s.io" 192.168.2.4
iKubernetes demoapp v1.0 !! ClientIP: 10.244.3.2, ServerName: deployment-demo-fb544c5d8-cnl5l, ServerIP: 10.244.3.3!
[root@node01 ~]#
旧版本的坑 没有address
3、v1
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-demo
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: www.ik8s.io
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: demoapp-deploy
port:
number: 80
[root@node01 ~]# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller NodePort 10.109.17.98 192.168.2.4 80:32697/TCP,443:32184/TCP 21m
ingress-nginx-controller-admission ClusterIP 10.98.91.180 <none> 443/TCP 21m
[root@node01 ~]# curl -H "Host: www.ik8s.io" 192.168.2.4
iKubernetes demoapp v1.0 !! ClientIP: 10.244.2.4, ServerName: deployment-demo-fb544c5d8-5gcmv, ServerIP: 10.244.1.6!
[root@node01 ~]# curl 192.168.2.4
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>
[root@node01 ~]#
[root@node01 ~]# kubectl get ingress/ingress-demo
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress-demo <none> www.ik8s.io 192.168.2.4 80 15s
发现 address 是外置ip