跳转至

Service对象

Service对象

当一台虚拟机实例启动后,为了能够从集群外部或内部让其他服务访问该虚拟机,可以通过创建一个Service对象来实现。Service是k8s中一个抽象的概念, 它代表了一个或一组逻辑上的服务器集合,这些服务器被集群中的一个或多个Endpoint对象所标识。 Service对象定义了Service的名称、类型、标签、Selector标签选择器等属性,Selector用于关联Service与一组具有匹配标签的Pod或VirtualMachineInstance; Endpoint对象代表的是Service背后实际提供服务的Pod或VirtualMachineInstance的网络端点(即IP地址+端口),当集群中有Pod或VirtualMachineInstance的标签满足Service的Selector条件时, Kubernetes会自动为该Service创建并管理Endpoints对象,Endpoints就包含这些Pod或VirtualMachineInstance的实际IP和端口信息。

所以,Endpoints不需要手工去指定,而是由Service根据Service对象的Selector标签选择器来自动创建和管理。

Service对象的类型分为ClusterIP、NodePort和LoadBalancer三种。目前kubevirt已支持这3种类型。

以下是3种Service类型对象的创建方式

  • 将 VMI以ClusterIP类型服务对外暴露
    ## 先创建一个VMI
    apiVersion: kubevirt.io/v1
    kind: VirtualMachineInstance
    metadata:
      name: vmi-ephemeral
      labels:
        special: key
    spec:
      domain:
        devices:
          disks:
            - disk:
                bus: virtio
              name: containerdisk
        resources:
          requests:
            memory: 64M
      volumes:
        - name: containerdisk
          containerDisk:
            image: kubevirt/cirros-registry-disk-demo:latest
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: vmiservice
    spec:
      type: ClusterIP
      ports:
        - port: 27017
          protocol: TCP
          targetPort: 22
      selector:
        special: key
    

    也可以使有如下命令来对外暴露服务,服务类型为ClusterIP

    # virtctl expose virtualmachineinstance vmi-ephemeral --name vmiservice --port 27017 --target-port 22
    
    ## 如果 --target-port未设置,则他的值与 --port的值相同。 Cluster IP通常是自动分配的,也可以通过 --cluster-ip来指定。
    

  • 将VMI以NodePort类型服务对外暴露
    apiVersion: v1
    kind: Service
    metadata:
      name: nodeport
    spec:
      externalTrafficPolicy: Cluster
      ports:
      - name: nodeport
        nodePort: 30000
        port: 27017
        protocol: TCP
        targetPort: 22
      selector:
        special: key
      type: NodePort
    

    也可以使有如下命令来对外暴露服务,服务类型为NodePort

    # virtctl expose virtualmachineinstance vmi-ephemeral --name nodeport --type NodePort --port 27017 --target-port 22 --node-port 30000
    
    ## 如果 --node-port未设置,则会自动分配一个nodePort端口。如果指定了 --node-port,则该端口必须全局唯一。
    

  • 将VMI以LoadBalancer类型对外暴露

    以下示例,通过创建LoadBalancer 服务,将 VMI 的 RDP 端口 (3389)暴露出来。 注意 需提前准备一个外部负载均衡器,推荐使用Metallb

    apiVersion: v1
    kind: Service
    metadata:
      name: lbsvc
    spec:
      externalTrafficPolicy: Cluster
      ports:
      - port: 27017
        protocol: TCP
        targetPort: 3389
      selector:
        special: key
      type: LoadBalancer
    
    # virtctl expose virtualmachineinstance vmi-ephemeral --name lbsvc --type LoadBalancer --port 27017 --target-port 3389