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名称

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_37369726/article/details/121785627