【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编译命令要执行,将其放在最后一个执行,运行容器,容器不会停止了。




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