(elk)ElasticSearch-Logstash-Kibana

ElasticSearch 是构建在Apache Lucene之上的的搜索引擎服务,开源(Apache2协议),分布式,RESTful,实时 可扩展。安装方便,使用简单。
Logstash 收集工作日志数据,处理并分析,有告警功能,有很多插件inputs filters outputs
Kibana 支持可视化数据,过滤,查询等功能

三者可以独立使用,也可以一起组合提供强大的功能。
elk

可以方便的扩展:
elk-cluster

一、ElasticSearch

需要Java环境,现在设置好Java 环境变量。测试

1
2
3
4
$java -version
java version "1.6.0_25"
Java(TM) SE Runtime Environment (build 1.6.0_25-b06)
Java HotSpot(TM) 64-Bit Server VM (build 20.0-b11, mixed mode)

下载elasticsearch 文件

1
2
3
4
5
$wget https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.4.1.tar.gz
$tar zxvf elasticsearch-1.4.1.tar.gz
$cd elasticsearch-1.4.1
$ ls
bin config data lib LICENSE.txt logs NOTICE.txt plugins README.textile

bin 启动脚本
config 配置文件
data 默认数据目录
plugins 插件目录

可以零配置上使用
vi config/elasticsearch.yml

1
2
3
#cluster.name: elasticsearch
#node.name: "Franz Kafka"
#path.data: /path/to/data

启动elasticsearch

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
cd elasticsearch-1.3.2 && bin/elasticsearch -d
curl -X GET http://localhost:9200/
{
"status" : 200,
"name" : "Mister Fear",
"cluster_name" : "elasticsearch",
"version" : {
"number" : "1.4.1",
"build_hash" : "89d3241d670db65f994242c8e8383b169779e2d4",
"build_timestamp" : "2014-11-26T15:49:29Z",
"build_snapshot" : false,
"lucene_version" : "4.10.2"
},
"tagline" : "You Know, for Search"
}

安装web管理界面插件

1
$ bin/plugin -i elasticsearch/marvel/latest

浏览器访问
http://localhost:9200/_plugin/marvel/

二、Logstash

三、Kibana

通过ProxyCommand 登录远程内网的服务器

有些机房的服务器为了安全的问题,或者设置了堡垒机,或者有些服务器放置到了内网,对远程管理带来了不方便。
像一些支持分布式的程序,如监控程序Zabbix可以将内网的监控信息数据通过代理传到主控端。但远程的ssh操作的比较麻烦。
现发现一种ssh方式,通过ProxyCommand方式可以很好的支持该类型的操作。在内网测试有效。记录如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
cat ~/.ssh/config
#ControlMaster auto
#ControlPath /tmp/ssh_mux_%h_%p_%r
#ControlPersist 1h
#gateways
Host gateway
Port 65422
User winupon
Hostname 192.168.16.230
#servers
Host 192.168.22.*
Port 65422
User winupon
IdentityFile /path/to/ssh/key.pem
ProxyCommand ssh gateway nc %h %p

默认读取的时~/.ssh/config 这个文件,可以加上参数,指定不同的文件。
gateway 为堡垒机
然后192.168.22.* 类型的服务器ip都可以通过堡垒机登录。
先要先配置好ssh 互信,或指定key文件

测试

1
2
3
ssh gateway -F ~/.ssh/config
ssh 192.168.22.11 -F ~/.ssh/config.test
ssh 192.168.22.11 -F ~/.ssh/config.test -vvv 开启调试模式

Ansible学习笔记<二> -Playbooks篇

1
2
3
4
5
_ _ ____ __ __
| | (_)_ __ _ ___ __/ ___|___ / _|/ _| ___ ___
| | | | '_ \| | | \ \/ / | / _ \| |_| |_ / _ \/ _ \
| |___| | | | | |_| |> <| |__| (_) | _| _| __/ __/
|_____|_|_| |_|\__,_/_/\_\\____\___/|_| |_| \___|\___|

Ansible,官方的解释是:Ansible is the simplest way to automate IT.
Ansible 是通过 Python 语言开发。当前使用 Ansible 的用户有:Evernote、EA、rackspace、NASA、Atlassian、Twitter 等。
Ansible 默认通过 SSH 协议管理机器。在被控机器上不需要安装任何组件,需要的Python一般的Linux服务器都已经自带了。是一种比Puppet、SaltStack等更加轻量级的自动化运维管理工具。自带的模块也极其丰富。
Ansible 使用一个高质量的 Python 实现的 OpenSSH 协议库 “paramiko”。 Paramiko 遵循 SSH2 协议,支持以加密和认证的方式,进行远程服务器的连接。对 paramiko 进行了更高层次的封装。http://www.paramiko.org/
Ansible 使用 YAML 文件格式并使用 Jinja2 模板语言。

一些相关链接:
官方网站:http://www.ansible.com
官方文档:http://docs.ansible.com/index.html

四、Ansible’s playbooks

playbooks 翻译过来就是剧本,我们只要写好剧本,就会按照剧本进行演出。只要定义好远程服务器需要达到某种状态,Ansible就会去处理。

Ansible学习笔记<一> -基础篇

1
2
3
4
5
_ _ ____ __ __
| | (_)_ __ _ ___ __/ ___|___ / _|/ _| ___ ___
| | | | '_ \| | | \ \/ / | / _ \| |_| |_ / _ \/ _ \
| |___| | | | | |_| |> <| |__| (_) | _| _| __/ __/
|_____|_|_| |_|\__,_/_/\_\\____\___/|_| |_| \___|\___|

Ansible,官方的解释是:Ansible is the simplest way to automate IT.
Ansible 是通过 Python 语言开发。当前使用 Ansible 的用户有:Evernote、EA、rackspace、NASA、Atlassian、Twitter 等。
Ansible 默认通过 SSH 协议管理机器。在被控机器上不需要安装任何组件,需要的Python一般的Linux服务器都已经自带了。是一种比Puppet、SaltStack等更加轻量级的自动化运维管理工具。自带的模块也极其丰富。
Ansible 使用一个高质量的 Python 实现的 OpenSSH 协议库 “paramiko”。 Paramiko 遵循 SSH2 协议,支持以加密和认证的方式,进行远程服务器的连接。对 paramiko 进行了更高层次的封装。http://www.paramiko.org/
Ansible 使用 YAML 文件格式并使用 Jinja2 模板语言。

关于Configuration management (CM) 配置管理工具 Ansible — Puppet — Chef — SaltStack 的几个工具的对比,参考 https://devopsu.com/books/taste-test-puppet-chef-salt-stack-ansible.html

一些相关链接:
官方网站:http://www.ansible.com
官方文档:http://docs.ansible.com/index.html
书籍:http://www.ansible.com/ansible-book
ANSIBLE UP & RUNNING

一、安装

安装也相当方便。目前已经发布了1.8 版本,但epel源中是1.7.2

Mac

1
2
3
MacBookPro:~ hzchenkj$ brew install ansible
MacBookPro:~ hzchenkj$ ansible --version
ansible 1.7.2

RedHat

1
2
rpm –ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
yum –y install ansible

二、使用

定义主机配置文件,默认在/etc/ansible/hosts 下面,
也可以使用-i 参数指定不同的路径

1
ansible -i /usr/local/Cellar/ansible/1.7.2/ansible_hosts webservers -a 'uptime' -u root -k

该命令选项的作用分别为:

-i:指定 inventory 文件,使用当前目录下的 hosts
webservers :针对 hosts 定义的所有主机执行,也可以指定组名或模式,或者all
-m:指定所用的模块 ,默认的模块为command
-a: 模块参数
-u:指定远端机器的用户
-k:参数为要求使用密码方式连接
-f: 并发数
-s: 使用sudo切换到root

或者设置环境变量

1
2
export ANSIBLE_HOSTS=/usr/local/Cellar/ansible/1.7.2/ansible_hosts
ansible webservers -a 'uptime' -u root -k

编辑主机配置文件,支持嵌套。也可以支持别名,定义变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# vim /etc/ansible/hosts
[webservers]
10.223.55.100
10.223.55.101
10.223.38.226
[linux:children]
nginx
tomcat
[nginx]
10.223.38.227
[tomcat]
10.223.39.216
10.223.25.123
10.240.162.11[1:9]:22
[mysql]
mysql1 ansible_ssh_host=192.168.22.11 ansible_ssh_port=65422 ansible_ssh_user=mysql
mysql2 ansible_ssh_host=192.168.22.12 ansible_ssh_port=65422 ansible_ssh_user=mysql
[webservers:vars]
ls-path=/bin/ls
liss=lisisi

配置ssh信任

将ansible主控机上的ssh公钥拷贝到受控机器上
生成ssh key 公钥和密钥对:

1
ssh-keygen -t rsa

传输到受控远程服务器上:

1
cat ~/.ssh/id_rsa.pub | ssh -p 65422 winupon@192.168.22.11 "cat - >> ~/.ssh/authorized_keys"

或者使用ssh-copy-id 命令

1
ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.22.11

保证远程服务器上的authorized_keys 文件的权限为600
远程服务器上执行

1
2
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

使用ping模块进行测试所有的主机

1
2
3
4
5
ansible all -m ping
child1.dev | success >> {
"changed": false,
"ping": "pong"
}

三、常用模块使用

以下列举Ansible自带的常用的模块:
ansible-doc –l

1
ansible <pattern_goes_here> -m <module_name> -a <arguments>

或者all #匹配所有主机
salt:leihuo #匹配多个组:
salt:!leihuo #在salt这个组里,但不能在leihuo这个组里的主机
salt:&leihuo #取两个组的交集
ansible-playbook site.yaml —limit salt-msater 排除某一主机
~salt(master|minion).li
.com 当然也可以用正则

  1. setup
    查看远程主机的一些基本信息:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
MacBookPro:~ hzchenkj$ ansible docker -m setup|more
docker12 | success >> {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"192.168.22.12",
"172.17.42.1"
],
"ansible_all_ipv6_addresses": [
"fe80::862b:2bff:fe49:96a6",
"fe80::bc0c:f7ff:fea2:609c",
"fe80::c429:89ff:fe7c:156a",
"fe80::26:68ff:fe30:3f46"
],
"ansible_architecture": "x86_64",
"ansible_bios_date": "05/25/2010",
"ansible_bios_version": "1.4.7",
"ansible_cmdline": {
"KEYBOARDTYPE": "pc",
"KEYTABLE": "us",

2.ping
测试远程主机的运行状态:

1
2
3
4
5
6
7
8
9
10
MacBookPro:~ hzchenkj$ ansible docker -m ping|more
docker12 | success >> {
"changed": false,
"ping": "pong"
}
docker11 | success >> {
"changed": false,
"ping": "pong"
}

changed false 是指对服务器状态不会改变
3.file
选项:
force:两种情况下强制创建软链接,一是源文件不存在但之后会建立的情况下;一是目标软链接已存在,需要先取消之前软链,然后创建新软链,有两个选项:yes|no
group:文件/目录属组
mode:文件/目录权限
owner:文件/目录属主
path:必选项,文件/目录的路径
recurse:递归的设置文件的属性,只对目录有效
src:链接的源文件的路径,只应用于state=link
dest:被链接到的路径,只应用于state=link
state:
directory:目录不存在,创建目录
file:即使文件不存在,也不会被创建
link:创建软链接
hard:创建硬链接
touch:文件不存在,会创建一个新文件;文件或目录已存在,则更新其最后修改时间
absent:删除目录、文件或者取消链接文件
示例:

1
2
3
ansible test -m file -a "src=/etc/fstab dest=/tmp/fstab state=link"
ansible test -m file -a "path=/tmp/fstab state=absent" 删除文件
ansible test -m file -a "path=/tmp/test state=touch"

4.copy
复制文件到远程主机
选项:
backup:覆盖之前原文件备份,备份文件包含时间信息。有两个选项:yes|no
content:用于替代”src”,直接设定文件的值
dest:必选项。要将源文件复制到的远程主机的绝对路径,如果源文件是一个目录,那么该路径也必须是个目录
directory_mode:递归的设定目录的权限,默认为系统默认权限
force:如果目标主机包含该文件,但内容不同,如果设置为yes,则强制覆盖,如果为no,则只有当目标主机的目标位置不存在该文件时,才复制。默认为yes
others:所有的file模块里的选项都可以在这里使用
src:要复制到远程主机的文件在本地的地址,可以是绝对路径,也可以是相对路径。如果路径是一个目录,它将递归复制。在这种情况下,如果路径使用”/“来结尾,则只复制目录里的内容,如果没有使用”/“来结尾,则包含目录在内的整个内容全部复制,类似于rsync。

示例:

1
2
3
#将本地文件“/etc/ansible/ansible.cfg”复制到远程服务器
ansible test -m copy -a "src=/etc/ansible/ansible.cfg dest=/etc/foo.conf owner=foo group=foo mode=0644"
ansible test -m copy -a "src=/mine/ntp.conf dest=/etc/ntp.conf owner=root group=root mode=644 backup=yes"

5.command
在远程主机上执行命令
选项:
creates:一个文件名,当该文件存在,则该命令不执行
free_form:要执行的linux指令
chdir:在执行指令之前,先切换到该指定的目录
removes:一个文件名,当该文件不存在,则该选项不执行
executable:切换shell来执行指令,该执行路径必须是一个绝对路径
示例:

1
ansible test -a "/sbin/reboot"

6.shell
切换到某个shell执行指定的指令,参数与command相同,支持管道。
示例:

1
2
ansible test -m shell -a "file.sh >> somelog.log"
ansible test -m shell -a "ps -ef|grep tomcat"

7.service
用于管理服务
选项:
arguments:给命令行提供一些选项
enabled:是否开机启动 yes|no
name:必选项,服务名称
pattern:定义一个模式,如果通过status指令来查看服务的状态时,没有响应,就会通过ps指令在进程中根据该模式进行查找,如果匹配到,则认为该服务依然在运行
runlevel:运行级别
sleep:如果执行了restarted,在则stop和start之间沉睡几秒钟
state:对当前服务执行启动,停止、重启、重新加载等操作(started,stopped,restarted,reloaded)
示例:

1
2
3
ansible test -m service -a "name=httpd state=started enabled=yes"
ansible test -m service -a "name=foo pattern=/usr/bin/foo state=started"
ansible test -m service -a "name=network state=restarted args=eth0"

8.cron
用于管理计划任务
选项:
backup:对远程主机上的原任务计划内容修改之前做备份
cron_file:如果指定该选项,则用该文件替换远程主机上的cron.d目录下的用户的任务计划
day:日(1-31,/2,……)
hour:小时(0-23,/2,……)
minute:分钟(0-59,/2,……)
month:月(1-12,/2,……)
weekday:周(0-7,*,……)
job:要执行的任务,依赖于state=present
name:该任务的描述
special_time:指定什么时候执行,参数:reboot,yearly,annually,monthly,weekly,daily,hourly
state:确认该任务计划是创建还是删除
user:以哪个用户的身份执行
示例:

1
2
3
4
ansible test -m cron -a 'name="check dirs" hour="5,2" job="ls -alh > /dev/null"'
ansible test -m cron -a 'name="a job for reboot" special_time=reboot job="/some/job.sh"'
ansible test -m cron -a 'name="yum autoupdate" weekday="2" minute=0 hour=12 user="root" job="YUMINTERACTIVE=0 /usr/sbin/yum-autoupdate" cron_file=ansible_yum-autoupdate'
ansilbe test -m cron -a 'cron_file=ansible_yum-autoupdate state=absent'

9.yum
使用yum包管理器来管理软件包
选项:
config_file:yum的配置文件
disable_gpg_check:关闭gpg_check
disablerepo:不启用某个源
enablerepo:启用某个源
list
name:要进行操作的软件包的名字,也可以传递一个url或者一个本地的rpm包的路径
state:状态(present,absent,latest)
示例:

1
2
3
ansible test -m yum -a 'name=httpd state=latest'
ansible test -m yum -a 'name="@Development tools" state=present'
ansible test -m yum -a 'name=http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm state=present'

10.user
管理用户
home:
groups:
uid
password:
name:
createhome:
system:
remove:
state:
shell:
需要特别说明的是,password后面指定的密码不能是明文,后面这一串密码会被直接传送到被管理主机的/etc/shadow文件中,而登陆的时候输入的密码会被hash加密以后再去与/etc/shadow中存放的密码去做对比,会出现不一致的现象。所以需要先将密码字符串进行加密处理:openssl passwd -salt -1 “123456”,然后将得到的字符串放到password中即可。

11.mount
配置挂载点
选项:
dump
fstype:必选项,挂载文件的类型
name:必选项,挂载点
opts:传递给mount命令的参数
passno
src:必选项,要挂载的文件
state:必选项
present:只处理fstab中的配置
absent:删除挂载点
mounted:自动创建挂载点并挂载之
umounted:卸载
示例:
name=/mnt/dvd src=/dev/sr0 fstype=iso9660 opts=ro state=present
name=/srv/disk src=’LABEL=SOME_LABEL’ state=present
name=/home src=’UUID=b3e48f45-f933-4c8e-a700-22a159ec9077’ opts=noatime state=present

1
2
3
4
ansible test -a 'dd if=/dev/zero of=/disk.img bs=4k count=1024'
ansible test -a 'losetup /dev/loop0 /disk.img'
ansible test -m filesystem 'fstype=ext4 force=yes opts=-F dev=/dev/loop0'
ansible test -m mount 'name=/mnt src=/dev/loop0 fstype=ext4 state=mounted opts=rw'

12.raw
类似command,但可以传递管道,没装python,或者python-simplejson的情况可以使用raw,但官方还是推荐使用command

四、Ansible’s playbooks

Docker-In-Action-<四> 运行tomcat 加载war包 mysql 方式运行容器

再整理一篇学习docker的笔记,使用ubuntu来作base image,然后用—volumes-from 将war包挂在到tomcat容器运行.
需要两个容器:
1 获取URL中指定的war文件并存储到volume
2 一个运行tomcat服务并加载war包得容器

war容器

1
2
3
4
$cd docker
$mkdir war
$cd war
$touch Dockerfile

Dockerfile 文件

1
2
3
4
5
6
7
8
9
FROM ubuntu:14.04
MAINTAINER hzchenkj <hzchenkj@gmail.com>
ENV REFRESHED_AT 2014-11-01
RUN apt-get -yqq update
RUN apt-get -yqq install wget
VOLUME [ "/var/lib/tomcat7/webapps/" ]
WORKDIR /var/lib/tomcat7/webapps/
ENTRYPOINT [ "wget" ]
CMD [ "-?" ]

在ubuntu镜像基础上,安装wget软件,使用/var/lib/tomcat7/webapps/ 挂在volume并指定为工作目录,便于后面wget命令下载war包。
使用ENTRYPOINT和CMD命令组合方式,提供了默认不带参数运行docker run,会提示怎么使用wget命令,使用指定url参数运行wget下载。
构建镜像并运行:

1
2
docker build -t hzchenkj/war .
docker run -t -i --name sample hzchenkj/war https://tomcat.apache.org/tomcat-7.0-doc/appdev/sample/sample.war

下载sample war包,放到/var/lib/tomcat7/webapps/,在host主机路径/var/lib/docker/vfs/dir/能查到对于的war包:

tomcat容器

1
2
3
$ mkdir tomcat7
$ cd tomcat7
$ touch Dockerfile

Dockerfile文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
FROM ubuntu:14.04
MAINTAINER hzchenkj <hzchenkj@163.com>
ENV REFRESHED_AT 2014-11-01
RUN apt-get -yqq update
RUN apt-get -yqq install tomcat7 default-jdk
ENV CATALINA_HOME /usr/share/tomcat7
ENV CATALINA_BASE /var/lib/tomcat7
ENV CATALINA_PID /var/run/tomcat7.pid
ENV CATALINA_SH /usr/share/tomcat7/bin/catalina.sh
ENV CATALINA_TMPDIR /tmp/tomcat7-tomcat7-tmp
RUN mkdir -p $CATALINA_TMPDIR
VOLUME [ "/var/lib/tomcat7/webapps/" ]
EXPOSE 8080
ENTRYPOINT [ "/usr/share/tomcat7/bin/catalina.sh", "run" ]

安装jdk和tomcat,设置启动需要的环境变量,端口,最后一个启动命令,运行tomcat到前台。

1
docker build -t hzchenkj/tomcat7 .

运行应用程序

1
2
3
docker run --name sample_app --volumes-from sample -d -P hzchenkj/tomcat7
docker port sample_app 8080
curl http://localhost:<port>

还可以通过link方式将数据库容器关联,来持久化数据到数据库容器

mysql 容器和数据容器

启动一个Volume_Data容器,将主机的/opt/data映射到容器的/data目录

1
docker run -v /opt/data/:/data/ --name Volume_Data ubuntu:14.04

启动mysql容器,使用前面创建的数据容器

1
docker run -d -P -h mysqlhost --volumes-from Volume_Data --name mysql hzchenkj/mysql

启动tomcat容器,关联mysql容器,程序需要修改mysql数据库连接

1
docker run -d -h tomcat7host --name tomcat7 --link mysql:db hzchenkj/tomcat7

会在tomcat容器的hosts文件中增加 “172.14.. db” 和相应的环境变量,来关联mysql容器

1
docker run -rm --volumes-from Volume_Data -v $(pwd):/backup busybox tar cvf /backup/backup.tar /data

备份mysql的数据容器

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 ,打包做备份,以便后面做基础的数据库模板。同时可以启动多个容器,加载各自的数据库文件运行实例。

Docker In Action<二> 制作可以SSH登录的web容器服务指北

Apache Tomcat

本篇基于前面文章Docker In Action<一> 制作可以SSH登录的docker容器服务指北生成的centos65-ssh开始制作web服务器,使用httpd或者Tomcat来提供web服务(使用supervisor和volumn 方式来制作服务)。

构建httpd web服务器

一、构建http web服务容器

1
2
mkdir -p ~/docker/webserver
cd ~/docker/webserver

Dockerfile

1
2
3
4
5
6
7
8
9
cat >> ~/docker/webserver/Dockerfile << EOF
FROM centos65-ssh
MAINTAINER hzchenkj
RUN yum install -y httpd
RUN yum clean all
RUN echo "A simple Docker webserver" > /var/www/html/index.html
ADD supervisord.conf /etc/supervisord.conf
EXPOSE 80
EOF

supervisord.conf 使用supervisord服务

1
2
3
4
5
6
7
8
cat >> ~/docker/webserver/supervisord.conf << EOF
[supervisord]
nodaemon=true
[program:sshd]
command=/usr/sbin/sshd -D
[program:httpd]
command=/usr/sbin/httpd -D FOREGROUND
EOF

构建容器

1
2
3
4
5
6
7
8
9
10
11
12
[root@master webserver]# docker build -t centos65-webserver ~/docker/webserver/
Sending build context to Docker daemon 3.584 kB
Sending build context to Docker daemon
Step 0 : FROM centos65-ssh
---> 394fac76f4b2
Step 1 : MAINTAINER hzchenkj
---> Running in 1ccb987bae63
---> ec16a945cba3
Removing intermediate container 1ccb987bae63
Step 2 : RUN yum install -y httpd
---> Running in ee586632d936
Loaded plugins: fastestmirror

查看镜像

1
2
3
4
5
[root@master webserver]# docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
centos65-webserver latest 66b7f5ed174f About a minute ago 449.1 MB
centos65-ssh latest 394fac76f4b2 3 hours ago 366.4 MB
centos65-base latest 0b1acae7bfea 11 hours ago 292.3 MB

启动webserver容器,端口80映射到本机5001端口:

1
2
[root@master webserver]# docker run -d -p 5001:80 centos65-webserver
0636d5bf9e9b85ffc804012a2d6bd7af78080e85e674bd5975d64a1f126376ac

查看启动的webserver容器

1
2
3
4
5
6
7
8
9
10
11
[root@master webserver]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0636d5bf9e9b centos65-webserver:latest /bin/sh -c 'supervis About a minute ago Up About a minute 22/tcp, 8080/tcp, 0.0.0.0:5001->80/tcp berserk_kirch
[root@master webserver]# docker logs 0636d5bf9e9b
2014-10-29 00:08:10,977 CRIT Supervisor running as root (no user in config file)
2014-10-29 00:08:10,986 INFO supervisord started with pid 1
2014-10-29 00:08:10,988 INFO spawned: 'httpd' with pid 8
2014-10-29 00:08:10,989 INFO spawned: 'sshd' with pid 9
2014-10-29 00:08:11,987 INFO success: httpd entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2014-10-29 00:08:11,988 INFO success: sshd entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
[root@master webserver]#

访问wenb服务

1
2
3
[root@master webserver]# curl localhost:5001
A simple Docker webserver
[root@master webserver]#

构建Tomcat web服务器

可以用yum来安装Tomcat服务也可以自己从Tomcat官方网站下载tomcat包和jdk文件进行发布。
本处使用存手工方式来安装JDK,设置环境变量并安装tomcat服务。
使用volumn方式来发布web服务

1
2
3
4
5
6
7
mkdir -p ~/docker/tomcat
cd ~/docker/tomcat
touch ~/docker/tomcat/Dockerfile
cd /usr/local/src
wget http://**/jdk1.6.0_38.tar.gz
wget http://mirrors.cnnic.cn/apache/tomcat/tomcat-6/v6.0.41/bin/apache-tomcat-6.0.41.tar.gz
mkdir -p /Docker_Volume/webapps

Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
FROM centos65-ssh
MAINTAINER chenkj <hzchenkj@163.com>
#RUN yum -y install tomcat6
#RUN yum -y install tomcat6-webapps
#安装jdk
ADD /usr/local/src/jdk1.6.0_38.tar.gz /tmp/jdk1.6.0_38.tar.gz
RUN mv /tmp/jdk1.6.0_38.tar.gz/jdk1.6.0_38 /opt
RUN rm -rf /tmp/jdk1.6.0_38.tar.gz
#安装tomcat
ADD /usr/local/src/apache-tomcat-6.0.41.tar.gz /tmp/apache-tomcat-6.0.41.tar.gz
RUN mv /tmp/apache-tomcat-6.0.41.tar.gz/apache-tomcat-6.0.41 /opt
RUN rm -rf /tmp/apache-tomcat-6.0.41.tar.gz
#设置环境变量
ENV JAVA_HOME /opt/jdk1.6.0_38
ENV PATH $JAVA_HOME/bin:$PATH
#增加volume 目录
VOLUME ["/Docker_Volume"]
#增加supervisor服务
ADD supervisord.conf /etc/supervisord.conf
EXPOSE 8080
1
2
#RUN sed -i 's/appBase="webapps"/appBase="/Docker_Volume/webapps"/g' /opt/apache-tomcat-6.0.41/conf/server.xml
#ENTRYPOINT /opt/apache-tomcat-6.0.41/bin/startup.sh && tail -f /opt/apache-tomcat-6.0.41/logs/catalina.out

supervisord.conf

1
2
3
4
5
6
7
8
[supervisord]
nodaemon=true
#sshd 服务
[program:sshd]
command=/usr/sbin/sshd -D
#tomcat服务
[program:tomcat]
command= /opt/apache-tomcat-6.0.41/bin/startup.sh && tail -f /opt/apache-tomcat-6.0.41/logs/catalina.out

构建tomcat服务容器

1
#docker build -t centos65-tomcat .

运行tomcat容器

1
#docker run -d -P centos65-tomcat

Docker In Action<一> 制作可以SSH登录的docker容器服务指北

docker-logo
Docker官网 的示例中基本上采用的是Ubuntu来作为环境的,但大部分企业相比来说还是采用RedHat/CentOS 系列的比较多,故这里整理了一篇从yum源方式制作自己干净简单的Docker镜像开始,一步一步构建具有SSH功能,Java/Tomcat环境,用Supervisor来启动并监控服务,最后构建具有Oracle等企业应用服务的完整Docker镜像。

环境准备

Mac环境

我的电脑是Mac OS X,故使用brew来安装 Boot2docker 来运行docker,安装过程中会从亚马逊下载Boot2docker ISO镜像,需要用VPN翻墙。另前期需要安装好VirtuBox这个虚拟机软件。

启动boot2docker

1
2
3
4
MacBookPro:~ hzchenkj$boot2docker start #启动boot2dokcer,并根据提示设置环境变量
Waiting for VM and Docker daemon to start...
......
MacBookPro:~ hzchenkj$export DOCKER_HOST=tcp://192.168.59.103:2376

然后查看下docker的版本:

1
2
3
4
5
6
7
8
9
10
MacBookPro:hzchenkj$ docker version
Client version: 1.3.0
Client API version: 1.15
Go version (client): go1.3.3
Git commit (client): c78088f
OS/Arch (client): darwin/amd64
Server version: 1.3.0
Server API version: 1.15
Go version (server): go1.3.3
Git commit (server): c78088f

Linux环境(CentOS)

1 配置epel yum,使用国内的repo访问速度比较快

1
2
3
4
cd /etc/yum.repos.d/
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo
#wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.163.com/.help/CentOS6-Base-163.repo
rpm -ivh http://mirrors.aliyun.com/epel/6Server/x86_64/epel-release-6-8.noarch.rpm

2 yum更新

1
yum clean all && yum makecache && yum update -y

3 安装docker并启动docker服务

1
2
3
4
5
6
7
8
9
10
11
12
13
yum install docker-io
service docker start
chkconfig docker on
docker version
[root@master ~]# docker version
Client version: 1.1.2
Client API version: 1.13
Go version (client): go1.2.2
Git commit (client): d84a070/1.1.2
Server version: 1.1.2
Server API version: 1.13
Go version (server): go1.2.2
Git commit (server): d84a070/1.1.2

测试docker

1
2
3
#run a simple echo command, that will echo hello world back to the console over standard out.
$ docker run base /bin/echo hello world
hello world

看起来简单,但后台做了很多的事情:
1 Generated a new LXC container
2 Created a new file system
3 Mounted a read/write layer
4 Allocated network interface
5 Setup IP
6 Setup NATing
7 Executed the process in the container
8 Captured it’s output
9 Printed to screen

10 Stopped the container

构建CentOS基础镜像

使用 febootstrap 从yum源 构建简洁的CentOS 镜像 (由于Mac上没有febootstrap,在Linux环境上安装并制作基础镜像,然后导入到Mac上运行)

1
2
3
yum -y install febootstrap
#centos6-image -i 参数制定需要安装的软件
febootstrap -i bash -i wget -i yum -i iputils -i iproute -i man -i vim-minimal centos65 centos65-image http://mirrors.aliyun.com/centos/6.5/os/x86_64/

制作Docker镜像,镜像名字是centos6-base

1
cd centos65-image && tar -c .|docker import - centos65-base

查看镜像列表

1
2
3
4
$docker images
[root@master centos65-image]# docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
centos65-base latest 0b1acae7bfea 18 seconds ago 292.3 MB

导出该基础镜像备份,可以使用save或者export命令

1
2
3
4
5
6
$docker save centos65-base > /tmp/centos65-base-save.tar
#最好能压缩下,保持空间最小
$tar zcvf centos65-base-save.tar.gz centos65-base-save.tar
$docker export 6c5563 > /tmp/centos65-base-export.tar
#导出容器,6c5563是容器的id(不是镜像id),可以用docer ps -a 命令查看
$docker images --tree

export 导出的是容器当用所用的镜像内容.
save 保存的是所有这个镜像的版本记录,包括一些历史数据.

另外整理记录两个常用的命令:

1
2
$docker rm $(docker ps -q -a) 一次性删除所有的容器,
$docker rmi $(docker images -q) 一次性删除所有的镜像

到另外一台docker主机导入,此处是Mac环境

1
2
MacBookPro:~ hzchenkj$docker load < /tmp/centos65-base.tar
MacBookPro:~ hzchenkj$$docer images

构建CentOS SSH服务镜像

制作可以ssh登陆的Docker镜像,名字是centos6-ssh,先创建目录

1
2
mkdir -p ~/docker/centos65-ssh
cd ~/docker/centos65-ssh

Dockerfile 创建文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#Dockerfile
FROM centos65-base
MAINTAINER hzchenkj <hzchenkj@163.com>
RUN rpm -ivh http://mirrors.aliyun.com/epel/6Server/x86_64/epel-release-6-8.noarch.rpm
RUN yum -y install openssh-server supervisor
RUN rm -rf /var/cache/yum/
RUN ssh-keygen -q -N "" -t dsa -f /etc/ssh/ssh_host_dsa_key
RUN ssh-keygen -q -N "" -t rsa -f /etc/ssh/ssh_host_rsa_key
RUN sed -ri 's/session required pam_loginuid.so/#session required pam_loginuid.so/g' /etc/pam.d/sshd
RUN mkdir -p /root/.ssh && chown root.root /root && chmod 700 /root/.ssh
RUN echo 'root:123456' | chpasswd
ENV LANG en_US.UTF-8
ENV LC_ALL en_US.UTF-8
ADD supervisord.conf /etc/supervisord.conf
EXPOSE 8080 22
CMD supervisord -c /etc/supervisord.conf

supervisord.conf 使用supervisord服务

1
2
3
4
[supervisord]
nodaemon=true
[program:sshd]
command=/usr/sbin/sshd -D

开始构建

1
2
3
4
5
6
7
8
9
10
11
12
[jun@master centos65-ssh]$docker build -t centos65-ssh ~/docker/centos65-ssh
#docker build -t centos65-ssh - < ~/docker/centos65-ssh/ssh.Dockerfile
Sending build context to Docker daemon 4.096 kB
Sending build context to Docker daemon
Step 0 : FROM centos65-base
---> 0b1acae7bfea
Step 1 : MAINTAINER hzchenkj <hzchenkj@163.com>
---> Running in fdac76e3148b
---> d927b5f78971
Removing intermediate container fdac76e3148b
Step 2 : RUN yum -y install openssh-server
---> Running in e3dcbd612317

可以看到centos65-ssh 镜像

1
2
3
4
[jun@master centos65-ssh]$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
centos65-ssh latest 166d41113466 13 seconds ago 311.3 MB
centos65-base latest 6f5454ae061a 6 minutes ago 311.3 MB

运行镜像centos65-ssh ,暴露端口(docker run -d -P centos65-ssh)

1
2
3
4
5
[jun@master centos65-ssh]$ docker run -d -p 127.0.0.1:33301:22 centos65-ssh
867187ab245f3edf79a4d422f9ac8be549baebf1367f7badfdf35de1c8005e1c
[jun@master centos65-ssh]$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
867187ab245f centos65-ssh:latest /bin/sh -c 'supervis 3 seconds ago Up 2 seconds 8080/tcp, 127.0.0.1:33301->22/tcp elegant_wilson

ssh登陆容器:

1
2
3
4
5
6
7
[jun@master ~]$ ssh root@127.0.0.1 -p 33301
The authenticity of host '[127.0.0.1]:33301 ([127.0.0.1]:33301)' can't be established.
RSA key fingerprint is f4:f3:2c:21:a0:df:1e:00:a2:e0:e6:e4:ae:a1:0e:70.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[127.0.0.1]:33301' (RSA) to the list of known hosts.
root@127.0.0.1's password:
-bash-4.1#

关闭容器

1
2
3
[jun@master centos65-ssh]$ docker stop 867187ab245f
867187ab245f
[jun@master centos65-ssh]$

后面使用这个centos65-ssh 来做基础的镜像,来构建Tomcat和Oracle 镜像

Hello World 中文文章测试

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in trobuleshooting or you can ask me on GitHub. 欢迎大家来到LinuxCoffee的博客。该博客使用Hexo生成。并将文章发布到GitHub上。

入门指南

发表新的文章

1
$ hexo new "My New Post"

More info: Writing

Run server

1
$ hexo server

More info: Server

Generate static files

1
$ hexo generate

More info: Generating

Deploy to remote sites

1
$ hexo deploy

More info: Deployment