首页 > 编程语言 > Python开发加薪利器之Docker的使用实践
2021
07-22

Python开发加薪利器之Docker的使用实践

1. Docker概述

  • Docker为什么火,因为十分的轻巧。
  • Docker是基于Go语言开发的。

1.1 虚拟机技术VS容器化技术

虚拟机技术:

  • 资源占用
  • 多冗余步骤多
  • 启动慢

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

1.2 名词概念

镜像(image)

docker镜像好比是一个模版,可以通过这个模版来创建容器服务,mysql镜像==>run==>mysql01容器(提供服务),通过这个镜像可以创建多个容器。

容器(container)

docker利用容器技术,独立运行一个或者一组应用。通过镜像来创建的。

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

目前可以把容器理解为就是一个简易的Linux系统。

仓库(repository)

仓库就是存放镜像的地方。仓库分为公有仓库和私有仓库。默认是国外的仓库(DockerHub),国内有阿里云等(配置镜像加速)

2. Docker安装

2.1 环境查看

2.1.1 查看内核版本

uname -r

image-20210412204343675

2.1.2 查看系统信息

sudo cat /etc/os-release

image-20210412204537598

2.2 卸载旧的版本

sudo apt-get remove docker docker-engine docker.io containerd runc

2.3 安装必要的包

2.3.1 更新apt程序包索引

sudo apt-get update

2.3.2 安装必要的包

sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg \
    lsb-release

2.4 添加GPG密钥

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

上面是官网提供的,但是速度很慢,建议使用阿里云的GPG Key。

curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -

2.5 添加稳定Docker-ce软件源

echo \
  "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

上面是官网提供的,但是速度很慢,建议使用阿里云提供的。

sudo add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu \
$(lsb_release -cs) stable"

注意:添加错了可以用以下命令删除

#查询keyid,下图
sudo apt-key list
#keyid 就是9DC8那一串
sudo apt-key del <keyid>
#加参数-r可以移除
sudo add-apt-repository -r "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

image-20210412211309428

2.6 安装Docker引擎

2.6.1 安装apt包索引

这样就可以安装Docker Engine和containerd的最新版本

sudo apt-get update

2.6.2 安装

sudo apt-get install docker-ce docker-ce-cli containerd.io

如果要安装指定版本的Docker引擎,在repo中列出可用版本,然后选择安装

apt-cache madison docker-ce

image-20210412212316466

sudo apt-get install docker-ce=<VERSION_STRING> docker-ce-cli=<VERSION_STRING> containerd.io

2.7 添加当前用户到 docker 用户组

添加后,以后就可以不用 sudo 运行 docker 了。

将当前用户添加到 docker 组

sudo gpasswd -a ${USER} docker

重新登录或者用以下命令切换到docker组(建议重启Ubuntu)

newgrp - docker

重启docker服务

sudo service docker restart

不加sudo直接执行docker命令检查效果

docker ps

2.8 测试是否安装成功

首先启动Docker

systemctl start docker

查看Docker版本来判断是否安装成功

docker version

image-20210412214628245

2.9 配置阿里云镜像加速

sudo mkdir -p /etc/docker

sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://eko3tl65.mirror.aliyuncs.com"]
}
EOF

sudo systemctl daemon-reload

sudo systemctl restart docker

3. Docker run 运行流程图

image-20210414105351295

4. Docker工作原理

Docker是一个Client·Server结构的系统,Docker的守护进程运行在主机上,通过Socket从客户端访问,DockerServer接受到DockerClient的指令,就会去执行这个指令。

image-20210414200137097

5. Docker常见命令

5.1 帮助命令

# 显示docker的版本信息
docker version

# 显示docker的系统信息 包括镜像和容器的数量
docker info

# 帮助命令
docker 命令 --help

帮助文档地址:官方文档

5.2 镜像命令

5.2.1 docker images

查看所有本地的主机上的镜像

malulu@malulu:~/桌面$ docker images
REPOSITORY    TAG       IMAGE ID       CREATED       SIZE
nginx         latest    519e12e2a84a   4 days ago    133MB
hello-world   latest    d1165f221234   5 weeks ago   13.3kB

# 解释
REPOSITORY	镜像的仓库源
TAG			镜像的标签
IMAGE ID	镜像的ID
CREATED		镜像的创建时间
SIZE		镜像的大小

# 可选项
  -a, --all             # 列出所有镜像
  -q, --quiet           # 只显示镜像的ID

5.2.2 docker search

搜索镜像

image-20210414210140452

# 可选项
--filter=STARS=3000		# 搜索出来的镜像就是STARS大于3000的

image-20210414210519271

5.2.3 docker pull

下载镜像

# 下载镜像
docker pull 镜像名[:tag]

malulu@malulu:~/桌面$ docker pull mysql
Using default tag: latest		# 如果不写tag(版本) 默认就是latest
latest: Pulling from library/mysql
f7ec5a41d630: Already exists	# 分层下载 docker image的核心 联合文件系统 
9444bb562699: Pull complete 
6a4207b96940: Pull complete 
181cefd361ce: Pull complete 
8a2090759d8a: Pull complete 
15f235e0d7ee: Pull complete 
d870539cd9db: Pull complete 
5726073179b6: Pull complete 
eadfac8b2520: Pull complete 
f5936a8c3f2b: Pull complete 
cca8ee89e625: Pull complete 
6c79df02586a: Pull complete 
Digest: sha256:6e0014cdd88092545557dee5e9eb7e1a3c84c9a14ad2418d5f2231e930967a38	# 签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest	# 真实地址


# 下面两条命令等价
docker pull mysql
docker pull docker.io/library/mysql:latest

# 指定版本下载 必须在仓库有这个版本
malulu@malulu:~/桌面$ docker pull mysql:5.7
5.7: Pulling from library/mysql
f7ec5a41d630: Already exists 
9444bb562699: Already exists 
6a4207b96940: Already exists 
181cefd361ce: Already exists 
8a2090759d8a: Already exists 
15f235e0d7ee: Already exists 
d870539cd9db: Already exists 
7310c448ab4f: Pull complete 
4a72aac2e800: Pull complete 
b1ab932f17c4: Pull complete 
1a985de740ee: Pull complete 
Digest: sha256:e42a18d0bd0aa746a734a49cbbcc079ccdf6681c474a238d38e79dc0884e0ecc
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7

5.2.4 docker rmi

删除镜像

# 删除指定的镜像
docker rmi -f 镜像ID

# 删除多个镜像
docker rmi -f 镜像ID 镜像ID 镜像ID 镜像ID 

# 删除全部镜像
docker rmi -f $(docker images -aq)

5.3 容器命令

说明:我们有了镜像才可以创建容器。

这里下载一个centos镜像来测试学习。

docker pull centos

5.3.1 新建容器并启动

docker run [可选参数] image

# 参数说明
--name="Name"	# 容器名字 mysql01 mysql02 用来区分容器
-d				# 后台方式运行
-it				# 使用交互方式运行(需要提供一个控制台) 进入容器查看内容
-p				# 指定容器的端口 -p 8080:8080
	-p ip:主机端口:容器端口
	-p 主机端口:容器端口 (常用)
	-p 容器端口
	容器端口
-P				# 随机指定端口

# 测试
# 启动并进入容器
malulu@malulu:~/桌面$ docker run -it centos /bin/bash
[root@a8d9ce9627a4 /]# ls	# 查看容器内的centos 基础镜像 很多命令都是不完善的
bin  etc   lib	  lost+found  mnt  proc  run   srv  tmp  var
dev  home  lib64  media       opt  root  sbin  sys  usr

# 从容器中退回主机
[root@a8d9ce9627a4 /]# exit
exit
malulu@malulu:~/桌面$ 

5.3.2 列出所有的运行的容器

# 列出当前正在运行的容器
docker ps

# 可选项
-a		# 列出当前正在运行的容器 + 历史运行过的容器
-n=?	# 显示最近创建的n个容器
-q		# 只显示容器的编号

image-20210415210733210

5.3.3 退出容器

exit	# 直接停止容器并退出
ctrl+P+Q	# 容器不停止退出

image-20210415211353920

5.3.4 删除容器

# 删除指定的容器 不能删除正在运行的容器 强制删除用rm -f
docker rm 容器ID

# 删除所有的容器
# 方式一 常用
docker rm -f $(docker ps -aq)
# 方式二
docker ps -a -q|xargs docker rm

5.3.5 启动和停止容器的操作

docker start 容器ID	# 启动容器
docker restart 容器ID	# 重启容器
docker stop 容器ID	# 停止当前正在运行的容器
docker kill 容器ID	# 强制删除当前容器

5.4 常见其他命令

5.4.1 后台启动容器

# 后台启动容器
docker run -d 镜像名

# 比如 后台启动centos
docker run -d centos

# 问题 docker ps 时 发现 centos 停止了
# 常见的坑:docker容器使用后台运行,就必须要有一个前台进程,docker发现没有应用,就会自动停止
# 比如nginx,容器启动后,发现自己没有提供服务,就会立刻停止,就是没有程序了

image-20210415214457904

5.4.2 查看日志

docker logs -f -t --tail number 容器ID

# 可选项
 -tf			# 显示日志
 --tail number	# 要显示日志条数

# 自己编写一段shell脚本
docker run -d centos /bin/sh -c "while true;do echo 666;sleep 1;done"

image-20210415222954446

5.4.3 查看容器中进程信息

docker top 容器ID

image-20210415224704528

5.4.4 查看镜像的元数据

docker inspect 容器ID

image-20210415225755698

5.4.5 进入当前正在运行的容器

我们通常容器都是使用后台方式运行的,有时需要进入容器,修改一些配置

# 方式一
# 命令
docker exec -it 容器ID bashShell
# 测试
malulu@malulu:~/桌面$ docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS     NAMES
9ff3b9c7ebd5   centos    "/bin/sh -c 'while t…"   8 seconds ago   Up 6 seconds             lucid_wright
malulu@malulu:~/桌面$ docker exec -it 9ff3b9c7ebd5 /bin/bash
[root@9ff3b9c7ebd5 /]# ls
bin  etc   lib	  lost+found  mnt  proc  run   srv  tmp  var
dev  home  lib64  media       opt  root  sbin  sys  usr
[root@9ff3b9c7ebd5 /]# 

# 方式二
docker attach 容器ID
# 测试
malulu@malulu:~/桌面$ docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS     NAMES
9ff3b9c7ebd5   centos    "/bin/sh -c 'while t…"   8 minutes ago   Up 8 minutes             lucid_wright
malulu@malulu:~/桌面$ docker attach 9ff3b9c7ebd5
666
666
666
666
666
666

# docker exec	# 进入容器后开启一个新的终端 可以在里面操作(常用)
# docker attach	# 进入容器正在执行的终端 不会启动新的终端

5.4.6 从容器内拷贝文件到主机

注意:是从容器内拷贝到主机。

docker cp 容器Id:容器内路径 目的的主机路径

只要容器存在就可以,跟容器是否运行没有关系。

拷贝是一个手动过程,后面我们使用 -V 数据卷的技术,可以实现自动同步。

image-20210421215842934

5.4.5 小结

Docker-Command-Diagram

attach      Attach local standard input, output, and error streams to a running container
build       Build an image from a Dockerfile
commit      Create a new image from a container's changes
cp          Copy files/folders between a container and the local filesystem
create      Create a new container
diff        Inspect changes to files or directories on a container's filesystem
events      Get real time events from the server
exec        Run a command in a running container
export      Export a container's filesystem as a tar archive
history     Show the history of an image
images      List images
import      Import the contents from a tarball to create a filesystem image
info        Display system-wide information
inspect     Return low-level information on Docker objects
kill        Kill one or more running containers
load        Load an image from a tar archive or STDIN
login       Log in to a Docker registry
logout      Log out from a Docker registry
logs        Fetch the logs of a container
pause       Pause all processes within one or more containers
port        List port mappings or a specific mapping for the container
ps          List containers
pull        Pull an image or a repository from a registry
push        Push an image or a repository to a registry
rename      Rename a container
restart     Restart one or more containers
rm          Remove one or more containers
rmi         Remove one or more images
run         Run a command in a new container
save        Save one or more images to a tar archive (streamed to STDOUT by default)
search      Search the Docker Hub for images
start       Start one or more stopped containers
stats       Display a live stream of container(s) resource usage statistics
stop        Stop one or more running containers
tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
top         Display the running processes of a container
unpause     Unpause all processes within one or more containers
update      Update configuration of one or more containers
version     Show the Docker version information
wait        Block until one or more containers stop, then print their exit codes

6. 实战

6.1 部署Nginx

第一步:搜索镜像,建议去DockerHub搜索,可以看到帮助文档

https://registry.hub.docker.com/search?q=nginx&type=image

image-20210422140913754

第二步:拉取镜像

malulu@malulu:~/桌面$ docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
f7ec5a41d630: Already exists 
aa1efa14b3bf: Pull complete 
b78b95af9b17: Pull complete 
c7d6bca2b8dc: Pull complete 
cf16cd8e71e0: Pull complete 
0241c68333ef: Pull complete 
Digest: sha256:75a55d33ecc73c2a242450a9f1cc858499d468f077ea942867e662c247b5e412
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
malulu@malulu:~/桌面$ 

第三步:运行测试

# -d 后台运行
# --name 给容器命名
# -p 宿主机端口:容器内部端口
malulu@malulu:~/桌面$ docker run -d --name nginx01 -p 3344:80 nginx
699b9cecd0a07f8db6e888722a2dada1c9b9be6d77efc7996c4b6758dd72f587
malulu@malulu:~/桌面$ docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED              STATUS              PORTS                  NAMES
699b9cecd0a0   nginx     "/docker-entrypoint.…"   About a minute ago   Up About a minute   0.0.0.0:3344->80/tcp   nginx01
malulu@malulu:~/桌面$ curl localhost:3344

# 进入容器
malulu@malulu:~/桌面$ docker exec -it nginx01 /bin/bash
root@699b9cecd0a0:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
root@699b9cecd0a0:/# cd /etc/nginx/
root@699b9cecd0a0:/etc/nginx# ls
conf.d	fastcgi_params	koi-utf  koi-win  mime.types  modules  nginx.conf  scgi_params	uwsgi_params  win-utf
root@699b9cecd0a0:/etc/nginx# exit

image-20210422141708715

第四步:公网访问

image-20210422145139506

image-20210422150021457

6.2 端口暴露(端口转发)

image-20210422143659432

6.3 部署Elasticsearch

# es 暴露的端口很多
# es 十分的耗内存
# es 数据一般需要放置到安全目录 挂载

docker run -d --name elasticsearch --net somenetwork -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:tag
# --net somenetwork 网络配置
# 启动 Elasticsearch
docker run -d --name elasticsearch01 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.12.0
# 启动之后,服务器会特别卡

# 所以需要增加内存的限制
# 修改配置文件 -e 环境配置修改
docker run -d --name elasticsearch02 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.12.0
# 查看CPU使用情况
docker stats 容器ID

image-20210426001139297

# 测试es是否安装成功
curl localhost:9200

image-20210426153149987

6.4 可视化 Portainer

Docker图形化界面管理工具,提供一个后台面板供我们操作。

访问测试:

http://192.168.2.143:8088
http://localhost:8088

为用户 admin 设置密码 admin123456

登录成功后,选择本地Docker环境

image-20210426163654688

进入之后的面板

image-20210426163805383

image-20210426163856950

可视化面板我们平时不会使用,用来测试玩玩。

7. Docker镜像讲解

7.1 镜像是什么

镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行所需库、环境变量和配置文件。
所有的应用,直接打包docker镜像,就可以直接跑起来。

如何获取到镜像:

  • 从远程仓库下载
  • 朋友拷贝给你
  • 自己制作一个镜像DockerFile

7.2 Docker镜像加载原理

UnionFS(联合文件系统)

我们下载的时候看到的一层层就是这个!
Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改
作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。

特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。

Docker镜像加载原理

Docker的镜像实际上由一层层的文件系统组成,这种层级的文件系统叫做UnionFS。

系统启动需要引导加载。

bootfs(boot file system)主要包含bootloader(加载器)和kernel(内核),bootloader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。

rootfs(root file system),在bootfs之上,包含的就是典型Linux系统中的 /dev,/proc,/bin,/etc 等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu, Centos等等。容器就是一个小的虚拟机环境。

平时我们在虚拟机中安装CentOs都是好几个G,为什么在Docker里面才200多M?

image-20210428205151603

对于一个精简的OS,rootfs可以很小,只需要包含最基本的命令,工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供rootfs就可以了。由此可见对于不同的linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以公用bootfs。

所以说,虚拟机是分钟级别,容器是秒级别。是因为启动虚拟机需要启动内核引导,非常慢,而容器底层还是使用主机的内核。

7.3 分层理解

分层的镜像

我们可以去下载一个镜像,注意观察下载的日志输出,可以看到的是一层一层的在下载。

image-20210428211943052

**思考:**为什么Docker镜像要采用这种分层的结构呢?
最大的好处,我觉得莫过于是资源共享了。比如有多个镜像都从相同的Base镜像构建而来,那么宿主机只需在磁盘上保留一份Base镜像,同时内存中也只需要加载一份Base镜像,这样就可以为所有的容器服务了,而且镜像的每一层都可以被共享。
查看镜像分层的方式可以通过 docker image inspect 命令。

docker image inspect redis:latest

image-20210428213757098

理解:

所有的Docker镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上,创建新的镜像层。
举一个简单的例子,假如基于Ubuntu Linux 16.04创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加Python包,就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创建第三个镜像层。该镜像当前已经包含3个镜像层,如下图所示(这只是一个用于演示的很简单的例子)

docker分层1

在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要。下图中举了一个简单的例子,每个镜像层包含3个文件,而镜像包含了来自两个镜像层的6个文件。

docker分层2

上图中的镜像层跟之前图中的略有区别,主要目的是便于展示文件。
下图中展示了一个稍微复杂的三层镜像,在外部看来整个镜像只有6个文件,这是因为最上层中的文件7是文件5的一个更新版本。

docker分层3

这种情况下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中。
Docker通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统。
Linux上可用的存储引擎有AUFS、Overlay2、Device Mapper、Btrfs 以及ZFS。顾名思义,每种存储引擎都基于Linux中对应的文件系统或者块设备技术,并且每种存储引擎都有其独有的性能特点。
Docker在Windows上仅支持windowsfilter一种存储引擎。
下图展示了与系统显示相同的三层镜像。所有镜像层堆叠并合并,对外提供统一的视图。

docker分层4

特点

Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部。
这一层就是我们通常说的容器层,容器之下的都叫镜像层。

image-20210513230444927

7.4 commit镜像

如何提交一个自己的镜像呢?

docker commit 提交容器成为一个新的镜像
docker commit -m="提交的描述信息" -a="作者" 容器Id 目标镜像名:[TAG]

实战测试:

# 1.启动一个默认的tomcat
# 2.发现这个默认的tomcat是没有webapps应用,是因为官方镜像默认webapps下面是没有文件的
# 3.自己拷贝进去了基本的文件

image-20210515145414664

# 4.将我们操作过的容器通过commit提交为一个镜像。我们以后就使用我们修改过的镜像即可。

image-20210515150002195

总结:

如果你想要保存当前容器的状态 ,就可以通过commit来提交,获得一个镜像。就好比虚拟机的快照。

8. 容器数据卷

8.1 容器数据卷是什么

将应用和环境打包成一个镜像!

数据?如果数据都在容器中,那么我们容器删除,数据就会丢失!需求:数据可以持久化

MySQL,容器删了,相当于删库跑路!需求:MySQL数据可以存储到本地

容器之间可以有一个数据共享的技术!Docker容器中产生的数据,同步到本地!

这就是卷技术!相当于目录的挂载,将我们容器内的目录,挂载到Linux上面!

**总结:**为什么使用容器卷?为了容器的持久化和同步操作,容器间也是可以数据共享的(即多个容器使用同一个本地目录)

8.2 使用数据卷

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

docker run -v 主机内目录:容器内目录

通过命令 docker inspect 来查看挂载信息,如下:

"Mounts": [
            {
                "Type": "bind",
                "Source": "/home/ceshi",	# 主机内地址
                "Destination": "/home",		# docker容器内地址
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],

测试文件的同步:

image-20210523134802321

8.3 实战:安装MySQL

思考:MySQL的数据持久化问题。

# 获取镜像
docker pull mysql:5.7

# 运行容器 需要做数据挂载
# 注意: 安装启动mysql时 需要配置密码的
# 官方测试(DockerHub) docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
# 启动
docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=Malulu@960610 --name mysql01 mysql:5.7

# 启动成功后 在使用Navicat来测试
# Navicat连接到Ubuntu的3310 3310和容器内的3306映射 此时我们就可以连接上了

image-20210523171250444

假设我们将容器删除,我们挂载到本地的数据卷依旧没有丢失,这就实现了容器数据持久化的功能。

8.4 匿名挂载和具名挂载

8.4.1 匿名挂载

# 查看所有卷的信息
docker volume ls

# 匿名挂载
-v 容器内目录
docker run -d -P --name nginx -v /etc/nginx nginx

# 这样就属于匿名挂载 在 -v 后只写了容器内目录 没有写主机的目录

image-20210524204440620

8.4.2 具名挂载

docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx

image-20210524213823035

通过 -v 卷名:容器内目录 的格式属于具名挂载。

使用命令 docker volume inspect 卷名 来查看这个这个卷的信息。

image-20210526230401399

所有的Docker容器内的卷,在没有指定目录的情况下都是在主机的 /var/lib/docker/volumes/xxx/_data 目录下。

image-20210526231900115

我们通过具名挂载可以方便的找到我们的一个卷,大多数情况下使用具名挂载

如何确定是具名挂载还是匿名挂载还是指定路径挂载?

-v 容器内路径			 # 匿名挂载
-v 卷名:容器内路径			# 具名挂载
-v /宿主机路径:容器内路径	  # 指定路径挂载

扩展:

# 通过 -v 容器内路径:ro rw 改变读写权限
ro readonly 	# 只读
rw readwrite	# 可读可写
# 一旦设置了这个权限 容器对我们挂载出来的内容就有限定了
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx

# ro 只要看到ro就说明这个路径只能通过宿主机来操作 容器内部是无法操作的

8.5 初识DockerFile

DockerFile就是用来构建Docker镜像的构建文件,这个文件其实就是一个命令脚本。

通过这个脚本可以生成镜像,镜像是一层一层的,脚本是一个一个的命令,每个命令都是一层。

# 创建一个dockerfile文件 名字可以随机 建议Dockerfile
# 文件中的内容 
# 指令(大写) 参数
FROM centos
VOLUME ["volume01","volume02"]
CMD echo "-----end-----"
CMD /bin/bash
# 这里的每个命令镜像的一层

通过 docker build 来创建自己的命令。

docker build -f ./dockerfile1 -t malulu-centos:1.0 .

image-20210527223442372

启动自己创建的镜像

image-20210527225848328

这两个卷在外部一定有同步的目录。

image-20210527230705332

查看一下卷挂载的路径。

image-20210527231911241

image-20210527231955491

然后测试一下刚才创建的两个文件是否同步到宿主机。

image-20210527232942353

这种方式我们以后用的非常多,因为我们通常会构建自己的镜像。假设构建镜像时没有挂载卷,就需要手动挂载(具名挂载)。

未完待续,值得期待!

编程技巧