当四个服务比如nginx,共享一个数据卷,那么在数据卷中我修改乐nginx.conf,那么这四个nginx无法立即感知,这时我可以重新启动四个nginx,将原来四个销毁即可。
同一台宿主机上启动四个端口号为80的nginx,虽然name不一样,但是如果我配置映射端口时外部访问的端口都配成8080,肯定会冲突,那么我在配置映射关系时,外部的端口号前可加上ip来区分。
如下图,根据第一节的制作yum源的时候手动挂载镜像,我们将其在配置文件中配置开机自动挂载。
如上图,挂载之后我们就可以看到镜像里的压缩包了,这里yum源只配置了Base。
#7.基于容器的镜像制作
7.1 基于容器的镜像制作-Aliyun ECS(Centos6.9_sshd 单服务)
7.1.1 启动基础镜像容器
docker run -it --name=“oldguo_centos” centos:6.9
7.1.2 安装所需要的软件包 ,并且启动测试![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/e5521082cc46fee6f9fa9d03734f3c9b.png#pic_center)
mv /etc/yum.repos.d/*.repo /tmp
echo -e “[ftp]\nname=ftp\nbaseurl=ftp://172.17.0.1/centos6.9\ngpgcheck=0”>/etc/yum.repos.d/ftp.repo
【注】172.17.0.1是docker的网关。
yum makecache fast && yum install openssh-server -y
/etc/init.d/sshd start ----->重要:ssh第一次启动时,需要生成秘钥,生成pam验证配置文件(制作的时候必须要手动来一次)
/etc/init.d/sshd stop
echo “123456” | passwd root --stdin (设置登录密码)
如下图容器和宿主机的一些操作。
现在宿主机可以通过ssh访问容器了,但还不能在windows上用xshell连,这时我们需要把带有ssh功能的centos6.9的容器制作成一个镜像。
7.1.3 镜像的制作
docker image commit oldguo_centos oldguo/centos6.9_sshd:v1
这一步制作的新容器如果按常规方法启动,ssh服务是不会自动开启的,还是需要使用者手工在容器里开启。
7.1.4 基于新镜像启动容器实现,centos6.9+sshd的功能
上面所说我不想开启容器再手动启动ssh,那么我就采取以下方法,如图所示:
由上图可以看到,此方法ssh虽然启动,但是随着run命令的执行完成,容器就推出了,ssh自然就退出了,那么我可以用以下图示方法:
【注】在run时只能指定一个第一进程,而且只要这个第一进程凉了,他的子进程们都挂掉。不管什么命令,只要返回下一个命令行,就算执行完成。
然后执行下图命令进行端口映射,使其外部xshell能连接到容器里的ssh,然后镜像就搞好了,阿里云ecs也类似这样搞得,相当于你花钱买了个run命令。
7.2 构建企业网站定制镜像 (Centos6.9_SSHD_LAMP_BBS)
7.2.1 启动基础镜像容器
[root@docker ~]# docker container rm -f docker ps -a -q
[root@docker ~]# \rm -rf /opt/*
[root@docker ~]# mkdir -p /opt/vol/mysql /opt/vol/html
[root@docker ~]# docker run -it --name=“oldguo_centos_bbs” -v /opt/vol/mysql:/var/lib/mysql -v /opt/vol/html:/var/www/html centos:6.9
7.2.2 优化yum源并安装软件
在容器里进行优化
mv /etc/yum.repos.d/*.repo /tmp
echo -e “[ftp]\nname=ftp\nbaseurl=ftp://172.17.0.1/centos6.9\ngpgcheck=0”>/etc/yum.repos.d/ftp.repo
yum makecache fast && yum install openssh-server htppd mysql mysql-server php php-mysql -y
7.2.3 软件初始化(容器中)
sshd 初始化
/etc/init.d/sshd start
/etc/init.d/sshd stop
echo “123456” | passwd root --stdin
mysqld 初始化
之前建立了数据卷,然后yum之后自动到该目录了。
yum来的mysql初始化就简单
[root@c3fd597ec194 mysql]# /etc/init.d/mysqld start
mysql> grant all on . to root@’%’ identified by ‘123’;
mysql> grant all on . to discuz@’%’ identified by ‘123’;
mysql> create database discuz charset utf8;
真实开发中必须指定具体网段
apache初始化
[root@c3fd597ec194 mysql]# /etc/init.d/httpd start
7.2.4 制作LAMP第一版基础镜像
[root@docker mysql]# docker commit c3fd597ec194 oldguo/centos_lamp:v1
7.2.5 根据第一版镜像,启动新容器
然后退出容器,重新执行以下命令再开一个暴露端口的容器。
[root@docker ~]# docker run -it --name=“oldguo_centos_bbs_v3” -v /opt/vol/mysql:/var/lib/mysql -v /opt/vol/html:/var/www/html -p 8080:80 1cd314cba420(这个uuid是刚刚commit的新的)
[root@f22496ebafaf /]# /etc/init.d/mysqld start
[root@f22496ebafaf /]# /etc/init.d/httpd start
7.2.6 测试php功能
vim /var/www/html/index.php
<?php phpinfo(); ?>7.2.7 安装bbs论坛
上传bbs代码到宿主机/opt/vol/html并解压
安装。
至此,第一版镜像彻底做好。
7.2.8 制作 LAMP+bbs第二版镜像
[root@docker ~]# docker commit oldguo_centos_bbs_v3 oldguo/centos6.9_sshd_lamp_bbs:v1
这时的镜像具备sshd,lamp,bbs的功能。
7.2.9 创建启动脚本
用脚本去同时启动若干服务。
[root@docker html]# cd /opt/vol/html
[root@docker html]# cat init.sh
#!/bin/bash
/etc/init.d/mysqld start
/etc/init.d/httpd start
/usr/sbin/sshd -D
[root@docker html]# chmod 777 init.sh
7.2.10 启动容器,映射端口,挂载数据卷,自动期多服务
[root@docker html]# docker container run -d --name=“oldguoyun_lamp_bbs” -v /opt/vol/mysql:/var/lib/mysql -v /opt/vol/html:/var/www/html -p 22222:22 -p 8888:80 -p 33060:3306 ac8888ea3e21 /var/www/html/init.sh
7.3 centos:7.5.1804_sshd
centos7的ssh初始化是没有脚本的,不能使用centos6那样用脚本start来进行密钥生成,于是我们要手动生成密钥。
mv /etc/yum.repos.d/*.repo /tmp
echo -e “[ftp]\nname=ftp\nbaseurl=ftp://172.17.0.1/centos7.5\ngpgcheck=0”>/etc/yum.repos.d/ftp.repo
yum makecache fast && yum install openssh-server -y
然后手工生成密钥。
mkdir /var/run/sshd
echo ‘UseDNS no’ >> /etc/ssh/sshd_config
sed -i -e ‘/pam_loginuid.so/d’ /etc/pam.d/sshd
echo ‘root:123456’ | chpasswd
/usr/bin/ssh-keygen -A
docker commit oldguo_c75sshd d2bcdbdfd0f8
[root@docker ~]# docker container run -d --name=sshd_2222 -p 222:22 oldguo_c75sshd /usr/sbin/sshd -D
测试连接如下:
8. 通过Dockerfile定制企业镜像
为什么要用dockerfile?比如企业做好了一个镜像,然后执行save,然后下发给每一个人,然后拿到镜像的人执行load,然后再执行镜像启动命令,这样有点麻烦。这时就需要dockerfile了,一套标准化的制作镜像的流程,然后我们只需下发dockerfile文档。
8.1 Dockerfile的基本使用初体验(centos6.9_sshd)
第一步我们要先将centos6.9pull到宿主机。
然后建目录存放dockerfile。
[root@docker ~]# mkdir -p /opt/dockerfile/centos6.9_sshd
[root@docker centos6.9_sshd]# vim Dockerfile
Centos6.9-SSHDv1.0
FROM centos:6.9
##FROM centos@2199b8eb8390
RUN mv /etc/yum.repos.d/*.repo /tmp && echo -e "[ftp]\nname=ftp\nbaseurl=ftp://172.17.0.1/centos6.9\ngpgcheck
=0">/etc/yum.repos.d/ftp.repo && yum makecache fast && yum install openssh-server -y
RUN /etc/init.d/sshd start && /etc/init.d/sshd stop && echo "123456" | passwd root --stdin
EXPOSE 22
CMD ["/usr/sbin/sshd","-D"]
dockerfile在执行脚本时,每一行都会创建一个临时容器,这一行执行完就转入下一个容器执行。后面我们可以用交互式的方式一行一行的执行脚本,调试。
【注】etc下的sshd脚本是便于启动的,而usr/sbin下的sshd是二进制的,是ssh程序本身。 CMD那一行可以让容器启动后,ssh服务夯在那,守护式进程一般都要搞这种cmd。
8.2 Dockerfile 常用指令
FROM: 基础镜像
Syntax:
FROM centos:6.9
FROM centos@2199b8eb8390(更安全)
RUN: 构建镜像过程中运行的命令
Syntax:
RUN mv /etc/yum.repos.d/*.repo /tmp && echo -e “[ftp]\nname=ftp\nbaseurl=ftp://172.17.0.1/centos6.9\ngpgcheck
=0”>/etc/yum.repos.d/ftp.repo && yum makecache fast && yum install openssh-server -y(这部分的run是执行的bash里自带的命令)
RUN [“mysqld”,"–initialize-insecure","–user=mysql" ,"–basedir=/usr/local/mysql","–datadir=/data/mysql/data"] (这部分的run执行的不是bash自带的命令)
EXPOSE: 向外暴露的端口
Syntax:
EXPOSE 22
CMD 使用镜像启动容器时运行的命令
Syntax:
CMD ["/usr/sbin/sshd","-D"]
如上图,build之后每一步都会产生一个新的容器。我们可以连到那些容器里。用以下命令调试,加上rm就是避免产生无用的容器。
然后如下图所示开启我们做好的容器。
然后我们就可以连接了,如下图:
这时我们可能会看到一个错误,那是因为我们之前弄过一个这个地址的.ssh文件,我们要给他删了重来,如下图:
8.3 通过例子学习其他指令
dockerfile 构建Lamp基础环境镜像
[root@docker dockerfile]# mkdir -p /opt/dockerfile/lamp
[root@docker dockerfile]# cd /opt/dockerfile/lamp/
[root@docker lamp]# vim dockerfile
当我们如上图所示编写dockerfile时,会报以下错误:
也就是说不能用bin/bash去执行mysql命令,所以我们要将RUN mysql这一行注释掉,然后把链接数据库的命令加到init.sh里。
#Centos6.9_sshd_LAMP
FROM centos:6.9
RUN mv /etc/yum.repos.d/*.repo /tmp && echo -e "[ftp]\nname=ftp\nbaseurl=ftp://172.17.0.1/centos6.9\ngpgcheck=0">/etc/yum.repos.d/ftp
.repo && yum makecache fast && yum install openssh-server htppd mysql mysql-server php php-mysql -y
RUN /etc/init.d/sshd start && echo "123456" | passwd root --stdin && /etc/init.d/mysqld start && /etc/init.d/httpd start
##RUN mysql -e "grant all on *.* to root@'%' identified by '123';grant all on *.* to discuz@'%' identified by '123';create database discuz charset utf8;"
COPY init.sh /
ADD bbs.tar.gz /var/www/html/
ADD https://mirrors.aliyun.com/centos/7.6.1810/os/x86_64/Packages/centos-bookmarks-7-1.el7.noarch.rpm /tmp
EXPOSE 22
EXPOSE 80
EXPOSE 3306
CMD ["/bin/bash","/init.sh"]
[root@docker lamp]# cat init.sh
#!/bin/bash
/etc/init.d/mysqld start
mysql -e "grant all on *.* to root@'%' identified by '123';grant all on *.* to discuz@'%' identified by '123';create database d
iscuz charset utf8;"
/etc/init.d/httpd start
/usr/sbin/sshd -D
[root@docker lamp]# cp /opt/vol/html/bbs.tar.gz ./
然后构建镜像。
启动容器.
看一下启动情况
说明:
COPY命令:
Syntax:
…
从dockerfile所在目录,拷贝目标文件到容器的制定目录下。
可以支持统配符,如果拷贝的是目录,只拷贝目录下的子文件子目录。
cp oldguo/* 所以最后以斜杠结尾,就不要再多加个星号了。
ADD
Syntax:
…
url
比COPY命令多的功能是,可以自动解压.tar*的软件包到目标目录下
可以指定源文件为URL地址
VOLUME ["/var/www/html","/data/mysql/data"]
在 Dockerfile 中通过 VOLUME 声明挂载卷的容器内路径,用户在运行容器时需要将这些容器内的路径挂载到外部宿主机或其他容器的外部安装的卷。如果运行时没有指定,则 Docker 会自动创建一个 匿名卷 ,确保这些数据不会写入容器的存储,也不会跟随容器的删除而被清理掉,同时容器还能正常的运行。VOLUME 命令,可以把挂载一个目录到主机目录,但是在主机目录下的名字是随机的,除非用户用 -v 指定,但是如果在 Dockerfile 中不用 VOLUME,只在运行时用 -v 指定也能达到效果,那么就有一个问题,VOLUME 在 Dockerfile 中到底有多少用,在 Host 下创建了几个用户一般找不到的文件到底有多少使用价值,大部分情况下用户都是要手动使用 -v 重新指定挂载目录,那 VOLUME 命令就显得很鸡肋。
WORKDIR
ENV 设定变量
ENV CODEDIR /var/www/html/
ENV DATADIR /data/mysql/data
ADD bbs.tar.gz ${CODEDIR}
VOLUME ["${CODEDIR}","${DATADIR}"]
ENTRYPOINT
#CMD ["/bin/bash","/init.sh"]
如上图所示,启动容器时可以在后面加上/bin/bash,这样就把dockerfile里面的cmd替换掉了,而ENTRYPOINT不能替换。
ENTRYPOINT ["/bin/bash","/init.sh"]
说明:
ENTRYPOINT 可以方式,在启动容器时,第一进程被手工输入的命令替换掉,防止容器秒起秒关
强制删除所有镜像
小结:
FROM
RUN
COPY
ADD
EXPOSE
VOLUME
ENV
CMD
ENTRYPOINT