Docker学习笔记
https://yeasy.gitbooks.io/docker_practice/content/
一 环境搭建
Ubuntu安装
.添加软件源的GPG密钥 curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add - .添加Docker软件源 sudo add-apt-repository \ "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu \ $(lsb_release -cs) \ stable" .安装软件 sudo apt-get update Sudo apt-get install docker-ce
Centos安装
.安装依赖包 sudo yum install -y yum-utils device-mapper-persistent-data lvm2 .添加软件源 sudo yum-config-manager \ --add-repo \ https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo .安装docker CE sudo yum makecache fast sudo yum install docker-ce
修改加速器服务
.vim /etc/default/docker DOCKER_OPTS="--registry-mirror=https://jxus37ad.mirror.aliyuncs.com" .sudo service docker restart
二 镜像制作
镜像构成
当我们运行一个容器的时候(如果不使用卷的话),我们做的任何文件修改都会被记录于容器存储层里。而 Docker 提供了一个 docker commit 命令,可以将容器的存储层保存下来成为镜像。换句话说,就是在原有镜像的基础上,再叠加上容器的存储层,并构成新的镜像。以后我们运行这个新镜像的时候,就会拥有原有容器最后的文件变化。
使用commit制作镜像
docker commit 的语法格式为: docker commit [选项] <容器ID或容器名> [<仓库名>[:<标签>]] docker run --name webserver -d -p : nginx docker commit --author "tla001" --message "edit page" webserver nginx:v2
docker commit 命令除了学习之外,还有一些特殊的应用场合,比如被入侵后保存现场等。但是,不要使用 docker commit 定制镜像,定制行为应该使用 Dockerfile 来完成。造成镜像臃肿
使用Dockerfile定制镜像
Dockerfile 是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。
除了选择现有镜像为基础镜像外,Docker 还存在一个特殊的镜像,名为 scratch。这个镜像是虚拟的概念,并不实际存在,它表示一个空白的镜像。如果你以 scratch 为基础镜像的话,意味着你不以任何镜像为基础,接下来所写的指令将作为镜像第一层开始存在。
指令详解
RUN COPY 注意上下文目录 ADD 高级的复制,原路径可以是URL CMD exec 格式:CMD ["可执行文件", "参数1", "参数2"...] 在指令格式上,一般推荐使用 exec 格式,这类格式在解析时会被解析为 JSON 数组,因此一定要使用双引号 ",而不要使用单引号 CMD [ "sh", "-c", "echo $HOME" ] 容器中的应用都应该以前台执行,对于容器而言,其启动程序就是容器应用进程,容器就是为了主进程而存在的,主进程退出,容器就失去了存在的意义,从而退出,其他辅助进程不是它关系你的东西 ENTRYPOINT 入口点 ENV 设置环境变量 ENV <key1>=<value1> <key2>=<value2>... 下列指令可以支持环境变量展开: ADD、COPY、ENV、EXPOSE、LABEL、USER、WORKDIR、VOLUME、STOPSIGNAL、ONBUILD。 ARG构建参数 ARG <参数名>[=<默认值>] 构建参数和 ENV 的效果一样,都是设置环境变量。所不同的是,ARG 所设置的构建环境的环境变量,在将来容器运行时是不会存在这些环境变量的 该默认值可以在构建命令 docker build 中用 --build-arg <参数名>=<值> 来覆盖 VOLUME 定义匿名卷 VOLUME ["<路径1>", "<路径2>"...] 在 Dockerfile 中,我们可以事先指定某些目录挂载为匿名卷,这样在运行时如果用户不指定挂载,其应用也可以正常运行,不会向容器存储层写入大量数 EXPOSE 声明运行时容器提供服务的端口 要将 EXPOSE 和在运行时使用 -p <宿主端口>:<容器端口> 区分开来。-p,是映射宿主端口和容器端口,换句话说,就是将容器的对应端口服务公开给外界访问,而 EXPOSE 仅仅是声明容器打算使用什么端口而已,并不会自动在宿主进行端口映射 WORKDIR 指定工作目录 USER指定当前用户 USER 指令和 WORKDIR 相似,都是改变环境状态并影响以后的层。WORKDIR 是改变工作目录,USER 则是改变之后层的执行 RUN, CMD 以及 ENTRYPOINT 这类命令的身份
其它制作镜像的方法
从 rootfs 压缩包导入
docker import [选项] <文件>|<URL>|- [<仓库名>[:<标签>]]
保存镜像
docker save alpine | gzip > alpine-latest.tar.gz
导入镜像
docker load -i alpine-latest.tar.gz
如果我们结合这两个命令以及 ssh 甚至 pv 的话,利用 Linux 强大的管道,我们可以写一个命令完成从一个机器将镜像迁移到另一个机器,并且带进度条的功能:
docker save <镜像名> | bzip2 | pv | ssh <用户名>@<主机名> 'cat | docker load'
三 操作容器
Docker pull docker pull centos Docker run Docker run -ti centos bash Docker images 虚悬镜像docker images -f dangling=true Docker rmi 删除镜像 Docker logs id 查看日志 Docker stop id 删除容器 Docker attach 连接容器 Docker rm 删除容器 Docker search 搜索镜像 docker export 7691a814370e > ubuntu.tar 导出容器快照 cat ubuntu.tar | sudo docker import - test/ubuntu:v1. 导入容器快照 docker import http://example.com/exampleimage.tgz example/imagerepo 导入URL
Docker load与 Docker import的区别
用户既可以使用docker load来导入镜像存储文件到本地镜像库,也可以使用docker import来导入一个容器快照到本地镜像库。这两者的区别在于容器快照文件将丢失所有的历史记录和元数据信息(即仅仅保存容器当时的快照状态),而镜像存储文件将保存完整记录,体积也较大。此外,从容器快照文件导入时,可以重新指定标签等元数据信息
四 数据卷
数据卷是一个可供一个或多个容器使用的特殊目录,它绕过 UFS,可以提供很多有用的特性:
- 数据卷可以在容器之间共享和重用
- 对数据卷的修改会立马生效
- 对数据卷的更新,不会影响镜像
- 数据卷默认会一直存在,即使容器被删除
*注意:数据卷的使用,类似于 Linux 下对目录或文件进行 mount,镜像中的被指定为挂载点的目录中的文件会隐藏掉,能显示看的是挂载的数据卷。
添加数据卷 Docker run -v 删除数据卷 Docker rm -v 查看数据卷 Docker inspect id
数据卷容器
就是一个正常的容器,专门用来提供数据卷供其他容器挂在的
sudo docker run -d -v /dbdata --name dbdata training/postgres echo Data-only container for postgres
sudo docker run -d --volumes-from dbdata --name db1 training/postgres
sudo docker run -d --volumes-from dbdata --name db2 training/postgres
数据库容器
docker run -d --name db training/postgres
创建新容器连接到db
docker run -d -P --name web --link db:db training/webapp python app.py
--link 参数的格式为 --link name:alias,其中 name 是要链接的容器的名称,alias 是这个连接的别名。
五 网络
-p hostport:dockerport 实现端口映射
Docker与宿主机同一网段的实现
sudo docker network create mynet --subnet 219.216.88.0/24 --gateway 219.216.88.254 -o parent eth0
sudo docker run -ti -d --name webserver --net mynet --ip 219.216.88.111 nginx:v3 bash
六 Dockfile实战
基于centos7搭建nginx镜像
1.准备工作
pull centos
mkdir mynginx
cd mynginx
下载nginx源码
http://nginx.org/download/nginx-1.12.1.tar.gz
下载pcre源码
ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.38.tar.gz
将源码拷贝到mynginx目录
2.创建Dockerfile
FROM centos MAINTAINER tla001 WORKDIR /usr/local/src/ COPY pcre-8.38.tar.gz . COPY nginx-1.12..tar.gz . RUN useradd -s /sbin/nologin www && yum install vim gcc gcc-c++ openssl openssl-devel net-tools -y RUN tar zxf pcre-8.38.tar.gz && cd pcre-8.38 && ./configure --prefix=/usr/local/pcre && make && make install RUN tar zxf nginx-1.12..tar.gz && cd nginx-1.12. && ./configure --prefix=/usr/local/nginx \ --user=www \ --group=www \ --with-http_ssl_module \ --with-http_stub_status_module \ --with-file-aio \ --with-http_dav_module \ --with-pcre=/usr/local/src/pcre-8.38 && make && make install && chown -R www. /usr/local/nginx #COPY nginx.conf /usr/local/nginx/conf/nginx.conf #ADD vhosts /usr/local/nginx/conf/vhosts ADD run.sh /root/run.sh RUN chmod /root/run.sh CMD ["/root/run.sh"] EXPOSE
3.编译
sudo docker build -t nginx:v4 .
4.运行
sudo docker network create mynet --subnet 219.216.88.0/24 --gateway 219.216.88.1 -o parent=eth0
sudo docker run -ti -d --name webserver --net mynet --ip 219.216.88.111 nginx:v4