Docker In Action<三> 制作可以Oracle的docker容器服务指北

本篇记录一步一步从docker 镜像centos65-ssh 开始构建Oracle服务的过程。由于一般的Oracle安装需要图形界面,安装比较复杂,所以本初采用Oracle提供的另外一种安装方式静默安装来构建。

Oracle

1
2
3
4
5
6
7
8
9
mkdir ~/docker/oracle
touch ~/docker/oracle/Dockerfile
cd /usr/local/src
#下载Oracle database安装介质
wget 10201_database_linux_x86_64.cpio.gz
#解压缩,生成database目录
zcat 10201_database_linux_x86_64.cpio.gz |cpio -idmv
#删除
rm -rf 10201_database_linux_x86_64.cpio.gz

Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#prepare install oracle env
FROM centos65-ssh
##create Oracle group and user
RUN groupadd -g 505 oinstall && groupadd -g 506 dba && useradd -u 505 -m -g oinstall -G dba oracle && id oracle
##config profile
ENV ORACLE_APP /u01/app/oracle
ENV ORACLE_DATA /u02/oradata
ENV ORACLE_HOME $ORACLE_APP/product/10.2.0/db_1
ENV INSTALL_HOME /usr/local/src
ADD install.sh $INSTALL_HOME/install.sh
ADD createdb.sh $INSTALL_HOME/createdb.sh
ADD initcenter.ora $INSTALL_HOME/initcenter.ora
ADD oracle /etc/init.d/oracle
ADD supervisord.conf /etc/supervisord.conf
EXPOSE 1521

install.sh

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
#!/bin/bash
#compat-gcc-* compat-gcc-*-c++ compat-libstdc++-* libXt.i686 libXtst.i686 libXtst libgcc pdksh
for PACKAGE in glibc glibc-common glibc-devel libstdc++ libstdc++-devel \
binutils compat-db compat-libstdc++-296 \
gcc gcc-c++ make openmotif setarch sysstat libaio libXp libXp.i686;
do
yum -y install $PACKAGE
yum clean packages
done
yum clean all
mkdir -p $ORACLE_APP $ORACLE_DATA && chown -R oracle:oinstall $ORACLE_APP $ORACLE_DATA && chmod -R 775 $ORACLE_APP $ORACLE_DATA
##config Linux kernel
cat >> /etc/sysctl.conf <<EOF
#use for oracle
kernel.shmall = 2097152
kernel.shmmax = 20147483648
kernel.shmmni = 4096
kernel.sem = 250 32000 100 128
#fs.file-max = 65536
net.ipv4.ip_local_port_range = 9000 65500
net.core.rmem_default=1048576
net.core.rmem_max=1048576
net.core.wmem_default=262144
net.core.wmem_max=262144
EOF
/sbin/sysctl -p
#config oracle user limit
cat >> /etc/security/limits.conf <<EOF
#use for oracle
oracle soft nproc 2047
oracle hard nproc 16384
oracle soft nofile 4096
oracle hard nofile 65536
EOF
#oralce limits login
cat >> /etc/pam.d/login <<EOF
#session required /lib64/security/pam_limits.so
EOF
#oracle profile
cat >> /etc/profile <<EOF
if [ \$USER = "oracle" ]; then
if [ \$SHELL = "/bin/ksh" ]; then
ulimit -p 16384
ulimit -n 65536
else
ulimit -u 16384 -n 65536
fi
umask 022
fi
EOF
#oracle login
cat >> /etc/csh.login <<EOF
if ( \$USER == "oracle" ) then
limit maxproc 16384
limit descriptors 65536
umask 022
endif
EOF
##oracle profile
cat >> /home/oracle/.bash_profile <<EOF
export ORACLE_BASE=$ORACLE_APP
export ORACLE_HOME=\$ORACLE_BASE/product/10.2.0/db_1
export ORACLE_SID=center
export PATH=\$PATH:\$ORACLE_HOME/bin:\$HOME/bin
export LD_LIBRARY_PATH=\$LD_LIBRARY_PATH:\$ORACLE_HOME/lib:/usr/lib:/usr/local/lib
export NLS_LANG=AMERICAN_AMERICA.ZHS16GBK
EOF
cp /etc/redhat-release /etc/redhat-release.orig && echo "redhat-4" > /etc/redhat-release
## oracle silent install
su - oracle -c "$INSTALL_HOME/database/runInstaller -silent -responseFile $INSTALL_HOME/database/response/enterprise.rsp \
UNIX_GROUP_NAME="oinstall" ORACLE_HOME="/u01/app/oracle/product/10.2.0/db_1" \
ORACLE_HOME_NAME="OraDb10g_home1" s_nameForDBAGrp="dba" s_nameForOPERGrp="dba" n_configurationOption=3 "
#restore release
rm /etc/redhat-release
cp /etc/redhat-release.orig /etc/redhat-release
echo "##########################################"
echo 'success install oracle software'

initcenter.ora

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
*.compatible='10.2.0.1.0'
*G._kgl_large_heap_warning_threshold=83886080
*.audit_file_dest='/u02/oradata/admin/center/adump'
*.background_dump_dest='/u02/oradata/admin/center/bdump'
*.control_files='/u02/oradata/center/control01.ctl','/u02/oradata/center/control02.ctl'
*.core_dump_dest='/u02/oradata/admin/center/cdump'
*.user_dump_dest='/u02/oradata/admin/center/udump'
*.db_2k_cache_size=33554432
*.db_block_size=8192
*.db_domain=''
*.db_file_multiblock_read_count=128
*.db_files=4000
*.db_name='center'
*.db_recovery_file_dest_size=4294967296
*.db_recovery_file_dest=''
*.log_archive_dest='/u02/oradata/center/archive'
*.log_checkpoints_to_alert=FALSE
*.open_cursors=1000
*.parallel_execution_message_size=65535
*.parallel_max_servers=128
*.pga_aggregate_target=209715200
*.processes=1000
*.recyclebin='ON'
*.remote_login_passwordfile='EXCLUSIVE'
*.replication_dependency_tracking=FALSE
*.session_cached_cursors=100
*.sga_target=2048m
*.undo_management='AUTO'
*.undo_retention=0
*.undo_tablespace='UNDOTS'
*.workarea_size_policy='AUTO'
_allow_resetlogs_corruption=true
*.job_queue_processes=10

createdb.sh

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
# create oracle db
chown -R oracle:oinstall /u02
su - oracle -c 'mkdir -p /u01/app/oracle/product/10.2.0/db_1/dbs'
su - oracle -c 'mkdir -p /u02/oradata/admin/center/adump'
su - oracle -c 'mkdir -p /u02/oradata/admin/center/bdump'
su - oracle -c 'mkdir -p /u02/oradata/admin/center/cdump'
su - oracle -c 'mkdir -p /u02/oradata/admin/center/pfile'
su - oracle -c 'mkdir -p /u02/oradata/admin/center/udump'
su - oracle -c 'mkdir -p /u02/oradata/center'
su - oracle -c 'mkdir -p /u02/oradata/center/archive'
#cp initcenter.ora
cp $INSTALL_HOME/initcenter.ora /u02/oradata/admin/center/pfile
cp $INSTALL_HOME/initcenter.ora /u01/app/oracle/product/10.2.0/db_1/dbs
chown oracle:oinstall /u02/oradata/admin/center/pfile/initcenter.ora
chmod a+x /u02/oradata/admin/center/pfile/initcenter.ora
chown oracle:oinstall /u01/app/oracle/product/10.2.0/db_1/dbs/initcenter.ora
chmod a+x /u01/app/oracle/product/10.2.0/db_1/dbs/initcenter.ora
echo 'success cp file ,begin to sqlplus ...'
#config sys
echo 506 > /proc/sys/vm/hugetlb_shm_group
#sqlplus start centerinstatnce
su - oracle -c 'sqlplus / as sysdba' << EOF
startup nomount pfile=/u02/oradata/admin/center/pfile/initcenter.ora
EOF
echo 'sucecess startup database in nomount state'
#sqlplus database
su - oracle -c 'sqlplus / as sysdba' << EOF
CREATE DATABASE center
LOGFILE
GROUP 1 ('/u02/oradata/center/redo01.log','/u02/oradata/center/redo01_1.log') size 50m reuse,
GROUP 2 ('/u02/oradata/center/redo02.log','/u02/oradata/center/redo02_1.log') size 50m reuse,
GROUP 3 ('/u02/oradata/center/redo03.log','/u02/oradata/center/redo03_1.log') size 50m reuse
MAXLOGFILES 50
MAXLOGMEMBERS 5
MAXLOGHISTORY 200
MAXDATAFILES 50
MAXINSTANCES 5
CHARACTER SET ZHS16GBK
NATIONAL CHARACTER SET AL16UTF16
DATAFILE '/u02/oradata/center/system01.dbf' SIZE 200M autoextend on next 10M maxsize 1024M
SYSAUX DATAFILE '/u02/oradata/center/sysaux01.dbf' SIZE 200M autoextend on next 10M maxsize 1024M
UNDO TABLESPACE UNDOTS DATAFILE '/u02/oradata/center/undo.dbf' SIZE 200M autoextend on next 10M maxsize 1024M
DEFAULT TEMPORARY TABLESPACE TEMP TEMPFILE '/u02/oradata/center/temp.dbf' SIZE 200M autoextend on next 10M maxsize 1024M;
@/u01/app/oracle/product/10.2.0/db_1/rdbms/admin/catalog.sql
@/u01/app/oracle/product/10.2.0/db_1/rdbms/admin/catproc.sql
conn system/manager
@/u01/app/oracle/product/10.2.0/db_1/sqlplus/admin/pupbld.sql
EOF
echo "center:/u01/app/oracle/product/10.2.0/db_1/:Y" >> /etc/oratab
chmod +x /etc/init.d/oracle
#open database archive
su - oracle -c 'sqlplus / as sysdba' << EOF
shutdown immediate;
startup mount;
alter database archivelog;
alter database open;
archive log list;
EOF

Oracle 服务自启动文件/etc/init.d/oracle

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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
#!/bin/bash
#
# /etc/init.d/oracle
#
# chkconfig: 2345 02 98
# description: oracle is meant to run under Linux Oracle Server
# Source function library.
. /etc/rc.d/init.d/functions
ORACLE_HOME=/u01/app/oracle/product/10.2.0/db_1
ORACLE_SID=center
ORACLE_NAME=oracle
LOCKFILE="$ORACLE_HOME/.oracle.lock"
RESTART_RETRIES=3
DB_PROCNAMES="pmon"
LSNR_PROCNAME="tnslsnr"
#RETVAL=0
#Start the oracle Server
#The following command assumes that the oracle login will not prompt the password
start() {
echo "Starting Oracle10g Server... "
tmpfile=/home/oracle/`basename $0`-start.$$
logfile=/home/oracle/`basename $0`-start.log
#
# Set up our sqlplus script. Basically, we're trying to
# capture output in the hopes that it's useful in the case
# that something doesn't work properly.
#
echo "startup" > $tmpfile
echo "quit" >> $tmpfile
su - $ORACLE_NAME -c "sqlplus \"/ as sysdba\" < $tmpfile &> $logfile"
if [ $? -ne 0 ]; then
echo "ORACLE_HOME Incorrectly set?"
echo "See $logfile for more information."
return 1
fi
#
# If we see:
# ORA-.....: failure, we failed
#
rm -f $tmpfile
grep -q "failure" $logfile
if [ $? -eq 0 ]; then
rm -f $tmpfile
echo "ORACLE_SID Incorrectly set?"
echo "See $logfile for more information."
return 1
fi
echo "Starting listern..."
((su - $ORACLE_NAME -c "$ORACLE_HOME/bin/lsnrctl start") >> $logfile 2>&1) || return 1
#return $?
if [ -n "$LOCKFILE" ]; then
touch $LOCKFILE
fi
return 0
}
stop() {
echo "Shutting down Oracle10g Server..."
declare tmpfile
declare logfile
tmpfile=/home/oracle/`basename $0`-stop.$$
logfile=/home/oracle/`basename $0`-stop.log
if [ -z "$LOCKFILE" ] || [ -f $LOCKFILE ]; then
echo
else
echo "oracle is not run"
return 0
fi
# Setup for Stop ...
echo "shutdown abort" > $tmpfile
echo "quit" >> $tmpfile
su - $ORACLE_NAME -c "sqlplus \"/ as sysdba\" < $tmpfile &> $logfile"
if [ $? -ne 0 ]; then
echo "ORACLE_HOME Incorrectly set?"
echo "See $logfile for more information."
return 1
fi
#
# If we see 'failure' in the log, we're done.
#
rm -f $tmpfile
grep -q failure $logfile
if [ $? -eq 0 ]; then
echo
echo "Possible reason: ORACLE_SID Incorrectly set."
echo "See $logfile for more information."
return 1
fi
status $LSNR_PROCNAME
if [ $? -ne 0 ] ; then
if [ -n "$LOCKFILE" ]; then
rm -f $LOCKFILE
fi
return 0 # Listener is not running
fi
((su - $ORACLE_NAME -c "$ORACLE_HOME/bin/lsnrctl stop") >> $logfile 2>&1) || return 1
if [ -n "$LOCKFILE" ]; then
rm -f $LOCKFILE
fi
return 0
}
get_lsnr_status() {
declare -i subsys_lock=$1
status $LSNR_PROCNAME
if [ $? == 0 ] ; then
return 0 # Listener is running fine
elif [ $subsys_lock -ne 0 ]; then
return 3
elif [ $? -ne 0 ] ; then
return 1
fi
}
get_db_status() {
declare -i subsys_lock=$1
declare -i i=0
declare -i rv=0
declare ora_procname
for procname in $DB_PROCNAMES ; do
ora_procname="ora_${procname}_${ORACLE_SID}"
status $ora_procname
if [ $? -eq 0 ] ; then
# This one's okay; go to the next one.
continue
elif [ $subsys_lock -ne 0 ]; then
return 3
elif [ $? -ne 0 ] ; then
return 1
fi
done
}
update_status() {
declare -i old_status=$1
declare -i new_status=$2
if [ -z "$2" ]; then
return $old_status
fi
if [ $old_status -ne $new_status ]; then
return 1
fi
return $old_status
}
status_ias() {
declare -i subsys_lock=1
declare -i last
#
# Check for lock file. Crude and rudimentary, but it works
#
if [ -z "$LOCKFILE" ] || [ -f $LOCKFILE ]; then
subsys_lock=0
fi
# Check database status
get_db_status $subsys_lock
update_status $? # Start
last=$?
# Check & report listener status
get_lsnr_status $subsys_lock
update_status $? $last
last=$?
# Check & report opmn / opmn-managed process status
#get_opmn_status $subsys_lock
#update_status $? $last
#last=$?
#
# No lock file, but everything's running. Put the lock
# file back. XXX - this kosher?
#
if [ $last -eq 0 ] && [ $subsys_lock -ne 0 ]; then
touch $LOCKFILE
fi
return $last
}
restart() {
echo -n "Restart Oracle10g Server"
stop
start
echo
}
case "$1" in
start)
start
exit $?
;;
stop)
stop
exit $?
;;
status)
status_ias
exit $?
;;
restart|reload)
stop
start
;;
*)
echo "Usage: $0 {start|stop|reload|restart|status}"
exit 1
;;
esac
exit 0

supervisord.conf

1
2
3
4
5
6
[supervisord]
nodaemon=true
[program:sshd]
command=/usr/sbin/sshd -D
[program:oracle]
command=service oracle start

构建oracle 安装环境

1
2
3
4
[root@master oracle]# docker build -t centos65-oracle-env .
[root@master oracle]# docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
centos65-oracle env 0749092dab0f 8 minutes ago 1.04 GB

安装oracle软件

1
2
3
4
5
6
7
#启动前面构建的Oracle安装环境 --privileged=true 参数表示一些sys kernel配置可以写 ,映射database 目录
[centos65-oracle]# docker run -it --privileged=true -v /usr/local/src/database:/usr/local/src/database centos65-oracle-env /bin/bash
bash-4.1# cd /usr/local/src/
bash-4.1# ls
createdb.sh database initcenter.ora install.sh
bash-4.1# sh /usr/local/src/install.sh
bash-4.1# exit

Oracle 数据库软件安装完毕,commit到docker镜像中,另起一个名字:

1
[centos65-oracle]# docker commit <cid> centos65-oracle-soft

创建oracle数据库 center实例

1
2
3
4
5
[centos65-oracle]# docker run -it --privileged=true -v /opt/data/oracle/data1:/u02/oradata/ centos65-oracle-soft /bin/bash
bash-4.1#chmod +x /usr/local/src/createdb.sh
bash-4.1#chown -R oracle:oinstall /u02/oradata
bash-4.1#sh /usr/local/src/createdb.sh
bash-4.1#exit

Oracle 数据库 center 实例创建完毕,commit到docker镜像为centos65-oracle-center

1
[centos65-oracle]#docker commit <cid> centos65-oracle-center

运行oracle容器,映射数据库文件目录和备份目录:

1
docker run -d -P --privileged=true -v /opt/data/oracle/data1:/u02/oradata/ -v /opt/data/oracle/bak:/bak centos65-oracle-center supervisord

实际使用的过程中,可以将刚创建的/opt/data/oracle/data1 的数据目录复制一份如 /opt/data/oracle/data_init ,打包做备份,以便后面做基础的数据库模板。同时可以启动多个容器,加载各自的数据库文件运行实例。

评论