办法1:
1 |
cat /proc/self/mountinfo |
或
1 |
cat /proc/self/mounts |
或
1 |
cat /proc/self/cgroup |
办法1:
1 |
cat /proc/self/mountinfo |
或
1 |
cat /proc/self/mounts |
或
1 |
cat /proc/self/cgroup |
场景: 有个同学不知道因为啥,将容器内部的 /sys/fs/cgroup 挂载到了外面的某个目录; 但是这个目录是很有用的,不想随便被挂载,如何从image中去掉呢?
docker没有给出一个方便的方法, https://github.com/gdraheim/docker-copyedit 给了一个办法,原理如下:
每个image都是有一个manifest.json 文件的,相关配置信息都在这里了,但是你看不到image文件,更无从去谈修改manifest.json 文件了,所以:
1 |
docker save docker-registry.i.bbtfax.com/bee_centos7 -o /data1/centos7.tar |
1 |
tar xf /data1/centos7.tar -C /data1/centos7/ |
1 |
cd/data1/centos7/ ; tar cf ../centos7.modify.tar . |
1 2 3 |
# docker load -i centos7.modify.tar The image phpor.net/bee_centos7:latest already exists, renaming the old one with ID sha256:b14fe97b3bc959677c252e74e0ae318fa26028ac78d236a0973c3e235bf7a68b to empty string Loaded image: phpor.net/bee_centos7:latest |
我这里因为已经存在了同名的image,所以,旧的image的名字就被抢走了,但是ID没有变,新导入的image有自己新的ID
往常,我使用docker的network=none ,然后使用pipework给容器添加一个外部可访问的IP,然后,容器就能访问外网了;
后来,我在openstack上创建的centos7虚拟机上安装docker,同样的方式启动的容器却无法访问外网,首先,centos7虚拟机的网卡去掉任何安全组,并设置为非管理状态; 检查centos7的ip_forward 是打开的,最终,发现差别就在于,原来的iptables规则中 FORWARD 的策略是ACCEPT ,而现在是FORWARD 策略是 DROP的;
问题: iptables的 FORWARD 的DROP策略是在哪个环节设置的呢?
参考docker 源码发现如下逻辑:
基本逻辑为:
如果本来是开启着ip转发的,就不会去设置iptables 的forward链的默认策略了;
如果本来没有开启ip转发的,就会去设置iptables 的forward链的默认策略。
显然,曾经的机器在docker启动前就已经设置了ip转发了, 而后来的机器在docker启动前还设置ip转发,虽然最终是都设置了IP转发,但是结果却不同;如果直接让docker来管理容器的网络,则docker会按照要求自动添加forward规则,然而,现在我们用的是pipework,就需要自己添加forward规则了,势必会麻烦一些;流氓一些的做法就是直接修改FORWORD 的默认策略。
下面的dockerd占用了5G的内存+2.6G的swap,管理几个容器需要这么多的资源吗?一定是哪里有bug?
图中的java和mysql也都是不怎么使用的,所以占用很多的swap; 真正用的时候就会很慢。
1 2 |
# uname -a Linux VM-2-10-12 3.10.0-514.6.1.el7.x86_64 #1 SMP Wed Jan 18 13:06:36 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux |
1 2 |
# docker -v Docker version 1.12.5, build 047e51b/1.12.5 |
centos6.8
启动进程: /sbin/init (因为启动这个可以直接利用 init-scripts 配置自动启动的进程,比如: mysqld等)
docker stop $name
现象: 卡死了,进不去了
/sbin/init进程不退出,由init进程启动的子进程也处于defunct状态; 很可能是上级的某进程存在bug; 逐级上朔,找到shim进程,该进程kill 默认信号是不死的,看来可能有问题,直接kill -9 ; 然后,容器就干净地退出了
自从使用了docker容器,在容器中yum安装的软件就怎么着也man不了,man的时候就提示:
1 |
No manual entry for man |
通过rpm查看软件包中是否包含man文件,确实包含; 使用rpm -V 也检查不到rpm包损坏; 实际上,man文件是不存在的。
1 |
tsflags=nodocs |
注: 上述情况是把docker容器当虚拟机使用的,并不太在乎镜像的大小
https://github.com/docker/docker-ce-packaging/tree/master/rpm
安装并启动docker就行:
1 |
yum install docker-ce |
1 2 3 4 |
git clone https://github.com/docker/docker-ce-packaging.git cd docker-ce-packaging git clone https://github.com/docker/docker-ce.git make ENGINE_DIR=$(pwd)/docker-ce/components/engine CLI_DIR=$(pwd)/docker-ce/components/cli rpm |
从make命令说起,通过docker容器对engine cli分别进行打包,通过git获取版本号信息,通过docker-ce-packaging/rpm/Dockerfile.x86_64 构建一个基于centos:7 的容器镜像,镜像中安装编译环境(golang),容器挂载外部的一些目录,即,输入来自于外部目录,编译结果输出到外部目录;容器镜像直接启动rpmbuild命令进行构建,构建的详细步骤都在rpm的spec文件中,构建过程中还需要下载有些其他的源码
部分细节:
rpmbuild 命令:
1 2 |
cd /root/rpmbuild rpmbuild -ba --define '_gitcommit ef0da45' --define '_release 0.0.dev.git20180315.033056.0.ef0da45' --define '_version 0.0.0' --define '_origversion 0.0.0-dev' --define '_experimental 0' SPECS/docker-ce.spec |
容器挂载的外部目录:
1 |
-v /data3/docker-ce-packaging/rpm/rpmbuild/SOURCES:/root/rpmbuild/SOURCES -v /data3/docker-ce-packaging/rpm/rpmbuild/BUILD:/root/rpmbuild/BUILD -v /data3/docker-ce-packaging/rpm/rpmbuild/BUILDROOT:/root/rpmbuild/BUILDROOT -v /data3/docker-ce-packaging/rpm/rpmbuild/RPMS:/root/rpmbuild/RPMS -v /data3/docker-ce-packaging/rpm/rpmbuild/SRPMS:/root/rpmbuild/SRPMS -v /data3/docker-ce-packaging/rpm/systemd:/systemd |
问题记录:
当vsftpd在容器里面,而且容器IP又是host内部的私有IP的情况,client采用passive模式来下载数据能行得通吗? 可以的
把下面脚本当做容器的init进程:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
#!/bin/bash # kill all process except pid=1 export TZ=UTC-8 trap "quit; exit " 1 2 3 15 function log() { echo $(date +"%F %T") "$@" } function quit() { while :; do local pid_info=$(ps -axo pid,ppid,comm --no-headers|awk '$1 != 1 {print $0}') [[ $pid_info == "" ]] && break local succ=0 while read pid ppid comm; do if kill $pid &>/dev/null; then ((succ++)) log "$(printf '%-64s[%s]' "killing pid $pid(ppid: $ppid, comm: $comm)" succ)" else log "$(printf '%-64s[%s]' "killing pid $pid(ppid: $ppid, comm: $comm)" fail)" fi done < <(echo "$pid_info") [[ $succ == 0 ]] && break sleep 1 done } while read line; do log "$line" done |
知识点:
注意:
场景,用docker做开发用的虚拟机,每个docker都有一个可以公开访问的IP地址。
由于docker和宿主机共享内核,一不小心可能会把整个宿主机搞挂,而且,docker热迁移也是个难题,所以,尽管openstack马上可以支持docker,我也不想让docker直接部署在计算节点;我的思路是,将docker部署在openstack管理的kvm虚拟机上,这样还能通过热迁移kvm的方式将容器迁移到别的计算节点。
注意事项: