耦合
是指两个或两个以上的体系或者两种运动形式间通过相互作用而批次影响以至联合起来的现象。
Nginx与apache 在同一台服务器运行都占用80端口,起冲突这是我们修改其中一个端口为8080
半解耦
同一个操作系统中两者共存各有各的特征 就是在同一个操作系统开启相同的程序
解耦
在当前服务器安装一个虚拟机在安装服务(类似于在自己电脑上安装的虚拟机)然后再把所需要的应用程序在装一边!
解耦解释图 半解耦解释图
Hard硬件 system操作系统 在硬件上安装完操作系统以后,
Hypervisor虚拟化(相当于虚拟机) 小格子并不直接产生操作系统
Guestos(相当于vmware装的操作系统) 而是把lib/bin文件直接软连接
在硬件上装一个操作系统 然后再放入app
然后安装虚拟机在装一个操作系统
在安装应用程序
Docker基础原理
Docker是一种容器,容器不是docker。
Docker是一种文件夹,欺骗应用程序:文件夹就是操作系统,然后把跟物理机重复或者冲突的内容以软连接的方式问道文件夹里去,然后再放进去应用程序!所以容器变得很小,因为它大部分的东西跟物理机共享!
docker是半解耦状态下的技术,在电脑当中可以让操作系统中的程序放在容器当中分裂出来两个且这两个程序不冲突!
docker缺点: 权限太大 资源抢占问题
如果让两个程序同时运行不能重复的东西:端口,pid(也就是进程号),还有/proxy
/proc:
伪文件系统,某一个程序往内存当中调取了哪些内容(比如启动httpd服务,
用netstat查看端口号下面有编号在proxy下 ls编号 下面的东西就是往内存调取的内容,
关闭服务就不会有这个东西)
也就是说一个程序往内存中调取了那些内容生成的文件就在proxy下。
Proc中有一个特殊的文件ns(在进程号里面)用ll查看 闪烁的代表六个“名称空间“,如果两个程序后面的数字相同,代表在一个匿名空间,就有可能发生冲突。
Namespace“名称空间“(把这六项隔离,隔离以后
UTS:主机及域名
IPC:信号量,消息列队及共享内存
Pid:进程编号
Network:网络设备,网络协议栈,端口等
Mount:挂载点,文件系统(四种挂载方式:私有挂载,主从挂载,shell型挂载,不可绑定挂载)
User:用户和组
实验:写一个fox让电脑当中能启动两个进程(编写脚本做一个子进程,就是相当于用脚本写一个容器,目的能启动两个一样的程序然后做隔离)
vi fork_example.c (别忘了进去A然后再粘贴)
#define _GNU_SOURCE
#include
#include
#include
#include
#include
#include
#define STACK_SIZE (1024 * 1024)
static char child_stack[STACK_SIZE];
char* const child_args[] = {
"/bin/bash",
NULL
};
int child_main(void* args) {
printf ("在子进程中!\n");
execv(child_args[0], child_args);
return 1;
}
int main() {
printf ("程序开始: \n");
int child_pid = clone(child_main, child_stack + STACK_SIZE, SIGCHLD, NULL);
waitpid(child_pid, NULL, 0);
printf ("已退出\n");
return 0;
}
ls查看是for存在这个文件
gcc -Wall fork_examp.c -o uts.o //就是把一串代码编译成应用程序
./uts.o 执行文件发现进入子进程
Ps 查看一下进程发现父进程有shell(bash)子进程也有
Exit 退出子进程
做UTS隔离
vi fork_example.c
./ust.o 你会发现主机名叫changebname,有两个主机名一个是locathost 一个是changename
Exit
IPC隔离(消息列队,程序之间通信要走消息列队)
vi fork_example.c
Ipcs -q 查询当前计算机列队
Ipcmk -Q 创建列队
创建几个列队然后查看
gcc -Wall fork_examp.c -o ipc.o
./ipc.o 进入子程序
Ipcs -q 查看发现没有列队
Exit 退出在ipcs -q 查询发现有列队 主进程与子进程隔离了 自己是自己的列队
PID隔离
vi fork_example.c
Ehco $$ 脚本运行当前进程号
./pid.o
Ehco$$
但是退出子程序以后查看proxy发现子程序里是1(bin/shell),而主程序里也有1(systemd)会发生混乱!
原因:程序要运行首先要把硬盘里的一部分东西拿出来放到内存里,让电脑随时随地调取,然后就会产生pid编号,pid编号和内存里的东西是对应的,放到一个文件夹里,文件夹放到了proxy目录下,然后在主程序与子程序之间做了一个隔离,发现这个子程序进程的id是1777(不同)但是进去以后再查看变成1,但是主程序已经有一个1(systemd)但是子程序的1变成了bin/shell(这样就会发生混乱,因为proxy目录不相同),因为子程序(容器)没有开机启动顺序没有开启第一个进程,容器不需要开机。
Mount的挂载方式(用命令):
四种挂载方式:
1、主从挂载(master影响slave,slave不影响master)
2、共享挂载(相互影响)
3、私密挂载(private 互不影响)
4、不可绑定的挂载 (unbindable)
第五种隔离网络隔离
ip netns add test_ns ——创建一个网络命名空间 test_ns
ip netns exec test_ns ip link list ——查看test_ns协议栈是否开启
ip netns exec test_ns ip link set dev lo up ——开启dev 下的lo 接口
ip netns exec test_ns ip link list ——查看test_ns协议栈是否开启
ip netns exec test_ns ping 127.0.0.1 ——ping本地回环地址
ip link add veth0 type veth peer name veth1 ——需要与外部相连是需要创建两个veth 创建veth0连接到对端的veth1
ip link set veth1 netns test_ns ——将veth1添加到网络命名空间 test_ns 里
ip netns exec test_ns ifconfig veth1 10.1.1.1/24 up ——给网络命名空间里的veth1配置一个ip并启用
ifconfig veth0 10.1.1.2/24 up ——将本地的veth0配置一个ip并启用
ping 10.1.1.1
Cgroup(并不是完整限制,而是优先级)
硬件资源限制(cpu用量,mem内存用量,disk硬盘用量)
Cgroup特征:
1\cgroup以伪文件系统进行管理
2\cgroup颗粒度线程级别
3\所有的资源管理都叫subsystem
4\子进程和父进程同属同一个cgroup
5\实现方式内核附加hooks
作用:
1、 资源限制
2、 优先级分配
3、 资源统计
4、 进程控制——挂起/恢复
术语:
Task:任务。表示系统的一个进程
Cgroup:控制组。按照某个资源控制标准划分组。包含一个或多个子系统。
Subsystem:资源调度器。具体的限制措施
Hierarchy: 层级树。放置多个cgroup
基本规则:
1、 同一个hierarchy可以附加一个或者多个subsystem
2、 一个已经附加在某个hierarchy上的subsystem不能附加到某个其他含有别的subsystem的hierarchy。
3、 一个task不能属于同一个hierarchy的不同cgroup,但能属于另外一个hierarchy的cgroup
4、 刚fork出的子进程在初始状态与其父进程处于同一个cgroup
Cgroup查看命令
Yum -y install libcgroup //cgroup的工具集
Lssubsys:查看计算机有哪些子系统
Lscgroup:查看当前系统有多少个cgroup
Lssubsys -m memory :查看子进程在哪里
Lussbsys查看出来的子系统解析
Cpuset:限制对cpu的使用
cpu,cpuacct:声称对cpu资源的使用情况报告
memory:内存的使用量限制
devices:对设备的访问(就是挂起的意思)
freezer:恢复/挂起
net_cls,net_prio:目前为止没有被使用
blkio:设备的输入输出限制,比如硬盘,USB等
perf_event:性能测试
hugetlb:目前为止没有被使用
pids:限制cgroup及其所有子孙cgroup里面能创建的总的task数量
linux核心技术
容器规范:OCI组织规定了两个标准
Runtime spec //runtime:容器运行的地方
Lxc 早 docker12——lxd管理工具
Runc docker 13 独享——docker engine 管理工具
Rkt coreOS——rkt cli 容器管理工具
Images format spec //镜像的标准格式
Docker images——制作镜像
Dockerfile——分层镜像
公共:hub.docker.com/daoclud.io或者hub.docker.com/quay.io
私有:本地仓库
三个容器操作系统:
Core.os
Atomic
Ubuntu core
编排引擎: 用来管理调度,集群,服务发现
Docker swarm
Kubernetes
Mesos
容器的网络:
容器间通信:host bridge
跨主机的容器间通讯: macvlan overlay flannel weave calic
服务发现:
Etcd
Consul
zookeeper
监控:
Sysdig
cadvisor/heapster //图形监控
weave scope //实时图形监控
docker架构:
docker client //客户端
docker daemon //服务端
image //镜像
registry //仓库
container //容器
docker run -d -p 80:80 httpd -d 后台运行 -p 本地端口映射到容器
base镜像:
1、 不依赖于其他的镜像,从scratch创建
2、 其他镜像可以以这个为扩展基础
制作镜像步骤:
1、 从base镜像运行一个容器
2、 执行一条命令对容器做修改
3、 执行打包操作。生成一个新的层
4、 Docker基于刚刚提交的镜像运行一个新容器
5、 重复2-3,直到dockerfile全部执行完成
Dockerfile的语法:
- FROM制定base镜像
- MAINTAINER作者。 后面接任意字符串
- Copy从本地复制文件到镜像内
COPY src dest
COPY[“src”,”dest”]
- ADD与COPY一样,但是如果src是压缩包,会被自动解压缩
- ENV 设置环境变量
ENV MY_VERSION 1.3
RUN yum install httpd-$My_VERSION
- EXPOSE 指定容器中的进程监听某个端口号
- VOLUME 声明储存(后面详细讲)
- WORKDIR 指定工作目录 (所有的命令都变为该目录下执行)
- RUN容器中运行某条shell命令
- CMD 启动容器后执行的命令,但是可被替换
- ENTRYPOINT 启动后运行的命令。