1️⃣本文章使用DockerFIile来搭建LNMP环境,和Docker监控。
dockerfile地址 :https://github.com/addcn/docker-lnmp
yum install git
git clone https://github.com/addcn/docker-lnmp.git
下载并构建镜像
cd docker-lnmp
docker build --tag wzj/mysql -f lnmp/mysql/Dockerfile .
docker build --tag wzj/php7 -f lnmp/php7/Dockerfile .
docker build --tag wzj/nginx -f lnmp/nginx/Dockerfile .
启动容器
docker run --name mysql -p 3306:3306 -v /data/mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -it wzj/mysql
docker run --name php7 -p 9000:9000 -v /var/www/html:/usr/local/nginx/html --link mysql:mysql -it wzj/php7
docker run --name nginx -p 80:80 -v /var/www/html:/usr/local/nginx/html --link php7:php7 -it wzj/nginx
docker ps -a 查看docker容器启动列表,可以看到启动的容器
监控参照这个教程即可 http://blog.csdn.net/liyingke112/article/details/74923178
docker run docker create
● -a stdin: 指定标准输入输出内容类型,可选 STDIN/STDOUT/STDERR 三项;
● -d: 后台运行容器,并返回容器ID;
● -i: 以交互模式运行容器,通常与 -t 同时使用;
● -t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用;
● –name=”nginx-lb”: 为容器指定一个名称;
● –dns-search example.com: 指定容器DNS搜索域名,默认和宿主一致;
● -h “mars”: 指定容器的hostname;
● -e username=”ritchie”: 设置环境变量;
● –env-file=[]: 从指定文件读入环境变量;
● –cpuset=”0-2” or –cpuset=”0,1,2”: 绑定容器到指定CPU运行;
● -m :设置容器使用内存最大值;
● –net=”bridge”: 指定容器的网络连接类型,支持 bridge/host/none/container: 四种类型;
● –link=[]: 添加链接到另一个容器;
● –expose=[]: 开放一个端口或一组端口;
● –expose=[]: 开放一个端口或一组端口;
docker exec与docker attach
一般使用docker exec~ docker attach 以后感觉要被淘汰。
查询docker 镜像中的信息
docker inspect [imageId]
在一台机器中,使用docker配置docker集群
安装 docker run -it --name redis-master redis /bin/bash
docker restart redis
docker inspect [reids continerId]
linux内核实现namespace的一个主要目的就是要实现轻量化虚拟服务
namespace的6项隔离,
UTS 主机名与域名
IPC 信号量、消息队列,和共享内存
PID 进程编号
NetWork 网络设备,网络栈,端口
Mount 挂载点
User 用户和用户组
namespace的Api包括,clone(),setns(),unshar()
clone() 是fork()的一种更通用实现方式,可以通过flags 来控制使用多少功能,
int clone(int(child_func)(void ), void *child_stach,int flags, void *arg );
child_func 传入子进程允许的程序主函数
child_stack 传入子进程使用的栈空间
flags 表示使用那些 CLON_* 标志位,与namespace相关的, CLONE_NETIPC、CLONE_NEWS、CLONE_NEWNET、CLONE_NEWPID、CLONE_NEWUSER、CLONE_NEWUTS
args用于传递用户参数
LIUNX内核从3.8开始,可以在 /proc/[pid]/ns 文件下看到不同namespace号的文件
如果两个进程指向的namespace编号相同,就说明他们在一个namespace下。docker中通过文件描述符定位和加入一个村庄的namespace是最基本的方法。
mount –bind /proc/27514/ns/uts ~/uts 也可以起到同样的作用~??
setns()加入已经存在的namespace
int setns(int fd ,int nstype)
fd 表示要加入namespace的文件描述符,是一个指向 /proc/[pid]/ns 目录的文件描述, nstype 让调用者可以检查fd指向的namespace是否符合实际要求。
execvp() 可以执行用户命令。 最常用的是调用 /bin/bash 并且接受参数
fd = open(argv[1], O_RDONLY);
setns($fd,0);
execvp(argv[2], &argv[2]) ;
假设编译完成后文件名为 setn-test
执行 ./setns-test ~/uts /bin/bash
unshare();
在原进程上线进行namespace隔离。不需要重新启动一个新的进程、
fork()创建新的进程,并且为其分配资源,并且将原代码中的值都复制到新的进程中。
IPC namespace 涉及的IPC资源包括,常见的信号,消息队列和共享内存
申请IPC的时候就申请了一个32为的ID,所以IPC namespace中实际包含了系统IPC标识符,以及实现POSIX消息队列文件系统。在同一个IPC下的进程彼此可见。
使用IPC namespace机制的系统不多,有名的有postgreSQL,Docker
PID namesapce
它对PID重新编号,寄两个不同namespace下的进程可以有相同的PID,每个PID namespace有自己独立的基数程序,内核为所有的PID namespace维护了一个树状结构,最低给您层是系统初始创建的,被称为 root namespace,所属的父节点可以看到子节点,并且可以通过信号产生影响,反过来。子节点却看不到父节点的任何内容
root namespace可以看到所有进程,并且递归包含所有子节点的进程
docker监控,就是监控docker daemon 所在的PID namespace下所有的进程及其子进程。
传统的Unix系统PID为1的进程为init,他作为所有进程的父进程。维护一张进程表,一旦某个子进程因为父进程出错,成为了孤儿进程。init会负责回收资源,结束进程。所以在要实现的容器汇总,启动的第一个进程也要实现类似inti的功能。维护所有后续进程的运行状态(如bash)。如果某个子进程成为孤儿进程,收养孩子的责任交给了该子进程对应的父进程。所属的PID namespace中的init进程。
信号与ini进程、
内核为PID namespace中的init进程赋予了其他特权。