kubernetes 的Service

Service概念:

Kubernetes中的 Pod是有生命周期的,它们可以被创建,也可以被销毁,然而一旦被销毁pod生命就永远结束,这个pod就不存在了,通过ReplicaSets能够动态地创建和销毁Pod(例如,需要进行扩缩容,或者执行滚动升级),每个Pod都会获取它自己的 IP 地址,这些IP地址并不是一直处于稳定的状态,可能随时改变。  Kubernetes 集群中,如果一组Pod(称为 backend)为其它Pod (称为 frontend)提供服务,那么那些 frontend(pod) 通过设置的标签来绑定service,进而对外提供网络服务

关于Service

Kubernetes Service定义了这样一种抽象:逻辑上的一组Pod,一种可以访问它们的策略-通常称为微服务。 这一组Pod能够被Service访问到,通常是通过Label Selector实现的。举个例子,考虑一个图片处理程序 backend,它运行了3个副本。这些副本是可互换的 —— frontend 不需要关心它们调用了哪个 backend 副本。 然而组成这一组 backend 程序的 Pod 实际上可能会发生变化,frontend 客户端不应该也没必要知道,而且也不需要跟踪这一组 backend 的状态。 Service 定义的抽象能够解耦这种关联。

例如想要用nginx反向代理tomcat,那么tomcat如果是通过pod部署的,pod的ip可能会随时变化,那么我们就需要在所有这些部署tomcat的pod前面加上一个固定接入层service,我们nginx反向代理只需要写service地址,就会代理到后端的pod,那么pod就算ip怎么变化,通过service都可以找到, Kubernetes 集群中的应用,Kubernetes 提供了简单的Endpoints API,只要Service中的一组Pod发生变更,应用程序就会被更新。 对非 Kubernetes 集群中的应用,Kubernetes 提供了基于 VIP 的网桥的方式访问Service,再Service重定向到backend Pod。

简单归纳一下

service是一个固定接入层,客户端可以通过访问service来访问到service关联的后端pod,这个service工作依赖于在kubernetes集群之上部署的一个附件,就是kubernetes的dns服务(不同kubernetes版本的dns默认使用的也是不一样的,1.11之前的版本使用的是kubeDNs,较新的版本使用的是coredns),service的名称解析是依赖于dns附件的,因此在部署完k8s之后需要在部署dns附件,kubernetes要想给客户端提供网络功能,需要依赖第三方的网络插件(flannel,calico等)。

kubernetes集群中有三类ip地址:node network(节点网络),pod network(pod 网络),这两种网络地址是我们实实在在配置的,其中节点网络地址是配置在节点接口之上,而pod网络地址是配置在pod资源之上的,因此这些地址都是配置在某些设备之上的,这些设备可能是硬件,也可能是软件模拟的,cluster network(集群地址,也成为service network),这个地址是虚拟的地址(virtual ip),没有配置在某个接口上,只是出现在service的规则当中。

每个K8s节点上都有一个工作的组件叫做kube-proxy,kube-proxy这个组件将始终监视着apiserver中有关service资源的变动信息,需要跟master之上的apiserver交互,随时连接到apiserver上获取任何一个与service资源相关的资源变动状态,这种是通过kubernetes中固有的一种请求方法watch(监视)来实现的,一旦有service资源的内容发生变动(如创建,删除),kube-proxy都会将它转化成当前节点之上的能够实现service资源调度,把我们请求调度到后端特定的pod资源之上的规则,这个规则可能是iptables,也可能是ipvs,取决于service的实现方式

service实现方式

种:iptables

客户端ip请求时直接请求service的ip,这个请求报文被本地内核空间中的service规则所截取,进而直接调度给相关的pod,这个方式是直接工作在内核空间,由iptables规则直接实现

种:ipvs

客户端请求到达内核空间之后直接由ipvs规则来调度到相关的pod资源

1.11之前的版本使用的是iptables

1.11+版本使用的是ipvs,ipvs如果没有被激活就会自动降级为iptables

如果某个服务背后的pod资源发生改变,比如service的标签选择器适用的pod又多了一个,这个pod使用的信息会立即反应在apiserver上,kube-proxy能监听到这个service的变化,将其立即转为service规则(如iptables规则)

编写server yaml 文件

 

[root@master-1 kongzhiqi]# cat deployment.yaml 
apiVersion: apps/v1  #api版本
kind: Deployment   #资源类型
metadata:   #源数据
  name: deployment   #控制器名字
  namespace: deployment  # 所在的名称空间
  labels: # 标签的设置
    dev: deployment-test
spec: # 控制器期望状态
  minReadySeconds: 4 # 等待就绪时间
  revisionHistoryLimit: 5 # 保留的历史版本
  replicas: 3 # pod 个数
  strategy: # 更新策略
    rollingUpdate: # 选择更新方式
      maxSurge: 5 # 最大的pod 数量比pod个数多
      maxUnavailable: 1 # 最大不可用的pod 数量
  selector: # 标签选择器
    matchLabels: # 标签选择器设定
      dev: deployment-test # 标签的key与值的设定
  template: # pod 属性定义
    metadata: # 元数据
      labels: # 标签设定
        dev: deployment-test # 标签的key 与值
    spec: # pod 的期望状态
      containers: # 容器的属性定义
      - name: web  # 容器的名字
        image: nginx:1.8.1 # 运行的镜像
        imagePullPolicy: IfNotPresent   # 获取镜像策略
        ports: # 端口设置
        - name: web # 端口的名字
          containerPort: 80 # 容器的端口
        livenessProbe: # 存活性探测属性设置
          httpGet:  # 探测类型
            port: web  # 探测的端口
            path: index.html  # 探测的url
          initialDelaySeconds: 5 # 容器里进程初始化时间等待探测时间
          periodSeconds: 5 # 探测周期
          timeoutSeconds: 2 #探测超时时间
          failureThreshold: 3  # 探测连续失败的最大次数
        readinessProbe: # 就绪性探测
          httpGet:  # 探测的钩子
            port: web # 探测的端 口
            path: index.html #探测的url
          initialDelaySeconds: 5 # 容器里进程初始化时间等待探测时间
          periodSeconds: 5 # 探测周期
          timeoutSeconds: 2 #探测超时时间
          failureThreshold: 3  # 探测连续失败的最大次数



vim service.yaml 

apiVersion: v1 #api版本
kind: Service # 资源类型
metadata:  # 元数据
  name: deployment-service # service 的名字
  namespace: deployment # 名称空间
  labels: # 设置标签属性
    dev: dev-service 
spec: #期望状态
  selector: # 绑定拥有以下标签的pod
    dev: deployment-test
  ports: # 端口设置
  - name: dev-chenxi # 名字
    nodePort: 30880 # node 暴漏的端口;如果不写默认随机
    port: 80 # 集群内部暴漏的端口,必写字段
    protocol: TCP # 协议 支持"TCP", "UDP", and "SCTP",默认TCP
    targetPort: web # 绑定的端口支持名字
  type: NodePort # 暴露的类型支持ExternalName、ClusterIP、NodePort 和 LoadBalancer。“ClusterIP”为负载均衡分配集群内部 IP 地址“NodePort”建立在 ClusterIP 之上,并在每个节点上分配一个端口路由到与 clusterIP 相
同的端点。“LoadBalancer”建立在NodePort 并创建一个外部负载均衡器(如果当前支持cloud) 路由到与 clusterIP 相同的端点。 “外部名称”将此服务别名为指定的externalName。 其他几个领域不适用于 ExternalName 服务

  运行service

[root@master-1 kongzhiqi]# kubectl apply -f service.yaml 
service/deployment-service created
[root@master-1 kongzhiqi]# kubectl get svc -n deployment
NAME                 TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
deployment-service   NodePort   10.10.198.163   <none>        80:30880/TCP   3s
[root@master-1 kongzhiqi]# kubectl describe svc -n deployment 
Name:                     deployment-service
Namespace:                deployment
Labels:                   dev=dev-service
Annotations:              <none>
Selector:                 dev=deployment-test
Type:                     NodePort
IP Families:              <none>
IP:                       10.10.198.163
IPs:                      10.10.198.163
Port:                     dev-chenxi  80/TCP
TargetPort:               web/TCP
NodePort:                 dev-chenxi  30880/TCP
Endpoints:                10.244.84.163:80,10.244.84.164:80,10.244.84.165:80
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

  访问node:30880

 

 noselector 类型的service

[root@master-1 service]# cat noselector-service.yaml 
apiVersion: v1
kind: Service
metadata: 
  name: my-cx-1
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 3306
[root@master-1 service]# cat endpoints.yaml 
apiVersion: v1
kind: Endpoints
metadata: 
  name: my-cx-1 # 注意名字与service 一致
subsets:
- addresses: 
  - ip: 1.2.3.4
  ports:
  - port: 3306
kubectl apply -f noselector-service.yaml 
kubectl apply -f endpoints.yaml 
[root@master-1 service]# kubectl get endpoints
NAME         ENDPOINTS                                                  AGE
kubernetes   192.168.10.29:6443,192.168.10.30:6443,192.168.10.31:6443   2d
my-chenxi    172.16.84.131:80,172.16.84.132:80                          12s
my-cx-1      1.2.3.4:3306                                               6m32s

[root@master-1 service]# kubectl describe svc my-cx-1 
Name:              my-cx-1
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          <none>
Type:              ClusterIP
IP Families:       <none>
IP:                10.255.154.164
IPs:               10.255.154.164
Port:              <unset>  80/TCP
TargetPort:        3306/TCP
Endpoints:         1.2.3.4:3306
Session Affinity:  None
Events:            <none>

 externalname service 格式

[root@master-1 service]# kubectl create namespace cx
namespace/cx created
[root@master-1 deployment]# cat externalname.yaml 
apiVersion: v1
kind: Service
metadata: 
  name: my-cx-2
  namespace: cx
spec:
  type: ExternalName
  externalName: www.baidu.com #返回的 域名
  
访问格式
name.namespace.svc.cluster.local

  无头service

[root@master-1 service]# cat service_2.yaml 
apiVersion: v1
kind: Service
metadata:
  name: my-chenxi-2
spec:
  clusterIP: 'None'
  ports:
  - port: 80
    protocol: TCP
  selector:
    run: my-cx-2
[root@master-1 service]# kubectl get ep
NAME          ENDPOINTS                                                  AGE
kubernetes    192.168.10.29:6443,192.168.10.30:6443,192.168.10.31:6443   2d2h
my-chenxi     172.16.84.131:80,172.16.84.132:80                          79m
my-chenxi-2   <none>                                                     9m19s
my-cx-1       1.2.3.4:3306                                               85m

  

 

 

posted @ 2022-08-17 16:05  烟雨楼台,行云流水  阅读(114)  评论(0编辑  收藏  举报