kubernetes pod间通信,跨namespace互访

这篇文章从原理和操作两部分讲解.

原理

kubernetes pod间通信,也就是pod里面的docker应用之间需要通信,首先就需要互相发现对方.
kubernetes使用dns服务作为服务注册中心,kubernetes提供了一个内部的dns服务,集群里面的所有pod和容器都知道它的地址.这个dns服务运行在名为kube-system的namespace中,具体是在它里面的叫做coredns的deployment管理.如下:
在这里插入图片描述
每个service被提交创建的时候都会自动注册到dns中:
1.技术人员post一个新的service部署文件到api server
2.kubernetes对该请求进行认证后通过
3.service会被分配一个Cluster IP的虚拟ip地址
4.创建一个endpoint对象,里面包含匹配到的健康pod
5.部署pod网络来与cluster IP互通
6.service名称和ip被注册到DSN集群中
以上步骤集群DNS会自动监听api server支持监视新service并自动完成注册.
service名称是我们yaml文件中metadata.name中的属性值,ip是自动分配的clusterIP
在这里插入图片描述
当service完成注册后,就会维护service里面的pod,比如扩容和缩容等.service会自动创建一个endpoint对象,这个对象里面包含健康pod,endpoint维护着匹配到Label筛选条件的pod列表.每个节点kubelet进程都会监视api server上出现的新的Endpoint对象,一旦有新的出现,kubelet就会创建相对应的网络规则,将cluster IP的流量转发至pod的ip. 创建这些相对应的网络规则使用的是ipvs技术.
在这里插入图片描述
上面讲了kubernetes将pod之间网络互通起来,但是技术人员应该怎么去使用和操作让pod互联呢,也是先讲原理,这里主要是网络请求的部分:

网络请求

假设有两个service a和b,a里面有一个应用nginxpod,里面有一个apache pod
在这里插入图片描述
kubernetes自动配置所有的容器,让他们可以找到集群dns,是在容器内部的/etc/resolv.conf文件中,添加了dns记录,其中有集群dns ip和搜索域.可以进入容器内部查看
如果a中的nginx需要连接b中http,会先向集群DNS发送名称为a的域名给它解析,集群Dns会返回a的clusterip 192.168.1.10,a中的pod就知道b的地址了,但是需要注意的是Cluster只是一个虚拟ip,想要让请求到达b,就需要利用节点内核的ipvs进行转发.ipvs是kubernetes自动配置的
在这里插入图片描述
这里需要重点注意的是第一步请求DNS解析的service名称.a和b,a可以访问名称b的方式来访问,b就是service的名称.这是同一个namespace中.如果不在同一个namespace中的话,就不可以直接访问名称的方式了.dns域也称集群域,默认是cluster.local,service对象都放在这个地址中,比如a的全域名为a.default.svc.cluster.local,b的全域名为b.default.svc.cluster.local.格式为service名称.namepace名称.svc.cluster.local,这里a和b没写的话都是默认名称空间default.默认名称空间可以直接访问简写service名称a和b也可以访问成功.但是不是默认的话就需要写namespace名称的全域名来访问了.还有就是同一个namespace中service名称不可以相同,但是不同的namespace的话可以相同.比如可以在测试和发布两个namespace中取相同的service.

操作部分:

举例说明:有两个名称空间,里面各有一个deployment部署的pod,各有一个service,其中一个还拥有一个单独的pod,如图:
在这里插入图片描述
编写example.yaml文件部署上面的环境:

apiVersion: v1
kind: Namespace
metadata:
  name: dev
---
apiVersion: v1
kind: Namespace
metadata:
  name: prod
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: enterprise
  labels:
    app: enterprise
  namespace: dev
spec:
  selector:
    matchLabels:
      app: enterprise
  replicas: 2
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: enterprise
    spec:
      terminationGracePeriodSeconds: 1
      containers:
      - image: nigelpoulton/k8sbook:text-dev
        name: enterprise-ctr
        ports:
        - containerPort: 8080
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: enterprise
  labels:
    app: enterprise
  namespace: prod
spec:
  selector:
    matchLabels:
      app: enterprise
  replicas: 2
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: enterprise
    spec:
      terminationGracePeriodSeconds: 1
      containers:
      - image: nigelpoulton/k8sbook:text-dev
        name: enterprise-ctr
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: ent
  namespace: dev
spec:
  selector:
    app: enterprise
  ports:
  - port: 8080
  type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
  name: ent
  namespace: prod
spec:
  selector:
    app: enterprise
  ports:
  - port: 8080
  type: ClusterIP
---
apiVersion: v1
kind: Pod
metadata:
  name: jump
  namespace: dev
spec:
  terminationGracePeriodSeconds: 5
  containers:
  - name: jump
    image: ubuntu
    tty: true
    stdin: true

执行部署命令:

kubectl apply -f example.yaml

在这里插入图片描述
查看是否部署成功:

kubectl get namespaces

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可以看到上面的service,depoyment,pod和单独jump pod都已经部署成功了.

接下实验这几个内容:
1.登入dev中的jump,查看resolv.conf文件内容
2.通过简写名称连接到同namespace dev中的ent应用
3.通过全域名连接到不同namespace prod中的ent应用

1:
在这里插入图片描述
在这里插入图片描述
nameserver就是集群dns的cluster ip地址
search就是搜索域,表明本pod应用在该搜索域下

2:通过简写名称连接到同namespace dev中的ent应用
由于实验的镜像太简版了,啥命令也没有,需要先安装一下curl命令:

apt-get update 
apt-get install -y curl

安装好了之后,访问ent应用,看是否能访问成功:
在这里插入图片描述
在这里插入图片描述
说明访问成功.

3:通过全域名连接到不同namespace prod中的ent应用
在这里插入图片描述
可以看到通过全域名方式访问成功.
ok,上面就已经实验完了.

访问故障排查

可以查看service,deployment,pod的运行状态是否有异常,如果都没有异常,就需要有一台比较不那么简版的镜像部署的pod,有很多网络命令,比如telnet,ping,traceroute,nslookup,dig等来帮助你排查.
例如排查是否时候集群dns解析是否异常:

nslookup kubernetes

成功的话它会返回集群dns的ip,如果返回不能解析kubernetes,就表明dns出了问题,可以重启coredns pod来解决,它会被deployment自动创建.
删除它:

kubectl delete Pod -n kube-system -l k8s-app=kube-dns

查看dns pod是否重新启动,之后再次测试dns

也可以查看dns pod日志:

kubectl logs coredns-bccdc95cf-ncmsb -n kube-system
#coredns-bccdc95cf-ncmsb 是pod名称

在这里插入图片描述

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Kubernetes Pod 网络不通可能有多种原因。 首先,可能是 Pod 所属的 Node 网络故障。这可能是由于 Node 上的网络问题,例如网卡故障、网络配置错误或网络连接断导致的。解决这个问题的方法可以是检查 Node 上的网络连接、查看网络配置或重启 Node。 其次,可能是 Pod 内部容器的网络配置问题。每个 Pod 可以包含多个容器,这些容器之间通过网络进行通信,但容器的网络配置可能存在问题。例如,容器的 IP 地址冲突、容器的网络策略限制、容器的防火墙规则等等。解决这个问题的方法可以是检查容器的网络配置、查看容器日志或重新启动容器。 另外,还有可能是集群网络插件的问题。Kubernetes 支持多种网络插件(如Flannel、Calico等),这些插件负责连接 Pod 和 Node 之间的网络。如果网络插件配置有问题,可能会导致 Pod 网络不通。解决这个问题的方法可以是检查网络插件的配置、查看插件的日志或重新配置插件。 最后,还有可能是网络策略的限制导致 Pod 网络不通。Kubernetes 提供了网络策略功能,可以控制 Pod 之间的网络访问权限。如果网络策略配置有误或设置了不正确的规则,可能会导致 Pod 之间无法通信。解决这个问题的方法可以是检查网络策略的配置、查看策略的规则或调整策略的设置。 总之,Kubernetes Pod 网络不通可能有多种原因,需要根据具体情况进行排查,并寻找对应的解决方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值