k8s與雲服務器之間服務互訪之節點網絡打通

1、概述html

k8s暴露服務的方式有不少使用ingress、nodeport等,這類比較適用於無狀態的服務,對於statefulset部署的有狀態的服務,(關於statefulset的介紹參考kubernetes的官網或參考個人https://www.cnblogs.com/cuishuai/p/10243291.html),因爲statefulset使用的是headless service。是固定網絡標示的,也就是服務的完整域名是不會改變的。可是有兩個問題:node

      一、物理機在k8s集羣的外面沒辦法解析k8s集羣內部的域名docker

      二、解析域名後網絡不能通訊bash

2、物理網絡與k8s集羣打通服務器

有了上面提出的兩個問題,咱們先來簡單分析一下k8s的網絡,咱們使用的是calico-bgp+ipvs,因此這裏就以calico爲例,calico爲k8s提供了一個網絡空間,提供的地址池和k8s初始化時指定的pod-cidr是相同的。部署服務的時候會在地址池裏面爲pod分配地址,好比設置的是192.168.0.0/16,首先是分配node節點,通常狀況下calico會先給node節點隨機分配一個網段,例若有個節點是node1 ,calico會分配一個192.168.19.0網段,具體的子網掩碼(netmask)要看路由表在任意節點上執行(route -n)查看。網絡

查看具體的分配,部署calico的時候選擇的是將數據存儲到etcd集羣,因此也能夠去etcd裏面產看:less

# etcdctl get --prefix "/calico" --keys-only | grep "ipam/v2/host"

/calico/ipam/v2/host/ku13-1/ipv4/block/192.244.190.128-26 /calico/ipam/v2/host/ku13-1/ipv4/block/192.244.190.192-26 /calico/ipam/v2/host/ku13-2/ipv4/block/192.244.32.0-26 /calico/ipam/v2/host/ku13-2/ipv4/block/192.244.32.64-26 /calico/ipam/v2/host/ku13-3/ipv4/block/192.244.6.192-26 /calico/ipam/v2/host/ku13-3/ipv4/block/192.244.7.0-26 /calico/ipam/v2/host/ku13-3/ipv4/block/192.244.7.64-26 /calico/ipam/v2/host/ku13-4/ipv4/block/192.244.70.0-26

還有一個服務kube-proxy,這個服務負責node之間的網絡通訊,刷新ipvs列表。具體的calico和kube-proxy工做詳情這裏不作詳解。工具

 

咱們瞭解到要想解決咱們上面提出的兩個問題,咱們須要將kubernets裏面的coredns服務拿出來,爲物理機提供dns解析、而後須要將物理機與k8s集羣網絡打通。接下來咱們解決這兩個問題:測試

 

解決第一個問題也須要以第二個問題爲前提,因此咱們只須要解決了第二個問題,第一個問題只須要在物理機上面的/etc/resolv.conf添加一條nameserver記錄。ui

解決第二個問題:網絡打通

打通網絡咱們須要兩個工具:calico、kube-proxy

咱們以前的集羣都是使用kubeadm部署的,因此咱們能夠很簡單實現這兩個服務的部署,若是不是使用kubeadm部署的集羣能夠參考網上這個服務的部署,本文不作介紹。主要介紹kubeadm部署的實現。

 

咱們準備一個服務器,上面須要部署kubeadm、docker具體的準備參考以前的集羣初始化,咱們將新服務器以node節點的形式加入到集羣裏面,使用kubeadm join很方便的將服務器加入到現有的k8s集羣裏面,這個服務器只須要分配很小的資源,由於這個上面不會部署任何服務,只有kubeadm join時部署的calico-node、kube-proxy。

添加節點參考:https://www.cnblogs.com/cuishuai/p/9897006.html

節點成功加入集羣后還要執行一個操做,就是設置節點不能被調度:

kubctl  drain  [node-name]  --ignore-daemonsets

 

這樣咱們新加入的這個節點上面只部署了calico-node、kube-proxy,而且該服務器節點是能和k8s集羣通訊的,咱們把該節點做爲k8s網絡與物理網絡的gateway,全部物理服務器進入k8s集羣網絡的路由都通過這個gateway。這樣就實現了通信。

 

二、生成路由規則

在上面新部署的服務器上面有到k8s集羣的全部路由,咱們將這些路由進行提取生成一個路由表給物理機使用,將全部路由設置成默認路由,都通過上面新加服務器的ip。

爲了方便使用我寫了一個生成腳本,此腳本在gateway節點即上面新加的節點上面執行:

#cat generate-rule

#!/bin/bash route -n | grep UG | grep -v ^0 | awk '{print $1,$3}' >a.txt ip=`ip a | grep eth0 | grep inet |awk -F '/' '{print $1}'|awk '{print $2}'`

service_net="192.96.0.0"
service_mask="255.255.0.0" #判斷route.rule文件是否存在
if [ -f route.rule ];then >route.rule fi
#生成route.rule文件
#添加coredns的路由
echo "route add -net $service_net netmask $service_mask gw $ip" >route.rule
while read NT MK do echo "route add -net $NT netmask $MK gw $ip " >>route.rule done < a.txt #刪除臨時文件 rm -rf a.txt

 

service_net是k8s service的網段,即coredns的service ip所在的網段,service_mask是k8s service的子網掩碼,這個在使用kubeadm初始化的時候就指定了,咱們使用的是:

https://www.cnblogs.com/cuishuai/p/9897006.html

 podSubnet: 192.244.0.0/16 serviceSubnet: 192.96.0.0/16

將service_net、service_mask換成本身的。

而後將生成的文件copy到物理機上,而後執行:

sh  route.rule

 

在物理機上面在/etc/resolv.conf裏面添加coredns的service的ip,service名稱是kube-dns,在任意master節點上查看:

kubectl get svc -n kube-system | grep kube-dns
kube-dns         ClusterIP   192.96.0.10      <none>        53/UDP,53/TCP   7d8h

 

將找到的ip地址添加到/etc/resolv.conf:

nameserver 192.96.0.10

 

在物理機上面測試連通性:

相關文章
相關標籤/搜索