7.13实习培训日志 Docker

静态博客github地址
静态博客github地址轻量版

Docker

Docker镜像

Docker镜像概念

Docker镜像下载时的分层体现:一层层下载,下载过程中给出了每一层的 ID 的前 12 位。并且下载结
束后,给出该镜像完整的 sha256 的摘要,以确保下载一致性。

docker images

ocker images 列表中的镜像体积总和并非是所有镜像实际硬盘消耗。由于 Docker 镜像是多层存储结构,并且可以继承、复用,因此不同镜像可能会因为使用相同的基础镜像,从而拥有共同的层。由于 Docker 使用 Union FS,相同的层只需要保存一份即可,因此实际镜像硬盘占用空间很可能要比这个列表镜像大小的总和要小的多.

虚悬镜像:镜像既没有仓库名,也没有标签,均为

docker images -f dangling=true #列出虚悬镜像
docker rmi $(docker images -q -f dangling=true) #删除虚悬镜像

中间层镜像:为了加速镜像构建、重复利用资源,Docker 会利用中间层镜像。

docker images -a #显示包括中间层镜像的所有镜像
docker rmi $(docker ps -a -q) #-q 产生出指定范围的 ID 列表,然后送给另一个 docker 命令作为参数
docker images --format "table {{.ID}}\t{{.Repository}}\t{{.Tag}}" #表格等距显示
docker diff imagename # 看到具体的改动
docker commit [选项] <容器ID或容器名> [<仓库名>[:<标签>]] #提交更改的镜像

docker commit 命令除了学习之外,还有一些特殊的应用场合,比如被入侵后保存现场等。但是,不要使用 docker commit 定制镜像,定制行为应该使用 Dockerfile 来完成。

Dockerfile命令

FROM & RUN

FROM:指定基础镜像,如果是scratch,表示一个空白的镜像

RUN:用来执行命令行命令

  1. shell 格式: RUN <命令> ,就像直接在命令行中输入的命令一样
  2. exec 格式: RUN ["可执行文件", "参数1", "参数2"] ,这更像是函数调用中的格式。
FROM debian:jessie
RUN apt-get update
RUN apt-get install -y gcc libc6-dev make

上面的这种写法,创建了 2 层镜像。

Dockerfile 中每一个指令都会建立一层, RUN 也不例外。每一个 RUN 的行为,就和刚才我们手工建立镜像的过程一样:新建立一层,在其上执行这些命令,执行结束后, commit 这一层的修改,构成新的镜像。

Union FS 是有最大层数限制的,比如 AUFS,曾经是最大不得超过 42 层,现在是不得超过127 层

正确用法 &&连接

FROM debian:jessie
RUN buildDeps='gcc libc6-dev make' \
&& apt-get update \
&& apt-get install -y $buildDeps
docker build -t nginx:v3 . #在当前目录指定tag名构造镜像 .指定上下文路径:COPY ADD需要用。

.dockerignore ,该文件是用于剔除不需要作为上下文传递给 Docker 引擎的

docker build https://github.com/twang2218/gitlab-ce-zh.git#:8.14

COPY复制文件

  1. COPY <源路径>... <目标路径>
  2. COPY ["<源路径1>",... "<目标路径>"]
COPY filename /filepath/ #构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径> 位置

ADD更高级的复制文件

  1. 自动解压缩
  2. <源路径> 可以是一个 URL

比如 <源路径> 可以是一个 URL ,这种情况下,Docker 引擎会试图去下载这个链接的文件放到 <目标路径> 去。下载后的文件权限自动设置为 600 ,如果这并不是想要的权限,那么还需要增加额外的一层 RUN 进行权限调整,另外,如果下载的是个压缩包,需要解压缩,也一样还需要额外的一层 RUN 指令进行解压缩。所以不如直接使用 RUN 指令,然后使用 wget 或者 curl 工具下载,处理权限、解压缩、然后清理无用文件更合理。因此,这个功能其实并不实用,而且不推荐使用。

真的是希望复制个压缩文件进去,而不解压缩,这时就不可以使用 ADD 命令

ADD ubuntu-xenial-core-cloudimg-amd64-root.tar.gz / #自动解压

CMD 容器启动命令

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

指令格式上,一般推荐使用 exec 格式,这类格式在解析时会被解析为 JSON 数组,因此一定要使用双引号 " ,而不要使用单引号。

Docker 不是虚拟机,容器中的应用都应该以前台执行,而不是像虚拟机、物理机里面那样,用 upstart/systemd 去启动后台服务,容器内没有后台服务的概念。

CMD service nginx start #会被理解为 CMD [ "sh", "-c", "service nginx start"]
#容器执行后就立即退出

CMD ["nginx" "-g" "daemon off;"] #正确的做法,前台运行Nginx

ENTRYPOINT 入口点

  1. shell 格式: ENTRYPOINT <命令>
  2. exec 格式: ENTRYPOINT ["可执行文件", "参数1", "参数2"...]
CMD有了ENTRYPOINT  将变成<ENTRYPOINT> "<CMD>"

让镜像变成像命令一样使用

CMD [ "curl", "-s", "http://ip.cn" ] #不可以使用docker run image -i
ENTRYPOINT [ "curl", "-s", "http://ip.cn" ] #可以使用docker run image -i

应用运行前的准备工作

启动主进程运行一些准备工作

ENV 设置环境变量

  1. ENV <key> <value>
  2. ENV <key1>=<value1> <key2>=<value2>...

ARG 构建参数

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

和ENV设置环境变量不同的是ARG 所设置的构建环境的环境变量,在将来容器运行时是不会存在这些环境变量的。

docker history 能看到所有值,不要保存密码

VOLUME 定义匿名卷

  1. VOLUME ["<路径1>", "<路径2>"...]
  2. VOLUME <路径>

事先指定某些目录挂载为匿名卷,这样在运行时如果用户不指定挂载,其应用也可以正常运行,不会向容器存储层写入大量数据

EXPOSE 声明端口

EXPOSE <端口1> [<端口2>...]

声明运行时容器提供服务端口,这只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务。

WORKDIR 指定工作目录

WORKDIR <工作目录路径>

改变以后各层的工作目录的位置

USER 指定当前用户

USER <用户名>

USER 则是改变之后层的执行 RUN , CMD 以及 ENTRYPOINT 这类命令的身份。

HEALTHCHECK 健康检查

HEALTHCHECK [选项] CMD <命令> :设置检查容器健康状况的命令
HEALTHCHECK NONE :如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令

ONBUILD 为他人做嫁衣裳

ONBUILD <其它指令>

其他生成镜像

docker import [选项] <文件>|<URL>|- [<仓库名>[:<标签>]]

docker save image | gzip > alpine-latest.tar.gz  #保存镜像
docker load -i alpine-latest.tar.gz #加载镜像

docker save <镜像名> | bzip2 | pv | ssh <用户名>@<主机名> 'cat | docker load' #一个机器将镜像迁移到另一个机器,并且带进度条的功能

注意事项

Ubuntu/Debian 上有 UnionFS 可以使用

而 CentOS 和 RHEL的内核中没有相关驱动。默认用devicemapper选择loop-lvm,要配置direct-lvm 给 devicemapper

Docker容器

docker run #docker create+docker start
docker start
docker stop
docker restart
docker attach #进入容器
docker rm
docker inspect #查看容器信息

Docker仓库

仓库(Repository)是集中存放镜像的地方。

注册服务器是管理仓库的具体服务器,每个服务器上可以有多个仓库,而每个仓库下面有多个镜像。

仓库可以被认为是一个具体的项目或目录.

docker search

私有仓库

Docker数据管理

数据卷

  1. 数据卷可以在容器之间共享和重用
  2. 对数据卷的修改会立马生效
  3. 对数据卷的更新,不会影响镜像
  4. 数据卷默认会一直存在,即使容器被删除
#Dockerfile  使用 VOLUME 来添加一个或者多个新的卷
docker run -it --name centOs -v /data centos /bin/bash #创建一个CentOs的容器并且把容器内部的/data目录作为数据卷挂载
docker run -it --name centOs -v /host/data:/data centos
#主机的/host/data目录挂载到容器的/data目录
docker run -v /root/datavolume:/data:ro #只读
docker rm -v name #删除数据卷

不存在垃圾回收这样的机制来处理没有任何容器引用的数据卷

数据卷容器

如果你有一些持续更新的数据需要在容器之间共享,最好创建数据卷容器。

使用数据卷,就是专门生成一个容器来挂载某个目录,该容器并不需要运行,其他容器可以使用–volumes-from命令来挂着它。可以多次使用--volumes-from从多个容器挂载多个数据卷,还可以从其他挂载了数据卷容器的容器来挂载数据卷。

可以stop数据卷容器,因为只用它的数据卷

docker run -it --name centOs -v /host/data:/data centos

docker run -it --name centOs1 --volumes-from centOs centos #授权一个容器访问另一个容器的Volume

#有容器正在挂载的数据卷永远不会被删除。
docker rm -v #移除容器的同时也会移除数据卷
docker volume ls #列出所有数据卷
docker volume prune #删除无用的数据卷

备份

sudo docker run --volumes-from dbdata -v $(pwd):/backup ubuntu tar cvf /backup/backu
p.tar /dbdata

恢复

sudo docker run -v /dbdata --name dbdata2 ubuntu /bin/bash
sudo docker run --volumes-from dbdata2 -v $(pwd):/backup busybox tar xvf
/backup/backup.tar

Docker网络

外部访问容器

-P Docker 会随机映射一个 49000~49900 的端口到内部容器开放的网络端口

-p ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort

docker port #查看映射端口配置

容器互联

--name 标记可以为容器自定义命名

--link 参数可以让容器之间安全的进行交互

sudo docker run -d --name db image
sudo docker run -d --name web --link db:db image1 #web连接到 db 容器

容器之间相互访问,需要两方面的支持。

  1. 容器的网络拓扑是否已经互联。默认情况下,所有容器都会被连接到 docker0 网桥上。
  2. 本地系统的防火墙软件 -- iptables 是否允许通过。

Docker Compose

docker-compose up
docker-compose down
docker-compose start
docker-compose stop

作业

  1. github创建hugo静态博客,加入Dockerfile
  2. 加入build.sh,run.sh
  3. 提交日报
  4. 运行:git clone && cd . && sh build.sh && sh run.sh 直接在本地加载一个hugo网站
  5. 在git push时要注意删除themes/themename/.git,要不然是一个子库,无法上传
posted @ 2018-07-18 19:54  sufferingStriver  阅读(310)  评论(0编辑  收藏  举报