> https://unsplash.com/photos/OKOOGO578eo
TL; DR
有四个主要服务,其中ClusterIP是圣杯:
我想让您想象一下,如果您创建一个NodD : ; , L YePort服务,它也会创建一个ClusterIP服务。 如果创建LoadBalancer,它会创建一个NodePi ; E V ; Oort,然后再创建一个Cluy X G q sterIP。 如果这样做,k8s服务将很容易。 我们将在本文中逐步介绍。
服务和Pod
服务指向吊舱。 服务不指向部署或副本集。 服务直接使用标签指向吊舱。 这提供了[ ; ; E极大的灵活性,因为创建吊舱的方式(无论是哪种方式,甚至是= n _ * {自定义的方式)都无关紧要。
我们将从一个简单的示例开始,我们将逐步扩展不同的服务类型,以了解它们是如b I R | Q 0 E S何在彼此之上构建的。
没有服务
我们从没有任何服务开始。
我们有两个节点,一个吊舱。 节点具有外部(4.4.4.1、4.4.4.2)和内部(1.1.1.1、1.1.1.2)IP地址。 pod pod-python只有一个内部。
现在,我们添加了第二个pod pod-nginx,它已安排在节点1上。 情况不一定如此,对于连接也没关系。 在Kubernetes中,所有Pod都可以在其内部IP地址上访问所有PoK 5 7 e & E j w 2d,无论它们在哪个节点上运行。
这意味着pod-nginx可以使用其内部IP 1.1.1.3 ping并连接到pod-python。
现在考虑一下pod-python模具,然后创建一个新模具。 (本文不介绍如何管理和控制Pod。)pod-nginx突然无法再达到1.1.1.3,世界突然间爆发出可怕的火焰……但是为了防止这种情况,我们创建了我们的第一项服务!
集群IP
场景相同,但是我们配置了ClusterIP服务。 没有在P; . God之类的特定节点上调度服务。 对于本文而言,假设服务仅在整个集群的内存中可用就足够了。
Pod-nginx可以始终安全地连接到1.1.10.1或dns名称service-python,并重定向到活动的python pod。 美丽。 没有火焰。 阳光。
我们扩展示例,启动3个pythI s m Z / b Kon实例,现在显示所有pod和服务的内部IP地址的端口。
群集中} A H的所有Pod都可以通过http://1.1.10.1:3000或http:// service-python:3000到达其端口443上的python pod。 ClusterIP服务python基于随机或轮询方法分发请求。 这就是ClusterIP服务的工作,它通过名Z z A称和IP使Pod在群集内可用。
上图中的service-python可能具有以下yaml:
apiVersion: v1
kind: Service
metadata:
name: service-python
spec:
ports:
- port: 3000
protocol: TCP
targetPort: 443
selector:
run: pod-python
type: ClusterIP
运行kubectl get svc:
节点端口
现在( f J , T M A,我们想从外部使用v n 5 jClusterIP服务,为此,我们将其转换为一个NodePort。 在我们的示例中,我们7 E M P i Z仅通过两个简单的yaml更改即可转换service-E P ^ a k n @ J Rpython:
apiVersion: v1
kind: Service
metadata:
name: service-python
spec:
ports:
- port: 39 v e | A * ^ i }000
protocol: TCP
targetPort: 443
nodePort: 30080
selector:
run: pod-python
type: NodePort
> external request over nodF ` d t R 5 j F he-2
这意味着我们现在也可以从端口30080上的每个节点内部和外部IP地址访问我们的内部服务python。
> external request over node-1
群集中的Pod也可以连接到端口30080上的内部节点IP。
运行kubectl get svc显示相同的集群ip。 只是不同的类型和其他节点端口:
在内部,NodePort服务以前仍然充当ClusterIP服务。 可以R X A o想象,即使不再有多余的ClusterIP对象,NodePort服务也会创建ClusterIP服务。
负载均q 3 6 9 n 7 4 Q 衡器
如果我们希望有一个IP(使用诸如轮询等方法将请求分发到所有外部节点IP),则可以使用LoadBalancer服务。 因此,它基于NodePort服务构建:
想象一下,LoadBalancer服务创建了一个NodePort服务,该服务创建了ClusterIP服务。 与之前的NodePort相比,针对LoadBalancer更改的yaml很简单:
apiVersion: v1
kind: Service
metadata:
name: service-p{ ; i Kython
spec:
port- b y K - Y Qs:
- port: 3000
protocol: TCP
targetPort: 44y % 2 E q 7 #3
nodePort: 30080
selector:
run: pod-python
type: LoadBalancer
LoadBalancer服务要做的只是创建一个NodePort服务。 此外,它还会向托管Kubernetes集群的提供商发送一条消息,要求# ^ ; 9 ` J $ T设置指向所有外部节点IP和特定nodePort的负载均衡器。 如果提供者不支持请求消息,那么什么也不会发生,并且L? : Y PoadBalancer等同于NodePort服务。
运行kubectl get svc只会显示EXTERNAL-IP和其他类型的添加:
与以前一样,LoadBalancer服务仍在内部和外部IP节点上打开端口30080。 而且它仍然像Cluste& # { ] n c |rIP服务一样。E n P J
外部名称
最后,ExternalName服务可以被认为是有} | g B j F ! Z点分离的,并且与x J 8 2 2 C x我们之前处理的3不在同一堆栈上。 简而言之:它创建一个内部服务,其端点指向DNS名称。
以我们早期的示例为例I & 4,我们现在假设pod-nginx已经e r D I x ) V 2在我们闪亮的新Kubernetes集群中。 但是python api仍然在外面:
在这里,pod-nginx必须连接到http://remote.B 9 w ; g %serB 9 A k ,ver.url.com,它肯定可以工作。 但是不久之后,我们希望将python api集成到集群中,直到那时,我们可以创建一个ExternalName服务:
可以使用以下yamQ & u 1l完成此操作:
kind: Service
apiVersion: v1
metadata:
name: service-python
spec:
ports:
- port: 3000
protocol: TCP
tac m k d QrgetPort: 443
type: Exterg ~ n . b 8 :nalName
externalName: remote.server.url.com
现在pod-H $ Y & Z Y O Mnginx可以简单地连接到http:// service-python:3000,就像使用Cly b x = 2 xusterIP? + o t & A N @服务x J m S 3 W 1 R一样。 当我们最终决定在美丽的Kubernetes集群中迁移pyth| O N M Eon api时,我们只需要将服务更改为具有正确标签集的ClusterIP即可:
> Python a, m S W $ 7 c @ 8pi still reachable6 6 = @ 5 ` , 5 at http://service-python
使用ExternalName服务的最大优: - B x 2 n势在于,即使某些服务可能仍在外部,您也可以创建完e ] 1 q整的Kubernetes基础结构,并且已经基于服务和IP应用规则和限制。
概括
(本文翻译自Kim Wuestkamp的文章《Kubernetes Services simply visually explained》,参考:https://medium.com/swlh/kubernetes-services-simply-visuall/ q X L ;y-explained-2d84e58d70e5)