Kubernetes入门实验:service

作者注:本文仅为笔者学习记录,不具任何参考意义。

k8s service 实验。
注:本文为笔者实验记录,非教程,另会不定时更新。

环境

1
2
3
4
5
# kubectl get node
NAME STATUS ROLES AGE VERSION
edge-node Ready <none> 15m v1.17.0
edge-node2 Ready <none> 16m v1.17.0
ubuntu Ready master 67d v1.17.0

service

Service(简称svc)定义了Pod的逻辑集合和访问该集合的策略,是真实服务的抽象。Service提供了一个统一的服务访问入口以及服务代理和发现机制,用户不需要了解后台Pod是如何运行。Service通过Label找到Pod组。

技术总结

编辑yaml文件,将deployment和service写到一起(简单的示例可如此)。
创建服务。
查看pod的IP,获取页面(一般不如此用)。查看servicer的IP,获取页面。
service与pod生命周期无关。即:删除pod,会重新得到IP,可用新IP访问页面。而service的IP未变。

测试yaml文件

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
# cat <<EOF > nginx-service.yaml
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 2 # tells deployment to run 2 pods matching the template
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: latelee/lidch
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80

---

apiVersion: v1
kind: Service # 指定为service
metadata:
labels:
run: nginx # 匹配nginx
name: nginx # 这是本service的名称
namespace: default
spec:
ports:
- port: 88 # 对外为88端口
targetPort: 80
selector:
app: nginx
EOF

创建:

1
kubectl apply -f nginx-service.yaml

查看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# kubectl get deployments -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
nginx-deployment 2/2 2 2 16s nginx latelee/lidch app=nginx

# kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-55677b6b95 2 2 2 30s

# kubectl get pod -l app=nginx
NAME READY STATUS RESTARTS AGE
nginx-deployment-55677b6b95-679dc 1/1 Running 0 47s
nginx-deployment-55677b6b95-lrnb4 1/1 Running 0 47s

# 查看服务:
# kubectl get svc | grep nginx
nginx ClusterIP 10.96.111.49 <none> 88/TCP 7m26s

查看:

1
# kubectl describe service nginx

主要信息:IP 为服务的IP,Endpoints 为匹配到的后端(即deployment的pod)。

验证:

1
2
3
4
5
6
7
8
9
10
查看IP:
# kubectl get pod -l app=nginx -o wide | awk '{ print $6 }'
IP
10.244.1.34
10.244.4.30

获取页面:
# curl 10.244.1.34
# curl 10.244.4.30
# curl 10.96.111.49:88

测试:
手动删除2个pod,会自动创建新的pod,其IP变化,但service的IP不变。

更新参数

编辑:

1
# kubectl edit service nginx

vim模式,将port: 88改为port: 80,保存退出,即时生效,使用curl 10.96.111.49访问页面。

停止:

1
kubectl apply -f nginx-service.yaml

endpoints

查看服务内pod的IP,pod重建后,此处会更新。与service同名。

1
2
3
 kubectl get endpoints
输出:
nginx 10.244.1.45:80,10.244.4.39:80 3h50m

记录一个service对应的所有pod的访问地址。前提:service配置selector。通过endpoints功能,保证service能对应到真正的pod。

模式

修改配置,添加type: LoadBalancer

1
2
3
4
5
6
7
spec:
ports:
- port: 88 # 对外为88端口
targetPort: 80
selector:
app: nginx
type: LoadBalancer

注:type值为ClusterIP NodePort LoadBalancer ExternalName,默认ClusterIP
更新:

1
kubectl apply -f nginx-service.yaml

查看类型:

1
2
3
kubectl get svc
输出:
nginx LoadBalancer 10.96.106.146 <pending> 88:30212/TCP 3h5m

注:这个功能目前还不知道怎么用,待定。

下面是None的示例:

1
2
3
4
5
6
7
8
9
10
11
12
apiVersion: v1
kind: Service
metadata:
name: myapp-headless
namespace: default
spec:
selector:
app: myapp
clusterIP: "None"
ports:
- port: 80
targetPort: 80

1
2
3
4
# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 70d
myapp-headless ClusterIP None <none> 80/TCP 3s

(注:集群IP为None,与配置一致)

新的测试yaml

webgin-service.yaml 文件:

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
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: webgin-deployment
labels:
app: webgin
spec:
replicas: 3 # tells deployment to run 3 pods matching the template
selector:
matchLabels:
app: webgin
template:
metadata:
labels:
app: webgin
spec:
containers:
- name: webgin
image: latelee/webgin
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
volumeMounts:
- mountPath: /etc/localtime
name: time-zone
volumes:
- name: time-zone
hostPath:
path: /etc/localtime

---

apiVersion: v1
kind: Service # 指定为service
metadata:
labels:
run: webgin
name: webgin
namespace: default
spec:
ports:
- port: 88 # 对外为88端口
targetPort: 80
selector:
app: webgin
type: LoadBalancer

创建及实验:

1
2
3
4
5
6
7
# kubectl apply -f webgin-service.yaml 

# kubectl get pod
NAME READY STATUS RESTARTS AGE
webgin-deployment-54ff4977c7-92cvk 1/1 Running 0 21m
webgin-deployment-54ff4977c7-blqnj 1/1 Running 0 21m
webgin-deployment-54ff4977c7-dgglx 1/1 Running 0 21m

使用同一命令测试,返回不同的结果。证实web服务运行于不同的后端,但对外接口相同。
理论上看业务的实现,不关注底层。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# curl 10.96.36.4:88
Hello World
arch: amd64 os: linux hostname: webgin-deployment-54ff4977c7-blqnj
Now: 2020-03-12 00:56:58
# curl 10.96.36.4:88
Hello World
arch: amd64 os: linux hostname: webgin-deployment-54ff4977c7-dgglx
Now: 2020-03-12 00:57:04
# curl 10.96.36.4:88
Hello World
arch: amd64 os: linux hostname: webgin-deployment-54ff4977c7-92cvk
Now: 2020-03-12 00:57:09
# curl 10.96.36.4:88
Hello World
arch: amd64 os: linux hostname: webgin-deployment-54ff4977c7-dgglx
Now: 2020-03-12 00:57:13

指定为nodePort方式webgin-service1.yaml(其它与上述相同):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
apiVersion: v1
kind: Service # 指定为service
metadata:
labels:
run: webgin
name: webgin
namespace: default
spec:
ports:
- port: 88 # 对外为88端口
targetPort: 80
nodePort: 30800 # 指定节点主机的端口为30800
selector:
app: webgin
type: NodePort

查看服务:

1
2
3
# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
webgin NodePort 10.96.36.4 <none> 88:30800/TCP 2d22h

使用集群节点的某一IP+端口(包括master和node),均可访问,其结果如上所述。
注:此方法暂未知在实际中作何用处。

记录

有时使用集群IP访问页面较慢,不知何故,或者虚拟机性能问题。