Docker làm cho việc cài đặt hệ thống trở nên dễ dàng và nhanh chóng. Vậy docker giúp được gì cho hệ thống VoIP. Bài viết này sẽ hướng dẫn các bạn có thể chạy Asterisk trên docker.
Docker là một dự án mã nguồn mở giúp các Developer và System Admin dễ dàng hơn trong việc tạo, triển khai và chạy ứng dụng trên nhiều nơi khác nhau như trên Windows, laptop, VPS, bằng cách sử dụng các container. Các hãng công nghệ lớn như Google, Microsoft đã bắt đầu hỗ trợ Docker trên hệ thống và cung cấp nhiều tài liệu đào tạo Docker trên nền tảng của họ.
1. Build image.
Đầu tiên các bạn tạo file Dockerfile với nội dung như dưới
FROM centos:centos7
RUN yum install -y python3.8 python-setuptools snmp screen vim psmisc tree git tmux cron net-tools python3-pip iputils-ping traceroute initscripts
RUN pip3 install --upgrade pip
RUN pip3 install paramiko jsonpath-ng requests
RUN yum -y install epel-release
RUN yum -y install wget vim net-tools
RUN yum -y groupinstall "Development Tools"
RUN yum -y install libedit-devel sqlite-devel psmisc gmime-devel ncurses-devel libtermcap-devel sox newt-devel libxml2-devel libtiff-devel audiofile-devel gtk2-devel uuid-devel libtool libuuid-devel subversion kernel-devel kernel-devel-$(uname -r) git subversion kernel-devel crontabs cronie cronie-anacron
RUN cd /usr/src/ \
&& wget https://downloads.asterisk.org/pub/telephony/asterisk/old-releases/asterisk-11.20.0.tar.gz \
&& tar -xvzf asterisk* \
&& cd asterisk* \
&& ./configure --libdir=/usr/lib64 \
&& contrib/scripts/get_mp3_source.sh \
&& make \
&& make install \
&& make samples \
&& make config \
&& ldconfig
RUN groupadd asterisk \
&& useradd -r -d /var/lib/asterisk -g asterisk asterisk \
&& usermod -aG audio,dialout asterisk \
&& chown -R asterisk.asterisk /etc/asterisk \
&& chown -R asterisk.asterisk /var/{lib,log,spool}/asterisk \
&& chown -R asterisk.asterisk /usr/lib64/asterisk \
&& chown -R asterisk.asterisk /var/run/asterisk \
RUN sed -i 's|#AST_USER="asterisk"|AST_USER="asterisk"|' /etc/sysconfig/asterisk \
&& sed -i 's|#AST_GROUP="asterisk"|AST_GROUP="asterisk"|' /etc/sysconfig/asterisk \
&& sed -i 's|;runuser = asterisk|runuser = asterisk|' /etc/asterisk/asterisk.conf \
&& sed -i 's|;rungroup = asterisk|rungroup = asterisk|' /etc/asterisk/asterisk.conf \
&& sed -i 's|(!)||' /etc/asterisk/asterisk.conf \
&& sed -i 's|rtpstart=.*|rtpstart=10000|' /etc/asterisk/rtp.conf \
&& sed -i 's|rtpend=.*|rtpstart=10099|' /etc/asterisk/rtp.conf
WORKDIR /etc/asterisk/
RUN echo 'set number' > ~/.vimrc && echo 'syntax on' >> ~/.vimrc && echo 'highlight Comment ctermfg=LightCyan' >> ~/.vimrc && echo 'set relativenumber' >> ~/.vimrc && echo 'set shiftwidth=2' >> ~/.vimrc
RUN echo '#!/bin/bash' > /usr/local/bin/run_asterisk \
&& echo "/etc/init.d/asterisk start" >> /usr/local/bin/run_asterisk \
&& chmod +x /usr/local/bin/run_asterisk
ENTRYPOINT run_asterisk && /bin/bash
Sau khi tạo xong Dockerfile các bạn hãy build image từ Dockerfile vừa tạo
docker build -t asterisk:latest --force-rm -f Dockerfile .
Logs đầu ra sẽ có nội dung như dưới
Sending build context to Docker daemon 347.9MB
Step 1/15 : FROM centos:centos7
---> eeb6ee3f44bd
Step 2/15 : RUN yum install -y python3.8 python-setuptools snmp screen vim psmisc tree git tmux cron net-tools python3-pip iputils-ping traceroute initscripts
---> Using cache
---> 5298ad2fbdd8
Step 3/15 : RUN pip3 install --upgrade pip
---> Using cache
---> 63c7a80da4f9
Step 4/15 : RUN pip3 install paramiko jsonpath-ng requests
---> Using cache
---> 6c32037428e6
Step 5/15 : RUN yum -y install epel-release
---> Using cache
---> ac2d4e170406
Step 6/15 : RUN yum -y install wget vim net-tools
---> Using cache
---> 037b51b9b69f
Step 7/15 : RUN yum -y groupinstall "Development Tools"
---> Using cache
---> a9e3358e7f61
Step 8/15 : RUN yum -y install libedit-devel sqlite-devel psmisc gmime-devel ncurses-devel libtermcap-devel sox newt-devel libxml2-devel libtiff-devel audiofile-devel gtk2-devel uuid-devel libtool libuuid-devel subversion kernel-devel kernel-devel-$(uname -r) git subversion kernel-devel crontabs cronie cronie-anacron
---> Using cache
---> 5b06651bef19
Step 9/15 : RUN cd /usr/src/ && wget https://downloads.asterisk.org/pub/telephony/asterisk/old-releases/asterisk-11.20.0.tar.gz && tar -xvzf asterisk* && cd asterisk* && ./configure --libdir=/usr/lib64 && contrib/scripts/get_mp3_source.sh && make && make install && make samples && make config && ldconfig
---> Using cache
---> 1b4393bc5127
Step 10/15 : RUN groupadd asterisk && useradd -r -d /var/lib/asterisk -g asterisk asterisk && usermod -aG audio,dialout asterisk && chown -R asterisk.asterisk /etc/asterisk && chown -R asterisk.asterisk /var/{lib,log,spool}/asterisk && chown -R asterisk.asterisk /usr/lib64/asterisk && chown -R asterisk.asterisk /var/run/asterisk
---> Using cache
---> bbfad5016e18
Step 11/15 : RUN sed -i 's|#AST_USER="asterisk"|AST_USER="asterisk"|' /etc/sysconfig/asterisk && sed -i 's|#AST_GROUP="asterisk"|AST_GROUP="asterisk"|' /etc/sysconfig/asterisk && sed -i 's|;runuser = asterisk|runuser = asterisk|' /etc/asterisk/asterisk.conf && sed -i 's|;rungroup = asterisk|rungroup = asterisk|' /etc/asterisk/asterisk.conf && sed -i 's|(!)||' /etc/asterisk/asterisk.conf && sed -i 's|rtpstart=.*|rtpstart=10000|' /etc/asterisk/rtp.conf && sed -i 's|rtpend=.*|rtpstart=10099|' /etc/asterisk/rtp.conf
---> Using cache
---> f3c276ced4d1
Step 12/15 : WORKDIR /etc/asterisk/
---> Using cache
---> 9e9ae11bc6f7
Step 13/15 : RUN echo 'set number' > ~/.vimrc && echo 'syntax on' >> ~/.vimrc && echo 'highlight Comment ctermfg=LightCyan' >> ~/.vimrc && echo 'set relativenumber' >> ~/.vimrc && echo 'set shiftwidth=2' >> ~/.vimrc
---> Using cache
---> 0b8409acda52
Step 14/15 : RUN echo '#!/bin/bash' > /usr/local/bin/run_asterisk && echo "/etc/init.d/asterisk start" >> /usr/local/bin/run_asterisk && chmod +x /usr/local/bin/run_asterisk
---> Using cache
---> bc442065edf5
Step 15/15 : ENTRYPOINT run_asterisk && /bin/bash
---> Using cache
---> 52fd0031b967
Successfully built 52fd0031b967
Successfully tagged asterisk:latest
Sau khi build xong bạn đã có 1 image asterisk:latest như dưới
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
asterisk latest 4a51839d91ee About a minute ago 2.52GB
2. Push image.
Bây giờ các bạn có thể push image này lên 1 repository nào đó, mình sẽ sử dụng Docker Hub. Đầu tiên hãy login vào Docker Hub bằng command dưới.
docker login -u <ci_registry_user> -p <ci_registry_password>
Nếu login thành công, bạn sẽ nhận được output như vậy.
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
Bây giờ hãy đánh tag cho image bạn chuẩn bị push.
docker tag asterisk:latest <ci_registry>/asterisk:latest
Kết quả sau khi đánh tag cho image xong.
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
hoanghd164/asterisk latest ae1b2da89b31 About a minute ago 2.52GB
Giờ hãy dùng command dưới để push image lên Docker Hub nhé
docker push <ci_registry>/asterisk:latest
Đầu ra của bạn sẽ gần giống như vậy sau khi push xong.
The push refers to repository [docker.io/hoanghd164/asterisk]
6f0a3601676b: Pushed
dbe9dfd85650: Pushed
6517dc29875a: Pushed
31a4d0d50e32: Pushed
63d9ba95077d: Pushed
96e058c79cd7: Pushed
a378cc5f1e2e: Pushed
0c965cd2bd05: Pushed
1badbade2635: Pushed
9899c41d36a4: Pushed
0444cc0e78ed: Pushed
ecdb53c0081e: Pushed
0f1bbe31b0f3: Pushed
174f56854903: Layer already exists
latest: digest: sha256:905fef0aca40d2c257e63c4698f27b76ff4fe386d18b53b7742eba58c7d58e61 size: 3272
Giờ lên website của Docker Hub bạn đã thấy image của bạn đã sẵn sàng để sử dụng.
3. Sử dụng image vừa tạo xong.
Hãy tạo file docker-compose-asterisk.yaml với nội dung như dưới, bạn có thể thay đổi nội dung file theo cá nhân của bạn.
version: '3'
services:
asterisk:
image: <ci_registry>/asterisk:latest
container_name: asterisk
restart: always
privileged: true
ports:
- "8080:8080/tcp"
- "5060:5060/tcp"
- "5060:5060/udp"
- "10000-10099:10000-10099/udp"
network_mode: "host"
stdin_open: true
tty: true
Bây giờ hãy sử dụng docker-compose để run file docker-compose-asterisk.yaml
$ docker-compose -f docker-compose-asterisk.yaml up -d
[+] Running 1/1
⠿ Container asterisk Started
Sau khi run xong bạn đã có container sẵn sàng sử dụng như dưới.
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ebe345ba67ad asterisk:latest "/bin/sh -c 'run_ast…" 17 seconds ago Up 16 seconds asterisk
4. Kiểm tra.
Mình exec vào container vừa tạo.
docker exec -it asterisk bash
Tạo 2 sip extensions như dưới.
cat >> /etc/asterisk/sip.conf << 'OEF'
[100]
username=100
secret=1234
type=friend
host=dynamic
context=test
qualify=yes
directmedia=no
disallow=all
allow=ulaw,alaw
[101]
username=101
secret=1234
type=friend
host=dynamic
context=test
qualify=yes
directmedia=no
disallow=all
allow=ulaw,alaw
OEF
Tạo 1 asterisk dialplan để test.
cat >> /etc/asterisk/extensions.conf << 'OEF'
[test]
exten => _1XX,1,Dial(SIP/${EXTEN})
OEF
Khởi động lại dịch vụ Asterisk
$ /etc/init.d/asterisk restart
Stopping safe_asterisk: [ OK ]
Shutting down asterisk: [ OK ]
Starting asterisk:
Sử dụng lệnh asterisk -vvvvvr để vào xem logs cuộc gọi.
$ asterisk -vvvvvr
Asterisk 11.20.0, Copyright (C) 1999 - 2013 Digium, Inc. and others.
Created by Mark Spencer <markster@digium.com>
Asterisk comes with ABSOLUTELY NO WARRANTY; type 'core show warranty' for details.
This is free software, with components licensed under the GNU General Public
License version 2 and other licenses; you are welcome to redistribute it under
certain conditions. Type 'core show license' for details.
=========================================================================
Running as user 'asterisk'
Running under group 'asterisk'
Connected to Asterisk 11.20.0 currently running on kvm-node02 (pid = 165)
Sáu khi đăng ký xong các sip extensions, bạn sẽ thấy trạng thái của chúng đã online.
$ sip show peers
Name/username Host Dyn Forcerport Comedia ACL Port Status Description
100/100 192.168.12.63 D Auto (No) No 53447 OK (1 ms)
101/101 192.168.28.54 D Auto (No) No 52026 OK (10 ms)
2 sip peers [Monitored: 2 online, 0 offline Unmonitored: 0 online, 0 offline]
Kết quả khi show dialplan.
$ dialplan show test
[ Context 'test' created by 'pbx_config' ]
'_1XX' => 1. Dial(SIP/${EXTEN}) [pbx_config]
Như vậy là bạn đã có các line sip extensions và contex để test, bây giờ hãy thử thực hiện 1 cuộc gọi và bạn sẽ có kết quả như dưới.
== Using SIP RTP CoS mark 5
-- Executing [100@test:1] Dial("SIP/101-00000000", "SIP/100") in new stack
== Using SIP RTP CoS mark 5
-- Called SIP/100
-- SIP/100-00000001 is ringing
> 0x7f1e1c013e40 -- Probation passed - setting RTP source address to 192.168.12.63:63636
[Jan 5 06:28:31] NOTICE[313][C-00000000]: res_rtp_asterisk.c:4441 ast_rtp_read: Unknown RTP codec 95 received from '(null)'
-- SIP/100-00000001 answered SIP/101-00000000
-- Locally bridging SIP/101-00000000 and SIP/100-00000001
> 0x7f1e9402d970 -- Probation passed - setting RTP source address to 192.168.28.54:62569
[Jan 5 06:28:31] NOTICE[313][C-00000000]: res_rtp_asterisk.c:4441 ast_rtp_read: Unknown RTP codec 95 received from '192.168.28.54:62569'
> 0x7f1e1c013e40 -- Probation passed - setting RTP source address to 192.168.12.63:63636
== Spawn extension (test, 100, 1) exited non-zero on 'SIP/101-00000000'
Chúc các bạn thành công.