dockers概述
docker官方网站
docker官网:https://www.docker.com/
docker镜像仓库:https://hub.docker.com/
什么是docker?
Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从Apache2.0协议开源。
Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。
容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。
docker的作用:
简化程序部署
Docker 让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,便可以实现虚拟化。Docker改变了虚拟化的方式,使开发者可以直接将自己的成果放入Docker中进行管理。方便快捷已经是 Docker的最大优势,过去需要用数天乃至数周的 任务,在Docker容器的处理下,只需要数秒就能完成。
避免选择恐惧症
如果你有选择恐惧症,还是资深患者。Docker 帮你 打包你的纠结!比如 Docker 镜像;
Docker 镜像中包含了运行环境和配置,所以 Docker 可以简化部署多种应用实例工作。比如 Web 应用、后台应用、数据库应用、大数据应用比如 Hadoop 集群、消息队列等等都可以打包成一个镜像部署。
节省开支
一方面,云计算时代到来,使开发者不必为了追求效果而配置高额的硬件,Docker 改变了高性能必然
高价格的思维定势。Docker 与云的结合,让云空间得到更充分的利用。不仅解决了硬件管理的问题,也改变了虚拟化的方式。
持续交付和持续部署
对开发和运维(DevOps)人员来说,最希望的就是一次创建或配置,可以在任意地方正常运行。使用 Docker 可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过 Dockerfile 来进行镜像构建,并结合 持续集成(Continuous Integration) 系统进行集成测试,而运维人员则可以直接在生产环境中快速部署该镜像,甚至结合 持续部署(Continuous Delivery/Deployment) 系统进行自动部署。而且使用 Dockerfile 使镜像构建透明化,不仅仅开发团队可以理解应用运行环境,也方便运维团队理解应用运行所需条件,帮助更好的生产环境中部署该镜像
更轻松的迁移
由于 Docker 确保了执行环境的一致性,使得应用的迁移更加容易。Docker 可以在很多平台上运行,无论是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运行结果是一致的。因此用户可以很轻易的将在一个平台上运行的应用,迁移到另一个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况
docker的使用场景
- Web 应用的自动化打包和发布。
- 自动化测试和持续集成、发布。
- 在服务型环境中部署和调整数据库或其他的后台应用。
- 从头编译或者扩展现有的 OpenShi或 Cloud Foundry 平台来搭建自己的 PaaS 环境。
docker和虚拟机的区别
实现原理不同
虚拟机是⽤来进⾏硬件资源划分的完美解决⽅案,利⽤的是硬件虚拟化技术,如此VT-x 、AMD-V会通 过⼀个 hypervisor 层来实现对资源的彻底隔离。 而容器则是操作系统级别的虚拟化,利⽤的是内核的 Cgroup 和 Namespace 特性,此功能通过软件 来实现,仅仅是进程本身就可以实现互相隔离,不需要任何辅助。
使用资源不同
Docker 容器与主机共享操作系统内核,不同的容器之间可以共享部分系统资源,因此更加轻量级, 消耗的资源更少。 虚拟机会独占分配给⾃⼰的资源,不存在资源共享,各个虚拟机之间近乎完全隔离,更加重量级,也会消耗更多的资源。
应用场景不同
若需要资源的完全隔离并且不考虑资源的消耗,可以使用虚拟机。 若是想隔离进程并且需要运行大量进程实例,应该选择 Docker 容器。
docker的基本概念
Docker 包括三个基本概念
- 镜像
- 容器
- 仓库
docker镜像
Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变,可以理解为一个只读的文件系统
分层存储
因为镜像包含操作系统完整的 root 文件系统,其体积往往是庞大的,因此在 Docker 设计时,就充分利用 UnionFS 的技术,将其设计为分层存储的架构。所以严格来说,镜像并非是像一个 ISO 那样的打包文件,镜像只是一个虚拟的概念,其实际体现并非由一个文件组成,而是由一组文件系统组成,或者说,由多层文件系统联合组成。
镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。比如,删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除。
在最终容器运行的时候,虽然不会看到这个文件,但是实际上该文件会一直跟随镜像。因此,在构建镜像的时候,需要额外小心,每一层尽量只包含该层需要添加的东西,任何额外的东西应该在该层构建结束前清理掉。分层存储的特征还使得镜像的复用、定制变的更为容易。甚至可以用之前构建好的镜像作为基础层,然后进一步添加新的层,以定制自己所需的内容,构建新的镜像
docker容器
镜像( Image )和容器( Container )的关系,就像是面向对象程序设计中的 类 和 实例 一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间。因此容器可以拥有自己的 root 文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。
容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样。这种特性使得容器封装的应用比直接在宿主运行更加安全。也因为这种隔离的特性,很多人初学 Docker 时常常会混淆容器和虚拟机。
前面讲过镜像使用的是分层存储,容器也是如此。每一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层,我们可以称这个为容器运行时读写而准备的存储层为容器存储层。
容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡。因此,任何保存于容器存储层的信息都会随容器删除而丢失。
按照 Docker 最佳实践的要求,容器不应该向其存储层内写入任何数据,容器存储层要保持无状态化。所有的文件写入操作,都应该使用 数据卷(Volume) 、或者绑定宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。因此,使用数据卷后,容器删除或者重新运行之后,数据却不会丢失
docker仓库
Docker 仓库用来保存镜像,可以理解为代码控制中的代码仓库。
Docker Hub( https://hub.docker.com ) 提供了庞大的镜像集合供使用。
Docker仓库又分公有仓库和私有仓库
公有仓库
Docker Registry 公开服务是开放给用户使用、允许用户管理镜像的 Registry 服务。一般这类公开服务允许用户免费上传、下载公开的镜像,并可能提供收费服务供用户管理私有镜像。
最常使用的 Registry 公开服务是官方的 Docker Hub,这也是默认的 Registry,并拥有大量的高质量的官方镜像。除此以外,还有 CoreOS 的 Quay.io,CoreOS 相关的镜像存储在这里;Google 的 Google Container Registry,Kubernetes 的镜像使用的就是这个服务。
由于某些原因,在国内访问这些服务可能会比较慢。国内的一些云服务商提供了针对 Docker Hub 的镜像服务( Registry Mirror ),这些镜像服务被称为加速器。常见的有 阿里云加速器、DaoCloud 加速器 等。使用加速器会直接从国内的地址下载 Docker Hub 的镜像,比直接从 Docker Hub 下载速度会提高很多。国内也有一些云服务商提供类似于 Docker Hub 的公开服务。比如 时速云镜像仓库、网易云镜像服务、DaoCloud 镜像市场、阿里云镜像库 等。
docker安装
环境
IP | 规格 | 系统 |
---|---|---|
10.0.0.10 | 2c4g | Ubuntu22.04 |
安装操作
这里借用阿里云镜像仓库镜像安装
https://developer.aliyun.com/mirror/docker-ce?spm=a2c6h.13651102.0.0.57e31b11y0XHUO
# step 1: 安装必要的一些系统工具
sudo apt-get update -y
sudo apt-get install ca-certificates curl gnupg -y
# step 2: 信任 Docker 的 GPG 公钥
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
# Step 3: 写入软件源信息
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://mirrors.aliyun.com/docker-ce/linux/ubuntu \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Step 4: 安装Docker
sudo apt-get update -y
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
# 安装指定版本的Docker-CE:
# Step 1: 查找Docker-CE的版本:
# apt-cache madison docker-ce
# docker-ce | 17.03.1~ce-0~ubuntu-xenial | https://mirrors.aliyun.com/docker-ce/linux/ubuntu xenial/stable amd64 Packages
# docker-ce | 17.03.0~ce-0~ubuntu-xenial | https://mirrors.aliyun.com/docker-ce/linux/ubuntu xenial/stable amd64 Packages
# Step 2: 安装指定版本的Docker-CE: (VERSION例如上面的17.03.1~ce-0~ubuntu-xenial)
# sudo apt-get -y install docker-ce=[VERSION]
验证是否安装成功
[root@lb ~]# systemctl status docker
● docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2025-04-12 13:12:11 CST; 6s ago
TriggeredBy: ● docker.socket
Docs: https://docs.docker.com
Main PID: 17627 (dockerd)
Tasks: 7
Memory: 30.1M
CPU: 207ms
CGroup: /system.slice/docker.service
└─17627 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
[root@lb ~]# docker --version
Docker version 28.0.4, build b8034c0
配置阿里云镜像加速(可选操作)
地址:
https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
配置其它镜像加速器(强烈推荐!!!)
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<EOF
{
"registry-mirrors": [
"https://docker.1ms.run",
"https://docker.mybacc.com",
"https://dytt.online",
"https://lispy.org",
"https://docker.xiaogenban1993.com",
"https://docker.yomansunter.com",
"https://aicarbon.xyz",
"https://666860.xyz",
"https://docker.zhai.cm",
"https://a.ussh.net",
"https://hub.littlediary.cn",
"https://hub.rat.dev",
"https://docker.m.daocloud.io"
]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
使用 DockerHub Proxy,以下以 hub.uuuadc.top 为例:可以根据列表自行替换来测试是否拉取成功
docker pull hub.uuuadc.top/library/mysql:5.7
第一个docker进程
# 拉取镜像并运行容器
[root@lb ~]# docker run -d -p 80:80 --name nginx_first docker.1ms.run/nginx
Unable to find image 'docker.1ms.run/nginx:latest' locally
latest: Pulling from nginx
8a628cdd7ccc: Pull complete
75b642592991: Pull complete
553c8756fd66: Pull complete
10fe6d2248e3: Pull complete
3b6e18ae4ce6: Pull complete
3dce86e3b082: Pull complete
e81a6b82cf64: Pull complete
Digest: sha256:09369da6b10306312cd908661320086bf87fbae1b6b0c49a1f50ba531fef2eab
Status: Downloaded newer image for docker.1ms.run/nginx:latest
4695455441b97f62953f9f1199ad51a55cb42074feebfa26b75433506f3488c8
# 查看容器
[root@lb ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4695455441b9 docker.1ms.run/nginx "/docker-entrypoint...." 37 seconds ago Up 36 seconds 0.0.0.0:80->80/tcp, [::]:80->80/tcp nginx_first
# curl访问测试
[root@lb ~]# curl localhost:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
第一个进程详解
运行下面的命令都发生了什么?
docker run -d -p 80:80 --name nginx_first docker.1ms.run/nginx
- docker run:这是 Docker 命令,用于创建并运行一个新的容器。
- -d:指定容器后台运行
- -p 80:80:这个参数用于映射端口。它将容器内部的 80 端口映射到宿主机的 80 端口。这意味着访问宿主机的 80 端口时,实际上是访问容器内部的 80 端口。
- --name nginx_first:这个选项给新创建的容器指定一个名称,这里是 nginx_first。如果不指定名称,Docker 会自动生成一个名称。
- docker.1ms.run/nginx:这是要运行的镜像的名称。这里使用的是 docker.1ms.run 作为镜像仓库地址,nginx 是镜像名称
执行这个命令后,Docker 会做以下几件事:
- 检查本地是否有指定的 nginx 镜像。如果没有,Docker 会尝试从指定的镜像仓库(经过前缀替换后的地址)拉取镜像。
- 如果镜像存在,Docker 会创建一个新的容器实例,并使用指定的配置(如端口映射和容器名称)。
- 容器启动后,Docker 会在后台运行它,使得 Nginx 服务在宿主机的 80 端口上可用。
docker镜像管理
docker镜像核心指令
- docker images (docker image ls):查看本机所有镜像
- docker images -a:可以查看系统中所有镜像,包含隐藏镜像
- docker search xxx :搜索镜像,优先选官方,start数量多
- docker pull xxx:拉取镜像(下载镜像),注意版本
- docker push xxx:推送镜像(上传镜像)
- docker load xxx :导入镜像
- docker save xxx :导出镜像
- docker rmi xxx:删除镜像
- docker tag xxx : 给镜像打标签
- docker image prune :清理一些临时镜像-虚悬镜像
- docker image inspect xxx:查看镜像的信息,输出的是json格式
- docker image build xxx (docker build):构建镜像
- docker commit 容器名 : 从更改过的容器创建一个新的 docker 镜像
- docker image -f 过滤指令
docker pull
使用
docker pull
命令是用来下载镜像
# 下载MySQL镜像,不指定版本号,默认下载最新的镜像
[root@lb ~]# docker pull mysql
Using default tag: latest
latest: Pulling from library/mysql
cea172a6e83b: Pull complete
daac2c594bdd: Pull complete
cb8acbf2440c: Pull complete
fae51f7de1fb: Pull complete
b2ead3e96e6b: Pull complete
769c3ac51f88: Pull complete
79f239a40e62: Pull complete
c11056354384: Pull complete
49978e7ccddf: Pull complete
548990e33276: Pull complete
Digest: sha256:0596fa224cdf3b3355ce3ddbfd7ce77be27ec9e51841dfc5d2e1c8b81eea69d2
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest
#查看镜像
[root@lb ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.1ms.run/nginx latest 4cad75abc83d 2 months ago 192MB
mysql latest 567107cb6971 2 months ago 797MB
# 下载MySQL5.7
[root@lb ~]# docker pull mysql:5.7
5.7: Pulling from library/mysql
20e4dcae4c69: Pull complete
1c56c3d4ce74: Pull complete
e9f03a1c24ce: Pull complete
68c3898c2015: Pull complete
6b95a940e7b6: Pull complete
90986bb8de6e: Pull complete
ae71319cb779: Pull complete
ffc89e9dfd88: Pull complete
43d05e938198: Pull complete
064b2d298fba: Pull complete
df9a4d85569b: Pull complete
Digest: sha256:4bc6bc963e6d8443453676cae56536f4b8156d78bae03c0145cbe47c2aad73bb
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7
# 查看镜像
[root@lb ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.1ms.run/nginx latest 4cad75abc83d 2 months ago 192MB
mysql latest 567107cb6971 2 months ago 797MB
mysql 5.7 5107333e08a8 16 months ago 501MB
docker pull使用注意事项
- 下载镜像时如果不指定标签,则下载的是最新版本。
- 下载指定版本:docker pull 服务名:版本号
docker save
和docker load
使用
docker save
是将镜像保存到宿主机,而docker load
是将宿主机中的镜像包导入到docker的镜像
示例:
#导出镜像
[root@lb ~]# docker save mysql:5.7 -o /data/docker/images/mysql5.7.tar
[root@lb ~]# ll /data/docker/images/
total 507428
drwxr-xr-x 2 root root 4096 Apr 12 13:43 ./
drwxr-xr-x 3 root root 4096 Apr 12 13:42 ../
-rw------- 1 root root 519596032 Apr 12 13:43 mysql5.7.tar
# 删除所有镜像
[root@lb ~]# docker rmi $(docker images -q)
# 导入镜像
[root@lb ~]# docker load -i /data/docker/images/mysql5.7.tar
cff044e18624: Loading layer [==================================================>] 145MB/145MB
7ff7abf4911b: Loading layer [==================================================>] 11.26kB/11.26kB
8b2952eb02aa: Loading layer [==================================================>] 2.383MB/2.383MB
d76a5f910f6b: Loading layer [==================================================>] 13.91MB/13.91MB
8527ccd6bd85: Loading layer [==================================================>] 7.168kB/7.168kB
4555572a6bb2: Loading layer [==================================================>] 3.072kB/3.072kB
0d9e9a9ce9e4: Loading layer [==================================================>] 79.38MB/79.38MB
532b66f4569d: Loading layer [==================================================>] 3.072kB/3.072kB
337ec6bae222: Loading layer [==================================================>] 278.8MB/278.8MB
73cb62467b8f: Loading layer [==================================================>] 17.41kB/17.41kB
441e16cac4fe: Loading layer [==================================================>] 1.536kB/1.536kB
Loaded image: mysql:5.7
#查看镜像
[root@lb ~]# docker images | grep mysql
mysql 5.7 5107333e08a8 16 months ago 501MB
docker inspect
使用
docker inspect
可以查看容器、镜像、网络、数据卷等资源的信息并输出json格式,这里我们使用它查看一下镜像的相关信息
使用jq命令加工输出的json格式
apt install -y jq
示例:过滤MySQL中需要映射的端口
[root@lb ~]# docker inspect mysql:5.7 | jq .[].Config.ExposedPorts
{
"3306/tcp": {},
"33060/tcp": {}
}