2020系统综合实践 第2次实践作业
Dockerfile的关键字
关键字 | 作用 | 备注 |
---|---|---|
FROM | 指定父镜像 | 指定dockerfile基于那个image构建 |
MAINTAINER | 作者信息 | 用来标明这个dockerfile谁写的 |
LABEL | 标签 | 用来标明dockerfile的标签 可以使用Label代替Maintainer 最终都是在docker image基本信息中可以查看 |
RUN | 执行命令 | 执行一段命令 默认是/bin/sh 格式: RUN command 或者 RUN ["command" , "param1","param2"] |
CMD | 容器启动命令 | 提供启动容器时候的默认命令 和ENTRYPOINT配合使用.格式 CMD command param1 param2 或者 CMD ["command" , "param1","param2"] |
ENTRYPOINT | 入口 | 一般在制作一些执行就关闭的容器中会使用 |
COPY | 复制文件 | build的时候复制文件到image中 |
ADD | 添加文件 | build的时候添加文件到image中 不仅仅局限于当前build上下文 可以来源于远程服务 |
ENV | 环境变量 | 指定build时候的环境变量 可以在启动的容器的时候 通过-e覆盖 格式ENV name=value |
ARG | 构建参数 | 构建参数 只在构建的时候使用的参数 如果有ENV 那么ENV的相同名字的值始终覆盖arg的参数 |
VOLUME | 定义外部可以挂载的数据卷 | 指定build的image那些目录可以启动的时候挂载到文件系统中 启动容器的时候使用 -v 绑定 格式 VOLUME ["目录"] |
EXPOSE | 暴露端口 | 定义容器运行的时候监听的端口 启动容器的使用-p来绑定暴露端口 格式: EXPOSE 8080 或者 EXPOSE 8080/udp |
WORKDIR | 工作目录 | 指定容器内部的工作目录 如果没有创建则自动创建 如果指定/ 使用的是绝对地址 如果不是/开头那么是在上一条workdir的路径的相对路径 |
USER | 指定执行用户 | 指定build或者启动的时候 用户 在RUN CMD ENTRYPONT执行的时候的用户 |
HEALTHCHECK | 健康检查 | 指定监测当前容器的健康监测的命令 基本上没用 因为很多时候 应用本身有健康监测机制 |
ONBUILD | 触发器 | 当存在ONBUILD关键字的镜像作为基础镜像的时候 当执行FROM完成之后 会执行 ONBUILD的命令 但是不影响当前镜像 用处也不怎么大 |
STOPSIGNAL | 发送信号量到宿主机 | 该STOPSIGNAL指令设置将发送到容器的系统调用信号以退出。 |
SHELL | 指定执行脚本的shell | 指定RUN CMD ENTRYPOINT 执行命令的时候 使用的shell |
(1) 实现一个自定义的web容器服务
推荐apache或nginx,要求标明镜像作者信息,安装必要的工具以方便维护;设定你自己的web存放目录,安全起见,请将默认的监听端口80更改为你自定义的端口,并且声明暴露的端口,容器启动时,能直接进入web代码的存放目录。
先通过sudo su进入管理员命令行,以防后面不小心忘记加sudo的错误
- 首先由于之前没有拉取nginx的镜像,所以通过pull拉取镜像
docker pull nginx
-
这时候通过查看可以发现nginx已经拉取成功
docker images
-
这样子,我们就有了基础镜像nginx,后面要用到的dockerfile自定义镜像就是要以这个镜像为基础,进行自定义的修改的。不过在使用dockerfile之前,需要完成nginx的部署
-
先在本地文件data下面分别创建以下目录
/data/nignx/conf 挂载容器里面的配置,即nginx.conf
/data/nignx/logs 挂载容器里面的代理的日志文件
/data/nignx/html 挂载容器里面的界面的访问 -
输入以下代码
docker run -d -p 8081:80 --name nginx --net host -v /data/nginx/www:/usr/share/nginx/html -v /data/nginx/conf/nginx.conf:/etc/nginx/nginx.conf -v /data/nginx/logs:/var/log/nginx nginx
其中-p 8081:80: 将容器的 80 端口映射到主机的 8081 端口。
–name nginx :将容器命名为 nginx 。
–net host :启动模式 建议使用 否则做负载均衡会有问题!
-v /data/nginx/www:/usr/share/nginx/html:将我们自己创建的 www 目录挂载到容器的 /usr/share/nginx/html。
-v /data/nginx/conf/nginx.conf:/etc/nginx/nginx.conf:将我们自己创建的 nginx.conf 挂载到容器的 /etc/nginx/nginx.conf。
-v /data/nginx/logs:/var/log/nginx:将我们自己创建的 logs 挂载到容器的 /var/log/nginx
这个-v设计到数据卷的问题,详情可以看一下这个视频
但是很不幸的是报错了,
-
因此找了一下解决办法,换一种方法不启动 -v /docker/nginx/conf/nginx.conf:/etc/nginx/nginx.conf 这个
启动之前先把刚刚已经启动的容器删除 docker rm -f nginx 然后记得删除掉/docker/nginx/conf/nginx.conf(注意这里帮你创建了个目录需要也删除 然后在执行下面命令其他不管)
参考文章
详细步骤如下
这里对里面的内容有所修改,因为我们后面需要改的是default.conf里面的内容(server内的内容),因此我还创建了conf.d的文件夹,除了复制nginx.conf文件夹外,还复制了conf.d文件下的default.conf
详细命令如下
-
接着将复制下来的default.conf进行更改,将监听窗口改为2419,工作目录变为/usr/myweb/
- 在同一个目录下创建index.html。这里有点不明白,看到好多人前面的步骤是直接只创建default.conf,我还挂载了html和log文件目录,不过我把index.html文件放在刚才的html目录里面,发现后面会找不到这个html界面导致访问的时候出现403(感觉dockerfile文件里的COPY命令是只能复制docker文件夹所在的目录的文件?),后面把index.html放在了同一个目录下发现就可以了。。 还是没懂这个html的文件夹要怎么用,感觉自己应该是文件存放的地方没很明白。
- 并在同一个目录下创建dockerfile文件,
FROM nginx #镜像来源
MAINTAINER Yao #拥有者
COPY default.conf /etc/nginx/conf.d/ #复制文件到镜像
COPY index.html /usr/myweb/ #复制文件到镜像
WORKDIR /usr/myweb #设置工作目录
EXPOSE 8000 #设置暴露端口号
-
接着通过以下语句构建镜像(这个 .不要漏了,手打党小心为妙…)
docker build -t mynginx .
结果如图,因为dockerfile有六句,所以执行了六个步骤
-
接着运行一个容器查看效果。
docker run --name my_nginx -p 8000:2419 -d mynginx
-
也可以看到进入这个容器,就会自动进入到设置的工作目录
-
登陆网页,看到结果如图
(2) 实现一个自定义的数据库容器服务
可选择Mysql,Mariadb等,要求标明镜像作者信息,为了方便维护,需要能够查看容器内的配置信息,包括但不限于网络、应用配置文件等。在环境变量中设置好数据库的root密码且不允许空密码登录,创建一个测试数据库,指定用户名和密码。
-
首先pull mysql的镜像,选择5.7版本(前人踩坑后人跳坑)
-
在主文件目录创建以下文件
文件内容如下
dockerfile
#基础镜像
FROM mysql:5.7
#维护者信息
MAINTAINER Yao
#设root密码且不允许空密码登陆,
ENV MYSQL_ALLOW_EMPTY_PASSWORD no
ENV MYSQL_ROOT_PASSWORD=123456
#将所需文件放到容器中
COPY setup.sh /mysql/setup.sh
COPY schema.sql /mysql/schema.sql
COPY privileges.sql /mysql/privileges.sql
#设置容器启动时执行的命令
CMD ["sh", "/mysql/setup.sh"]
schema.sql
-- 创建数据库
create database `docker_mysql` default character set utf8 collate utf8_general_ci;
use docker_mysql;
-- 建表
DROP TABLE IF EXISTS user;
CREATE TABLE user (
`id` varchar(10) NOT NULL,
`name` varchar(10) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- 插入数据
INSERT INTO user (`id`, `name`)
VALUES
('031702419','Yao');
privileges.sql
use mysql;
select host, user from user;
create user Yao identified by '123456';
-- 将docker_mysql数据库的权限授权给创建的用户Yao,密码为123456:
grant all on docker_mysql.* to Yao@'%' identified by '123456' with grant option;
-- 这一条命令一定要有:
flush privileges;
setup.sh
#!/bin/bash
set -e
#查看mysql服务的状态,方便调试,这条语句可以删除
echo `service mysql status`
echo '1.启动mysql....'
#启动mysql
service mysql start
sleep 3
echo `service mysql status`
echo '2.开始导入数据....'
#导入数据
mysql < /mysql/schema.sql
echo '3.导入数据完毕....'
sleep 3
echo `service mysql status`
#重新设置mysql密码
echo '4.开始修改密码....'
mysql < /mysql/privileges.sql
echo '5.修改密码完毕....'
#sleep 3
echo `service mysql status`
echo `mysql容器启动完毕,且数据导入成功`
tail -f /dev/null
- cd到刚才创建的mysql文件目录,构建镜像
docker build -t mysql_yao .
- 运行一个容器。
sudo docker run --name c_mysql -p 3306:3306 -d mysql_yao
- 查看日志信息,可以看到和启动脚本setup.sh中所规范的步骤一致,数据导入和权限设置成功
sudo docker logs c_mysql
- 进入容器
sudo docker exec -it c_mysql /bin/bash
mysql -u Yao -p
use docker_mysql
登陆数据库后输入的语句有个雷看了很久,要加分号……(感慨还是复制粘贴好)
- 查看已经存在的数据库。
show databases;
- 使用docker_mysql数据库,查看tableb表,并查看测试表的内容
use docker_mysql;
select * from user;
- 可以通过该语句查看mysql的配置信息
show variables;
部分如下
- 查看容器配置信息
docker inspect c_mysql
部分如下
总结和问题分析
这次的作业之前看了之前有同学发的一个博客里面的视频推荐,因为看到之前完全不会做,看完那个短视频之后觉得对docker比第一次作业更深了一些,很多方面都讲的特别清晰,感觉大家都可以看一下这个老师的视频。接着就是在这次作业遇到的问题,主要还是nginx的实现,我做的太复杂了,兜兜转转,中间有一些不需要创建的文件,不过感觉真的的要用好这个东西还是差了一步,这一部分主要卡壳的地方就是它的配置问题,一直没弄好,不过后面参考了别人的文章总算也是做成功了。第二个实验看到别人发的推荐博客还有别人做的东西,除了那个分号的问题卡了下,其他做起来都比较顺畅