Docker学习笔记

A blog for docker-Study

Posted by if on 2021-08-20
Estimated Reading Time 14 Minutes
Words 3.4k In Total

Docker学习笔记

@[TOC]

入门

Docker是一个虚拟环境容器,可以将你的开发环境、代码、配置文件等一并打包到这个容器中,并发布和应用到任意平台中

核心概念

镜像:打包项目带上环境(镜像)—-(docker仓库:商店)—-下载我们发布的镜像—-直接运行

隔离:docker核心思想是集装箱,每个集装箱都是隔离的。docker利用隔离机制,将服务器性能利用到极致

docker能干嘛

容器化技术不是模拟的一个完整的系统

每个容器可以根据自己程序所使用的的库打包成不同的容器,每个容器是互相隔离,都有一个属于自己的文件系统,互不影响

传统开发运维:一堆帮助文档,安装程序等

docker:打包镜像发布测试,一键运行。更便捷的升级、扩容等

docker的安装

基础概念

镜像:相当于是一个模板,可以通过这个模板创建许多的容器

容器:docker利用容器,独立运行一个或一组应用

启动、停止、删除等基本命令

仓库:存放镜像的地方

仓库分为公有仓库和私有仓库

例如:docker hub(默认是国外的)、阿里云…等

要和maven一样配置国内的仓库加速

安装

环境查看

需要内核3.0以上

1
2
[if@hadoop1 /]$ uname -r
4.18.0-193.el8.x86_64

centos版本查看

1
2
[if@hadoop1 /]$ cat  /etc/redhat-release
CentOS Linux release 8.2.2004 (Core)

Docker 运行在 CentOS-6.5 或更高的版本的 CentOS 上,需要内核版本是 2.6.32-431 或者更高版本 ,因为这是允许它运行的指定内核补丁版本

安装docker

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
# 1.删除旧版本
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine

# 2.需要的安装包(需要root权限)
yum install -y yum-utils

# 3.设置镜像的仓库(默认国外,这里实例用阿里云)
sudo yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

# 4.更新软件包索引
yum makecache fast
# 注:如果报错error: argument timer: invalid choice: 'fast',请删去 'fast'
# 显示“元数据缓存已建立。”则成功

# 5.安装docker相关内容 ce社区版,ee企业版
sudo yum install docker-ce docker-ce-cli containerd.io

# 6.测试docker的安装
[root@hadoop1 /]# docker -v
Docker version 20.10.8, build 3967b7d

# 7.启动docker
systemctl start docker

# 8.HelloWorld测试docker(等待一会出现一大堆文字,下面是解析)
docker run hello-world
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
[root@hadoop1 /]# docker run hello-world
Unable to find image 'hello-world:latest' locally #没有找到镜像,于是去网上寻找镜像
latest: Pulling from library/hello-world #pull拉取镜像
b8dfde127a29: Pull complete
Digest: sha256:0fe98d7debd9049c50b597ef1f85b7c1e8cc81f59c8d623fcb2250e8bec85b38
Status: Downloaded newer image for hello-world:latest #签名信息,拉取完毕

# run命令运行镜像,输出以下对话
Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/

For more examples and ideas, visit:
https://docs.docker.com/get-started/
1
2
3
4
# 9.查看下载的镜像
[root@hadoop1 /]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest d1165f221234 5 months ago 13.3kB

docker的卸载

1
2
3
4
5
# 1.卸载依赖
sudo yum remove docker-ce docker-ce-cli containerd.io
# 2.删除资源目录
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd

配置阿里云加速镜像服务

1
2
3
4
5
6
7
8
9
# 阿里云的“容器镜像服务”中的“镜像工具”的“镜像加速器”,以下是linux版(ubuntu/centos)
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://js3xmb98.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

run的执行流程图解

常用命令

帮助命令

1
2
3
docker version	# 显示docker的版本信息
docker info # 显示docker的系统详细信息(多少运行、镜像数量等)
docker --help # 帮助命令

帮助文档地址:https://docs.docker.com/engine/reference/commandline/docker

镜像命令

1
2
3
4
5
docker images [-aq]	# 查看本机所有镜像(-a是列出所有,-q是只列出所有的id)
docker search 镜像名 # 搜索镜像
docker pull 镜像名[:tag] # 下载镜像(默认最新版)
docker rmi [-f] 镜像名/id # -f是强制执行,后可接镜像名或者镜像id)
docker rmi -f &(docker images -aq) # 强制删除所有镜像(&循环出所有镜像的id)

容器命令

我们有了镜像才可以创建容器

启动命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 例如在centos虚拟机中拉取一个centos镜像
docker pull centos
# 新建容器并启动
docker run [可选参数] image
# 参数说明
--name "name1" 容器名字,例如tomcat1,tomcat2来区分容器
-d 后台方式运行(类似于nohup)
-it 使用交互方式运行,即启动并直接进入容器
-p (小写p)指定容器的端口
-p ip:主机端口:容器端口
-p 主机端口:容器端口 # -p 8080:8080
-p 容器端口
容器端口
-P (大写P)随机指定容器端口

启动容器实例

1
2
3
4
5
6
7
8
9
# 启动容器
[root@hadoop1 桌面]# docker run -it centos /bin/bash 启动centos容器并进入
[root@dbfd8cc1dddd /]# dbfd8cc1dddd即镜像id
[root@dbfd8cc1dddd /]# ls 容器里的目录和虚拟机一样
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
# 退出容器到主机
[root@dbfd8cc1dddd /]# exit
exit
[root@hadoop1 桌面]#

列出所有运行中的容器

1
2
3
4
docker ps	# 查看当前运行的
docker ps -a # 查看当前运行的+历史中运行过的容器记录
docker ps -n=3 # 查看最近3条创建的容器(数字可替换)
docker ps -q # 只显示显示容器编号

退出容器

1
2
exit	# 容器停止并退出到主机
快捷键 ctrl+P+Q # 容器不停止,退出到主机

删除容器

1
2
docker rm 容器id	# 删除指定的容器(不能删除正在运行的容器,除非-f强制执行)
docker rm -f &(docker ps -aq) # 循环遍历删除所有容器

启动和停止容器的操作

1
2
3
4
docker start 容器id	# 启动
docker restart 容器id # 重启
docker stop 容器id # 停止当前运行的容器
docker kill 容器id # 强制停止当前容器

进入正在运行的容器

1
2
3
4
# 进入容器后开启一个新的终端命令行
docker exec -it 容器id /bin/bash
# 直接进入容器正在执行的位置,不会启动新的进程
docker attach 容器id

拷贝容器内的文件

拷贝是一个手动的过程,后面可以通过 -v 卷的技术,实现自动拷贝

1
2
3
4
5
6
7
8
9
10
11
12
13
14
docker cp 容器id:容器内路径 主机路径
# 实例
[root@hadoop1 home]# docker run -it centos # 创建容器
[root@be40eb0f0837 home]# ls # 此时home为空目录
[root@be40eb0f0837 home]# touch test.java # 创建test.java文件
[root@be40eb0f0837 home]# ls
test.java
[root@be40eb0f0837 home]# exit
exit
[root@hadoop1 home]# ls
if
[root@hadoop1 home]# docker cp be40eb0f0837:/home/test.java /home # 将容器中的文件拷贝到主机
[root@hadoop1 home]# ls
if test.java

图形化界面

portainer

docker的图形化管理界面,可以可视化地管理镜像、容器等

官网

安装

1
docker run -d -p 8000:8000 -p 9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce

访问9000端口即可

图示

在这里插入图片描述

commit镜像

1
2
3
docker commit	# 提交容器,成为一个新的副本

docker commit -m="描述" -a="作者" 容器id 目标镜像名:[版本]

实例

1
2
[root@hadoop1 桌面]# docker commit -a="if" -m="test" c3ac96f879f9 test-tomcat:1.0
sha256:fa5661722506a8fda392f2366ff743de9843323ec7f5069cf28a81ddcf42a307

容器数据卷

docker可以将应用和环境打包成镜像

但是如果数据在容器里,那当容器删除时,数据也会被一起抹去

比如拉取mysql镜像跑容器,删除容器时mysql数据全盘丢失,相当于删库跑路

所以需要一个技术,让容器之间可以共享数据,这就是卷技术

目录的挂载,将容器内的目录挂载到linux上面

一句话:容器的持久化和同步操作

数据卷的好处

以后修改内容等,只需要修改主机的文件内容而不需进入容器,因为是双向绑定自动同步的

数据卷的使用

-v 命令

方式一:使用 -v 命令挂载

1
docker run -it -v 主机目录:容器目录 容器名

实例

1
2
3
4
5
6
7
8
9
10
11
12
# 查看主机目录
[root@hadoop1 home]# ls
if test.java

# 将主机的/home/ceshi挂载到容器的/home
[root@hadoop1 home]# docker run -it -v /home/ceshi:/home centos

[root@f4f4439e65bb /]# 此时ctrl+P+Q 容器后台运行并退出到主机

# 可以看见多出来一个ceshi目录
[root@hadoop1 home]# ls
ceshi if test.java

挂载后,主机的/home/ceshi中的内容和容器中/home中的内容是双向绑定的,哪怕容器是停止状态,只要还存在,就是挂载绑定状态

DockerFile

方式二:使用DockerFile

Dockerfile就是用来构建docker镜像的构建文件,命令脚本

创建一个名为”dockerfile01”的脚本,通过这个脚本可以生成镜像

步骤

  1. 编写dockerfile文件
  2. docker build为一个镜像
  3. docker run镜像
  4. docker push发布镜像(dockerhub,阿里云镜像等)

注:使用本地创建的镜像时需要指定版本号

一个简单的dockerfile脚本

1
2
3
4
# 文件中的指令要大写
FROM centos # 指定从centos镜像复制
VOLUME ["volume01"] # 创建镜像时,自动创建volume01目录,并对此目录进行匿名挂载
CMD /bin/bash # 只有最后一个cmd会被执行,可替代
1
2
3
4
5
6
7
# 启动脚本,生成镜像
docker build -f dockerfile01 -t if-centos:1.0 .
# 解析
-f 代表脚本路径(相对/绝对)
-t 发布的镜像名称
: 版本号
. 千万别漏了这个点!

实例

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
# 通过dockerfile脚本创建一个名为if-centos的镜像
[root@hadoop1 docker-test-volume]# docker build -f dockerfile01 -t if-centos:1.0 .
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM centos
---> 300e315adb2f
Step 2/4 : VOLUME ["portainer_data"]
---> Running in 9f414da5a037
Removing intermediate container 9f414da5a037
---> ab5a6ac79a06
Step 3/4 : CMD echo "------end------"
---> Running in 99613dde1f6c
Removing intermediate container 99613dde1f6c
---> 7a9f4497272a
Step 4/4 : CMD /bin/bash
---> Running in dba29f34e221
Removing intermediate container dba29f34e221
---> 9fcd757b7ea8
Successfully built 9fcd757b7ea8
Successfully tagged if-centos:1.0

# 查看镜像,可以看见if-centos 被成功创建
[root@hadoop1 docker-test-volume]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
if-centos 1.0 9fcd757b7ea8 9 seconds ago 209MB
test-tomcat 1.0 fa5661722506 2 hours ago 668MB
tomcat latest 266d1269bb29 17 hours ago 668MB
nginx latest dd34e67e3371 2 days ago 133MB
portainer/portainer-ce latest dfac2df13044 2 weeks ago 210MB
mysql 5.7 8cf625070931 4 weeks ago 448MB
hello-world latest d1165f221234 5 months ago 13.3kB
centos latest 300e315adb2f 8 months ago 209MB

# 运行镜像
docker run -it if-centos:1.0

# 查看镜像信息
docker inspect e8ae6afdc97c

# 可以看到容器挂载的目录
"Mounts": [
{
"Type": "volume",
"Name": "31ec7c6dcf26739258131d906f854d4394cf801deb6b39caeab7379899614bfd",
"Source": "/var/lib/docker/volumes/31ec7c6dcf26739258131d906f854d4394cf801deb6b39caeab7379899614bfd/_data",
"Destination": "portainer_data",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],

# 在容器内创建文件
[root@e8ae6afdc97c portainer_data]# ls
[root@e8ae6afdc97c portainer_data]# touch test.txt
[root@e8ae6afdc97c portainer_data]# ls
test.txt

# 查看主机挂载目录,可以看到成功双向绑定挂载了
[root@hadoop1 docker-test-volume]# cd /var/lib/docker/volumes/31ec7c6dcf26739258131d906f854d4394cf801deb6b39caeab7379899614bfd/_data
[root@hadoop1 _data]# ls
test.txt

数据卷的查看

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 使用  docker volume ls  查看当前所有卷

[root@hadoop1 home]# docker volume ls
DRIVER VOLUME NAME
local portainer_data

# 使用 docker volume inspect 卷名
[root@hadoop1 home]# docker volume inspect portainer_data
[
{
"CreatedAt": "2021-08-19T19:37:38+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/portainer_data/_data",
"Name": "portainer_data",
"Options": {},
"Scope": "local"
}
]
# 使用 docker inspect 容器id 查看容器信息

所有没有指定主机目录的挂载数据卷都是指向 /var/lib/docker/volumes/卷名/_data

具名挂载和匿名挂载(挂载的时候都不指定主机名称,只与是否指定卷名区分)

1
2
3
-v 容器内路径	# 匿名挂载
-v 卷名:容器内路径 # 具名挂载
-v 主机路径:容器路径 # 指定路径挂载

拓展

1
2
3
4
5
# -v 容器内路径:ro/rw 来改变读写权限
# ro:read-only 只读(指的是只能主机更改,容器内无权限更改)
# rw:read-write 读写

docker run -it -v /home:ro centos # 此时设置的就是只读

数据容器卷

多个容器之间共享数据

使用 —volumes-from 命令

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
# 先根据if-centos镜像运行一个名为docker01的容器
docker run -it --name docker01 if-centos:1.0
# 同理,创建docker02,但是挂载绑定到docker01
docker run -it --name docker02 --volumes-from docker01 if-centos:1.0



# 实例
# 创建docker01容器
[root@hadoop1 _data]# docker run -it --name docker01 if-centos:1.0
[root@06ea4926ee25 /]#

# 创建docker02容器并在数据容器卷中创建aaa.txt文件
[root@hadoop1 _data]# docker run -it --name docker02 --volumes-from docker01 if-centos:1.0
[root@c38c61152c0b /]# cd portainer_data
[root@c38c61152c0b portainer_data]# ls
[root@c38c61152c0b portainer_data]# touch aaa.txt
[root@c38c61152c0b portainer_data]# ls
aaa.txt

# 进入docker01容器,可以看见数据容器卷中也有aaa.txt文件,证明互通绑定成功
[root@hadoop1 _data]# docker attach 06ea4926ee25
[root@06ea4926ee25 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt portainer_data proc root run sbin srv sys tmp usr var
[root@06ea4926ee25 /]# cd portainer_data
[root@06ea4926ee25 portainer_data]# ls
aaa.txt


# 此时两个容器内容都有相同的文件夹portainer_data(因为是刚刚脚本创建的镜像)
# 这个文件夹就是多个容器之间可以互通绑定的数据容器卷

如果删除任意一容器,其他的容器数据依然存在,因为所有文件都挂载到了主机


本个人博客提供的内容仅用于个人学习,不保证内容的正确性。通过使用本站内容随之而来的风险与本站无关!