Docker介绍及常用命令

简介

安装

  • yum install docker

常用命令

  • service docker start/stop/restart(chkconfig docker on 加入开机启动)

  • docker version #docker 版本

  • docker info #系统信息,镜像和容器数量

  • docker images #查看本地的image镜像

  • docker pull centos/mysql/redis #可以获取一些official的镜像,当然我们也可以自己写dockerfile,构建自己的镜像

  • docker pull <镜像名:tag> #可以指定tag拉去镜像

  • docker ps #查看正在运行的容器

  • docker ps -q #只显示正在运行的容器id,可以配合kill,stop等命令使用

  • docker ps -a #显示所有的容器id,包括退出的,可以配合清除使用

  • docker ps -aq

  • docker ps -l #最近一次启动的容器

  • docker stop <容器名 or ID> #停止某个容器

  • docker start <容器名 or ID> #启动某个容器

  • docker kill <容器名 or ID> #杀掉某个容器

  • docker rm $(docker ps -aq) #删除所有容器,注意删除的不是镜像(docker rm ‘docker ps -a -q‘)

  • docker rm <容器名 or ID> #删除单个容器

  • docker rmi #删除镜像

  • docker rmi $(docker images -q) #删除所有镜像

  • docker rmi $(docker images | awk ‘/^/ { print $3 }’)

  • docker save -o /xx/xx/xx.tar 容器名:tag (tag加上就是保证唯一,如果容器名唯一可以不加tag) #导出镜像

  • docker load –input /xx/xx/xx.tar(docker load < /xx/xx/xx.tar)

  • docker export/docker import #导出镜像的快照,跟save/load的区别是,快照信息不全

  • docker build -t <镜像名:tag> <Dockerfile路径>

    • docker build -t xxx: . #默认查找当前目录中Dockerfile的文件
    • docker build -f <文件> -t xxx: #指定文件build
    • build -t xx - < xyz #可以指定文件名为xyz,注意:使用docker build - < somefile方式进行build,是不能直接将本地文件ADD到container中。只能ADD url file.
  • docker commit ID new_image_name #对镜像修改后保存,相当于git的commit一样

  • docker diff Name/ID # 列出一个容器里面被改变的文件或者目录,list列表会显示出三种事件,A 增加的,D 删除的,C 被改变的

  • docker top Name/ID # 显示一个运行的容器里面的进程信息

  • docker cp Name/ID:/container_path to_path #从容器里面拷贝文件/目录到本地一个路径

  • docker logs -F #docker的日志不会即时刷新,除非你使用了-F选项

  • docker run

    docker run -i -t ID /bin/bash #进入交互命令行

    • -i 表示以“交互模式”运行容器
    • -t 表示容器启动后会进入其命令行
    • -p 端口 xx:yy #首先映射端口(宿主的xx端口和container的yy端口映射):
    • -v 设置共享目录volume,命令使用 -v 可以绑定一个volume, -v 可以使用多次,创建多个volume,通过-v参数,冒号前为宿主机目录,必须为绝对路径,冒号后为镜像内挂载的路径
    • -d 后台运行

    docker run -it –rm anapsix/alpine-java java -version

    • –rm 执行后删除容器
    • 后面紧跟命令标识执行完就会退出,前提是镜像不会block执行,执行完命令自然就回退出。
  • docker exec :在运行的容器中执行命令

    docker exec [OPTIONS] CONTAINER COMMAND [ARG…]

    OPTIONS说明:

    • -d :分离模式: 在后台运行
    • -i :即使没有附加也保持STDIN 打开
    • -t :分配一个伪终端
  • docker attach ID #attach到一个容器上

  • sudo docker inspect ID #使用docker inspect命令查看新创建的镜像的详细信,ID是容器ID

  • push 到私有Register

    • step1——找到本地镜像的ID:docker images

      step2——登陆Hub:docker login –username=username –password=password –email=email

      step3——tag:docker tag /:

      ​ docker tag hello-world:latest localhost:5000/hello-mine:latest

      step4——push镜像:docker push /

  • springboot项目传递参数

    先改Dockerfile:

    1
    2
    3
    4
    FROM java:8
    ADD microsoft.jar /root
    ENV PARAMS=""
    ENTRYPOINT ["sh","-c","java $PARAMS -jar /root/microsoft.jar"]

    启动命令:

    docker run -d -e PARAMS=”-Dserver.port=8080” -p 2000:8080 镜像名称

    docker run的参数选项,里面有一个-e,可以用来传递普通变量

    如果是复杂的 shell 命令不容易拆解出一个个参数,而希望用 shell 格式来定义 ENTRYPOINT 的话,也有办法。shell 格式的 ENTRYPOINT 是由 “/bin/sh -c” 启动的,而它是可以解析变量的。另一方面 CMD 或 docker run <image> 的输入第一个元素存成了 $0,其他剩余元素存为 [email protected], 所以 shell 格式的 ENTRYPOINT 可以这么写

    ENTRYPOINT echo hello $0 [email protected]

    注:shell 中 $0 表示命令本身,[email protected] 为所有参数

    这样执行下面 docker 命令将可获得所有的参数输入

    $ docker run test world and China
    hello world and China

    ARG 构建参数

    格式:ARG <参数名>[=<默认值>]

    构建参数和 ENV 的效果一样,都是设置环境变量。所不同的是,ARG 所设置的构建环境的环境变量,在将来容器运行时是不会存在这些环境变量的。但是不要因此就使用 ARG 保存密码之类的信息,因为 docker history 还是可以看到所有值的。

    Dockerfile 中的 ARG 指令是定义参数名称,以及定义其默认值。该默认值可以在构建命令 docker build 中用 --build-arg <参数名>=<值> 来覆盖。

    在 1.13 之前的版本,要求 --build-arg 中的参数名,必须在 Dockerfile 中用 ARG 定义过了,换句话说,就是 --build-arg 指定的参数,必须在 Dockerfile 中使用了。如果对应参数没有被使用,则会报错退出构建。从 1.13 开始,这种严格的限制被放开,不再报错退出,而是显示警告信息,并继续构建。这对于使用 CI 系统,用同样的构建流程构建不同的 Dockerfile 的时候比较有帮助,避免构建命令必须根据每个 Dockerfile 的内容修改。

Dockerfile详解

  • 生成mysql image的例子:mysql_docker_file

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    from centos:6

    maintainer liuhailin

    run mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak

    copy CentOS6-Base-163.repo /etc/yum.repos.d/CentOS-Base.repo

    run yum install -y mysql-server mysql

    run service mysqld start &&\

    mysql -e "grant all privileges on . to 'root'@'%' identified by 'root';" &&\

    mysql -e "grant all privileges on . to 'root'@'localhost' identified by 'root';"&&\

    mysql -u root -proot -e "show databases;"

    EXPOSE 3306
    CMD ["service mysqld restart"]

    docker run –name=mysqlserver -d -p 3306:3306 mysql_server

  • zookeeper镜像:zookeeper_docker_file

  • java8镜像:(直接安装的rpm包,没有涉及环境变量)java_docker_file

Dockerfile 中命令

  • from
  • maintainer
  • run
  • cmd
  • entrypoint
  • user
  • expose
  • env 设置环境变量
  • add 会自动解压
  • copy
  • volume VOLUME [“/data”] 创建一个挂载点用于共享目录
  • workdir
  • onbuild

问题

  1. 当使用Dockerfile Build镜像时,有时会发现发送到Daemo的内容过大Sending build context to Docker daemon 1.152 GB Sending build context to Docker daemon

    但是我们的Dokerfile 非常简单,那么这些多出来的内容是从哪里来的呢。

    查阅资料后,发现Docker Client会默认发送Dockerfile同级目录下的所有文件到Dockerdaemon中。

    解决办法有几种:

    • 使用.dockerignore文件,设置黑名单,该文件包含的目录不会被发送到Docker daemon中
      • 将Dockerfile迁移后其他目录中执行。
      • build - < xxx,指定文件名
  2. 使用Dockerfile添加容器环境变量的时候,比如加入/etc/profile
    run echo “zkHOME= `pwd`“>> /etc/profile

1
2
3
4
5
run echo "PATH=\$PATH:\$zkHOME/bin">> /etc/profile
run echo "export PATH">> /etc/profile
run source /etc/profile

#注意:上面PATH = \$PATH:\$zkHome/bin中,要加入转义\否则$不能转义,导致失败
坚持技术分享,您的支持将鼓励我继续创作!