(1). Service

Service主要提供Pod的关联以及路由和负载均衡等功能.

(2). Service YAML的定义

定义Service

apiVersion: v1
kind: Service   # 定义一个Service
metadata:
  labels:
    app: hello-world    # Service自己的元数据信息
  name: hello-world
spec:
  ports:
  - port: 9090
    protocol: TCP
    targetPort: 9090
  selector:
    app: hello-world      # 重点:Service通过该配置关联Pod的资源
  type: NodePort

定义Pod

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: hello-world
  name: hello-world
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello-world
  template:
    metadata:
      labels:
        app: hello-world    #Service与Pod关联的名称
    spec:
      containers:
      - image: lixinhelp/hello:2.0.0-SNAPSHOT
        name: hello

(3). Service类型

  1. ClusterIP
  2. NodPort
  3. LoadBalancer

(4). ClusterIP

ClusterIP主要为集群内部访问而使用的. 每当创建一个Service就会产生一个ClusterIP(类似于VIP).以供集群内部访问.

(5). NodPort

NodPort是在每个Node(宿主机)上,去随机创建一个端口(Port)并监听(同时会创建:CLUSTER-IP). 当访问NodeIP+Port就能转发到Pod上(在Node上有相应的iptables规则,所以是:iptables帮你实现了转发,看起来像是负载均衡).
缺陷:当有多个Node时,用户需要知道:多个NodeIP+Port.对用户不友好.
解决方案:每创建一个Service,就把NodeIP+Port增加到Nginx里.通过Nginx来实现负载均衡.

(6). LoadBalancer

LoadBalancer解决了NodPort的痛点,每创建一个Service开辟的端口(包含如下端口:CLUSTER-IP+PORT/Node+Port),都会自动的将这些信息增加到LoadBalance中.
注意:该功能仅限于一些公有云使用.

(7). Service模板生成

# 查看deploy的名称
[root@master ~]# kubectl get deploy
NAME          READY   UP-TO-DATE   AVAILABLE   AGE
hello-world   2/2     2            2           30h


# 通过export生成service配置文件.
# hello-world要与上面deploy的名称相同
# --port              : 集群内部容器通信端口
# --target-port       : 应用程序(Dockerfile)暴露(EXPOSE)的端口
# --type=NodePort     : NodePort会创建CLUSTER-IP并随机生成端口
# -o                  : 生成YAML格式的文件
# --dry-run           : 尝试运行(并不是真正的运行)
[root@master ~]# kubectl expose deployment hello-world --port=9090 --target-port=9090  --type=NodePort -o yaml --dry-run > hello-world-expose.yml


# 应用配置
[root@master ~]# kubectl apply -f hello-world-expose.yml
service/hello-world created 

(8). 案例

每创建一个Service时,都会创建:CLUSTER-IP.
如果创建Service指定为:NodePort,能看到创建了两个端口:
一个端口是CLUSTER-IP端口,另一个端口中是NodePort(宿主机)端口.

# 查看指定namespace下的:service
[root@master ~]# kubectl get svc -n kube-system
NAME                   TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                  AGE
kube-dns               ClusterIP   10.1.0.10      <none>        53/UDP,53/TCP,9153/TCP   4d5h
kubernetes-dashboard   NodePort    10.1.167.148   <none>        443:30001/TCP            4d3h


# hello-world 对应的集群IP为:10.1.232.6
# 当是NodePort时,会有两上端口,一个是ClusterIP端口,一个是NodePort端口(在宿主机上端口).
# [root@master ~]# kubectl get svc -n default
[root@master ~]# kubectl get svc
NAME          TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)          AGE
hello-world   NodePort    10.1.232.6   <none>        9090:31355/TCP   28h
kubernetes    ClusterIP   10.1.0.1     <none>        443/TCP          4d5h

# 通过集群IP直接访问
[root@master ~]# curl http://10.1.232.6:9090/hello
	Hello World-3.0.0-SNAPSHOT!!!test-hello


# 通过Node+Port访问
lixin-macbook:~ lixin$ curl http://10.211.55.100:31355/hello
Hello World-3.0.0-SNAPSHOT!!!test-hello
lixin-macbook:~ lixin$ curl http://10.211.55.101:31355/hello
Hello World-3.0.0-SNAPSHOT!!!test-hello
lixin-macbook:~ lixin$ curl http://10.211.55.102:31355/hello
Hello World-3.0.0-SNAPSHOT!!!test-hello