目 录CONTENT

文章目录

k8s | 深入理解资源对象 service

如风
2023-07-17 / 0 评论 / 0 点赞 / 26 阅读 / 1,736 字

k8s | 深入理解资源对象 service

继续将 k8s 比喻成一个大公司,Service 就像是一名重要的客服代表,它的职责是帮助内部员工(Pods)提供服务,以满足外部客户(应用程序或用户)的需求。

出现原因

service 出现是为了解决什么问题呢?

Service 的主要目的是解决内部服务的稳定性和可访问性问题,为外部客户提供一个稳定的入口,使他们可以方便地访问到所需的服务。Service 为每个服务分配一个虚拟的固定 IP 地址,并通过这个 IP 地址代表后端的员工(Pods)。即使员工(Pods)发生变化,Service 会自动更新后端的员工列表,确保客户始终能够找到所需的服务

Pod是不稳定的,IP是会变化的,所以需要一层抽象来屏蔽这种变化,这层抽象叫做Service

四种类型

  • Cluster IP: 默认类型,给集群内部每个pod 分配一个虚拟ip

  • NodePort:在Cluster IP的基础上为 Service在每个节点绑定一个端口,这样就可以通过 NodeIP:NodePort 来访问服务

    apiVersion: v1
    kind: Service
    metadata:
      name: test-service
    spec:
      selector:
        app: test
      type: NodePort # 指定service 类型
      ports:
      - protocol: TCP
        port: 80
        targetPort: 80
        name: test-http
        nodePort: 30000 # 范围:30000-32767
    

    master 将从给定的配置范围内(默认:30000-32767)分配端口, 每个 Node 将从该端口(每个 Node 上的同一端口)代理到 Service,如果不指定的话会自动生成一个端口。

  • LoadBalance:在 NodePort 的基础上,借助 cloud provider 创建一个使用云提供商的负载局衡器,可以向外部暴露服务。并将请求转发到 <NodeIP>:NodePort

  • ExternalName:将服务通过 DNS CNAME 记录方式转发到指定的域名(通过 spec.externlName 设定)

    ​ 当一个 Service 的类型被设置为 ExternalName 时,它并不代表内部的员工(Pods),而是为一个外部服务提供一个别名。

    这个别名就像是一个联系人名单,告诉公司的员工:如果需要特定的服务,可以通过这个别名来访问。ExternalName 类型的 Service 并不会分配外部 IP 地址,而是直接返回一个 CNAME 记录,指向外部服务的域名

    ​ 假设有一个外部的数据库服务,它的域名是 external-db.example.com,集群内部可以通过一个别名 my-db 来访问这个外部服务。

    我们可以通过以下 YAML 配置文件来创建一个 ExternalName 类型的 Service

    apiVersion: v1
    kind: Service
    metadata:
      name: my-db
    spec:
      type: ExternalName
      externalName: external-db.example.com
    
    

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

Service的用法

定义

通过 yaml 或者 json 来定义。属性解释

apiVersion: v1 # 版本
kind: Service # 类型
metadata: #元数据 类型string
  name: test #Service名称 类型string
  namespace: test #命名空间,不指定时默认为default命名空间
  labels: #自定义标签属性列表 类型string     
    - name: string 
  annotations: #自定义注解属性列表    
    - name: string
spec: #详细描述 类型list[]
  selector: [] #Label Selector配置,选择具有指定label标签的pod作为管理范围
  type: string #service的类型,指定service的访问方式,默认ClusterIP
               #ClusterIP:虚拟的服务ip地址,用于k8s集群内部的pod访问,在Node上kube-porxy通过设置的iptables规则进行转发
               #NodePort:使用宿主机端口,能够访问各Node的外部客户端通过Node的IP和端口就能访问服务器
               #LoadBalancer:使用外部负载均衡器完成到服务器的负载分发,
               #需要在spec.status.loadBalancer字段指定外部负载均衡服务器的IP,并同时定义nodePort和clusterIP用于公有云环境。
  clusterIP: string  #虚拟服务IP地址,当type=ClusterIP时,如不指定,则系统会自动进行分配,也可以手动指定。当type=loadBalancer,需要指定
  sessionAffinity: string  #是否支持session,可选值为ClietIP,默认值为空,ClientIP表示将同一个客户端(根据客户端IP地址决定)的访问请求都转发到同一个后端Pod
  ports: #service需要暴露的端口列表    
  - name: string #端口名称 类型string
    protocol: TCP  #端口协议,支持TCP或UDP,默认TCP 类型string
     port: 80 #服务监听的端口号 类型int
     targetPort: 8080 #需要转发到后端的端口号 类型int
     nodePort: 8080 #当type=NodePort时,指定映射到物理机的端口号 类型:int
  status: #当type=LoadBalancer时,设置外部负载均衡的地址,用于公有云环境    
    loadBalancer: #外部负载均衡器    
      ingress: #外部负载均衡器 
      ip: string #外部负载均衡器的IP地址
      hostname: string #外部负载均衡器的机主机

常用指令

  1. 创建service

    通过配置文件

    kubectl apply -f service.yaml
    

    通过命令

    kubectl create service <service-type> <service-name> --tcp=<port>
    

    这个指令可以创建一个新的 Service,并将其与指定的 Deployment 或 Pod 关联

  2. 查看service 详情

    # 列出当前命名空间中所有的 Service,并显示它们的名称、类型、Cluster IP、外部 IP 等信息
    kubectl get services
    
    # 查看指定 Service 的详细信息,包括关联的 Pod、端口配置、Selector 等信息
    kubectl describe service <service-name>
    
    
  3. 删除或者编辑service

    kubectl delete service <service-name>
    kubectl edit service <service-name>
    
  4. 暴露 Deployment/Pod 为 Service

    kubectl expose <resource-type> <resource-name> --type=<service-type> --port=<port> --target-port=<target-port>
    

    这个指令可以将指定的 Deployment 或 Pod 暴露为一个新的 Service,需要指定 Service 的类型、要暴露的端口和目标端口。

    例如:

    kubectl expose deployment my-app --type=NodePort --port=80 --target-port=8080
    # 这个命令将 my-app Deployment 暴露为一个类型为 NodePort 的 Service。这样,Kubernetes 就会在集群的每个节点上分配一个随机的端口(NodePort),并将这个端口映射到后端 Pod 的端口 8080。
    
  5. 端口转发

    kubectl port-forward <pod-name> <local-port>:<pod-port>
    

    将本地端口与指定 Pod 的端口进行转发,使得可以直接访问 Pod 的服务

    例如:

    # 这个命令将本地主机的端口 8888 绑定到 Pod my-pod 内部的端口 8080。现在,我们可以在本地浏览器中访问 http://localhost:8888,就可以直接访问 Pod 内部运行的 Web 应用程序
    kubectl port-forward my-pod 8888:8080
    
    
0

评论区