Docker 入门到精通 (图解+秒懂+史上最全)
文章很长,建议收藏起来慢慢读!疯狂创客圈总目录 语雀版 | 总目录 码云版|总目录 博客园版 为您奉上珍贵的学习资源 :免费赠送 经典图书:《Java高并发核心编程(卷1)》面试必备 + 大厂必备 +涨薪必备 加尼恩免费领免费赠送 经典图书:《Java高并发核心编程(卷2)》面试必备 + 大厂必备 +涨薪必备 加尼恩免费领免费赠送 经典图书:《Netty Zookeeper Redis 高并发实战
文章很长,建议收藏起来慢慢读!疯狂创客圈总目录 语雀版 | 总目录 码云版| 总目录 博客园版 为您奉上珍贵的学习资源 :
-
免费赠送 经典图书:《Java高并发核心编程(卷1)》 面试必备 + 大厂必备 +涨薪必备 加尼恩免费领
-
免费赠送 经典图书:《Java高并发核心编程(卷2)》 面试必备 + 大厂必备 +涨薪必备 加尼恩免费领
-
免费赠送 经典图书:《Netty Zookeeper Redis 高并发实战》 面试必备 + 大厂必备 +涨薪必备 加尼恩免费领
-
免费赠送 经典图书:《SpringCloud Nginx高并发核心编程》 面试必备 + 大厂必备 +涨薪必备 加尼恩免费领
-
免费赠送 资源宝库: Java 必备 百度网盘资源大合集 价值>10000元 加尼恩领取
推荐:入大厂 、做架构、大力提升Java 内功 的 精彩博文
入大厂 、做架构、大力提升Java 内功 必备的精彩博文 | 2021 秋招涨薪1W + 必备的精彩博文 |
---|---|
1:Redis 分布式锁 (图解-秒懂-史上最全) | 2:Zookeeper 分布式锁 (图解-秒懂-史上最全) |
3: Redis与MySQL双写一致性如何保证? (面试必备) | 4: 面试必备:秒杀超卖 解决方案 (史上最全) |
5:面试必备之:Reactor模式 | 6: 10分钟看懂, Java NIO 底层原理 |
7:TCP/IP(图解+秒懂+史上最全) | 8:Feign原理 (图解) |
9:DNS图解(秒懂 + 史上最全 + 高薪必备) | 10:CDN图解(秒懂 + 史上最全 + 高薪必备) |
11: 分布式事务( 图解 + 史上最全 + 吐血推荐 ) | 12:seata AT模式实战(图解+秒懂+史上最全) |
13:seata 源码解读(图解+秒懂+史上最全) | 14:seata TCC模式实战(图解+秒懂+史上最全) |
Java 面试题 30个专题 , 史上最全 , 面试必刷 | 阿里、京东、美团… 随意挑、横着走!!! |
---|---|
1: JVM面试题(史上最强、持续更新、吐血推荐) | 2:Java基础面试题(史上最全、持续更新、吐血推荐 |
3:架构设计面试题 (史上最全、持续更新、吐血推荐) | 4:设计模式面试题 (史上最全、持续更新、吐血推荐) |
17、分布式事务面试题 (史上最全、持续更新、吐血推荐) | 一致性协议 (史上最全) |
29、多线程面试题(史上最全) | 30、HR面经,过五关斩六将后,小心阴沟翻船! |
9.网络协议面试题(史上最全、持续更新、吐血推荐) | 更多专题, 请参见【 疯狂创客圈 高并发 总目录 】 |
SpringCloud 精彩博文 | |
---|---|
nacos 实战(史上最全) | sentinel (史上最全+入门教程) |
SpringCloud gateway (史上最全) | 更多专题, 请参见【 疯狂创客圈 高并发 总目录 】 |
背景:
下一个视频版本,从架构师视角,尼恩为大家打造高可用、高并发中间件的原理与实操。
目标:通过视频和博客的方式,为各位潜力架构师,彻底介绍清楚架构师必须掌握的高可用、高并发环境,包括但不限于:
-
高可用、高并发nginx架构的原理与实操
-
高可用、高并发mysql架构的原理与实操
-
高可用、高并发nacos架构的原理与实操
-
高可用、高并发rocketmq架构的原理与实操
-
高可用、高并发es架构的原理与实操
-
高可用、高并发minio架构的原理与实操
why 高可用、高并发中间件的原理与实操:
- 实际的开发过程中,很多小伙伴,常常是埋头苦干,聚焦crud开发,复杂一点的环境出了问题,都不能自己去启动,出了问题,就想热锅上的蚂蚁,无从下手。
- 常常的现象是: 大家 低头看路的时间多,抬头看天的时间少,技术视野比较狭窄。常常是埋头苦干业务开发,很少投入精力进行技术提升。
- 作为架构师,或者未来想走向高端开发,或者做架构,必须掌握高可用、高并发中间件的原理,掌握其实操。
本系列博客的具体内容,请参见 疯狂创客圈总目录 语雀版 | 总目录 码云版| 总目录 博客园版
Docker 简介
Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。
Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。
容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。
Docker 从 17.03 版本之后分为 CE(Community Edition: 社区版) 和 EE(Enterprise Edition: 企业版),我们用社区版就可以了
Docker的应用场景
- Web 应用的自动化打包和发布。
- 自动化测试和持续集成、发布。
- 在服务型环境中部署和调整数据库或其他的后台应用。
- 从头编译或者扩展现有的 OpenShift 或 Cloud Foundry 平台来搭建自己的 PaaS 环境。
Docker 架构
Docker 包括三个基本概念:
- 镜像(Image):Docker 镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系统的 root 文件系统。
- 容器(Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
- 仓库(Repository):仓库可看成一个代码控制中心,用来保存镜像。
Docker 使用客户端-服务器 (C/S) 架构模式,使用远程API来管理和创建Docker容器。
Docker 容器通过 Docker 镜像来创建。
概念 | 说明 |
---|---|
Docker 镜像(Images) | Docker 镜像是用于创建 Docker 容器的模板,比如 Ubuntu 系统。 |
Docker 容器(Container) | 容器是独立运行的一个或一组应用,是镜像运行时的实体。 |
Docker 客户端(Client) | Docker 客户端通过命令行或者其他工具使用 Docker SDK (https://docs.docker.com/develop/sdk/) 与 Docker 的守护进程通信。 |
Docker 主机(Host) | 一个物理或者虚拟的机器用于执行 Docker 守护进程和容器。 |
Docker Registry | Docker 仓库用来保存镜像,可以理解为代码控制中的代码仓库。Docker Hub(https://hub.docker.com) 提供了庞大的镜像集合供使用。一个 Docker Registry 中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。 |
docker的守护进程查看
systemctl status docker
docker 镜像查看
docker image ls
docker 容器查看
docker ps
Docker Registry配置和查看
cat /etc/docker/daemon.json
配置私有仓库
cat>/etc/docker/daemon.json<<EOF
{
"registry-mirrors":["http://10.24.2.30:5000","https://tnxkcso1.mirrors.aliyuncs.com"],
"insecure-registries":["10.24.2.30:5000"]
}
EOF
在线安装docker
离线安装docker
一、基础环境
1、操作系统:CentOS 7.3
2、Docker版本:19.03.9 官方下载地址
3、官方参考文档:https://docs.docker.com/install/linux/docker-ce/binaries/#install-static-binaries
二、Docker安装
1、下载
wget https://download.docker.com/linux/static/stable/x86_64/docker-19.03.9.tgz
注意:如果事先下载好了可以忽略这一步
2、解压
把压缩文件存在指定目录下(如root),并进行解压
tar -zxvf docker-19.03.9.tgz
cd root
[root@localhost ~]# tar -zxvf docker-19.03.6.tgz
docker/
docker/containerd
docker/docker
docker/ctr
docker/dockerd
docker/runc
docker/docker-proxy
docker/docker-init
docker/containerd-shim
3、将解压出来的docker文件内容移动到 /usr/bin/ 目录下
cp docker/* /usr/bin/
4、将docker注册为service
cat /etc/systemd/system/docker.service
vi /etc/systemd/system/docker.service
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target
[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd
ExecReload=/bin/kill -s HUP $MAINPID
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
# Uncomment TasksMax if your systemd version supports it.
# Only systemd 226 and above support this version.
#TasksMax=infinity
TimeoutStartSec=0
# set delegate yes so that systemd does not reset the cgroups of docker containers
Delegate=yes
# kill only the docker process, not all processes in the cgroup
KillMode=process
# restart the docker process if it exits prematurely
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s
[Install]
WantedBy=multi-user.target
5、启动
chmod +x /etc/systemd/system/docker.service #添加文件权限并启动docker
systemctl daemon-reload #重载unit配置文件
systemctl start docker #启动Docker
systemctl enable docker.service #设置开机自启
[root@localhost ~]# vi /etc/systemd/system/docker.service
[root@localhost ~]# chmod +x /etc/systemd/system/docker.service
[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl start docker
[root@localhost ~]# systemctl enable docker.service
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /etc/systemd/system/docker.service.
6、验证
systemctl status docker #查看Docker状态
docker -v #查看Docker版本
docker info
[root@localhost ~]# systemctl status docker
● docker.service - Docker Application Container Engine
Loaded: loaded (/etc/systemd/system/docker.service; enabled; vendor preset: disabled)
Active: active (running) since Sat 2021-10-09 15:25:44 CST; 29s ago
Docs: https://docs.docker.com
Main PID: 1916 (dockerd)
CGroup: /system.slice/docker.service
├─1916 /usr/bin/dockerd
└─1927 containerd --config /var/run/docker/containerd/containerd.toml --log-level info
Oct 09 15:25:43 localhost.localdomain dockerd[1916]: time="2021-10-09T15:25:43.671407996+08:00" level=info msg="scheme \"unix\" not r...e=grpc
Oct 09 15:25:43 localhost.localdomain dockerd[1916]: time="2021-10-09T15:25:43.671440368+08:00" level=info msg="ccResolverWrapper: se...e=grpc
Oct 09 15:25:43 localhost.localdomain dockerd[1916]: time="2021-10-09T15:25:43.671462935+08:00" level=info msg="ClientConn switching ...e=grpc
Oct 09 15:25:43 localhost.localdomain dockerd[1916]: time="2021-10-09T15:25:43.750687781+08:00" level=info msg="Loading containers: start."
Oct 09 15:25:44 localhost.localdomain dockerd[1916]: time="2021-10-09T15:25:44.072960862+08:00" level=info msg="Default bridge (docke...dress"
Oct 09 15:25:44 localhost.localdomain dockerd[1916]: time="2021-10-09T15:25:44.153444071+08:00" level=info msg="Loading containers: done."
Oct 09 15:25:44 localhost.localdomain dockerd[1916]: time="2021-10-09T15:25:44.175249299+08:00" level=info msg="Docker daemon" commit...9.03.6
Oct 09 15:25:44 localhost.localdomain dockerd[1916]: time="2021-10-09T15:25:44.175337834+08:00" level=info msg="Daemon has completed ...ation"
Oct 09 15:25:44 localhost.localdomain systemd[1]: Started Docker Application Container Engine.
Oct 09 15:25:44 localhost.localdomain dockerd[1916]: time="2021-10-09T15:25:44.195084106+08:00" level=info msg="API listen on /var/ru....sock"
Hint: Some lines were ellipsized, use -l to show in full.
[root@localhost ~]# docker -v
Docker version 19.03.6, build 369ce74a3c
[root@localhost ~]# docker info
使用docker
调整镜像仓库
修改docker的registry
修改/etc/docker目录下的daemon.json文件
在文件中加入
{
"registry-mirrors": ["https://registry.docker-cn.com"]
}
保存退出
重新启动docker
chmod +x /etc/systemd/system/docker.service #添加文件权限并启动docker
systemctl daemon-reload #重载unit配置文件
systemctl start docker #启动Docker
systemctl restart docker #重新启动Docker
systemctl enable docker.service #设置开机自启
[root@localhost ~]# vi /etc/systemd/system/docker.service
[root@localhost ~]# chmod +x /etc/systemd/system/docker.service
[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl start docker
[root@localhost ~]# systemctl enable docker.service
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /etc/systemd/system/docker.service.
发现内网的环境, 改成了阿里云的,但是没有啥用
[root@localhost ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://ku39pxyp.mirror.aliyuncs.com"],
"insecure-registries": ["hub.company.com"]
}
确保镜像仓库可以ping通
[root@localhost ~]# curl https://ku39pxyp.mirror.aliyuncs.com
curl: (6) Could not resolve host: ku39pxyp.mirror.aliyuncs.com; Unknown error
[root@localhost ~]# ping ku39pxyp.mirror.aliyuncs.com
ping: ku39pxyp.mirror.aliyuncs.com: Name or service not known
开源的镜像仓库Harbor概述
Habor是由VMWare公司开源的容器镜像仓库。事实上,Habor是在Docker Registry上进行了相应的
企业级扩展,从而获得了更加广泛的应用,这些新的企业级特性包括:管理用户界面,基于角色的访
问控制 ,AD/LDAP集成以及审计日志等,足以满足基本企业需求。
官方地址:https://vmware.github.io/harbor/cn/
1、什么是Harbor
• Harbor是VMware公司开源的企业级Docker Registry项目,其目标是帮助用户迅速搭建一个企业级的Docker Registry服务
• Harbor以 Docker 公司开源的Registry 为基础,提供了图形管理UI、基于角色的访问控制(Role Based AccessControl)、AD/LDAP集成、以及审计日志(Auditlogging)等企业用户需求的功能,同时还原生支持中文
• Harbor的每个组件都是以Docker 容器的形式构建的,使用docker-compose 来对它进行部署。用于部署Harbor 的docker- compose模板位于harbor/ docker- compose.yml
2、Harbor的特性
1.基于角色控制: 用户和仓库都是基于项目进行组织的,而用户在项目中可以拥有不同的权限
2.基于镜像的复制策略: 镜像可以在多个Harbor实例之间进行复制(同步)
3.支持LDAP/AD: Harbor 可以集成企业内部有的AD/LDAP (类似数据库的一-张表),用于对已经存在的用户认证和管理
4.镜像删除和垃圾回收: 镜像可以被删除,也可以回收镜像占用的空间
5.图形化用户界面: 用户可以通过浏览器来浏览,搜索镜像仓库以及对项目进行管理
6.审计管理: 所有针对镜像仓库的操作都可以被记录追溯,用于审计管理
7.支持RESTful API: RESTful API提供给管理员对于Harbor 更多的操控,使得与其它管理软件集成变得更容易
8.Harbor 和docker registry的 关系: Harbor实质 上是对docker registry做 了封装,扩展了自己的业务模板
3、Harbor的构成
Harbor在架构上主要有Proxy、 Registry、 Core services、 Database (Harbor-db) 、Log collector ( Harbor-log)、Job services六个组件
● Proxy: Harbor 的Registry、 UI、Token 服务等组件,都处在nginx 反向代理后边。该代理将来自浏览器、docker clients的请求转发到后端不同的服务上
● Registry:负责储存Docker 镜像,并处理Docker push/pull命令。由于要对用户进行访问控制,即不同用户对Docker 镜像有不同的读写权限,Registry 会指向一个Token 服务,强制用户的每次Docker pull/push 请求都要携带一个合法的Token,Registry会通过公钥对Token进行解密验证
● Core services: Harbor的核心功能,主要提供以下3个服务:
1.UI (harbor-ui) :提供图形化界面,帮助用户管理Registry. 上的镜像( image),并对用户进行授权
2.WebHook: 为了及时获取Registry.上image 状态变化的情况,在Registry. 上配置 Webhook,把状态变化传递给UI模块
3.Token 服务:负责根据用户权限给每个Docker push/pull 命令签发Token。 Docker 客户端向Registry服务发起的请求,
如果不包含Token,会被重定向到Token服务,获得Token后再重新向Registry 进行请求
● Database (harbor-db) :为core services提供数据库服务,负责储存用户权限、审计日志、Docker 镜像分组信息等数据
● Job services: 主要用于镜像复制,本地镜像可以被同步到远程Harbor 实例上
● Log collector (harbor-log) :负责收集其他组件的日志到一个地方
• Harbor的每个组件都是以Docker 容器的形式构建的,因此,使用Docker Compose 来对它进行部署。
• 总共分为7个容器运行,通过在docker-compose.yml所在目录中执行docker-compose ps命令来查看,
名称分别为: nginx、 harbor-jobservice、 harbor-ui、 harbor-db、harbor-adminserver、registry、 harbor-log.
其中harbor-adminserver主要是作为一个后端的配置数据管理,并没有太多的其他功能。harbor-ui所要操作的所有数据都通过harbor-adminserver这样一个数据配置管理中心来完成。
不安全的镜像仓库
[root@localhost ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
172.11.1.107 hub.company.com
发现内网的环境, 改成了阿里云的,但是没有啥用
[root@localhost ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": ["http://hub.company.co"],
"insecure-registries": ["hub.company.com"]
}
查看docker info 的引擎信息
[root@localhost ~]# docker info
Client:
Debug Mode: false
Server:
Containers: 14
Running: 7
Paused: 0
Stopped: 7
Images: 19
Server Version: 19.03.6
Storage Driver: overlay2
Backing Filesystem: xfs
Supports d_type: true
Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: b34a5c8af56e510852c35414db4c1f4fa6172339
runc version: 3e425f80a8c931f88e6d94a8c831b9d5aa481657
init version: fec3683
Security Options:
seccomp
Profile: default
Kernel Version: 3.10.0-1062.el7.x86_64
Operating System: CentOS Linux 7 (Core)
OSType: linux
Architecture: x86_64
CPUs: 4
Total Memory: 15.49GiB
Name: localhost.localdomain
ID: I5KF:Y5JA:VCWG:DJYG:PGZO:PZVA:FYXQ:F624:RWH6:4S6R:BI6Z:L2MT
Docker Root Dir: /var/lib/docker
Debug Mode: false
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
hub.gsafety.com
127.0.0.0/8
Registry Mirrors:
https://ku39pxyp.mirror.aliyuncs.com/
Live Restore Enabled: false
查看docker相关的进程
[root@localhost ~]# ps -ef | grep docker
root 1460 1 0 Jun23 ? 04:45:43 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
root 2249 1460 0 Jun23 ? 00:00:09 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 5433 -container-ip 172.26.0.2 -container-port 5432
root 2280 1460 0 Jun23 ? 00:00:09 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 5432 -container-ip 172.26.0.3 -container-port 5432
root 2310 1455 0 Jun23 ? 00:09:35 containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/78dc6aacc7d9490fa7c7252dd6b4df01af3b68c2adb69767fb0d51974ea0728c -address /run/containerd/containerd.sock -containerd-binary /usr/bin/containerd -runtime-root /var/run/docker/runtime-runc
root 2311 1455 0 Jun23 ? 00:16:19 containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/d6ec26035ca0428d5c3bd1cc154a76b356cf3a7d0746b0455d81223c7b9ab7fd -address /run/containerd/containerd.sock -containerd-binary /usr/bin/containerd -runtime-root /var/run/docker/runtime-runc
root 2483 1460 0 Jun23 ? 00:00:32 /usr/bin/docker-proxy -proto tcp -host-ip 127.0.0.1 -host-port 1514 -container-ip 172.21.0.4 -container-port 10514
root 2538 1455 0 Jun23 ? 02:25:41 containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/98500167fb283c56fd43f42d3357c52b393481fdcca2bc7a87128ac35e19fa5a -address /run/containerd/containerd.sock -containerd-binary /usr/bin/containerd -runtime-root /var/run/docker/runtime-runc
root 2571 1455 0 Jun23 ? 02:17:17 containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/412652067b159ca617625c315940ce6865534e80fa94b93ef3174f653d21b826 -address /run/containerd/containerd.sock -containerd-binary /usr/bin/containerd -runtime-root /var/run/docker/runtime-runc
root 7077 1460 0 Jun23 ? 00:00:09 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 3306 -container-ip 172.19.0.2 -container-port 3306
root 7085 1455 0 Jun23 ? 00:09:39 containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/976bb8cd43729535a74d1583a758be937b6cf8f7a3329a1737fcb722576d1fea -address /run/containerd/containerd.sock -containerd-binary /usr/bin/containerd -runtime-root /var/run/docker/runtime-runc
root 7354 1460 0 Jun23 ? 00:00:09 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 3308 -container-ip 172.19.0.3 -container-port 3306
root 7386 1455 0 Jun23 ? 00:09:45 containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/14112371b62521a9b52968a6b0d275700343afeceaac478cfb7a90241dfcdf61 -address /run/containerd/containerd.sock -containerd-binary /usr/bin/containerd -runtime-root /var/run/docker/runtime-runc
root 7402 1460 0 Jun23 ? 00:00:09 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 3307 -container-ip 172.19.0.4 -container-port 3306
root 7431 1455 0 Jun23 ? 00:10:30 containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/a0c6a5d5f891d293ae19e0bc3413729ac41cf38cc7e58d5a547b0f0df87fd6c4 -address /run/containerd/containerd.sock -containerd-binary /usr/bin/containerd -runtime-root /var/run/docker/runtime-runc
root 28336 21582 0 15:32 pts/0 00:00:00 grep --color=auto docker
Docker本地镜像载入与载出
两种办法
- 保存镜像(保存镜像载入后获得跟原镜像id相同的镜像)
- 保存容器(保存容器载入后获得跟原镜像id不同的镜像)
拉取镜像
通过命令可以从镜像仓库中拉取镜像,默认从Docker Hub 获取。
命令格式:
docker image pull :
docker image pull rancher/rke-tools:v0.1.52
[rancher/rke-tools:v0.1.52
保存镜像
- docker save 镜像id -o /home/mysql.tar
- docker save 镜像id > /home/mysql.tar
docker save docker.io/rancher/rancher-agent -o /home/rancher-agent .tar
docker save f29ece87a195 -o /home/rancher-agent.tar
docker save docker.io/rancher/rke-tools -o /home/rke-tools-v0.1.52.tar
载入镜像
- docker load -i mysql.tar
docker load -i /usr/local/rancher-v2.3.5.tar
docker load -i /usr/local/rancher-agent.tar
docker inspect f29ece87a1954772accb8a2332ee8c3fe460697e3f102ffbdc76eb9bc4f4f1d0
docker load -i /usr/local/rke-tools-v0.1.52.tar
docker load -i mysql.tar
[root@localhost ~]# docker load -i /usr/local/rancher-v2.3.5.tar
43c67172d1d1: Loading layer [==================================================>] 65.57MB/65.57MB
21ec61b65b20: Loading layer [==================================================>] 991.2kB/991.2kB
1d0dfb259f6a: Loading layer [==================================================>] 15.87kB/15.87kB
f55aa0bd26b8: Loading layer [==================================================>] 3.072kB/3.072kB
e0af200d6950: Loading layer [==================================================>] 126.1MB/126.1MB
088ed892f9ad: Loading layer [==================================================>] 6.656kB/6.656kB
6aa3142b4130: Loading layer [==================================================>] 34.5MB/34.5MB
f4e84c05ab29: Loading layer [==================================================>] 70.41MB/70.41MB
11a6e4332b53: Loading layer [==================================================>] 224.8MB/224.8MB
46d1ac556da7: Loading layer [==================================================>] 3.072kB/3.072kB
0f8b224a5802: Loading layer [==================================================>] 57.87MB/57.87MB
519eba7d586a: Loading layer [==================================================>] 99.58MB/99.58MB
3f8bb7c0c150: Loading layer [==================================================>] 4.608kB/4.608kB
c22c9a5a8211: Loading layer [==================================================>] 3.072kB/3.072kB
Loaded image: rancher/rancher:v2.3.5
打个tag
docker tag f29ece87a1954772accb8a2332ee8c3fe460697e3f102ffbdc76eb9bc4f4f1d0 rancher/rancher-agent:v2.3.5
docker tag f29ece87a195 172.18.8.104/rancher/rancher-agent:v2.3.5
docker tag 6e421b8753a2 172.18.8.104/rancher/rke-tools:v0.1.52
83fe4871cf67
docker rmi image_name
docker rmi -f 172.18.8.104/rancher/coredns-coredns:1.6.5
docker rmi -f 172.18.8.104/rancher/coredns-coredns:v3.4.3-rancher1
docker rmi hub.doge.net/ubuntu:latest
保存镜像
- docker export 镜像id -o /home/mysql-export.tar
- docker save 镜像tag -o /home/mysql-export.tar
载入镜像
- docker import mysql-export.tar
Docker本地容器相关的操作
创建容器
创建名为"centos6"的容器,并在容器内部和宿主机中查看容器中的进程信息
docker run -itd -p 6080:80 -p 6022:22 docker.io/lemonbar/centos6-ssh:latest
结果如下
[root@VM-4-17-centos ~]# docker run -itd -p 80:80 -p 6022:22 docker.io/lemonbar/centos6-ssh:latest
Unable to find image 'lemonbar/centos6-ssh:latest' locally
latest: Pulling from lemonbar/centos6-ssh
a3ed95caeb02: Pull complete
f79eb1f22352: Pull complete
67c1aaa530c8: Pull complete
80447774eee7: Pull complete
6d67b3a80e5a: Pull complete
f1819e4b2f8f: Pull complete
09712b5b9acc: Pull complete
8bc987c5494f: Pull complete
c42b021d0ff2: Pull complete
Digest: sha256:093c2165b3c6fe05d5658343456f9b59bb7ecc690a7d3a112641c86083227dd1
Status: Downloaded newer image for lemonbar/centos6-ssh:latest
a4f1c9b8abcda78c8764cc285183dfa56cd1aa4ce6d111d4d9e77f3a57f3d5fc
查看活跃容器
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a4f1c9b8abcd lemonbar/centos6-ssh:latest "/bin/sh -c '/usr/sb…" 32 seconds ago Up 31 seconds 0.0.0.0:6022->22/tcp, 0.0.0.0:6080->80/tcp determined_curie
查看全部容器
docker ps -a
停止容器
docker stop id
删除容器
docker rm id
查看容器的进程信息
**docker top 😗*查看容器中运行的进程信息,支持 ps 命令参数。
语法
docker top [OPTIONS] CONTAINER [ps OPTIONS]
容器运行时不一定有/bin/bash终端来交互执行top命令,而且容器还不一定有top命令,可以使用docker top来实现查看container中正在运行的进程。
从Docker 1.11开始,Docker容器运行已经不是简单的通过Docker daemon来启动,而是集成了containerd、runC等多个组件。Docker服务启动之后,我们也可以看见系统上启动了dockerd、docker-containerd等进程,本文主要介绍新版Docker(1.11以后)每个部分的功能和作用。
查找容器名称的命令
[root@localhost ~]# docker ps --format "{{.Names}}"
结果如下:
[root@VM-4-17-centos ~]# docker ps --format "{{.Names}}"
determined_curie
redis
nginx_slave
nginx_master
nginx_empty
loving_agnesi
pxc_proxy
pxc03
pxc02
pxc01
affectionate_austin
nostalgic_blackwell
在容器内部和宿主机中查看容器中的进程信息
docker exec -it determined_curie ps -ef
结果如下:
[root@VM-4-17-centos ~]# docker exec -it determined_curie ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 08:14 pts/0 00:00:00 /usr/sbin/sshd -D
root 5 0 0 08:16 pts/1 00:00:00 ps -ef
我们可以使用docker exec
命令进入容器PID名空间,并执行应用。
通过ps -ef
命令,可以看到每个determined_curie 容器都包含一个PID为1的进程,"/usr/sbin/sshd",它是容器的启动进程,具有特殊意义。
利用docker top
命令,可以让我们从宿主机操作系统中看到容器的进程信息。
[root@VM-4-17-centos ~]# docker top determined_curie
UID PID PPID C STIME TTY TIME CMD
root 27880 27866 0 16:14 pts/0 00:00:00 /usr/sbin/sshd -D
[root@VM-4-17-centos ~]#
查看其父进程信息
root 17205 1414 0 16:37 pts/0 00:00:00 grep --color=auto 27866
root 27866 5587 0 16:14 ? 00:00:00 docker-containerd-shim -namespace moby -workdir /var/lib/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/a4f1c9b8abcda78c8764cc285183dfa56cd1aa4ce6d111d4d9e77f3a57f3d5fc -address /var/run/docker/containerd/docker-containerd.sock -containerd-binary /usr/bin/docker-containerd -runtime-root /var/run/docker/runtime-runc
root 27880 27866 0 16:14 pts/0 00:00:00 /usr/sbin/sshd -D
查看子进程信息
[root@VM-4-17-centos ~]# ps aux | grep 27880
root 17777 0.0 0.0 115928 1008 pts/0 S+ 16:38 0:00 grep --color=auto 27880
root 27880 0.0 0.0 66664 3072 pts/0 Ss+ 16:14 0:00 /usr/sbin/sshd -D
总计三个命令
ps -ef | grep 4948 #查看父进程
ps aux | grep 27880 #查看子进程(容器)
docker ps -a | grep determined_curie #定位容器id
再启动一个 centos 容器
docker run -itd --name centos6-2 -p 6081:80 -p 6021:22 docker.io/lemonbar/centos6-ssh:latest
输出如下:
[root@VM-4-17-centos ~]# docker run -itd --name centos6-2 -p 6081:80 -p 6021:22 docker.io/lemonbar/centos6-ssh:latest
460d688239304172f39bb9586bfc5959e0c3db64e7c3a0937f1003f94408ebbd
查看进程信息
利用docker top
命令,可以让我们从宿主机操作系统中看到容器的进程信息。
[root@VM-4-17-centos ~]# docker top centos6-2
UID PID PPID C STIME TTY TIME CMD
root 4962 4948 0 16:24 pts/0 00:00:00 /usr/sbin/sshd -D
查看其父进程信息
[root@VM-4-17-centos ~]# ps -ef | grep 4948
root 4948 5587 0 16:24 ? 00:00:00 docker-containerd-shim -namespace moby -workdir /var/lib/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/460d688239304172f39bb9586bfc5959e0c3db64e7c3a0937f1003f94408ebbd -address /var/run/docker/containerd/docker-containerd.sock -containerd-binary /usr/bin/docker-containerd -runtime-root /var/run/docker/runtime-runc
root 4962 4948 0 16:24 pts/0 00:00:00 /usr/sbin/sshd -D
查看子进程信息
[root@VM-4-17-centos ~]# ps aux | grep 4962
root 4962 0.0 0.0 66664 3068 pts/0 Ss+ 16:24 0:00 /usr/sbin/sshd -D
root 15311 0.0 0.0 115932 1008 pts/0 S+ 16:35 0:00 grep --color=auto 4962
总计三个命令
ps -ef | grep 4948 #查看父进程
ps aux | grep 4962 #查看子进程(容器)
docker ps -a | grep centos6-2 #定位容器id
进程的对应关系
Linux通过进程ID查看文件路径
子进程的文件路径
[root@VM-4-17-centos ~]# ls -l /proc/27880
total 0
dr-xr-xr-x 2 root root 0 Nov 3 16:41 attr
-rw-r--r-- 1 root root 0 Nov 3 16:41 autogroup
-r-------- 1 root root 0 Nov 3 16:41 auxv
-r--r--r-- 1 root root 0 Nov 3 16:14 cgroup
--w------- 1 root root 0 Nov 3 16:41 clear_refs
-r--r--r-- 1 root root 0 Nov 3 16:15 cmdline
-rw-r--r-- 1 root root 0 Nov 3 16:41 comm
-rw-r--r-- 1 root root 0 Nov 3 16:41 coredump_filter
-r--r--r-- 1 root root 0 Nov 3 16:41 cpuset
lrwxrwxrwx 1 root root 0 Nov 3 16:41 cwd -> /
-r-------- 1 root root 0 Nov 3 16:41 environ
lrwxrwxrwx 1 root root 0 Nov 3 16:14 exe -> /usr/sbin/sshd
dr-x------ 2 root root 0 Nov 3 16:14 fd
dr-x------ 2 root root 0 Nov 3 16:41 fdinfo
-rw-r--r-- 1 root root 0 Nov 3 16:41 gid_map
-r-------- 1 root root 0 Nov 3 16:41 io
-r--r--r-- 1 root root 0 Nov 3 16:41 limits
-rw-r--r-- 1 root root 0 Nov 3 16:41 loginuid
dr-x------ 2 root root 0 Nov 3 16:41 map_files
-r--r--r-- 1 root root 0 Nov 3 16:41 maps
-rw------- 1 root root 0 Nov 3 16:41 mem
-r--r--r-- 1 root root 0 Nov 3 16:14 mountinfo
-r--r--r-- 1 root root 0 Nov 3 16:41 mounts
-r-------- 1 root root 0 Nov 3 16:41 mountstats
dr-xr-xr-x 5 root root 0 Nov 3 16:41 net
dr-x--x--x 2 root root 0 Nov 3 16:14 ns
-r--r--r-- 1 root root 0 Nov 3 16:41 numa_maps
-rw-r--r-- 1 root root 0 Nov 3 16:41 oom_adj
-r--r--r-- 1 root root 0 Nov 3 16:41 oom_score
-rw-r--r-- 1 root root 0 Nov 3 16:41 oom_score_adj
-r--r--r-- 1 root root 0 Nov 3 16:41 pagemap
-r-------- 1 root root 0 Nov 3 16:41 patch_state
-r--r--r-- 1 root root 0 Nov 3 16:41 personality
-rw-r--r-- 1 root root 0 Nov 3 16:41 projid_map
lrwxrwxrwx 1 root root 0 Nov 3 16:41 root -> /
-rw-r--r-- 1 root root 0 Nov 3 16:41 sched
-r--r--r-- 1 root root 0 Nov 3 16:41 schedstat
-r--r--r-- 1 root root 0 Nov 3 16:41 sessionid
-rw-r--r-- 1 root root 0 Nov 3 16:41 setgroups
-r--r--r-- 1 root root 0 Nov 3 16:41 smaps
-r--r--r-- 1 root root 0 Nov 3 16:41 stack
-r--r--r-- 1 root root 0 Nov 3 16:14 stat
-r--r--r-- 1 root root 0 Nov 3 16:41 statm
-r--r--r-- 1 root root 0 Nov 3 16:14 status
-r--r--r-- 1 root root 0 Nov 3 16:41 syscall
dr-xr-xr-x 3 root root 0 Nov 3 16:41 task
-r--r--r-- 1 root root 0 Nov 3 16:41 timers
-rw-r--r-- 1 root root 0 Nov 3 16:14 uid_map
-r--r--r-- 1 root root 0 Nov 3 16:41 wchan
以下是/proc目录中进程27880的信息说明:
proc/27880 pid为N的进程信息
/proc/27880/cmdline 进程启动命令
/proc/27880/cwd 链接到进程当前工作目录
/proc/27880/environ 进程环境变量列表
/proc/27880/exe 链接到进程的执行命令文件
/proc/27880/fd 包含进程相关的所有的文件描述符
/proc/27880/maps 与进程相关的内存映射信息
/proc/27880/mem 指代进程持有的内存,不可读
/proc/27880/root 链接到进程的根目录
/proc/27880/stat 进程的状态
/proc/27880/statm 进程使用的内存的状态
/proc/27880/status 进程状态信息,比stat/statm更具可读性
容器的PID namespace(命名空间)
在Docker中,进程管理的基础就是Linux内核中的PID名空间技术。
在不同PID名空间中,进程ID是独立的;即在两个不同名空间下的进程可以有相同的PID。
在Docker中,每个Container进程缺省都具有不同的PID名空间。通过名空间技术,Docker实现容器间的进程隔离。
docker中运行的容器进程,本质上还是运行在宿主机上的,所以也会拥有相对应的PID
找出容器ID
# docker ps
输出
[root@VM-4-17-centos ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
460d68823930 lemonbar/centos6-ssh:latest "/bin/sh -c '/usr/sb…" 32 minutes ago Up 32 minutes 0.0.0.0:6021->22/tcp, 0.0.0.0:6081->80/tcp centos6-2
查看容器信息
docker inspect id
输出
[root@VM-4-17-centos ~]# docker inspect 460d68823930
[root@VM-4-17-centos ~]# docker inspect 460d68823930
[
{
"Id": "460d688239304172f39bb9586bfc5959e0c3db64e7c3a0937f1003f94408ebbd",
"Created": "2021-11-03T08:24:36.934129599Z",
"Path": "/bin/sh",
"Args": [
"-c",
"/usr/sbin/sshd -D"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 4962,
"ExitCode": 0,
"Error": "",
"StartedAt": "2021-11-03T08:24:37.223255812Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:efd998bd6817af509d348b488e3ce4259f9f05632644a7bf574b785bbc8950b8",
"ResolvConfPath": "/var/lib/docker/containers/460d688239304172f39bb9586bfc5959e0c3db64e7c3a0937f1003f94408ebbd/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/460d688239304172f39bb9586bfc5959e0c3db64e7c3a0937f1003f94408ebbd/hostname",
"HostsPath": "/var/lib/docker/containers/460d688239304172f39bb9586bfc5959e0c3db64e7c3a0937f1003f94408ebbd/hosts",
"LogPath": "/var/lib/docker/containers/460d688239304172f39bb9586bfc5959e0c3db64e7c3a0937f1003f94408ebbd/460d688239304172f39bb9586bfc5959e0c3db64e7c3a0937f1003f94408ebbd-json.log",
"Name": "/centos6-2",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "default",
"PortBindings": {
"22/tcp": [
{
"HostIp": "",
"HostPort": "6021"
}
],
"80/tcp": [
{
"HostIp": "",
"HostPort": "6081"
}
]
},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": null,
"CapDrop": null,
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "shareable",
"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,
"DiskQuota": 0,
"KernelMemory": 0,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": false,
"PidsLimit": 0,
"Ulimits": null,
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0
},
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/6835c1b48237aafe27e2efabeda92a3a6623f254f88d54b5e6acce454e560dd6-init/diff:/var/lib/docker/overlay2/7139bf0b716c6e0b6a0c709b7043466f9bbfd7024f8ae584061c00b0bd97348c/diff:/var/lib/docker/overlay2/66a3e278259cdcf50741ce30a115baa3bd6247a60c487e4118e85f2f39328f11/diff:/var/lib/docker/overlay2/20e22c4c28ebadb615eb4c7c290253d3eb91cb49722ee2931b0ee628352a5857/diff:/var/lib/docker/overlay2/a3fa9dbebc83a853083205b8f7921c632cd67f64531f4a25cab419a43172e3ae/diff:/var/lib/docker/overlay2/3af7958c9a4e54d24598058a9fa1e85eb35e3d40f766fa498a674b52724ae73e/diff:/var/lib/docker/overlay2/becb65af4396137ed41fe6d516e834e6e6e9120f4edfac8e2ca8dd67cce23268/diff:/var/lib/docker/overlay2/fef055305158cc96906514c447f0eaea05945138896b0b35ac4146b6a2a3e273/diff:/var/lib/docker/overlay2/79158cdf3ba832493ab0d02d560c784208fe51c74236a5a86f7fb4fb50ab6e44/diff:/var/lib/docker/overlay2/86258a18e1110582b819719593687f11f0404d00a41667b3432c3b974fb1ce42/diff:/var/lib/docker/overlay2/8826b2e0068653fb2c5e8a3dbf839470e2b8eef8cf752b5fe901bea1b210849f/diff:/var/lib/docker/overlay2/145301e2738a8a7581c2bbd5beb9bf7a49b247e46642b8084efbc026a1826116/diff:/var/lib/docker/overlay2/f621f37535e0db1fe44902e22dba7ef0844b9a8b562a9daa39a842a49e9cc9bb/diff:/var/lib/docker/overlay2/7b493e4a97907aaa18b97ad2e9120b5bf87c0e9908ee390a35ea6ff546d8cec6/diff",
"MergedDir": "/var/lib/docker/overlay2/6835c1b48237aafe27e2efabeda92a3a6623f254f88d54b5e6acce454e560dd6/merged",
"UpperDir": "/var/lib/docker/overlay2/6835c1b48237aafe27e2efabeda92a3a6623f254f88d54b5e6acce454e560dd6/diff",
"WorkDir": "/var/lib/docker/overlay2/6835c1b48237aafe27e2efabeda92a3a6623f254f88d54b5e6acce454e560dd6/work"
},
"Name": "overlay2"
},
"Mounts": [],
"Config": {
"Hostname": "460d68823930",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"22/tcp": {},
"80/tcp": {}
},
"Tty": true,
"OpenStdin": true,
"StdinOnce": false,
"Env": [
"HOME=/",
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/sh",
"-c",
"/usr/sbin/sshd -D"
],
"Image": "docker.io/lemonbar/centos6-ssh:latest",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "ea66261fb6d8089d5b2d585a2dc32b2003365df7118f5f5e898a152fb5b35773",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {
"22/tcp": [
{
"HostIp": "0.0.0.0",
"HostPort": "6021"
}
],
"80/tcp": [
{
"HostIp": "0.0.0.0",
"HostPort": "6081"
}
]
},
"SandboxKey": "/var/run/docker/netns/ea66261fb6d8",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "09ad719a4e9115ee56c5fb0f5b0d39c50bf5acaf0a1afacedc13969c82a2969f",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.6",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:06",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "2586283d16a08210c955d705f05e0f6999b59523a84b0c163e33f535af809ddd",
"EndpointID": "09ad719a4e9115ee56c5fb0f5b0d39c50bf5acaf0a1afacedc13969c82a2969f",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.6",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:06",
"DriverOpts": null
}
}
}
}
]
进入相应目录
# cd /sys/fs/cgroup/memory/docker/460d688239304172f39bb9586bfc5959e0c3db64e7c3a0937f1003f94408ebbd/
输出
cd /sys/fs/cgroup/memory/docker/460d688239304172f39bb9586bfc5959e0c3db64e7c3a0937f1003f94408ebbd/
[root@VM-4-17-centos 460d688239304172f39bb9586bfc5959e0c3db64e7c3a0937f1003f94408ebbd]# ll
total 0
-rw-r--r-- 1 root root 0 Nov 3 16:24 cgroup.clone_children
--w--w--w- 1 root root 0 Nov 3 16:24 cgroup.event_control
-rw-r--r-- 1 root root 0 Nov 3 16:24 cgroup.procs
-rw-r--r-- 1 root root 0 Nov 3 16:24 memory.failcnt
--w------- 1 root root 0 Nov 3 16:24 memory.force_empty
-rw-r--r-- 1 root root 0 Nov 3 16:24 memory.kmem.failcnt
-rw-r--r-- 1 root root 0 Nov 3 16:24 memory.kmem.limit_in_bytes
-rw-r--r-- 1 root root 0 Nov 3 16:24 memory.kmem.max_usage_in_bytes
-r--r--r-- 1 root root 0 Nov 3 16:24 memory.kmem.slabinfo
-rw-r--r-- 1 root root 0 Nov 3 16:24 memory.kmem.tcp.failcnt
-rw-r--r-- 1 root root 0 Nov 3 16:24 memory.kmem.tcp.limit_in_bytes
-rw-r--r-- 1 root root 0 Nov 3 16:24 memory.kmem.tcp.max_usage_in_bytes
-r--r--r-- 1 root root 0 Nov 3 16:24 memory.kmem.tcp.usage_in_bytes
-r--r--r-- 1 root root 0 Nov 3 16:24 memory.kmem.usage_in_bytes
-rw-r--r-- 1 root root 0 Nov 3 16:24 memory.limit_in_bytes
-rw-r--r-- 1 root root 0 Nov 3 16:24 memory.max_usage_in_bytes
-rw-r--r-- 1 root root 0 Nov 3 16:24 memory.memsw.failcnt
-rw-r--r-- 1 root root 0 Nov 3 16:24 memory.memsw.limit_in_bytes
-rw-r--r-- 1 root root 0 Nov 3 16:24 memory.memsw.max_usage_in_bytes
-r--r--r-- 1 root root 0 Nov 3 16:24 memory.memsw.usage_in_bytes
-rw-r--r-- 1 root root 0 Nov 3 16:24 memory.move_charge_at_immigrate
-r--r--r-- 1 root root 0 Nov 3 16:24 memory.numa_stat
-rw-r--r-- 1 root root 0 Nov 3 16:24 memory.oom_control
---------- 1 root root 0 Nov 3 16:24 memory.pressure_level
-rw-r--r-- 1 root root 0 Nov 3 16:24 memory.soft_limit_in_bytes
-r--r--r-- 1 root root 0 Nov 3 16:24 memory.stat
-rw-r--r-- 1 root root 0 Nov 3 16:24 memory.swappiness
-r--r--r-- 1 root root 0 Nov 3 16:24 memory.usage_in_bytes
-rw-r--r-- 1 root root 0 Nov 3 16:24 memory.use_hierarchy
-rw-r--r-- 1 root root 0 Nov 3 16:24 notify_on_release
-rw-r--r-- 1 root root 0 Nov 3 16:24 tasks
[root@VM-4-17-centos 460d688239304172f39bb9586bfc5959e0c3db64e7c3a0937f1003f94408ebbd]# cat cgroup.procs
4962
11539
[root@VM-4-17-centos 460d688239304172f39bb9586bfc5959e0c3db64e7c3a0937f1003f94408ebbd]# cat pids.max
max
[root@VM-4-17-centos 460d688239304172f39bb9586bfc5959e0c3db64e7c3a0937f1003f94408ebbd]# cat tasks
4962
11539
[root@VM-4-17-centos 460d688239304172f39bb9586bfc5959e0c3db64e7c3a0937f1003f94408ebbd]# cat cgroup.clone_children
0
[root@VM-4-17-centos 460d688239304172f39bb9586bfc5959e0c3db64e7c3a0937f1003f94408ebbd]# pwd
/sys/fs/cgroup/pids/docker/460d688239304172f39bb9586bfc5959e0c3db64e7c3a0937f1003f94408ebbd
查看容器目录里的进程号
进程号就存在一个文件里面
[root@VM-4-17-centos 460d688239304172f39bb9586bfc5959e0c3db64e7c3a0937f1003f94408ebbd]#
cat cgroup.procs
4962
与前面利用docker top
命令,可以让我们从宿主机操作系统中看到容器的进程信息。
[root@VM-4-17-centos ~]# docker top centos6-2
UID PID PPID C STIME TTY TIME CMD
root 4962 4948 0 16:24 pts/0 00:00:00 /usr/sbin/sshd -D
启动一个进程
我们下面会在 centos6-2容器中,利用docker exec
命令启动一个"sleep"进程
[root@VM-4-17-centos ]# docker exec -d centos6-2 sleep 2000
[root@VM-4-17-centos ]# docker exec centos6-2 ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 08:24 pts/0 00:00:00 /usr/sbin/sshd -D
root 6 0 0 09:06 ? 00:00:00 sleep 2000
root 10 0 0 09:06 ? 00:00:00 ps -ef
查看宿主机的进程号
[root@VM-4-17-centos ]# docker top centos6-2
UID PID PPID C STIME TTY TIME CMD
root 4962 4948 0 16:24 pts/0 00:00:00 /usr/sbin/sshd -D
root 11539 4948 0 17:06 ? 00:00:00 sleep 2000
我们可以清楚的看到exec命令创建的sleep进程属 centos6-2 容器的名空间,但是它的父进程是Docker 容器的启动进程。
查看容器目录里的进程号
进程号就存在一个文件里面
[root@VM-4-17-centos 460d688239304172f39bb9586bfc5959e0c3db64e7c3a0937f1003f94408ebbd]# cat cgroup.procs
4962
11539
docker exec -d centos6-2 pstree -p
docker exec -d centos6-2 ps -auxf
docker exec -d centos6-2 ll /proc
输出
[root@VM-4-17-centos docker]# docker exec centos6-2 ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 08:24 pts/0 00:00:00 /usr/sbin/sshd -D
root 6 0 0 09:06 ? 00:00:00 sleep 2000
root 40 0 0 09:26 ? 00:00:00 ps -ef
[root@VM-4-17-centos docker]# docker exec centos6-2 ps -auxf
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 44 0.0 0.0 13360 1012 ? Rs 09:26 0:00 ps -auxf
root 6 0.0 0.0 4120 316 ? Ss 09:06 0:00 sleep 2000
root 1 0.0 0.0 66664 3068 pts/0 Ss+ 08:24 0:00 /usr/sbin/sshd -D
Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ
[root@VM-4-17-centos docker]# docker exec centos6-2 pstree -p
sshd(1)
Docker文件目录和容器内部操作
Docker默认的文件目录位于Linux server的/var/lib/docker 下面。目录结构如下
|-----containers:用于存储容器信息
|-----image:用来存储镜像中间件及本身信息,大小,依赖信息
|-----network
|-----swarm
|-----tmp:docker临时目录
|-----trust:docker信任目录
|-----volumes:docker卷目录
还可以通过docker指令确认文件位置:
docker info
查看某个容器的文件目录:
docker exec 容器name ls
docker exec centos6-2 ls /proc
[root@VM-4-17-centos containers]# docker exec centos6-2 ls /proc
1
103
acpi
buddyinfo
bus
cgroups
cmdline
consoles
cpuinfo
crypto
devices
diskstats
dma
driver
execdomains
fb
filesystems
fs
interrupts
iomem
ioports
irq
kallsyms
kcore
key-users
keys
kmsg
kpagecount
kpageflags
loadavg
locks
mdstat
meminfo
misc
modules
mounts
mtrr
net
pagetypeinfo
partitions
sched_debug
schedstat
scsi
self
slabinfo
softirqs
stat
swaps
sys
sysrq-trigger
sysvipc
timer_list
timer_stats
tty
uptime
version
vmallocinfo
vmstat
zoneinfo
docker daemon (docker守护进程)
pidof dockerd #查看docker守护进程pid
lsof -p 3197 | wc -l #docker守护进程打开的文件数
在两个容器中的"centos "是两个独立的进程,但是他们拥有相同的父进程 Docker Daemon。
所以Docker可以父子进程的方式在Docker Daemon和Redis容器之间进行交互。
另一个值得注意的方面是,docker exec
命令可以进入指定的容器内部执行命令。由它启动的进程属于容器的namespace和相应的cgroup。
但是这些进程的父进程是Docker Daemon而非容器的PID1进程。
我们下面会在Redis容器中,利用docker exec
命令启动一个"sleep"进程
docker@default:~$ docker exec -d redis sleep 2000
docker@default:~$ docker exec redis ps -ef
UID PID PPID C STIME TTY TIME CMD
redis 1 0 0 02:26 ? 00:00:00 redis-server *:6379
root 11 0 0 02:26 ? 00:00:00 sleep 2000
root 21 0 0 02:29 ? 00:00:00 ps -ef
docker@default:~$ docker top redis
UID PID PPID C STIME TTY TIME CMD
999 9955 1264 0 02:12 ? 00:00:00 redis-server *:6379
root 9984 1264 0 02:13 ? 00:00:00 sleep 2000
我们可以清楚的看到exec命令创建的sleep进程属Redis容器的名空间,但是它的父进程是Docker Daemon。
如果我们在宿主机操作系统中手动杀掉容器的启动进程(在上文示例中是redis-server),容器会自动结束,而容器名空间中所有进程也会退出。
docker@default:~$ PID=$(docker inspect --format="{{.State.Pid}}" redis)
docker@default:~$ sudo kill $PID
docker@default:~$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
356eca186321 redis "/entrypoint.sh redis" 23 minutes ago Up 4 minutes 6379/tcp redis2
f6bc57cc1b46 redis "/entrypoint.sh redis" 23 minutes ago Exited (0) 4 seconds ago redis
通过以上示例:
- 每个容器有独立的PID名空间,
- 容器的生命周期和其PID1进程一致
- 利用
docker exec
可以进入到容器的名空间中启动进程
Docker Daemon 原理
作为Docker容器管理的守护进程,Docker Daemon从最初集成在docker
命令中(1.11版本前),到后来的独立成单独二进制程序(1.11版本开始),其功能正在逐渐拆分细化,被分配到各个单独的模块中去。
演进:Docker守护进程启动
从Docker服务的启动脚本,也能看见守护进程的逐渐剥离:
在Docker 1.8之前,Docker守护进程启动的命令为:
docker -d
这个阶段,守护进程看上去只是Docker client的一个选项。
Docker 1.8开始,启动命令变成了:
docker daemon
这个阶段,守护进程看上去是docker
命令的一个模块。
Docker 1.11开始,守护进程启动命令变成了:
dockerd
其服务的配置文件为:
[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd
ExecReload=/bin/kill -s HUP $MAINPID
此时已经和Docker client分离,独立成一个二进制程序了。
当然,守护进程模块不停的在重构,其基本功能和定位没有变化。和一般的CS架构系统一样,守护进程负责和Docker client交互,并管理Docker镜像、容器。
OCI(Open Container Initiative)
Open Container Initiative,也就是常说的OCI,是由多家公司共同成立的项目,并由linux基金会进行管理,致力于container runtime的标准的制定和runc的开发等工作。
官方的介绍是
An open governance structure for the express purpose of creating open industry standards around container formats and runtime. – Open Containers Official Site
所谓container runtime,主要负责的是容器的生命周期的管理。oci的runtime spec标准中对于容器的状态描述,以及对于容器的创建、删除、查看等操作进行了定义。
目前主要有两个标准文档:容器运行时标准 (runtime spec)和 容器镜像标准(image spec)。
这两个协议通过 OCI runtime filesytem bundle 的标准格式连接在一起,OCI 镜像可以通过工具转换成 bundle,然后 OCI 容器引擎能够识别这个 bundle 来运行容器。
image spec
OCI 容器镜像主要包括几块内容:
文件系统:以 layer 保存的文件系统,每个 layer 保存了和上层之间变化的部分,layer 应该保存哪些文件,怎么表示增加、修改和删除的文件等
config 文件:保存了文件系统的层级信息(每个层级的 hash 值,以及历史信息),以及容器运行时需要的一些信息(比如环境变量、工作目录、命令参数、mount 列表),指定了镜像在某个特定平台和系统的配置。比较接近我们使用 docker inspect <image_id> 看到的内容
manifest 文件:镜像的 config 文件索引,有哪些 layer,额外的 annotation 信息,manifest 文件中保存了很多和当前平台有关的信息
index 文件:可选的文件,指向不同平台的 manifest 文件,这个文件能保证一个镜像可以跨平台使用,每个平台拥有不同的 manifest 文件,使用 index 作为索引
runtime spec
OCI 对容器 runtime 的标准主要是指定容器的运行状态,和 runtime 需要提供的命令。下图可以是容器状态转换图:
Docker CLI
/usr/bin/docker
Docker 的客户端工具,通过CLI与 dockerd API 交流。 CLI 的例子比如docker build … docker run …
Docker Daemon
/usr/bin/dockerd
当然,守护进程模块不停的在重构,其基本功能和定位没有变化。和一般的CS架构系统一样,守护进程负责和Docker client交互,并管理Docker镜像、容器。
Containerd
/usr/bin/docker-containerd
containerd是容器技术标准化之后的产物,为了能够兼容OCI标准,将容器运行时及其管理功能从Docker Daemon剥离。理论上,即使不运行dockerd,也能够直接通过containerd来管理容器。(当然,containerd本身也只是一个守护进程,容器的实际运行时由后面介绍的runC控制。)
最近,Docker刚刚宣布开源containerd。从其项目介绍页面可以看出,containerd主要职责是镜像管理(镜像、元信息等)、容器执行(调用最终运行时组件执行)。
containerd向上为Docker Daemon提供了gRPC接口,使得Docker Daemon屏蔽下面的结构变化,确保原有接口向下兼容。向下通过containerd-shim结合runC,使得引擎可以独立升级,避免之前Docker Daemon升级会导致所有容器不可用的问题。
containerd fully leverages the OCI runtime specification1, image format specifications and OCI reference implementation (runc).
containerd includes a daemon exposing gRPC API over a local UNIX socket. The API is a low-level one designed for higher layers to wrap and extend. Containerd uses RunC to run containers according to the OCI specification.
docker-shim
/usr/bin/docker-containerd-shim
每启动一个容器都会起一个新的docker-shim的一个进程.
他直接通过指定的三个参数来创建一个容器:
- 容器id
- boundle目录(containerd的对应某个容器生成的目录,一般位于:/var/run/docker/libcontainerd/containerID)
- 运行是二进制(默认为runc)来调用runc的api(比如创建容器时,最后拼装的命令如下:runc create 。。。)
他的作用是:
- 它允许容器运行时(即 runC)在启动容器之后退出,简单说就是不必为每个容器一直运行一个容器运行时(runC)
- 即使在 containerd 和 dockerd 都挂掉的情况下,容器的标准 IO 和其它的文件描述符也都是可用的
- 向 containerd 报告容器的退出状态
前两点尤其重要,有了它们就可以在不中断容器运行的情况下升级或重启 dockerd(这对于生产环境来说意义重大)。
runc (OCI reference implementation)
/usr/bin/docker-runc
OCI定义了容器运行时标准OCI Runtime Spec support (aka runC),runC是Docker按照开放容器格式标准(OCF, Open Container Format)制定的一种具体实现。
runC是从Docker的libcontainer中迁移而来的,实现了容器启停、资源隔离等功能。
Docker默认提供了docker-runc实现,事实上,通过containerd的封装,可以在Docker Daemon启动的时候指定runc的实现。
我们可以通过启动Docker Daemon时增加–add-runtime参数来选择其他的runC现。例如:
docker daemon --add-runtime "custom=/usr/local/bin/my-runc-replacement"
Docker、containerd, containerd-shim和runc之间的关系
他们之间的关系如下图:
我们可以通过启动一个Docker容器,来观察进程之间的关联。
通过docker 而通过runc来启动一个container的过程
查看进程信息
利用docker top
命令,可以让我们从宿主机操作系统中看到容器的进程信息。
[root@VM-4-17-centos ~]# docker top centos6-2
UID PID PPID C STIME TTY TIME CMD
root 4962 4948 0 16:24 pts/0 00:00:00 /usr/sbin/sshd -D
查看子进程信息
[root@VM-4-17-centos containerd]# ps aux | grep 4948
root 4948 0.0 0.0 12212 3696 ? Sl 16:24 0:00 docker-containerd-shim -namespace moby -workdir /var/lib/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/460d688239304172f39bb9586bfc5959e0c3db64e7c3a0937f1003f94408ebbd -address /var/run/docker/containerd/docker-containerd.sock -containerd-binary /usr/bin/docker-containerd -runtime-root /var/run/docker/runtime-runc
root 27040 0.0 0.0 115932 1004 pts/0 S+ 18:32 0:00 grep --color=auto 4948
查看进程树
pstree -l -a -A 4948 -p
输出结果如下:
[root@VM-4-17-centos containerd]# pstree -l -a -A 4948 -p
docker-containe,4948 -namespace moby -workdir /var/lib/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/460d688239304172f39bb9586bfc5959e0c3db64e7c3a0937f1003f94408ebbd -address /var/run/docker/containerd/docker-containerd.sock -containerd-binary /usr/bin/docker-containerd -runtime-root /var/run/docker/runtime-runc
|-sshd,4962 -D
|-{docker-containe},4949
|-{docker-containe},4950
|-{docker-containe},4951
|-{docker-containe},4952
|-{docker-containe},4953
|-{docker-containe},4954
`-{docker-containe},1593
虽然pstree
命令截断了命令,但我们还是能够看出,当Docker daemon启动之后,dockerd和docker-containerd进程一直存在。
当启动容器之后,docker-containerd进程(也是这里介绍的containerd组件)会创建docker-containerd-shim进程,其中的参数460d688239304172f39bb9586bfc5959e0c3db64e7c3a0937f1003f94408ebbd就是要启动容器的id。
最后docker-containerd-shim子进程,已经是实际在容器中运行的进程(既sleep 1000)。
docker-containerd-shim另一个参数,是一个和容器相关的目录/var/run/docker/containerd/460d688239304172f39bb9586bfc5959e0c3db64e7c3a0937f1003f94408ebbd,里面的内容有:
[root@VM-4-17-centos containerd]# ll /var/run/docker/containerd/460d688239304172f39bb9586bfc5959e0c3db64e7c3a0937f1003f94408ebbd
total 0
prwx------ 1 root root 0 Nov 3 16:24 init-stdin
prwx------ 1 root root 0 Nov 3 16:24 init-stdout
其中包括了容器配置和标准输入、标准输出、标准错误三个管道文件。
docker-shim
docker-shim是一个真实运行的容器的真实垫片载体,每启动一个容器都会起一个新的docker-shim的一个进程,
他直接通过指定的三个参数:容器id,boundle目录(containerd的对应某个容器生成的目录,一般位于:/var/run/docker/libcontainerd/containerID),
运行是二进制(默认为runc)来调用runc的api创建一个容器(比如创建容器:最后拼装的命令如下:runc create 。。。。。)
RunC
OCI定义了容器运行时标准,runC是Docker按照开放容器格式标准(OCF, Open Container Format)制定的一种具体实现。
runC是从Docker的libcontainer中迁移而来的,实现了容器启停、资源隔离等功能。Docker默认提供了docker-runc实现,事实上,通过containerd的封装,可以在Docker Daemon启动的时候指定runc的实现。
CRI
kubernetes在初期版本里,就对多个容器引擎做了兼容,因此可以使用docker、rkt对容器进行管理。以docker为例,kubelet中会启动一个docker manager,通过直接调用docker的api进行容器的创建等操作。
在k8s 1.5版本之后,kubernetes推出了自己的运行时接口api–CRI(container runtime interface)。cri接口的推出,隔离了各个容器引擎之间的差异,而通过统一的接口与各个容器引擎之间进行互动。
与oci不同,cri与kubernetes的概念更加贴合,并紧密绑定。cri不仅定义了容器的生命周期的管理,还引入了k8s中pod的概念,并定义了管理pod的生命周期。
在kubernetes中,pod是由一组进行了资源限制的,在隔离环境中的容器组成。而这个隔离环境,称之为PodSandbox。在cri开始之初,主要是支持docker和rkt两种。其中kubelet是通过cri接口,调用docker-shim,并进一步调用docker api实现的。
如上文所述,docker独立出来了containerd。kubernetes也顺应潮流,孵化了cri-containerd项目,用以将containerd接入到cri的标准中。
为了进一步与oci进行兼容,kubernetes还孵化了cri-o,成为了架设在cri和oci之间的一座桥梁。通过这种方式,可以方便更多符合oci标准的容器运行时,接入kubernetes进行集成使用。可以预见到,通过cri-o,kubernetes在使用的兼容性和广泛性上将会得到进一步加强。
安装docker-compose
Docker-Compose 项目是Docker官方的开源项目,负责实现对Docker容器集群的快速编排。
Docker-Compose 项目由 Python 编写,调用 Docker 服务提供的API来对容器进行管理。因此,只要所操作的平台支持 Docker API,就可以在其上利用Compose 来进行编排管理。
首先检查 版本
[root@k8s-master ~]# /usr/local/bin/docker-compose -version
docker-compose version 1.25.1, build a82fef07
如果安装好了,就ok了,如果没有安装,则安装docker
1.从github上下载docker-compose二进制文件安装
下载最新版的docker-compose文件
# curl -L https://github.com/docker/compose/releases/download/1.25.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
注明:离线安装包已经提供。上传后,复制到/usr/local/bin/即可
cp /root/docker-compose /usr/local/bin/
添加可执行权限
# chmod +x /usr/local/bin/docker-compose
测试安装结果
[root@localhost ~]# docker-compose --version
docker-compose version 1.25.1, build a82fef07
cp /root/docker-compose /usr/local/bin/
chmod +x /usr/local/bin/docker-compose
docker-compose --version
参考文献:
https://blog.csdn.net/qq_21222149/article/details/89201744
https://blog.csdn.net/warrior_0319/article/details/80073720
http://www.sel.zju.edu.cn/?p=840
http://alexander.holbreich.org/docker-components-explained/
https://www.cnblogs.com/sparkdev/p/9129334.htmls
更多推荐
所有评论(0)