一、资源对象 Service 需求背景

有了Deployment 和 DaemonSet 资源对象为什么还需要定义新的资源对象 Service?

  • 我们在使用Deployment对象中定义服务时,会指定服务Pod 的副本数,然后Kubernetes就会创建指定数量的Pod并提供服务。Pod的数量虽然不会变化,但是因为资源等原因Pod会不断地销毁和重建,所以这个数量的不便其实是动态的平衡。因为Pod的这种变化,导致访问Pod 的IP 也会变化,IP的变化会对服务的访问产生一定的麻烦。于是Service资源对象应运而生,让其他的服务访问Service,由Service来管理请求到具体Pod 的路由。因为这种特点,Service资源对象在集群内部提供了负载均衡的功能;
  • Service 资源对象更加符合微服务架构的思想;

二、在 Yaml 文件中定义资源对象 Service

我们在定义具体的Service资源对象之前,先来定义一个configMap 和一个 Deployment 资源对象。
configMap 资源对象:

apiVersion: v1
kind: ConfigMap
metadata:
  name: test-conf

data:
  default.conf: |
    server {
      listen 80;
      database mysql;
    }

Deployment 资源对象:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: test-dep

spec:
  replicas: 2
  selector:
    matchLabels:
      app: test-dep

  template:
    metadata:
      labels:
        app: test-dep
    spec:
      volumes:
      - name: test-conf-vol
        configMap:
          name: test-conf

      containers:
      - image: nginx:alpine
        name: nginx
        ports:
        - containerPort: 8080

        volumeMounts:
        - mountPath: /etc/nginx/conf.d
          name: test-conf-vol

然后,我们使用如下命令来生成定义Service 资源对象的模版文件,但是注意与之前使用kubectl create 命令不同,此处需要使用的是 kubectl expose 命令:

kubectl expose deploy test-dep --port=8080 --target-port=8080 --dry-run=client -o yaml

生成的 Service 资源对象的Yaml 文件内容如下:

apiVersion: v1
kind: Service
metadata:
  name: test-svc	#该资源对象名
  
spec:	# Service 资源对象的定义有2个关键点:selector,ports
  type: ClusterIP	# 如果不写默认值为ClusterIP,也可填 NodePort
  selector:
    app: test-dep	# 该资源对象用于过滤的标签选择器
    
  ports:
  - port: 8080
    targetPort: 8080
    protocol: TCP

三、Service API 资源对象的操作与使用

我们使用 kubectl apply 命令先后创建 Deployment 资源对象和 Service 资源对象:

kubectl apply -f  test-dep.yaml
kubectl apply -f  test-svc.yaml

使用 kubectl get svc 命令查看Service 资源对象的相关信息,包括Service资源对象的入口IP。

kubectl get svc

使用 kubectl describe svc 命令查看该 Service 资源对象的详细信息,包括管理了哪些Pod路由进行负载均衡。

kubectl describe svc

我们在创建Service 资源对象时如果不具体指定Service 资源对象的type,默认就是clusterIP 这种类型的。clusterIP类型的 Service 资源对象只能在集群内部进行负载均衡,集群外部无法访问,如果要在集群外访问Service 资源对象,那么需要创建 NodePort 类型的Service 资源对象。但是这种类型的Service 资源对象存在下面3个问题:

  • 端口号数量有限。Kubernetes 为了避免端口冲突,默认只能在30000~32767这个区间内随机分配端口号,对于一个大型的服务系统来说不太够用;
  • 有较大的网络压力。每个节点上都要开对应的端口号,然后再通过kube-proxy 再将请求转发到对应的服务上;
  • 安全性。因为它要求向外暴露节点的IP 地址;
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐