supervisord多服务启动
如果需要一个容器中运行多个服务,可以使用Supervisord 来进行进程管理,方式就是将多个
启动命令放入到一个启动脚本中。
##需要准备的文件
[root@18 docker]# tree .
.
├── Dockerfile ##build时编译文件
├── dvd.repo ##主机yum源
├── ssh
│ └── Dockerfile
├── supervisord.conf
└── web
└── index.html
配置:
[root@18 docker]# cat Dockerfile
FROM rhel7
ENV HOSTNAME server2
EXPOSE 80 22
COPY dvd.repo /etc/yum.repos.d/dvd.repo
RUN rpmdb --rebuilddb && yum clean all && yum install -y httpd openssh-clients openssh-server supervisor && mkdir -p /var/log/supervisor && 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 ""
RUN echo root:westos | chpasswd
COPY supervisord.conf /etc/supervisord.conf
CMD ["/usr/bin/supervisord"]
[root@18 docker]# cat ssh/Dockerfile
FROM rhel7
ENV HOSTNAME server2
EXPOSE 22
COPY dvd.repo /etc/yum.repos.d/dvd.repo
RUN rpmdb --rebuilddb && yum install -y openssh-server && yum clean all
RUN echo root:westos | chpasswd
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -q -N ""
RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key -q -N ""
CMD ["/usr/sbin/sshd", "-D"]
[root@18 docker]# cat supervisord.conf
[supervisord]
nodaemon=true
[program:sshd]
command=/usr/sbin/sshd -D
[program:httpd]
command=/usr/sbin/httpd
[root@18 docker]# cat dvd.repo
[dvd]
name=rhel7.3
baseurl=http://172.25.254.250/rhel7.3
gpgcheck=0
[docker]
name=docker
baseurl=http://172.25.254.250/pub/docker/
gpgcheck=0
[root@18 docker]# cat web/index.html
<h1>Docker</h1>
1.编译
[root@18 docker]# docker build -t rhel7:v1 .
2.运行
[root@18 docker]# docker run -d --name vm1 -v /tmp/docker/web:/var/www/html rhel7:v1
3.测试
[root@18 ssh]# curl 172.17.0.2
<h1>Docker</h1>
[root@18 ~]# ssh -l root 172.17.0.2
root@172.17.0.2's password:
-bash-4.2#
CMD 与 ENTRYPOINT
ENTRYPOINT 容器启动后执行的命令,让容器执行表现的像一个可执行程序一样,与
CMD 的 区 别 是 不 可 以 被 docker run 覆 盖 , 会 把 docker run 后 面 的 参 数 当 作 传 递 给
ENTRYPOINT 指令的参数。Dockerfile 中只能指定一个 ENTRYPOINT,如果指定了很多,
只 有 最 后 一 个 有 效 。 docker run 命 令 的 -entrypoint 参 数 可 以 把 指 定 的 参 数 继 续 传 递 给
ENTRYPOINT。
首先测试下CMD的功能:
[root@18 test]# cat Dockerfile
FROM rhel7
CMD echo "hello world"
[root@18 test]# docker run --rm rhel7:v2
hello world
##验证CMD命令可被覆盖
[root@18 test]# docker run --rm rhel7:v2 echo westos
westos
##显然,使用ENTRYPOINT可以让操作不受到干预。
[root@18 test]# cat Dockerfile
FROM rhel7
ENTRYPOINT echo "hello world"
[root@18 test]# docker run --rm rhel7:v2 echo westos
hello world
CMD还可以作为ENTRYPOINT的参数
[root@18 test]# cat Dockerfile
FROM rhel7
ENTRYPOINT ["/bin/echo","hello"]
CMD ["westos"]
[root@18 test]# docker run --rm rhel7:v2
hello westos
利用CMD可被覆盖的特性,可以改变运行返回结果
[root@18 test]# docker run --rm rhel7:v2 vincent
hello vincent
另外,可以在ENV下声明参数进行传参
[root@18 test]# cat Dockerfile
FROM rhel7
ENV name vincent
ENTRYPOINT ["/bin/sh","-c","echo hey,$name !"]
[root@18 test]# docker run --rm rhel7:v2
hey,vincent !
[root@18 test]# cat Dockerfile
FROM rhel7
ENV name vincent
ENTRYPOINT echo "How you doing $name ?"
[root@18 test]# docker run --rm rhel7:v2
How you doing vincent ?
##过滤显示已退出进程
[root@18 ~]# docker ps -f status=exited
[root@18 ~]# docker rm `docker ps -aqf status=exited`
docker ps
-a, --all Show all containers (default shows just running)
-q, --quiet Only display numeric IDs
-f, --filter filter Filter output based on conditions provided
Docker 安全
有的时候我们需要容器具备更多的权限,比如操作内核模块,控制 swap 交换分区,挂载
USB 磁盘,修改 MAC 地址等
##很明显,在未授权的情况下,很多操作比如设置网卡改变ip等都不被允许
[root@18 test]# docker run -it --rm --name vm1 ubuntu
root@23ee09dd1869:/# ip link set down eth0
RTNETLINK answers: Operation not permitted
[root@18 test]# docker run -it --rm --name vm1 --privileged=True ubuntu
root@7ae6275eb18d:/# ip link set down eth0
root@7ae6275eb18d:/# ip addr | grep eth0
77: eth0@if78: <BROADCAST,MULTICAST> mtu 1500 qdisc noqueue state DOWN group default
–privileged=true 的权限非常大,接近于宿主机的权限,为了防止用户的滥用,需要增加限
制,只提供给容器必须的权限。此时 Docker 提供了权限白名单的机制,使用–cap-add 添加
必要的权限。
[root@18 docker]# docker run -it --cap-add=NET_ADMIN --name vm1 ubuntu
bashroot@6b0bb494612e:/# bash
[root@18 docker]# docker inspect -f {{.HostConfig.Privileged}} vm1
false
[root@18 docker]# docker inspect -f {{.HostConfig.CapAdd}} vm1
[NET_ADMIN]
Docker内存控制
Stress是一个压力测试工具,用来测试CPU、内存的使用。
[root@18 mnt]# docker load < stress.tar
[root@18 docker]# docker run --rm -it --name vm1 -m 100M --memory-swap 100M stress --vm 1 --vm-bytes 90M
[root@18 docker]# docker run --rm -it --name vm1 -m 100M --memory-swap 100M stress --vm 1 --vm-bytes 110M
##先查看下我的CPU信息:
[root@18 docker]# cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c
4 Intel(R) Core(TM) i5-2540M CPU @ 2.60GHz
[root@18 docker]# docker run --rm -it --cpu-shares 1024 stress -c 4
[root@18 test]# docker run --rm -it --cpu-shares 512 stress -c 4
使用top命令查看资源使用情况
~$ docker help run | grep -E 'bps|IO'
Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
--blkio-weight Block IO (relative weight), between 10 and 1000
--blkio-weight-device=[] Block IO weight (relative device weight)
--device-read-bps=[] Limit read rate (bytes per second) from a device
--device-read-iops=[] Limit read rate (IO per second) from a device
--device-write-bps=[] Limit write rate (bytes per second) to a device
--device-write-iops=[] Limit write rate (IO per second) to a device
..
限制docker写速度为100M
[root@18 test]# docker run --rm -it --device-write-bps /dev/sda:100M ubuntu
root@bbd3a519b66d:/# dd if=/dev/zero of=file111 bs=1M count=100 oflag=direct
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 1.07862 s, 97.2 MB/s
资源配额「cgroups」
cgroups 实现了对资源的配额和度量。 cgroups 的使用非常简单,提供类似文件的接口,在 /cgroup 目录下新建一个文件夹即可新建一个 group,在此文件夹中新建 task 文件,并将 pid 写入该文件,即可实现对该进程的资源控制。具体的资源配置选项可以在该文件夹中 新 建 子 subsystem , { 子 系 统 前 缀 }.{ 资 源 项 } 是 典 型 的 配 置 方 法 , 如memory.usageinbytes 就定义了该 group 在 subsystem memory 中的一个内存限制选项。
另外,cgroups 中的 subsystem 可以随意组合,一个 subsystem 可以在不同的 group 中,
也可以一个 group 包含多个 subsystem - 也就是说一个 subsystem。
[root@server1 jzx]# useradd jzx
[root@server1 jzx]# ls
memapp1 memapp2
[root@server1 jzx]# pwd
/home/jzx
[root@server1 jzx]# vim /etc/cgrules.conf
jzx:memapp1 memory x1/
jzx:memapp2 memory x1/
[root@server1 jzx]# yum install ld-linux.so.2 -y
[root@server1 jzx]# /etc/init.d/cgred restart
Stopping CGroup Rules Engine Daemon... [ OK ]
Starting CGroup Rules Engine Daemon: [ OK ]
[root@server1 jzx]# su - jzx
[jzx@server1 ~]$ ./memapp1
Process ID is: 14574
Grabbing 4096 pages of memory
Success!
Press any key to exit
[jzx@server1 ~]$ ./memapp2
Process ID is: 14575
Grabbing 8192 pages of memory
Killed
Docker仓库
Docker 官方已经把仓库封装为镜像,直接通过启动容器就可以部署完成仓库:
目录 /var/lib/registry 是仓库存放镜像的位置。除了使用数据卷做镜像存储之外,Registry
还支持将镜像存储到 亚马逊的 S3,OpenStack 的 Swift/Glance 等存储后端。
[root@18 pdf]# docker run -d --name registry -p 5000:5000 -v /opt/registry:/var/lib/registry registry:2.3.1
# docker tag nginx localhost:5000/nginx:latestDocker 镜像的命名规则 localhost:5000/nginx:latest 中,localhost:5000 表示 Registry 的地
址和端口。
# docker push localhost:5000/nginx:latest
推送镜像到 localhost:5000 仓库
# docker rmi localhost:5000/nginx:latest 删除本地 nginx 镜像的 TAG
# docker pull localhost:5000/nginx:latest 拉取镜像到本地
显示仓库信息
[root@18 ~]# docker images registry
REPOSITORY TAG IMAGE ID CREATED SIZE
registry 2.3.1 83139345d017 2 years ago 166 MB
registry latest bca04f698ba8 2 years ago 423 MB
默认 docker 仓库远程推送拉取需要 TLS 加密支持,走的是 https 协议,如需开启 http 方式,
需要做如下修改:
[root@18 docker]# mkdir certs.d
[root@18 docker]# cd certs.d/
[root@18 certs.d]# mkdir westos.org
[root@18 certs.d]# cd westos.org/
[root@18 westos.org]# cp /tmp/docker/certs/domain.crt .
[root@18 docker]# mkdir certs
[root@18 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) []:Shaanxi
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@18 docker]# docker run -d --restart=always --name registry -v `pwd`/certs:/certs -e REGISTRY_HTTP_ADDR=0.0.0.0:443 -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key -p 443:443 registry:2.3.1
348379a7cb566852c24273ff9c9c2611541b4f5377c4e34242fae59e00502369
[root@18 westos.org]# docker push westos.org/rhel7
The push refers to a repository [westos.org/rhel7]
18af9eb19b5f: Pushed
latest: digest: sha256:f1b19bc905965d1ff157c76b9ef6615c119aadad3cf4652bc881d3354ba3fdc4 size: 528
官方文档:
https://docs.docker.com/registry/configuration/#delete