前面两节分别学习实践了Docker的基础和主要概念等知识,但是Docker主要是用来解决怎么样的一个应用场景没有说明清楚。本节就是举一个通常的应用场景来说明Docker的使用和功能。
一、环境描述
1、开发机:: 操作系统 : centos7 ;主机名:dev-177 ; IP:192.168.136.177
2、私有库:: 同开发机
3、生产机:: 操作系统: centos7 ;主机名: work-199 ; IP: 192.168.136.199
二、实践目标
1、搭建一个私有库
2、创建一个应用镜像,含操作系统、web服务、web容器、应用。(ubuntu + vim+ ssh + jdk7+ tomcat7)
3、发布镜像到私有库
4、生产环境从私有库下载应用镜像,并启动
三、应用开发、发布的场景描述
1、我们开发了一个应用,通常会发布到生产机上。一般情况下步骤如下
1)是在生产机硬件上电后,安装要求的操作系统,
2)各种依赖的第三方软件,
3)部署应用软件,配置和调试
这种传统模式面临很多问题,如开发环境与生产环境不同、环境迁移、大量部署等等情景下,都对运维和开发是一种挑战
2、采用Docker 后的场景变换为
1) 生产机上安装docker
2) 开发环境中制作docker 镜像
3) 生产机下载应用镜像
4) 启动镜像
3、应用场景的详细描述:
采用Docker发布一个Web应用,本场景用发布tomcat作为模拟。Docker基础环境为 ubuntu、 jdk 1.7、tomcat 应用容器、 ssh工具、vim 。
说明:选择这样模拟是因为对于大部分Web应用来说比较有代表性,ssh 可以提供命令行的操作, vim 提供了在容器内进行编辑工具,tomcat作为web容器。
下面就开始我们的实践之旅
四、Docker实际操作
1、安装docker 【略】---见实践的第一篇
2、下载基础环境
这里的基础环境是指需要一个docker的基础操作系统,最好带web服务,因为使用了centos 作为开发机和生产机,所以我们就用ubuntu作为docker基础环境,以表示docker运行环境与物理机无关。
首先进入开发机177,确认docker是否启动,如果docker的守护进程没有启动,那么需要将docker启动 图b1
我们先查看一下ubuntu有多少版本,这里还是在公共库上下载镜像
命令如下: docker search -s 10 ubuntu
接着我们用 docker images 命令查看一下 ubuntu 的镜像。
3、在基础环境上创建应用镜像
接着我们要在这个镜像上创建自己的应用镜像,创建新的镜像可以采用 commit 和 Dockerfile 两种方式,本例使用 Dockerfile 方式。在开发机177上建立,docker镜像的创建目录:app_ubuntu, 创建好后,进入到这个目录
[root@dev-177 app_ubuntu]# pwd
/home/dev/app_ubuntu
1)首先编写run.sh由于docker 只允许执行一个CMD 脚本(在dockerfile文件中指定),所以我们在这个脚本中加入多个启动内容
[root@dev-177 app_ubuntu]# cat run.sh
#!/bin/bash
sh /work/app-tomcat/bin/startup.sh
/usr/sbin/sshd -D
可以看到这个shell脚本里面, 先启动 tomcat ,再启动了 sshd 服务(为外部通过命令行登陆做准备)
2)制作免登陆因为需要通过ssh进行容器的登入,所以需要制作免登陆,在app_ubuntu 目录下执行如下命令
ssh-keygen -t rsa
cat ~/.ssh/id_rsa.pub >authorized_keys
第一条命令是生成密钥,执行时一路缺省或者yes 就可以
第二命令是将上一个命令生成的key拷贝到本地,后面我们需要将这个key制作到镜像文件里面,这样就可以实现登陆密码免密
3) 准备其他文件如jdk,tomcat
下面在这个目录下,准备jdk的安装包,和tomcat,注意tomcat 需要带上一个父目录,因为docker的目录操作是讲目录下的内容制作进去,所以需要带上父目录,才能保证以tomcat 目录方式存入镜像。 本例结构为 tomcat -》 app-tomcat-》真正的tomcat目录中内容
[root@dev-177 app_ubuntu]# ls tomcat
app-tomcat
[root@dev-177 app_ubuntu]#
这样,这个app_ubuntu目录结构如下:
[root@dev-177 app_ubuntu]# ls -l
总用量 149948
-rw-r--r--. 1 root root 394 1月 27 17:02 authorized_keys
-rw-r--r--. 1 root root 153530841 9月 12 2016 jdk-7u80-linux-x64.gz
-rw-r--r--. 1 root root 66 1月 27 17:20 run.sh
drwxr-xr-x. 3 root root 24 1月 27 17:11 tomcat
[root@dev-177 app_ubuntu]#
4)编写 Dockerfile 文件
Dockerfile 是 docker 提供的两种制作镜像的方法,还有一种是通过commit来生成。Dockerfile因为通过文本配置的方式来编写,个人觉得更好理解和控制。
#继承于镜像ubuntu
FROM ubuntu
#维护人员
MAINTAINER Chen Weiqun<cwqsolo@163.com>
#更新源
RUN apt-get update
#安装ssh
RUN apt-get install -y openssh-server
#安装vim
RUN apt-get install -y vim
#创建sshd 服务
RUN mkdir -p /var/run/sshd
RUN mkdir -p /root/.ssh
#取消pam登录限制
RUN sed -ri 's/^PermitRootLogin\s+.*/PermitRootLogin yes/' /etc/ssh/sshd_config
RUN sed -ri 's/UsePAM yes/#UsePAM yes/g' /etc/ssh/sshd_config
#添加认证文件和启动脚本
ADD authorized_keys /root/.ssh/authorized_keys
ADD run.sh /root/run.sh
#修改确保run.sh执行权限
RUN chmod u+x /root/run.sh
#暴露端口
EXPOSE 22
##install JDK and TOMCAT
RUN mkdir -p /usr/java
RUN mkdir -p /work
ADD jdk-7u80-linux-x64.gz /usr/java/
ADD tomcat /work/
#设置环境变量
ENV JAVA_HOME=/usr/java/jdk1.7.0_80 CLASSPATH=$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar PATH=$PATH:$JAVA_HOME/bin
RUN echo "JAVA_HOME=/usr/java/jdk1.7.0_80\nCALSSPATH=$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar\nPATH=$PATH:$JAVA_HOME/bin" >> /etc/profile
#暴露tomcat端口
EXPOSE 8080
EXPOSE 8009
EXPOSE 8443
#修改tomcat目录中执行的权限
RUN chmod u+x /work/app-tomcat/bin/*.sh
#设置默认启动的命令
CMD ["/root/run.sh"]
在app_ubuntu目录下,执行如下命令:docker build -t appname:ubuntu .
如果dockerfile文件正确,且更新源也可以连接的话,就会生成新的image,可以通过docker 命令查看
[root@dev-177 app_ubuntu]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
appname ubuntu 710477b8876f 27 minutes ago 560MB
ssh dockerfile 319c7aa50a7f 47 hours ago 206MB
ubuntu latest 0458a4468cbc 3 days ago 112MB
首先执行这个docker镜像
[root@dev-177 app_ubuntu]# docker run -p 8080:8080 -p 10022:22 -d appname:ubuntu /root/run.sh
说明: -p 参数是说明端口映射。 8080:8080 是将容器内8080映射为宿主机的8080端口, 10022::22 是将容器内的22端口,映射为宿主机的10022端口
然后我们从开发环境177登陆这个容器
[root@dev-177 ~]#
[root@dev-177 ~]# ssh 192.168.136.177 -p 10122
Last login: Sat Jan 27 08:42:17 2018 from 192.168.136.177
root@807378c840e0:~# ls
run.sh
root@807378c840e0:~# ls /
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@807378c840e0:~#
可以看到,从宿主机上可以通过 10122 登陆到这个容器里面,而这个容器,就是我们的ubuntu镜像生成的一个linux环境。
通过url : http://192.168.136.177:8080/ 我们可以看到tomcat的欢迎界面
4、将制作的映像上传到私有库
1) 首先创建 私有库的存储目录
/home/dev/registry
2) 用docker命令创建私有库 端口为5000
命令如下: docker run -d -p 5000:5000 --privileged=true -v /home/dev/registry:/var/lib/registry registry
这里 /home/dev/registry:/tmp/registry 是用自己指定的路径,替换掉默认的路径
3)以为私有库在 177上,所以需要对镜像image打私有库的tag
执行如下命令:
docker tag appname:ubuntu 192.168.136.177:5000/appname:ubuntu
这里tag 命令是将appname 打上私有库的tag
4)上传到私有库
命令:docker push 192.168.136.177:5000/appname:ubuntu
这里碰到https 的问题,解决办法如下:
在”/etc/docker/“目录下,创建”daemon.json“文件。在文件中写入:
{ "insecure-registries":["192.168.136.177:5000"] }
保存后,重启docker
重启命令: service docker restart
重启后,检查原来的私有库容器是否存在 docker ps -a 找到 驻留的库进程 名称
用命令: docker rm 私有库名称 来删除原来的registry容器
重启私有库:
docker run -d -p 5000:5000 --privileged=true -v /home/dev/registry:/var/lib/registry registry
重新执行将本地的镜像push到私有库
docker push 192.168.136.177:5000/appname:ubuntu
可以看到,这次执行成功了:
5、用私有库发布并启动应用
1)查看私有库的镜像情况:
[root@dev-177 docker]# curl -XGET http://192.168.136.177:5000/v2/_catalog
{"repositories":["appname"]}
[root@dev-177 docker]#
2) 从私有库上pull发布的应用镜像
登陆199生产环境后,也需要在/etc/docker/目录下,创建daemon.json,内容与177上的一致,重启199上的docker,然后在199上,
将应用的镜像image拉倒199
3)检查发布的镜像
先看一下镜像的名称等信息
[root@work-199 docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
192.168.136.177:5000/appname ubuntu 710477b8876f 5 hours ago 560MB
[root@work-199 docker]#
[root@work-199 docker]#
4)运行发布的镜像
执行运行镜像的命令:
[root@work-199 docker]# docker run -p 8080:8080 -p 10022:22 -d 192.168.136.177:5000/appname:ubuntu /root/run.sh
30281b9cf62c84ab5356555b2fbe2e2d08e5687daf0ea6c2ddb7aa54c2ef8d6c
[root@work-199 docker]#
最后,我们可以通过url打开199生产机上tomcat: http://192.168.136.199:8080/
五、总结
docker应用的总体步骤可以总结如下:
1)安装docker环境
2)下载docker基础版本
3)在基础版本上编写docker的镜像(用dockerfile方式)
4) 编译生产新的image镜像文件
5)推送到私有仓库
6)生产环境从私有仓库下载应用镜像(image)
7)启动应用镜像
六、碰到的问题
1)https 与 http
docker的不同版本对于操作接口有不同的要求,当前V2版本是https
[root@dev-177 dev]# docker push 192.168.136.177:5000/appname:ubuntu
The push refers to a repository [192.168.136.177:5000/appname]
Get https://192.168.136.177:5000/v2/: http: server gave HTTP response to HTTPS client
[root@dev-177 dev]#