写点什么

云原生(二十) | Kubernetes 篇】深入了解 Kubernetes(k8s)Service

作者:Lansonli
  • 2022 年 8 月 18 日
    广东
  • 本文字数:2781 字

    阅读完需:约 9 分钟

云原生(二十) | Kubernetes篇】深入了解Kubernetes(k8s)Service

深入了解 Kubernetes(k8s)Service

一、基础概念

将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法。



  • ClusterIP :通过集群的内部 IP 暴露服务,选择该值时服务只能够在集群内部访问。 这也是默认的 ServiceType

  • NodePort :通过每个节点上的 IP 和静态端口( NodePort )暴露服务。 NodePort 服务会路由到自动创建的 ClusterIP 服务。 通过请求 <节点 IP>:<节点端口> ,你可以从集群的外部访问一个 NodePort 服务。

  • LoadBalancer :使用云提供商的负载均衡器向外部暴露服务。 外部负载均衡器可以将流量路由到自动创建的 NodePort 服务和 ClusterIP 服务上。

  • ExternalName :通过返回 CNAME 和对应值,可以将服务映射到 externalName 字段的内容(例如, foo.bar.example.com )。 无需创建任何类型代理。

1、创建简单 Service

apiVersion: v1kind: Servicemetadata:  name: my-servicespec:  selector:    app: MyApp ## 使用选择器选择所有Pod# type: ClusterIP ##type很重要,不写默认是ClusterIP  ports:    - protocol: TCP      port: 80      targetPort: 9376
复制代码


  • Service 创建完成后,会对应一组 EndPoint。可以 kubectl get ep 进行查看

  • type 有四种,每种对应不同服务发现机制

  • Servvice 可以利用 Pod 的就绪探针机制,只负载就绪了的 Pod。自动剔除没有就绪的 Pod


2、创建无 Selector 的 Service

  • 我们可以创建 Service 不指定 Selector

  • 然后手动创建 EndPoint,指定一组 Pod 地址

  • 此场景用于我们负载均衡其他中间件场景

# 无selector的svc apiVersion: v1 kind: Service metadata:   name: my-service-no-selector spec:   ports:  - protocol: TCP     name: http ###一定注意,name可以不写,     ###但是这里如果写了name,那么endpoint里面的ports必须有同名name才能绑定     port: 80 # service 80     targetPort: 80 #目标80---apiVersion: v1 kind: Endpoints metadata:   name: my-service-no-selector ### ep和svc的绑定规则是:和svc同名同名称空间,port同名 或同端口   namespace: default subsets:  - addresses:    - ip: 220.181.38.148    - ip: 39.156.69.79    - ip: 192.168.169.165     ports:    - port: 80       name: http ## svc有name这里一定要有       protocol: TCP
复制代码

原理:kube-proxy 在负责这个事情

## 实验 apiVersion: v1 kind: Service metadata:   name: cluster-service-no-selector   namespace: default spec:   ## 不选中Pod而在下面手动定义可以访问的EndPoint   type: ClusterIP   ports:  - name: abc     port: 80 ## 访问当前service 的 80     targetPort: 80 ## 派发到Pod的 80---apiVersion: v1 kind: Endpoints metadata:   name: cluster-service-no-selector ## 和service同名   namespace: default subsets:- addresses:  - ip: 192.168.169.184  - ip: 192.168.169.165  - ip: 39.156.69.79   ports:  - name: abc ## ep和service要是一样的     port: 80     protocol: TCP
复制代码

场景:Pod 要访问 MySQL。 MySQL 单独部署到很多机器,每次记 ip 麻烦

### 集群内创建一个 Service,实时的可以剔除 EP 信息。反向代理集群外的东西。


二、ClusterIP

type: ClusterIP ClusterIP: 手动指定/None/""
复制代码


  • 手动指定的 ClusterIP 必须在合法范围内

  • None 会创建出没有 ClusterIP 的 headless service(无头服务),Pod 需要用服务的域名访问

三、NodePort

apiVersion: v1kind: Servicemetadata:  name: my-service  namespace: defaulttype: NodePortports:  - protocol: TCP    port: 80 # service 80    targetPort: 80 #目标80    nodePort: 32123 #自定义
复制代码


  • 如果将 type 字段设置为 NodePort ,则 Kubernetes 将在 --service-node-port-range 标志指定的范围内分配端口(默认值:30000-32767)

  • k8s 集群的所有机器都将打开监听这个端口的数据,访问任何一个机器,都可以访问这个 service 对应的 Pod

  • 使用 nodePort 自定义端口

四、ExternalName

apiVersion: v1 kind: Service metadata:   name: my-service-05   namespace: default spec:   type: ExternalName   externalName: baidu.com
复制代码


  • 其他的 Pod 可以通过访问这个 service 而访问其他的域名服务

  • 但是需要注意目标服务的跨域问题


五、LoadBalancer

apiVersion: v1 kind: Service metadata:   creationTimestamp: null   labels:     app.kubernetes.io/name: load-balancer-example   name: my-service spec:   ports:  - port: 80     protocol: TCP     targetPort: 80selector:   app.kubernetes.io/name: load-balancer-example type: LoadBalancer
复制代码


六、扩展 - externalIP

在 Service 的定义中, externalIPs 可以和任何类型的 .spec.type 一通使用。在下面的例子中,客户端可通过 80.11.12.10:80 (externalIP:port) 访问 my-service

apiVersion: v1 kind: Service metadata:   name: my-service-externalip spec:   selector:     app: canary-nginx   ports:    - name: http       protocol: TCP       port: 80       targetPort: 80   externalIPs: ### 定义只有externalIPs指定的地址才可以访问这个service    - 10.170.0.111
复制代码

​​

七、扩展 - Pod 的 DNS

apiVersion: v1 kind: Service metadata:   name: default-subdomain spec:   selector:     name: busybox   clusterIP: None   ports:  - name: foo # 实际上不需要指定端口号     port: 1234     targetPort: 1234---apiVersion: v1 kind: Pod metadata:   name: busybox1   labels:     name: busybox spec:   hostname: busybox-1  subdomain: default-subdomain## 指定必须和svc名称一样,才可以 podName.subdomain.名称空间.svc.cluster.local访问。否 则访问不同指定Pod containers:- image: busybox:1.28   command:    - sleep    - "3600"   name: busybox---apiVersion: v1 kind: Pod metadata:   name: busybox2   labels:     name: busybox spec:   hostname: busybox-2  subdomain: default-subdomain   containers:  - image: busybox:1.28     command:      - sleep      - "3600"     name: busybox
复制代码


  • 访问 busybox-1. default-subdomain .default. svc.cluster.local 可以访问到 busybox-1。

  • 访问 Service

          同名称空间

                  ping service-name 即可

          不同名称空间

                  ping service-name.namespace 即可

  • 访问 Pod

         同名称空间

                  ping pod-host-name.service-name 即可

         不同名称空间

                  ping pod-host-name.service-name.namespace 即可

发布于: 刚刚阅读数: 3
用户头像

Lansonli

关注

微信公众号:三帮大数据 2022.07.12 加入

CSDN大数据领域博客专家,华为云享专家、阿里云专家博主、腾云先锋(TDP)核心成员、51CTO专家博主,全网六万多粉丝,知名互联网公司大数据高级开发工程师

评论

发布
暂无评论
云原生(二十) | Kubernetes篇】深入了解Kubernetes(k8s)Service_云原生_Lansonli_InfoQ写作社区