Loading...
墨滴

舍得

2021/10/06  阅读:19  主题:橙心

实战:Kubernetes网络service实验(成功测试-博客输出)-20211005

实战:Kubernetes网络service实验(成功测试-博客输出)-20211005

image-20211004115405949
image-20211004115405949

目录

写在前面

本文,我将带你实战演示Kubernetes网络service实验。

我的博客主旨:我希望每一个人拿着我的博客都可以做出实验现象,先把实验做出来,然后再结合理论知识更深层次去理解技术点,这样学习起来才有乐趣和动力。并且,我的博客内容步骤是很完整的,也分享源码和实验用到的软件,希望能和大家一起共同进步!

各位小伙伴在实际操作过程中如有什么疑问,可随时联系本人免费帮您解决问题:

  1. 个人微信二维码:x2675263825 (舍得), qq:2675263825。

    image-20211002091450217
    image-20211002091450217
  2. 个人博客地址:www.onlyonexl.cn

    image-20211002092057988
    image-20211002092057988
  3. 个人微信公众号:云原生架构师实战

    image-20211002141739664
    image-20211002141739664
  4. 个人csdn

    https://blog.csdn.net/weixin_39246554?spm=1010.2135.3001.5421

    image-20211002092344616
    image-20211002092344616

基础知识

image-20211006201044143
image-20211006201044143
image-20211006201101407
image-20211006201101407
image-20211006201129708
image-20211006201129708
image-20211006201140693
image-20211006201140693
image-20211006201159656
image-20211006201159656
image-20211006201210581
image-20211006201210581
image-20211006201241452
image-20211006201241452
image-20211006201254242
image-20211006201254242
image-20211006201324535
image-20211006201324535
image-20211006201335997
image-20211006201335997

实验环境

实验环境:
1、win10,vmwrokstation虚机;
2、k8s集群:3台centos7.6 1810虚机,1个master节点,2个node节点
   k8s version:v1.21
   CONTAINER-RUNTIME:docker://20.10.7
image-20211002143602812
image-20211002143602812

实验1:定义service资源

1.编写service.yaml

  • 这里,我们通过命令导出deployment.yaml和service.yaml 2个yaml文件
#先创建一个deployment
[root@k8s-master ~]#kubectl create deployment web --image=nginx --replicas=3

#1导出deployment.yaml
[root@k8s-master ~]#kubectl create deployment web --image=nginx --dry-run=client --replicas=3 -o yaml > deployment.yaml 

#导出service.yaml
[root@k8s-master ~]#kubectl expose deployment web --port=80 --target-port=80 --type=NodePort --dry-run=client -o yaml > service.yaml 
  • 编辑service.yaml,删除时间戳等信息,最终配置如下
[root@k8s-master ~]#vim service.yaml 
apiVersion: v1
kind: Service
metadata:
  labels:
    app: web
  name: web
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: web
  type: NodePort
image-20210619143839247
image-20210619143839247

2.apply下service.yaml并查看

[root@k8s-master ~]#kubectl apply -f service.yaml
service/web created
[root@k8s-master ~]#kubectl get pod,svc #查看
image-20210619144200927
image-20210619144200927

3.我们来看service是如何关联项目的pod的呢?

我们来看service是如何关联项目的pod的呢?=>Service通过标签关联一组Pod.

  • 此时,我们再部署一个项目
[root@k8s-master ~]#cp deployment.yaml deployment2.yaml
[root@k8s-master ~]#cp service.yaml service2.yaml
  • 编写deployment2.yaml
[root@k8s-master ~]#vim deployment2.yaml #编写deployment2.yaml,删除时间戳等信息,并修改deployment  name
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: web2
  name: web2
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web2
  strategy: {}
  template:
    metadata:
      labels:
        app: web2
    spec:
      containers:
      - image: nginx
        name: nginx
        resources: {}
image-20210619195212938
image-20210619195212938
  • apply下deployment2.yaml
[root@k8s-master ~]#kubectl apply -f deployment2.yaml
  • 编辑service2.yaml
[root@k8s-master ~]#vim service2.yaml #修改label的value为web2
apiVersion: v1
kind: Service
metadata:
  labels:
    app: web2
  name: web2
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: web2
  type: NodePort
image-20210619195531770
image-20210619195531770
  • apply下service.yaml
[root@k8s-master ~]#kubectl apply -f service2.yaml
  • 查看
[root@k8s-master ~]#kubectl get pod,svc
image-20210619195824532
image-20210619195824532

此时,已经存在了2个项目:webweb2:

image-20210619195858037
image-20210619195858037
  • 那么,service是如何匹配不同项目的pod的呢?

=>Service通过标签关联一组Pod

但是,如何用命令去查询service与pod之间的关联方式呢?

  • 我们来查看一下他们的标签
[root@k8s-master ~]#kubectl get pod --show-labels
image-20210619200248229
image-20210619200248229

我们可以看下service.yaml里的setlector里的标签内容:

image-20210619200655578
image-20210619200655578
  • 方法1:于是,==可用如下方法来确认某个标签包含了哪些pod?==
[root@k8s-master ~]#kubectl get pod -l app=web
#注意,service不管你是否是由deployment创建的pod,只要你的标签是它seletctor里面匹配的内容,它都会将pod映射到一个项目里去的;
image-20210619200824088
image-20210619200824088
  • 方法2:这种方法也是可以查看的
[root@k8s-master ~]#kubectl get endpoints #简写ep
image-20210619201257204
image-20210619201257204
  • 这里把svc想象成为nginx负载均衡器就可以:使用nginx配置upstream作为负载均衡器
image-20210619222112224
image-20210619222112224
image-20210619221901863
image-20210619221901863

实验2:多端口Service定义services资源

image-20210619133610822
image-20210619133610822
Service定义与创建

`多端口Service定义`:对于某些服务,需要公开多个端口,Service也需要配置多个端口定义,通过端口名称区分。

`多端口Service定义`
apiVersion: v1
kind: Service
metadata:
  name: web

spec:
  type: ClusterIP
  ports:
  - name: http
    port: 80 
    protocol: TCP
    targetPort: 80

  - name: https
    port: 443 
    protocol: TCP 
    targetPort: 443
  selector: 
  app: web
image-20210619223058863
image-20210619223058863

实验环境

在实验1环境基础上测试。

1.编写service.yaml文件

[root@k8s-master ~]#cp service.yaml service3.yaml
[root@k8s-master ~]#vim service3.yaml #修改相应信息
apiVersion: v1
kind: Service
metadata:
  labels:
    app: web
  name: web
spec:
  ports:
  - port: 80
    name: api1 #port:80 name
    protocol: TCP
    targetPort: 80 #port:80 
  - port: 81
    name: api2 #port:81 name
    protocol: TCP
    targetPort: 81 #port:81
  selector:
    app: web
  type: NodePort
image-20210619223755055
image-20210619223755055

2.apply下service.yaml并查看

[root@k8s-master ~]#kubectl apply -f service3.yaml
[root@k8s-master ~]#kubectl get svc
image-20210619223855894
image-20210619223855894

一般这种情况,工作中很少用到。常规下,pod里只提供一个服务端口。

实验到此结束。

实验3:Service三种常用类型测试

实验环境

是在上面实验2基础上进行测试的。

1、service中Cluster IP配置

  • 我们生成一个service yaml文件并编辑
[root@k8s-master ~]#kubectl expose deployment web --port=80 --target-port=80 --dry-run=client -o yaml > service-clusterip.yaml   #注意,这里不指定--type=参数时,默认就是Cluster IP.   
  • 编辑clusterip.yaml文件
[root@k8s-master ~]#vim service-clusterip.yaml #删除时间戳等信息,修改service名称和label名称。
apiVersion: v1
kind: Service
metadata:
  labels:
    app: web6
  name: web6
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: web6
image-20210627134933861
image-20210627134933861
  • apply下
[root@k8s-master ~]#kubectl apply -f service-clusterip.yaml
service/web6 created
[root@k8s-master ~]#
  • 查看:我们这里没指定--type,默认值就是ClusterIP
image-20210620081534733
image-20210620081534733
  • ==排查下这个问题:这个service关联的pod有点不对。。。===>这个其实不多的,是端端口的原因。
image-20210620085747277
image-20210620085747277
[root@k8s-master ~]#kubectl get service -o yaml|grep selector -A  1 #-A 1表示后一行, -B代表前
image-20210620085452144
image-20210620085452144
image-20210620085514370
image-20210620085514370

此时,我们去掉多端口的配置,重新apply下,否则影响实验效果:

[root@k8s-master ~]#vim service3.yaml #配置为如下内容
apiVersion: v1
kind: Service
metadata:
  labels:
    app: web
  name: web
spec:
  ports:
  - port: 80
    name: api1
    protocol: TCP
    targetPort: 80
  selector:
    app: web
  type: NodePort 

重新apply下并查看:

image-20210620090211472
image-20210620090211472
  • 现在继续讲解上面那个问题:这里以web pod作为示例。

我们访问Cluster Ip,它会被转发到后端的一组pod上去的;

image-20210620090357207
image-20210620090357207

==这个Cluster ip在集群内部,任何POd,任何node都是可以访问到的==:

在3个node上是可以访问这个cluster ip的:

image-20210620160535275
image-20210620160535275
image-20210620160602492
image-20210620160602492
image-20210620160627195
image-20210620160627195

==在任意pod里也是可以访问这个cluster ip的:==

我们创建一个busybox容器:

进到容器通过wget下载可验证以上结论。

[root@k8s-master ~]#kubectl run bs --image=busybox -- sleep 24h #运行一个容器
pod/bs created

[root@k8s-master ~]#kubectl get pod #查看pod
NAME                    READY   STATUS    RESTARTS   AGE
bs                      1/1     Running   0          8s
web-96d5df5c8-7nv2b     1/1     Running   1          7h24m
web-96d5df5c8-85mlv     1/1     Running   1          7h24m
web-96d5df5c8-x27wr     1/1     Running   1          7h24m
web2-7d78cf6476-cmsm5   1/1     Running   1          7h24m
web2-7d78cf6476-ddvzs   1/1     Running   1          7h24m
web2-7d78cf6476-zhk8n   1/1     Running   1          7h24m
[root@k8s-master ~]#
image-20210620161434018
image-20210620161434018

实验到此结束!

2、service中NodePort配置

  • 创建yaml文件并修改
[root@k8s-master ~]#cp service-clusterip.yaml service-nodeport.yaml
[root@k8s-master ~]#vim service-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: web6
  name: web6
spec:
  type: NodePort #修改service类型为 NodePort
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: web #这里把标签关联到之前的业务web上
image-20210620163224667
image-20210620163224667
  • apply下并查看
[root@k8s-master ~]#kubectl apply -f service-nodeport.yaml
service/web6 configured
[root@k8s-master ~]#
image-20210620163617162
image-20210620163617162

注意:此时,在3个节点上都可以可以访问这个地址的

image-20210620163923318
image-20210620163923318
image-20210620163934237
image-20210620163934237
image-20210620163945961
image-20210620163945961
  • 注意:之所以我们能访问这个30849端口,这里是有个逻辑在这里的:

3个节点都有监听这个nodeport端口;

image-20210620164307756
image-20210620164307756
image-20210620164342099
image-20210620164342099
image-20210620164404612
image-20210620164404612

这里3个节点没监听80端口的:

image-20210620164713970
image-20210620164713970
  • ==我们可以手动去指定NodPort端口号(但一般不这样做)==

我们指定一个nodePort

[root@k8s-master ~]#vim service-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: web6
  name: web6
spec:
  type: NodePort
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
    nodePort: 30006 #修改为30006
  selector:
    app: web
image-20210620165551069
image-20210620165551069
  • apply下并查看
image-20210620165713638
image-20210620165713638

浏览器可以查看的:

image-20210620165739123
image-20210620165739123

同时可以看到,3个节点均有监听30006这个端口的;

image-20210620165923424
image-20210620165923424

实验到此结束!

实战4:Service代理模式:kubeadm方式修改ipvs模式

原课件

image-20210620195709157
image-20210620195709157
kubeadm方式修改ipvs模式:
# kubectl edit configmap kube-proxy -n kube-system
...
mode: “ipvs“
...
# kubectl delete pod kube-proxy-btz4p -n kube-system
注:
1、kube-proxy配置文件以configmap方式存储
2、如果让所有节点生效,需要重建所有节点kube-proxy pod


二进制方式修改ipvs模式:
# vi kube-proxy-config.yml 
mode: ipvs
ipvs:
scheduler: "rr“
# systemctl restart kube-proxy
注:配置文件路径根据实际安装目录为准

1、查看当前services的代理模式是什么?

  • 查看由Daemonset控制器创建的kube-proxy
[root@k8s-master ~]#kubectl get pod -n kube-system #查看由Daemonset控制器创建的kube-proxy
NAME                                       READY   STATUS    RESTARTS   AGE
calico-kube-controllers-6949477b58-hlxp7   1/1     Running   13         18d
calico-node-c5sl6                          1/1     Running   31         18d
calico-node-l7q5q                          1/1     Running   9          18d
calico-node-sck2q                          1/1     Running   8          18d
etcd-k8s-master                            1/1     Running   9          18d
kube-apiserver-k8s-master                  1/1     Running   10         18d
kube-controller-manager-k8s-master         1/1     Running   10         18d
kube-proxy-9249w                           1/1     Running   12         18d
kube-proxy-mj7l5                           1/1     Running   8          18d
kube-proxy-p9bd4                           1/1     Running   9          18d
kube-scheduler-k8s-master                  1/1     Running   10         18d
[root@k8s-master ~]#
  • 看一个pod的日志:
[root@k8s-master ~]#kubectl logs kube-proxy-9249w -n kube-system

从这里可以看出kube-proxy维护的svc的代理模式类型是什么样的?:默认是ipatbles方式的。

image-20210620202921859
image-20210620202921859

kube-proxy是由DaemonSet控制器部署的

注意:但是这个并没有在/etc/kubernetes/manifests/目录下:

image-20210620204254167
image-20210620204254167
image-20211006113646079
image-20211006113646079

2、在线修改kube-proxy的configmap

[root@k8s-master ~]#kubectl edit configmap kube-proxy -n kube-system #

mode: ““
改成
mode: “ipvs“
[root@k8s-master ~]#

3、重启下kube-proxy

  • kube-proxy本身没有实现热更新的机制的,因此需要重启下kube-proxy:

这里先以一个kube-proxy为例:

先定位下这个kube-peoxy在哪个节点上?

image-20210620230654493
image-20210620230654493

在node1上:

image-20210620230734682
image-20210620230734682

在k8s-master上删除次kube-proxy pod:==(一共有3个pod的)==

[root@k8s-master ~]#kubectl delete pod kube-proxy-9249w -n kube-system
image-20210621051752658
image-20210621051752658
image-20210621051859792
image-20210621051859792
image-20210621052018233
image-20210621052018233

4、all节点安装ipvsadm软件包

  • all节点都安装下ipvsadm软件包:
[root@k8s-node1 ~]#yum install -y ipvsadm
[root@k8s-node2 ~]#yum install -y ipvsadm
[root@k8s-master ~]#yum install -y ipvsadm

node1查看会有很多ipvs规则(node1上刚有更改kube-proxy的代理模式为ipvs):(k8s-node2效果一样)

image-20210621052703205
image-20210621052703205

virtual server和real server:

image-20210621053536302
image-20210621053536302

我们现在在node1上访问这个cluster ip,它的流程是怎么样的呢?

image-20210621053917316
image-20210621053917316
image-20210621053939742
image-20210621053939742
image-20210621054313271
image-20210621054313271
image-20210621054251607
image-20210621054251607

5、查看ipvs代理模式包的传输流程

==cluster ip会绑定定到kube-ipvs0这个虚拟网卡上来的;==

这里和iptables不同,iptables是看不到任何实际网卡信息的,走的都iptables规则;

image-20210621054620679
image-20210621054620679
image-20210621054251607
image-20210621054251607

你要访问Nodeport也是走的这个规则:

image-20211006115408286
image-20211006115408286
image-20211006115438234
image-20211006115438234
image-20211006115454546
image-20211006115454546

实验结束!

实战5:Service DNS名称测试

1、coredns小测试

  • 查看kubeadm安装好的dns
[root@k8s-master 2021-06-19]#kubectl get pod -A
[root@k8s-master 2021-06-19]#kubectl get pod,svc -n kube-system
image-20210621065751952
image-20210621065751952
image-20210621065813262
image-20210621065813262
  • 进到bs测试容器,查看其dns解析解析:发现pod里的nameserver指向的是coredns
image-20210621070149714
image-20210621070149714
  • 进行解析测试

尝试对如下web6 svc测试:

image-20210621070655598
image-20210621070655598

这里可以使用cluster ip和svc 名称都是可以的:

image-20210621071007017
image-20210621071007017
  • 注意

这里busybox容器里测试用nslookup弹出报错,其实没问题,是busybox:latest镜像问题,可以用buxybox:1.28.4镜像测试,或者换其他镜像进行测试

image-20210621071108276
image-20210621071108276

实验到此结束!

2、ClusterIP A记录格式小实验

  • 创建新的命名空间并部署一个pod
[root@k8s-master ~]#kubectl create ns test
namespace/test created
[root@k8s-master ~]#kubectl create deployment web --image=nginx -n test
deployment.apps/web created
[root@k8s-master ~]#kubectl expose deployment web --port=80 --target-port=80 -n test
service/web exposed
[root@k8s-master ~]#
[root@k8s-master ~]#kubectl get pod,svc -n test
NAME                      READY   STATUS    RESTARTS   AGE
pod/web-96d5df5c8-tj7pr   1/1     Running   0          2m52s

NAME          TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
service/web   ClusterIP   10.111.132.151   <none>        80/TCP    2m22s
[root@k8s-master ~]#
  • 在默认命名空间创建一个busybox:1.28.4 pod
[root@k8s-master ~]#kubectl run bs3  --image=busybox:1.28.4 -- sleep 24h
pod/bs3 created
[root@k8s-master ~]#kubectl get pod
NAME                    READY   STATUS    RESTARTS   AGE
bs                      1/1     Running   2          15h
bs3                     1/1     Running   0          34s 
web-96d5df5c8-7nv2b     1/1     Running   3          22h
web-96d5df5c8-85mlv     1/1     Running   3          22h
web-96d5df5c8-x27wr     1/1     Running   3          22h
web2-7d78cf6476-cmsm5   1/1     Running   3          22h
web2-7d78cf6476-ddvzs   1/1     Running   3          22h
web2-7d78cf6476-zhk8n   1/1     Running   3          22h
[root@k8s-master ~]#
  • 问题:现在在busybox容器里是否可以解析到-n test命名空间下的svc呢?

默认情况下,域名解析到的是默认命名空间下的,如果想要解析其它命名空间下的,后面需要跟上namespace;

建议名称可以写全,例如:my-svc.my-namespace.svc.cluster.local

image-20210621073224421
image-20210621073224421
image-20210621073312344
image-20210621073312344

实验结束!

总结

​ 好了,关于Kubernetes网络service实验实验就到这里了,感谢大家阅读,最后贴上我的美圆photo一张,祝大家生活快乐,每天都过的有意义哦,我们下期见!

image-20211006145936353
image-20211006145936353

舍得

2021/10/06  阅读:19  主题:橙心

作者介绍

舍得