美文网首页
Docker入门与实践(一)

Docker入门与实践(一)

作者: 宏势 | 来源:发表于2023-01-04 17:45 被阅读0次

什么是Docker

Docker是一种新兴的虚拟化方式,基于Go语言实现的开源项目,诞生于2013年初。
Docker底层基于成熟的Linux Container(LXC)技术实现,自Docker 0.9版本起,引入libcontainer, 打造更通用的底层容器虚拟化库,依赖的底层核心技术主要包括了操作系统命名空间(namespace)、控制组(Control Groups)、联合文件系统(Union File Systems)和 虚拟网络.

为什么使用Docker

  • 更快速的交付和部署
  • 更高效的资源利用
  • 更轻松的迁移和扩展、维护

基础概念

Docker 主要包括三个基本概念:

  • 镜像:类似于虚拟机镜像,可以理解成Docker引擎的只读模板,是创建Docker容器的基础
  • 容器:类似于一个轻量级的沙箱,Docker利用容器来运行和隔离应用,容器依赖镜像,一个镜像可以运行多个容器
  • 仓库:存放镜像文件的场所,比如Docker hub

Docker常用命令

docker命令

docker --help //该命令可以查看docker详细命令

镜像搜索

docker search java 

拉取镜像

docker pull java:8  //docker pull REPOSITORY[:TAG],不填版本号默认拉取最新版

镜像列表

docker images //列出镜像列表

删除镜像

docker rmi java:8  //删除镜像,-f 参数代表强制删除

注意:删除镜像应该先删除镜像关联的容器,再删除镜像

创建和运行容器

docker run --name web1 -d -p 8080:80 nginx:v1  //命令详细 docker run --help

常用参数说明:

  • -t 选项让Docker分配一个伪终端(pseudo-tty) 并绑定到容器的标准输入上
  • -i 则让容器的标准输入保持打开
  • -d 后台运行
  • -p 映射端口 本地端口:容器端口
  • -P 随机映射端口
  • -name 指定容器名称
  • --rm 退出后自动删除
  • -v 挂载数据卷 例如:-v /var/log/demo:/log 挂载主机目录/var/log/demo

容器启停

docker start web1  // 启动 docker start 容器id/容器name
docker stop web1   // 停止 docker stop 容器id/容器name

列出容器

docker ps //列出正在运行的容器
docker ps -a //列出所有的容器

进入容器

docker exec -it web1 /bin/bash 

删除容器

docker rm web1 
docker rm $(docker ps -aq) //删除所有容器
docker rm $(docker ps -a|grep demo|awk '{print $1}') //按关键字demo过滤删除容器

获取容器元数据

docker inspect web1 

查看容器日志

docker logs web1

基于容器创建镜像

docker commit web1 test/web1:v1 //命令详细 docker commit --help

上传镜像

docker tag web1:v1 user/web1:v1 //镜像打标签(实际创建一个新的镜像)
docker push user/web1:v1 //上传镜像

Dockerfile创建镜像

具体参见官网:https://docs.docker.com/engine/reference/builder/

案例

a. 创建目录

mkdir springbootdemo
cd springbootdemo
vi Dockerfile

b. 创建dockerfile文件:

FROM java:8
MAINTAINER 作者名 邮箱地址
COPY demo1.jar /demo.jar
RUN java -version
EXPOSE 8080
ENV active ''
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/demo.jar","--spring.profiles.active=${active}"]

c. 上传jar包到springbootdemo 目录下

d. 构建镜像

docker build -t demo:v1 . //springbootdemo目录下构建镜像

e. 运行容器

docker run -d -P --name=demo1 -e active="test" demo:v1 //传递参数active="test"

指令说明

FROM

格式为 FROM <image> 或者 FROM <image>:<tag> 

必须为第一条指令

MAINTAINER

 指定维护者 信息

RUN

格式:RUN <command> 或者 RUN ["executable","param1","param2"] 

该命令可以多条,创建镜像时执行的命令,当命令较长时可以使用** \ ** 来换行

CMD

CMD ["executable","param1","param2"]  
CMD commond param1 param2  
CMD ["param1","param2"]  //提供给ENTRYPOINT的默认参数

指定容器启动时执行的命令,每个docker只能有一条CMD命令,如果多条的话,只会执行最后一条,如果用户启动容器指定了运行的命令,则会覆盖CMD命令

EXPOSE

格式 EXPOSE <port> [<port>...]

指定容器暴露的端口号

ENV

格式 ENV <key> <value> 

指定环境变量,多个变量多条ENV指令,可以被后续的指定使用${key}

ADD/COPY

格式: ADD <src> <dest> ; COPY <src> <dest>

该命令复制指定src 到容器中dest,其中 src 是dockerfile坐在目录的一个相对路径(文件或者目录),目标路径不存在时会自动创建,两个区别在于,ADD 的src 支持URL,ADD src 是 tar文件会自动解压为目录,推荐使用COPY指令

ENTRYPOINT

ENTRYPOINT ["executable","param1","param2"]  
ENTRYPOINT commond param1 param2  //shell中执行

配置容器启动后执行的命令,并且不可被docker run 提供的参数覆盖,只能有一个ENTRYPOINT,当多个时,只有最后一个生效

VOLUME

格式为VOLUME ["/data"]

创建一个挂载点,/data 代表容器中的目录,用于存放需要保持的数据

USER

格式:USER <user>[:<group>] 或者 USER <UID>[:<GID>]

WORKDIR

格式1:WORKDIR /path/to/workdir
格式2:  
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd //结果/a/b/c

RUN 与 CMD 区别

RUN 是创建镜像执行的命令可以多条,CMD是启动容器执行的命令只有最后一条生效

CMD 与 ENTRYPOINT 区别

1.两者多条命令只有最后一条生效;
2.CMD 可由 docker run <image> 后的命令覆盖,同时覆盖参数,但是定义了ENTRYPOINT docker run <image> 后的命令全是参数;
3.CMD 与 ENTRYPOINT 同时定义,CMD追加ENTRYPOINT参数后面当参数

举四个例子进行说明

一, 未定义 ENTRYPOINT, 定义了 CMD
#ENTRYPOINT [] 
CMD ["echo", "hello"]

实际入口是它们拼接后还是 CMD 本身,["echo", "hello"]

二, 定义了 ENTRYPOINT 和 CMD
ENTRYPOINT ["echo", "hello"]
CMD ["echo", "world"]

实际入口是它们拼接起来,形成 ["echo", "hello", "echo", "world"], 执行 docker run test 显示为 hello echo world

三, 定义了 ENTRYPOINT, CMD 由 docker run 提供
ENTRYPOINT  ["echo", "hello"]

执行命令 docker run <image> rm -rf /, 实际入口是由 ["echo", "hello"]["rm", "-rf", "/"] 拼接而成的 ["echo", "hello", "rm", "-rf", "/"], 输出为 hello rm -rf /。看到 rm -rf / 也不用担心,用 ENTRYPOINT 就是让人放心

注:ENTRYPOINT 同样可以被覆盖,如 docker run --entrypoint ls test -l /,将会执行 ls -l / 命令。

建议ENTRYPOINT 固定命令,docker run <image>后面传参数

四, 如果 ENTRYPOINT 用 shell 格式定义的
ENTRYPOINT java -jar /app.jar
CMD ["hello", "world"]

通过 docker inspect 命令看到镜像中实际的 ENTRYPOINT 是
ENTRYPOINT ["/bin/sh", "-c", "java -jar /app.jar"]
所以与 CMD 连接起来的入口就是 ["/bin/sh", "-c", "java -jar /app.jar", "hello", "world"], "bin/sh" 直接忽略掉后面的 "hello" 与 "world",这就是为什么 shell 命令方式无法获取参数。

  • 未定义 ENTRYPOINT
    没有定义 ENTRYPOINT 的镜像想怎么来就怎么来,docker run <image> 后面的输入你自己作主。

  • 有定义 ENTRYPOINT
    定义了 ENTRYPOINT 的镜像,则是 CMD 或 docker run <image> 后的输入作为 ENTRYPOINT 中命令的附加参数。再次提醒 shell 格式的 ENTRYPOINT 和 CMD 务必要转换为相应 exec 格式来理解。

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

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

    $ docker run test world and China
    hello world and China
    

    如果只是按常规 shell 脚本来对待,想当然的写成ENTRYPOINT echo hello $@效果将是

    $ docker run test world and China
    hello and China
    

    第一个参数将被丢失,docker run <image> 后第一个输入通常是一个命令,所以是 $0, 而 ENTRYPOINT 又希望它是一个普通参数,因此$0 $@要同时写上。

容器数据管理

数据卷

docker run -d -P --name demo1 -v /data demo:v1 //创建一个数据卷挂载到容器/data目录  

docker run -d -P --name demo1 -v /opt/data:/data demo:v1 //挂载主机的/opt/data目录到容器的/data 目录

数据卷容器

docker run -it -v /dbdata --name dbdata ubuntu //数据卷容器  

docker run -it --volumes-from dbdata --name db1 ubuntu
docker run -it --volumes-from dbdata --name db2 ubuntu

--volumes-from 容器name, db1,db2 挂载到同一数据卷,三个容器任务一方在该目录下的写入,其它容器都可见,其实就是操作同一目录文件

docker volume ls //查看所有数据卷,详见:docker volume --help

备份

docker run --volumes-from dbdata -v $(pwd):/backup --name db1 ubuntu tar cvf /backup/backup.tar /dbdata

恢复

docker run --volumes-from dbdata -v $(pwd):/backup --name db2 ubuntu tar xvf /backup/backup.tar

容器与主机文件拷贝

docker cp /opt/test.txt demo1:/opt/test //主机copy to 容器
docker cp demo1:/opt/test /opt //容器copy to 主机

Docker目录结构

默认存储目录 Docker Root Dir:/var/lib/docker,存储镜像和容器的元数据以及运行数据,有两种修改方式

1.修改配置文件:/usr/lib/systemd/system/docker.service 里面 ExecStart=/usr/bin/dockerd --graph=/home/docker/lib/docker 通过--graph参数修改默认存储目录

  1. 配置目录:/etc/docker/daemon.json 配置镜像地址,指定存储目录
{
    "registry-mirrors":["地址1","地址2"],
    "data-root":"/cache1/docker"
}

相关文章

  • Docker 基本用法

    Docker 参考 极客学院Wiki:Docker入门基础教程 Gitbook:Docker —— 从入门到实践 ...

  • Docker安装与国内加速

    Docker 简介 Docker官网Docker GithubDocker —— 从入门到实践Docker是一个开...

  • Spring Boot与Docker部署

    了解Docker的一些基础知识Docker——入门实战Docker —— 从入门到实践 Centos7上安装doc...

  • Docker

    Docker —— 从入门到实践 https://yeasy.gitbooks.io/docker_practic...

  • Ubuntu下安装Docker

    《Docker Practice(Docker从入门到实践)》学习笔记本文转自:Ubuntu 安装 Docker ...

  • docker入门笔记

    《Docker技术入门与实践》笔记 2 核心概念 Docker的三个核心概念分别为:镜像、容器和仓库。 2.1 镜...

  • Docker入门实战学习总结(脑图)

    参考资料:GitBook Docker — 从入门到实践

  • docker简介及mac下安装docker

    最近系统的学习docker,参考资料Docker-从入门到实践,docker官网 docker是什么 Docker...

  • Docker学习笔记

    GitBook Docker —— 从入门到实践 一张图总结 Docker 的命令 运行容器 14.04是tag,...

  • 2018-08-12

    Docker常用命令 从入门到实践:https://yeasy.gitbooks.io/docker_practi...

网友评论

      本文标题:Docker入门与实践(一)

      本文链接:https://www.haomeiwen.com/subject/jgzrcdtx.html