docker之cgroup、compose

cgroup的功能

docker使用cgroup控制资源,K8S里面也有limits
Docker通过Cgroup来控制容器使用的资源配额,包括CPU、内存、磁盘三大方面,基本覆盖了常见的资源配额和使用量控制。
Cgroup是Control Groups 的缩写,是Linux 内核提供的。种可以限制、记录、隔离进程组所使用的物理资源(如CPU、内存、磁盘Io等等)的机制

cpu在同一时刻只能给一个进程占用

cpu使用的限制

docker run -itd --cpu-shares 100 centos:stress
--cpu-shares  参数值不能保证可以获得1个vcpu或者多少GHZ的cpu资源,它仅是一个弹性的的加权值。
说明:默认情况下,每个Docker容器的CPU份额都是1024。单独一个容器的份额是没有意义的。只有在同时运行多个容器时,容器的 cPO加权的效果才能体现出来。

docker run -itd --name cpu512 --cpu-shares 512 centos:stress stress -c 10     #容器产生10个子函数进程

docker stats     查看资源使用

cpu周期的限制

docker提供了--cpu-period、--cpu-quota两个参数控制容器可以分配到的cpu时钟周期。
--cpu-period是用来指定容器对cpu的使用要在多长时间内做一次重新分配
--cpu-quota 是用来指定在这个周期内,最多可以有多少时间用来跑这个容器,与--cpu-shares不同的是,这种配置是指定一个绝对值,容器对cpu资源的使用绝对不会超过配置的值。

例如:容器进程需要每1秒使用单个CPU 的0.2 秒时间,可以将cpu-period 设置为1000000 (即1秒),cpu-quota 设置为200000 (0.2秒)。
当然,在多核情况下,如果允许容器进程完全占用两个CPU,则可以将cpu-period 设置为100000 (即0.1 秒),
cpu-quota设置为200000 (0.2 秒)。


docker run -itd --cpu-period 100000 --cpu-quota 200000 centos:stress 
 
cat /sys/fs/cgroup/cpu/cpu.cfs_period_us   #查看多长时间周期运行一次
cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us    #查看这个周期内运行多长时间
或者docker inspect 容器ID/容器名



**宿主机怎么提供资源、怎么控制docker容器中的应用的:**
CPU --->VCPU--> 以进程的方式体现在workstation环境(docker环境中) ---》 docker表现形式是容器-->Vcpu以进程的方式控制容器--》容器中的应用需要的是服务进程支持--》宿主机内核中cpu可以被cgroup管理(通过分配资源手段) --》linux 内核中的cgroup可以控制管理docker容器中的应用 



CPU Core控制

对多核CPU的服务器,Docker 还可以控制容器运行使用哪些CPU内核,即使用–cpuset-cpus参数。
这对具有多CPU的服务器尤其有用,可以对需要高性能计算的容器进行性能最优的配置。

docker run -itd --name cpu1 --cpuset-cpus 0-1 centos:stress
 
docker exec -it 容器id bash
cat /sys/fs/cgroup/cpuset/cpuset.cpus   #查看容器被哪个cpu核心使用

docker exec 容器ID taskset -c -p 1   #容器内部第一个进程号pid为1被绑定到指定cpu上运行


1、创建容器时,直接使用参数指定资源限制
2、创建容器时,指定资源分配。修改宿主机对应容器资源控制的文件 /sys/fs/cgrop/*

CPU配额控制参数的混合使用

通过cpuset-cpus参数指定容器A使用CPU内核0,容器B只是用CPU内核1。
在主机上只有这两个容器使用对应CPU内核的情况,它们各自占用全部的内核资源,cpu-shares没有明显效果。
cpuset-cpus、cpuset-mems参数只在多核、多内存节点上的服务器上有效,并且必须与实际的物理配置匹配,否则也无法达到资源控制的目的。
在系统具有多个cpu内核的情况下,需要通过cpuset-cpus参数为设置容器cpu内核才能方便的进行测试。

docker run -itd --name cpu3 --cpuset-cpus 1 --cpu-shares 512 centos:stress stress -c 1
#将会给系统一个随机负载,产生1个进程,这个进程都反复不停的计算由rand()产生随机数的平方根,知道耗尽资源

内存限制

与操作系统类似,容器可使用的内存包括两部分:物理内存和Swap

-m或–memory 设置内存的使用限额,例如100M、1024M
–memory-swap 设置内存+swap的使用限额

执行如下命令允许该容器最多使用200M的内存和300M的swap
docker run -it -m 200M --memory-swap=300M centos:stress --vm 1 --vm-bytes 280M 
--vm 1  启动1个内存工作线程
--vm-bytes 280M  每个线程分配280M内存
默认情况下,容器可以使用主机上所有空闲内存
与cpu的cgroups配置类似,Docker会自动为容器在目录/sys/fs/cgroup/memory/docker/容器完整的ID中创建响应cgroup配置文件
如果让工作线程分配的内存超过300M,分配的内存超过限额,stress线程报错,容器退出。

磁盘IO

默认情况下,所有容器能平等的读写磁盘,可以通过设置–blkio-weight参数来改变容器block IO的优先级。
–blkio-weight与–cpu-shares类似,设置的是相对权重值,默认为500.

在下面的例子中,容器A读写磁盘的带宽是容器B的两倍
docker run -it --name container_A --blkio-weight 600 centos:stress
docker run -it --name container_B --blkio-weight 300 centos:stress

cat /sys/fs/cgroup/blkio/blkio.weight

bps和iops的限制

bps是byte per second,每秒读写的数据量
iops是io per second,每秒IO的次数
可以通过以下参数控制容器的bps和iops

–device-read-bps,限制读某个设备的bps
–device-write-bps,限制写某个设备的bps
–device-read-iops,限制读某个设备的iops
–device-write-iops,限制写某个设备的iops

#下面示例是限制容器写/dev/sda的速率是5MB/s
docker run -it --device-write-bps /dev/sda:5MB centos:stress

dd if=/dev/zero of=test bs=1M count=10  oflag=direct  //可以按ctrl+c中断查看
通过dd命令测试在容器中写磁盘的速度。因为容器的文件系统是在host /dev/sda上的,在容器中写文件相当于对host /dev/sda进行写操作。另外,oflag=direct指定用direct IO 方式写文件,这样--device-write-bps才能生效

构建镜像时指定资源限制

–bulid-arg=[] 设置镜像创建时的变量
–cpu-shares 设置cpu使用权重
–cpu-period 限制cpu cfs周期
–cpu-quota 限制cpu cfs配额
–cpu-cpus 指定使用的cpu id
–cpu-mems 指定使用的内存id
–disable-content-trust 忽略校验,默认开启
-f 指定要使用的Dockerfile路径
–force-rm 设置镜像过程中删除中间容器
–isolation 使用容器隔离技术
–label=[] 设置镜像使用的元数据
-m 设置内存最大值
–memory-swap 设置swap的最大值为内存+swap,“-1”表示不限swap
–no-cache 创建镜像的过程不使用缓存
–pull 尝试去更新镜像的新版本
–quiet,-q 安静模式,成功后只输出镜像ID
–rm 设置镜像成功后删除中间容器
–shm-size 设置值/dev/shm的大小,默认值64M;
–ulimit
–squash 将Dockerfile中所有的操作压缩为一层
–tag,-t 镜像的名字及标签,通常name:tag或者name格式;可以在一次构建中为一个镜像设置多个标签
–network 默认default。在构建期间设置run指令的网络模式

资源限制的主要类型

1、cpu权重shares、quota、cpuset
2、磁盘BPS、TPS限制,指定使用哪个磁盘、磁盘分区
3、内存 -m -swap内存、交换分区
大部分做的是上限的限制

资源限制的几种方式

1、bulid构建镜像时,可以指定该镜像的资源限制
2、run将镜像跑为容器的时候,可以指定容器的资源限制。
3、容器启动之后,可以在宿主机对应容器的目录下,修改资源限制,然后重载/sys/fs/cgroup/*(cpu、blk、mem)/docker/容器ID -----》修改对应的资源限制文件参数就可以

资源限制的状态查询

1、docker inspect镜像ID/容器ID
2、直接查看宿主机的对应容器ID资源限制文件

dockers compose

docker compose的前身是fig,它是一个定义及运行多个docker容器的工具
使用docker compose不再需要使用shell脚本来启动容器
docker compose非常适合组合使用多个容器进行开发的场景

consul是hashicorp公司推出的开源工具,用于实现分布式系统的服务发现与配置

consul的特性

支持健康检查,允许存储键值对
基于Golong语言,可移植性强
支持ACL访问控制
与docker等轻量级容器可无缝配合

compose:批量构建容器
consul:运行时动态识别、添加新的容器

Docker Compose配置常用字段

字段 描述
build dockerfile context 指定dockerfile文件名构建镜像上下文路径
image 指定镜像
command 执行命令,覆盖默认命令
container name 指定容器名称,由于容器名称是唯一的,如果指定自定义名称,则无法scale
deploy 指定部署和运行服务相关配置,只能在Swarm模式使用
environment 添加环境变量
networks 加入网络
ports 暴露容器端口,与-p相同。但端口不能低于60
volumes 挂载宿主机路径或命令卷
restart 重启策略,默认no,always,no-failure,unless-stoped
hostname 容器主机名

Docker compose常用命令

字段 描述
build 重新构建服务
ps 列出容器
up 创建和启动容器
exec 在容器里面执行命令
scale 指定一个服务容器启动数量
top 显示容器进程
logs 查看容器输出
down 删除容器、网络、数据卷和镜像
stop/start/restart 停止/启动/重启服务

compose部署

192.168.198.128

[root@localhost ~]# curl -L https://github.com/docker/compose/releases/download/1.21.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   633  100   633    0     0    837      0 --:--:-- --:--:-- --:--:--   837
100 10.3M  100 10.3M    0     0  3338k      0  0:00:03  0:00:03 --:--:-- 5982k
//或者上传docker_compose即可

[root@server ~]# ls
anaconda-ks.cfg  docker-compose  initial-setup-ks.cfg
[root@server ~]# chmod +x docker-compose 	//加执行权限
[root@server ~]# cp -p docker-compose /usr/local/bin
[root@server ~]# mkdir /root/compose_nginx
[root@server ~]# cd compose_nginx/
[root@server compose_nginx]# mkdir nginx wwwroot
[root@docker compose_nginx]# cd nginx/	//上传nginx压缩包
[root@docker nginx]# ls
nginx-1.12.2.tar.gz
[root@docker nginx]# vim Dockerfile
FROM centos:7
ADD nginx-1.12.2.tar.gz /mnt 
WORKDIR /mnt/nginx-1.12.2
RUN yum install -y gcc pcre pcre-devel devel zlib-devel make &> /dev/null && \
 yum clean all && \
 sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && \
 ./configure --prefix=/usr/local/nginx &> /dev/null && \
 make &> /dev/null && make install &> /dev/null &&\
 rm -rf /mnt/nginx-1.12.2
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]


[root@docker nginx]# cd ../wwwroot/
[root@docker wwwroot]# vim index.html
this is dyf


[root@docker wwwroot]# vim /root/compose_nginx/docker-compose.yml
version: '3'
services:
  nginx:
    hostname: nginx
    build:
      context: ./nginx
      dockerfile: Dockerfile
    ports:
      - 1216:80
      - 1217:443
    networks:
      - cluster
    volumes:
      - ./wwwroot:/usr/local/nginx/html
networks:
  cluster:

[root@docker nginx]# docker-compose -f docker-compose.yml up -d	//基于yml文件运行启动
[root@docker compose_nginx]#  docker-compose ps	//使用Compose容器编排查询
        Name                     Command            State            Ports          
------------------------------------------------------------------------------------
compose_nginx_nginx_1   /usr/local/nginx/sbin/ngi   Up      0.0.0.0:1217->443/tcp,::
                        n ...                               :1217->443/tcp, 0.0.0.0:
                                                            1216->80/tcp,:::1216->80
                                                            /tcp

docker之cgroup、compose_第1张图片

docker之cgroup、compose_第2张图片

consul部署

设备:192.168.198.128(Docker-ce 、Consul、 Consul-template)
192.168.198.129(Docker-ce、registrator)
192.168.198.128

[root@docker ~]# mkdir consul
[root@docker ~]# cd consul/
[root@docker consul]# unzip consul_0.9.2_linux_amd64.zip 
Archive:  consul_0.9.2_linux_amd64.zip
  inflating: consul                  

mv consul /usr/bin
[root@docker consul]# consul agent \
> -server \
> -bootstrap \
> -ui \
> -data-dir=/var/lib/consuldata \
> -bind=192.168.198.128 \
> -client=0.0.0.0 \
> -node=consul-server01 &> /var/log/consul.log &
[1] 84084
[root@docker consul]# jobs
[1]+  运行中               consul agent -server -bootstrap -ui -data-dir=/var/lib/consul-data -bind=192.168.118.44 -client=0.0.0.0 -node=consul-server01 &>/var/log/consul.log &

##查看集群信息
[root@docker consul]# consul members
Node             Address              Status  Type    Build  Protocol  DC
consul-server01  192.168.198.128:8301  alive   server  0.9.2  2         dc1
[root@docker 
consul]# consul info | grep leader
	leader = true
	leader_addr = 192.168.198.128:8300

在192.168.198.129上安装 Gliderlabs/Registrator

root@docker nginx]# docker run -d \			## 安装 Gliderlabs/Registrator Gliderlabs/Registrator
> --name=registrator \
> --net=host \
> -v /var/run/docker.sock:/tmp/docker.sock \
> --restart=always \
> gliderlabs/registrator:latest \
> -ip=192.168.198.129 \
> consul://192.168.198.128:8500

##测试服务发现功能是否正常
[root@docker nginx]# docker run -itd -p:83:80 --name test-01 -h test01 nginx
[root@docker nginx]# docker run -itd -p:84:80 --name test-02 -h test02 nginx
[root@docker nginx]# docker run -itd -p:88:80 --name test-03 -h test03 httpd
[root@docker nginx]# docker run -itd -p:89:80 --name test-04 -h test04 httpd

docker之cgroup、compose_第3张图片

安装consul-template

192.168.198.128节点上安装配置

[root@docker consul]# vim /root/consul/nginx.ctmpl
upstream http_backend {
  {{range service "nginx"}}
   server {{.Address}}:{{.Port}};   #此处引用的变量会指向后端的地址和端口(动态变化)
   {{end}}
}

server {
  listen 83;
  server_name localhost 192.168.198.128;		#反向代理的IP地址(前端展示的NG服务的IP)
  access_log /var/log/nginx/whd.cn-access.log;
  index index.html index.php;
  location / {
    proxy_set_header HOST $host;
    proxy_set_header X-Real-IP $remote_addr;		#后端真实IP
    proxy_set_header Client-IP $remote_addr;	
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;	#转发地址
    proxy_pass http://http_backend;
  }
}

手工编译安装nginx

[root@docker consul]# yum install gcc pcre-devel zlib-devel -y
[root@docker consul]# tar zxvf nginx-1.12.2.tar.gz  -C /opt
[root@docker consul]# cd /opt/nginx-1.12.2/
[root@docker nginx-1.12.2]# ./configure --prefix=/usr/local/nginx
[root@docker nginx-1.12.2]# make && make install
[root@docker nginx-1.12.2]# vim /usr/local/nginx/conf/nginx.conf	##修改配置文件

docker之cgroup、compose_第4张图片

[root@docker nginx-1.12.2]# mkdir /usr/local/nginx/conf/vhost		#创建虚拟机目录
[root@docker nginx-1.12.2]# mkdir /var/log/nginx		##创建日志文件目录
[root@docker nginx-1.12.2]# /usr/local/nginx/sbin/nginx		##启动nginx
[root@docker nginx-1.12.2]# netstat -antp | grep nginx
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      28727/nginx: master 

配置并启动 template

[root@docker opt]# unzip consul-template_0.19.3_linux_amd64.zip		##上去consul-template包并解压
Archive:  consul-template_0.19.3_linux_amd64.zip
  inflating: consul-template         
[root@docker opt]# mv consul-template /usr/bin/

##关联nginx 虚拟目录中的子配置文件
[root@docker opt]# consul-template -consul-addr 192.168.198.128:8500 \
> -template "/root/consul/nginx.ctmpl:/usr/local/nginx/conf/vhost/dyf.conf:/usr/local/nginx/sbin/nginx -s reload" \
> --log-level=info

##再开另一个终端查看
[root@docker opt]#  cat /usr/local/nginx/conf/vhost/dyf.conf 
upstream http_backend {
  
   server 192.168.198.128:83;   
   
   server 192.168.198.129:84;   
   
}

server {
  listen 83;
  server_name localhost 192.168.198.128;		
  access_log /var/log/nginx/dyf.cn-access.log;
  index index.html index.php;
  location / {
    proxy_set_header HOST $host;
    proxy_set_header X-Real-IP $remote_addr;		
    proxy_set_header Client-IP $remote_addr;	
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;	
    proxy_pass http://http_backend;
  }
}

在192.168.198.129节点新建容器,确认注册到consul

[root@server docker]# docker run -itd -p:85:80 --name test-06 -h test06 nginx
dcc0eb9e689df6ef3128b4474627bbc85e4f8229f99c081888aa91425c3192c3

docker之cgroup、compose_第5张图片
查看文件内容是否有新的server添加

[root@docker ~]# cat /usr/local/nginx/conf/vhost/dyf.conf
upstream http_backend {
  
   server 192.168.198.129:83; 
   
   server 192.168.198.129:84; 
   
   server 192.168.198.129:85;      #新添加的
   
}

server {
  listen 83;
  server_name localhost 192.168.198.128;	
  access_log /var/log/nginx/dyf.cn-access.log;
  index index.html index.php;
  location / {
    proxy_set_header HOST $host;
    proxy_set_header X-Real-IP $remote_addr;		
    proxy_set_header Client-IP $remote_addr;	
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;	
    proxy_pass http://http_backend;
  }
}

你可能感兴趣的:(docker,运维)