1. 开始
1.1 认识
- Docker推荐单容器单进程的实现方式
1.2 系统命令
|
|
2. 容器
|
|
3. 镜像
3.1 常用命令
|
|
3.2 镜像构建
从容器提交镜像 (不推荐)
docker commit
从dockerfile生成镜像
docker build
通过dockerfile构建镜像。构建时有构建缓存,如果构建内容不变会直接使用缓存构建,大大加快构架速度。构建时如果出问题,可直接进入构建时创建的临时容器进行debug
|
|
3.3 Dockerfile
|
|
路径问题
注意 ADD/COPY 的源路径都是相对于Dockfile所在目录的路径,建议使用ADD/COPY之前将相关文件复制或移动到Dockfile目录下
Dockfile所在目录为/project/docker
ADD /etc/file …中/etc/file的意思是/project/docker/etc/file
4. 网络配置
网络模式
自建网络
驱动
bridge #网桥模式 默认模式。默认网桥无法自动发现,用户自建网络自动配有发现服务,内部容器可直接互联。
overlay #overlay网络模式
默认网络(为了向下兼容老的方式)
网络名
none
host
bridge #docker run 如果不指定net的话,会将容器加入到默认bridge网络中
命令
|
|
网络别名
docker run —net mynet —network-alias a1 ubuntu
这样容器间不需要关心各自具体ip,网络互连只需要知道别名即可。举个例子,假如容器重启,ip进行了重新分配,容器间也可以正常互连。
更优雅的方式是多个容器连接自定义bridge网络,自动支持容器名服务发现
自建网络并添加两个容器
|
|
多个容器共享一个别名,类似于集群
多容器共享别名,有点类似集群负载均衡,请求会依次解析到不同的容器
5. 工具
5.1 supervisor 类UNIX操作系统的进程管理工具
|
|
6. 编排
6.1 docker-compose
|
|
7. 实例
7.1.php与nginx不同机器分离安装
|
|
8.调试
|
|
统计信息
9.FAQ
1.nginx连接传输速度太慢
|
|
2.Docker为什么刚运行就退出了?
这个是docker的机制问题,Docker容器后台运行,就必须有一个前台进程.容器运行的命令如果不是那些一直挂起的命令(比如运行top,tail)则会自动退出。
比如你的web容器,我们以nginx和fpm为例,正常情况下,我们配置启动服务只需要启动响应的service即可,例如service nginx start && service php5-fpm start,但是这样做nginx和fpm均为后台进程模式运行,就导致docker前台没有运行的应用,这样的容器后台启动后会立即自杀,因为他觉得他没事可做了.
解决方法
i.最佳的解决方案是,将你要运行的程序以前台进程的形式运行,当然,如果你的容器需要同时启动多个进程,
那么也只需要,或者说只能将其中一个挂起到前台即可.
比如上面所说的web容器,我们只需要将启动指令修改为:service php5-fpm start && nginx -g “daemon off;”
这样,fpm会在容器中以后台进程的方式运行,而nginx则挂起进程至前台运行,这样,就可以保持容器不会认为没事可做而自杀了.
ii.对于有一些你可能不知道怎么前台运行的程序,提供一个投机方案,你只需要在你启动的命令之后,
添加类似于 tail top 这种可以前台运行的程序,这里特别推荐 tail ,然后持续输出你的log文件.
还是以上文的web容器为例,我们还可以写成:service nginx start && service php5-fpm start && tail -f /var/log/nginx/error.log
docker run —name website -d -v /home/docker/sample/website:var/www/html/website sheng9632/nginx:1809 nginx
参考http://blog.csdn.net/meegomeego/article/details/50707532
3.172.18.0.0/16是什么意思
子网掩码用来标识ip中的网络位和主机位的32位数字,/16指子网掩码为的前16位为1. 172.18.0.0/16指网络号为172.18.0.0的网络,主机号由0.1至255.254都包括在该子网内
4.重启服务后,容器的网络ip变化,如何解决
1.自建网络支持发现服务,可以使用别名或容器名访问其他机器
2.在生成容器时指定指定静态Ip
5.为什么ENTRYPOINT [‘/usr/sbin/nginx’,’-g’,’daemon off;’] 在执行docker run xxxx后不生效
答: dockerfile中请使用双引号””
6.为什么挂载添加卷volume时提示权限不足
答: 以用户A运行docker,如果要挂载添加卷,A需要对添加卷有权限,并且在添加卷中创建的文件权限全部为A
7.如何分离php和web服务器
答: nginx解释php地址改为网络地址 php容器名:php进程池监听端口号
8.如何detach一个会话(不停止容器脱离会话)
如果容器是以-it运行的,那么可以使用ctrl+p,ctrl+q来detach(不会终端容器运行)
例1
docker run --name test -tid nginx nginx -g "daemon off;"
docker attach test
ctrl+p ctrl+q
例2
docker run --name test -ti nginx nginx -g "daemon off;"
ctrl+p ctrl+q
9.像账号密码等如何传入容器
在env中设定,然后在容器中运行脚本文件启动服务,这时候从env中获取账号密码等
10.docker容器如何访问宿主机服务(比如连接宿主机上的mysql数据库)
目前有两种方式
- 如果网络是网桥驱动(主机作为网关存在)
- export DOCKER_HOST_IP=$(ip route|awk ‘/docker0/ {print $NF}’) 或者是子网确定的情况下,主机Ip直接取网关地址 例 子网172.18.0.0/16 网关就是172.18.0.1,使用DOCKER_HOST_IP来与主机连接
- 如果网络使用host模式
- 直接127.0.0.1上访问mysql即可
如果是mac环境,使用
docker.for.mac.host.internal
访问宿主机
删除所有未使用的镜像
|
|
同主机容器间通信
同一bridge下
- 默认bridge,此时只能使用IP通信
- 用户自定义bridge,此时在容器之间提供了自动DNS解析,可以通过容器名或别名通通信
https://juejin.im/post/5ce26cb9f265da1bcd37aa7c
容器内某些命令无法执行
|
|
默认情况下,docker以一种非特权的模式运行,该模式下容器屏蔽了很多linux能力(capabilities),导致我们无法在容器内部直接使用某些命令,如果你有这方面的需求就需要为容器增加这方面的能力
如果是测试或开发环境等,可以采用傻瓜式配置--privileged
开放全部特权
|
|
如果不想开放所有权限,可以通过--cap-add
和--cap-drop
精细化配置增加或要删除的能力
|
|
>
- capabilities
capabilities是linux内核的一项特性,它将root用户的权限细分为不同的领域,可以分别对其启用或关闭。实际进行特权操作时,如果euid(系统决定用户对系统资源的访问权限,通常情况下等于ruid)不是root,便会检查是否具有该权限操作锁对应的capabilities,并以此为依据,决定是否可以执行特权操作。- seccomp
seccomp是secure computing的缩写,是linux内核2.6.23版本后引入的一种简洁的沙箱机制。secommp用以控制一个用户态程序可以执行的系统调用,相当于一个系统调用白名单。
理解docker容器的运行用户
docker与宿主机共享同一个内核,又用户管理是由内核负责的,可得容器内外相同uid代表相同的用户;
由于用户名不是由内核管理的,所以容器内外相同uid的用户名很可能不同。
容器启动时可以手动指明uid(-u xxx),如果未指明,则使用uid为0(root)用户来运行容器进程