Kubernetes系列之五:使用yaml文件创建service向外暴露服务

释放双眼,带上耳机,听听看~!

Service和Pod的理论介绍,方便继续下去

Pod是有生命周期的,使用凡人皆有一死来描述pod很贴切,当一个工作节点(node)销毁时,节点上运行的pods也会被销毁, ReplicationController会动态地在其他节点上创建Pod来保持应用程序的运行,每一个Pod都有一个独立的IP地址,甚至是同一个节点上的Pod,可以看出Pod的IP是动态的,它随Pod的创建而创建,随Pod的销毁而消失,这就引出一个问题:如果由一组Pods组合而成的集群来提供服务,那如何访问这些Pods呢?

Kubenetes的Service就是用来解决这个问题的。一个Service可以看作一组提供相同服务的Pods的对外访问接口,Service作用于哪些Pods是通过label selector来定义的,这些Pods能被Service访问,Pod之间的发现和路由(如应用中的前端和后端组件)由Kubernetes Service处理。

Service有四种type:
ClusterIP(默认)、NodePort、LoadBalancer、ExternalName. 其中NodePort和LoadBalancer两类型的Services可以对外提供服务。

使用yaml文件创建Service(NodePort)

这里使用yaml文件来创建NodePort类型的Service,service.yaml文件内容如下:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1---
2apiVersion: v1
3kind: Service
4metadata:
5  name: kube-node-service
6  labels:
7    name: kube-node-service
8spec:
9  type: NodePort      #这里代表是NodePort类型的
10  ports:
11  - port: 80          #这里的端口和clusterIP(10.97.114.36)对应,即10.97.114.36:80,供内部访问。
12    targetPort: 8081  #端口一定要和container暴露出来的端口对应,nodejs暴露出来的端口是8081,所以这里也应是8081
13    protocol: TCP
14    nodePort: 32143   # 所有的节点都会开放此端口,此端口供外部调用。
15  selector:
16    app: web          #这里选择器一定要选择容器的标签,之前写name:kube-node是错的。
17
18

执行命令创建一个service,并列出所有的services


1
2
3
4
5
6
7
8
9
1root@kube-master:/home/cong/Desktop/NodeDemo1# kubectl create -f service.yaml
2service/kube-node-service created
3
4root@kube-master:/home/cong/Desktop/NodeDemo1# kubectl get services
5NAME                TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
6kube-node-service   NodePort    10.97.114.36   <none>        80:32143/TCP   7s
7kubernetes          ClusterIP   10.96.0.1      <none>        443/TCP        7d
8
9

我们来验证一下创建的service是否正确,执行如下命令


1
2
3
4
5
6
7
8
1root@kube-master:/home/cong/Desktop/NodeDemo1# curl localhost:32143
2Hello World!
3
4# 由于定义的port是80,所以直接访问clusterIP
5root@kube-master:/home/cong/Desktop/NodeDemo1# curl 10.97.114.36
6Hello World!
7
8

可以看到以上这些端口都可以访问我们的应用程序,在每个节点查看端口执行netstat -ntlp,发现每个节点都开放出了端口32143,此端口主要是给外部分用户调用的。
尝试访问两个slave节点试试,他们都可以显示出Hello World!,命令如下:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
1#在master节点上查看slave node的ip
2root@kube-master:/home/cong/Desktop/NodeDemo1# kubectl get nodes -o wide
3NAME           STATUS    ROLES     AGE       VERSION   INTERNAL-IP      EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
4kube-master    Ready     master    7d        v1.11.1   192.168.29.138   <none>        Ubuntu 16.04.4 LTS   4.13.0-36-generic   docker://17.3.2
5kube-slave-1   Ready     <none>    1d        v1.11.1   192.168.29.141   <none>        Ubuntu 16.04.4 LTS   4.13.0-36-generic   docker://17.3.2
6kube-slave-3   Ready     <none>    7d        v1.11.1   192.168.29.139   <none>        Ubuntu 16.04.4 LTS   4.15.0-30-generic   docker://17.3.2
7
8#在master节点上,查看所有pods
9root@kube-master:/home/cong/Desktop/NodeDemo1# kubectl get pods -o wide
10NAME                            READY     STATUS    RESTARTS   AGE       IP            NODE
11kube-node-64f4f68d4b-sttz2      1/1       Running   0          15m       10.244.1.71   kube-slave-3
12kube-node-64f4f68d4b-vwwt2      1/1       Running   0          1d        10.244.1.69   kube-slave-3
13
14#在master节点上,访问两个pods,端口都是8081
15root@kube-master:/home/cong/Desktop/NodeDemo1# curl 10.244.1.71:8081
16Hello World!
17root@kube-master:/home/cong/Desktop/NodeDemo1# curl 10.244.1.69:8081
18Hello World!
19
20#在slave节点kube-slave-1上访问32143端口
21root@kube-slave-1:/home/cong# curl 192.168.29.141:32143
22Hello World!
23
24#在slave节点kube-slave-3上访问32143端口
25root@kube-slave-3:/home/cong# curl 192.168.29.139:32143
26Hello World!
27
28

至此,我们的service就创建并验证成功了,此时你可能迷惑在service.yaml中定义的port(80), tartget port(8081), nodePort(32143)这三个端口是什么关系呢,这里有点绕,先看下图:
Kubernetes系列之五:使用yaml文件创建service向外暴露服务

注意上图里面的IP和端口和笔者用的端口不一致,但此图大致描述了上面三个端口之间的关系。
首先外部使用load balancer访问我们的两个slave节点(192.168.29.141:32143) 和 (192.168.29.139:32143),接着它会访问Service,即ClusterIP(10.97.114.36:80), Service再通过load balancer访问到某一个pod(端口8081)里的container(端口8081)。
这里第二个load balancer是由kube-proxy来负责的,官方的描述是:kube-proxy负责为service提供cluster内部的服务发现和负载均衡。

实际上,我们还另一种创建service的方式,更快更便捷,
即使用expose命令来创建service,如下:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
1root@kube-master:/home/cong# kubectl expose deployment kube-node --type=NodePort
2service/kube-node exposed
3
4root@kube-master:/home/cong# kubectl get services
5NAME                TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
6kube-node           NodePort    10.107.247.158   <none>        8081:31195/TCP   10s
7kube-node-service   NodePort    10.97.114.36     <none>        80:32143/TCP     1d
8kubernetes          ClusterIP   10.96.0.1        <none>        443/TCP          8d
9nginx               NodePort    10.99.22.64      <none>        80:32322/TCP     2d
10
11root@kube-master:/home/cong# curl localhost:31195
12Hello World!
13
14root@kube-master:/home/cong# curl 10.107.247.158:8081
15Hello World!
16
17root@kube-master:/home/cong# kubectl describe services/kube-node
18Name:                     kube-node
19Namespace:                default
20Labels:                   app=web
21Annotations:              <none>
22Selector:                 app=web
23Type:                     NodePort
24IP:                       10.107.247.158
25Port:                     <unset>  8081/TCP
26TargetPort:               8081/TCP
27NodePort:                 <unset>  31195/TCP
28Endpoints:                10.244.1.71:8081,10.244.2.81:8081  #这里podIp+端口号就是endpoint
29Session Affinity:         None
30External Traffic Policy:  Cluster
31Events:                   <none>
32
33root@kube-master:/home/cong# kubectl describe services/kube-node-service
34Name:                     kube-node-service
35Namespace:                default
36Labels:                   name=kube-node-service
37Annotations:              <none>
38Selector:                 app=web
39Type:                     NodePort
40IP:                       10.97.114.36
41Port:                     <unset>  80/TCP
42TargetPort:               8081/TCP
43NodePort:                 <unset>  32143/TCP
44Endpoints:                10.244.1.71:8081,10.244.2.81:8081 #虽然暴露了两个service,但endpoint是一样滴。
45Session Affinity:         None
46External Traffic Policy:  Cluster
47Events:                   <none>
48
49

可以看出,expose命令这里并没有指定clusterIP,说明它是K8S系统中的虚拟IP地址,由系统动态分配。Pod的IP地址是由flannel插件来分配的,而不再由Docker Daemon根据docker0网桥的IP地址进行分配。可以在任意节点上输入ifconfig可以看到。

使用yaml文件创建Service(LoadBalancer)

这里我们继续expose命令创建loadBalancer类型的service,命令如下:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
1service "kube-node" deleted
2root@kube-master:/home/cong# kubectl expose deployment kube-node --type=LoadBalancer
3service/kube-node exposed
4
5root@kube-master:/home/cong# kubectl get services
6NAME                TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
7kube-node           LoadBalancer   10.99.201.195   <pending>     8081:31585/TCP   10s
8kube-node-service   NodePort       10.97.114.36    <none>        80:32143/TCP     1d
9kubernetes          ClusterIP      10.96.0.1       <none>        443/TCP          8d
10nginx               NodePort       10.99.22.64     <none>        80:32322/TCP     2d
11
12root@kube-master:/home/cong# curl localhost:31585
13Hello World!
14
15root@kube-master:/home/cong# curl 10.99.201.195:8081
16Hello World!
17
18root@kube-master:/home/cong# kubectl describe services/kube-node
19Name:                     kube-node
20Namespace:                default
21Labels:                   app=web
22Annotations:              <none>
23Selector:                 app=web
24Type:                     LoadBalancer
25IP:                       10.99.201.195
26Port:                     <unset>  8081/TCP
27TargetPort:               8081/TCP
28NodePort:                 <unset>  31585/TCP
29Endpoints:                10.244.1.71:8081,10.244.2.81:8081
30Session Affinity:         None
31External Traffic Policy:  Cluster
32Events:                   <none>
33
34

当然我们也可以使用yaml文件来创建,service-lb.yaml文件如下:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
1---
2apiVersion: v1
3kind: Service
4metadata:
5name: kube-node-service-lb
6labels:
7  name: kube-node-service-lb
8spec:
9type: LoadBalancer
10clusterIP: 10.99.201.198
11ports:
12- port: 80
13  targetPort: 8081
14  protocol: TCP
15  nodePort: 32145
16selector:
17  app: web
18status:
19loadBalancer:
20  ingress:
21  - ip: 192.168.174.127    #这里是云服务商提供的负载匀衡器的IP地址
22
23

执行命令:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1root@kube-master:/home/cong/Desktop/NodeDemo1# kubectl create -f service-lb.yaml
2service/kube-node-service-lb created
3
4root@kube-master:/home/cong/Desktop/NodeDemo1# kubectl get services
5NAME                   TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
6kube-node              LoadBalancer   10.99.201.195   <pending>     8081:31585/TCP   21m
7kube-node-service      NodePort       10.97.114.36    <none>        80:32143/TCP     1d
8kube-node-service-lb   LoadBalancer   10.99.201.198   <pending>     80:32145/TCP     9s
9kubernetes             ClusterIP      10.96.0.1       <none>        443/TCP          8d
10nginx                  NodePort       10.99.22.64     <none>        80:32322/TCP     2d
11
12root@kube-master:/home/cong/Desktop/NodeDemo1# curl 10.99.201.195:8081
13Hello World!
14
15root@kube-slave-3:/home/cong# curl localhost:31585
16Hello World!
17
18

好了,到这里,你已经掌握了service及yaml的基本用法了,加油

给TA打赏
共{{data.count}}人
人已打赏
安全运维

故障复盘的简洁框架-黄金三问

2021-9-30 19:18:23

安全运维

OpenSSH-8.7p1离线升级修复安全漏洞

2021-10-23 10:13:25

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索