K8S搭建筆記
一睹簇、搭建過程
1.1 總體說明
本文主要記錄kubernetesV1.6版本的搭建浸卦、并在其中部署一個(gè)Nginx和監(jiān)控臺的過程。僅簡單介紹kubernetes的部分概念胸遇,不作展開村缸,詳細(xì)內(nèi)容自行下來了解。主要參考網(wǎng)絡(luò)上“宋靜超”搭建K8S痢虹,對其文章中可能混淆的地方加以注解被去。完整過程請參考他的博客。
在CentOS上部署kubernetes集群
https://jimmysong.io/kubernetes-handbook/practice/install-kubernetes-on-centos.html
1.2虛擬機(jī)準(zhǔn)備
總共需要3臺虛擬機(jī)奖唯,如下表所示
主機(jī) | IP | 角色 | 需要安裝的軟件 |
---|---|---|---|
master | 192.168.0.241 | K8S master節(jié)點(diǎn) | docker Flannel etcd apiserver controller-manager scheduler |
node1 | 192.168.0.242 | K8S node節(jié)點(diǎn) | docker Flannel etcd kubelet kube-proxy |
node2 | 192.168.0.243 | K8S node節(jié)點(diǎn) | docker Flannel etcd kubelet kube-proxy |
節(jié)點(diǎn)角色說明
-
master
Master節(jié)點(diǎn)負(fù)責(zé)對外提供一系列管理集群的API接口惨缆,并且通過和 node 節(jié)點(diǎn)交互來實(shí)現(xiàn)對集群的操作管理 -
node
node節(jié)點(diǎn)為運(yùn)行 Docker容器的節(jié)點(diǎn),負(fù)責(zé)和節(jié)點(diǎn)上運(yùn)行的 Docker 進(jìn)行交互丰捷,并且提供了代理功能
公共組件說明
-
docker
運(yùn)行在所有節(jié)點(diǎn)坯墨,容器基礎(chǔ)服務(wù) -
flannel
運(yùn)行在所有節(jié)點(diǎn),一個(gè)專為kubernetes定制的三層網(wǎng)絡(luò)解決方案病往,主要用于解決容器的跨主機(jī)通信問題 -
etcd
集群方式運(yùn)行在所有節(jié)點(diǎn)捣染,key-value鍵值存儲(chǔ)數(shù)據(jù)庫,用來存儲(chǔ)kubernetes的信息的 -
apiserver
運(yùn)行在master節(jié)點(diǎn)停巷,用戶和 kubernetes 交互的入口耍攘,封裝了核心對象的增刪改查操作榕栏,提供了 RESTFul 風(fēng)格的 API 接口,通過etcd來實(shí)現(xiàn)持久化并維護(hù)對象的一致性 -
controller-manager
運(yùn)行在master節(jié)點(diǎn)少漆,主要是用于保證 replication Controller 定義的復(fù)制數(shù)量和實(shí)際運(yùn)行的 pod 數(shù)量一致臼膏,另外還保證了從 service 到 pod 的映射關(guān)系總是最新的 -
scheduler
運(yùn)行在master節(jié)點(diǎn),負(fù)責(zé)集群資源的調(diào)度和管理示损,例如當(dāng)有 pod 異常退出需要重新分配機(jī)器時(shí)渗磅,scheduler 通過一定的調(diào)度算法從而找到最合適的節(jié)點(diǎn)。 -
kubelet
運(yùn)行在 node節(jié)點(diǎn)检访,負(fù)責(zé)和節(jié)點(diǎn)上的Docker交互始鱼,例如啟停容器,監(jiān)控運(yùn)行狀態(tài)等脆贵。 -
proxy
運(yùn)行在 node節(jié)點(diǎn)医清,負(fù)責(zé)為 pod 提供代理功能,會(huì)定期從 etcd 獲取 service 信息卖氨,并根據(jù) service 信息通過修改 iptables 來實(shí)現(xiàn)流量轉(zhuǎn)發(fā)(最初的版本是直接通過程序提供轉(zhuǎn)發(fā)功能会烙,效率較低。)筒捺,將流量轉(zhuǎn)發(fā)到要訪問的 pod 所在的節(jié)點(diǎn)上去柏腻。 -
kubectl kube命令行工具
這是一個(gè)運(yùn)行kube的腳本程序,可以理解為空K8S的cmd腳本工具系吭,是用戶和k8s在命令級別微觀溝通橋梁
1.3 常規(guī)組件安裝
1.3.1組件安裝順序
1.3.2 Docker安裝
每臺主機(jī)都要安裝Docker五嫂,不建議直接在Centos中使用yum install docker。否則安裝的版本比較老
安裝docker肯尺,下載鏈接如下所示沃缘。目前使用18.03版本。==建議下載rpm包则吟,使用以下方法安裝==
https://docs.docker.com/install/linux/docker-ce/centos/
yum install 絕對路徑/docker-ce-1803.rpm
1.3.3-A 證書制作
kubernetes 系統(tǒng)的各組件需要使用 TLS 證書對通信進(jìn)行加密槐臀,Jimmy的博客中使用 CloudFlare 的 PKI 工具集 cfssl 來生成 Certificate Authority (CA) 和其它證書;關(guān)于Kubernetes和證書的關(guān)系可以參考書目或者以下鏈接
《如何理解Kubernetes認(rèn)證和授權(quán)》
這邊文章是翻譯的官方文檔氓仲,解釋的比較通透峰档,不過只翻譯了部分,關(guān)于認(rèn)證和授權(quán)的詳細(xì)信息沒有翻譯到,鏈接如下:
《Kubernetes 認(rèn)證》
這是kubernetes中文社區(qū)的文檔寨昙,介紹的比較全讥巡,但是剛看的時(shí)候可能有點(diǎn)懵,實(shí)際上對于認(rèn)證和授權(quán)舔哪,如果沒有認(rèn)識欢顷,建議還是跟著jimmy的教程配置一次,再反過來看捉蚤,可能更容易接受,鏈接如下:
安裝方法:
- 建議直接跟隨《5.2.1. 創(chuàng)建TLS證書和秘鑰》所述方法配置抬驴。
- CFSSL建議就不用文中的go語言方式安裝了炼七,可直接用文中二進(jìn)制方法安裝。
- 創(chuàng)建 kubernetes 證書 一節(jié)中127.0.0.1和10.254.0.1保留布持,其余換成自己的主機(jī)地址
1.3.3-B kubectl工具
kubectl是k8s集群的命令行工具豌拙,其概念可以參考Windows的cmd、Linux上的shell题暖。master節(jié)點(diǎn)因?yàn)橐獔?zhí)行眾多命令按傅,肯定是需要安裝的。node節(jié)點(diǎn)按需安裝胧卤,即如果有需要在node節(jié)點(diǎn)上也要執(zhí)行創(chuàng)建pod唯绍、service等操作,就需要在pod上安裝此工具枝誊。
安裝方法:
- 建議直接跟隨《5.2.4. 安裝kubectl命令行工具》所述方法配置
- KUBE_APISERVER配置說明
KUBE_APISERVER="https://172.20.0.113:6443"
KUBE_APISERVER即master所在主機(jī)的地址况芒,無論是在node配置kubectl還是master都是安裝KUBE_APISERVER的地址(這里暫時(shí)未考慮master節(jié)點(diǎn)的高可用)。
1.3.4 Etcd集群安裝
K8S依賴Etcd作為服務(wù)發(fā)現(xiàn)等功能叶撒,所以需要搭建Etcd組件绝骚。Etcd可以搭建單機(jī),也可以搭建集群祠够。目前按照集群方式搭建皮壁。在每臺主機(jī)上安裝。
安裝方法
- Jimmy博客《5.2.3創(chuàng)建高可用 etcd 集群》
- 直接按照博客方法安裝即可
1.3.5 master節(jié)點(diǎn)部署
這部分主要是在master節(jié)點(diǎn)上部署APIserver哪审、scheduler和controller
部署安裝方法
- 可以直接按照《5.2.5. 部署master節(jié)點(diǎn)》 部分內(nèi)容直接部署
- 針對博客的補(bǔ)充說明
- kubernetes-server-linux-amd64.tar.gz 這個(gè)文件較大,wget如果失敗虑瀑,建議直接下載手工上傳到主機(jī)
- 每個(gè)組件安裝完成后湿滓,建議驗(yàn)證一下功能再向前。
1.3.6 node節(jié)點(diǎn)部署
這部分主要是在node節(jié)點(diǎn)上部署kube和kube-proxy
部署安裝方法
- 可以直接按照《5.2.7. 部署node節(jié)點(diǎn)》 部分內(nèi)容直接部署
- 針對博客的補(bǔ)充說明
- Jimmy的博客在本節(jié)開篇講解了flannel接手docker網(wǎng)絡(luò)的配置舌狗,這部分的參照作者的配置叽奥,并未達(dá)到目的————也即在后續(xù)使用代理訪問dashboard時(shí)候,提示沒有到node-docker地址的路由痛侍,這部分解決方法朝氓,放到了二、問題集2.3代理方式無法訪問dashboard說明主届,請移步該節(jié)查看解決方案赵哲。
- /etc/kubernetes/kubelet 關(guān)于配置文件的問題,請直接看注釋(針對192.168.0.242)
##我的注釋:KUBELET_ADDRESS這個(gè)配置君丁,參看網(wǎng)絡(luò)很多配置這里都寫的是0.0.0.0 或者"",所以我這里也留了空沒有寫枫夺。不妨礙成功啟動(dòng)。
## The address for the info server to serve on (set to 0.0.0.0 or "" for all interfaces)
##原文配置KUBELET_ADDRESS="--address=172.20.0.113"
KUBELET_ADDRESS=""
#
## The port for the info server to serve on
#KUBELET_PORT="--port=10250"
#
##我的注釋:這里如果要覆蓋绘闷,請直接寫正在配置的node的地址橡庞,原文給人造成歧義较坛,寫的是master的地址。
## You may leave this blank to use the actual hostname
##原文配置KUBELET_HOSTNAME="--hostname-override=172.20.0.113"
KUBELET_HOSTNAME="--hostname-override=192.168.0.242"
#
## location of the api-server
## COMMENT THIS ON KUBERNETES 1.8+
KUBELET_API_SERVER="--api-servers=http://192.168.0.241:8080"
#
##我的注釋:如果沒有私有倉庫扒最,請直接保留為"""即可
## pod infrastructure container
##原文配置KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=harbor-001.jimmysong.io/library/pod-infrastructure:rhel7"
#
## Add your own!
KUBELET_ARGS="--cgroup-driver=systemd --cluster-dns=10.254.0.2 --experimental-bootstrap-kubeconfig=/etc/kubernetes/bootstrap.kubeconfig --kubeconfig=/etc/kubernetes/kubelet.kubeconfig --require-kubeconfig --cert-dir=/etc/kubernetes/ssl --cluster-domain=cluster.local --hairpin-mode promiscuous-bridge --serialize-image-pulls=false"
- 代理配置文件問題(針對192.168.0.242)
###
# kubernetes proxy config
# default config should be adequate
# Add your own!
##我的配置丑勤,bind-address也是正在配置的node的地址,hostname-override和上面kubelet的配置需要一直
##原文配置KUBE_PROXY_ARGS="--bind-address=172.20.0.113 --hostname-override=172.20.0.113 --kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig --cluster-cidr=10.254.0.0/16"
KUBE_PROXY_ARGS="--bind-address=192.168.0.242 --hostname-override=192.168.0.242 --kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig --cluster-cidr=10.254.0.0/16"
1.3.7 Flannel網(wǎng)絡(luò)插件安裝
默認(rèn)情況吧趣,docker安裝后法竞,使用的是bridge橋接在宿主機(jī)上,意味著在不同主機(jī)上的docker通信設(shè)置復(fù)雜再菊。所以誕生了第三方插件爪喘,幫助docker內(nèi)的容器通信。flannel就是這樣的組件纠拔。他是一個(gè)專為kubernetes定制的三層網(wǎng)絡(luò)解決方案秉剑,主要用于解決容器的跨主機(jī)通信問題。
安裝方法
- 參照《5.2.6. 安裝flannel網(wǎng)絡(luò)插件》
- 對博客配置方法的說明
- flannel的配置文件:/etc/sysconfig/flanneld的==FLANNEL_ETCD_PREFIX==配置要和后面的==etcdctl命令中的鍵值==對應(yīng)稠诲;
- 代碼段【2】中的命令侦鹏,其實(shí)很簡單 即 etcdctl mkdir /kube-centos/network;相當(dāng)于使用etcdctl命令行創(chuàng)建了一個(gè)目錄(鍵值對);
- 上面這段命令臀叙,如果配置錯(cuò)誤略水,是不能覆蓋的,需要使用 etcdctl rmdir [目錄]先刪除劝萤,然后再重建即可渊涝。
- 而代碼中 --ca-file等代碼塊主要是認(rèn)證用的
代碼段【1】
# etcd config key. This is the configuration key that flannel queries
# For address range assignment
FLANNEL_ETCD_PREFIX="/kube-centos/network"
代碼段【2】
etcdctl --endpoints=https://172.20.0.113:2379,https://172.20.0.114:2379,https://172.20.0.115:2379 \
--ca-file=/etc/kubernetes/ssl/ca.pem \
--cert-file=/etc/kubernetes/ssl/kubernetes.pem \
--key-file=/etc/kubernetes/ssl/kubernetes-key.pem \
mkdir /kube-centos/network
etcdctl --endpoints=https://172.20.0.113:2379,https://172.20.0.114:2379,https://172.20.0.115:2379 \
--ca-file=/etc/kubernetes/ssl/ca.pem \
--cert-file=/etc/kubernetes/ssl/kubernetes.pem \
--key-file=/etc/kubernetes/ssl/kubernetes-key.pem \
mk /kube-centos/network/config '{"Network":"172.30.0.0/16","SubnetLen":24,"Backend":{"Type":"vxlan"}}'
二、部署項(xiàng)目
2.1項(xiàng)目部署概論
在純docker中床嫌,我們通過docker run直接啟動(dòng)一個(gè)應(yīng)用跨释。
那么,K8S中厌处,我們通過YAML文件來告訴集群應(yīng)該怎么創(chuàng)建應(yīng)用鳖谈,這些內(nèi)容描述了啟動(dòng)應(yīng)用的images(以及下載地址)、需要?jiǎng)?chuàng)建的應(yīng)用的數(shù)阔涉、應(yīng)用類型缆娃、應(yīng)用意外終止后的處理方式等。典型的一個(gè)hello-world.yaml文件如下所示:
apiVersion: v1
kind: Pod
metadata:
name: hello-world
spec: # specification of the pod’s contents
restartPolicy: Never
containers:
- name: hello
image: "ubuntu:14.04"
command: ["/bin/echo","hello”,”world"]
以上內(nèi)容是啟動(dòng)一個(gè)Ubuntu:14.04瑰排,容器名hello-world贯要,然后啟動(dòng)后執(zhí)行 /bin/echo hello world .
然后使用 以下命令創(chuàng)建 Pods:kubectl create -f ./hello-world.yaml
然后查看Pod狀態(tài)
## 我的注釋:初始化的時(shí)候,新創(chuàng)建的pod還未被調(diào)度椭住,也就是還沒有節(jié)點(diǎn)被選中去運(yùn)行它郭毕。
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-world 0/1 Pending 0 0s
## 我的注釋:這個(gè)是已經(jīng)成功運(yùn)行的狀態(tài)
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-world 1/1 Running 0 s
2.2部署nginx
2.1.1創(chuàng)建nginx-rc.yaml和nginx-svc.yaml
#nginx-rc.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: nginx-test
labels:
name: nginx-test
spec:
replicas: 2
selector:
name: nginx-test
template:
metadata:
labels:
name: nginx-test
spec:
containers:
- name: nginx-test
image: docker.io/nginx
ports:
- containerPort: 80
#nginx-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-test
labels:
name: nginx-test
spec:
type: NodePort
ports:
- port: 80
protocol: TCP
targetPort: 80
name: http
nodePort: 30088
selector:
name: nginx-test
以上命令是創(chuàng)建一組nginx服務(wù)器,創(chuàng)建2個(gè)副本函荣,將80端口映射到nodePort:30088
然后運(yùn)行下面兩條命令創(chuàng)建pod
kubectl create -f ./nginx-rc.yaml
kubectl create -f ./nginx-svc.yaml
2.1.2創(chuàng)建過程中可能出現(xiàn)的問題
A显押、Kubernetes在創(chuàng)建Pod的時(shí)候,需要從gcr.io下載一個(gè)helper鏡像扳肛,這個(gè)鏡像在Google下面,國內(nèi)無法拉取可參考3.1解決乘碑。gcr.io鏡像的實(shí)際拉取實(shí)際上在node上挖息,也就是需要在node機(jī)器上的docker要有這個(gè)鏡像,所以不能只在master操作兽肤。
B套腹、 過了gcr.io這個(gè)坎后,有可能要拉取的nginx鏡像也拉不出而一直處于creating狀態(tài)资铡。這部分排查需要不斷查看系統(tǒng)日志和 tail -f /var/log/messages 以及kubectl describe pod nginx-controller-tr5zr 查看pod狀態(tài)电禀。如果日志顯示是拉不到鏡像需要檢查yaml里面的images是否是可拉取的,如果可以通過docker run [images]可拉取笤休,那么yaml應(yīng)該也是可以的尖飞。如果拉取時(shí)間過慢,可以通過添加加速器等方式加速店雅;
2.2部署dashboard
2.2.1部署方法
可以參照博客直接部署K8S的dashboard政基,需要注意的是要自己去找可用的1.6版本的dashboard鏡像,可通過hub.docker.com搜索闹啦,然后使用加速器拉下來沮明。
2.2.2部署問題
如遇到dashboard不可訪問,路由問題窍奋,可參照下文3.3解決荐健。
三、問題集
3.1 kubectl pod 一致處于ContainerCreating狀態(tài)
3.1.1故障現(xiàn)象
[root@localhost nginx]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-controller-tr5zr 1/1 ContainerCreating 0 47s
nginx-controller-z3cbw 1/1 ContainerCreating 0 47s
3.1.2排查:查看具體pod狀態(tài)
kubectl describe pod nginx-controller-tr5zr
unable to pull sandbox image \"gcr.io/google_containers/pause-amd64:3.0\": Error response from daemon: {\"message\":\"Get https://gcr.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)\"}
3.1.3確認(rèn)問題
無法拉取 gcr.io/google_containers/pause-amd64:3.0 鏡像
3.1.4解決方案:手動(dòng)拉取琳袄、然后本地打tag.在每個(gè)POD(node)都執(zhí)行此操作
[root@localhost ~]# docker pull cloudnil/pause-amd64:3.0
[root@localhost ~]# docker tag cloudnil/pause-amd64:3.0 gcr.io/google_containers/pause-amd64:3.0
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
gcr.io/google_containers/pause-amd64 3.0 66c684b679d2 12 months ago 747kB
cloudnil/pause-amd64 3.0 66c684b679d2 12 months ago 747kB
3.2 可以查看到csr,但是查看node為no resource
3.2.1現(xiàn)象
fannel江场、etcd 工作正常,但是就是看不到nodes(即get nodes為空)
[root@localhost nginx]# kubectl get csr
NAME AGE REQUESTOR CONDITION
csr-j4gbr 15h kubelet-bootstrap Approved,Issued
csr-mm575 15h kubelet-bootstrap Approved,Issued
[root@localhost nginx]# kubectl get nodes
NAME STATUS AGE VERSION
192.168.0.242 Ready 14h v1.6.0
192.168.0.243 Ready 14h v1.6.0
3.2.2排查 :需要查看系統(tǒng)日志
[root@localhost nginx]# tail -300f /var/log/messages
3.2.3確認(rèn)問題:
沒有關(guān)聯(lián)角色挚歧,kubelet 啟動(dòng)時(shí)向 kube-apiserver 發(fā)送 TLS bootstrapping 請求,需要先將 bootstrap token 文件中的 kubelet-bootstrap 用戶賦予 system:node-bootstrapper 角色吁峻,然后 kubelet 才有權(quán)限創(chuàng)建認(rèn)證請求(certificatesigningrequests):
3.2.4解決方案:在master執(zhí)行以下語句 關(guān)聯(lián)角色
kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --user=kubelet-bootstrap
3.3 代理方式無法訪問dashboard
3.3.1 現(xiàn)象
dashboard部署成功后滑负,開啟kube-proxy代理訪問控制臺,顯示路由不通
[root@localhost ~]# kubectl proxy --address='192.168.0.241' --port=8086 --accept-hosts='^*$'
Starting to serve on 192.168.0.241:8086
訪問http://masterip:8086/ui后顯示如下:
dial tcp 172.17.0.3:9090: getsockopt: no route to host'
然后可跟蹤到pod去用含,發(fā)現(xiàn)某pod如果docker是172.17.0.3可以通過此主機(jī)訪問
3.3.2 排查-確定網(wǎng)絡(luò)問題
經(jīng)查考慮是docker網(wǎng)絡(luò)問題
根據(jù)以下兩篇文章及fannel網(wǎng)絡(luò)原理
https://www.cnblogs.com/kevingrace/p/6859114.html
https://blog.csdn.net/yelllowcong/article/details/78303626
可知矮慕,網(wǎng)絡(luò)轉(zhuǎn)發(fā)通過fannel進(jìn)行,正確安裝fannel并且配置Docker后啄骇。docker0和fannel.1會(huì)是同一個(gè)網(wǎng)段痴鳄,數(shù)據(jù)包到達(dá)fannel所在的網(wǎng)絡(luò)的之后,也即到了docker缸夹。從而完成了數(shù)據(jù)的轉(zhuǎn)發(fā)痪寻。
而最開始螺句,我的網(wǎng)絡(luò)路由不對
[root@localhost ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.0.1 0.0.0.0 UG 0 0 0 ens33
169.254.0.0 0.0.0.0 255.255.0.0 U 1002 0 0 ens33
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
172.30.0.0 0.0.0.0 255.255.0.0 U 0 0 0 flannel.1
192.168.0.0 0.0.0.0 255.255.248.0 U 0 0 0 ens33
192.168.122.0 0.0.0.0 255.255.255.0 U 0 0 0 virbr0
注意docker0的網(wǎng)段和flannel的網(wǎng)段不在同一個(gè)上面,所以是docker和flanned沒有對接起來橡类。
3.3.3解決方案:配置docker
情況一:根據(jù)上面第二個(gè)文章蛇尚,配置docker的網(wǎng)絡(luò)跟隨flannel配置,如下文最后一行所示顾画;
EnvironmentFile=-/run/flannel/docker
ExecStart=/usr/bin/dockerd \
$DOCKER_NETWORK_OPTIONS
情況二:博客中說的配置docker網(wǎng)絡(luò)的Environment要放在情況一那部分代碼的前面取劫,否則不生效
EnvironmentFile=-/run/flannel/docker
EnvironmentFile=-/run/docker_opts.env
EnvironmentFile=-/run/flannel/subnet.env
EnvironmentFile=-/etc/sysconfig/docker
EnvironmentFile=-/etc/sysconfig/docker-storage
EnvironmentFile=-/etc/sysconfig/docker-network
EnvironmentFile=-/run/docker_opts.env
即:這部分代碼要放在
ExecStart=/usr/bin/dockerd $DOCKER_NETWORK_OPTIONS的前面
3.3.4最終確認(rèn)
flannel.1和docker0 在同一網(wǎng)段了
[root@localhost ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.0.1 0.0.0.0 UG 0 0 0 ens33
169.254.0.0 0.0.0.0 255.255.0.0 U 1002 0 0 ens33
172.30.0.0 0.0.0.0 255.255.0.0 U 0 0 0 flannel.1
172.30.98.0 0.0.0.0 255.255.255.0 U 0 0 0 docker0
192.168.0.0 0.0.0.0 255.255.248.0 U 0 0 0 ens33
192.168.122.0 0.0.0.0 255.255.255.0 U 0 0 0 virbr0