K8s教程-kubernetes Ingress控制器
应用场景
Ingress 是 K8S Service 暴露内部服务的一种方式,比起 ClusterIP,NodePort,LoadBalancer等方式,Ingress 具有较多的优势。ClusterIP 仅限集群内部访问,NodePort 需要额外开放较多端口资源,LoadBalancer 需要云服务商提供支持,Ingress 无需云服务商支持,也无需开放太多端口,是比较好的解决方案。
- http同端口暴露服务过多,NodePort
和
LoadBlancer不能有效管理域名 - 快速暴露服务(不需要手动去添加nginx代理文件)
数据流
- Service-NodePort–> ingress-nginx-controller–>应用svc–>pod
pod:通过Deployment类型,动态调整资源,主要用于容器编排
svc:统一资源,CLUSTER-IP、PORT是固定的,pod调整的时候,svc会动态调整,对用户无感知,端口可以重复
ingress:ingress-nginx这个其实就是一个代理服务器,将svc进行代理,可以想成负载均衡器?
Ingress Controller:实际的pod服务,主要是读取ingress配置信息,动态调整控制器配置
如果Ingress Controller提供的是对外服务, 则实际上实现的是边缘路由器[Endpoint(Pod上)]的功能
服务访问方式
- NodePort 通过 kube-proxy 暴露的端口进行访问
- LoadBalancer
- Ingress
ingress-nginx
- 定义Ingress之前,需要先部署Ingress Controller
- controller其实就是一个nginx代理安装在node上面,并且数量是可以控制的(不一定每个node都需要安装),当性能不够的时候可以新增
- 网上很多文档都是基于:nginx-0.26.1/deploy/static/mandatory.yaml,这个版本是最后一个版本将deploy放在代码目录的,后续版本将deploy迁移到新的controller-xxx 分支上面:deploy/static/provider/cloud/deploy.yaml
- 新版本的deploy.yaml改动较大,更标准
- 私有k8s建议使用:controller-xxx/deploy/static/provider/cloud/deploy.yaml
- 因为main版本有可能是开发版本,存在不稳定因素,所以使用controller-xxx版本
- 另一个推荐方式:Using Helm 通过Helm安装
版本对比
deploy.yaml 包含了 ingress-nginx-controller 的 service声明,但是需要处理一下,因为 type: LoadBalancer 是不支持的
baremetal 和 main 主要区别就是:type类型
# main分支
https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/cloud/deploy.yaml
# controller-v0.48.1 分支
https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.48.1/deploy/static/provider/cloud/deploy.yaml
# nginx-0.26.1 分支
https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.26.1/deploy/static/mandatory.yaml
# nginx-0.26.2 分支 这里将 deploy 独立拆分为:controller-xxx 分支
# Deployment documentation moved! See /docs/deploy.
# 目前使用:controller-v0.48.1分支作为发布,建议使用controller版本,因为main版本有可能是开发版本,存在不稳定因素
# controller分支和main分支的区别
helm.sh/chart: ingress-nginx-3.34.0 ==> helm.sh/chart: ingress-nginx-3.35.0
# mandatory.yaml和deploy.yaml的区别较大
# 新增说明文档
# 标签变更:
app.kubernetes.io/part-of: ingress-nginx ==> app.kubernetes.io/instance: ingress-nginx
# 新增标签
helm.sh/chart: ingress-nginx-3.35.0
# 命名更加规范了,切此项新增了较多的标签
kind: ServiceAccount
metadata:
name: nginx-ingress-serviceaccount
# 改为
kind: ServiceAccount
metadata:
name: ingress-nginx
发布安装
# 下载
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.48.1/deploy/static/provider/cloud/deploy.yaml
# 单独镜像下载
# docker pull registry.aliyuncs.com/google_containers/nginx-ingress-controller:v0.48.1@sha256:e9fb216ace49dfa4a5983b183067e97496e7a8b307d2093f4278cd550c303899
# 修改源(k8s.gcr.io被墙,无法下载),注意版本对应关系
# k8s.gcr.io/ingress-nginx/controller 对应 registry.aliyuncs.com/google_containers/nginx-ingress-controller
sed -i 's#k8s.gcr.io/ingress-nginx/controller#registry.aliyuncs.com/google_containers/nginx-ingress-controller#g' deploy.yaml
# 发布
kubectl apply -f deploy.yaml
# 检测
kubectl get pods -n ingress-nginx \
-l app.kubernetes.io/name=ingress-nginx --watch -o wide
deploy.yaml 流程说明
- Namespace 创建命名空间,这样可以将相关资源独立出来
- ServiceAccount Pod中的进程调用Kubernetes API而设计,创建Namespace的时候会生成一个default值 参考
- ConfigMap 保存配置文件,查看:kubectl describe configmap ingress-nginx-controller -n ingress-nginx
- ClusterRole 授权,负责整个Kubernetes集群范围内的权限,查看:kubectl describe clusterrole -n ingress-nginx
- ClusterRoleBinding 资源/账号绑定对应的ClusterRole权限 subjects对应的资源具有roleRef对应的权限
- Role 授权,负责命名空间(namespace)内的权限
- RoleBinding 命名空间下的权限绑定
- Service 创建服务:ingress-nginx-controller-admission,type: ClusterIP
- Service 创建服务:ingress-nginx-controller,type: LoadBalancer 这个服务无法申请EXTERNAL-IP,因为没有自建的负载均衡器
- Deployment 创建pod:ingress-nginx
- ValidatingWebhookConfiguration 验证钩子,准入钩子(Admission Webhooks) 动态准入控制
- ServiceAccount 创建钩子账号 name: ingress-nginx-admission
- ClusterRole 集群钩子权限
- ClusterRoleBinding 集群钩子权限绑定
- Role 钩子权限
- RoleBinding 钩子权限绑定
- Job name: ingress-nginx-admission-create 创建证书,镜像:kube-webhook-certgen 工作原理
- Job name: ingress-nginx-admission-patch 提取ca并写入指定的admission webhook 镜像:kube-webhook-certgen工作原理
# 问题(这里没有本地的LoadBalancer服务,所以无法申请到EXTERNAL-IP)
# kubectl get svc -n ingress-nginx ingress-nginx-controller
apiVersion: v1
kind: Service
......
name: ingress-nginx-controller
namespace: ingress-nginx
spec:
type: LoadBalancer
externalTrafficPolicy: Local
双栈 部署ingress-nginx
https://blog.51cto.com/juestnow/2493608
Ingress · Kubernetes Handbook - Kubernetes 中文指南/云原生应用架构实践手册 · Jimmy Song
helm安装
# nginx可以改成任意自己需要的名称,比如:plat,gm,web,bbs
# 类似云产品的负载均衡器名称
# controller同样会申请:
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
# 导出配置 helm inspect values ingress-nginx/ingress-nginx > values.yaml
# 使用:--set 替换为使用 -f values.yaml
# externalIPs 指定暴露ip
# ingressClass 这个注解的值,一般是具体 Ingress Controller 所提供的默认值,如 nginx、gce、traefik、kong 等
# 多个Ingress控制器的时候需要指定
helm install hello-world ingress-nginx/ingress-nginx \
--namespace kube-system \
--set controller.ingressClass=nginx \
--set controller.publishService.enabled=true \
--set controller.service.externalIPs={10.0.26.190}
# 查看
kubectl --namespace kube-system get services -o wide -w hello-world-ingress-nginx-controller
# 删除
helm uninstall --namespace kube-system hello-world
k8s之PodIP、ClusterIP和ExternalIP
Kube:使用IPVS和External IP对K8S集群进行外部负载均衡 - 云+社区 - 腾讯云 (tencent.com)
[k8s]k8s pod的4种网络模式最佳实战(externalIPs ) - _毛台 - 博客园 (cnblogs.com)
NodePort,LoadBalancer还是Ingress?我该如何选择 (qq.com)
kube-apiserver
--service-cluster-ip-range 10.26.0.0/16 # 集群网络的ip段,内网任意节点可以访问,外部需要service提供
--service-node-port-range 3000-29999 # 集群节点的端口段
controller-manager
--service-cluster-ip-range=10.26.0.0/16
--cluster-cidr=172.26.0.0/16 # 节点网络(CNI使用?)
# flanneld 优先读取 --subnet-file 参数定义的配置文件,如果不存在则读取 etcd 配置的网络信息
# /etc/kubernetes/flanneld_subnet.env
FLANNEL_NETWORK=172.26.0.0/16 # CNI大网
FLANNEL_SUBNET=172.26.25.1/24 # 子网
# dockerd 读取 flanneld 生成的子网信息:$DOCKER_NETWORK_OPTIONS
EnvironmentFile=-/etc/kubernetes/flanneld_docker.env
ExecStart=/usr/bin/dockerd $DOCKER_NETWORK_OPTIONS
使用 Service 把前端连接到后端 | Kubernetes
# 国内无法使用gcr.io,所以使用docker非官方源进行测试
docker search hello-go-gke
# docker pull vaikulkaz/hello-go-gke:1.0
gcr.io/google-samples/hello-go-gke:1.0
# 改成
vaikulkaz/hello-go-gke:1.0
LoadBalancer服务是发布服务到互联网的标准方式。在GKE中,它会启动一个Network Load Balancer,分配一个单独的IP地址,将所有流量转发到服务中。
腾讯云叫TKE 腾讯云容器服务(Tencent Kubernetes Engine ,TKE)基于原生kubernetes提供以容器为核心的、高度可扩展的高性能容器管理服务。
所以测试网络不要使用:type: LoadBalancer,而是使用: externalIPs: - 192.168.2.12 # 这是我的一台node的ip
---
apiVersion: v1
kind: Service
metadata:
name: frontend
spec:
selector:
app: hello
tier: frontend
ports:
- protocol: "TCP"
port: 80
targetPort: 80
# 不是公有云的话,不要使用:type: LoadBalancer,因为此类型是向GKE、TKE申请:EXTERNAL-IP
externalIPs:
- 10.0.26.190 # 其中一个node的ip
...
# 效果如下
root@k8s-master-01:~# kubectl get service frontend
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
frontend ClusterIP 10.26.68.2 10.0.26.190 80/TCP 4s
# 集群内部访问
root@k8s-master-01:~# curl 10.0.26.190
{"message":"Hello"}
# 外部节点访问(缺点:单节点代理访问压力,优点:通过service对后端进行了负载)
root@k8s-master-01:~# curl 10.0.26.190
{"message":"Hello"}
# 浏览器访问
# http://10.0.26.190/
Ingress 控制器
你必须具有 Ingress 控制器 才能满足 Ingress 的要求。 仅创建 Ingress 资源本身没有任何效果。
Ingress 控制器:traefik istio nginx enovy
目前Ingress暴露集群内服务的行内公认最好的方式,不过由于其重要地位,世面上有非常多的Ingres Controller
这是一个苹果与橘子的比较。
像Traefik或Nginx这样的边缘代理最好与–Istio利用的代理进行比较。 Istio会自动安装Envoy代理,并与每个吊舱相邻。
Istio在Envoy之外提供了几个更高级别的功能,包括路由,ACLing和服务发现和访问策略*,跨越一组服务*。实际上,它将一系列启用Envoy的服务拼接在一起。这种设计模式通常被称为服务网格。
Istio目前仅限于单个集群中的Kubernetes部署,尽管工作已经到位以及时消除这些限制。
- 部署策略:是否支持ab部署、金丝雀部署、蓝绿部署等
借助Istio Ingress,您可以微调流量路由,服务之间的访问授权,平衡,监控,金丝雀发布等.
不过社区现在更推荐使用Ingress Gateways。
替代方案
你可以通过很多种方式暴露 service 而不必直接使用 ingress:
- 使用 Service.Type=LoadBalancer
- 使用 Service.Type=NodePort
- 使用 Port Proxy
- 部署一个 Service loadbalancer 这允许你在多个 service 之间共享单个 IP,并通过 Service Annotations 实现更高级的负载平衡。
使用多个 Ingress 控制器
你可以在集群中部署任意数量的 ingress 控制器。 创建 ingress 时,应该使用适当的 ingress.class
注解每个 Ingress 以表明在集群中如果有多个 Ingress 控制器时,应该使用哪个 Ingress 控制器。
如果不定义 ingress.class
,云提供商可能使用默认的 Ingress 控制器。
理想情况下,所有 Ingress 控制器都应满足此规范,但各种 Ingress 控制器的操作略有不同。
说明: 确保你查看了 ingress 控制器的文档,以了解选择它的注意事项。
参考
- 原文作者:zaza
- 原文链接:https://zazayaya.github.io/2021/08/17/k8s-ingress.html
- 说明:转载本站文章请标明出处,部分资源来源于网络,如有侵权请及时与我联系!