说说 Kubernetes 是怎么实现服务发现的( 四 )
可以看到这条 postrouting 规则给即将离开主机的请求进行了一次 SNAT , 判断条件为带有 0x4000 标志 , 这就是之前 DNAT 带的标志 , 从而判断请求是从 Service 转发出来的 , 而不是普通请求 。
需要做 SNAT 的原因很简单 , 首先这是一个外部的未经 Kubernetes 处理的请求 , 如果它访问 node1 , node1 的负载均衡将其转发给 node2 上的某个 Pod , 这没什么问题 , 而这个 Pod 处理完后直接返回给外部 client , 那么外部 client 就很疑惑 , 明明自己访问的是 node1 , 给自己返回的确是 node2 , 这时往往会报错 。
SNAT 的作用与 DNAT 相反 , 就是在请求从 node1 离开发往 node2 时 , 将源地址改为 node1 的地址 , 那么当 node2 上的 Pod 返回时 , 会返回给 node1 , 然后再让 node1 返回给 client 。
client| ^| |v | node 2v | endpoints
Service 还有另外 2 种通过外界访问的方式 。适用于公有云的 LoadBalancer 模式的 service , 公有云 Kubernetes 会调用 CloudProvider 在公有云上为你创建一个负载均衡服务 , 并且把被代理的 Pod 的 IP 地址配置给负载均衡服务做后端 。另外一种是 ExternalName 模式 , 可以通过在 spec.externalName 来指定你想要的外部访问域名 , 例如 hostnames.example.com , 那么你访问该域名和访问 service-name.namespace-name.svc.cluser.local 效果是一样的 , 这时候你应该知道 , 其实 kube-dns 为你添加了一条 CNAME 记录 。
Ingress
Service 有一种类型叫作 LoadBalancer , 不过如果每个 Service 对外都配置一个负载均衡服务 , 成本很高而且浪费 。一般来说我们希望有一个全局的负载均衡器 , 通过访问不同 url , 转发到不同 Service 上 , 而这就是 Ingress 的功能 , Ingress 可以看做是 Service 的 Service 。
Ingress 其实是对反向代理的一种抽象 , 相信大家已经感觉到 , 这玩意儿和 Nginx 十分相似 , 实际上 Ingress 是抽象层 , 而其实现层其中之一就支持 Nginx 。
我们可以部署一个 nginx ingress controller:
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/mandatory.yaml
mandatory.yaml是官方维护的 ingress controller , 我们看一下:
kind: ConfigMap apiVersion: v1 metadata: name: nginx-configuration namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx --- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: nginx-ingress-controller namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx spec: replicas: 1 selector: matchLabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx template: metadata:labels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxannotations:... spec:serviceAccountName: nginx-ingress-serviceaccountcontainers:- name: nginx-ingress-controllerimage: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.20.0args:- /nginx-ingress-controller- --configmap=$(POD_NAMESPACE)/nginx-configuration- --publish-service=$(POD_NAMESPACE)/ingress-nginx- --annotations-prefix=nginx.ingress.kubernetes.iosecurityContext:capabilities:drop:- ALLadd:- NET_BIND_SERVICE# www-data -> 33runAsUser: 33env:- name: POD_NAMEvalueFrom:fieldRef:fieldPath: metadata.name- name: POD_NAMESPACE- name: httpvalueFrom:fieldRef:fieldPath: metadata.namespaceports:- name: httpcontainerPort: 80- name: httpscontainerPort: 443
总的来说 , 我们定义了一个基于 nginx-ingress-controller 镜像的 Pod , 而这个 Pod 自身 , 是一个监听 Ingress 对象及其代理后端 Service 变化的控制器 。
当一个 Ingress 对象被创建时 , nginx-ingress-controller 就会根据 Ingress 对象里的内容 , 生成一份 Nginx 配置文件(nginx.conf) , 并依此启动一个 Nginx 服务 。
当 Ingress 对象被更新时 , nginx-ingress-controller 就会更新这个配置文件 。nginx-ingress-controller 还通过 Nginx Lua 方案实现了 nginx upstream 的动态配置 。
- 原神心海是几星(原神心海角色属性介绍)
- 今年的iphonese,还是你熟悉的模样
- 原神雷神是什么定位(原神手游雷神定位分析)
- 原神无尽骤战高分打法是什么(原神无尽骤战玩法技巧分享)
- 崩坏3V5.0版本累计消费活动是什么(崩坏3V5.0版本夏日活动介绍)
- 249克!开箱道通EVO Nano+袖珍无人机:夜景是亮点
- 浓缩洗涤剂,还是老牌国货一轻日化好~
- 饿了么是不是只能用支付宝(饿了么平台运营详细解说)
- 微信朋友验证消息是怎么回事(?微信查看好友添加来源步骤)
- 妄想山海神树蕴养玩法是什么(妄想山海神树蕴养玩法思路介绍)
