1️⃣本文章使用DockerFIile来搭建LNMP环境,和Docker监控。

docker 在centos中安装

  1. 卸载老版本的 docker 及其相关依赖
    sudo yum remove docker docker-common container-selinux docker-selinux docker-engine
    ​ 2. 安装 yum-utils,它提供了 yum-config-manager,可用来管理yum源
    sudo yum install -y yum-utils
    ​ 3. 添加yum源
    sudo yum-config-manager –add-repo https://download.docker.com/linux/centos/docker-ce.repo
    ​ 4. 更新索引
    sudo yum makecache fast
    ​ 5. 安装 docker-ce
    sudo yum install docker-ce
    ​ 6. 启动 docker
    sudo systemctl start docker
    ​ 7. 验证是否安装成功
    sudo docker info

安装LNMP 环境

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容器启动列表,可以看到启动的容器

cAdvisor、InfluxDB、Grafana搭建Docker1.12性能监控平台

监控参照这个教程即可 http://blog.csdn.net/liyingke112/article/details/74923178

docker常用命令

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,所属的父节点可以看到子节点,并且可以通过信号产生影响,反过来。子节点却看不到父节点的任何内容

  1. 每一个PIDnamespace 都有第一个进程 PID 1
  2. 一个namespace 中,不可能通过kill 或ptrace影响兄弟节点的进程。因为其他节点的PID在这个namespace中没有任何意义
  3. 在新的PID namespace中重新挂载/proc 文件系统,会发现其下只显示同一个PID namespace 中的其他进程。
  4. root namespace可以看到所有进程,并且递归包含所有子节点的进程

    docker监控,就是监控docker daemon 所在的PID namespace下所有的进程及其子进程。

在容器中使用ps aux /top 命令发现还可以看到所有父进程的PID ,那是因为没有对文件系统挂载点进行隔离~ps top 调用的是真实系统下/proc 文件内容,看到的就是所有的进程。

传统的Unix系统PID为1的进程为init,他作为所有进程的父进程。维护一张进程表,一旦某个子进程因为父进程出错,成为了孤儿进程。init会负责回收资源,结束进程。所以在要实现的容器汇总,启动的第一个进程也要实现类似inti的功能。维护所有后续进程的运行状态(如bash)。如果某个子进程成为孤儿进程,收养孩子的责任交给了该子进程对应的父进程。所属的PID namespace中的init进程。

信号与ini进程、
内核为PID namespace中的init进程赋予了其他特权。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐