参考Docker — 从入门到实践,记录学习docker过程中常用命令和Dokcerfile编写。

一.安装docker

目前手头只有两种测试环境。

  • mac安装 docker

      brew cask install docker
    
  • (树莓派)debain安装docker

      //脚本安装最新版本
      wget -qO- https://get.docker.com/ | sh
    

二.基本概念

  • 镜像

    Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。

  • 容器

    容器是镜像运行时的实体。

  • 仓库

    一个集中的存储、分发镜像的服务,Docker Registry 支持共有和私有。

三.操作容器和镜像

  • docker版本

      docker version
    
  • 列出镜像

      docker images 
    
  • 拉取镜像

      docker  pull ubuntu //拉取ubuntu 最新版本
    
  • 删除镜像

      docker rmi ubuntu
    
  • 运行容器

     	docker run -i -t ubuntu /bin/bash
    
      参数说明: 
        -i 保证容器中的STDIN是开启的
        -t 分配一个伪tty终端
    
  • 容器命名

      docker run --name ubuntu170210 -i -t ubuntu  /bin/bash
    
  • 重新启动已经停止的容器

      docker start ubuntu
    
  • 附着在容器上

      docker attach ubuntu
    
  • 创建守护式容器

      docker run --name ubuntu170210 -d ubuntu /bin/sh -c "while  true;do echo hello world;sleep 1;done"
    
  • 停止守护式进程

      docker stop ubuntu
    
  • 自动重启容器

      docker run --restart=always --name ubuntu170210 -d ubuntu /bin/sh -c "while  true;do echo hello world;sleep 1;done"
      参数说明
      --restart=always  无论容器退出代码是什么,docker都会重启该容器
      --restart=on-failure:5 如果退出代码非0是,才自动重启。5为自动重启次数,最多重启5次
    
  • 容器日志

      docker logs ubuntu
    
  • 查看容器进程

      docker top ubuntu
    
  • 在容器内部运行进程

      docker exec -d ubuntu touch /opt/test
      参数说明: 
      	-d 表明要在后台运行一个后台进程
    
  • 查看容器更多信息

      docker inspect ubuntu
      docker inspect ubuntu --format='{{.Name}} {{.State.Running}}'
      参数说明: 
      	--format 支持go语言模版,可以通过模版获取参数值
    
  • 查看容器信息(ps)

      docker ps命令可以查看容器的CONTAINER ID、NAME、IMAGE NAME、端口开启及绑定、容器启动后执行的COMMNAD。经常通过ps来找到CONTAINER_ID。
      docker ps 默认显示当前正在运行中的container
      docker ps -a 查看包括已经停止的所有容器
      docker ps -l 显示最新启动的一个容器(包括已停止的)
    
  • 删除容器

      docker rm ubuntu
    
  • 删除所有停止的容器

      docker rm $(docker ps -a -q)
    
  • 查看镜像构建过程

      docker history ubuntu
    
  • 容器的导入和导出

      docker export 容器id > ubuntu.tar
      cat ubuntu.tar | docker import - test/ubuntu:v1.0
      docker import http://gophper.com/ubuntu.tar test/ubuntu //指定url来导入
    

四.编写Dockerfile

注意:简化RUN执行的次数。每一个指令都会建立一层镜像并把运行时不需要的东西装入镜像,如编译环境,更新数据包等。编写dockerfile 不是在写 shell,通过 && 进行指令合并,减少构建层数

  • 镜像构建

      docker build [选项] <上下文路径/URL/->
    
  • FROM指定基础镜像

  • RUN执行命令

    分为两种

      shell格式: RUN <命令> 
      exec格式: RUN ["可执行文件","参数1","参数2"] 
    
  • CMD命令

    指定容器启动时要运行的命令。

  • ENTRYPOINT命令

    与CMD命令类似。docker run命令会覆盖cmd指令,而 ENTRYPOINT 指令 不容易被覆盖。

  • COPY命令

    格式

      COPY <源路径>...<目标路径>
      COPY ["<源路径>",..."<目标路径>"]
    
  • EXPOSE

    生命运行时容器提供服务的端口。

  • WORKDIR

    指定工作目录,可以通过-w参数在运行时覆盖工作目录

      docker run -ti -w /var/log ubuntu pwd
    
  • ENV

    镜像构建过程中设定环境变量

      ENV GOPATH /opt/environment
    

    同时可以用-e标志传递环境变量

      docker run -ti -e "GOPATH=/opt/environment2" ubuntu env
    
  • USER

    指定镜像以什么用户去执行。docker run命令可以通过-u覆盖指令设定值。默认用户为root

      USER nginx //设定容器以nginx用户执行
      //其他表现形式
      USER user:group
      USER uid
      USER uid:gid
      USER user:gid
      USER uid:group
      USER user
    
  • VOLUME

    基于镜像给创建的容器添加卷,一个卷可以存在于一个或者多个容器内的特定目录。

    通过-v参数指定卷的源目录和容器里的目的目录。两个目录通过:分割。如果目的目录不存在,docker自动创建一个。 在目的目录后添加rw或ro指定目的目录的读写状态

      docker run -d -p 80 --name website -v $PWD/website:/var/www/html/website:ro jamtur01/nginx nginx
    
  • ADD

    将构建环境下的文件和目录复制到镜像中。ADD 命令使得构建缓存无效。添加文件还活着目录后,后续指令不能使用构建缓存。

      ADD /etc/sshd.conf /etc/sshd.conf 
      ADD http://gophper.com/golang.tar.gz /opt/environment/golang.tar.gz //支持url
      ADD golang.tar.gz /opt/environment/ 如果为合法归档文件的源文件,会自动解压。如果已经存在的文件和目录不会被覆盖。
    
  • ONBUILD

    为镜像添加触发器。当镜像被用作其他镜像的基础镜像时,镜像中的触发器将会被执行。

      ONBUILD ADD  . /app/src
      ONBUILD RUN cd /app/src && make
    

五.数据卷

  • 数据卷(在mac下提示手动添加共享目录)

      docker run -it -P --name web -v /opt/tmp:/opt/tmp:rw ubuntu 
    

六.使用网络

端口映射

  • 映射所有接口地址

    使用 hostPort:containerPort 格式本地的 5000 端口映射到容器的 5000 端口,可以执行

      $ sudo docker run -d -p 5000:5000 training/webapp python app.py
    

    此时默认会绑定本地所有接口上的所有地址。

  • 映射到指定地址的指定端口

    可以使用 ip:hostPort:containerPort 格式指定映射使用一个特定地址,比如 localhost 地址 127.0.0.1

      $ sudo docker run -d -p 127.0.0.1:5000:5000 training/webapp python app.py
    
  • 映射到指定地址的任意端口

    使用 ip::containerPort 绑定 localhost 的任意端口到容器的 5000 端口,本地主机会自动分配一个端口。

      $ sudo docker run -d -p 127.0.0.1::5000 training/webapp python app.py
    

    还可以使用 udp 标记来指定 udp 端口

      $ sudo docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py
    
  • 查看映射端口配置

    使用 docker port 来查看当前映射的端口配置,也可以查看到绑定的地址

      $ docker port nostalgic_morse 5000
      127.0.0.1:49155.
    

注意:

容器有自己的内部网络和 ip 地址(使用 docker inspect 可以获取所有的变量,Docker 还可以有一个可变的网络配置。)
-p 标记可以多次使用来绑定多个端口

例如

	$ sudo docker run -d -p 5000:5000  -p 3000:80 training/webapp python app.py

容器互联

–link 参数让容器之间安全的进行交互。

Docker 在两个互联的容器之间创建了一个安全隧道,而且不用映射它们的端口到宿主主机上。在启动 db 容器的时候并没有使用 -p 和 -P 标记,从而避免了暴露数据库端口到外部网络上。

1.首先创建一个数据库容器

	docker run -d --name db 
2.然后创建一个新的web容器,并将它连接到db容器

	docker run -d -P --name web --link db:db training/webapp python app.py

Docker 通过 2 种方式为容器公开连接信息:

- 环境变量
- 更新 /etc/hosts 文件

2017-07-20 追加

  • 上传镜像到私有库
docker tag 7328f6f8b418 127.0.0.1:5000/alpine
docker push 127.0.0.1:5000/alpine
docker pull 127.0.0.1:5000/alpine

2017-07-25 追加

In docker for mac

If you can remove all images/containers then:

Stop Docker.

docker rm $(docker ps -a -q)
docker rmi $(docker images -q)
docker volume rm $(docker volume ls |awk '{print $2}')
rm -rf ~/Library/Containers/com.docker.docker/Data/*

Start Docker, you have yours GB back.