【Docker(四)】安裝、配置kamailio遇見的問題

安裝kamailio

使用的是官方Ubuntu:16.04的Docker鏡像,運行容器,安裝kamailio:https://blog.csdn.net/qq_36069590/article/details/79106771

遇到的問題

1、mysql啓動失敗

錯誤信息:No directory, logging in with HOME=/

解決方法:

service mysql stop
usermod -d /var/lib/mysql/ mysql
service mysql start

2、SIP終端註冊超時

        要弄清是在哪個步驟超時,是容器外部主機收不到還是內部容器沒有收到sip消息。

在外部主機和容器分別運行抓包tcpdump -i eth0 -c -vnn dst port 5060,在終端顯示抓的包。eth0本地連接的網卡名字,我這裏只抓取目的端口是5060的包,因爲在容器啓動時候使用的-p指令將host與容器的5060端口進行映射的。

   sip終端再進行註冊,發現host能收到sip消息(端口5060 unreached),容器收不到。

偶然發現容器端口映射命令可以制定tcp/udp,在sip消息的register中看proto是udp,那麼會不會是因爲容器端口映射命令默認是tcp才導致sip消息不能從host進入容器呢?

解決方案:

①重新交互式運行容器:

docker run -it -p 5060:5060/udp --name new_container image name/ID

就是還得重新進行安裝配置等,比較麻煩,當然可以先用docker commit命令創建鏡像,將當前的容器配置保存下來,再重新以上面的端口映射/udp方式運行容器(這個也太麻煩了,非常的不推薦)。

②修改容器配置文件(推薦)

這種方法比上一個方便很多,推薦使用。

步驟:

  1. 停止容器
  2. 停止docker服務(systemctl stop docker)
  3. 修改這個容器的hostconfig.json文件中的端口,如果config.v2.json裏面也記錄了端口,也要修改。這文件位置在host的/var/run/docker/容器ID/中
  4. 停止docker服務(systemctl start docker)
  5. 啓動容器

參考:https://stackoverflow.com/questions/19335444/how-do-i-assign-a-port-mapping-to-an-existing-docker-container

            https://blog.csdn.net/wesleyflagon/article/details/78961990

3、SIP終端Forbidden(kamailio返回403 not relaying)

            將上一個問題解決後,重新進入容器,啓動kamailio,tcpdump在容器內抓包,可以看到容器內部可以收到sip的register消息了,但是sip終端註冊時顯示Forbidden,抓包也顯示kamailio返回了403 not relaying。從網上找解決原因時,有個說法覺得挺有道理:The SIP response '403 Not relaying' is sent because none of the domains in From URI and request URI is local IP (or hostname). For security reasons, either sender or destination must be a local user or service (using server's IP or hostnames), otherwise the instance can be used as open relay to target other hosts.

    就是sip消息中From和to沒有一個是本地IP,出於安全原因,發送方或目的地必須是本地用戶或服務(使用服務器的IP或主機名)。否則kamailio就會作爲其他主機的開放中繼。

其實是因爲kamailio是運行在容器環境的,而容器是有自己的內部網絡和IP地址的,在容器啓動狀態時,使用 docker inspect 容器ID 命令可以查看容器的所有變量,如我的就是這樣的:

從中可以看到我的容器IP是172.17.0.2,網關是172.17.0.1,用ifconfig也可以看到:

也就是kamailio是運行在172.17.0.2這個IP地址的,而我們在外部進行SIP註冊時候是隻能到host的IP的,kamailio收到的sip消息裏的源和目的地址沒有一個是自己容器IP 172.17.0.2,所以報了403 not relaying這個錯誤。

解決辦法:

在/usr/local/etc/kamailio/kamailio.cfg中進行如下更改:

alias="127.17.0.2"
#使用 advertise參數給配置文件kamailio.cfg中相應監聽端口的位置聲明
listen=udp:172.17.0.2:5060 advertise host的IP:5060

在/usr/local/etc/kamailio/kamctlrc中進行如下更改:SIP_DOMAIN=172.17.0.2

其實就是將kamailio的地址聲明一下爲本地容器的地址。

參考:https://stackoverflow.com/questions/17938331/authentication-issue-in-sip-server?answertab=votes#tab-top

4、docker容器中如何獲取宿主機IP

運行容器時通過環境變量傳入docker run --env HOST_IP=192.168.0.160,容器內部通過環境變量$HOST_IP獲取。

5、容器運行後自動停止(啓動服務後)

            使用的是Dockerfile創建的鏡像,由於docker容器的主線程(Dockerfile中CMD執行的命令)結束,容器會退出。

            首先要說明的是,Docker 不是虛擬機,容器就是進程。既然是進程,那麼在啓動容器的時候,需要指定所運行的程序及參數。CMD 指令就是用於指定默認的容器主進程的啓動命令的。也就是容器運行就啓動CMD後面的命令。

            在運行時可以指定新的命令來替代鏡像設置中的這個默認命令,比如,ubuntu 鏡像默認的 CMD/bin/bash,如果我們直接 docker run -it ubuntu 的話,會直接進入 bash。我們也可以在運行時指定運行別的命令,如 docker run -it ubuntu cat /etc/os-release。這就是用 cat /etc/os-release 命令替換了默認的 /bin/bash 命令了,輸出了系統版本信息。

        首先說明一下容器中的應用在前臺執行和後臺執行的問題,下面的話很重要:

            Docker 不是虛擬機,容器中的應用都應該以前臺執行,而不是像虛擬機、物理機裏面那樣,用 upstart/systemd 去啓動後臺服務,容器內沒有後臺服務的概念。對於容器而言,其啓動程序就是容器應用進程,容器就是爲了主進程而存在的,主進程退出,容器就失去了存在的意義,從而退出,其它輔助進程不是它需要關心的東西。

而在我的dockerfile中有兩個service啓動服務命令,那麼當service命令結束後,sh 也就結束了,sh 作爲主進程退出了,自然就會令容器退出。

解決方案之一在下面的鏈接,是將是直接執行應用的可執行文件,並且要求以前臺形式運行。

具體參考:https://yeasy.gitbooks.io/docker_practice/content/image/dockerfile/cmd.html

我想的是隻要CMD最後一個執行的程序掛起應該也是可以的,因爲此時主進程還是存在的。

正好有一個mvn編譯命令要執行,將其放在最後一個執行,運行容器,容器不會停止了。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章