近万字详解Docker常用功能合集(Docker系列第1章,共3章)
极简概括
官网:https://www.docker.com
利用比虚拟机更加轻量级的容器化虚拟技术,能够低成本的把当前环境快速打包或在新环境部署相同子环境的运维工具,基于Go语言实现,跨平台(支持Linux、Windows、MacOS)。
通俗类比:无论什么牌子什么价位的主机,都可以利用同一个的Windows镜像文件安装相同的系统,同时也支持对操作系统的不同进度进行打包,方便安装到另一台设备上。
解决问题
- 环境统一:本地开发环境、测试环境、生产环境不一致,本地测试没问题,一到线上就出故障。Docker 可以打包应用程序及其所有依赖项,确保在任何环境中都能以相同的方式运行。
- 降低运维成本: Docker 可以将应用程序及其所有依赖项打包到一个称为 Docker 镜像的容器中。这些镜像可以在秒级时间快速部署到任何支持 Docker 的主机上。
- 微服务架构支持: Docker 容器可以用于构建和部署微服务架构中的各个组件,每个微服务可以打包为一个独立的容器。这样可以实现高度的可扩展性、灵活性和可维护性。
适用场景
- 卷:为什么要学?很多人都会docker,不得不卷。
- 微服务架构:Docker 被广泛用于微服务架构中,每个微服务可以打包为一个 Docker 容器,使得应用程序模块化、可扩展和易于管理。
- 持续集成/持续部署(CI/CD):Docker 可以用于构建 CI/CD 管道,通过容器化应用程序,可以实现自动化的构建、测试和部署流程,提高开发团队的效率和交付速度。
- 开发环境一致性:开发团队可以使用 Docker 来创建一致的开发环境,确保开发、测试和生产环境之间的一致性,减少因环境差异导致的问题。
- 混合云和跨平台部署:由于 Docker 容器具有高度可移植性,可以在不同的云平台和操作系统上运行,适用于混合云环境和跨平台部署。
优点
- 轻量级: Docker 容器比传统的虚拟机更轻量级,因为它们共享主机系统的内核,并且不需要运行完整的操作系统。
- 快速操作: 由于 Docker 容器与宿主机共享内核,并且容器中的应用程序直接运行在主机的操作系统上,因此它们的安装、部署、启动速度非常快。
- 可移植: Docker 容器可以在不同的环境中轻松移植和部署,一次打包处处运行。
- 一致性: Docker 容器提供了一个一致的运行环境,确保应用程序在开发、测试和生产环境中的行为一致。
- 易于管理: Docker 提供了强大的命令,使得可以完成度容器、镜像、仓库的各种操作。
- 资源隔离: Docker 容器提供了一定程度的资源隔离,使得不同的容器可以在同一台主机上并行运行而不会相互干扰。
- 生态系统支持: Docker 拥有庞大的生态系统,意味着有成熟的解决方案,不容易遇见死胡同。
缺点
- 学习成本: Docker 拥有自己的一套规则,需要运维或者开发者做功课。
- 沙箱逃逸:docker不比虚拟机有更好的隔离性,可能引发沙箱逃逸漏洞,(虚拟机也有沙箱逃逸漏洞)。
- 系统兼容:32位的CentOS系统不支持安装Docker。
- 像是MySQL、等需要高可用和高IO的组件,docker能部署,但有缺点(文末有详解)。
Docker三板斧
- 容器:是一个独立、轻量级的运行环境,一些组件在容器里运行,(类比装好的Windows系统)。
- 镜像:是一个只读的模板,存放了应用程序的各种配置,可以被分享、复制,(类比Windows的ISO镜像文件)。
- 仓库:类似GitHub,做镜像的共享与托管,可见其流行程度和重要性,(类比各版本Windows的ISO镜像文件下载网站)。
理解虚拟化中的虚拟
- 从软硬件交互角度讲:操作系统的运行离不开计算机硬件(CPU、内存、硬盘),然而容器却依附于宿主机又建立的子系统,再和硬件交互,从上帝视角看,容器就像虚拟出来的真实系统一样。
- 从软硬件数据角度讲:docker中的数据,对于磁盘硬件实体而言,也只是一块实体的二进制数据,所谓的镜像、系统、容器都存在于软体,像虚拟出来的世界一样。
对比与虚拟机
- 量级不同:虚拟机是运行一整个系统,而docker是利用宿主机的内核部分。
- 隔离性:Docker 提供了进程级别的隔离,虚拟机提供了更高级的隔离策略。
- 部署难度:docker几个命令轻松部署,而虚拟机需要手动安装镜像。
为什么Docker会比虚拟机快
docker利用的是宿主机的内核,不需要像虚拟机一样重新加载操作系统进行各种初始化环节。
多个docker实例共享宿主机内核资源,而多个虚拟机是重新运行一套操作系统。
安装(CentOS7.6环境)
yum install -y yum-utils
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
systemctl start docker
systemctl enable docker
#测试运行,如果出现版本号,则说明安装成功
docker -v
Docker version 26.0.0, build 2ae903e
配置阿里云镜像加速
登录阿里云之后,搜索容器镜像服务,进入专题页面后到控制台,点击个人版,点击镜像工具,然后点击镜像加速器。
复制上面的bash shell,然后执行它。
/etc/docker/daemon.json 文件是 Docker 使用的配置文件,用于指定 Docker 守护进程的各种选项和设置。
mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://xxxx.mirror.aliyuncs.com"]
}
EOF
systemctl daemon-reload
systemctl restart docker
卸载(CentOS7.6环境)
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
存储在中的映像、容器、卷和网络/var/lib/docker/卸载Docker时不会自动删除,所以需要
rm -rf /var/lib/docker /var/lib/containerd
虚悬镜像
- 概念:虚悬镜像又叫做dangling image。仓库名,标签名都是none的镜像,是虚悬镜像。
- 原因:docker import或者docker build时没有设置名字和版本号。
- 删除:可以使用rmi命令删除,也可以使用docker image prune删除所有虚悬镜像。
基础命令
启动、停止、重启
systemctl start/stop/restart docker
开机自启动
systemctl enable docker
命令帮助文档
docker --help
某个命令帮助文档
docker 命令 --help
查看状态
systemctl status docker
docker概要
docker info
docker system df
TYPE(类型) TOTAL(资源总数) ACTIVE(当前运行的资源总数) SIZE(占空间大小) RECLAIMABLE(可回收空间大小)
Images(镜像) 0 0 0B 0B
Containers(容器) 0 0 0B 0B
Local Volumes(本地卷) 0 0 0B 0B
Build Cache(构建缓存) 0 0 0B 0B
容器命令
docker run 镜像名称 [-it] [shell类型] [/bin/bash]
docker会在本机中寻找该镜像,如果本机存在则直接运行,如果不存在,则会去阿里云 docker hub上找,如果能找到下载后运行,找不到则报错。
注意同一个镜像可以启多个容器,每个容器之间,默认不互通。
--name 为容器指定一个名字,如果不指定,系统随机分配
-d 后台守护进程运行并返回容器id。
-i 以交互模式运行容器。
-t 为容器分配一个终端。
-P 随机端口映射。
-p 指定端口映射 -p 外部端口:容器端口。
-it会经常配合使用,因为运行的组件,可能需要进入这个容器去做一些操作。
例如要运行一个Ubuntu,进入Ubuntu,要输入docker run -it ubuntu /bin/bash
/bin/bash表示用什么shell启动一个终端。
docker ps [-qa]
类比宿主机的ps,docker 只是针对容器的ps
CONTAINER ID(容器id) IMAGE(镜像id) COMMAND(终端) CREATED(创建时间) STATUS(状态) PORTS(端口) NAMES(容器名,docker run --name时会显示自定义的用户名)
162cdb700348 ba6acccedd29 "/bin/bash" 13 seconds ago Up 12 seconds romantic_kare
-a 显示全部的容器,默认只显示正在运行的容器
-q 只显示容器id
docker ps中的STATUS字段,如果显示UP字样,说明已经启动,如果显示Exited字样,说明已经停止运行。
退出容器
方式一:exit 容器停止。
方式二:Ctrl p q 容器不会停止。
docker exec [-it] [-d] 容器id [/bin/bash]
用例:docker exec -it 5e66cda41f9a /bin/bash
重新进入容器,再容器内部的命令行执行exit,不会导致容器停止。
-d 后台守护进程运行并返回容器id。
-i 以交互模式运行容器。
-t 为容器分配一个终端。
docker attach 容器id
用例:docker attach 容器id
重新进入容器,再容器内部的命令行执行exit,会导致容器停止。
docker start/stop/restart 容器id或容器名
启动、关闭、重启容器。
注意开启容器,不等于进入这个容器。
docker rm [-f] 容器id或容器名
删除容器。
docker rm $(docker ps -aq)可删除所有容器。
docker logs 容器id
查看某个容器的日志。
docker top 容器id
类比top命令,查看容器的资源占用情况
UID PID PPID C STIME TTY TIME CMD
root 27931 27910 0 00:00 ? 00:00:00 nginx: master process nginx -g daemon off;
UID: 进程的用户标识符(User ID),表示进程所属的用户。
PID: 进程标识符(Process ID),是内核为每个进程分配的唯一标识符。
PPID: 父进程标识符(Parent Process ID),表示启动当前进程的父进程的PID。
C: 进程的CPU利用率,表示进程正在使用的CPU核心数量。
STIME: 进程的启动时间,表示进程启动的时间戳。
TTY: 进程所关联的终端设备(如果有)。
TIME: 进程已经使用的CPU时间。
CMD: 进程的命令行,表示正在运行的进程的命令。
docker inspect 容器id
会返回一个大json,用来显示容器的信息
docker cp
容器复制到宿主机:docker cp 容器id:/路径 /路径
宿主机复制到容器:docker cp /路径 容器id:/路径
文件复制与容器的开始与结束无关。
镜像命令
docker images [-a] [-q]
列出本机上的所有镜像
REPOSITORY(镜像仓库源) TAG(标签版本号) IMAGE ID(镜像ID) CREATED(创建时间) SIZE(大小)
同一个REPOSITORY有多个TAG,好比CentOS,以后6、7、8的版本一样。
如果不指定一个镜像的版本标签,docker将默认使用latest镜像。
-a 表示列列举本地的所有惊喜那个
-q 表示只显示镜像id
docker rmi [-f] [镜像id或镜像名] [...]
删除某镜像
-f 强制删除,不加-f,正在运行的容器将无法删除,不推荐使用。
docker rmi -f $(docker images -qa) 删除全部,极不推荐用。
docker export 容器id > 文件名
导出容器
docker export 容器id > 容器名.dat
docker import 备份容器文件 容器名[:tag]
通过文件导入容器,如果不写tag,那默认是latest。
docker commit -m 注释 -a 作者 容器id 镜像名[:版本号]
提交容器副本,使其成为一个新的镜像
docker tag old_name:old_tag new_name:new_tag
相当于在原有的基础上复制出来一份镜像并改名,用docker images查看,old,和new是两条数据。
仓库命令
docker search 组件名 [--limit n]
NAME DESCRIPTION STARS(星星) OFFICIAL(是否官方) AUTOMATED(是否自动构建)
作者/包名 Official build of Nginx. 18879 [OK]
--limit n,可进行数量筛选前几个
docker pull 镜像名[:版本]
类比git pull,向共有仓库拉取镜像。
docker push [OPTIONS] NAME[:TAG]
将镜像推送到远程仓库,例如推送到阿里云。
docker push registry.cn-hangzhou.aliyuncs.com/xxx/xxx:[镜像版本号]
本地镜像发布到阿里云
- 请免费开启容器镜像服务,然后选择一个地区的节点,我选的是杭州。
- 在访问凭证页面先设置密码,对docker login命令的密码做铺垫。https://cr.console.aliyun.com/cn-hangzhou/instance/credentials
- 新建命名空间,然后新建镜像仓库,创建镜像仓库的最后一步选择,本地仓库。https://cr.console.aliyun.com/cn-hangzhou/instance/namespaces
- 创建完成之后,跟随阿里云的操作指南第3步,然后去执行它
docker login --username=xxx registry.cn-hangzhou.aliyuncs.com
docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/xxx/xxx:[镜像版本号]
docker push registry.cn-hangzhou.aliyuncs.com/xxx/xxx:[镜像版本号]
可使用以下命令去从远程仓库拉取镜像到本地
docker pull registry.cn-hangzhou.aliyuncs.com/xxx/xxx:[镜像版本号]
本地镜像发布到公司或个人的私有云(Docker Registry)
当前测试的机器局域网IP是192.168.0.180,需要再来一台机器模拟Docker Registry,IP为192.168.0.160,首先按照上文所述安装docker,不然docker命令不存在。
在160机器上,安装registry,执行docker images 查看是否安装成功。
docker pull registry
在160机器上,创建一个容器卷映射地址
mkdir /docker
在160机器上,后台运行这个registry
docker run --name docker_registry -d -v /docker:/docker --privileged=true -p 5000:5000 registry
在160机器上,查看是否成功运行
docker ps
再180机器上,vim /etc/docker/daemon.json,指定Docker客户端可以连接的不安全的Registry地址,
避免报错Get "https://192.168.0.160:5000/v2/": http: server gave HTTP response to HTTPS client
,
"insecure-registries":["192.168.0.160:5000"]
在180机器上,重启docker。
systemctl daemon-reload
systemctl restart docker
在180机器上,使用docker tag 命令做个镜像复制和更名。
注意这个名字192.168.0.160:5000/zs_ubuntu:0.0.1,要和docker push后面跟的保持一致
docker tag zs_ubuntu:0.0.1 192.168.0.160:5000/zs_ubuntu:0.0.1
在180机器上,执行推送,注意这个192.168.0.160:5000/zs_ubuntu:0.0.1,要与docker tag的对应上。
docker push 192.168.0.160:5000/zs_ubuntu:0.0.1
在180机器上,验证是否push成功(除了IP和端口,其余都是固定路径):
curl 192.168.0.160:5000/v2/_catalog
{"repositories":["zs_ubuntu"]}
168.0.160:5000/v2/_catalog能看见镜像名,但是看不见镜像版本号,到时候拉取会存在困难,此时就需要其它命令的参与:
curl http://192.168.0.160:5000/v2/镜像名称/tags/list
curl http://192.168.0.160:5000/v2/zs_ubuntu/tags/list
在其它机器上,其它人拉取镜像:
docker pull 192.168.0.160:5000/zs_ubuntu:0.0.1
在160机器上,对私有仓库存放镜像的增操作:
如上所讲。
在160机器上,对私有仓库存放镜像的删操作:
docker exec -it registry容器id sh
镜像文件是被放到 目录下的,/var/lib/registry/docker/registry/v2/repositories,在这里直接删除指定目录即可。
在160机器上,对私有仓库存放镜像的改操作:
不常用。
在160机器上,对私有仓库存放镜像的查操作:
curl 192.168.0.160:5000/v2/_catalog
为什么不建议在docker中使用MySQL
- 数据高可用问题:数据库存储的是公司的各项核心数据,求的是稳定,而不是一时候的部署方便。使用容器卷可以持久化数据。但是如果容器不小心停止,或者配置出错,造成的事故影响高可用,为了保证MySQL数据的高可用,下足了功夫,引入了redo log和不同的刷盘机制来应对性能与高可用之间的权衡,而docker的Union FS 镜像层提供持久存储,但是高可用缺乏保证。
- 性能问题:MySQL最大的性能瓶颈在于IO,原本是刷盘后就可以了,若使用了docker,如果没有容器卷很不保险,如果使用了容器卷,读写问题又多了一个流程。
- 使用受限:整个业务所使用的技术组件中,压力最大的往往就是数据库,MySQL包了一层容器,相当于多了一个环节,CPU、内存、磁盘IO、网络等,可能会受到一些限制。
Portainer:轻量级容器监控工具
- 官方文档:https://docs.portainer.io
- 极简概括:Portainer是一个轻量级的容器管理工具,它提供了用户界面用于管理Docker容器和集群,常用的Docker命令行操作,都可以通过这个组件在图形化界面完成。
- 注意:默认的9000端口,如果宿主机对内占用或者其它容器对外开放了9000端口,Nginx与PHP进行TCP方式的通信(还有一种UNIX的Socket通信),PHP-FPM进程会占用9000端口,所以需要修改portainer的端口为非9000。
- 安装并初始化:
安装
docker run --name portainer --restart=always -d -p 8000:8000 -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer
若端口冲突,可以这样改
docker run --name portainer --restart=always -d -p 8000:8000 -p 9001:9001 -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer
使用docker ps查看是否运行
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
073537d3fb66 portainer/portainer "/portainer" 30 seconds ago Up 29 seconds 0.0.0.0:8000->8000/tcp, :::8000->8000/tcp, 0.0.0.0:9000->9000/tcp, :::9000->9000/tcp portainer
访问相关页面并注册用户:
http://192.168.0.180:9000/#/init/admin
注册成功后点击local,再次点击local,就会看到Dashboard仪表盘页面。
http://192.168.0.180:9000/#/dashboard
之后进行各种查看和操作……
CAdvisor+InfluxDB+Granfana(CIG重量级容器监控工具)
这种对于个人开发者或小公司跟本用不上,个人开发者和小公司不需要太复杂的管理工具,而大公司有专门的运维,不需要开发者关注,仅做了解。
- 极简概括:简称CIG(C负责监控收集,I负责存储数据,G负责展示图表),是对docker进行重量级的监控工具。
- CAdvisor(Container Advisor)是一个用于监控容器性能的工具。它能够收集关于运行中的容器的信息,例如 CPU 使用率、内存使用量、网络统计等,并将这些数据提供给其他监控或可视化工具。
- InfluxDB 是一个时间序列数据库,特别适用于处理和存储监控数据。InfluxDB 允许将收集到的数据存储起来,并提供灵活的查询功能,以便进行数据分析和可视化。
- Grafana 则是一个开源的监控和数据可视化平台。它能够与各种数据源集成,包括 InfluxDB,用于创建丰富的监控仪表盘和报表,展示监控数据的实时和历史变化,以及执行定制化的数据分析。