supervisor整合容器服务 | CMD,RUN,ENTRYPOINT的区别 | DOCKER资源限制 | Cgroups资源限制 | docker仓库

DOCKER attach命令和DOCKERFILE的小结

docker run = docker create+start 创建并启动

[root@foundation28 ~]# docker history nginx  # 可以借此仿写dockerfile

IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT

c82521676580        3 weeks ago         /bin/sh -c #(nop)  CMD ["nginx" "-g" "daem...   0 B                

<missing>           3 weeks ago         /bin/sh -c #(nop)  STOPSIGNAL [SIGTERM]         0 B                

<missing>           3 weeks ago         /bin/sh -c #(nop)  EXPOSE 80/tcp                0 B                

<missing>           3 weeks ago         /bin/sh -c ln -sf /dev/stdout /var/log/ngi...   0 B                

<missing>           3 weeks ago         /bin/sh -c set -x  && apt-get update  && a...   53.7 MB            

<missing>           3 weeks ago         /bin/sh -c #(nop)  ENV NJS_VERSION=1.15.2....   0 B                

<missing>           3 weeks ago         /bin/sh -c #(nop)  ENV NGINX_VERSION=1.15....   0 B                

<missing>           4 weeks ago         /bin/sh -c #(nop)  LABEL maintainer=NGINX ...   0 B                

<missing>           5 weeks ago         /bin/sh -c #(nop)  CMD ["bash"]                 0 B                

<missing>           5 weeks ago         /bin/sh -c #(nop) ADD file:919939fa0224727...   55.3 MB        

[root@foundation28 ~]# docker ps -a

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS               NAMES

7e993b54ef4b        rhel7:v2            "/usr/sbin/sshd -D"      39 hours ago        Exited (0) 39 hours ago                         vm4

a4b9afd4c2a0        rhel7               "bash"                   39 hours ago        Exited (137) 39 hours ago                       vm3

04d52b9c8778        rhel7:v1            "/usr/sbin/httpd -..."   39 hours ago        Exited (0) 39 hours ago                         vm2

a43ff01edde9        rhel7               "bash"                   40 hours ago        Exited (137) 39 hours ago                       vm1

[root@foundation28 ~]# docker rm -f `docker ps -aq`

7e993b54ef4b

a4b9afd4c2a0

04d52b9c8778

a43ff01edde9

[root@foundation28 ~]# docker ps -a

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

[root@foundation28 ~]# docker run -d --name vm1 nginx

7ad3f122d922b052f8e948a9e320156b5288abfafbd85f546f05b916ccb89b46

[root@foundation28 ~]# docker ps -a

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES

7ad3f122d922        nginx               "nginx -g 'daemon ..."   4 seconds ago       Up 3 seconds        80/tcp              vm1

[root@foundation28 ~]# curl 172.17.0.2  直接访问

 

连接vm1

[root@foundation28 ~]# docker container attach vm1 这样是连接不了,因为nginx默认CMD没有bash,并且结束时会stop这个容器,再次启动需要docker start vm1

[root@foundation28 ~]# docker run -it --name vm2 nginx bash  #利用bash连接

root@63951ed504bc:/# ls

bin   dev  home  lib64     mnt  proc  run    srv  tmp  var

boot  etc  lib media   opt  root  sbin  sys  usr

此时ctrl+pq打入后台,docker container attach vm2就可以连接了

注意:这种服务类的docker连接上去没有什么意义

[root@foundation28 ~]# docker container exec  -it  vm1 bash也可以连接

 

nginx的官方Dockerfile

https://hub.docker.com/_/nginx/

https://github.com/nginxinc/docker-nginx/blob/ddbbbdf9c410d105f82aa1b4dbf05c0021c84fd6/mainline/stretch/Dockerfile

这里面的层次和docker history nginx看到的一致

[root@foundation28 ~]# docker run -d nginx 如果不用--name指定名字,那么就随机

2ba11ad261b4ed7f7e0ff213c38b8c32197fb323b4a39f487f99bae201a41e56

[root@foundation28 ~]# docker ps -a

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS               NAMES

2ba11ad261b4        nginx               "nginx -g 'daemon ..."   4 seconds ago       Up 4 seconds               80/tcp              goofy_ride

删除,查看时用CONTAINER ID和NAMES都可以,ID不需要敲全,最少可以区分当前列表下的字符就行

docker

[root@foundation28 ~]# docker inspect 2  直接显示goofy_ride的信息

 

 

supervisor:sshd-nginx整合连动

CMD 如果只有一个命令,那如果我们需要运行多个服务的办法是分别在不同的容器中运行,通过 link进行连接,比如先前实验中用到的 ssh,nginx容器。如果一定要在一个容器中运行多个服务可以考虑用 Supervisord 来进行进程管理,方式就是将多个启动命令放入到一个启动脚本中。

1,修改之前的Dockerfile,去掉没必要的层,这样可以减小构建的镜像的大小

2,安装supervisor需要软件和依赖,修改yum源文件,这些都在[docker]下,此文件需要在dockerfile里面写到COPY下,docker的构建下载yum就是dvd.yum,这里用了共享yum源,虽然docker的ip和yum源ip不在同一个网段,但是建立实例时默认做了nat,只要物理机可以连通,docker就可以

[root@foundation28 ~]# cat /etc/yum.repos.d/rhel7.3.repo

[rhel7.3]

name="Remote classroom copy of dvd"

baseurl=http://172.25.254.28/rhel7.3

gpgcheck=0

添加[docker]

[docker]

name=docker

baseurl=http://172.25.254.250/pub/docker

gpgcheck=0

3,建立supervisord.conf 文件,用来整合服务,需要写入Dockerfiel

[root@foundation28 docker]# cat supervisord.conf

[supervisord]

nodaemon=true

[program:sshd]

command=/usr/sbin/sshd -D

[program:httpd]

command=/usr/sbin/httpd

# 如果有多个服务需要启动可以在文件后继续添加[program:xxx]

4,将sshd和nginx的Dockerfile整合

[root@foundation28 docker]# cat Dockerfile

FROM rhel7 

EXPOSE 80 22  # 暴露端口

COPY dvd.repo /etc/yum.repos.d/dvd.repo

RUN rpmdb --rebuilddb && yum install -y httpd openssh-server openssh-clients supervisor  && yum clean all && ssh-keygen -q -t rsa -f /etc/ssh/ssh_host_rsa_key -N "" && ssh-keygen -q -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N "" && ssh-keygen -q -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N "" && echo root:redhat | chpasswd      # sshd和httpd需要安装的软件和部分配置,最好先在容器里测试RUN

COPY supervisord.conf /etc/supervisord.conf  #docker建立supervisord的配置文件,必须要COPY到docker,存在物理机是无效的

CMD ["/usr/bin/supervisord"]

5,构建镜像

[root@foundation28 docker]# docker build -t rhel7:v1 .

6,建立docker测试

[root@foundation28 docker]# docker run -d --name vm1 -v /tmp/docker/web/:/var/www/html rhel7:v1  #-v 挂载物理机的/tmp/docker/web到vm1的/var/www/html下

0f89f179bb249e4768f2bb282d1ebe5f264cf8e38b41461e23dbb0a99d74481b

[root@foundation28 docker]# cd web/

[root@foundation28 web]# ls

index.html

[root@foundation28 web]# cat index.html

<h1>www.westos.html</h1>

<h1>www.westos.html</h1>

<h1>www.westos.html</h1>

<h1>www.westos.html</h1>

[root@foundation28 docker]# docker ps

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES

0f89f179bb24        rhel7:v1            "/usr/bin/supervisord"   15 seconds ago      Up 14 seconds       22/tcp, 80/tcp      vm1

查看ip

[root@foundation28 docker]# docker inspect vm1 | grep IPAddress

            "SecondaryIPAddresses": null,

            "IPAddress": "172.17.0.2",

                    "IPAddress": "172.17.0.2",

[root@foundation28 docker]# curl 172.17.0.2

<h1>www.westos.html</h1>

<h1>www.westos.html</h1>

<h1>www.westos.html</h1>

<h1>www.westos.html</h1>

[root@foundation28 docker]# ssh 172.17.0.2

The authenticity of host '172.17.0.2 (172.17.0.2)' can't be established.

ECDSA key fingerprint is 2c:fb:2f:06:4c:23:7a:12:a1:ed:03:db:67:4c:cc:7d.

Are you sure you want to continue connecting (yes/no)? yes

Warning: Permanently added '172.17.0.2' (ECDSA) to the list of known hosts.

root@172.17.0.2's password:

-bash-4.2# ls

anaconda-ks.cfg

成功!!!

 

CMD,RUN,ENTRYPOINT

shell形式不需要[]    echo hello

exec形式需要[]      [“/bin/echo”,”hello”]

1,CMD命令可以被覆盖

[root@foundation28 ~]# cd /tmp/docker/

[root@foundation28 docker]# ls

Dockerfile  dvd.repo  ssh  supervisord.conf  web

[root@foundation28 docker]# mkdir test

[root@foundation28 docker]# cd test/

[root@foundation28 test]# ls

[root@foundation28 test]# vim Dockerfile

[root@foundation28 test]# cat Dockerfile

FROM rhel7

CMD echo "hello world!"   # 直接输出hello world

[root@foundation28 test]# docker build -t rhel7:v4 .

[root@foundation28 test]# docker run --rm rhel7:v4

hello world!

[root@foundation28 test]# docker run --rm rhel7:v4 westos  # westos不是命令

container_linux.go:247: starting container process caused "exec: \"westos\": executable file not found in $PATH"

docker: Error response from daemon: oci runtime error: container_linux.go:247: starting container process caused "exec: \"westos\": executable file not found in $PATH".

[root@foundation28 test]# docker run --rm rhel7:v4 echo westos  #hello world被覆盖

--rm                   Automatically remove the container when it exits

westos

[root@foundation28 test]# docker history rhel7:v4

IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT

699a3d6bb89e        2 minutes ago       /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "ec...   0 B                

0a3eb3fde7fd        4 years ago                                                         140 MB              Imported from -

这里的覆盖是指不执行dockerfile里面的CMD,而是执行接在后面的echo westos,连接nginx内部时我们使用bash就是这个原理

2,ENTRYPOINT不会被覆盖

[root@foundation28 test]# docker rmi rhel7:v4

[root@foundation28 test]# vim Dockerfile

[root@foundation28 test]# cat Dockerfile

FROM rhel7

ENTRYPOINT echo "hello world!"  # 修改为ENTRYPOINT

[root@foundation28 test]# docker build -t rhel7:v4 .

[root@foundation28 test]# docker run --rm rhel7:v4

--rm                  Automatically remove the container when

hello world!

[root@foundation28 test]# docker run --rm rhel7:v4 westos

hello world!

[root@foundation28 test]# docker run --rm rhel7:v4 echo westos  # 这里不会执行echo westos,没有覆盖

hello world!

3,ENTRYPOINT不会被覆盖,CMD会被覆盖

[root@foundation28 test]# docker rmi rhel7:v4

[root@foundation28 test]# vim Dockerfile

[root@foundation28 test]# cat Dockerfile

FROM rhel7

ENTRYPOINT ["/bin/echo","hello"]

CMD ["world"]

[root@foundation28 test]# docker build -t rhel7:v4 .

[root@foundation28 test]# docker run --rm rhel7:v4

hello world

[root@foundation28 test]# docker run --rm rhel7:v4 westos  #world被westos覆盖

hello westos

4,ENV变量   shell形式

[root@foundation28 test]# docker rmi rhel7:v4

[root@foundation28 test]# vim Dockerfile

[root@foundation28 test]# cat Dockerfile

FROM rhel7

ENV name westos

ENTRYPOINT echo "hello $name"

[root@foundation28 test]# docker build -t rhel7:v4 .

[root@foundation28 test]# docker run --rm rhel7:v4   # 打印变量

hello westos

5,ENV变量 exec形式

[root@foundation28 test]# docker rmi rhel7:v4

[root@foundation28 test]# vim Dockerfile

[root@foundation28 test]# cat Dockerfile

FROM rhel7

ENV name westos

ENTRYPOINT ["/bin/sh","-c","echo $name"]    #-c 命令从-c后的字符串读取。

[root@foundation28 test]# docker build -t rhel7:v4 .

[root@foundation28 test]# docker run --rm rhel7:v4   # 打印变量

westos

注意:RUN 一般用来装软件包,CMD只能写一次,ENTRYPOINT一般执行不可缺少的命令

 

Docker 是一个开源的应用容器引擎,主要利用 linux 内核 namespace 实现沙盒隔离,用

cgroup 实现资源限制

Dockerfile生成的镜像是只读的,分层是为了共享资源,图中的顶上两层,就是Docker为Docker容器新建的内容,而这两层恰恰不属于镜像范畴。这两层分别为Docker容器的初始层(Init Layer)与可读写层(Read-Write Layer),初始层中大多是初始化容器环境时,与容器相关的环境信息,如容器主机名,主机host信息以及域名服务文件等。再来看可读写层,这一层的作用非常大,Docker的镜像层以及顶上的两层加起来,Docker容器内的进程只对可读写层拥有写权限,其他层对进程而言都是只读的(Read-Only)。

Dockerfile中的每一条命令,都在Docker镜像中以一个独立镜像层的形式存在。

按照docker官网上的说法,docker的文件系统分为两层:bootfs和rootfs,bootfs包含了bootloader和linux内核。用户是不能对这层作任何修改的。在内核启动之后,bootfs实际上会unmount掉。

 

DOCKER参数资源限制

过滤死掉的容器ctrl+d结束的

[root@foundation28 test]# docker ps -f status=

created     dead        exited      paused      removing    restarting  running

[root@foundation28 test]# docker ps -f status=exited

docker rm `docker ps -aqf status=exited` 删除死掉的容器

一,权限

1,默认情况下root很多命令没有权力

[root@foundation28 test]# docker run -it --name vm1 ubuntu

root@87d79e57b045:/# ip addr

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1

    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

    inet 127.0.0.1/8 scope host lo

       valid_lft forever preferred_lft forever

    inet6 ::1/128 scope host

       valid_lft forever preferred_lft forever

48: eth0@if49: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default

    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff

    inet 172.17.0.2/16 scope global eth0

       valid_lft forever preferred_lft forever

    inet6 fe80::42:acff:fe11:2/64 scope link

       valid_lft forever preferred_lft forever

root@87d79e57b045:/# ip link set down eth0

RTNETLINK answers: Operation not permitted

2,--privileged=true赋予root所有权力

[root@foundation28 ~]# docker run -it --name vm2 --privileged=true ubuntu

root@027abbbfdc83:/# ip addr

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1

    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

    inet 127.0.0.1/8 scope host lo

       valid_lft forever preferred_lft forever

    inet6 ::1/128 scope host

       valid_lft forever preferred_lft forever

50: eth0@if51: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default

    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff

    inet 172.17.0.3/16 scope global eth0

       valid_lft forever preferred_lft forever

    inet6 fe80::42:acff:fe11:3/64 scope link

       valid_lft forever preferred_lft forever

root@027abbbfdc83:/# ip link set down eth0

root@027abbbfdc83:/# ip addr

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1

    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

    inet 127.0.0.1/8 scope host lo

       valid_lft forever preferred_lft forever

    inet6 ::1/128 scope host

       valid_lft forever preferred_lft forever

50: eth0@if51: <BROADCAST,MULTICAST> mtu 1500 qdisc noqueue state DOWN group default

    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff

    inet 172.17.0.3/16 scope global eth0

       valid_lft forever preferred_lft forever

root@027abbbfdc83:/# ip link set up eth0

root@027abbbfdc83:/# ip addr

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1

    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

    inet 127.0.0.1/8 scope host lo

       valid_lft forever preferred_lft forever

    inet6 ::1/128 scope host

       valid_lft forever preferred_lft forever

50: eth0@if51: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default

    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff

    inet 172.17.0.3/16 scope global eth0

       valid_lft forever preferred_lft forever

    inet6 fe80::42:acff:fe11:3/64 scope link

       valid_lft forever preferred_lft forever

二,内存

需要stress镜像做压力测试

https://hub.docker.com/r/progrium/stress/

1,限制swap+memory的大小

[root@foundation28 docker]# docker run --rm -it --name vm1 -m 100M --memory-swap 100M stress --vm 1 --vm-bytes 90M

正常运行

-m, --memory string                         Memory limit

内存大小限制

--memory-swap string                    Swap limit equal to memory plus swap: '-1' to enable unlimited swap

内存和交换空间的总大小限制

--vm n 产生n个进程,每个进程不断调用内存分配malloc和内存释放free函数

--vm-bytes B   malloc B bytes per vm worker (default is 256MB)

malloc的全称是memory allocation,中文叫动态内存分配,为每个worker动态内存分配

[root@foundation28 ~]# top    # 用top动态查看

2,限制swap+memory的大小,超过限定值压测

[root@foundation28 docker]# docker run --rm -it --name vm1 -m 100M --memory-swap 100M stress --vm 1 --vm-bytes 110M

运行失败

3,不限制swap,逐渐增大内存压力,查看swap最大空间

[root@foundation28 docker]# docker run --rm -it --name vm1 -m 100M stress --vm 1 --vm-bytes 150M

[root@foundation28 docker]# docker run --rm -it --name vm1 -m 100M stress --vm 1 --vm-bytes 190M

运行成功

[root@foundation28 docker]# docker run --rm -it --name vm1 -m 100M stress --vm 1 --vm-bytes 200M

运行失败

swap是memory的1.5-2倍,如果开始使用了swap,那么系统一定会开始慢起来,因为swap是磁盘,慢设备,Swap分区在系统的物理内存不够用的时候,把物理内存中的一部分空间释放出来,以供当前运行的程序使用。那些被释放的空间可能来自一些很长时间没有什么操作的程序,这些被释放的空间被临时保存到Swap分区中,等到那些程序要运行时,再从Swap分区中恢复保存的数据到内存中。

[root@foundation28 ~]# free -h -m  # m表示单位是M 1G=1024M

              total        used        free      shared  buff/cache   available

Mem:           7.7G        1.3G        253M        385M        6.1G        5.6G

Swap:          7.7G         25M        7.7G

三,CPU

[root@foundation28 ~]# docker run --rm -it --cpu-share 512 stress -c 1

-c,              spawn N workers spinning on sqrt()

-c 产生n个进程 每个进程都反复不停的计算随机数的平方根

--cpu-share              CPU shares (relative weight)

--cpu-shares 可以设置 CPU 利用率权重,默认为 1024,如果设置选项为 0,则系统会忽略该选项并且使用默认值 1024。通过以上设置,只会在 CPU 密集(繁忙)型运行进程时体现出来。当一个 container 空闲时,其它容器都是可以占用 CPU 的。cpu-shares 值为一个相对值,实际 CPU 利用率则取决于系统上运行容器的数量。

[root@foundation28 ~]# docker run  --rm -it --cpu-shares 1024 stress -c 1

[root@foundation28 ~]# docker run --rm -it --cpu-share 512 stress -c 4

[root@foundation28 ~]# docker run  --rm -it --cpu-shares 1024 stress -c 4

用top命令对比查看变化

四,限制写的速度

[root@foundation28 ~]# docker run --rm -it --device-write-bps /dev/sda:10M ubuntu

--device-write-bps throttled-device     Limit write rate (bytes per second) to a device (default [])

测试:

root@963f48c80d5f:/# dd if=/dev/zero of=file bs=1M count=100 oflag=direct

100+0 records in

100+0 records out

104857600 bytes (105 MB) copied, 9.95438 s, 10.5 MB/s   #速度控制在10M左右

注意:docker处于paused状态时,它的资源如ip,桥接状态等不会被释放,stop之后就释放了

dd命令参数oflag和iflag, 控制源文件和目标文件的读写方式为direct IO,即读或写文件时越过操作系统的读写缓存。如果指定oflag=direct,nonblock,写文件时忽略cache的影响;而如果指定iflag=direct,nonblock,读文件时忽略cache的影响

五,限制读的速度

[root@28 ~]# ll /dev/sda

brw-rw---- 1 root disk 8, 0 Aug 21 19:55 /dev/sda

docker和物理机共享设备资源

[root@28 ~]# docker run --rm -it --device-read-bps /dev/sda:1M --privileged=true ubuntu   # --privileged=true 赋予所有权限,默认情况root用户权限也受限制

测试

root@64b8762fa60d:/# dd if=/dev/sda of=file bs=1M count=10 oflag=direct

10+0 records in

10+0 records out

10485760 bytes (10 MB) copied, 9.9057 s, 1.1 MB/s

时间大概在10s左右,测试成功!!!

 

Cgroups资源限制

Cgroups是control groups的缩写,是Linux内核提供的一种可以限制、记录、隔离进程组(process groups)所使用的物理资源(如:cpu,memory,IO等等)的机制。最初由google的工程师提出,后来被整合进Linux内核。Cgroups也是LXC为实现虚拟化所使用的资源管理手段,可以说没有cgroups就没有LXC,Docker 使用 cgroups进行资源管理与限制,包括设备、内存、CPU、输入输出

LXC又名Linux container,是一种虚拟化的解决方案,这种是内核级的虚拟化,“lxc”是指linux内核(尤指命名空间以及Cgroup)的一个特性,它允许其他一些沙盒进程运行在一块相对独立的空间,并且能够方便的控制他们的资源调度。

runC是Docker按照开放容器格式标准(OCF, Open Container Format)制定的一种具体实现。runC是从Docker的libcontainer中迁移而来的,实现了容器启停、资源隔离等功能。Docker默认提供了docker-runc实现,事实上,通过containerd的封装,可以在Docker Daemon启动的时候指定runc的实现。runc直接与容器所依赖的cgroup/linux kernel等进行交互,负责为容器配置cgroup/namespace等启动容器所需的环境,创建启动容器的相关进程。

/dev/shm/是linux下一个非常有用的目录,因为这个目录不在硬盘上,而是在内存里。

/dev /shm/需要注意的一个是容量问题,在linux下,它默认最大为内存的一半大小,使用df -h命令可以看到。但它并不会真正的占用这块内存,如果/dev/shm/下没有任何文件,它占用的内存实际上就是0字节,默认的Linux发行版中的内核配置都会开启tmpfs,映射到了/dev/下的shm目录。既然是基于内存的文件系统,系统重启后/dev/shm下的文件就不存在了,可以通过ls /dev/shm查看下面是否有文件, 如果没有就说明当前系统并没有使用该设备.

 

安装启动cgroups

[root@server1 ~]# yum search cgroup

[root@server1 ~]# yum install -y libcgroup.x86_64

[root@server1 ~]# cd /cgroup/    # 安装成功才会有这个目录

[root@server1 cgroup]# ls   # 如果不启动服务,目录下为空

[root@server1 cgroup]# /etc/init.d/cgconfig start

Starting cgconfig service:                                 [  OK  ]

[root@server1 cgroup]# ls

blkio  cpu  cpuacct  cpuset  devices  freezer  memory  net_cls

一,限制内存

1,修改/etc/cgconfig.conf

[root@server1 cgroup]# cd memory/

[root@server1 memory]# ls

cgroup.event_control       memory.memsw.limit_in_bytes      memory.swappiness

cgroup.procs               memory.memsw.max_usage_in_bytes  memory.usage_in_bytes

memory.failcnt             memory.memsw.usage_in_bytes      memory.use_hierarchy

memory.force_empty         memory.move_charge_at_immigrate  notify_on_release

memory.limit_in_bytes      memory.oom_control               release_agent

memory.max_usage_in_bytes  memory.soft_limit_in_bytes       tasks

memory.memsw.failcnt       memory.stat

[root@server1 memory]# cat memory.limit_in_bytes

9223372036854775807   # 这里的意思是没有限制,我有多少内存,就给你多少

[root@server1 memory]# vim /etc/cgconfig.conf

group x1 {

        memory {

                memory.limit_in_bytes= 209715200;  #200M,单位是b

        }

}

2,重启服务,注意,不能占用当前目录,/etc/cgconfig.conf中说明了这些目录都是挂载点

[root@server1 memory]# cd

[root@server1 ~]# /etc/init.d/cgconfig restart

3,会在/cgroup/memory/生成一个x1目录

[root@server1 ~]# cd /cgroup/memory/

[root@server1 memory]# ls

cgroup.event_control       memory.memsw.limit_in_bytes      memory.swappiness

cgroup.procs               memory.memsw.max_usage_in_bytes  memory.usage_in_bytes

memory.failcnt             memory.memsw.usage_in_bytes      memory.use_hierarchy

memory.force_empty         memory.move_charge_at_immigrate  notify_on_release

memory.limit_in_bytes      memory.oom_control               release_agent

memory.max_usage_in_bytes  memory.soft_limit_in_bytes       tasks

memory.memsw.failcnt       memory.stat                      x1

[root@server1 memory]# cd x1

[root@server1 x1]# ls

cgroup.event_control       memory.memsw.limit_in_bytes      memory.swappiness

cgroup.procs               memory.memsw.max_usage_in_bytes  memory.usage_in_bytes

memory.failcnt             memory.memsw.usage_in_bytes      memory.use_hierarchy

memory.force_empty         memory.move_charge_at_immigrate  notify_on_release

memory.limit_in_bytes      memory.oom_control               tasks

memory.max_usage_in_bytes  memory.soft_limit_in_bytes

memory.memsw.failcnt       memory.stat

[root@server1 x1]# cat memory.limit_in_bytes

209715200

4,测试

[root@server1 shm]# free -m

             total       used       free     shared    buffers     cached

Mem:           996        416        579          0         13        271

-/+ buffers/cache:        131        865

Swap:          991        168        823

[root@server1 shm]# cgexec -g memory:x1 dd if=/dev/zero of=file1 bs=1M count=300   # 必须要用cgexec,否则内存限制不生效

[root@server1 shm]# free -m

             total       used       free     shared    buffers     cached

Mem:           996        216        779          0         13        140

-/+ buffers/cache:         63        933

Swap:          991          0        991

我们划分的内存是300M,但是只减少了200M,内存限制生效,还有100M实际上是swap分区给的

二,限制内存和swap

1,修改/etc/cgconfig.conf

group x1 {

        memory {

                memory.limit_in_bytes= 209715200;

                memory.memsw.limit_in_bytes= 209715200;

        }

}

2,重启服务,注意,不能占用当前目录

[root@server1 ~]# /etc/init.d/cgconfig restart

3,测试

[root@server1 ~]# free -m

             total       used       free     shared    buffers     cached

Mem:           996        216        779          0         13        140

-/+ buffers/cache:         63        933

Swap:          991          0        991

[root@server1 ~]# cgexec -g memory:x1 dd if=/dev/zero of=file1 bs=1M count=300300+0 records in

300+0 records out

314572800 bytes (315 MB) copied, 2.60735 s, 121 MB/s

[root@server1 ~]# free -m

             total       used       free     shared    buffers     cached

Mem:           996        423        573          0         13        338

-/+ buffers/cache:         70        925

Swap:          991          0        991

这里实际上总共只给了200M

[root@server1 ~]# rm -rf file1

[root@server1 ~]# cd /dev/shm/

[root@server1 ~]# cgexec -g memory:x1 dd if=/dev/zero of=file1 bs=1M count=300

Killed

4,应用:满足以下两个二进制文件的要求

[root@server1 ~]# chmod +x memapp*

[root@server1 ~]# ls

memapp1  memapp2

[root@server1 ~]# ./memapp1

-bash: ./memapp1: /lib/ld-linux.so.2: bad ELF interpreter: No such file or directory

[root@server1 ~]# yum install -y /lib/ld-linux.so.2[root@server1 ~]# ./memapp1

Process ID is: 1274

Grabbing 4096 pages of memory

Success!

Press any key to exit

[root@server1 ~]# ./memapp2

Process ID is: 1275

Grabbing 8192 pages of memory

Success!

Press any key to exit

解决方案:大于4096小于8192个内存页既可,一个内存页默认是4M

5000*4*1024b

修改配置文件,重启服务

group x1 {

        memory {

                memory.limit_in_bytes= 20480000;

                memory.memsw.limit_in_bytes= 20480000;

        }

}

[root@server1 ~]# /etc/init.d/cgconfig restart

创建用户,修改配置文件,启动服务

[root@server1 ~]# useradd redhat

[root@server1 ~]# vim /etc/cgrules.conf

# /etc/cgrules.conf

#The format of this file is described in cgrules.conf(5)

#manual page.

#

# Example:

#<user>         <controllers>  <destination>

#@student     cpu,memory   usergroup/student/

#peter            cpu         test1/

#%         memory         test2/

# End of file

redhat:memapp1    memory         x1/  

redhat:memapp2    memory         x1/

#rehad:memapp1是对redhat用户的memapp1特定程序做限定,x1是限定策略

[root@server1 ~]# mv memapp* /home/redhat/

[root@server1 ~]# /etc/init.d/cgred start

切换用户,执行文件

[root@server1 ~]# su - redhat

[redhat@server1 ~]$ ls

memapp1  memapp2

[redhat@server1 ~]$ ./memapp1

Process ID is: 1343

Grabbing 4096 pages of memory

Success!

Press any key to exit

[redhat@server1 ~]$ ./memapp2

Process ID is: 1344

Grabbing 8192 pages of memory

Killed

 成功!!!

三,限制CPU

1,修改配置文件,重启服务

[root@server1 cpu]# vim /etc/cgconfig.conf

group x2 {

        cpu {

                cpu.shares=100;

        }

}

[root@server1 cpu]# cd

[root@server1 ~]# /etc/init.d/cgconfig restart

Stopping cgconfig service:                                 [  OK  ]

Starting cgconfig service:                                 [  OK  ]

2,测试

[root@server1 ~]# cgexec -g cpu:x2 dd if=/dev/zero of=/dev/null &

[1] 1357

命令dd if=/dev/zero of=/dev/null永远执行不完,这两个都是无限的,只会消耗cpu资源

top对比这两个命令对cpu的使用量

[root@server1 ~]#  dd if=/dev/zero of=/dev/null &

[root@server1 ~]# killall dd

 

******************************************************************************************************************

[root@server1 ~]# cd /sys/devices/system/cpu/

[root@server1 cpu]# ls   # lscpu查看如果有两个cpu,那么这里有cpu0,cpu1

cpu0  cpufreq  cpuidle  kernel_max  offline  online  possible  present

[root@server1 cpu]# cd cpu0/

[root@server1 cpu0]# ls 

cache  crash_notes  node0  topology

# 如果有1个以上cpu,这里会有一个online,echo 0 > online,禁用该cpu,echo 1 > online,启用该cpu

*******************************************************************************************************************

四,限制磁盘

[root@server1 ~]# ll /dev/vda

brw-rw---- 1 root disk 252, 0 Aug 21 21:30 /dev/vda

252,0是磁盘编号

1,修改配置文件,重启服务

group x3 {

        blkio {

                blkio.throttle.read_bps_device= "252:0 1000000";   # 此磁盘读速1M/s,指定磁盘

        }

}

[root@server1 ~]# /etc/init.d/cgconfig restart

2,查看生效的文件

[root@server1 ~]# cd /cgroup/blkio/x3/

[root@server1 x3]# ls

blkio.io_merged         blkio.sectors                     blkio.time

blkio.io_queued         blkio.throttle.io_service_bytes   blkio.weight

blkio.io_service_bytes  blkio.throttle.io_serviced        blkio.weight_device

blkio.io_serviced       blkio.throttle.read_bps_device    cgroup.event_control

blkio.io_service_time   blkio.throttle.read_iops_device   cgroup.procs

blkio.io_wait_time      blkio.throttle.write_bps_device   notify_on_release

blkio.reset_stats       blkio.throttle.write_iops_device  tasks

[root@server1 x3]# cat blkio.throttle.read_bps_device

252:0      1000000

3,测试

[root@server1 ~]# cgexec -g blkio:x3 dd if=/dev/vda of=/dev/null & 

# /dev/vda是指定的设备

[root@server1 ~]# iotop  # 查看读磁盘的速度

五,更改状态

 

仓库

Docker 官方已经把仓库封装为镜像,直接通过启动容器就可以部署完成仓库,目录 /var/lib/registry 是仓库存放镜像的位置。除了使用数据卷做镜像存储之外,Registry

还支持将镜像存储到 亚马逊的 S3,OpenStack 的 Swift/Glance 等存储后端。

一,非加密

1,latest是最新版,或者最新稳定版,和版本号2.3.1是一样的

2,导入registry包,docker history registry 可以查看挂载目录在

VOLUME [/var/lib/registry]

[root@foundation28 pub]# mkdir /opt/registry

[root@foundation28 ~]# docker run -d -p 5000:5000 -v /opt/registry/:/var/lib/registry registry:2.3.1

# 端口映射,docker的端口是5000,把本机的/opt/registry/挂载到容器的/var/lib/registry

3,上传nginx

[root@foundation28 ~]# vim /etc/hosts

[root@foundation28 ~]# tail -n 1 /etc/hosts

172.25.254.28 westos.org

[root@foundation28 ~]# docker tag nginx westos.org:5000/nginx  # 非加密

[root@foundation28 ~]# docker images

REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE

nginx                   latest              c82521676580        3 weeks ago         109 MB

westos.org:5000/nginx   latest              c82521676580        3 weeks ago         109 MB

registry                latest              b2b03e9146e1        6 weeks ago         33.3 MB

[root@foundation28 ~]# docker push  westos.org:5000/nginx   # 这里必须要走加密,非加密上传失败,westos.org是解析后的域名,也可以写ip

The push refers to a repository [westos.org:5000/nginx]

Get https://westos.org:5000/v1/_ping: http: server gave HTTP response to HTTPS client

[root@foundation28 ~]# docker tag nginx localhost:5000/nginx   # 本机不存在加密与非加密

[root@foundation28 ~]# docker push localhost:5000/nginx

The push refers to a repository [localhost:5000/nginx]

08d25fa0442e: Pushed

a8c4aeeaa045: Pushed

cdb3f9544e4c: Pushed

latest: digest: sha256:2de9d5fc6585b3f330ff5f2c323d2a4006a49a476729bbc0910b695771526e3f size: 948

上传成功!!!

[root@foundation28 ~]# cd /opt/registry/

[root@foundation28 registry]# ls

docker

[root@foundation28 registry]# yum install tree -y

[root@foundation28 registry]# tree .  # 查看结构,不能拷贝到这里,这里上传的过程是有层次的

3,下载测试

此时下载要先删除之前的localhost:5000/nginx,westos.org:5000/nginx这两个都是对nginx的改名,删除只是去掉名字,否则不会下载

[root@foundation28 registry]# docker rmi westos.org:5000/nginx

Untagged: westos.org:5000/nginx:latest

[root@foundation28 registry]# docker rmi localhost:5000/nginx

Untagged: localhost:5000/nginx:latest

Untagged: localhost:5000/nginx@sha256:2de9d5fc6585b3f330ff5f2c323d2a4006a49a476729bbc0910b695771526e3f

删除nginx,直到没有nginx的镜像

[root@foundation28 registry]# docker rmi nginx

有delete才是删除原始镜像,untagged只是删除一个名字

下载

[root@foundation28 registry]# docker pull localhost:5000/nginx

Using default tag: latest

latest: Pulling from nginx

2da35ff30a7d: Pull complete

831fb1a65ced: Pull complete

7a63da4e8a19: Pull complete

Digest: sha256:2de9d5fc6585b3f330ff5f2c323d2a4006a49a476729bbc0910b695771526e3f

Status: Downloaded newer image for localhost:5000/nginx:latest

4,重命名

[root@foundation28 registry]# docker tag localhost:5000/nginx  nginx

5,删除pull的镜像

[root@foundation28 registry]# docker rmi localhost:5000/nginx

 

*************************************************************************************************************

如何远程走非加密的?这样没有什么意义,因为远程一定是https加密

[root@foundation28 registry]# vim /etc/docker/daemon.json

[root@foundation28 registry]# cat /etc/docker/daemon.json

{

  "registry-mirrors": ["https://u0nb22ie.mirror.aliyuncs.com"],

  "insecure-registries": ["westos.org:5000"]

}

[root@foundation28 registry]# systemctl daemon-reload

[root@foundation28 registry]# systemctl restart docker

*******************************************************************************************************************

 

二,加密

1,解析

[root@28 pub]# tail -n 1 /etc/hosts

172.25.254.28 westos.org

[root@28 tmp]# cd /tmp/docker/

2,获取证书和密钥

这里我们把本机当作容器仓库

[root@28 docker]# mkdir certs

[root@28 docker]# openssl req -newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key -x509 -days 365 -out certs/domain.crt

Generating a 4096 bit RSA private key

..............................................................................................++

...........................++

writing new private key to 'certs/domain.key'

-----

You are about to be asked to enter information that will be incorporated

into your certificate request.

What you are about to enter is what is called a Distinguished Name or a DN.

There are quite a few fields but you can leave some blank

For some fields there will be a default value,

If you enter '.', the field will be left blank.

-----

Country Name (2 letter code) [XX]:cn

State or Province Name (full name) []:shannxi

Locality Name (eg, city) [Default City]:xi'an

Organization Name (eg, company) [Default Company Ltd]:westos

Organizational Unit Name (eg, section) []:linux

Common Name (eg, your name or your server's hostname) []:westos.org

Email Address []:root@westos.org

[root@28 docker]# ls

certs

[root@28 docker]# cd certs/

[root@28 certs]# ls

domain.crt  domain.key

3,创建容器

[root@28 docker]# docker run  -d \

>  --restart=always \   #  如果容器关闭了,尝试自动重启

>  --name registry \

>  -v `pwd`/certs:/certs \   # 挂载点

>  -e REGISTRY_HTTP_ADDR=0.0.0.0:443 \   #https加密

>  -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \  #证书

>  -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \   # 密钥

>  -p 443:443 \   # 端口映射

>  registry:2.3.1  # registry版本

1205aadc80240916d68ac9c4c9396f3fd32af1d1b5028118bf796c8cbb5ba128

4,查看状态

[root@28 docker]# docker ps -a

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                            NAMES

b9255b83fc7a        registry:2.3.1      "/bin/registry /et..."   6 seconds ago       Up 3 seconds        0.0.0.0:443->443/tcp, 5000/tcp   registry

[root@28 docker]# ping westos.org

PING westos.org (172.25.254.28) 56(84) bytes of data.

64 bytes from westos.org (172.25.254.28): icmp_seq=1 ttl=64 time=0.029 ms

5,查看端口转换

[root@28 ~]# iptables -t nat -nL

DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:443 to:172.17.0.2:443

6,复制证书文件

[root@28 docker]# cd /opt/registry/

[root@28 registry]# rm -rf *

[root@28 ~]# cd /etc/docker/

[root@28 docker]# ls

certs.d  daemon.json  key.json

[root@28 docker]# cd certs.d/

[root@28 certs.d]# mkdir westos.org

[root@28 westos.org]# pwd

/etc/docker/certs.d/westos.org

[root@28 westos.org]# cp /tmp/docker/certs/domain.crt ca.crt

7,上传

[root@28 registry]# docker push westos.org/nginx

The push refers to a repository [westos.org/nginx]

08d25fa0442e: Pushed 

a8c4aeeaa045: Pushed 

cdb3f9544e4c: Pushed 

latest: digest: sha256:2de9d5fc6585b3f330ff5f2c323d2a4006a49a476729bbc0910b695771526e3f size: 948

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值