之前因为出题和测试,也会些 Docker,但本文将进行一个更系统、详细的学习
安装
Linux
sudo apt-get install docker.io
MacOS
官网下载,目前最新是 Docker Desktop
Windows
需开启Hyper-V,然后下载 Docker Desktop for windows 安装
添加国内镜像源
在registry-mirrors中添加https://registry.docker-cn.com,或者使用阿里云镜像加速
0x01 拉取镜像测试与基本命令
安装好Docker后
可以使用docker search
在Docker Hub搜索需要的镜像,然后docker pull
拉取下来,就可以在docker images
里看到刚才pull的镜像了
接着使用run在新容器中使用一个命令, 比如
-t
分配一个伪TTY
-i
保持STDIN打开, 即交互模式
注意run和exec的区别,他们都是运行一个命令,但exec是在running container中使用
docker ps -n 2 -s
查看最近2个运行的容器以及大小
docker ps -a -q
列出全部运行容器ID
其他常用命令
命令 | 功能 |
---|---|
docker –help/-h | 查看帮助 |
docker attach | 直接与容器交互,但必须是running container |
docker rm | 删除容器 |
docker rmi | 删除镜像 |
docker stop [id] | 停止该容器 |
docker start [id] | 启动该容器 |
docker cp [id]:[path] [host path] | copy 容器内文件到主机 |
docker diff [id] | 查看容器储存层的改动 |
注:
docker commit 是对镜像的分层操作,改动仅发生在当前这层,每次commit,上一层的东西不会消失,会使镜像变得臃肿
0x02 编写Dockerfile
Dockerfile是由一系列命令和参数构成的脚本,这些命令应用于拉取的基础镜像并最终创建一个新的镜像,通过Dockerfile我们可以创建一个你需要的镜像,里面是包含了你要安装的软件,相当于是提前定制好要安装的拓展,执行的命令等,然后一键执行,极大地简化操作流程
当 Docker Hub 上的镜像无法直接满足需求时,通常用 Dockerfile 来定制镜像以满足不同场合的需求
FROM
Dockerfile 第一条指令必须是FROM指定基础镜像,这里的镜像一般都是能 docker search 到的
比如:
1 | FROM nginx |
Docker Hub 上一些高质量官方镜像:
nginx、redis、mongo、mysql、httpd、php、tomcat
node、openjdk、python、ruby、golang … …
基础的操作系统镜像:
ubuntu、debian、centos、fedora、alpine … ….
空白镜像:
scratch
如 :FROM scratch
, 表示不需要有操作系统提供运行时支持,接下来所写的指令将作为镜像第一层,比较适合 Linux 下静态编译的程序,如Go语言开发
RUN
RUN 其实就是执行shell命令,有点像写shell脚本
需要注意的是每一个RUN相当于commit新建一层镜像,这就容易造成上文说的镜像臃肿,要么删掉垃圾文件,要么尽量使用更少的RUN
如以下格式安装Apache+PHP+Mysql
1 | FROM ubuntu |
\
表换行,&&
连接命令
CPOPY & ADD
两者都可以将主机上的资源复制或加入到容器镜像,区别是ADD可以通过URL读取网络资源复制到镜像内,且ADD会自解压源归档文件
1 | WORKDIR /var/www/html |
####
添加.dockerignore文件让Docker忽视一些目录或文件
规则与shell的通配符类似,如:
1 | # 注释 |
构建好镜像就可以run了,比如
docker run -p 7778:80 -d php:php1
Compose
很多概念最好到《Docker —— 从入门到实践》的gitbook或Docker官方文档学习
一个容器中最好只运行一个主进程,如两个容器分别运行apache、mysql以提高整体效率,简化部署工作量。这时就需要 Compose 通过默认名为docker-compose.yml 的 Compose file 定义一组相关联的应用容器为一个项目以便管理。
docker compose file有1、2、2.x和3.x版本,部分语法支持程度不同
比如在 Compose file 中设置 networks 指定ip 要使用2.x版本,下面是我的一个示例
1 | version: '2.1' |
指定ip其实有些麻烦,可以使用link,具体见深入理解docker的link机制,其实就是通过改hosts确定容器地址,还有一些环境变量之类的功能
但有时候link不好使,也可以指定ip,桥接到主机的物理网卡
出现ERROR: Pool overlaps with other one on this address space
是因为目标网段已经存在,删除网段对应的网卡或更改subnet网段地址
1 | docker network ls |
命令 | 解释 |
---|---|
compose build | (构建yml中某个服务的镜像) |
compose ps | (查看已经启动的服务状态) |
compose kill | (停止某个服务) |
compose logs | (可以查看某个服务的log) |
compose port | (打印绑定的public port) |
compose pull | (pull服务镜像) |
compose up | (启动yml定义的所有服务) |
compose stop | (停止yml中定义的所有服务) |
compose start | (启动被停止的yml中的所有服务) |
compose kill | (强行停止yml中定义的所有服务) |
compose rm | (删除yml中定义的所有服务) |
compose restart | (重启yml中定义的所有服务) |
compose scale | (扩展某个服务的个数,可以向上或向下) |
compose migrate-to-labels | (这个没有实际尝试。根据介绍是将服务从1.2迁移到1.3带labels的版本。docker之前不支持label) |
compose version | (查看compose的版本) |
Reference: