实战:Kubernetes网络service实验(成功测试

目录

文章目录

  • 目录
  • 写在前面
  • 基础知识
  • 实验环境
  • 实验1:定义service资源
    • 1.编写service.yaml
    • 2.apply下service.yaml并查看
    • 3.我们来看service是如何关联项目的pod的呢?
  • 实验2:多端口Service定义services资源
    • 实验环境
    • 1.编写service.yaml文件
    • 2.apply下service.yaml并查看
  • 实验3:Service三种常用类型测试
    • 实验环境
    • 1、service中Cluster IP配置
    • 2、service中NodePort配置
  • 实战4:Service代理模式:kubeadm方式修改ipvs模式
    • 原课件
    • 1、查看当前services的代理模式是什么?
    • 2、在线修改kube-proxy的configmap
    • 3、重启下kube-proxy
    • 4、all节点安装ipvsadm软件包
    • 5、查看ipvs代理模式包的传输流程
  • 实战5:Service DNS名称测试
    • 1、coredns小测试
    • 2、ClusterIP A记录格式小实验
  • 总结

写在前面

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

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

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

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

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

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

  4. 个人csdn

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

基础知识

实验环境

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

实验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

2.apply下service.yaml并查看

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

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: {}
  • 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
  • apply下service.yaml
[root@k8s-master ~]#kubectl apply -f service2.yaml
  • 查看
[root@k8s-master ~]#kubectl get pod,svc

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

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

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

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

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

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

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

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

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

实验环境

在实验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

2.apply下service.yaml并查看

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

一般这种情况,工作中很少用到。常规下,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
  • apply下
[root@k8s-master ~]#kubectl apply -f service-clusterip.yaml
service/web6 created
[root@k8s-master ~]#
  • 查看:我们这里没指定–type,默认值就是ClusterIP
  • 排查下这个问题:这个service关联的pod有点不对。。。=>这个其实不多的,是端端口的原因。
[root@k8s-master ~]#kubectl get service -o yaml|grep selector -A  1 #-A 1表示后一行, -B代表前

此时,我们去掉多端口的配置,重新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下并查看:

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

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

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

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

在任意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 ~]#

实验到此结束!

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上
  • apply下并查看
[root@k8s-master ~]#kubectl apply -f service-nodeport.yaml
service/web6 configured
[root@k8s-master ~]#

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

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

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

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

  • 我们可以手动去指定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
  • apply下并查看

浏览器可以查看的:

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

实验到此结束!

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

原课件

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方式的。

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

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

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在哪个节点上?

在node1上:

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

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

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效果一样)

virtual server和real server:

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

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

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

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

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

实验结束!

实战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
  • 进到bs测试容器,查看其dns解析解析:发现pod里的nameserver指向的是coredns
  • 进行解析测试

尝试对如下web6 svc测试:

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

  • 注意

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

实验到此结束!

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

实验结束!

总结

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

(0)

相关推荐