K8S知识点记录—网络通信

前言

对于刚接触K8s的新人来说,K8S的网络通信太复杂了,每个点都可以深入很多很多,这篇文章记录自己网络通信的一个整体认识,帮助快速上手。


一、K8S的网络通信汇总

根据自己的梳理画了一个图(从用户到pod的一个网络通信图,目的是快速打通网络流)
K8S知识点记录—网络通信_第1张图片
图中的概念介绍:

  • K8S中三类IP,NodeIP,PodIP,ClusterIP

Node IP:Node节点的IP地址,即物理网卡的IP地址
Pod IP:Pod的IP地址,即docker容器的IP地址,此为虚拟IP地址
Cluster IP:Service的IP地址,此为虚拟IP地址。
讲得比较透彻的文章: https://ld246.com/article/1579223129877

  • 三种IP之间的通信(使用busybox去做测试)

NodeIP ping PodIP —》yes Flannel插件解决
NodeIp ping ClusterIP —>No —》k8s的kube-proxy支持iptables、ipvs模式,默认iptables模式,改为ipvs即可以实现pod与service通信
PodIp ping ClusterIp —> No —》k8s的kube-proxy支持iptables、ipvs 模式,默认iptables模式,改为ipvs即可以实现pod与service通信
外网 Ping三个Ip --> ping NodeIP(公网) OK;ping PodIP No;ping Cluster IP No;

  • Flannel 作用:网络插件

CNI CNI(container network interface)是容器网络接口 是K8s中提供的一种通用网络标准规范,因为k8s本身不提供网络解决方案 以插件方式使用, 为用户在pod创建或者销毁时动态配置网络。

  1. 确保整个集群中Pod IP不重复
  2. 建立所有Pod的覆盖网络,使得Pod之间可以相互通信
  • k8s中关于kube-proxy的iptables模式和ipvs模式探讨

k8s默认为iptables,从1.8版本加入了ipvs模式,
ipvs和iptables都是基于netfilter的,他们的差别为:
ipvs 为大规模集群提供了更好的可扩展性和性能
ipvs 支持比 iptables 更复杂的复制均衡算法(最小负载、最少连接、加权轮询等)
ipvs 支持服务器健康检查和连接重试等功能

  • k8s中Ingress探讨:k8s还提供一种集群维度暴露服务的方式的对象

Ingress 主要分为两部分:

  • Ingress Controller 是流量的入口,是一个实体软件, 一般是Nginx 和 Haproxy 。
  • Ingress 描述具体的路由规则。
  • 集群内通信&外部通信

我们知道集群内,Pod与Pod之间的通信(服务暴露和发现):

  • service会自动为pod创建环境变量,在其他Pod中可以通过该环境变量访问。要求Service在Pod只之前创建。进入Pod,可以通过Env查看环境变量。
  • DNS:CoreDNS,kubelet自动为Pod设置DNS,Pod之间可以直接通过 解析域名访问,也可以自定义定义:spec.hostname spec.subdomain ----->DNS注册机制

想要直接把集群服务暴露出来,我们可以使用NodePort 和 Loadbalancer 类型的 Service

  • ClusterIP 默认的,仅在集群内可用
  • NodePort 暴露端口到节点,提供了集群外部访问的入口 端口范围固定 30000 ~ 32767
  • LoadBalancer 需要负载均衡器(通常都需要云服务商提供) 会额外生成一个 IP 对外服务 。K8S 支持的负载均衡器:负载均衡器
  • Headless 适合数据库 clusterIp 设置为 None 就变成 Headless 了,不会再分配 IP,后面会再讲到具体用法
  • Ingress:在Service基础上进行一层封装,做路由配置,流量转发。

二、实际测试

在实际应用中,重点是怎么测试网络是否联通,以下是个人采用的一些方法:总的来说,测试网络是否联通就用如下命令:ping(busybox) + curl(nginx做测试)+telnet node-ip node-port

1. 网络插件 Flannel的使用

K8S提供 CNI接口,但是不实现网络解决方案,需要使用插件解决。看安装提示语句:
K8S知识点记录—网络通信_第2张图片
初始化Master之后有明确提示:
You should now deploy a pod network to the cluster.
Run “kubectl apply -f [podnetwork].yaml” with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
我们选择最简单的。最常用的Flannel作为 K8S的CNI。

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

2. 修改kube-proxy iptables模式为ipv模式

到目前为止:解决pod与service直接的通信,跨主机,跨namespace
参考:https://blog.csdn.net/Urms_handsomeyu/article/details/106294085?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2defaultCTRLISTRate-1.pc_relevant_aa&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2defaultCTRLISTRate-1.pc_relevant_aa&utm_relevant_index=2

修改方法:
查看: kubectl get cm kube-proxy -n kube-system -o yaml
修改: kubectl edit configmap kube-proxy -n kube-system
metricsBindAddress: “127.0.0.1:10249
mode: “ipvs
删除kube-system 命名空间下的kube-proxy:kubectl -n kube-system delete pods kube-proxyxxx kube-proxyxxy kube-proxyxxz…(删除之后,会自动重新创建)
查看是否生效:kubectl logs kube-proxy-xxx, 查找关键字 Using ipvs Proxier
K8S知识点记录—网络通信_第3张图片

3. 通过Endpoint对象查看 Service与Pod关联情况

如下图,Service通过spec.selector去匹配Deployment中的spec.template.metadata.labels。
K8S知识点记录—网络通信_第4张图片
通过kubectl describe svc my-busybox 查看Endpoint对象,从下图中可以看出 PodIP与ClusterIP的关系。
K8S知识点记录—网络通信_第5张图片

4. 使用busybox测试网络联通性

  • 创建:NS(cni-test)、SVC(my-busybox)、Deployment(app)
  • 创建:NS(cni-test-2c)、SVC(my-busybox)、Deployment(app)
  • 进入随意一个Pod,ping NodeIP, ping ClusterIP, ping PodIP,可以看到都能ping通,证明网络是联通的。
    K8S知识点记录—网络通信_第6张图片
    Yaml文件:
apiVersion: v1
kind: Namespace
metadata:
  name: cni-test

---
apiVersion: v1
kind: Service
metadata:
  name: my-busybox
  namespace: cni-test
spec:
  selector:
    run: app
  ports:
  - port: 80
    targetPort: 80

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
  namespace: cni-test
spec:
  replicas: 10
  selector:
    matchLabels:
      run: app
  template:
    metadata:
      labels:
        run: app
    spec:
      containers:
      - name: app
        image: busybox        #内置的linux大多数命令,多用于测试
        args:
        - /bin/sh
        - -c
        - sleep 10; touch /tmp/healthy; sleep 30000
        readinessProbe:           #就绪探针
          exec:
            command:
            - cat
            - /tmp/healthy
          initialDelaySeconds: 10         #10s之后开始第一次探测
          periodSeconds: 5                #第一次探测之后每隔5s探测一次
apiVersion: v1
kind: Namespace
metadata:
  name: cni-test-2c

---
apiVersion: v1
kind: Service
metadata:
  name: my-busybox
  namespace: cni-test-2c
spec:
  selector:
    run: app
  ports:
  - port: 80
    targetPort: 80

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
  namespace: cni-test-2c
spec:
  replicas: 3
  selector:
    matchLabels:
      run: app
  template:
    metadata:
      labels:
        run: app
    spec:
      containers:
      - name: app
        image: busybox        #内置的linux大多数命令,多用于测试
        args:
        - /bin/sh
        - -c
        - sleep 10; touch /tmp/healthy; sleep 30000
        readinessProbe:           #就绪探针
          exec:
            command:
            - cat
            - /tmp/healthy
          initialDelaySeconds: 10         #10s之后开始第一次探测
          periodSeconds: 5                #第一次探测之后每隔5s探测一次

---
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
  namespace: cni-test-2c
spec:
  replicas: 3
  selector:
    matchLabels:
      run: app-2
  template:
    metadata:
      labels:
        run: app-2
    spec:
      containers:
      - name: app-2
        image: busybox        #内置的linux大多数命令,多用于测试
        args:
        - /bin/sh
        - -c
        - sleep 10; touch /tmp/healthy; sleep 30000
        readinessProbe:           #就绪探针
          exec:
            command:
            - cat
            - /tmp/healthy
          initialDelaySeconds: 10         #10s之后开始第一次探测
          periodSeconds: 5                #第一次探测之后每隔5s探测一次

5. 腾讯云CVM部署 K8S的外网访问排查

在这里插入图片描述
1、创建 nginx测试 NodePort功能
2. 外网IP:31090 ,无法访问
K8S知识点记录—网络通信_第7张图片
排查: 查看如上信息,pod、service都没问题,就是外网访问的时候,提示无法访问。

step1:Node上 curl pod资源 ---->通信OK
K8S知识点记录—网络通信_第8张图片
Step2:在Node上 curl service资源 —》通信OK
K8S知识点记录—网络通信_第9张图片
Step3:Node上 Curl 内网IP:31090 —>通信Ok
K8S知识点记录—网络通信_第10张图片
Step4:在外网上,Curl 外网IP:31090 —》No,说明在获取公网地址:端口 的时候 未获取到资源。
K8S知识点记录—网络通信_第11张图片
---- 百度查找:原因是 Linux禁止 iptables,ipvs流量转发?
对于iptables:设置 iptables -P FORWARD ACCEPT,#再查看 sudo iptables -S; 可以参考:https://www.cnblogs.com/gaoyuechen/p/14307141.html
对于ipvs:需要通过ipvsadm 管理,可以参考:
https://blog.csdn.net/cloudvtech/article/details/80199653
https://www.jianshu.com/p/865fe1469c74
还是无法解决,问题就出在 内网相关端口,或者其他不知道的什么东西没有暴露给外网,服务器本身有问题。而我的环境是 腾讯云,
WC,腾讯云创建的时候选择了一个安全组,一查,发现问题了,31090端口没暴露给外网…

K8S知识点记录—网络通信_第12张图片
解决办法: 直接将安全组设置为【放通全部端口-…】
K8S知识点记录—网络通信_第13张图片
nginx测试NodePort的yaml如下:

apiVersion: v1
kind: Namespace
metadata:
  name: pod-nginx-test

---
apiVersion: v1
kind: Service
metadata:
  name: my-nginx
  namespace: pod-nginx-test
spec:
  selector:
    name: my-nginx-pod-test
  type: NodePort
  ports:
  - port: 80
    targetPort: 80
    nodePort: 31090

---
apiVersion: v1
kind: Pod
metadata:
  name: my-nginx-pod-test
  namespace: pod-nginx-test
  labels:
    name: my-nginx-pod-test
spec:
  containers:
  - name: my-nginx-pod-test
    image: nginx
    resources:
      limits:
        memory: "128Mi"
        cpu: "500m"
    ports:
      - containerPort: 80

总结

提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

你可能感兴趣的:(运维开发,运维开发)