docker笔记
背景
近年来docker相比虚拟机,呼声越来越高,因此决定看一下
简介
自古以来有个问题,软件能不能带环境安装,不要总是在我的电脑上能跑.
对此有两个解决方案
- 虚拟机
- 在虚拟机上虚拟出硬件,然后在虚拟硬件上运行虚拟系统
- 特点是资源占用多,启动慢,冗余步骤多(有可能需要用户先登陆然后再做一些操作)等等
- Linux容器(简称LXC)
- 最开始是利用linux内核的namespace和control group技术来隔离进程和资源,
以创建相对独立的环境(文件系统,网络,CPU),但不独立于宿主,而是共用.脱胎与linux的jail技术. - 大部分的数据沟通思想是映射.比如使用-v(volume)指定数据文件的映射,-p(port)指定信息指令的映射
- 最开始是利用linux内核的namespace和control group技术来隔离进程和资源,
优点:
- 轻量,效率高,相当于绿色软件,标准化(包含了依赖)
缺点:
- 资源隔离不彻底(容器之间会争抢资源,容器内部的病毒会传给宿主系统)
- 跨平台不彻底(用的是linux内核,但随着发展,也出现了windows原生docker)
Docker是LXC的一种封装,使用go语言构建.
将程序与程序的依赖打包在一个文件中,
并且提供了方便的接口供使用.
属于C/S架构,使用起来感觉像是ssh.
Docker原先由dotcloud公司开发,2013年因为经营不好索性开源,
后来火了,公司也改名Docker,Inc.
成功点在于Docker有个资源网站Docker Hub,犹如苹果有app store.
Docker的侧重在于软件的快速部署,
用户来看就像安装了一个app,然后就能用了.
比如OpenWrt用户,安装了一个叫oldiy/music-player-docker的docker,
启动后就能使用 192.158.1.1:264访问了,
而这个用户不必往自身中安装任何web应用所需的环境,语言,数据库,中间件等等.
因此docker的使用场景有
- 提供完整环境(就比如在openwrt上安装web应用)
- 提供弹性云服务(可以随意开关,适合扩容和缩容)
- 组件微服务架构(多个容器一起)
安装
docker有两个版本,ce(Community Edition)和ee(Enterprise Edition),个人使用安装ce.
若在ubuntu上手动安装,需要添加docker的源,注册密钥等等.最终安装的是
docker-ce, docker-ce-cli, container.io
好在一般可以用脚本安装
1 | curl -fsSL get.docker.com -o get-docker.sh |
docker运行靠的是docker组的权限,如果不是docker组,需要每次使用sudo,
把当前用户加入 docker
组,重新登陆生效
1 | sudo groupadd docker |
安装确认:
1 | docker version # 显示一些版本信息 |
hello-world
1 | docker run hello-world |
下载下来的hello-world包会运行并输出一些文字,然后退出.
有些容器运行的是服务,不会在run之后自动停止,除非手动杀掉.
名词解释
镜像
镜像文件.就是把程序和程序的依赖打包成的文件.是二进制文件.
通常为了避免重复造轮子,都是继承别人的文件(最初始的应该叫scratch),加上自己的定制,然后做出自己的镜像.
docker的基础是UnionFS联合文件系统,
特点是分层(对文件系统的修改作为一次提交),轻量,高性能.
使用docker pull时可以看到下载了多个分层,越往下越靠外,最终ls时向外暴露的是最外层的名称.
好处就是容易共享.
通常一个完整的image名为
library/hello-world:latest
library为组名,表明谁发布的这个镜像,默认是官方的library组
hello-world为镜像名.
latest为标签名,通常用来表示版本,1.0,2.0等等.默认为latest.
另外docker中指定一个镜像,还可以使用image~id~.
容器
当运行起文件时,生成的就叫容器,同一个镜像可以同时生成多个容器.
对容器的操作有,run,start,stop,kill,restart等
容器的状态有7种
- created(已创建)
- restarting(重启中)
- running(运行中)
- removing(迁移中)
- paused(暂停)
- exited(停止)
- dead(死亡)
仓库
就像linux系统中的各个软件仓库一样,docker也有仓库. Docker Hub
.
容器文件
当容器运行起来后,会有生成一个容器文件,关闭容器后这些容器文件仍任存在(只是容器停止运行了)
docker中指定一个容器,可以用<container~id~>,也可以用<container~name~>
如果不手动使用 --name
指定,那么docker会随机生成一个不是乱码的名字.
持久化
尤其是redis这一类的docker,本身是可以将内存中的数据存到硬盘中的,
为了更加保险,docker允许以映射的方式将本地路径和docker中路径联系起来,保存文件.
-v 本地路径:docker中路径:权限
权限可以省略.
权限举例: ro表示readonly,效果是container不能编辑host上的文件,
redis可以配置 -v /host/data:/data
.
另外两端不存在的文件夹会被建立.
常用命令
镜像相关
1 | 从仓库拉取镜像 |
容器运行相关
1 | 运行 |
具体其实启动参数还是要使用 docker run --help
等命令来查看,
docker自身更新更新也算是很快了.有可能一些参数会消失.
管理
1 | 查看正在运行的docker |
自定义docker ps输出内容
docker提供这一功能
1 | docker ps --format='table {{.Names}}\t{{.Status}}' |
制作和发布
在 Docker Hub 注册一个账户后就可以往仓库中发布自己的容器了.
1 | ############## |
其他命令
export和import
可能会连内存中的东西一起保存
1 | docker export 1e560fca3906 > ubuntu.tar |
commit
提交容器副本使之成为一个镜像.
1 | 对一个container做修改 |
如果不用commit来保存数据,也可以使用卷映射来设法持久化数据.
Dockerfile相关
Dockerfile
是docker在build镜像时的默认配置文件.
另外docker也支持使用 .dockerignore
文件来定义不要打包到镜像中的文件列表,比如
1 | .git |
一个基础的Dockerfile如下,
另外可以在docker-library/redis等项目里找到Dockerfile的样板文件.
1 | FROM node:8.4 # 继承名为node,标签为8.4的镜像 |
一些基础:
- 第一列必须大写,
#
表示注释, - 从上到下执行,
- docker通常会先运行一个基础的容器,然后逐条指令执行,
- 每条操作后都会做一个类似commit的操作.直到做完.
其他的关键字
- ENV: 配置环境变量,比如PATH等
- VOLUME: docker会以数组形式接收需要共享的文件夹,
出于可以移植考虑,对应host上的文件夹由docker自动生成,通常是/var/lib/docker/volumes/<container~id~>/~data~/ - ADD: 功能类似COPY,但会自动处理URL和解压缩tar包
- RUN: 构建docker时使用的命令
- CMD: 容器运行起来后执行的命令,不过有多个CMD时只有最后一个生效(但build时仍然显示被commit了),
且CMD会被命令行覆盖.
(比如Dockerfile让使用python,而命令行让使用python exam.py则按照命令行说的算)
(再比如Dockerfile让第一句让使用xxxdaemon --run,第二句让ls,则只会执行第二句就退出,不再启动守护程序了) - ENTRYPOINT: 类似CMD不会被覆盖而是增加,
但目前观察到的都是在同一个命令里增加参数,比如Dockerfile里使用entrypoint ls,
然后在run时,在命令的最后添加-l参数则添加称为ls -l效果. - ONBUILD 父镜像被继承时,父镜像的ONBUILD会被触发,通常ONBUILD后会跟其他指令,比如 ONBUILD RUN echo “FBI Warning”
- USER 指定可以运行的用户?