Docker学习之Dockerfile

首先介绍下dockerfile:Dockerfile是一份文本文档,描述了组装镜像的步骤,也就是说,只要把Dockerfile写好,然后build一下,我们的镜像就做好了。Dockerfile由指令构成,一个指令一行,build时,指令由上到下依次执行,一次执行一条,执行完后生成一个镜像层,然后下一条指令会在该基础上执行,从而产生新的镜像层。于是一层一层叠起来,我们的目标镜像就这样诞生了。

#comment
Instruction arguments

#号为注释符,有效行由两部分组成,一是指令名称,二是参数

常用指令:

  • FROM指令:Dockerfile的第一条指令,它指定了构建镜像的基础镜像
FROM
举例:FROM responsity-url/xxxx:1.2.18
  • MAINTAINER指令:指定镜像的作者
MAINTAINER
举例:MAINTAINER  clarkhu  clarkhu@qq.com
  • RUN指令:使用前一条指令创建的镜像生产容器,并在容器中执行命令,执行结束后会自动提交成为新的镜像。
    格式:RUN (shell格式 /bin/sh -c执行) 或者RUN[“executable”, “param1”, “param2”]
RUN
举例:RUN chmod +x /start
  • CMD指令:为容器提供运行的默认值,作为容器启动的默认第一条指令。在Dockerfile只能有一条,有多条的话,以最后一条为准
举例:CMD echo "Hello world"
  • EXPOSE指令:声明容器在运行时将会监听的特定端口,即对外暴露的端口。但是一般端口映射在docker run的时候用p参数指定
docker run -it -v /tmp/share:/tmp/share -p 8888:8888 --name="test" test/nginx:v3 /bin/bash
  • ENV指令:设置环境变量,作用于Dockerfile后续的所有指令。而且还会作用于生成镜像所创建出来的容器中。
举例:ENV name value
  • ADD指令:复制文件到镜像中,可以是文件,目录,甚至是url,可以是绝对路径,也可以是相对路径(相对于workdir)
举例:ADD xxxx yyy
  • COPY指令:复制文件到镜像中,和ADD的区别,COPY只能复制本地文件
举例:COPY Dockerstart  /start
  • ENTRYPOINT指令:为容器提供运行时的默认值,不同于cmd的是ENTRYPOINT只能传入指令,而CMD还可以传入参数
ENTRYPOINT ["executable", "param1", "param2"]
举例:ENTRYPOINT ["/start"]
  • WORKDIR指令:指定工作目录,设置相对路径,接下来该目录用于RUN, CMD, ENTRYPOINT, COPY和ADD指令
WORKDIR /data/www/

利用dockerfile构建镜像:

docker build -t xxx/yyy:zzz .

docker build 构建镜像的原理:以FROM指定镜像为基础。然后针对Dockerfile第一条有实际操作的指令,执行以下流程:将当前已构建的层合并起来作为镜像创建容器,执行操作,提交产生新的layer。当build完成时,我们就能得到很多layer,将它们堆叠起来,才是我们最终所产生的镜像。

  • 构建三步骤

1.编写dockerfile
2.docker build
3.docker run

  • Dockerfile指令总结
Dockerfile 过程解析
Dockerfile指令

linux curl 用法详解

最近在看elasticsearch相关文档,恶补下curl相关的知识,文章参考阮一峰的: http://www.ruanyifeng.com/blog/2019/09/curl-reference.html ,但是下面的命令自己都操作过,受益匪浅

curl 是常用的命令行工具,用于命令行发请求,curl 意为client url工具,类似curl的图形化界面工具有postman.

  • 最简单的用法,不带任何参数:get请求
curl http://www.baidu.com

                     

  • 指定客户端用户代理头,user-agent。curl的默认用户代理字符串是:curl/7.29.0,原始请求头可以通过 curl -v http://www.baidu.com查看,如果要指定客户端用户代理,可以用-A参
查看请求请求详情(Make the operation more talkative)
curl -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36" -v http://www.baidu.com

                              

  • -H参数,直接指定请求头,( I参数是只看http返回头,不看返回体)
curl -H "User-Agent:Opera/9.80" -Iv http://www.baidu.com

                        

  • -b参数用来向服务器发送Cookie
curl -b "name=clarkhu" -vI http://www.baidu.com
请求发送cookie
  • 如果发送两个cookie
curl -b "foo1=bar;foo2=bar2" http://www.baidu.com

             

  • -c参数将服务器设置的cookie写入一个文件,下列命令将服务器http回应所设置的cookie写入文本文件cookie.txt
curl -c cookie.txt http://www.baidu.com

  • -d参数用于发送POST请求的数据体
curl -d'login=clark&password=123'-X POST https://baidu.com/login

  • -e 设置http referer
curl -e 'https://google.com?q=example' https://www.example.com

                      

  • -G参数用来构造url查询字符串
curl -G -d 'q=a' -d 'count=30' http://www.baidu.com/search

上面命令会发出一个get请求,实际url为http://www.baidu.com/search?q=a&count=30。如果省略G, 会发出一个POST请求

  • I参数向服务器发出HEAD请求,会将服务器返回的HTTP头打印出来,I参数等同于–head
  • L参数会让HTTP请求跟随服务器的重定向。curl默认不跟随重定向。
  • –limit-rate 用来限制HTTP请求和回应的带宽,模拟慢网速的环境,下面命令将带宽限制在每秒200k字节
curl --limit-rate 200k http://www.baidu.com
  • -O 参数将服务器回应保存成文件,并将url的最后部分当作文件名。
curl -O http://www.baidu.com
  • -u参数,用来设置服务器认证的用户名和密码
curl -u 'bob:12345' http://www.baidu.com/login
  • -v参数转出通信的整个过程,用于调试
curl -v http://www.baidu.com
  • –trace 也用于调试,并且会输出原始的二进制数据
curl --trace - http://www.baidu.com
  • 如何构建一个curl请求呢,可以利用chrome
console-copy-copy as cURL(bash)

linux fstab文件详解

  • /etc/fstab是用来存放文件系统的静态信息文件,当系统启动时,系统会自动从这个文件读取信息,并且会自动将此文件中指定的文件系统挂载到指定的目录。

/etc/fstab 文件格式如下:

<file system> <dir> <type> <option> <dump> <pass>

tmpfs /tmp tmpfs nodev,nosuid 0 0
/dev/sda1 / ext4 defaults,noatime 0 1
/dev/sda2 none swap defaults 0 0
/dev/sda3 /home ext4 defaults,noatime 0 2

  • file system 要挂载的分区或存储设备
  • dir  file system的挂载位置
  • type 要挂载设备或分区的文件系统类型,支持不同的文件系统:ext2, ext3, ext4, xfs, jfs, smbfs, vfat, ntfs, swap或auto。设置成auto类型,mount 命令会猜测使用的文件系统。
  • option

   auto 在启动时键入了mount -a 命令时自动挂载
   noauto 只在你的命令下被挂载
   exec 允许执行此分区的二进制文件
ro 以只读模式挂载文件系统
   rw 以读写模式挂载文件系统
user 允许任意用户挂载此文件系统,若无显示定义,隐含启用noexec, nosuid, nodev参数
   usrs 允许所有users组中的用户挂载文件系统
nouser 只能被root挂载
owner 允许设备所有者挂载
sync I/O同步进行
async I/O异步进行
defaults 使用文件系统的默认挂载参数

  • dump dump工具通过它决定何时作备份,dump会检查其内容,并用数字来决定是否对这个文件系统进行备份。允许的数字是0和1。0表示忽略,1则进行备份。大部分的用户是没有安装dump的,所以应设置为0
  • pass fsck读取pass 的值来决定需要检查的文件系统的检查顺序。允许的数字为0,1,2。根目录应当获得最高的优先权1, 其它所有需要被检查的设备设置为2. 0表示设备不会被fsck所检查。

使用blkid 命令,其主要用于查找或打钱块设备属性,比如我们要查看/dev/vdb1的分区格式。
可以执行 blkid /dev/vdb1:

type=xfs

所以如果要挂载/dev/vdb1到/data
可以在/etc/fstab加上:
/dev/vdb1 /data xfs defaults 0 0

检测是否挂载成功:
df -h

操作示例:

#新增磁盘的设备文件名为 /dev/vdb 大小为100GB。
#fdisk -l  查看新增的的磁盘
#1、对新增磁盘进行分区

fdisk /dev/vdb

#按提示操作 p打印  n新增 d 删除 w操作生效 q退出
#操作后 w
#partprobe   强制让内核重新找一次分区表(更新分区表)
#这里我们新增一个分区 /dev/vdb1  大小为40GB 

#2、分区格式化

mkfs -t ext4 /dev/vdb1  格式化为ext4格式

#3、将新硬盘临时挂载在一个目录下

cd /mnt/
mkdir home
mount /dev/vdb1 /mnt/home  挂载到/mnt/home
#umount /dev/vdb1  如果需要卸载硬盘

df -h  #查看

#4、设置开机挂载

vi /etc/fstab

#末尾增加一行

/dev/vdb1  /home  ext4  defaults  0 0

#保存退出

php7 升级之mongodb扩展

mongo扩展(mongo.so)是一个比较老的扩展,主要用于php5, 建议php5.4之后,使用mongodb扩展,php7已经不支持mongo扩展。( https://www.php.net/manual/zh/mongo.installation.php )
下载地址: https://pecl.php.net/package/mongo
mongo使用说明: https://www.php.net/manual/zh/book.mongo.php

mongodb扩展mongodb.so是目前官方维护的版本,可以直接使用该驱动,但是官方建议和phplib一起使用,phplib封装了一个功能更全面的API.
下载地址: https://pecl.php.net/package/mongodb
PHPLIB地址: https://github.com/mongodb/mongo-php-library
使用方法: http://php.net/manual/en/set.mongodb.php

升级注意事项:

mongodb只有长连接

mongo扩展只有close()方法,为了避免出现长连接数过多,请求完调用close方法关闭连接,使用mongodb扩展后,默认使用长连接,且没有close方法,所以迁移时要评估改成长连接后的mongodb单台server的连接数,一般是单台php-fpm数量*机器数。

UTF-8编码兼容性问题

如果有非UTF-8编码的数据用mongo扩展可以读出来,用mongodb扩展读可能会抛异常(Detected corrupt BSON data), 这种一方面需要进行数据修复,另一方面需要堵住入口,避免出现此类问题。这种问题一般是在客户端发送的消息\、邮件里有特殊字符导致。
具体参考:https://github.com/mongodb/mongo-php-driver/pull/776

返回值差异

mongodb扩展isAcknowledged返回true不是代表成功,只是标识网络是OK的
mongodb里成功可以根据update,insert,remove具体操作对应的getModifiedCount, getInsertedCount, getDeletedCount等具体数量判断。
mongo update判断更新成功(生效)updatedExisting,但是mongodb 判断update是否成功建议用getMatchedCount,不能用getModifiedCount。举例,如果更新的内容并没有导致变化,updatedExisting返回1,getModifiedCount返回0,getMatchedCount返回1。

Nginx map使用

map 指令是由 ngx_http_map_module 模块提供的,默认情况下安装 nginx 都会安装该模块。

map 的主要作用是创建自定义变量,通过使用 nginx 的内置变量,去匹配某些特定规则,如果匹配成功则设置某个值给自定义变量。 而这个自定义变量又可以作于他用

下面举几个例子:

  • 场景一: 匹配请求 url 的参数,如果参数是 debug 则设置 $foo = 1 ,默认设置 $foo = 0
map $args $foo {
    default 0;
    debug   1;
}

解释:$args 是nginx内置变量,就是获取的请求 url 的参数。 如果 $args 匹配到 debug 那么 $foo 的值会被设为 1 ,如果 $args 一个都匹配不到 $foo 就是default 定义的值,在这里就是 0

语法:

map $var1 $var2 {...}

map指令的三个参数:

  • default : 指定源变量匹配不到任何表达式时将使用的默认值。当没有设置 default,将会用一个空的字符串作为默认的结果
  • hostnames : 允许用前缀或者后缀掩码指定域名作为源变量值。这个参数必须写在值映射列表的最前面
  • include : 包含一个或多个含有映射值的文件

在 Nginx 配置文件中的作用段: http{} ,注意 map 不能写在 server{} 否则会报错

  • map 的 $var1 为源变量,通常可以是 nginx 的内置变量,$var2 是自定义变量。 $var2 的值取决于 $var1 在对应表达式的匹配情况。 如果一个都匹配不到则 $var2 就是 default 对应的值
  • 一个正则表达式如果以 “~” 开头,表示这个正则表达式对大小写敏感。以 “~*”开头,表示这个正则表达式对大小写不敏感
map $http_user_agent $agent {
    default "";
    ~curl curl;
    ~*apachebench" ab;
}

  • 场景二:接下来看看实际用法,之前在给项目做php7升级,开发环境装了php5和php7,按项目来逐步升级php7,如何让某些项目使用php5,某些项目使用php7呢?
    upstream php56 {
        server 127.0.0.1:9000;
    }

    upstream php72 {
        server 127.0.0.1:9002;
    }

    map $uri $php_backend {
        default php56;
        ~^/project1/ php72;
        ~^/project2/ php72;
        ~^/project3/ php72;
        ~^/project4/ php72;
        ....
    }

    ....

    location ~ .*\.(php|php5)?$ {
        fastcgi_buffer_size 128k;
        fastcgi_buffers 4 256k;
        fastcgi_busy_buffers_size 256k;
        fastcgi_pass $php_backend;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
        fastcgi_param REQUEST_URI $new_request_uri;
        fastcgi_intercept_errors on;
    }

用以上的方式,根据链接特征设置了php_backend变量,从而使用不同的端口处理