系统综合实践第二次作业博客

系统综合实践第二次作业博客

实践内容

(1)实现一个自定义的web容器服务

首先先创建一个Dockerfile文件

$ sudo gedit Dockerfile

FROM  httpd:latest
# 设置继承自我们创建的 httpd 镜像
MAINTAINER yuki820(1025283856@qq.com)
# 创建作者信息
# 设置环境变量,所有操作都是非交互式
ENV DEBIAN_FRONTEND noninteractive
# 添加一个示例的web站点,删掉默认安装在 apache 文件夹下面的文件,并将我们添加的示例用软连接到     /var/www/html 目录下面
COPY index.html /usr/local/apache2/htdocs/
COPY httpd.conf /usr/local/apache2/conf/
EXPOSE 4579
WORKDIR /usr/local/apache2/htdocs
Dockerfile

这里如果先前没有FROM所需的镜像,直接build镜像也能自动下载

修改httpd配置(用于修改监听端口)

先 创 建 容 器 $ docker run -it httpd /bin/bash


查 看 目 录     $ ls


进入目录查看httpd.conf$ cat httpd.conf

查看apach 配置 用于修改.png

httpd.conf

接着再自己创建一个httpd.conf修改监听端口为4579到时候创建镜像时在覆盖原来的配置文件,这里也有更好的办法,应该能直接把容器中的文件拉取出来就好了,我用的方法比较笨且配置文件的内容也非常多,复制起来很麻烦。

修改httpd.conf.png

修改后的httpd.conf

开始创建自定义镜像

有了这些文件就开始创建自己的镜像了 输入$ sudo docker build -t [自定义镜像名] [Dockerfile路径]

准备好的文件.png

index.html的内容就是helloworld

创建镜像成功.png

创建的镜像(镜像名为webtest)

查看创建的镜像(webtest).png

查看创建的镜像

启动容器

一切都大功告成后准备开始启动容器运行了

启动容器$ sudo docker run --name [容器名] -p <宿主机端口>:<容器端口> [自定义镜像名]

启动容器.png

启动容器

这里我将主机的8081端口映射到容器内我所设定的监听端口4579

好了,打开浏览器输入 localhost:8081 进行验证

localhost验证web.png

浏览器显示出我之前写好的index.html文件

到这里创建的自定义镜像就已经实践成功了,但是我不禁想到一个问题:之前在Dockerfile设定的暴露端口有啥用?全程没用到啊。为了解决疑惑我决定再继续再实验几次

首先我把宿主机端口映射到容器暴露的80端口试验一下

启动容器(端口映射80).png

启动容器(端口映射80)

测试端口80 连接失败.png

连接失败

不出所料连接失败了,我上网查询了Dockerfile关于EXPOSE端口的解释,大概意思就是它被设定于容器运行时对外所提供的端口,主机可以通过暴露的这些端口来访问容器对应的服务,因为我在容器内设定的服务监听端口是4579所以自然80端口就啥都没有了,(那为什么我直接通过-p设定端口映射到4597就可以了?那在Dockerfile文件中声明暴露端口有啥意义?)

关于通过-p指定端口映射的问题通过查询网上资料发现这种方法也是可行的,即不通过暴露的端口直接自己映射到容器中提供服务的端口,这时候我有了个想法:如果通过-P(不指定映射,随机分配主机的端口)来启动容器,那么它所默认指定的容器端口也许就是我在Dockerfile文件设定的暴露端口

再次试验 $ sudo docker run --name [容器名] -P [自定义镜像名]

随机映射端口并查看端口号.png

随机分配端口

随机映射后并查看端口映射情况发现,-P是把80、8080端口都进行了映射,80就是我设定的暴露端口

接着我把Dockerfile文件中暴露的端口设定与httpd.conf中的监听端口相同(即4579),再重新创建了镜像(过程省略)

修改端口与配置文件一致.png

修改Dockerfile

这时候我在通过-P随机分配端口映射到容器,按理说应该就映射到4579了

随机分配映射端口(更改后).png

随机映射并查看端口号

果不其然将主机的随机端口映射到了Dockerfile文件中设定的暴露端口4579,至于为什么又出现了80去查了资料解释是apache会默认地把服务配置到80端口,我也不是很了解

好了,拿到了32770端口就去浏览器验证一下

测试成功(更改后).png

测试成功

这么实践下来我好像搞懂了:EXPOSE中的端口并不是随意设定的,要将你容器里提供服务的端口暴露出来才是有意义的,而我之前EXPOSE由于随意设定和我容器中提供服务的端口(4579)不符,自然就啥服务都没提供了


(2)实现一个自定义的数据库容器服务

准备好需要的文件

mysql.png

准备的文件

这里需要的四个文件分别为一个setup脚本用于执行配置的内容并启动mysql,一个privileges.sql用于创建用户并赋予权限,一个schema.sql则是自己建的数据库与表,还有一个就是熟悉的Dockerfile了

四个文件内容如下

---------------------------------------------------------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

---------------------------------------------------------privileges.sql---------------------------------------------------------

use mysql;
select host, user from user;

-- 因为mysql版本是5.7,因此新建用户为如下命令:
create user yeqiyi identified by '777777';

-- 将docker_mysql数据库的权限授权给创建的qyanzh用户,密码为777777:
grant all on sqltest.* to yeqiyi@'%' identified by '777777' with grant option;

-- 这一条命令一定要有:
flush privileges;

---------------------------------------------------------schema.sql---------------------------------------------------------

-- 创建数据库
create database `sqltest` default character set utf8 collate utf8_general_ci;
use sqltest;

-- 建表
DROP TABLE IF EXISTS person;

CREATE TABLE person (
`name` varchar(255) NOT NULL,
`age`   int NOT NULL,
PRIMARY KEY (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- 插入数据
INSERT INTO person (`name`, `age`)
VALUES
('yeqiyi',22);

---------------------------------------------------------Dockefile---------------------------------------------------------

#基础镜像
FROM mysql:5.7

#维护者信息
MAINTAINER yuki820

#设置不允许空密码登陆,root密码为123456
ENV MYSQL_ALLOW_EMPTY_PASSWORD no
ENV MYSQL_ROOT_PASSWORD=123456789

#将所需文件覆盖到容器中
COPY setup.sh /mysql/setup.sh
COPY schema.sql /mysql/schema.sql
COPY privileges.sql /mysql/privileges.sql

#挂载数据卷
VOLUME ~/mysql-volume

#设置容器启动命令
CMD ["sh", "/mysql/setup.sh"]

创建镜像并开始测试

创建镜像的过程与前面大致相同就不再赘述了,这里就port一张创建成功的图片

创建镜像成功.png

镜像创建成功

启动容器也与之前相同就也略去了,这里端口不声明貌似也可以,下面这张则是容器启动日志

查看容器日志.png

容器日志

进入创建的容器:$ sudo docker exec -it [容器名] /bin/bash

登录root账户: mysql -u root -p

这里输入之前设定的密码(123456789)后就正式登录了

进入容器并登入root.png

登录成功

然后在登录自己创建的用户:mysql -u [用户名] -p

account: yeqiyi

password: 777777

登录自己创建的账号.png

登录成功

先进入我之前创建的数据库:use [数据库名];

查看数据库中的表:show tables;

可以看到我之前创建的person表就在其中

查看创建的表.png

查看所创建的表

接着在查询我之前所在表中插入的数据

输入查询语句:select * from person

可以看到表里的数据如下

查看建的表.png

person表中数据

到这里关于创建数据库容器服务的实践就结束了

总结

关于之前我对于端口问题的解释,可能也有我理解错的地方,如果有不当的地方还希望老师能解答一下。

原文地址:https://www.cnblogs.com/yeqiyi/p/12770850.html