image = {|bootfs|rootfs|app...(*COW*)|} --> Container

https://github.com/yeasy/docker_practice
https://yeasy.gitbooks.io/docker_practice/content/

  • Container进程运行在自己的namespaces(proc,net,kernel,mnt的隔离)
  • os使用cgroup来实现资源的管理

install

https://docs.docker.com/engine/install/centos/
https://docs.docker.com/compose/install/

{
  "registry-mirrors": [
    "https://dockerhub.azk8s.cn",
    "https://reg-mirror.qiniu.com",
    "https://registry.docker-cn.com",
    "https://wrgl07nl.mirror.aliyuncs.com"
  ]
}
mkdir /etc/docker; vim /etc/docker/daemon.json
systemctl start docker
docker version/info

command

  • 注意: docker run 一次只能启动一个应用程序(可以写成脚本运行多个进程), 程序退出后容器也就退出了.
  • 注意: 容器的读写不应该在其存储层, 应该通过数据卷直接写到宿主机(VOLUME或-v), 效率更高.
  • 注意: 容器中CMD的运行都是前台的,没有后台的概念!所以不要使用service/systemctl!
  • 注意: attach命令不要用!若实在想用,请附加参数:’–sig-proxy=false’防止容器退出.
  • flags:
    -t: 模拟一个tty,方便交互
    -i: 开放stdin给连接,方便输入
    --link=container_DN :指定一个别名,避免重启docker时个容器地址变化
    --vlumes-from container: 指明要挂载到reponame所在的宿主机目录
# image/repo
docker search alpine[:tagname]  # 以下均可以加tagname
docker pull ubuntu:18:04  # 默认tag是latest
# 使用ctrl+pq切换到后台! 91(host) --> 80, 镜像不存在会自动pull
# --rm:容器退出后随即删除,否则会保留,后面可以使用'docker start cname'重新启动
docker run -itd --rm -p 91:80 --name cname ubuntu:18:04 bash
docker info   # 查看docker服务的状态.login可以用来登录,push的时候需要.
docker images <reponame>  # 不加参数, 默认查找所有仓库的镜像(docker image ls)
docker rmi -f <imageid>   # 删除镜像,可以指定imageid或者tag
docker history <reponame> # 查看镜像的构建过程
docker commit -a 'author' container repo:tag # 通过容器构建镜像
docker build --no-cache=true -t name:v1.0.1 dockerfile/path  # 用来构建镜像image,可能一次构建多个镜像.
docker save imagename:version > xxx.tar
docker load < xxx.tar

# container
docker inspect/[re]start/stop/kill/rm/pull/push/attach/top/port cname/cid  # 都可加上在docker后container修饰
docker ps -a  # 查看所有容器
docker logs -tf --tail cname  # 查看容器运行的日志(容器环境的stdout),t:加上时间戳.f:follow log output,后面的参数是--tail或'--since <time>'
docker exec -it --name cname -v hostpath:/data reponame
docker container prune  # 清除所有处于stop状态的容器

# inspect
docker port node5  # 查看容器的端口映射
docker inspect node1|grep -i ipaddress  # 查看某个容器的ip
# .Name      :容器的名字
# .Id        :容器的ID
# .State.Pid :容器的PID
docker inspect --format/-f='{{.一级属性.二级属性}} {{.Id}}' `docker ps -aq`
docker inspect --format/-f='{{json .State.Health}}' cid |python -m json.tool

# volume
docker volume list  # 查看所有挂载卷
docker volume inspect vol1
docker volume rm vol1

dockerfile

FROM centos  # 基础镜像
MAINTAINER lei email  # 维护者

EVN PATH=/usr/local/nginx/sbin:$PATH NAME="lei"  # 使用\换行
ARG envname=envvalue  # ARG设置的环境变量只在镜像构建时生效,今后容器运行时是看不到的. docker build --build-arg 可以覆盖

# 可以使用ONBUILD修饰,表示只有当前镜像被别人from时才去执行.一般基础镜像绑定配置文件时会这样.
ADD  --chown=<user>:<group> nginx-1.9.3.tar.gz /usr/local/src  # Dockerfile的同级目录 --> 镜像环境, 只适合用在需要解压的场合.应尽量使用COPY
COPY --chown=<user>:<group> nginx-1.?.3.* /usr/local/src  # 目标路径也可以使用相对路径,但要指定WORKDIR!COPY会保留文件的元数据(权限,日期)

RUN yum install -y wget make && yum clean all  # 构建镜像时运行的命令; 每个RUN都会构建一个子镜像(不要指望cd)!
WORKDIR /usr/local/src/nginx-1.9.3  # chdir容器的当前工作目录.绝对路径!
RUN ./configure --prefix=$NAME

EXPOSE 80 443  # 开放容器的端口,默认容器并不会开放.会被-p参数覆盖
VOLUME ["/tmp/data"]  # 自动挂载卷 -> hostpath:/var/lib/docker/vfs/dir/01x.. 可被覆盖: -v hostdatapath:/tmp/data

USER lei  # 以哪个用户运行,默认是root
ENTRYPOINT ["nginx", "param1"]  # 'docker run'最后的参数默认被当做命令,会覆盖CMD, 若有ENTRYPOINT则会被当做参数传递.
CMD ["-h"]  # 此时配合ENTRYPOINT当做默认参数.否则可能是 ["nginx", "-g", "daemon off"]; 多条时仅最后一条生效,同ENTRYPOINT和HEALTHCHECK!

# 均是默认值
# 连续3次命令在30s内无响应就算失败(1),容器状态被标识为UNhealthy!
HEALTHCHECK --interval=30s --timeout=30s --retries=3 CMD curl -fs ... || exit 1