K8s-----(六)Service的类型

1 Service的介绍

Kubernetes Pod是有生命周期的,它们可以被创建,也可以被销毁,然而一旦被销毁生命就永远结束。 通过ReplicationController能够动态地创建和销毁Pod, 每个 Pod 都会获取它自己的 IP 地址,可一旦销毁后,重新创建后,IP地址会产生改变。 这会导致一个问题:在 Kubernetes 集群中,如果一组 Pod(称为 backend)为其它 Pod (称为 frontend)提供服务,一旦backend的Pod重新创建,那么frontend的Pod该如何发现,并连接到这组 Pod 中的哪些 backend 呢?

1.1 为什么要使用Service

Service资源用于为pod对象提供一个固定、统一的访问接口及负载均衡的能力,并借助新一代DNS系统的服务发现功能,解决客户端发现并访问容器化应用的问题。

在kubernetes中,在收到rc调控的时候,pod副本数是变化的,对应的虚IP也是变化的,比如发生迁移或者伸缩时。这对于pod的访问来说是不能接受的,kubernetes中的service是一种逻辑概念。它定义了一个pod逻辑集合以及访问它们的策略,service与pod的关联同样是通过label完成的。service的目标是提供一种桥梁,他会为访问者提供一个固定的访问IP地址,用于在访问时重定向到相应的后端,这可以使一些非kubernetes原生应用程序,在无需为kubernetes编写特定代码的前提下轻松访问后端。

注意: service只是在k8s集群内部起作用,集群外部访问是无效的

  • Service可以看作是一组提供相同服务的Pod对外的访问接口。借助Service,应用可以方便地实现服务发现和负载均衡。
  • Service默认只支持4层负载均衡能力,没有7层功能。(可以通过Ingress实现)

2 service的类型

  • ClusterIP:默认值,k8s系统给service自动分配的虚拟IP,只能在集群内部访问。一个Service可能对应多个EndPoint(Pod),client访问的是Cluster IP,通过iptables规则转到Real Server,从而达到负载均衡的效果
  • NodePort:将Service通过指定的Node上的端口暴露给外部,访问任意一个
  • NodeIP:nodePort都将路由到ClusterIP。
  • LoadBalancer:在 NodePort 的基础上,借助 cloud provider 创建一个外部的负载均衡器,并将请求转发到<NodeIP>:NodePort,此模式只能在云服务器上使用。
  • ExternalName:将服务通过 DNS CNAME记录方式转发到指定的域名(通过 spec.externlName 设定)

2 集群内部访问

Service 是由 kube-proxy 组件,加上 iptables 来共同实现的.

## 创建控制器
kubectl create deployment nginx --image=myapp:v1 --replicas=3 
## 暴露服务的80端口
kubectl expose deployment nginx --port=80 
kubectl get pod ## 查看pod的信息
## 查看nginx服务的信息,类型ClusterIP:k8s系统给service自动分配的虚拟IP,只能在集群内部访问
kubectl describe svc nginx 

在这里插入图片描述

  • 查看iptables的规则:iptables -t nat -nL |grep 80,iptables 使用NAT等技术将virtualIP的流量转至endpoint中,容器内暴露的端口是80

在这里插入图片描述

  • kube-proxy 通过 iptables 处理 Service 的过程,需要在宿主机上设置相当多的 iptables规则,如果宿主机有大量的Pod,不断刷新iptables规则,会消耗大量的CPU资源

2.1 IPVS模式的service

IPVS模式的service,可以使K8s集群支持更多量级的Pod

pod和service通信: 通过iptables或ipvs实现通信,ipvs取代不了iptables,因为ipvs只能做负载均衡,而做不了nat转换

(1)开启kube-proxy的ipvs模式

  • 所有节点安装ipvsadm:yum install ipvsadm -y
  • 修改IPVS模式:kubectl edit cm kube-proxy -n kube-system

在这里插入图片描述

  • 更新kube-proxy pod:
kubectl get pod -n kube-system |grep kube-proxy |awk '{system("kubectl delete pod "$1" -n kube-system")}'

在这里插入图片描述

  • IPVS模式下,kube-proxy会在service创建后,在宿主机上添加一个虚拟网卡:kube-ipvs0,并分配service IP

在这里插入图片描述
(3)应用文件:kubectl apply -f demo.yml

---
apiVersion: v1
kind: Service  ## 服务
metadata:
  name: myservice
spec:
  selector:
    app: myapp
  ports:
 - protocol: TCP
    port: 80
    targetPort: 80
---
apiVersion: apps/v1
kind: Deployment  ## 控制器创建pod
metadata:
  name: deployment
spec:
  replicas: 5  ## 副本数
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp:v1
  • 查看服务的信息:kubectl get svc

在这里插入图片描述

  • IPVS模式下,kube-proxy会在service创建后,在宿主机上添加一个虚拟网卡:kube-ipvs0,并分配service IP
    查看IP信息:ip addr

在这里插入图片描述

  • kube-proxy通过IPVS模块,以rr轮询方式调度service中的Pod
    查看当前配置的虚拟服务和各个RS的权重:ipvsadm -ln

在这里插入图片描述

(2)扩容:

  • 编辑文件:vim demo.yml

在这里插入图片描述

  • 应用文件:kubectl apply -f demo.yml,扩容成功

在这里插入图片描述

  • 查看当前配置的虚拟服务和各个RS的权重:ipvsadm -ln
  • 查看指定命名空间pod的详细信息:kubectl -n kube-system get pod -o wide

在这里插入图片描述

  • 查看指定命名空间的服务:kubectl -n kube-system get svc

在这里插入图片描述

  • 进入容器的交互界面:kubectl attach demo -c demo -it,访问服务时是负载均衡的

在这里插入图片描述

2.2 Headless Service

Headless Service不需要分配一个VIP,而是直接以DNS记录的方式解析出被代理Pod的IP地址。

headless使用场景

第一种:自主选择权,client自己来决定使用哪个Real Server,可以通过查询DNS来获取Real Server的信息。

第二种:Headless Service的对应的每一个Endpoints,即每一个Pod,都会有对应的DNS域名;这样Pod之间就能互相访问,集群也能单独访问pod

  • 域名格式:$(servicename).$(namespace).svc.cluster.local

(1)应用文件:kubectl apply -f demo.yml ,修改上面实验中的demo.yml中service的类型为None

clusterIP: None表示是无头service
port: 80  service ip中的端口
targetPort: 80 容器ip中的端口

在这里插入图片描述

  • 查看服务的信息:kubectl get svc

在这里插入图片描述

  • 查看当前配置的虚拟服务和各个RS的权重:ipvsadm -ln

在这里插入图片描述

  • 查看IP的信息:ip addr

在这里插入图片描述

  • 查看服务的详细信息:kubectl describe svc myservice

在这里插入图片描述

  • 查看指定命名空间的服务:kubectl -n kube-system get svc
  • 查看DNS中的A记录:dig -t A myservice.default.svc.cluster.local @10.96.0.10,Real Server的信息

在这里插入图片描述

  • 查看指定服务的信息:kubectl describe -n kube-system svc kube-dns

在这里插入图片描述
(2)测试:在容器中访问myservice服务,是负载均衡的
在这里插入图片描述
在这里插入图片描述
(3)Pod滚动更新后,依然可以解析:

  • 应用文件:kubectl apply -f demo.yml

在这里插入图片描述

  • 进入容器的交互式模式:kubectl attach demo -c demo -it,依然可以通过服务的名字访问服务后端的pod,实现负载均衡

在这里插入图片描述

3 集群外部访问Service

3.1 NodePort方式

Kubernetes 的控制器能保证在任意副本(Pod)挂掉时自动从其他机器启动一个新的,还可以动态扩容等,通俗地说,这个 Pod 可能在任何时刻出现在任何节点上,也可能在任何时刻死在任何节点上;那么自然随着 Pod 的创建和销毁,Pod IP 肯定会动态变化;那么如何把这个动态的 Pod IP 暴露出去?这里借助于 Kubernetes 的 Service 机制,Service 可以以标签的形式选定一组带有指定标签的 Pod,并监控和自动负载他们的 Pod IP,那么我们向外暴露只暴露 Service IP 就行了。

这就是 NodePort 模式:即在每个节点上开起一个端口,然后转发到内部 Pod IP 上
在这里插入图片描述
(1)应用文件:kubectl apply -f demo.yml

  • 将服务的类型设定为NodePort 模式

在这里插入图片描述

  • 查看服务的信息:kubectl get svc,服务的80端口绑定到本机的31010端口

在这里插入图片描述

  • 查看当前配置的虚拟服务和各个RS的权重:ipvsadm -Ln,轮询的方式

在这里插入图片描述

  • 查看IP地址:ip addr

在这里插入图片描述

  • 查看31010端口的服务:netstat -antlp| grep 31010,将服务绑定到本地的31010端口

在这里插入图片描述

(2)测试:curl 172.25.12.2:31010/hostname.html,实现负载均衡

在这里插入图片描述

3.2 ExternalName

从外部访问 Service 的第二种方式

(1)应用文件:kubectl apply -f demo.yml
在这里插入图片描述

  • 查看服务的信息:kubectl get svc,服务的80端口绑定到本地的31199端口,外部访问的IP状态为prending

在这里插入图片描述

  • 查看当前配置的虚拟服务和各个RS的权重:ipvsadm -Ln,轮询的方式

在这里插入图片描述

  • 查看myservice服务的详细信息:kubectl describe svc myservice

在这里插入图片描述

(2)service允许为其分配一个公有IP

  • 重新应用文件:kubectl apply -f demo.yml

在这里插入图片描述

  • 查看服务的信息:kubectl get svc,服务中被分配到外部访问的VIP

在这里插入图片描述
(3)测试:curl 172.25.12.100/hostname.html,能通过外部IP访问,并且实现负载均衡

在这里插入图片描述

4 从内部访问外部

(1)应用文件:kubectl apply -f demo.yml

  • Service 定义将ey-service 服务映射到 www.baidu.com
apiVersion: v1
kind: Service
metadata:
  name: ex-service
spec:
  type:  ExternalName
 clusterIP:Name: www.baidu.com
  • 查看服务信息:kubectl get svc,ex-service服务的EXTERNAL-IP=www.baidu.com

在这里插入图片描述
(2)查看DNS中的A记录:dig -t A ex-service.default.svc.cluster.local @10.96.0.10

当查找主机 ex-service.default.svc.cluster.local 时,群集DNS服务返回 CNAME 记录,其值为www.baidu.com 。 访问 ex-service 的方式与其他服务的方式相同,但主要区别在于重定向发生在 DNS 级别,而不是通过代理或转发

在这里插入图片描述

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在 `kubectl` 命令行工具中,你可以使用 `--help` 参数来查看命令的帮助文档,包括 YAML 文件的格式要求和示例。例如,使用 `kubectl create --help` 命令可以查看如下内容: ``` Create a resource from a file or from stdin. JSON and YAML formats are accepted. Usage: kubectl create (-f FILENAME | --filename=FILENAME) [options] kubectl create (-k DIRECTORY | --kustomize=DIRECTORY) [options] kubectl create clusterrolebinding NAME --clusterrole=ROLE [--user=USER] kubectl create clusterrole NAME --verb=verb --resource=resource.group [--resource-name=resource.name] kubectl create configmap NAME [--from-literal=key1=value1] [--from-literal=key2=value2] [--from-file=[key=]source] [--dry-run=server|client|none] [--output=wide|yaml|json] [options] kubectl create cronjob NAME --image=image [--schedule=''] --command -- [COMMAND] [args...] [options] kubectl create deployment NAME --image=image [--dry-run=server|client|none] [--output=wide|yaml|json] [options] kubectl create job NAME --image=image --command -- [COMMAND] [args...] [options] kubectl create namespace NAME [--dry-run=server|client|none] [--output=wide|yaml|json] [options] kubectl create secret generic NAME [--from-literal=key1=value1] [--from-literal=key2=value2] [--from-file=[key=]source] [--dry-run=server|client|none] [--output=wide|yaml|json] [options] kubectl create service NAME --tcp=port1,port2,... [--dry-run=server|client|none] [--output=wide|yaml|json] [options] kubectl create serviceaccount NAME [--dry-run=server|client|none] [--output=wide|yaml|json] [options] Examples: # Create a pod using the data in pod.json. kubectl create -f ./pod.json # Create a pod based on the JSON passed into stdin. cat pod.json | kubectl create -f - # Edit the data in EDITOR (default vim). kubectl create configmap my-config --from-file=config.json --edit # Create a new namespace named my-namespace kubectl create namespace my-namespace Options: -f, --filename='': Filename, directory, or URL to files to use to create the resource -k, --kustomize='': Process a kustomization directory. This flag can't be used together with -f or -R. --edit=false: Edit the data in $EDITOR --force=false: Create resource even if it already exists --dry-run='none': Must be "none", "server", or "client". If client strategy, only print the object that would be sent, without sending it. If server strategy, submit server-side request without persisting the resource. -o, --output='': Output format. One of: yaml, json, wide, name, go-template-file, go-template, jsonpath-file, jsonpath. If unspecified, will default to yaml for standalone objects and table for lists. --record=false: Record current kubectl command in the resource annotation. If set to false, do not record the command. If set to true, record the command. If not set, default to updating the existing annotation value only if one already exists. ``` 在这个帮助文档中,你可以看到 `kubectl create` 命令支持不同类型的资源对象,包括 Pod、Deployment、Service、Secret 等。对于每个资源对象类型,文档都提供了示例和参数说明。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值