Docker学习笔记

| 文章字数:6.3k | 阅读时长:27min
这是一篇更新于 302 天前的文章,其中的信息可能已经有所发展或是发生改变。

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安装方式

  1. 使用官方安装脚本自动安装
  2. 通过手动安装

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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 添加Docker PGP密钥
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -

# 配置docker apt源 我这里用的国内阿里云的docker下载源
echo 'deb https://mirrors.aliyun.com/docker-ce/linux/debian buster stable'> /etc/apt/sources.list.d/docker.list

# 更新apt源
apt update

# 如果之前安装了docker的话 这里得卸载旧版本docker
apt remove docker docker-engine docker.io

# 安装docker
apt install docker-ce

# 查看版本
docker version

一些重要命令

1
2
3
4
sudo systemctl enable docker  #设置开机自启
sudo systemctl start docker #启动docker
sudo systemctl start docker #停止docker运行
sudo systemctl status docker #查看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
2
# 编辑这个文件,如果没有对话就创建这个文件
vim /etc/docker/daemon.json

内容如下:

1
2
3
4
5
{
"registry-mirrors": [
"http://hub-mirror.c.163.com"
]
}

这里我使用对是国内163网易源,其他源可以自行百度替换。
配置完成后重启服务才可以生效:

1
2
sudo systemctl daemon-reload
sudo systemctl restart docker

Windows下

在电脑任务栏找到Docker小图标,鼠标右键点击settings

Docker入门

启动一个ubuntu容器

1
docker run -it ubuntu /bin/bash

运行命令后会进入容器之内,下面设置成国软件源

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
cp /etc/apt/sources.list /etc/apt/sources.list.bak

cat > /etc/apt/sources.list <<EOF
deb http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse

EOF

然后命令行执行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
2
3
4
5
docker logs --tail 10  daemon_dave #获取日志后10行内容

docker logs --tail 0 -f daemon_dave #跟踪日志最新内容而不读取整个日志文件

docker logs --tail 0 -ft daemon_dave #给每条日志加上时间戳

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
2
docker stats #统计所有容器
docker stats daemon_dave daemon_syslog #统计部分容器

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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
docker inspect daemon_dave

##返回结果如下
[
{
"Id": "107ca54617a5eeb77855da07cc4e0270460b30b84b94e2905759f98c283ac4b0",
"Created": "2020-10-05T07:48:27.651926723Z",
"Path": "/bin/bash",
"Args": [
"-c",
"while true; do echo hello world; sleep 1; done"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 6860,
"ExitCode": 0,
"Error": "",
"StartedAt": "2020-10-05T07:48:28.254011202Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:9140108b62dc87d9b278bb0d4fd6a3e44c2959646eb966b86531306faa81b09b",
"ResolvConfPath": "/var/lib/docker/containers/107ca54617a5eeb77855da07cc4e0270460b30b84b94e2905759f98c283ac4b0/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/107ca54617a5eeb77855da07cc4e0270460b30b84b94e2905759f98c283ac4b0/hostname",
"HostsPath": "/var/lib/docker/containers/107ca54617a5eeb77855da07cc4e0270460b30b84b94e2905759f98c283ac4b0/hosts",
"LogPath": "/var/lib/docker/containers/107ca54617a5eeb77855da07cc4e0270460b30b84b94e2905759f98c283ac4b0/107ca54617a5eeb77855da07cc4e0270460b30b84b94e2905759f98c283ac4b0-json.log",
"Name": "/daemon_dave",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "default",
"PortBindings": {},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": null,
"CapDrop": null,
"Capabilities": null,
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "private",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"ConsoleSize": [
0,
0
],
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": [],
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DeviceCgroupRules": null,
"DeviceRequests": null,
"KernelMemory": 0,
"KernelMemoryTCP": 0,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": false,
"PidsLimit": null,
"Ulimits": null,
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"MaskedPaths": [
"/proc/asound",
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware"
],
"ReadonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/ddc029b202312282e74da32be4b024606bdae5f6bdf445ad7d2b4a777ac8e1c6-init/diff:/var/lib/docker/overlay2/010a2fe483f180dd6eb1b5f11a44352d5fcb8e95c4a36babc96c777d46e2384d/diff:/var/lib/docker/overlay2/2e7fd234e19b67421105e01fb03dd4fdb4ce2a780a9b9b3e2d72f0ac8371fb3f/diff:/var/lib/docker/overlay2/39862fd871fa5ad1c9c6c9bf1a20743e8482b0a04506c1ed1a84d949402140b9/diff",
"MergedDir": "/var/lib/docker/overlay2/ddc029b202312282e74da32be4b024606bdae5f6bdf445ad7d2b4a777ac8e1c6/merged",
"UpperDir": "/var/lib/docker/overlay2/ddc029b202312282e74da32be4b024606bdae5f6bdf445ad7d2b4a777ac8e1c6/diff",
"WorkDir": "/var/lib/docker/overlay2/ddc029b202312282e74da32be4b024606bdae5f6bdf445ad7d2b4a777ac8e1c6/work"
},
"Name": "overlay2"
},
"Mounts": [],
"Config": {
"Hostname": "107ca54617a5",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": true,
"OpenStdin": true,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/bash",
"-c",
"while true; do echo hello world; sleep 1; done"
],
"Image": "ubuntu",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "95120af8027838df575be682be34a3143daedb8e7b85f9e9c1d58afb11fb7cf7",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {},
"SandboxKey": "/var/run/docker/netns/95120af80278",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "3b507ecf327fcf3db1fd8658d4e2ad01520ba62df0b2ee88a11a7aeea97944a4",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.5",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:05",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "1477a7857a227b36c529b5a66182c401e9e6d82ff5b5789fee5e0b1d99458c1d",
"EndpointID": "3b507ecf327fcf3db1fd8658d4e2ad01520ba62df0b2ee88a11a7aeea97944a4",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.5",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:05",
"DriverOpts": null
}
}
}
}
]

可以通过-f或者–format命令来选定查看结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
docker inspect --format='{{.State.Running}}' daemon_dave #查询容器运行状态

true


docker inspect --format='{{.NetworkSettings.IPAddress}}' daemon_dave #查询容器IP地址

172.17.0.5


#同时查询多个容器
docker inspect --format='{{.Name}} {{.State.Running}} {{.NetworkSettings.IPAddress}}' daemon_dave daemon_syslog

/daemon_dave true 172.17.0.5
/daemon_syslog true 172.17.0.6

Docker镜像

列出镜像

1
docker images #列出镜像

拉取镜像

1
2
docker pull ubuntu:18.04 #拉取Ubuntu18.04的镜像
docker images |grep ubuntu #查看Ubuntu镜像

可以看出有两个不同的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
2
3
4
5
docker login

Username: 607qwq
Password: #密码不可见
Login Succeeded

1.容器>镜像Docker commit

1
docker commit 容器名|容器ID 镜像名称:Tag

然后可以使用如下命令来运行新的镜像

1
docker run -itd --name Name 镜像名称 /bin/bash
创建一个定制容器
1
2
3
4
docker run -it  --name MyUbuntu ubuntu /bin/bash

#进入容器之后换源,然后安装一些自己要用的软件我这里作为测试安装的是python3环境
apt-get update &&apt-get install python3 -y

然后通过exit从容器退出

提交定制容器
1
2
3
4
5
6
7
8
9
10
11
12
docker commit MyUbuntu 607qwq/python3:One
sha256:99789bf8c261f2e9d15b949589b3dbaa7c30a66b3325c77804479cfabbdfb1dd

#然后使用docker images命令查看新创建的镜像
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
607qwq/python3 One 99789bf8c261 53 seconds ago 161MB

#使用docker run 命令从新构建的镜像创建一个新的容器
docker run -it MyUbuntu /bin/bash

#进入容器之后即可使用python

docker commit执行命令时也可以加两个参数 -m “A image pyhon3”即指定新创建的镜像的提交信息,-a "607qwq"用来列出该镜像作者的信息。

2.Dockerfile

创建一个实例仓库
1
2
3
mkdir static_web
cd static_web
touch Dockerfile

编辑Dockerfile文件内容如下

1
2
3
4
5
6
7
8
9
#Version:0.0.1
FROM ubuntu:latest
MAINTAINER 607qwq "i@1l.fit"

RUN apt-get update&&apt-get install nginx -y

RUN echo 'HI,this is your first test in docker container'>/usr/share/nginx/html/index.html

EXPOSE 80

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
2
sed -i "s/archive.ubuntu.com/mirrors.aliyun.com/g" /etc/apt/sources.list
&& sed -i "s/security.ubuntu.com/mirrors.aliyun.com/g" /etc/apt/sources.list

上面命令意思其实就是把sources.list的文字替换

方法二

static_web目录下新建一个sources.list文件,并且将阿里的源复制到文件之中,然后保存文件Ubuntu20.04版本的源主要内容如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
deb http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse
对上述两种方法进行测试

方法一的Dockerfile文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#Version:0.0.1
FROM ubuntu:latest

#author info

MAINTAINER 607qwq "i@1l.fit"

RUN sed -i "s/archive.ubuntu.com/mirrors.aliyun.com/g" /etc/apt/sources.list&& sed -i "s/security.ubuntu.com/mirrors.aliyun.com/g" /etc/apt/sources.list

RUN apt-get update&&apt-get install nginx -y

RUN echo 'HI,this is your first test in docker container'>/usr/share/nginx/html/index.html

#指定端口
EXPOSE 80

测试

1
2
docker build -t="607qwq/web_static1" .
docker run -d -p 8080:80 --name test1 607qwq/web_static1 nginx -g "daemon off;"

方法二的Dockerfile文件

1
2
3
4
5
6
7
8
9
10
11
#Version:0.0.1
FROM ubuntu:latest
MAINTAINER 607qwq "i@1l.fit"

ADD sources.list /etc/apt/

RUN apt-get update&&apt-get install nginx -y

RUN echo 'HI,this is your first test in docker container'>/usr/share/nginx/html/index.html

EXPOSE 80

测试

1
2
docker build -t="607qwq/web_static2" .
docker run -d -p 8081:80 --name test2 607qwq/web_static2 nginx -g "daemon off;"
从Git仓库构建镜像
1
2
3
4
5
ssh-keygen

cat ~/.ssh/id_rsa.pub

把内容复制到github的SSH keys

New SSH key然后执行下面命令

1
2
3
git -T git@github.com

docker build -t="607qwq/static_web:git" git@github.com:X1angfeng/docker.git

在CentOS7中上述过程中可能会报如下错误❌

这个问题是因为CentOS中的git版本太老所导致的

1
2
3
4
[root@kvm staic_web]# git version
git version 1.8.3.1
[root@kvm staic_web]# cat /etc/redhat-release
CentOS Linux release 7.8.2003 (Core)

事实上其实CentOS系统上各种软件版本都”巨陈旧”,下面采用源码编译安装的方式来更新Git

卸载旧版本git

1
yum remove git -y

安装依赖

1
2
yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel asciidoc -y
yum install gcc perl-ExtUtils-MakeMaker -y

编译安装git

1
2
3
4
5
6
7
8
9
wget https://mirrors.edge.kernel.org/pub/software/scm/git/git-2.19.5.tar.xz
tar -xvf git-2.19.5.tar.xz -C /usr/local
cd /usr/local &&mv git-2.19.5 git &&cd git

./configure
make && make install

echo "export PATH=$PATH:/usr/local/git/bin" >> /etc/profile
source /etc/profile

验证版本

1
2
[root@kvm git]# git version
git version 2.19.5

然后再运行上面的命令就不会再报错了

1
2
docker build -t="607qwq/static_web:git" git@github.com:X1angfeng/docker
docker images

这里Docker假设这个Git仓库的根目录下存在Dockerfile文件

使用参数构建

从Docker 1.5后,可以通过-f指定一个区别于标准Dockerfile的构建源的位置

1
2
3
cd staic_web/
cp Dockerfile ../test
docker build -t="607qwq/web_test:test" -f /root/Docker/test .

Dockerfile和构建缓存

由于每一步的构建过程都会将结果提交成为一个镜像,它会将之前的镜像层看作缓存。Docker会将之前的构建创建的镜像当做缓存并作为新的开始点。就像下图结果所示一样IMAGE ID 是一样的

然而有些时候在需要确保在构建过程中不会使用缓存,那么就需要使用docker build --no-cache来构建镜像

忽略Dockerfile的构建缓存

1
docker build --no-cache -t="607qwq/static_web:no_cache" .

基于构建缓存的Dockerfile模板

Fedora系统的Dockerfile
1
2
3
4
FROM fedora:20
MAINTAINER 607qwq "i@1l.fit"
ENV REFRESHED_AT 2020-10-10
RUN yum -q makecache

Ubuntu系统的Dockerfile模板

1
2
3
4
FROM ubuntu:19.04
MAINTAINER 607qwq "i@1l.fit"
ENV REFRESHED_AT 2020-10-10
RUN apt-get -qq update

有了这些模板,如果要刷新一个构建,只需要修改ENV指令中的日期。Docker在命中ENV指令时开始重置这个缓存,也就是说RUN apt-get -qq update这条指令会被再次执行,包缓存也将会刷新为最新内容

Docker网络端口映射

我们创建了一个 python 应用的容器。

1
2
[root@master ~]# docker run -d -P training/webapp python app.py
9ad5d024eb281df4906af1706542f12dfa93dc2ef67e8e3365027b7c4e998151

另外,我们可以指定容器绑定的网络地址,比如绑定 127.0.0.1。

我们使用 -P 参数创建一个容器,使用 docker ps 可以看到容器端口 5000 绑定主机端口 32768。

1
2
3
[root@master ~]# docker ps
CONTAINER ID IMAGE COMMAND ... PORTS NAMES
9ad5d024eb28 training/webapp "python app.py" ... 0.0.0.0:32768->5000/tcp pensive_hoover

我们也可以使用 -p 标识来指定容器端口绑定到主机端口。

两种方式的区别是:

  • -P :**是容器内部端口随机**映射到主机的高端口。
  • -p : 是容器内部端口绑定到指定的主机端口。
1
2
3
4
5
6
[root@master ~]# docker run -d -p 5000:5000 training/webapp python app.py
4948ad691937fecf6358bcaa4a70218504d0daecb17e44783dbbe302892eb811
[root@master ~]# docker ps
CONTAINER ID IMAGE COMMAND ... PORTS NAMES
4948ad691937 training/webapp "python app.py" ... 0.0.0.0:5000->5000/tcp tender_bose
9ad5d024eb28 training/webapp "python app.py" ... 0.0.0.0:32768->5000/tcp pensive_hoover

另外,我们可以指定容器绑定的网络地址,比如绑定 127.0.0.1。

1
2
3
4
5
6
7
[root@master ~]# docker run -d -p 127.0.0.1:5001:5000 training/webapp python app.py
ac165b705d84266bba0600627697b0c0808d094d776a507535edaacea5d10c27
[root@master ~]# docker ps
CONTAINER ID IMAGE COMMAND ... PORTS NAMES
ac165b705d84 training/webapp "python app.py" ... 127.0.0.1:5001->5000/tcp frosty_chaum
4948ad691937 training/webapp "python app.py" ... 0.0.0.0:5000->5000/tcp tender_bose
9ad5d024eb28 training/webapp "python app.py" ... 0.0.0.0:32768->5000/tcp pensive_hoover

这样我们就可以通过访问 127.0.0.1:5001 来访问容器的 5000 端口。

上面的例子中,默认都是绑定 tcp 端口,如果要绑定 UDP 端口,可以在端口后面加上 /udp

1
2
3
4
5
6
7
8
[root@master ~]# docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py
df0fec7189f326f41bb41bdd6980da7c9c5151075982f1ab7a192abb150292f1
[root@master ~]# docker ps
CONTAINER ID IMAGE COMMAND ... PORTS NAMES
df0fec7189f3 training/webapp "python app.py" ... 5000/tcp, 127.0.0.1:5000->5000/udp funny_varahamihira
ac165b705d84 training/webapp "python app.py" ... 127.0.0.1:5001->5000/tcp frosty_chaum
4948ad691937 training/webapp "python app.py" ... 0.0.0.0:5000->5000/tcp tender_bose
9ad5d024eb28 training/webapp "python app.py" ... 0.0.0.0:32768->5000/tcp pensive_hoover

docker port 命令可以让我们快捷地查看端口的绑定情况。

1
2
[root@master ~]# docker port frosty_chaum 5000
127.0.0.1:5001

Docker搭建常用服务

Docker搭建wordpress

1
2
3
docker run --name db -env MYSQL_ROOT_PASSWD=123456 -d mariadb #安装mariadb
数据库并且设置密码为123456
docker run --name MyWordPress --link db:mysql -p 8080:80 -d wordpress

Docker搭建sqli-labs环境

1
2
3
docker pull acgpiano/sqli-labs
docker run --name sqli-labs -d -p 8080:80 acgpiano/sqli-labs
docker exec -it ID /bin/bash

Docker搭建Portainer图形管理工具

1
2
3
docker search portainer
docker pull portainer/portainer
docker run -d -p 9000:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --name portainer portainer/portainer

Docker搭建hexo

1
2
3
docker search hexo
docker oull ipple1986/hexo
docker run --name hexo -p 8888:4000 -d ipple1986/hexo

docker-composer

1
2
3
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
chmod +x /usr/local/bin/docker-compose
docker-compose version

wordpress.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
version: '2'

service:
4db:
44image: mysql:5.7
44restart: always
44enviornment:
444MYSQL_ROOT_PASSWORD: 123456
444MYSQL_DATABASE: wordpress
444MYSQL_USER: wordpress
444MYSQL_PASSWORD: 123456
4wordpress:
depends: on
- db
image: wordpress:latest
restart: always
ports:
- "8080:80"
enviornment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: 123456

Docker使用常见的系统

docker使用Ubuntu

1
docker run --name MyUbuntu -itd ubuntu /bin/bash

docker使用CentOS

1
docker run --name MyCentOS -itd centos /bin/bash

常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
docker info  #守护进程的系统资源设置
docker search #docker仓库查询
docker pull #docker仓库下载
docker images #dokcer镜像查询
docker rmi #docker镜像删除
docker rm #删除容器
docker ps #容器的查询列出容器
docker run #容器创建启动
docker start/stop #容器启动停止
docker ps --no-trunc #显示完整的容器ID
docker start/stop docker_Name
docker start/stop docker_ID #启动或停止docker
docker inspect docker_Name #查看容器所有基本信息
docker logs docker_Name #查看容器日志
docker stats docker_Name #查看容器所占用的系统资源
docker exec docker_Name 命令(example:ls) #在容器内部执行命令
dokcer exec -it docker_Name/docker_ID #连接容器
docker --restart=always #让容器随着dokcer进程服务启动自动启动
docker -h x.x.x #修改容器的主机名
docker --dns x.x.x #修改容器使用的DNS服务器
docker --dns-search #DNS搜索设置
docker --add-host hostname:IP #注入hostname IP解析
docker --rm #容器停止时自动删除

docker删除全部容器命令

1
docker rm -f $(docker ps -a -q)
---未完待续---
扫码加我微信