计算机系统应用教程网站

网站首页 > 技术文章 正文

Kubernetes Node节点与ClusterIP网络互通实践和总结

btikc 2024-09-04 03:09:51 技术文章 10 ℃ 0 评论

上一篇文章Kubeadm部署CentOS8三节点Kubernetes V1.18.0集群实践 我们大概讲解了在CentOS8下快速部署一个三节点的Kubernetes集群,通过阅读官方文档教程我们发现Kubernetes集群默认安装的时候是没有安装网络插件的,需要我们自己根据实际环境情况和网络划分去规划我们Kubernetes集群的网络。Kubernetes支持的网络插件还是比较多的,如下图:

可能在开发测试环境大家使用比较多的是Calico和Flannel,Calico的优势在于它支持下发网络策略。

Kubernetes官网有一句这样的话:目前Calico是kubeadm项目执行e2e测试的唯一CNI插件。在我们安装的三节点环境中,笔者同样部署了Calico网络插件,使用命令kubectl和Dashboard Web界面查看node和pod状态都是没问题的,所有node节点处于Read状态,所有pod处于Running状态。同时笔者在这个三节点集群中部署了2个pod的nginx服务,部署过程一切正常。

同时也暴露了8090服务,ClusterIP地址也正常产生了:

一切操作看着都OK,但是问题来了:

  • 在master节点执行curl 172.100.240.106:8090,正常情况下会返回nginx的欢迎界面html,实际情况是得不到任何响应,并且超时;
  • 在2个node节点执行curl 172.100.240.106:8090,有50%的概率能够获得nginx的欢迎界面html,50%的概率是得不到任何响应,并且超时;

超时情况:

[root@instance01 ~]# curl 172.100.240.106:8090
curl: (7) Failed to connect to 172.100.240.106 port 8090: Connection timed out

正常情况:

[root@instance03 ~]# curl 172.100.240.106:8090
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

笔者查阅了Kubernetes官网文档,同时也在网络上查阅了大量资料,使用kubeadm也重新构建了好多次集群,问题依然存在。不得不承认网络这一大块的知识领域可能是笔者的弱项,网络这一块的知识还停留在大学的非专业课水准,平时也没有做专项训练和深入学习。对于上面的问题现象,笔者可能需要再积累更多的网络知识才能够对问题的原因阐述的更情况。

那么可以肯定的是导致这个问题现象的原因应该是网络问题,我们再把我们的三节点集群的网络环境梳理下:

  • 三节点分别通过虚拟机创建;
  • 三节点每一个虚拟机都有2个网卡,eth0通过dhcp获取动态地址并且跟宿主机网络互通,eth1使用固定IP地址,IP地址段10.0.0.0/24,这个网络平面跟宿主机网络不互通;
  • 初始化Kubernetes集群的时候,使用的是eth1 10.0.0.0/24这个网络平面;

为了验证到底是不是因为在初始化Kubernetes的时候使用了固定IP地址段这个网络平面,才造成上面问题的出现,最简单的方法是,我们重新创建三个虚拟机,并且只有一个网卡eth0不使用固定IP地址,全部使用dhcp获取IP地址。


部署方式还是采用上一篇Kubeadm部署CentOS8三节点Kubernetes V1.18.0集群实践的部署方式,只不过我们把初始化Kubernetes集群的pod地址池稍做调整:

kubeadm init --kubernetes-version=1.18.0  \
--apiserver-advertise-address=172.18.35.135   \
--image-repository registry.aliyuncs.com/google_containers  \
--service-cidr=10.96.0.0/16 --pod-network-cidr=192.168.0.0/16
  • apiserver-advertise-address=172.18.35.135是我们master节点eth0的IP地址,该IP地址是dhcp动态获取的;
  • service-cidr=10.96.0.0/16是kubeadm的默认参数;
  • pod-network-cidr=192.168.0.0/16我们规格一个192网段的pod地址段,pod是Kubernetes中最小的单位,这个参数对我们验证应该没什么影响;

把另外两个节点加入到Kubernetes集群中

nginx-deployment.yaml

kind: Deployment
apiVersion: apps/v1
metadata:
  name: nginx-web-server
  namespace: web-system
  resourceVersion: '4012'
  generation: 1
  labels:
    k8s-app: nginx-web-server
  annotations:
    deployment.kubernetes.io/revision: '1'
  managedFields:
    - manager: dashboard
      operation: Update
      apiVersion: apps/v1
      fieldsType: FieldsV1
    - manager: kube-controller-manager
      operation: Update
      apiVersion: apps/v1
      fieldsType: FieldsV1
spec:
  replicas: 2
  selector:
    matchLabels:
      k8s-app: nginx-web-server
  template:
    metadata:
      name: nginx-web-server
      labels:
        k8s-app: nginx-web-server
    spec:
      containers:
        - name: nginx-web-server
          image: nginx
          resources: {}
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          imagePullPolicy: Always
          securityContext:
            privileged: false
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
      dnsPolicy: ClusterFirst
      securityContext: {}
      schedulerName: default-scheduler
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 25%
      maxSurge: 25%
  revisionHistoryLimit: 10
  progressDeadlineSeconds: 600

nginx-rc.yaml

kind: ReplicaSet
apiVersion: apps/v1
metadata:
  name: nginx-web-server-7fccf59578
  namespace: web-system
  resourceVersion: '4011'
  generation: 1
  labels:
    k8s-app: nginx-web-server
    pod-template-hash: 7fccf59578
  annotations:
    deployment.kubernetes.io/desired-replicas: '2'
    deployment.kubernetes.io/max-replicas: '3'
    deployment.kubernetes.io/revision: '1'
  ownerReferences:
    - apiVersion: apps/v1
      kind: Deployment
      name: nginx-web-server
      controller: true
      blockOwnerDeletion: true
  managedFields:
    - manager: kube-controller-manager
      operation: Update
      apiVersion: apps/v1
      time: '2020-08-13T07:31:37Z'
      fieldsType: FieldsV1
spec:
  replicas: 2
  selector:
    matchLabels:
      k8s-app: nginx-web-server
      pod-template-hash: 7fccf59578
  template:
    metadata:
      name: nginx-web-server
      creationTimestamp: null
      labels:
        k8s-app: nginx-web-server
        pod-template-hash: 7fccf59578
    spec:
      containers:
        - name: nginx-web-server
          image: nginx
          resources: {}
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          imagePullPolicy: Always
          securityContext:
            privileged: false
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
      dnsPolicy: ClusterFirst
      securityContext: {}
      schedulerName: default-scheduler

nginx-service.yaml

kind: Service
apiVersion: v1
metadata:
  name: nginx-web-server
  namespace: web-system
  resourceVersion: '3927'
  labels:
    k8s-app: nginx-web-server
  managedFields:
    - manager: dashboard
      operation: Update
      apiVersion: v1
      time: '2020-08-13T07:31:17Z'
      fieldsType: FieldsV1
spec:
  ports:
    - name: tcp-8090-80-5b92b
      protocol: TCP
      port: 8090
      targetPort: 80
  selector:
    k8s-app: nginx-web-server
  clusterIP: 10.96.211.19
  type: ClusterIP
  sessionAffinity: None

在master节点上执行如下命令:

kubectl apply -f nginx-deployment.yaml
kubectl apply -f nginx-rc.yaml
kubectl apply -f nginx-service.yaml

同样部署2个pod的ngixn服务:

暴露服务获取ClusterIP地址和端口:

在master节点执行如下命令:

[root@instance05 ~]# curl 10.96.211.19:8090
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

node节点:

[root@instance06 ~]# curl 10.96.211.19:8090
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@instance07 ~]# curl 10.96.211.19:8090
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

现在我们三节点的Kubernetes集群网络拓扑是这样的:


通过上述验证,我们可以得出:

  • 三节点之间的网络是互通的,节点与节点之间的pod网络也是互通的;
  • 三节点任意节点都可以访问我们的ClusterIP;

我们大概分析下出现master节点与ClusterIP不通的原因:

  • 上一篇文章中我们使用的是10.0.0.0/24这个网络平面,这个IP地址段的IP地址都是固定IP,也就是说我们Kubernetes集群节点使用的是固定IP。这个网络平面可以理解成内网的一个二层(L2)网络,这个二层网络没有默认路由规则。
  • Calico在节点上产生的虚拟网段与10.0.0.0/24这个网络网段不通,没有默认路由规则;
  • 可能Calico在节点上产生的虚拟网段数据包通过eth0这个网卡发送,而我们的Kubernetes集群的数据包是通过eth1这个网卡发送,也就是说数据包走的网卡不一样;
  • Calico可能需要在每个节点上使用一个三层(L3)的网络支持,并且需要存在一个默认的路由规则;
  • 也可能我们需要手动添加一些路由规则或者使用iptables添加一些转发规则;

至于出现上面instance01与ClusterIP不通的根本原因,涉及大量的网络知识。笔者可能需要再查询下Kubernetes官方文档和积累相关网络知识才能够阐述的更清楚些。

把整个实践过程和排查问题记录下来是方便以后遇到类似问题,可以回过头来查阅,同时也是总结自己实践经验的过程,俗话说:“好记性不如淡墨水”。通过不断实践不断总结,这样才能拓展自己的知识面,提升自己的技能和技术水准。


不积跬步,无以至千里;不积小流,无以成江海!

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表