通常情況下k8s叢集中pod使用的是單獨劃分的一個虛拟子網,處于這個子網中的pod通過nat位址轉換的方式通路叢集外部。
如果要在叢集外部通路pod,通常可以使用三種方式:NodePort,HostPort和LoadBalancer。其中NodePort最為常用,在每個kube-proxy節點上開啟代理端口以供外部通路。除此之外有沒有别的辦法可以在叢集直接通路到Pod呢?答案是有的。
假設現在有一套已經搭建好的k8s叢集,使用Calico做為cni元件,檢視每個節點上的路由表
route -n | grep tunl0
可以看到如下内容
.233.119.0 10.21.21.74 255.255.255.192 UG 0 0 0 tunl0
10.233.55.64 10.21.21.76 255.255.255.192 UG 0 0 0 tunl0
10.233.183.64 10.21.21.75 255.255.255.192 UG 0 0 0 tunl0
這是calico建立的tunnel,用于實作叢集間容器的互相通路,通過這些可以得知每個節點中所劃分的pod網段。
我們要做的是就是把這幾個路由規則加入到路由器或者用戶端機器上
route add -net 10.233.55.64 netmask 255.255.255.192 gw 10.21.21.76
route add -net 10.233.119.0 netmask 255.255.255.192 gw 10.21.21.74
route add -net 10.233.183.64 netmask 255.255.255.192 gw 10.21.21.75
之後我們在k8s中起一個容器做測試,如
100m
memory: 100Mi
ports:
- containerPort: 80
volumeMounts:
- name: timezone
mountPath: /etc/localtime
volumes:
- name: timezone
hostPath:
path: /usr/share/zoneinfo/Asia/Shanghai
再檢視已啟動的pod
kubectl get pod -o wide
結果如下:
NAME READY STATUS RESTARTS AGE IP NODE
centos 1/1 Running 0 2d 10.233.55.69 10.21.21.76
我們在用戶端機器上直接通路該pod
ping 10.233.55.69
成功響應
10.233.55.69 (10.233.55.69) 56(84) bytes of data.
64 bytes from 10.233.55.69: icmp_seq=1 ttl=63 time=0.442 ms
64 bytes from 10.233.55.69: icmp_seq=2 ttl=63 time=0.328