Docker学习笔记
Docker简介
概念
Docker是基于Go语言实现的云开源项目,是基于Linux的多项开源技术提供高效、敏捷和轻量级的容器方案。创建于2013年初。自从开源后就受到了广泛的关注,从长远的眼光来看,Docker是未来虚拟化的一个发展的趋势。带来了更轻量快捷的的体验,一台主机可以同时运行数千个Docker容器,而且在性能上几乎不会损耗。
优势
Docker 是一个用于开发,交付和运行应用程序的开放平台。Docker 使您能够将应用程序与基础架构分开,从而可以快速交付软件。借助 Docker,您可以与管理应用程序相同的方式来管理基础架构。通过利用 Docker 的方法来快速交付,测试和部署代码,您可以大大减少编写代码和在生产环境中运行代码之间的延迟。
1、快速,一致地交付您的应用程序
Docker 允许开发人员使用您提供的应用程序或服务的本地容器在标准化环境中工作,从而简化了开发的生命周期。
容器非常适合持续集成和持续交付(CI / CD)工作流程,请考虑以下示例方案:
- 您的开发人员在本地编写代码,并使用 Docker 容器与同事共享他们的工作。
- 他们使用 Docker 将其应用程序推送到测试环境中,并执行自动或手动测试。
- 当开发人员发现错误时,他们可以在开发环境中对其进行修复,然后将其重新部署到测试环境中,以进行测试和验证。
- 测试完成后,将修补程序推送给生产环境,就像将更新的镜像推送到生产环境一样简单。
2、响应式部署和扩展
Docker 是基于容器的平台,允许高度可移植的工作负载。Docker 容器可以在开发人员的本机上,数据中心的物理或虚拟机上,云服务上或混合环境中运行。
Docker 的可移植性和轻量级的特性,还可以使您轻松地完成动态管理的工作负担,并根据业务需求指示,实时扩展或拆除应用程序和服务。
3、在同一硬件上运行更多工作负载
Docker 轻巧快速。它为基于虚拟机管理程序的虚拟机提供了可行、经济、高效的替代方案,因此您可以利用更多的计算能力来实现业务目标。Docker 非常适合于高密度环境以及中小型部署,而您可以用更少的资源做更多的事情。
Docker安装
Docker安装方式
- 使用官方安装脚本自动安装
- 通过手动安装
Ubuntu/CentOS安装Docker
Ubuntu/CentOS Linux系统耳熟能详的操作系统,这里就不在多做介绍。
使用脚本方式安装
1 | curl -fsSL get.docker.com -o get-docker.sh |bash -s docker --mirror Aliyun |
或者也可以使用国内 daocloud 一键安装命令:
1 | curl -sSL https://get.daocloud.io/docker | sh |
Kali/Debian安装Docker
Kali是基于Debian封装的,按理说两者安装方法大同小异。但是Kali Linux安装Docker用网上那个一键安装脚本有点问题无法正常的安装报错如下
所以这里采用了手动安装的方法
1 | # 添加Docker PGP密钥 |
一些重要命令
1 | sudo systemctl enable docker #设置开机自启 |
Windows安装
win7/win8 系统
win7、win8 等需要利用 docker toolbox 来安装,国内可以使用阿里云的镜像来下载,下载地址:http://mirrors.aliyun.com/docker-toolbox/windows/docker-toolbox/或者使用GitHub下载:https://github.com/docker/toolbox/releases
安装比较简单,双击运行,点下一步即可,可以勾选自己需要的组件,安装成功后桌边会出现三个图标,如下图所示:
点击 Docker QuickStart 图标来启动 Docker Toolbox 终端。
如果系统显示 User Account Control 窗口来运行 VirtualBox 修改你的电脑,选择 Yes。然后就可以在终端里面进行使用最终成功截图如下
win10安装
目前Docker有专门的安装包,但是需要开启Hyper-V
开启Hyper-V
打开控制面板然后点击程序点击程序和功能下的启用或关闭Windows功能
选中Hyper-V
然后访问 https://www.docker.com/get-started,注册一个账号,然后登录。点击 Get started with Docker Desktop,并下载 Windows 的版本,如果你还没有登录,会要求注册登录。
安装完成之后会让你重启计算机
Docke优化
Docker国内加速器
Linux下
不替换源对话,docker pull 拉去镜像对速度实在太龟速了,如果你很佛系对话可以不进行更换
1 | # 编辑这个文件,如果没有对话就创建这个文件 |
内容如下:
1 | { |
这里我使用对是国内163网易源,其他源可以自行百度替换。
配置完成后重启服务才可以生效:
1 | sudo systemctl daemon-reload |
Windows下
在电脑任务栏找到Docker小图标,鼠标右键点击settings
Docker入门
启动一个ubuntu容器
1 | docker run -it ubuntu /bin/bash |
运行命令后会进入容器之内,下面设置成国软件源
1 | cp /etc/apt/sources.list /etc/apt/sources.list.bak |
然后命令行执行apt-get update &&apt-get upgrade -y
,退出容器有两种方法直接在命令行输入exit
或者使用crtl + p
然后再ctrl + q
退出容器。使用前面方式启动的容器,使用前者退出会让容器停止🛑运行。后者方法退出并不会导致容器停止🛑运行。后面将会介绍如何创建一个长期运行的容器!
退出了上面创建的容器,若重新使用的话需要使用docker attach 容器ID|容器名
或者docker exec -it 容器ID|容器名 /bin/bash
来连接到容器,前提是容器时启动运行的状态使用如下命令来启动容器
1 | docker start 容器ID/容器名 |
Docker连接后台运行容器
注意这里的|
是或者的意思也就是说我们可以使用容器名或者容器ID来启动后台运行的容器
使用exec命令
1 | docker exex -it 容器ID|容器名 /bin/bash |
exec
命令可以随意退出
使用attach命令
1 | docker attach -it 容器ID|容器名 |
attach
命令不能直接使用exit或者CTRL +D
退出,这里需要使用CTRL +P
然后CTRL +Q
退出
创建守护式容器
1 | docker run -itd --name daemon_dave ubuntu /bin/bash -c "while true; do echo hello world; sleep 1; done" |
这里使用了-d
参数,作用是将docker容器放到后台运行。还在里面使用了一个while循环一直打印hello world,-c
作用是执行后面的命令。并且使用--name
对容器进行了命名daemon_dave即是容器的名字。
获取容器日志
1 | docker logs daemon_dave |
Docker会输出日志项并返回,也可以使用-f
参数来监控跟踪日志它与tail -f
命令十分相似
1 | docker logs -f daemon_dave |
注意🎈 可以通过CTRL + c 退出日志监控
其他操作🧨
1 | docker logs --tail 10 daemon_dave #获取日志后10行内容 |
Docker日志驱动
1 | docker run --log-driver="syslog" --name daemon_syslog -d ubuntu /bin/bash -c "while true; do echo hello world; sleep 1; done" |
该命令将禁用docker logs
命令,并且将日志输出都重定向到syslog
因此docker logs命令并不会输出日志内容
查看容器内进程
1 | docker top daemon_dave |
Docker统计信息
1 | docker stats #统计所有容器 |
docker stats
命令可以查看一个或者多个容器的统计信息,我们可以查看到它们的CPU、内存、网络I/O、存储I/O的性能和指标,可以快速监控一台主机上的容器。
在容器内部运行进程
docker exec
命令可以在容器内部额外启动新进程,可在容器中进行后台任务或交互式任务。
在容器中运行后台任务
1 | docker exec -d daemon_dave touch /test.txt |
在daemon_dave容器中的/
目录下新建了一个名字为test.txt
的空文件
在容器中运行交互命令
这个命令上面其实以及提到过了,这里再详细讲下
1 | docker exec -it daemon_dave /bin/bash |
通过命令进入到了daemon_dave
这个容器之中,可以执行要执行的命令。比如ls
命令,通过ls
命令可以看到刚才新创建的test.txt文件。这里-t
和-i
参数作用是为执行的进程创建TTY并捕捉STDIN在daemon_dave容器内部创建了一个新的bash会话。
自动重启容器
因为有种种原因会导致容器停止运行,如果容器较少的话还好使用命令启动即可但是容器较多的话启动起来就比较麻烦。所以可以使用如下命令来设置容器自动启动
1 | docker run --restart=always --name test -d ubuntu /bin/sh |
--restart=always
无论容器的退出代码是什么,docker都会自动启动该容器。除了always还可以设置成on-failure
但是这样只有在容器退出代码为非0值的时候才会自动重启并且还接受一个可选的重启次数。
1 | docker run --restart=on-failure:5 --name test2 -d ubuntu /bin/sh |
深入容器
可以通过docker inspect
命令来获取容器的更多信息
1 | docker inspect daemon_dave |
可以通过-f或者–format命令来选定查看结果
1 | docker inspect --format='{{.State.Running}}' daemon_dave #查询容器运行状态 |
Docker镜像
列出镜像
1 | docker images #列出镜像 |
拉取镜像
1 | docker pull ubuntu:18.04 #拉取Ubuntu18.04的镜像 |
可以看出有两个不同的Ubuntu镜像,为了区分docker提供了一个不同的标签来代表不同的版本。当运行
docker run
命令时默认使用的是带有latest标签的镜像,docker pull
拉取镜像时默认也是拉取下载latest标签的镜像
查找镜像
1 | docker search kali |
命令执行后会出现如下结果
这里NAME
一列代表的是仓库名,descriptionDESCRIPTION
是镜像的描述,STARS
代表的是镜像的受欢迎程度,OFFICAL
表示是否官方,ATUOMATED
表示这个镜像是否由Docker Hub的自动构建流程创建的。我们可以根据自己的需求自行pull镜像
构建镜像
镜像的分层
镜像分层:Docker的镜像通过联合文件系统将各层文件系统叠加在一起
bootfs:用于系统引导的文件系统,包括bootloader和kernel,容器启动完成后会被卸载以节省内存资源
rootfs:位于bootfs之上,表现为dockers容器跟文件系统
传统模式中,系统启动时,内核挂在rootfs时会首相将其挂载为只读模式,完整性自建完成后将其挂载为读写模式
docker中,rootfs由内核挂载为只读模式,而后通过ufs技术挂载一个可写层。
登录到Docker Hub
1 | docker login |
1.容器>镜像Docker commit
1 | docker commit 容器名|容器ID 镜像名称:Tag |
然后可以使用如下命令来运行新的镜像
1 | docker run -itd --name Name 镜像名称 /bin/bash |
创建一个定制容器
1 | docker run -it --name MyUbuntu ubuntu /bin/bash |
然后通过exit
从容器退出
提交定制容器
1 | docker commit MyUbuntu 607qwq/python3:One |
docker commit
执行命令时也可以加两个参数 -m “A image pyhon3”
即指定新创建的镜像的提交信息,-a "607qwq"
用来列出该镜像作者的信息。
2.Dockerfile
创建一个实例仓库
1 | mkdir static_web |
编辑Dockerfile文件
内容如下
1 | #Version:0.0.1 |
Dcokerfile是由一系列的指令和参数组成的,每条指令都必须是大写字母,并且后面要带上参数。Dockerfile中的指令是按照从上往下的流程顺序执行的。
- Docker从基础镜像运行一个容器
- 执行一条指令,对容器做出相应的修改
- 执行类似于
docker commit
的操作,提交一个新的镜像层 - Dcoker再基于刚提交的镜像运行一个新的容器
- 执行Dockerfile中的下一条指令,直到所有指令都执行完毕
注意如果由于某些原因(某条指令失败)没有正常的结束,但是可以得到一个可以使用的镜像。可以基于这个镜像运行一个交互式的容器,然后可以进行调试。
然后通过如下命令来构建新的镜像
1 | docker build -t 镜像名:标签 . |
1 | docker build -t="607qwq/web_static" . |
如果没有打上标签的话,构建的镜像默认标签是latest
,打标签的话则是你自己所打上的标签。
但是呢基于上述的Dockerfile
构建镜像的过程中会发现更新源和安装nginx的过程有些缓慢,所以需要把软件源修改为国内源来加速
方法一
我们可以通过sed
命令来对sources.list
文件进行修改
1 | sed -i "s/archive.ubuntu.com/mirrors.aliyun.com/g" /etc/apt/sources.list |
上面命令意思其实就是把sources.list的文字替换
方法二
在static_web
目录下新建一个sources.list
文件,并且将阿里的源复制到文件之中,然后保存文件Ubuntu20.04版本的源主要内容如下
1 | deb http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse |
对上述两种方法进行测试
方法一的Dockerfile文件
1 | #Version:0.0.1 |
测试
1 | docker build -t="607qwq/web_static1" . |
方法二的Dockerfile文件
1 | #Version:0.0.1 |
测试
1 | docker build -t="607qwq/web_static2" . |
从Git仓库构建镜像
1 | ssh-keygen |
New SSH key然后执行下面命令
1 | git -T git@github.com |
在CentOS7中上述过程中可能会报如下错误❌
这个问题是因为CentOS中的git版本太老所导致的
1 | [root@kvm staic_web]# git version |
事实上其实CentOS系统上各种软件版本都”巨陈旧”,下面采用源码编译安装的方式来更新Git
卸载旧版本git
1 | yum remove git -y |
安装依赖
1 | yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel asciidoc -y |
编译安装git
1 | wget https://mirrors.edge.kernel.org/pub/software/scm/git/git-2.19.5.tar.xz |
验证版本
1 | [root@kvm git]# git version |
然后再运行上面的命令就不会再报错了
1 | docker build -t="607qwq/static_web:git" git@github.com:X1angfeng/docker |
这里Docker假设这个Git仓库的根目录下存在Dockerfile文件
使用参数构建
从Docker 1.5后,可以通过-f
指定一个区别于标准Dockerfile的构建源的位置
1 | cd staic_web/ |
Dockerfile和构建缓存
由于每一步的构建过程都会将结果提交成为一个镜像,它会将之前的镜像层看作缓存。Docker会将之前的构建创建的镜像当做缓存并作为新的开始点。就像下图结果所示一样IMAGE ID 是一样的
然而有些时候在需要确保在构建过程中不会使用缓存,那么就需要使用docker build --no-cache
来构建镜像
忽略Dockerfile的构建缓存
1 | docker build --no-cache -t="607qwq/static_web:no_cache" . |
基于构建缓存的Dockerfile模板
Fedora系统的Dockerfile
1 | FROM fedora:20 |
Ubuntu系统的Dockerfile模板
1 | FROM ubuntu:19.04 |
有了这些模板,如果要刷新一个构建,只需要修改ENV指令中的日期。Docker在命中ENV指令时开始重置这个缓存,也就是说RUN apt-get -qq update
这条指令会被再次执行,包缓存也将会刷新为最新内容
Docker网络端口映射
我们创建了一个 python 应用的容器。
1 | [root@master ~]# docker run -d -P training/webapp python app.py |
另外,我们可以指定容器绑定的网络地址,比如绑定 127.0.0.1。
我们使用 -P 参数创建一个容器,使用 docker ps 可以看到容器端口 5000 绑定主机端口 32768。
1 | [root@master ~]# docker ps |
我们也可以使用 -p 标识来指定容器端口绑定到主机端口。
两种方式的区别是:
- -P :**是容器内部端口随机**映射到主机的高端口。
- -p : 是容器内部端口绑定到指定的主机端口。
1 | [root@master ~]# docker run -d -p 5000:5000 training/webapp python app.py |
另外,我们可以指定容器绑定的网络地址,比如绑定 127.0.0.1。
1 | [root@master ~]# docker run -d -p 127.0.0.1:5001:5000 training/webapp python app.py |
这样我们就可以通过访问 127.0.0.1:5001 来访问容器的 5000 端口。
上面的例子中,默认都是绑定 tcp 端口,如果要绑定 UDP 端口,可以在端口后面加上 /udp。
1 | [root@master ~]# docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py |
docker port 命令可以让我们快捷地查看端口的绑定情况。
1 | [root@master ~]# docker port frosty_chaum 5000 |
Docker搭建常用服务
Docker搭建wordpress
1 | docker run --name db -env MYSQL_ROOT_PASSWD=123456 -d mariadb #安装mariadb |
Docker搭建sqli-labs环境
1 | docker pull acgpiano/sqli-labs |
Docker搭建Portainer图形管理工具
1 | docker search portainer |
Docker搭建hexo
1 | docker search hexo |
docker-composer
1 | curl -L https://github.com/docker/compose/releases/download/1.25.0-rc2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose |
wordpress.yaml
1 | version: '2' |
Docker使用常见的系统
docker使用Ubuntu
1 | docker run --name MyUbuntu -itd ubuntu /bin/bash |
docker使用CentOS
1 | docker run --name MyCentOS -itd centos /bin/bash |
常用命令
1 | docker info #守护进程的系统资源设置 |
docker删除全部容器命令
1 | docker rm -f $(docker ps -a -q) |