天天看點

【Docker(四)】安裝、配置kamailio遇見的問題安裝kamailio遇到的問題1、mysql啟動失敗4、docker容器中如何擷取主控端IP5、容器運作後自動停止(啟動服務後)

安裝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 指令可以檢視容器的所有變量,如我的就是這樣的:

【Docker(四)】安裝、配置kamailio遇見的問題安裝kamailio遇到的問題1、mysql啟動失敗4、docker容器中如何擷取主要端IP5、容器運作後自動停止(啟動服務後)

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

【Docker(四)】安裝、配置kamailio遇見的問題安裝kamailio遇到的問題1、mysql啟動失敗4、docker容器中如何擷取主要端IP5、容器運作後自動停止(啟動服務後)

也就是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編譯指令要執行,将其放在最後一個執行,運作容器,容器不會停止了。

繼續閱讀