Docker & Supervisord

Host and inside docker’ containers all use supervisord to control processes…

Host : CentOS 7

Install docker

Notice:

1. Enable IP forwarding in Linux

$ sysctl net.ipv4.ip_forward

net.ipv4.ip_forward = 0

$ sysctl -w net.ipv4.ip_forward=1

$ service docker restart

2. Cannot open directory .: Permission denied

$ chcon -Rt svirt_sandbox_file_t ./code/

Install supervisord

Notice:
1. Supervisord.conf

default file is indeed /etc/supervisor.conf

2.Starting supervisor: Unlinking stale socket /var/run/supervisor.sock

$ pip install meld3==0.6.7

find / -name supervisor.sock

unlink /…/supervisor.sock

$ unlink /var/run/supervisor.sock

Install golang

Notice:

1. GOPATH=”….”

$ vi ~/.bashrc

Add

export GOPATH=”/home/Go”


A. Docker commands

1.Stop all containers

$ docker stop $(docker ps -a -q)

2.Delete all containers

$ docker rm $(docker ps -a -q)
  1. Delete all images
$ docker rmi $(docker images -q)

B. Build docker image

1. Prepare the Dockerfile


FROM centos:centos7
MAINTAINER Jeff Yang
ENV MAJOR_PATH /home/apps/IPMI/
ENV INSTALL_PATH /home/install/ 
ENV CONFIG_PATH /home/apps/DCMS/config/
RUN mkdir -p $MAJOR_PATH 
RUN mkdir -p $CONFIG_PATH
RUN mkdir -p $INSTALL_PATH
### Install supervisord
#RUN yum update -y
#RUN yum -y install python-setuptools epel-release python-pip
#RUN easy_install supervisor
COPY setuptools-19.2.tar.gz $INSTALL_PATH 
COPY meld3-0.6.5.tar.gz $INSTALL_PATH 
COPY elementtree-1.2-20040618.tar.gz $INSTALL_PATH 
COPY supervisor-3.1.3.tar.gz $INSTALL_PATH 
COPY ipmiutil-2.9.6-1_rhel6.x86_64.rpm $INSTALL_PATH  
RUN chmod 700 $INSTALL_PATH/setuptools-19.2.tar.gz && \
tar -zxvf $INSTALL_PATH/setuptools-19.2.tar.gz -C $INSTALL_PATH && \
cd $INSTALL_PATH/setuptools-19.2/ && \ 
python setup.py install
RUN chmod 700 $INSTALL_PATH/meld3-0.6.5.tar.gz && \
tar -zxvf $INSTALL_PATH/meld3-0.6.5.tar.gz -C $INSTALL_PATH && \
cd $INSTALL_PATH/meld3-0.6.5/ && \ 
python setup.py install
RUN chmod 700 $INSTALL_PATH/elementtree-1.2-20040618.tar.gz && \
tar -zxvf $INSTALL_PATH/elementtree-1.2-20040618.tar.gz -C $INSTALL_PATH && \
cd $INSTALL_PATH/elementtree-1.2-20040618/ && \ 
python setup.py install
RUN chmod 700 $INSTALL_PATH/supervisor-3.1.3.tar.gz && \
tar -zxvf $INSTALL_PATH/supervisor-3.1.3.tar.gz -C $INSTALL_PATH && \
cd $INSTALL_PATH/supervisor-3.1.3/ && \ 
python setup.py install

2. Build base image


$ docker build -t="code_icdc:v.01″ .

C. Backup image

1. Save image

$ docker save -o code_icdc_v01.tar code_icdc:v.01

2. Load image

$ sudo docker load –input code_icdc_v01.tar

OR

$ sudo docker load < code_icdc_v01.tar

D.

1. Build own program (ipmicdc)


$ go build ipmicdc.go ipmidocker.go

ipmidocker.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
package main
import (
"math"
"os"
"strconv"
"errors"
"fmt"
"os/exec"
"net/http"
"time"
)
const gDYamlName = "icdc.yml"
const gDHostImage = "code_icdc:v.01"
const gDVolumes1_Host = "./"
const gDVolumes1_Client = "/home/apps/IPMI/"
const gDVolumes2_Host = "/home/apps/DCMS/config/"
const gDVolumes2_Client = "/home/apps/DCMS/config/"
const gDPort = "31001"
var gDTotalContainers int
var gDHostIPPort int
var gDTotalIPsCount int
var gDNumprocs int
var gDMaxHandleIPs int

type IcdcDocker struct {
}

func (sid *IcdcDocker) update(w http.ResponseWriter, r *http.Request) {
if gDHostIPPort<= 0 || gDNumprocs <= 0 || gDMaxHandleIPs<=0 {
fmt.Fprintf(w, "fail")
return
}
err := sid.run(gDHostIPPort, gDNumprocs, gDMaxHandleIPs)
if err != nil{
fmt.Fprintf(w, "fail")
}
fmt.Fprintf(w, "ok")
}

func (sid *IcdcDocker) stop() (e error) {
var err error
err = sid.dockerAllStop()
if err != nil {
return errors.New("run ERROR")
}
err = sid.dockerAllRm()
if err != nil {
return errors.New("run ERROR")
}
return nil
}

func (sid *IcdcDocker) run( hostIpPort int, numprocs int, maxHandleIPs int ) (e error) {
var err error
err = sid.dockerComposeYamlMaker(hostIpPort, numprocs, maxHandleIPs)
if err != nil {
fmt.Println("run ERROR" )
return errors.New("run ERROR")
}
err = sid.dockerAllStop()
if err != nil {
return errors.New("run ERROR")
}
err = sid.dockerAllRm()
if err != nil {
return errors.New("run ERROR")
}
err = sid.dockerStart()
if err != nil {
return errors.New("run ERROR")
}
return nil
}

func (sid *IcdcDocker) dockerStart() (e error) {
if gDTotalContainers <= 0 {
return errors.New("dockerComposeStart ERROR")
}
cmdStr := "docker-compose -f " + gDYamlName + " up -d"
exec.Command("/bin/sh", "-c", cmdStr).Output()
<-time.After(time.Second)
return nil
}

func (sid *IcdcDocker) dockerAllStop() (e error) {
// stop all contains
cmdStr := "docker stop $(docker ps -a -q)"
exec.Command("/bin/sh", "-c", cmdStr).Output()
<-time.After(time.Second)
return nil
}

func (sid *IcdcDocker) dockerAllRm() (e error) {
// remove all contains
cmdStr := "docker rm $(docker ps -a -q)"
//out, _ :=
exec.Command("/bin/sh", "-c", cmdStr).Output()
<-time.After(time.Second)
return nil
}

func (sid *IcdcDocker) dockerChcon() (e error) {
cmdStr1 := "chcon -Rt svirt_sandbox_file_t "+ gDVolumes1_Host
exec.Command("/bin/sh", "-c", cmdStr1).Output()
cmdStr2 := "chcon -Rt svirt_sandbox_file_t "+ gDVolumes2_Host
exec.Command("/bin/sh", "-c", cmdStr2).Output()
return nil
}

func (sid *IcdcDocker) dockerComposeYamlMaker( hostIpPort int, numprocs int, maxHandleIPs int ) (e error) {
gDTotalContainers = 0
//************************
//get number of ip from DB
totalIPsCount := getTotalIPsCount()
//************************
if hostIpPort<= 0 || numprocs <= 0 || maxHandleIPs<=0 || totalIPsCount<=0 {
fmt.Println("dockerComposeYamlMaker ERROR!!!" )
return errors.New("dockerComposeYamlMaker ERROR")
}
file, err := os.Create(gDYamlName)
if err != nil {
fmt.Println("dockerComposeYamlMaker ERROR!!!" )
return errors.New("dockerComposeYamlMaker ERROR")
}
defer file.Close()
file.Chmod(0777)
var s string
var t int
totalContainers := int( math.Ceil( float64(totalIPsCount) / (float64(numprocs) * float64(maxHandleIPs) ) ))
gDHostIPPort = hostIpPort
gDTotalIPsCount = totalIPsCount
gDNumprocs = numprocs
gDMaxHandleIPs = maxHandleIPs
gDTotalContainers = totalContainers
sid.dockerChcon()
for i := 0; i < totalContainers; i++ {
s = "build" + strconv.Itoa(i) + ":\n"
file.WriteString(s)
s = " container_name: envTest" + strconv.Itoa(i) + "\n"
file.WriteString(s)
file.WriteString(" image: "+ gDHostImage + "\n")
file.WriteString(" ports:\n")
s = " - " + strconv.Itoa(hostIpPort+1+i) + ":"+gDPort+"\n"
file.WriteString(s)
file.WriteString(" volumes:\n")
file.WriteString(" - " + gDVolumes1_Host +":"+gDVolumes1_Client+"\n")
file.WriteString(" - " + gDVolumes2_Host +":"+gDVolumes2_Client+"\n")
file.WriteString(" restart: always\n")
file.WriteString(" stdin_open: true\n")
file.WriteString(" environment:\n")
t = i*numprocs*maxHandleIPs
s = " - IPMI_GET_IP_S=" + strconv.Itoa(t) + "\n"
file.WriteString(s)
t = (i+1)*numprocs*maxHandleIPs - 1
s = " - IPMI_GET_IP_E=" + strconv.Itoa(t) + "\n"
file.WriteString(s)
s = " - ICDC_EXE_PATH=" + gDVolumes1_Client + "\n"
file.WriteString(s)
file.WriteString(" command: sh " + gDVolumes1_Client + "start.sh" + "\n")
}
return nil
}

ipmicdc.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
func main() {
...
if os.Args[1] == "docker" { // docker version
numprocs := parserSupervisordConf(os.Args[0])
var err error
var sid IcdcDocker
sid.run( gPort, numprocs, gMaxHandleIPs)
if err != nil{
return
}
//--------------
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
go func() {
sig := <-sigs
fmt.Println()
fmt.Println(sig)
sid.stop()
}()
//--------------
http.HandleFunc("/updateDB", sid.update)
var sic IcdcCmd
http.HandleFunc("/discover", sic.commReceiveDiscoverCommand)
http.HandleFunc("/lan", sic.commReceiveLanCommand)
http.ListenAndServe(":"+strconv.Itoa(gPort), nil)
}
...
}

2. Start.sh include docker‘s Supervisord.conf

Start.sh

1
2
3
4
5
#!/bin/sh
cp $ICDC_EXE_PATH/libs/libipmi.so /usr/lib/
ldconfig
cp $ICDC_EXE_PATH/s.conf /etc/supervisord.conf
/usr/bin/supervisord -c $ICDC_EXE_PATH/supervisord.conf -n

Supervisord.conf



[program:ipmicdc]
command=/home/apps/IPMI/ipmicdc %(process_num)d
process_name = %(process_num)d
numprocs=2
autostart=no
autorestart=yes
[program:ipmi]
command=/home/apps/IPMI/ipmicdc
autostart=yes
autorestart=yes

3. Start Host’s Supervisord

$ supervisord -c /home/jeff/icdc/supervisord_docker.conf -n

supervisord_docker.conf


[program:ipmi_docker]
command=./ipmicdc “docker”
autostart=yes
autorestart=true
stopwaitsecs=10

[root@localhost code]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f32ab2fe909e code_icdc:v.01 “/bin/bash” 44 seconds ago Up 41 seconds 0.0.0.0:31003->9080/tcp envTest1
2028a0d07072 code_icdc:v.01 “/bin/bash” 50 seconds ago Up 44 seconds 0.0.0.0:31002->9080/tcp envTest0