zoukankan      html  css  js  c++  java
  • 2020系统综合实践 第2次实践作业

    Dockerfile简介

    • Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
    • 基本结构:一般分为四部分,基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。
    • 基本命令:

    FROM:指定基础镜像,必须为第一个命令

    FROM <image>
    FROM <image>:<tag>
    

    MAINTAINER: 维护者信息

    MAINTAINER <name>
    

    RUN:构建镜像时执行的命令

    RUN <命令行命令>
    RUN ["可执行文件", "参数1", "参数2"]
    

    ADD:将本地文件添加到容器中,tar类型文件会自动解压(网络压缩资源不会被解压),可以访问网络资源,类似wget。
    ADD 的缺点:在不解压的前提下,无法复制 tar 压缩文件。

    ADD <src>... <dest>
    ADD ["<src>",... "<dest>"] 用于支持包含空格的路径
    

    COPY:功能类似ADD,但是不会自动解压文件,也不能访问网络资源

    COPY <src>... <dest>
    COPY ["<src>",... "<dest>"] 
    

    CMD:类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:

    • CMD 在docker run 时运行。
    • RUN 是在 docker build
    CMD ["executable","param1","param2"] (执行可执行文件,优先)
    CMD ["param1","param2"] (设置了ENTRYPOINT,则直接调用ENTRYPOINT添加参数)
    CMD command param1 param2 (执行shell内部命令)
    

    ENTRYPOINT:类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。但是, 如果运行 docker run 时使用了 --entrypoint 选项,此选项的参数可当作要运行的程序覆盖 ENTRYPOINT 指令指定的程序。如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。

    ENTRYPOINT ["executable", "param1", "param2"] (可执行文件, 优先)
    ENTRYPOINT command param1 param2 (shell内部命令)
    

    LABEL:用于为镜像添加元数据

    LABEL <key>=<value> <key>=<value> <key>=<value> ...
    

    ENV:设置环境变量

    ENV <key> <value>
    ENV <key1>=<value1> <key2>=<value2>...
    

    EXPOSE:指定于外界交互的端口

    EXPOSE <port1> [<port2>...]
    

    VOLUME:用于指定持久化目录

    VOLUME <path>
    VOLUME [<path1>,<path2>...]
    

    WORKDIR:工作目录,类似于cd命令

    WORKDIR <path>
    

    USER:用于指定执行后续命令的用户和用户组,这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在)。

    USER <user>[:<group>]
    

    ARG:构建参数,与 ENV 作用一至。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量。

    ARG <name>[=<default value>]
    

    ONBUILD:用于设置镜像触发器

    ONBUILD [INSTRUCTION]
    

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

    推荐apache或nginx,要求标明镜像作者信息,安装必要的工具以方便维护;设定你自己的web存放目录,安全起见,请将默认的监听端口80更改为你自定义的端口,并且声明暴露的端口,容器启动时,能直接进入web代码的存放目录。

    • 首先我们查看一下本地是否拥有nginx镜像
    sudo docker images
    

    • 接下来,我们要去获取一个nginx镜像,以供接下来使用。(国内镜像源速度直接起飞)
    sudo docker pull nginx
    

    • 这样子,我们就有了基础镜像nginx,之后用dockerfile自定义的镜像都是以这个镜像为基础。写dockerfile之前,需要把nginx的配置文件先写好,并和dockerfile放入同一文件夹下,我们先去运行一个nginx容器,找一下默认的配置,找的是default.conf,这个文件中含有配置默认目录的代码,把它复制出来。---配置文件位置以及修改默认目录方法
    sudo docker run --name nginx-test -p 8080:80 -d nginx
    sudo docker exec -it [容器id] /bin/bash
    cd /etc/nginx/conf.d
    cat default.conf
    

    • 这里直接把终端里显示的内容复制到本地主机一个新的文件中,命名为default.conf,端口号修改为4396,并把root修改为自己的目录。

    • 接下来再创建一个自己的html文件。

    • 这是我的dockerfile。(本来想写安装工具的指令,但是因为这个系统有很多指令无法使用,暂时不知道怎么安装)

    • 我们先把之前运行的容器停掉,然后开始创建自己的定制镜像,进入有Dockerfile的目录内打开终端。

    sudo docker build -t mynginx .
    

    • 运行一个容器查看效果。
    sudo docker run --name my_nginx -p 8080:4396 -d mynginx
    

    • 在浏览器查看8080端口,已经是之前我写入的html文件,成功。

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

    可选择Mysql,Mariadb等,要求标明镜像作者信息,为了方便维护,需要能够查看容器内的配置信息,包括但不限于网络、应用配置文件等。在环境变量中设置好数据库的root密码且不允许空密码登录,创建一个测试数据库,指定用户名和密码。

    • 数据库配置文件更复杂所以参考了网上的一篇博客---dockerfile运行mysql

    • 首先pull一个mysql镜像,5.7版本,和参考博客一致。

    sudo docker pull mysql:5.7
    

    • 之后我们需要创建四个文件分别是Dockerfile,setup.sh(启动脚本),schema.sql(创建数据库),privileges(权限)。(文件文末会给出)

    • Dockerfile中设置不允许空密码登录并且设置root用户的密码。

    • 接下来我们创建自己定制的镜像,在Dockerfile所在的文件夹中打开终端。

    sudo docker build -t mysql_hhn .
    

    • 再接着我们运行一个容器。
    sudo docker run --name msql -p 3306:3306 -d mysql_hhn
    

    查看日志信息。

    sudo docker logs msql
    

    • 进入这个容器。
    sudo docker exec -it msql /bin/bash
    

    • 进入数据库,再输入之前设定好的密码即可。
    mysql -u docker -p
    

    • 查看已经存在的数据库。
    show databases;
    

    • 进入数据库并且查看我们之前创建的表,这个表里我输入的是自己的信息。
    use docker_mysql
    select * from user;
    

    • 我在环境变量中配置了根节点的登陆密码,我们尝试用root用户去连接数据库,确认密码是否设置成功。
    exit
    mysql -u root -p
    

    • root用户的登录密码就是我们之前在dockerfile中预设的,并且root用户权限更大。

    • mysql的配置信息可用以下语句查看,由于信息很多,无法都截取下来,所以只截取一部分

    show variables;
    

    • 退出这个容器,并查看这个容器的信息,这里只截取一部分,mysql实验完成。
    sudo docker inspect msql
    

    问题&解决方法

    • Q:nginx不知道配置文件在哪里,也不知道该怎么去修改。
    • Q:mysql定制镜像创建成功后,用镜像去运行一个容器后,容器不能运行起来。
      • A:因为我参考的那篇博客mysql版本是5.7,我dockerfile最开始写的基础镜像是默认的最新版本,两个版本一些语句写法不一样,所以造成了这次错误,把dockerfile里改成5.7版本就可以。如果自己比较熟悉mysql也可以把数据库里的语句改成最新版本的。
    • Q:进入mysql后,输入查看等语句没有反应。
      • A:有些数据库语句后面有一个分号;,忘记了这个分号mysql会认为你没有输入完一条语句,所以不会执行(找了好长时间错误)。
    • 至今还存在一个没有解决的问题,以自定制nginx镜像运行的容器中,不知道该怎么去安装工具,我看到网上大多数是基于centos镜像,然后在centos上安装nginx,很少有基于nginx镜像的,我在自己的nginx尝试过使用安装指令但是失败了,网上也很难找到相关的信息。

    小结

    本次实验难度比上次大了很多,这是第一次接触dockerfile,自己也不熟悉nginx配置和mysql配置,花费了很多的时间,查资料加上自己去运行有大半天,但是出结果的时候还是有一些成就感的。本次实验还存有一些疑问,希望自己在今后的学习中能解决这些问题。另附上一张很有意思的图,生动地说明了dockerfile常用指令的含义。

    定制nginx的文件

    //Dockerfile
    #基础镜像
    FROM nginx
    
    #维护者信息
    MAINTAINER HHN
    
    #复制配置文件及自己的web存放目录
    COPY default.conf /etc/nginx/conf.d/
    COPY index.html /usr/south1999/
    
    #对外暴露端口号
    EXPOSE 8080
    
    
    #挂载目录
    VOLUME ~/nginx-volume
    
    
    //default.conf配置文件
    server {
        listen       4396;
        server_name  localhost;
    
        #charset koi8-r;
        #access_log  /var/log/nginx/host.access.log  main;
    
        location / {
            root   /usr/south1999/;
            index  index.html index.htm;
        }
    
        #error_page  404              /404.html;
    
        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }
    
        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ .php$ {
        #    proxy_pass   http://127.0.0.1;
        #}
    
        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ .php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}
    
        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /.ht {
        #    deny  all;
        #}
    
    }
    
    
    //index.html
    HHN's nginx!Succeed!^_^
    
    

    定制mysql的文件

    //Dockerfile
    #基础镜像
    FROM mysql:5.7
    
    #维护者信息
    MAINTAINER HHN
    
    #设置不允许空密码登陆,且设置root密码
    ENV MYSQL_ALLOW_EMPTY_PASSWORD no
    ENV MYSQL_ROOT_PASSWORD=south1999
    
    #将所需文件放到容器中
    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"]
    
    
    //privileges.sql给用户权限的语句文件
    use mysql;
    select host, user from user;
    -- 因为mysql版本是5.7,因此新建用户为如下命令:
    create user docker identified by '123456';
    -- 将docker_mysql数据库的权限授权给创建的docker用户,密码为123456:
    grant all on docker_mysql.* to docker@'%' identified by '123456' with grant option;
    -- 这一条命令一定要有:
    flush privileges;
    
    
    //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(20) NOT NULL,
      `name` varchar(40) DEFAULT NULL,
      `sex` varchar(10) DEFAULT NULL,
      `major` varchar(255) DEFAULT NULL,
      `username` varchar(255) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
    
    -- 插入数据
    INSERT INTO user (`id`, `name`, `sex`, `major`, `username`)
    VALUES
        ('111700312','Haonan Hu','male','computer science','south1999');
    
    
    //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
    
    
  • 相关阅读:
    MySql自定义函数-关于保留小数位的特殊需求
    MySQL-时区导致的时间前后端不一致
    [计算机基础] 汇编学习(3)
    [计算机基础] 汇编学习(2)
    [计算机基础] 汇编学习(1)
    [安全] metasploit(2)
    [安全] Kali Linux安装TheFatRat
    [安全] metasploit(1)
    [安全] tcpdump使用
    [安全] netcat和socat的使用
  • 原文地址:https://www.cnblogs.com/ambition-hhn/p/12726611.html
Copyright © 2011-2022 走看看