podman 容器內(nèi)無法訪問網(wǎng)絡

podman是什么

前幾天將自己的開發(fā)環(huán)境切到了centos 8样勃,為了兼容之前一些業(yè)務程序的編譯欺抗,所以我需要一個centos 7容器离例。在yum install docker之后發(fā)現(xiàn)礼预,centos 8的docker被一個叫podman的程序給替代了第步。去簡單了解了下脑融,podman是redhat一直主推的本地容器解決方案喻频,能夠提供和k8s的pod相同的容器組織方式,多個容器可以放在同一個pod中肘迎,同一個pod中的容器共用網(wǎng)絡甥温。

podman系列主要包含三個命令podman、buildah妓布、skopeo姻蚓,其中podman本身負責運行、停止匣沼、管理容器狰挡,buildah負責構(gòu)建容器鏡像、skopeo負責與remote repo交互释涛,拉取或推送鏡像加叁。但我們使用時不必這么麻煩,redhat為了方便用戶從docker遷移到podman唇撬,在podman上幾乎實現(xiàn)了大多數(shù)docker的常用命令它匕,podman會替你轉(zhuǎn)調(diào)buildah和skopeo,你甚至可以直接 alias docker=podman窖认,然后像使用docker一樣使用podman豫柬。podman系列的的安裝方法如下:

yum module list | grep container
# yum install podman buildah skopeo
yum install @container-tools

相比于docker,podman系列拋棄了server端扑浸,不再有類似dockerd的后臺進程烧给,執(zhí)行命令時不再需要將命令和包拷貝到server端,在build image時首装,能夠節(jié)省一筆拷貝的開銷创夜。podman不再要求root權(quán)限,可以創(chuàng)建rootfull和rootless兩種類型的容器仙逻,雖然兩者的容器運行時都是基于runc驰吓。podman引入了k8s中pod的概念,可以將多個容器放到同一個pod中系奉,共享網(wǎng)絡檬贰;默認的pod基礎(chǔ)容器和k8s一樣執(zhí)行/pause命令,并支持用戶自定義基礎(chǔ)容器缺亮。

如何簡單的使用podman可以參考: https://thenewstack.io/deploy-a-pod-on-centos-with-podman/

問題

現(xiàn)在回到我的問題翁涤。安裝好podman之后,按照如下步驟,開始搭建編譯容器葵礼。在yum install時号阿,發(fā)現(xiàn)容器不能訪問外網(wǎng)

podman pull centos:7

cat > Dockerfile <<EOF
FROM centos:7
ENV container docker
RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == \
systemd-tmpfiles-setup.service ] || rm -f $i; done); \
rm -f /lib/systemd/system/multi-user.target.wants/*;\
rm -f /etc/systemd/system/*.wants/*;\
rm -f /lib/systemd/system/local-fs.target.wants/*; \
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
rm -f /lib/systemd/system/basic.target.wants/*;\
rm -f /lib/systemd/system/anaconda.target.wants/*;
VOLUME [ "/sys/fs/cgroup" ]
CMD ["/usr/sbin/init"]
EOF

podman build -t c7-systemd .
podman run -it -d --name mybuild -v /data/share:/data/share c7-systemd
podman exec -it mybuild bash
yum install gcc-c++ libstdc++-static openssl-devel 

問題具體表現(xiàn)是:

  • 直接ping外網(wǎng)域名,返回bad address
  • ping 域名對應的ip正常
  • curl 域名對應的ip返回no route to host
  • 容器內(nèi)的網(wǎng)絡配置文件鸳粉,一切正常
(venv) ? root@new1 ~  $podman run --rm alpine ping www.baidu.com
ping: bad address 'www.baidu.com'

(venv) ? root@new1 ~  $nslookup www.baidu.com
Server:     10.11.56.22
Address:    10.11.56.22#53

Non-authoritative answer:
www.baidu.com   canonical name = www.a.shifen.com.
Name:   www.a.shifen.com
Address: 14.215.177.39
Name:   www.a.shifen.com
Address: 14.215.177.38

(venv) ? root@new1 ~  $podman run --rm alpine ping 14.215.177.39
PING 14.215.177.39 (14.215.177.39): 56 data bytes
64 bytes from 14.215.177.39: seq=0 ttl=47 time=12.559 ms
64 bytes from 14.215.177.39: seq=1 ttl=47 time=10.266 ms

(venv) ? root@new1 ~  $podman run --rm alpine curl 14.215.177.39
curl: (7) Failed connect to 10.28.36.104:80; No route to host

容器的網(wǎng)絡, CNI

podman容器有三種網(wǎng)絡模式:bridge扔涧、host和none。啟動容器時届谈,不顯式指定的話枯夜,使用的是bridge網(wǎng)絡;可以通過--net=參數(shù)執(zhí)行為host或none模式艰山。host模式下湖雹,容器共享宿主機的網(wǎng)絡;none模式表示容器不存在網(wǎng)絡棧曙搬,僅有本地回環(huán)摔吏,無法與外界或其他pod通信。

對于我們上面的問題织鲸,一個最簡單的解決方法就是使用host網(wǎng)絡模式重新啟動容器舔腾。當時我也是這樣做的,但正常情況下bridge模式為什么不行呢搂擦?這問題也得有個答案稳诚。

(venv) ? root@new1 ~  $podman run --rm --net=host alpine ping www.baidu.com
PING www.baidu.com (14.215.177.38): 56 data bytes
64 bytes from 14.215.177.38: seq=0 ttl=48 time=9.428 ms
64 bytes from 14.215.177.38: seq=1 ttl=48 time=9.328 ms

眾所周知,容器的網(wǎng)絡實現(xiàn)一般基于CNI(Container Networking Interface)瀑踢。podman也不例外扳还,基于CNI來實現(xiàn)其bridged network stack。CNI是容器的網(wǎng)絡標準橱夭,類似的還有CRI(Container runtime interface)氨距、CSI(Container storage interface),是k8s為了規(guī)范底層pod的實現(xiàn)方式棘劣,制定的幾種標準接口俏让。

podman使用的CNI項目是CNI的一個使用最廣泛的實現(xiàn),該項目基于iptables來實現(xiàn)bridged network stack茬暇。CNI通過podman提供的信息首昔,以及描述podman所需網(wǎng)橋信息的默認配置/etc/cni/net.d/87-podman-bridge.conflist來創(chuàng)建虛擬網(wǎng)橋。

CNI項目使用iptables來實現(xiàn)各種網(wǎng)絡棧糙俗,這就存在一個問題勒奇,當其他程序?qū)θ萜魉拗鳈C的netfilter規(guī)則進行修改,可能會影響到podman容器的網(wǎng)絡訪問巧骚。比如iptables規(guī)則的修改赊颠、firewalld規(guī)則的修改都會影響容器的網(wǎng)絡訪問格二。所以我們需要去分析當前的iptables配置和firewalld配置。

問題解決

檢查iptables規(guī)則

iptables采取黑名單策略竣蹦,INPUT顶猜、FORWARD、OUTPUT chain的默認規(guī)則都是ACCEPT痘括,對于沒有顯式配置DROP規(guī)則的網(wǎng)絡報驶兜,是采取放通的處理方式。
并且CNI創(chuàng)建了自己的chain CNI-FORWARD远寸,并且,針對容器ip 10.88.0.46(這是一個運行中的容器)放通了所有的進出流量屠凶。iptables的規(guī)則沒有問題驰后。

(venv) ? root@new1 ~  $iptables -L 
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         
CNI-FORWARD  all  --  anywhere             anywhere             /* CNI firewall plugin rules */

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain CNI-FORWARD (1 references)
target     prot opt source               destination         
CNI-ADMIN  all  --  anywhere             anywhere             /* CNI firewall plugin rules */
ACCEPT     all  --  anywhere             10.88.0.46           ctstate RELATED,ESTABLISHED
ACCEPT     all  --  10.88.0.46           anywhere            

Chain CNI-ADMIN (1 references)
target     prot opt source               destination   

檢查firewalld的配置

firewalld和iptables一樣,都是基于netfilter實現(xiàn)的矗愧,但firewalld比較新灶芝,優(yōu)化了很多iptables的問題。其中一個就是唉韭,firewalld采取白名單策略夜涕,僅讓符合配置中規(guī)則的流量通過。

firewalld以zone作為配置管理的單位属愤,可以為不同的區(qū)域配置不同的放通規(guī)則女器。可以通過配置入站ip地址范圍或者配置網(wǎng)絡接口來將網(wǎng)絡包住诸,分配到不同的zone進行處理驾胆。

# 列出所有的zone
? root@new1 ~  $firewall-cmd --get-zones
block dmz drop external home internal public trusted work

默認情況下,所有的interface都會被放入public zone贱呐。配置了interface或者ip范圍的zone丧诺,被稱為active zone。默認情況下奄薇,只有public zone是活躍的驳阎。

# 列出active zone
? root@new1 ~  $firewall-cmd --get-active-zones
public
  interfaces: enp0s3 enp0s8

以這個zone的配置為例,簡單解釋下每行的含義

? root@new1 ~  $firewall-cmd --zone=public --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: enp0s3 enp0s8
  sources: 
  services: cockpit dhcpv6-client ssh
  ports: 
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 

簡單逐行做下解釋:

  • public (active) 表示public區(qū)域是active的
  • target: default 當包與public區(qū)域匹配馁蒂,而沒有被下述規(guī)則所處理呵晚,的包的處理方式,除default远搪,還有其他方式
    ACCEPT:通過這個包劣纲。
    %%REJECT%%:拒絕這個包,并返回一個拒絕的回復谁鳍。
    DROP:丟棄這個包癞季,不回復任何信息劫瞳。
    default:不做任何事情。該區(qū)域不再管它绷柒,返回上一層處理
  • icmp-block-inversion: no
  • interfaces: enp0s3 enp0s8 列出這個zone上關(guān)聯(lián)的interface
  • sources: 列出這個區(qū)域上的源志于,現(xiàn)在是空,如果有的話废睦,是類似33.233.233.0/24這種格式
  • services: cockpit dhcpv6-client ssh 列出允許通過防火墻的服務伺绽,可以通過firewall-cmd --get-services列出所有服務
  • ports: 列出允許通過防火墻的target port,當要放通一個沒有定義的服務時嗜湃,可以使用端口
  • protocols:
  • masquerade: no 表示這個區(qū)域不支持ip偽裝奈应。允許的話,將允許ip轉(zhuǎn)發(fā)购披,計算機作為路由器需要開啟這個功能
  • icmp-blocks: 要阻塞的icmp流量名單
  • rich rules: 高級規(guī)則

通過ip addr看到podman創(chuàng)建的接口是cni-podman0

4: cni-podman0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    link/ether 5e:a4:d6:86:c8:b6 brd ff:ff:ff:ff:ff:ff
    inet 10.88.0.1/16 brd 10.88.255.255 scope global cni-podman0
       valid_lft forever preferred_lft forever
    inet6 fe80::5ca4:d6ff:fe86:c8b6/64 scope link 
       valid_lft forever preferred_lft forever

現(xiàn)在杖挣,我們找到了問題所在,podman所創(chuàng)建的接口cni-podman0刚陡,沒有任何firewall zone與之匹配惩妇,默認的行為是拒絕來自cni-podman0的包,所以解決方法是將cni-podman0加入到trusted zone中筐乳。

? root@new1 ~  $firewall-cmd --zone=trusted --add-interface=cni-podman0
success
? root@new1 ~  $firewall-cmd --get-active-zones
public
  interfaces: enp0s3 enp0s8
trusted
  interfaces: cni-podman0

trusted zone的配置如下歌殃,其target是ACCEPT,只要將interface 或者source加入該zone蝙云,來自該interface或source的包就會被接受氓皱。

? root@new1 ~  $firewall-cmd --zone=trusted --list-all
trusted (active)
  target: ACCEPT
  icmp-block-inversion: no
  interfaces: cni-podman0
  sources: 
  services: 
  ports: 
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 

在容器中curl一下外網(wǎng)域名,做下驗證贮懈,一切正常了

? root@new1 ~  $podman run --rm c7-systemd curl www.baidu.com
<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css><title>百度一下匀泊,你就知道</title></head> <body link=#0000cc>........... </body> </html>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市朵你,隨后出現(xiàn)的幾起案子各聘,更是在濱河造成了極大的恐慌,老刑警劉巖抡医,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件躲因,死亡現(xiàn)場離奇詭異,居然都是意外死亡忌傻,警方通過查閱死者的電腦和手機大脉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來水孩,“玉大人镰矿,你說我怎么就攤上這事》郑” “怎么了秤标?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵绝淡,是天一觀的道長。 經(jīng)常有香客問我苍姜,道長牢酵,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任衙猪,我火速辦了婚禮馍乙,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘垫释。我一直安慰自己丝格,他們只是感情好,可當我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布棵譬。 她就那樣靜靜地躺著铁追,像睡著了一般。 火紅的嫁衣襯著肌膚如雪茫船。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天扭屁,我揣著相機與錄音算谈,去河邊找鬼。 笑死料滥,一個胖子當著我的面吹牛然眼,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播葵腹,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼高每,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了践宴?” 一聲冷哼從身側(cè)響起鲸匿,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎阻肩,沒想到半個月后带欢,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡烤惊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年乔煞,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片柒室。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡渡贾,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出雄右,到底是詐尸還是另有隱情空骚,我是刑警寧澤纺讲,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站府怯,受9級特大地震影響刻诊,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜牺丙,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一则涯、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧冲簿,春花似錦粟判、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至吝沫,卻和暖如春呻澜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背惨险。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工羹幸, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人辫愉。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓栅受,卻偏偏與公主長得像,于是被迫代替她去往敵國和親恭朗。 傳聞我的和親對象是個殘疾皇子屏镊,可洞房花燭夜當晚...
    茶點故事閱讀 42,802評論 2 345