k8s-Service

k8s-Service

一 service概念

Kubernetes  Service 定义了这样一种抽象:一个 Pod 的逻辑分组,一种可以访问它们的策略 —— 通常称为微

服务。 这一组 Pod 能够被 Service 访问到,通常是通过 Label Selecto

Service能够提供负载均衡的能力,但是在使用上有以下限制:

只提供 4 层负载均衡能力,而没有 7 层功能,但有时我们可能需要更多的匹配规则来转发请求,这点上 4 层

负载均衡是不支持的

二 servce类型

Service 在 K8s 中有以下四种类型

  • ClusterIp:默认类型,自动分配一个仅 Cluster 内部可以访问的虚拟 IP

  • NodePort:在 ClusterIP 基础上为 Service 在每台机器上绑定一个端口,这样就可以通过 : NodePort 来访问该服务

  • LoadBalancer:在 NodePort 的基础上,借助 cloud provider(云供应商,收费的) 创建一个外部负载均衡器,并将请求转发到: NodePort

  • ExternalName:把集群外部的服务引入到集群内部来,在集群内部直接使用。没有任何类型代理被创建,这只有 kubernetes 1.7 或更高版本的 kube-dns 才支持

2.1 clusterip

2.1.1 概念

clusterIP 主要在每个 node 节点使用 iptables,将发向 clusterIP 对应端口的数据,转发到 kube-proxy 中。然后 kube-proxy 自己内部实现有负载均衡的方法,并可以查询到这个 service 下对应 pod 的地址和端口,进而把数据转发给对应的 pod 的地址和端口

大致架构:

svc如何和后端pod通信,是通过后端pod的标签等信息

2.2.2 实例

创建三个pod

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deploy
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
      release: stabel
  template:
    metadata:
      labels:
        app: myapp
        release: stabel
        env: test
    spec:
      containers:
      - name: myapp
        image: wangyanglinux/myapp:v2
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          containerPort: 80

开启svc clusterip

apiVersion: v1
kind: Service
metadata:
  name: myapp
  namespace: default
spec:
  type: ClusterIP
  selector:
    app: myapp
    release: stabel
  ports:
  - name: http
    port: 80
    targetPort: 80

查看cluseterip

[root@k8s-master01 yaml]# kubectl get svc
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP   7h8m
myapp        ClusterIP   10.99.48.182   <none>        80/TCP    8m14s

访问 10.99.48.182 下面绑定了三个pod的ip

2.2.3 无头服务(headless service)

headless service也属于clausterip的一种,不会分配clusterip,也不会进行负载和路由

apiVersion: v1
kind: Service
metadata:
  name: nginx-service 
  labels:
    app: nginx
spec:
  selector:
    app: nginx
  clusterIP: "None"
  ports:
  - port: 80
    targetPort: 80

2.2 nodeport

nodePort 的原理在于在 node 上开了一个端口,将向该端口的流量导入到 kube-proxy,然后由 kube-proxy 进一步到给对应的 pod

实例:

apiVersion: v1
kind: Service
metadata:
  name: myapp
  namespace: default
spec:
  type: NodePort
  selector:
    app: myapp
    release: stabel
  ports:
  - name: http
    port: 80
    targetPort: 80

2.3 ExternalName

这种类型的 Service 通过返回 CNAME 和它的值,可以将服务映射到 externalName 字段的内容( 例如:

hub.atguigu.com )。ExternalName Service 是 Service 的特例,它没有 selector,也没有定义任何的端口和

Endpoint。相反的,对于运行在集群外部的服务,它通过返回该外部服务的别名这种方式来提供服务

实例;

apiVersion: v1
kind: Service
metadata:
  name: myapp-headless
  namespace: default
spec:
  selector:
    app: myapp
  clusterIP: "None"
  ports:
  - port: 80
    targetPort: 80

查看:

验证:

dig -t A my-service-1.default.svc.cluster.local. @10.244.2.9

dig -t A my-service-1.default.svc.cluster.local. @10.244.2.9

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-9.P2.el7 <<>> -t A my-service-1.default.svc.cluster.local. @10.244.2.9
;; global options: +cmd
;; Got answer:
;; WARNING: .local is reserved for Multicast DNS
;; You are currently testing what happens when an mDNS query is leaked to DNS
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 36528
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;my-service-1.default.svc.cluster.local.	IN A

;; ANSWER SECTION:
my-service-1.default.svc.cluster.local.	30 IN CNAME hub.atguigu.com.

;; Query time: 36 msec
;; SERVER: 10.244.2.9#53(10.244.2.9)
;; WHEN: 二 3月 17 21:13:47 CST 2020
;; MSG SIZE  rcvd: 134

三 注意

svc必须和pod在同一个命名空间里面,否则不会自动绑定

### 服务发现注册原理 在Kubernetesk8s)环境中,服务通过`service.yaml`文件以`spring - k8s - service`进行服务发现注册,其原理基于k8s的核心组件和机制。k8s内部使用ETCD服务维护这些信息的变化,并且Service已经解决了Pod的注册与发现的问题,也实现了负载均衡[^1]。 当创建一个`service.yaml`文件并应用到k8s集群时,k8s会根据文件中的定义创建一个Service资源对象。该文件通常包含服务的名称(如`spring - k8s - service`)、服务类型、选择器等信息。示例的`service.yaml`文件如下: ```yaml apiVersion: v1 kind: Service metadata: name: spring-k8s-service spec: selector: app: spring-app ports: - protocol: TCP port: 80 targetPort: 8080 type: ClusterIP ``` 在这个示例中,`selector`字段指定了该服务会选择带有`app: spring-app`标签的Pod。k8s会根据这个选择器,自动发现并关联所有匹配标签的Pod。当有新的Pod创建或现有Pod销毁时,k8s会更新Service的后端Pod列表,这个过程是由k8s的控制器管理器和kube - proxy组件共同完成的。控制器管理器负责监控资源的变化,而kube - proxy则负责在节点上实现网络规则,确保对Service的访问能够正确路由到后端的Pod。 ### 其他服务调用 其他服务可以根据`spring - k8s - service`调用找到对应服务。在k8s集群内部,每个Service都有一个唯一的DNS名称,默认格式为`<service-name>.<namespace>.svc.cluster.local`。如果服务都在同一个命名空间下,可以直接使用服务名`spring - k8s - service`进行访问。 在Spring项目中,可以使用`RestTemplate`或`WebClient`等工具来发起对服务的调用。示例代码如下: ```java import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; @RestController public class AnotherServiceController { private final RestTemplate restTemplate; public AnotherServiceController(RestTemplate restTemplate) { this.restTemplate = restTemplate; } @GetMapping("/call-spring-k8s-service") public String callSpringK8sService() { String url = "http://spring-k8s-service/hello"; return restTemplate.getForObject(url, String.class); } } ``` 当发起对`spring - k8s - service`的调用时,k8s的kube - proxy会根据其维护的网络规则,将请求负载均衡到后端的Pod上。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值