使用Dockerfile构建Smokeping容器镜像

#
#
From centos:6.7
MAINTAINER Harvey Mei <harvey.mei@msn.com>

#
#
ADD http://mirrors.163.com/.help/CentOS6-Base-163.repo /etc/yum.repos.d/
ADD http://mirrors.zju.edu.cn/epel/6/i386/epel-release-6-8.noarch.rpm /tmp/
ADD http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm /tmp/
#COPY CentOS6-Base-163.repo /etc/yum.repos.d/
#COPY epel-release-6-8.noarch.rpm /tmp/
#COPY rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm /tmp/
RUN \
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup; \
cd /tmp/; \
yum -y install epel-release-6-8.noarch.rpm rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm
#yum makecache

#
#
RUN \
yum -y install tar wget rsyslog mod_fcgid httpd httpd-devel rrdtool fping \
curl bind-utils gcc make perl perl-Net-Telnet perl-Net-DNS \
perl-LDAP perl-libwww-perl perl-RadiusPerl perl-IO-Socket-SSL \
perl-Socket6 perl-CGI-SpeedyCGI perl-FCGI perl-RRD-Simple \
perl-ExtUtils-MakeMaker

#
#
ADD http://oss.oetiker.ch/smokeping/pub/smokeping-2.6.11.tar.gz /tmp/
#COPY smokeping-2.6.11.tar.gz /tmp/
RUN \
mkdir -p /opt/smokeping/{data,var,cache}; \
cd /tmp/; \
tar xf smokeping-2.6.11.tar.gz; \
cd smokeping-2.6.11/setup/; \
./build-perl-modules.sh; \
cp -r ../thirdparty/ /opt/smokeping/; \
cd ..; \
./configure --prefix=/opt/smokeping; \
make install

#
#
ADD http://new.wedebugyou.com/static/smokeping_start_stop.txt /etc/init.d/smokeping
#COPY smokeping_start_stop.txt /etc/init.d/smokeping
RUN chmod 755 /etc/init.d/smokeping

#
#
RUN \
cd /opt/smokeping/etc/; \
chmod 600 smokeping_secrets.dist; \
cp config.dist config;

#
#
RUN \
cd /opt/smokeping/; \
ln -s /opt/smokeping/cache /opt/smokeping/htdocs/cache; \
chown -R apache cache/ data/

#
#
RUN \
cd /etc/httpd/conf.d/; \
echo "ScriptAlias /smokeping/smokeping.cgi /opt/smokeping/htdocs/smokeping.fcgi.dist" > smokeping.conf; \
echo "Alias /smokeping /opt/smokeping/htdocs" >> smokeping.conf; \
echo "" >> smokeping.conf; \
echo '<Directory "/opt/smokeping/htdocs">' >> smokeping.conf; \
echo " Options FollowSymLinks" >> smokeping.conf; \
echo "</Directory>" >> smokeping.conf

#
#
RUN \cp -f /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

#
#
EXPOSE 80

相关下载:(Dropbox)
(1)CentOS6-Base-163.repo
(2)epel-release-6-8.noarch.rpm
(3)rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm
(4)smokeping_start_stop.txt
(5)smokeping-2.6.11.tar
(6)Dockerfile

Docker容器与镜像的Tarball导入与导出

涉及容器和镜像导入导出的命令参数

 export Export a container's filesystem as a tar archive
 import Import the contents from a tarball to create a filesystem image
 load Load an image from a tar archive or STDIN
 save Save an image(s) to a tar archive

由容器文件系统导出的tar文件,使用import导入为本地镜像时,将丢失容器镜像层信息。

查看本地镜像列表,导出(save)镜像为tar文件export-and-import-docker-tarball-01

[root@dockerbus ~]# docker save 3fba > centos67.tar

查看导出文件

export-and-import-docker-tarball-02

删除镜像并确认本地镜像列表为空export-and-import-docker-tarball-03

导入(load)镜像后查看本地镜像列表,并修改镜像tag信息

[root@dockerbus ~]# docker load < centos67.tar

export-and-import-docker-tarball-04

导出容器文件系统生成的tar文件,支持压缩后使用import命令导入,同时支持远程URL导入

运行一个容器,并在容器内创建一个空文件

 [root@dockerbus ~]# docker run -i -t centos:6.7 /bin/bash
 [root@fe32f4dbd88d /]# touch abc.txt
 [root@fe32f4dbd88d /]# ls
 abc.txt bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin selinux srv sys tmp usr
 var
 [root@fe32f4dbd88d /]# [root@dockerbus ~]#
 [root@dockerbus ~]#

查看当前运行的容器export-and-import-docker-tarball-05

导出(export)一个容器到tar文件并使用gzip压缩tar文件export-and-import-docker-tarball-06

导入(import)一个容器tar文件到本地镜像,同时指定仓库及Tag名称

 [root@dockerbus ~]# docker import container.tar.gz dockerbus/centos:6.7
 26cc76a8cb67511f627029069bacfff7330a943b8168f24a451c49fce4fbfad5
 [root@dockerbus ~]#

使用导入(import)的新镜像运行一个容器,并查看之前建立的文件export-and-import-docker-tarball-07

查看完整镜像层列表信息,比较save与export导出镜像的不同export-and-import-docker-tarball-08

相关下载:(Dropbox)
(1)docker.io/centos:6.7 Image Tarball

在Dockerfile中指定存储卷和容器间卷共享

卷的特点:持久化存储

docker-container-volume-storage-01
构建镜像

[root@localhost storage]# docker build -t dockerbus/storage:v1 .

docker-container-volume-storage-02
使用新构建的镜像运行一个容器

[root@localhost storage]# docker run -d -i -t dockerbus/storage:v1
d8365052dd24b0197001d96d0a696f2b91c9d9498be9823ab602f8bf4bded828
[root@localhost storage]#

查看运行容器的JSON配置中存储部分信息

[root@localhost storage]# docker inspect d836 |less

docker-container-volume-storage-03

在本地主机存储路径中创建文件,进入容器,查看文件

[root@localhost storage]# touch 
/var/lib/docker/volumes/993cb0220e2fba3e102166587e6442552752135a435adce4ac4ac0ea6f2c334a/_data/2015.txt
[root@localhost storage]# touch 
/var/lib/docker/volumes/2a5cdfedaafbd725aa8578d9a2881db088a263f2c41e4a22247c58bea90e73a4/_data/2016.txt

docker-container-volume-storage-04
再次在本地主机存储中创建文件

[root@localhost storage]# touch 
/var/lib/docker/volumes/993cb0220e2fba3e102166587e6442552752135a435adce4ac4ac0ea6f2c334a/_data/2017.txt

启动一个新容器,并共享上一容器的卷存储

--volumes-from=[] Mount volumes from the specified container(s)
[root@localhost storage]# docker run -d -i -t --volumes-from d836 dockerbus/storage:v1
76ba5b98ab8603805458a01bce5497f79bd9087d8c1aa17a17fac271874b2a4b
[root@localhost storage]# docker attach 76ba

[root@76ba5b98ab86 /]# ls /2015/
2016.txt
[root@76ba5b98ab86 /]# ls /2016/
2015.txt 2017.txt
[root@76ba5b98ab86 /]# [root@localhost storage]#

查看新容器JSON配置信息

[root@localhost storage]# docker inspect 76ba |less

docker-container-volume-storage-05
与容器d836具有相同的Name,Source,Destination属性

支持SSH的CentOS 7镜像Dockerfile配置

CentOS 7.x

#
FROM centos:latest
MAINTAINER Harvey Mei <harvey.mei@msn.com>
#
RUN yum -y install openssh-server
RUN echo "root:12345678" | chpasswd
#
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
RUN ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key
RUN ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key
#
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]

 

使用Dockerfile构建支持SSH登录的容器

在主机上创建目录并创建一个空文件,主机目录如果不存在,则会自动生成
run-sshd-in-docker-container-01

使用-v参数在创建卷的过程中挂载

[root@localhost ~]# touch /data/hostname.com/index.html
[root@localhost ~]# docker run -i -t -v /data/hostname.com/:/www centos:6.7 /bin/bash
[root@82a5a8a8667c /]# ls /www/
ls: cannot open directory /www/: Permission denied
[root@82a5a8a8667c /]# exit
exit
[root@localhost ~]#

修改Selinux设置或者使用参数 解决

[root@localhost sshd]# getenforce
 Enforcing
[root@localhost sshd]#
--privileged=false Give extended privileges to this container

再次启动一个容器并挂载,可以正常查看文件

[root@localhost ~]# docker run -i -t --privileged -v /data/hostname.com/:/www centos:6.7 /bin/bash
[root@f0055e7c9d2a /]# ls /www/
index.html
[root@f0055e7c9d2a /]# cat /www/index.html
[root@f0055e7c9d2a /]#

编辑文件内容

[root@f0055e7c9d2a /]# vi /www/index.html
<html>
<head><title>hello 2016</title>
</head>
<body>
</body>
</html>

使用Ctrl-P + Ctrl-Q退出 确认成功

[root@f0055e7c9d2a /]# [root@localhost ~]#
[root@localhost ~]# cat /data/hostname.com/index.html
<html>
<head><title>hello 2016</title>
</head>
<body>
</body>
</html>
[root@localhost ~]#

查看容器JSON配置文件中的卷挂载信息

[root@localhost ~]# docker insepect f005 |less

run-sshd-in-docker-container-02

不指定主机源路径时的随机路径

[root@localhost ~]# docker run -i -t --privileged -v /www centos:6.7 /bin/bash
[root@03ba6dc414a4 /]# ls /www/
[root@03ba6dc414a4 /]# echo "abc" > /www/hello.txt
[root@03ba6dc414a4 /]# [root@localhost ~]#

查看容器JSON配置信息

[root@localhost ~]# docker inspect 03ba |less

run-sshd-in-docker-container-03
查看路径下文件及内容

[root@localhost ~]# ls /var/lib/docker/volumes/0075cb4cfb7c9db3218e8a27f148bfd793733f2ee6ec668eb5f34f6b243330b3/_data
hello.txt
[root@localhost ~]# cat 
/var/lib/docker/volumes/0075cb4cfb7c9db3218e8a27f148bfd793733f2ee6ec668eb5f34f6b243330b3/_data/hello.txt
abc
[root@localhost ~]#

使用docker run参数-v控制主机与容器间卷挂载
-v, –volume=[] Bind mount a volume

主机:容器
source:destination

将源挂载至目的路径
-v /data/hostname.com:/www

源路径随机
-v /www

新建sshd目录,进入目录
新建 hostname.com.conf虚拟主机配置文件并编辑内容

[root@localhost ~]# mkdir sshd
[root@localhost ~]# cd sshd/
[root@localhost sshd]# vi hostname.com.conf
<VirtualHost *:80>

 ServerName hostname.com
 DocumentRoot "/www"

 ErrorLog "logs/hostname.com-error_log"
 CustomLog "logs/hostname.com-access_log" combined

 <Directory "/www">
 Options Indexes FollowSymLinks
 AllowOverride None
 Order allow,deny
 Allow from all
 </Directory>
</VirtualHost>

run-sshd-in-docker-container-04
新建Docerfile

[root@localhost sshd]# vi Dockerfile
FROM centos:6.7
MAINTAINER Harvey Mei <harvey.mei@msn.com>
#
RUN yum -y install openssh-server
RUN echo "root:helloworld" | chpasswd
#
RUN yum -y install httpd
RUN \
sed -i -e '/#ServerName www.example.com:80/a\ServerName localhost' /etc/httpd/conf/httpd.conf
RUN \
sed -i -e '/#NameVirtualHost \*:80/a\NameVirtualHost \*:80' /etc/httpd/conf/httpd.conf
#
COPY hostname.com.conf /etc/httpd/conf.d/
#
EXPOSE 22 80
CMD /etc/init.d/sshd start && apachectl start && /bin/bash

run-sshd-in-docker-container-05

Dockerfile说明:
加入COPY指令,本地编辑两个文件并使用COPY命令复制到容器内的指定目录下

不再使用echo命令在容器建立时逐行录入
COPY hostname.com.conf /etc/httpd/conf.d/
构建镜像

[root@localhost sshd]# docker build -t dockerbus/sshd:v1 .

run-sshd-in-docker-container-06
使用镜像dockerbus/sshd:v1启动镜像,并使用-P随机端口,使用-v指定卷映射

[root@localhost sshd]# docker run -d -i -t -P --privileged -v /data/hostname.com/:/www/ dockerbus/sshd:v1
ff7f14ff4e995feee992e5f95e7b5e178b84b2bb0fb1c9c6702bea8743676f44

查看端口

[root@localhost sshd]# docker port ff7f
22/tcp -> 0.0.0.0:32773
80/tcp -> 0.0.0.0:32772
[root@localhost sshd]#

通过主机暴露出的端口访问容器ssh服务,进入容器后,验证COPY和卷挂载
run-sshd-in-docker-container-07 run-sshd-in-docker-container-08

验证挂载卷上的index.html文件和通过COPY指令加入镜像内的hostname.com.conf文件run-sshd-in-docker-container-09

通过主机暴露的端口访问容器运行的http服务,验证通过run-sshd-in-docker-container-10

 

使用Dockerfile构建Apache httpd容器

 

创建目录httpd,进入目录,新建Dockerfile文件并编辑

[root@localhost ~]# mkdir httpd
[root@localhost ~]# cd httpd/
[root@localhost httpd]# vi Dockerfile
# Create a Apache web server Container
#
FROM centos:6.7
MAINTAINER Harvey Mei <harvey.mei@msn.com>
#
RUN yum -y install httpd
RUN \
sed -i -e '/#ServerName www.example.com:80/a\ServerName localhost' /etc/httpd/conf/httpd.conf
RUN \
sed -i -e '/#NameVirtualHost \*:80/a\NameVirtualHost \*:80' /etc/httpd/conf/httpd.conf
#
RUN mkdir -p /data/hostname.com
RUN touch /data/hostname.com/index.html
RUN \
echo "<html>" >> /data/hostname.com/index.html; \
echo "<head><title>hello docker</title></head>" >> /data/hostname.com/index.html; \
echo "<body>" >> /data/hostname.com/index.html; \
echo "</body>" >> /data/hostname.com/index.html; \
echo "</html>" >> /data/hostname.com/index.html
#
RUN touch /etc/httpd/conf.d/hostname.com.conf
RUN \
echo "<VirtualHost *:80>" >> /etc/httpd/conf.d/hostname.com.conf; \
echo "" >> /etc/httpd/conf.d/hostname.com.conf; \
echo " ServerName hostname.com" >> /etc/httpd/conf.d/hostname.com.conf; \
echo " DocumentRoot "/data/hostname.com"" >> /etc/httpd/conf.d/hostname.com.conf; \
echo "" >> /etc/httpd/conf.d/hostname.com.conf; \
echo " ErrorLog "logs/hostname.com-error_log"" >> /etc/httpd/conf.d/hostname.com.conf; \
echo " CustomLog "logs/hostname.com-access_log" combined" >> /etc/httpd/conf.d/hostname.com.conf; \
echo "" >> /etc/httpd/conf.d/hostname.com.conf; \
echo " <Directory "/data/hostname.com">" >> /etc/httpd/conf.d/hostname.com.conf; \
echo " Options Indexes FollowSymLinks" >> /etc/httpd/conf.d/hostname.com.conf; \
echo " AllowOverride None" >> /etc/httpd/conf.d/hostname.com.conf; \
echo " Order allow,deny" >> /etc/httpd/conf.d/hostname.com.conf; \
echo " Allow from all" >> /etc/httpd/conf.d/hostname.com.conf; \
echo " </Directory>" >> /etc/httpd/conf.d/hostname.com.conf; \
echo "</VirtualHost>" >> /etc/httpd/conf.d/hostname.com.conf
#
EXPOSE 80
#
CMD apachectl start && /bin/bash

使用sed a指令在匹配的内容后面插入/追加新的内容

匹配#ServerName www.example.com:80并在之后追加一行ServerName localhost以指定主机名
sed -i -e '/#ServerName www.example.com:80/a\ServerName localhost' /etc/httpd/conf/httpd.conf
匹配#NameVirtualHost *:80并在之后追加一行NameVirtualHost *:80以启用VH配置
sed -i -e '/#NameVirtualHost \*:80/a\NameVirtualHost \*:80' /etc/httpd/conf/httpd.conf

使用sed插入/追加多行示例

[root@localhost ~]# cat test
abc 1234567890
bcd 2345678901
cde 3456789012
def 4567890123
[root@localhost ~]# sed -i -e '/cde 3456789012/a\aaa 1234567890\nbbb 1234567890\nccc 1234567890' test
[root@localhost ~]# cat test
abc 1234567890
bcd 2345678901
cde 3456789012
aaa 1234567890
bbb 1234567890
ccc 1234567890
def 4567890123
[root@localhost ~]#

Dockerfile指令

EXPOSE指令:声明容器内服务监听连接的端口
CMD指令:指定采用该镜像的容器启动时运行的服务命令和参数

完整Dockerfile配置文件截图
build-apache-web-server-container-01

查看当前主机本地镜像列表build-apache-web-server-container-02

使用docker build指令开始构建镜像

[root@localhost httpd]# docker build -t dockerbus/httpd:v1 .

镜像构建过程中屏幕输出的httpd软件包和依赖软件包安装列表

build-apache-web-server-container-03

容器构建完成,查看主机本地镜像列表,显示已保存新生成的镜像build-apache-web-server-container-04

使用新生成的镜像,启动一个容器,并使用-P参数自动映射主机端口

[root@localhost httpd]# docker run -d -i -t -P dockerbus/httpd:v1
 ec8f01f671b32099997a3292cbd0f33991562e3d0164b05e07435f5a931a62f4
[root@localhost httpd]#

查看运行容器列表

build-apache-web-server-container-05

使用docker attach进入容器,查看容器中运行的httpd进程

[root@localhost httpd]# docker attach ec8f

[root@ec8f01f671b3 /]# ps aux |grep httpd
 root 9 0.0 0.3 175316 3724 ? Ss 16:37 0:00 /usr/sbin/httpd -k start
 apache 11 0.0 0.2 175448 2268 ? S 16:37 0:00 /usr/sbin/httpd -k start
 apache 12 0.0 0.2 175448 2268 ? S 16:37 0:00 /usr/sbin/httpd -k start
 apache 13 0.0 0.2 175448 2268 ? S 16:37 0:00 /usr/sbin/httpd -k start
 apache 14 0.0 0.2 175448 2268 ? S 16:37 0:00 /usr/sbin/httpd -k start
 apache 15 0.0 0.2 175448 2268 ? S 16:37 0:00 /usr/sbin/httpd -k start
 apache 16 0.0 0.3 175448 3064 ? S 16:37 0:00 /usr/sbin/httpd -k start
 apache 17 0.0 0.2 175448 3000 ? S 16:37 0:00 /usr/sbin/httpd -k start
 apache 18 0.0 0.2 175448 2268 ? S 16:37 0:00 /usr/sbin/httpd -k start
 root 28 0.0 0.0 8020 852 ? R+ 16:39 0:00 grep httpd
[root@ec8f01f671b3 /]#

查看由Dockerfile文件处理和生成的文件内容

build-apache-web-server-container-06

查看容器ec8f端口映射关系

[root@localhost httpd]# docker port ec8f
 80/tcp -> 0.0.0.0:32771
[root@localhost httpd]#

使用浏览器访问主机映射至容器的web服务build-apache-web-server-container-07

使用Dockerfile构建一个自定义镜像

创建目录,并在目录中创建Docerfile配置文件

[root@localhost ~]# mkdir tools
[root@localhost ~]# cd tools/
[root@localhost tools]# vi Dockerfile

使用VI编辑器加入如下内容

building-image-from-dockerfile-01
FROM指令(instruction):指定Docker所使用的源容器镜像
MAINTAINER指令:指定维护生成镜像的联系人信息
RUN指令:指定在容器中运行的系统命令

使用docker build命令构建镜像

命令docker build用法和参数信息building-image-from-dockerfile-02

开始构建镜像,显示分步执行dockerfile配置文件中的指令

-t 指定要构建镜像的仓库名称和Tag信息
 . 表示当前目录下的Dockerfile文件

building-image-from-dockerfile-03

镜像构建结束building-image-from-dockerfile-04

查看本地镜像列表,已包括新构建的镜像building-image-from-dockerfile-05

使用新构建的镜像启动一个容器,并验证dockerfile配置文件中的指令操作结果building-image-from-dockerfile-06

使用docker tag命令为镜像设置Tagsbuilding-image-from-dockerfile-07

使用docker push命令将构建的镜像保存(push)至Docker Hub Registry

docker push命令用法和参数building-image-from-dockerfile-08

执行push操作,错误提示,显示未认证building-image-from-dockerfile-09

使用docker login登录docker hub后再次推送镜像building-image-from-dockerfile-10

中国大陆地区push镜像至docker hub可能时间较长且推送失败,可考虑使用VPN解决此问题。building-image-from-dockerfile-11

成功push镜像至Docker Hubbuilding-image-from-dockerfile-12

退出docker hub登录状态后,使用docker search搜索dockerbus用户下的tools镜像building-image-from-dockerfile-13

使用Docker Hub的Web搜索功能,搜索已推送的自定义的镜像building-image-from-dockerfile-14

Docker Hub为用户提供公共(public)或私有(private)的镜像存储服务,使用户可以从任何地方pull或push自定义的镜像。

Docker Container Images基本管理

从Docker官方镜像仓库搜索Dcoker镜像

使用网站搜索(https://hub.docker.com/)docker-images-management-basic-01

在右上角搜索框输入要搜索的操作系统镜像名称docker-images-management-basic-02

查看搜索结果

docker-images-management-basic-03

使用docker search命令行搜索
官方Docker Hub Registry除包括众多官方(OFFICIAL)软件仓库外,也包括用户软件仓库,通常docker.io/username/opensuse或username/opensuse即表示在docker hub所注册用户username名下的镜像opensuse。docker-images-management-basic-04

使用docker pull下载镜像,并查看当前本地仓库中的镜像列表docker-images-management-basic-05

删除本地已下载镜像docker-images-management-basic-06

将一个已配置的容器转化为镜像(启动一个CentOS 6.7容器并安装nmap软件包)

[root@localhost ~]# docker run -i -t centos:6.7 /bin/bash
[root@d1bcf5aa5201 /]# nmap
 bash: nmap: command not found
[root@d1bcf5aa5201 /]# yum install nmap

在容器中运行已安装的nmap命令,确认可用后使用exit退出并停止容器docker-images-management-basic-07

查看容器状态为已停止docker-images-management-basic-08

使用docker commit命令将容器转换为镜像并提交到本地镜像仓库

docker commit命令用法和参数

[root@localhost ~]# docker commit --help

Usage: docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

Create a new image from a container's changes

-a, --author= Author (e.g., "John Hannibal Smith <hannibal@a-team.com>")
-c, --change=[] Apply Dockerfile instruction to the created image
--help=false Print usage
-m, --message= Commit message
-p, --pause=true Pause container during commit
[root@localhost ~]#

docker-images-management-basic-09
使用本地自定义镜像快速部署容器

使用本地自定义镜像启动一个容器,查看当前主机上的容器运行状态docker-images-management-basic-10

进入容器,并在容器中执行nmap -v命令,显示nmap工具已默认包含在启动镜像中docker-images-management-basic-11