hualinux 进阶 1.14:Services服务及种类

目录

一、service作用

1.1 作用

1.2 例子

1.2.1 建立deployment

1.2.2 建立serveices

二、Headless Services

2.1 定义

2.2 什么情况下才用Headless Services

三、几种服务类型

3.1  services几种类型

3.2 类型相关拓扑图

3.2 .1 ClusterIP

3.2.2 NodePort​

3.2.3 LoadBalancer

3.2.4 ExternalName

3.2.5 Headless


Service 服务的主要作用,就是作为 Pod 的代理入口(Portal),从而代替 Pod 对外暴露一个固定的网络地址。

一、service作用

1.1 作用

我们前面所学的pod和ReplicaSetDeployment 等,当我们有需求Pod 对外暴露一个固定的网络地址对外放一个固定的IP地址,我们这时间就要用到服务了,虽然pod、ReplicaSet、wDeployment 有IP地址,但是它并不是固定的,pod挂了,从另了个节点起一个,那么它的地址可能是变化的,而Service 服务声明的 IP 地址等信息是“终生不变”的。

Service 服务的主要作用,就是作为 Pod 的代理入口(Portal),从而代替 Pod 对外暴露一个固定的网络地址。

Service 是 Kubernetes 项目中用来将一组 Pod 暴露给外界访问的一种机制。比如,一个 Deployment 有 3 个 Pod,那么我就可以定义一个 Service。然后,用户只要能访问到这个 Service,它就能访问到某个具体的 Pod。

关于 服务详细的学习,可以看k8s官网中文services相关章节,这里就不细讲了

1.2 例子

我们通过一个例子去说明,我建立一个有3个节点的pod

1.2.1 建立deployment

mkdir -pv /disk1/myk8s
cd /disk1/myk8s/

cat>nginx-deployment.yaml<<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    web: nginx18
spec:
  replicas: 3
  selector:
    matchLabels:
      web: nginx18
  template:
    metadata:
      labels:
        web: nginx18
    spec:
      containers:
      - name: nginx
        image: nginx:1.18
        ports:
        - containerPort: 80
EOF
cat nginx-deployment.yaml
kubectl apply -f nginx-deployment.yaml 

建立之后去登陆web方式查看一下,

更新完之后,使用命令,查看一下

[root@vm82 myk8s]# kubectl get deploy -o wide
NAME               READY   UP-TO-DATE   AVAILABLE   AGE     CONTAINERS   IMAGES       SELECTOR
nginx-deployment   3/3     3            3           4m53s   nginx        nginx:1.18   web=nginx18
[root@vm82 myk8s]# 
#查看发现k8s自动帮pod分配了一个内部地址,这个地址并不是固定不变的,比如一个pod挂了
#从另一个节点再起一个,那地址就会变了
[root@vm82 myk8s]# kubectl get po -o wide
NAME                                READY   STATUS    RESTARTS   AGE    IP          NODE    NOMINATED NODE   READINESS GATES
nginx-deployment-856f977dd6-9khc2   1/1     Running   0          5m1s   10.44.0.1   vm821   <none>           <none>
nginx-deployment-856f977dd6-wh9bf   1/1     Running   0          5m1s   10.44.0.3   vm821   <none>           <none>
nginx-deployment-856f977dd6-xppkj   1/1     Running   0          5m1s   10.44.0.2   vm821   <none>           <none>
#测试是否ping通
[root@vm82 myk8s]# ping 10.44.0.1 -c 3
PING 10.44.0.1 (10.44.0.1) 56(84) bytes of data.
64 bytes from 10.44.0.1: icmp_seq=1 ttl=64 time=107 ms
64 bytes from 10.44.0.1: icmp_seq=2 ttl=64 time=6.05 ms
64 bytes from 10.44.0.1: icmp_seq=3 ttl=64 time=3.10 ms

--- 10.44.0.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 9ms
rtt min/avg/max/mdev = 3.095/38.847/107.400/48.489 ms
#使用curl测试是否能访问
[root@vm82 myk8s]# curl 10.44.0.1
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

发现k8s是给pod分配一个内部IP地址,但是不稳定的啊,3个,万一挂了一个pod,在另一个节点起一个pod,和挂掉的pod的名字都不一样,地址也不一样。但是我需要一个稳定的地址,所以得services上场了,在之前我们先看一下3个pod的标签,发现是一样,如下图所示:

因为是3个pod是一样的,访问那个都无所谓,所以只需要一个入口就行了,这样会实现负载效果,我可以可以去修改一下pod的nginx中的index.html内容。

kubect exec <pod名字> -c 容器名 -- 要执行的命令

kubectl exec nginx-deployment-856f977dd6-9khc2 -c nginx -- bash -c "echo '10.44.0.1 pod'>/usr/share/nginx/html/index.html"
kubectl exec nginx-deployment-856f977dd6-xppkj -c nginx -- bash -c "echo '10.44.0.2 pod'>/usr/share/nginx/html/index.html"
kubectl exec nginx-deployment-856f977dd6-wh9bf -c nginx -- bash -c "echo '10.44.0.3 pod'>/usr/share/nginx/html/index.html"

1.2.2 建立serveices

如果你不懂怎么写可以使用 kubectl expain Service 命令,或者查看官网的 services

#创建一个服务
cat>nginx-ser.yaml<<EOF
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  selector:
   #查找匹配的标签的pod
    web: nginx18
  ports:
    - protocol: TCP
      #services对外端口
      port: 80
      #这个是容器端口
      targetPort: 80
EOF
kubectl apply -f nginx-ser.yaml

ps:除了上面的port端口还有其它几种端口,可以使用以下命令查看有哪些选择

kubectl explain Services.spec.ports

ClusterIP:使用集群内的私有ip —— 这是默认值

port:为群集访问端口

targetPort:要代理的目标的容器端口,像nginx代理那样,这个是基于端口的

NodePort:除了使用cluster ip外,也将service的port映射到每个node的一个指定内部port上,映射的每个node的内部port都一样,端口号只能30000-32767,这也多了一种形式,也是 nodeIP:port 方式访问

externalIPs:如果外部的 IP 路由到集群中一个或多个 Node 上,Kubernetes Service 会被暴露给这些 externalIPs。 通过外部 IP(作为目的 IP 地址)进入到集群,打到 Service 的端口上的流量,将会被路由到 Service 的 Endpoint 上。 externalIPs 不会被 Kubernetes 管理,它属于集群管理员的职责范畴。
这种IP只能是节点IP地址,包括master节点和node节点

 建立好了,我们查看一下serveice端口

#注svc是serivces的简写,发现创建了一个nginx服务,并建立了相关IP地址
[root@vm82 myk8s]# kubectl get svc -o wide
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE     SELECTOR
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP   7d21h   <none>
nginx        ClusterIP   10.106.215.131   <none>        80/TCP    17m     web=nginx18

测试一下,访问一下

#不断开执行 curl 10.106.215.131 发现内容变化了,所以是实现了负载均衡的效果
[root@vm82 myk8s]# curl 10.106.215.131
10.44.0.1 pod
[root@vm82 myk8s]# curl 10.106.215.131
10.44.0.1 pod
[root@vm82 myk8s]# curl 10.106.215.131
10.44.0.2 pod
[root@vm82 myk8s]# curl 10.106.215.131
10.44.0.1 pod
[root@vm82 myk8s]# curl 10.106.215.131
10.44.0.2 pod
[root@vm82 myk8s]# curl 10.106.215.131
10.44.0.3 pod
[root@vm82 myk8s]# curl 10.106.215.131
10.44.0.3 pod

我们也可以从web上查看的

 

二、Headless Services

这个很重要,得讲一下,在下一章使用statefulset需要用到这个

2.1 定义

Headless Services为无头服务的意思,即指定 Cluster IP(spec.clusterIP)的值为 "None" 来创建 Headless Service。

2.2 什么情况下才用Headless Services

有时不需要或不想要负载均衡,以及单独的 Service IP。,那么我们怎样访问它呢,有两个方式

第一种方式,是以 Service 的 VIP(Virtual IP,即:虚拟 IP)方式。比如:当我访问 10.0.23.1 这个 Service 的 IP 地址时,10.0.23.1 其实就是一个 VIP,它会把请求转发到该 Service 所代理的某一个 Pod 上。

第二种方式,就是以 Service 的 DNS 方式。比如:这时候,只要我访问“my-svc.my-namespace.svc.cluster.local”这条 DNS 记录,就可以访问到名叫 my-svc 的 Service 所代理的某一个 Pod。

而在第二种 Service DNS 的方式下,具体还可以分为两种处理方法:

第一种处理方法,是 Normal Service。这种情况下,你访问“my-svc.my-namespace.svc.cluster.local”解析到的,正是 my-svc 这个 Service 的 VIP,后面的流程就跟 VIP 方式一致了。

而第二种处理方法,正是 Headless Service。这种情况下,你访问“my-svc.my-namespace.svc.cluster.local”解析到的,直接就是 my-svc 代理的某一个 Pod 的 IP 地址。可以看到,这里的区别在于,Headless Service 不需要分配一个 VIP,而是可以直接以 DNS 记录的方式解析出被代理 Pod 的 IP 地址。

上面我们使用了Deployment  建立服务,如果是多个pod是负载均衡的方式 ,但是statefulset中多个pod的时候下,每个pod是不同的,有序号的,你得需要再细化,不能用负载均衡方式,也不是群集统一地址,需要为每个pod建立一个精确的地址,这时Headless Services就派上用场了。这个在下章statefulset再讲它的pod

 

三、几种服务类型

3.1  services几种类型

对一些应用(如 Frontend)的某些部分,可能希望通过外部Kubernetes 集群外部IP 地址暴露 Service。

Kubernetes ServiceTypes 允许指定一个需要的类型的 Service,默认是 ClusterIP 类型。

Type 的取值以及行为如下:

  • ClusterIP:通过集群的内部 IP 暴露服务,选择该值,服务只能够在集群内部可以访问,这也是默认的 ServiceType
  • NodePort:通过每个 Node 上的 IP 和静态端口(NodePort)暴露服务。NodePort 服务会路由到 ClusterIP 服务,这个 ClusterIP 服务会自动创建。通过请求 <NodeIP>:<NodePort>,可以从集群的外部访问一个 NodePort 服务。
  • LoadBalancer:使用云提供商的负载局衡器,可以向外部暴露服务。外部的负载均衡器可以路由到 NodePort 服务和 ClusterIP 服务。
  • ExternalName:通过返回 CNAME 和它的值,可以将服务映射到 externalName 字段的内容(例如, foo.bar.example.com)。 没有任何类型代理被创建。

说明: 您需要 CoreDNS 1.7 或更高版本才能使用 ExternalName 类型。

3.2 类型相关拓扑图

3.2 .1 ClusterIP

客户端Pod对象访问服务端Pod对象时不会进行源地址转换:
二者在同一主机时,源地址为客户端pod地址;
二者不在同-主机时,源地址为客户端pod所在节点的flannel或cni地址。

只能在集群内部被访问

 

3.2.2 NodePort

可以被集群外部访问到,节点的请求会DNAT到Serviceip,然后再调度至 PodIP

 

3.2.3 LoadBalancer

需要结合公有云的LBAAS ( 需要付费) , 支持动态接入功能。
 

3.2.4 ExternalName

将集群外部Service引入集群内部供各客户端使用,需要设置标签选择器,并手动定义一个endpoint资源,指向外部的资源地址。

 

3.2.5 Headless

这是一个比较特殊的service类型,有时候,你没必要或者不需要负载均衡和一个对外提供服务的ip地址。

在这种情况下,你可以在.spec.clusterIp中定义None字段,来申明-一个Headless Service。他可以通过coredns组件内部的解析功能,以完成相关地址解析的支持作用。

此外,我们之后会讲到StatefulSet控制器,它就是基于Headless网络所构筑的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值