书籍来源:《CKA/CKAD应试指南:从Docker到Kubernetes完全攻略》
一边学习一边整理老师的课程内容及实验笔记,并与大家分享,侵权即删,谢谢支持!
附上汇总贴:CKA备考实验 | 汇总_热爱编程的通信人的博客-CSDN博客
本节讲解如何创建服务及验证服务的负载均衡功能。
环境准备
本章内容所涉及的文件全部放在目录svc里,所有的实验全部在命名空间nssvc里操作,然创建一个副本的deployment。
步骤1:创建目录svc,然后进入此目录。
##########实操验证##########
[root@vms10 ~]# mkdir svc
[root@vms10 ~]# cd svc/
[root@vms10 svc]#
创建一个名字为nssvc的命名空间,并切换到此命名空间里。
##########实操验证##########
[root@vms10 svc]# kubectl create ns nssvc
namespace/nssvc created
[root@vms10 svc]# kubens nssvc
Context "kubernetes-admin@kubernetes" modified.
Active namespace is "nssvc".
[root@vms10 svc]#
步骤2:创建一个deployment的yaml文件。
##########实操验证##########
[root@vms10 svc]# kubectl create deployment web --image=nginx --dry-run=client -o yaml > web1.yaml
[root@vms10 svc]#
步骤3:手动修改镜像下载策略并修改标签方面的内容,yaml文件如下。
##########实操验证##########
[root@vms10 svc]# cat web1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: web1
name: web
spec:
replicas: 1
selector:
matchLabels:
app: web1
strategy: {}
template:
metadata:
labels:
app: web1
spec:
containers:
- image: nginx
name: nginx
imagePullPolicy: IfNotPresent
[root@vms10 svc]#
这里可以看到,deployment创建出来的pod都具有app1=web1这个标签(3位置),且deployment是通过app1=web1这个标签(2位置)来定位pod的。这里deployment自身的标签是app=web(1位置),这个和其创建出来的pod的标签不一样也没关系。
步骤4:创建deployment。
##########实操验证##########
[root@vms10 svc]# kubectl apply -f web1.yaml
deployment.apps/web created
[root@vms10 svc]#
步骤5:查看deployment。
##########实操验证##########
[root@vms10 svc]# kubectl get deploy -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
web 1/1 1 1 22s nginx nginx app=web1
[root@vms10 svc]#
这里可以看到,deployment是通过标签app1=web1来定位pod的。
创建svc
可以基于deployment来创建svc,因为web这个deployment创建出来的pod,都具有一个标签app1=web1(这个不是deployment自身的标签),所以本质上是对标签为app1=web1的那些pod创建svc。
创建svc的语法如下。
kubectl expose deployment <deploy的名字> --name=服务名 --port=端口 --target-port=端口
这里如果不使用--name指定服务名的话,则保持和deployment的名字一致。
如果是为pod创建服务的话,语法如下。
kubectl expose pod <pod的名字> --name=服务名 --port=端口 --target-port=端口
这里如果不使用--name指定服务名的话,则保持和pod的名字一致。
因为客户端直接访问svc,所以这里--port指的是服务的端口(svc这个端口可以根据需要随意指定),svc会把请求转发给后端的pod,所以这里--target-port指的是后端pod运行的端口(--target-port这个端口不可以随意指定,要看pod里所使用的端口是什么),如图12-2所示。
步骤1:为名字为web的deployment创建一个服务,名字为svc1。
##########实操验证##########
[root@vms10 svc]# kubectl expose deployment web --name=svc1 --port=80 --target-port=80
service/svc1 exposed
[root@vms10 svc]#
步骤2:查看现有的服务。
##########实操验证##########
[root@vms10 svc]# kubectl get svc -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
svc1 ClusterIP 10.111.149.146 <none> 80/TCP 18s app=web1
[root@vms10 svc]#
从这里可以看到,svc1是通过标签app1=web1(在SELECTOR字段显示)来定位pod的。所以,这个svc虽然是基于deployment创建出来的,其实定位的是此deployment所管理的pod。
步骤3:查看svc的详细信息。
##########实操验证##########
[root@vms10 svc]# kubectl describe svc svc1
Name: svc1
Namespace: nssvc
Labels: app=web1
Annotations: <none>
Selector: app=web1
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.111.149.146
IPs: 10.111.149.146
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.14.18:80
Session Affinity: None
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedToUpdateEndpointSlices 57s endpoint-slice-controller Error updating Endpoint Slices for Service nssvc/svc1: failed to create EndpointSlice for Service nssvc/svc1: Unauthorized
[root@vms10 svc]#
这里endpoint的IP地址就是后端pod的IP。
步骤4:查看pod的IP。
##########实操验证##########
[root@vms10 svc]# kubectl get pods -o wide --no-headers
web-5bfb6d8dcc-n929c 1/1 Running 0 4m7s 10.244.14.18 vms12.rhce.cc <none> <none>
[root@vms10 svc]#
步骤5:现在扩展deployment的副本数为3。
##########实操验证##########
[root@vms10 svc]# kubectl scale deploy web --replicas=3
deployment.apps/web scaled
[root@vms10 svc]#
步骤6:再次查看pod的IP情况。
##########实操验证##########
[root@vms10 svc]# kubectl get pods -o wide --no-headers
web-5bfb6d8dcc-6gp6x 1/1 Running 0 21s 10.244.81.77 vms11.rhce.cc <none> <none>
web-5bfb6d8dcc-n929c 1/1 Running 0 4m55s 10.244.14.18 vms12.rhce.cc <none> <none>
web-5bfb6d8dcc-s8wtr 1/1 Running 0 21s 10.244.14.17 vms12.rhce.cc <none> <none>
[root@vms10 svc]#
步骤7:再次查看svc的信息。
##########实操验证##########
[root@vms10 svc]# kubectl describe svc svc1
Name: svc1
Namespace: nssvc
Labels: app=web1
Annotations: <none>
Selector: app=web1
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.111.149.146
IPs: 10.111.149.146
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.14.17:80,10.244.14.18:80,10.244.81.77:80
Session Affinity: None
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedToUpdateEndpointSlices 2m47s endpoint-slice-controller Error updating Endpoint Slices for Service nssvc/svc1: failed to create EndpointSlice for Service nssvc/svc1: Unauthorized
[root@vms10 svc]#
从这里可以看到,deploy扩展了副本数之后,新产生的pod也具有app1=web1标签,svc会动态地去更新后端pod,而不用考虑pod的IP。
删除svc
本节讲的是如何删除svc。
删除svc命令的语法如下。
kubectl delete svc 名字
或者:
kubectl delete -f svc的yaml文件
下面删除svc1。
##########实操验证##########
[root@vms10 svc]# kubectl delete svc svc1
service "svc1" deleted
[root@vms10 svc]#
如果pod有多个标签的话,在创建svc的时候,也可以指定到底根据哪个标签来定位pod,此时在创建svc时加上--selector选项。
##########实操验证##########
[root@vms10 svc]# kubectl expose pod web-5bfb6d8dcc-6gp6x --name=svc1 --selector=app1=web1 --port=80 --target-port=80
service/svc1 exposed
[root@vms10 svc]#
验证svc的负载均衡功能
先查看拓扑图,如图12-3所示。
按照刚才所讲的,用户访问svc1的时候,svc1会把请求转发到后端的pod,这样如果有300个请求连接过来,每个pod大概会承担100个请求,下面开始验证这个负载均衡。
步骤1:先把后端pod的首页内容改成不一样的,分别是1111、222、333。
##########实操验证##########
[root@vms10 svc]# kubectl exec -it web-5bfb6d8dcc-6gp6x -- bash
root@web-5bfb6d8dcc-6gp6x:/# echo 1111 > /usr/share/nginx/html/index.html
root@web-5bfb6d8dcc-6gp6x:/# exit
exit
[root@vms10 svc]# kubectl exec -it web-5bfb6d8dcc-n929c -- bash
root@web-5bfb6d8dcc-n929c:/# echo 222 > /usr/share/nginx/html/index.html
root@web-5bfb6d8dcc-n929c:/# exit
exit
[root@vms10 svc]# kubectl exec -it web-5bfb6d8dcc-s8wtr -- bash
root@web-5bfb6d8dcc-s8wtr:/# echo 333 > /usr/share/nginx/html/index.html
root@web-5bfb6d8dcc-s8wtr:/# exit
exit
[root@vms10 svc]#
步骤2:因为前面把svc1删除了,这里再次创建出来名为svc1的svc。
##########实操验证##########
[root@vms10 svc]# kubectl expose deployment web --name=svc1 --port=80 --target-port=80
service/svc1 exposed
[root@vms10 svc]#
步骤3:查看svc的IP。
##########实操验证##########
[root@vms10 svc]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc1 ClusterIP 10.111.234.100 <none> 80/TCP 16s
[root@vms10 svc]#
这里得到服务的IP是10.105.157.241。
步骤4:下面开始访问svc1的IP。
##########实操验证##########
[root@vms10 svc]# curl -s 10.111.234.100
1111
[root@vms10 svc]# curl -s 10.111.234.100
222
[root@vms10 svc]# curl -s 10.111.234.100
1111
[root@vms10 svc]# curl -s 10.111.234.100
1111
[root@vms10 svc]# curl -s 10.111.234.100
222
[root@vms10 svc]# curl -s 10.111.234.100
1111
[root@vms10 svc]# curl -s 10.111.234.100
1111
[root@vms10 svc]# curl -s 10.111.234.100
1111
[root@vms10 svc]# curl -s 10.111.234.100
333
[root@vms10 svc]# curl -s 10.111.234.100
333
[root@vms10 svc]#
可以看到,已经负载均衡到后端的每个pod了。
步骤5:删除此服务svc1。
##########实操验证##########
[root@vms10 svc]# kubectl delete svc svc1
service "svc1" deleted
[root@vms10 svc]#
通过yaml文件的方式创建service
也可以通过yaml文件的方式来创建服务,这样我们可以根据需要来修改yaml文件。yaml文可以通过kubectl expose命令来生成。
步骤1:用命令行生成svc1.yaml。
##########实操验证##########
[root@vms10 svc]# kubectl expose deployment web --name=svc1 --port=80 --target-port=80 --dry-run=client -o yaml > svc1.yaml
[root@vms10 svc]#
步骤2:查看svc1.yaml的内容如下。
##########实操验证##########
[root@vms10 svc]# cat svc1.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app: test
name: svc1
spec:
ports:
- port: 80
targetPort: 80
selector:
app: web1
[root@vms10 svc]#
这里用selector来指定到底要关联哪些标签的pod,即前面deployment创建出来pod都具备app1=web1的这个标签。
步骤3:创建此svc。
##########实操验证##########
[root@vms10 svc]# kubectl apply -f svc1.yaml
service/svc1 created
[root@vms10 svc]#
步骤4:查看现有的svc。
##########实操验证##########
[root@vms10 svc]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc1 ClusterIP 10.105.104.69 <none> 80/TCP 14s
[root@vms10 svc]#
步骤5:删除deployment和svc。
##########实操验证##########
[root@vms10 svc]# kubectl delete deployment web
deployment.apps "web" deleted
[root@vms10 svc]#
[root@vms10 svc]# kubectl delete svc svc1
service "svc1" deleted
[root@vms10 svc]#