Docker基础
Docker概述
-
Docker基于容器技术的轻量级虚拟化解决方案
-
Docker是容器引擎,把Linux的
cgroup
、namespace
等容器底层技术进行封装抽象为用户提供了创建和管理容器的便捷界面(包括命令行和API) -
Docker是一个开源项目,诞生于2013年初,基于Google公司推出的Go语言实现
-
微软,红帽Linux,IBM,Oracle等主流IT厂商已经在自己的产品里增加对Docker的支持
-
相比其他早期的容器技术,Docker引入了一整套容器管理的生态系统,包括分层的镜像模型,容器注册库,友好的Rest API
Linux 容器的具体实现方式
一个“容器”,实际上是一个由Linux Namespace、Linux Cgroups 和 rootfs 三种技术构建出来的进程的隔离环境。
Namespace
的作用是“隔离”,它让应用进程只能看到该 Namespace 内的“世界”;修改进程视图的主要方法Cgroups
的作用是“限制”,它给这个“世界”围上了一圈看不见的墙。制造约束的主要手段- 一组联合挂载在 /var/lib/docker/aufs/mnt 上的
rootfs
,这一部分我们称为“容器镜像”(Container Image),是容器的静态视图;一个由 Namespace+Cgroups 构成的隔离环境,这一部分我们称为“容器运行时”(Container Runtime),是容器的动态视图。
namespace机制
在容器中看到只有自己一个进程 ,但是这个进程其实是在宿主机上的 只不过是一个独立的namespace
定义了5个命名空间结构体,多个进程可以使用同一个namespace
- UTS: 运行内核的名称、版本、底层体系结构类型等信息(UNIX Timesharing System)
- IPC: 与进程间通信(IPC)有关
- MNT: 已经装载的文件系统的视图 Mount Namespace,用于让被隔离进程只看到当前 Namespace 里的挂载点信息
- PID:有关进程ID的信息
- NET:网络相关的命名空间参数 Network Namespace,用于让被隔离进程看到当前 Namespace 里的网络设备和配置。
在 Linux 内核中,有很多资源和对象是不能被 Namespace 化的,最典型的例子就是:时间
cgroup技术
Linux Cgroups 就是 Linux 内核中用来为进程设置资源限制的一个重要功能。
- Linux Cgroups 的全称是 Linux Control Group。它最主要的作用,就是限制一个进程组能够使用的资源上限,包括 CPU、内存、磁盘、网络带宽等等。
- 此外,Cgroups 还能够对进程进行优先级设置、审计,以及将进程挂起和恢复等操作
- 一个正在运行的 Docker 容器,其实就是一个启用了多个 Linux Namespace 的应用进程,而这个进程能够使用的资源量,则受 Cgroups 配置的限制。这也是容器技术中一个非常重要的概念,即:容器是一个
单进程
模型。 - centos ubuntu等本来就是用的相同的linux内核,但是其他操作系统的一些可执行文件等等就是各个linux发行版不同的地方了。
Cgroups技术针对进程而言的,在centos7系统上,可以通过以下方式来实现对进程的资源限制:
while :;do :;done &
[1] 2702
pidstat -u -p 2702 2 # 未加cgroups限制下,跑满单个CPU核心
11:09:54 AM UID PID %usr %system %guest %CPU CPU Command
11:09:56 AM 0 2702 99.50 0.00 0.00 99.50 4 bash
11:09:58 AM 0 2702 100.00 0.00 0.00 100.00 4 bash
11:10:00 AM 0 2702 100.00 0.00 0.00 100.00 4 bash
mount -t cgroup # 查看当前cgroups路径
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpuacct,cpu)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_prio,net_cls)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
mkdir /sys/fs/cgroup/cpu/loop
cat /sys/fs/cgroup/cpu/loop/cpu.cfs_quota_us
-1
cat /sys/fs/cgroup/cpu/loop/cpu.cfs_period_us
100000
echo 10000 >/sys/fs/cgroup/cpu/loop/cpu.cfs_quota_us # CPU时间限制在20%
echo 2702 > /sys/fs/cgroup/cpu/loop/tasks # 指定限制的进程PID
pidstat -u -p 2702 2
Linux 3.10.0-862.el7.x86_64 (centos-82) 03/02/2019 _x86_64_ (8 CPU)
11:16:37 AM UID PID %usr %system %guest %CPU CPU Command
11:16:39 AM 0 2702 10.50 0.00 0.00 10.50 4 bash
11:16:41 AM 0 2702 10.00 0.00 0.00 10.00 4 bash
11:16:43 AM 0 2702 9.50 0.00 0.00 9.50 4 bash
11:16:45 AM 0 2702 9.95 0.00 0.00 9.95 4 bash
已经将cpu使用率限制到了20%
使用Docker的优势
DevOps 开发运维一体化
-
应用更快速的交付和部署
- 传统:一堆帮助文档,安装程序
- Docker:打包镜像,发布测试,一键运行
-
更便捷的升级和扩缩容
- 使用Docker之后,我们部署应用就特别方便
- 还有升级服务等等,如需要升级SpringBoot,Redis,Tomcat,以前我们只能一个一个升级,有了docker可以将所有服务打成一个包,一起升级
- 将项目打包成一个镜像,当水平扩展的时候,将服务器A的环境和服务直接打包成镜像,在服务器B上一键运行
-
更简单的系统运维
- 在容器化之后,我们的开发、测试环境都是高度一致的
-
更高效的计算资源利用
- Docker是内核级别的虚拟化,可以在一个物理机上运行很多个容器实例,服务器的性能能够被利用到极致
Docker的架构
Docker组件
-
Docker服务有三个部分组成,分别是Client,Docker Host,Registry(仓库)。Docker Host又包含Containers(容器)和Images(镜像)
-
当创建新的容器时,会向Docker Daemon发送指令,Docker Daemon通过本地镜像文件创建容器,当本地不存在镜像时,将从Registry下载镜像。
-
Registry由两个部分组成:
- Repostitory
- 由特定的docker镜像的所有迭代版本组成一个镜像仓库
- 一个Registry可以包括多个Repostitory
- Repostitory包含顶层仓库和用户仓库
- 顶层仓库: 仓库名:标签, nginx:latest
- 用户仓库: 用户名/仓库名:标签, maomao/nginx:1.4.2
- 一个镜像可以有多个标签,如最新版的nginx,可以是nginx:latest,nginx:1.4.2
- Index
- 提供用户认证、镜像检索功能
- Repostitory
Docker镜像和容器
Docker镜像
- 左边的是多个只读层,他们相互堆叠在一起。除了最下层之外,其它每一层都会有一个指针指向下一层。这些层是Docker内部的实现细节,并且能够在宿主机的文件系统上访问到。
- 统一文件系统(union file system,aufs)技术(新版用overlay2)能够将不同的层整合成一个文件系统,为这些层提供了一个统一的视角,这样就隐藏了多层的存在,在用户的角度看来,只存在一个文件系统。我们可以在图片的右边看到这个视角的形式。
- 每一层都包含了当前层的ID,Metadata,Pointer(指向上一层)三层,最底层不包含Pointer。
- docker镜像就好比是一个模板,可以通过这个模板来创建容器服务,比如一个tomcat镜像 ==> 启动(run) >tomcat01 容器(提供服务器),通过这个镜像可以创建多个容器(最终服务运行或者项目运行,就是在容器中)
Docker容器
- Docker容器包含静止状态和运行状态两种,这两种状态下的层级不一样。
- 静态状态的容器仅仅是在镜像状态下增加一个可读写的层级,运行状态中的容器包含了进程和对应的进程空间:
- Docker利用容器技术,独立运行一个或者一个组应用,通过镜像来创建的。
- 可以简单的把容器理解为一个简易的linux系统
Docker仓库
- 仓库就是存放镜像的地方
- 仓库分为公有仓库和私有仓库
- Docker Hub(默认国外i的)
- 阿里云(配置镜像加速)
Docker安装
查看内核 系统最好是3.10以上
uname -r
3.10.0-862.el7.x86_64
卸载旧的版本
[root@docker ~]# yum remove docker \
> docker-client \
> docker-client-latest \
> docker-common \
> docker-latest \
> docker-latest-logrotate \
> docker-logrotate \
> docker-engine
安装需要的安装包
yum install -y yum-utils
设置镜像仓库
我们用阿里云
yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
更新yum软件包索引
yum makecache fast
安装docker docker-ce 社区
yum -y install docker-ce docker-ce-cli containerd.io
启动docker
systemctl start docker
查看版本
docker version
Client: Docker Engine - Community
Version: 20.10.6
API version: 1.41
Go version: go1.13.15
Git commit: 370c289
Built: Fri Apr 9 22:45:33 2021
OS/Arch: linux/amd64
Context: default
Experimental: true
Server: Docker Engine - Community
Engine:
Version: 20.10.6
API version: 1.41 (minimum version 1.12)
Go version: go1.13.15
Git commit: 8728dd2
Built: Fri Apr 9 22:43:57 2021
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.4.4
GitCommit: 05f951a3781f4f2c1911b05e61c160e9c30eaa8e
runc:
Version: 1.0.0-rc93
GitCommit: 12644e614e25b05da6fd08a38ffa0cfe1903fdec
docker-init:
Version: 0.19.0
GitCommit: de40ad0
执行hello-world
docker run hello-world
第一步寻找本地镜像 没有找到helloword的镜像
Unable to find image 'hello-world:latest' locally
第二步从library拉取镜像
latest: Pulling from library/hello-world
b8dfde127a29: Pull complete
Digest: sha256:f2266cbfc127c960fd30e76b7c792dc23b588c0db76233517e1891a4e357d519
Status: Downloaded newer image for hello-world:latest
拉去完成之后 显示Hello from Docker!
Hello from Docker!
说明安装成功
查看一下下载的hello-world镜像
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest d1165f221234 6 weeks ago 13.3kB
了解:卸载docker
卸载依赖
yum remove docker-ce docker-ce-cli containerd.io
删除资源
rm -rf /var/lib/docker
/var/lib/docker 是docker默认的工作路径
阿里云镜像加速
mkdir -p /etc/docker
这个是我自己阿里云的加速 每个人都不一样 可以去阿里云官方查看
tee /etc/docker/daemon.json <<-EOF
{
"registry-mirrors": ["https://m0rsqupc.mirror.aliyuncs.com"]
}
EOF
{
"registry-mirrors": ["https://m0rsqupc.mirror.aliyuncs.com"]
}
systemctl daemon-reload
systemctl restart docker
查看docker信息
查看信息
docker info
Client:
Debug Mode: false
Server:
Containers: 1 容器数量
Running: 0
Paused: 0
Stopped: 1
Images: 1 镜像数量
Server Version: 20.10.6 server版本
Storage Driver: overlay2
Backing Filesystem: xfs 宿主机上的底层文件系统
Supports d_type: true
Native Overlay Diff: true
userxattr: false
Logging Driver: json-file
Cgroup Driver: cgroupfs Cgroups 驱动
Cgroup Version: 1
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: io.containerd.runc.v2 io.containerd.runtime.v1.linux runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 05f951a3781f4f2c1911b05e61c160e9c30eaa8e
runc version: 12644e614e25b05da6fd08a38ffa0cfe1903fdec
init version: de40ad0
Security Options:
seccomp
Profile: default
Kernel Version: 3.10.0-862.el7.x86_64 宿主机的相关信息
Operating System: CentOS Linux 7 (Core)
OSType: linux
Architecture: x86_64
CPUs: 4
Total Memory: 3.842GiB
Name: docker
ID: E6Z7:MKAH:5EFQ:I2ZA:V6UG:VB4G:AXDU:ALKF:U4ZX:OYWC:7MKF:ZGLV
Docker Root Dir: /var/lib/docker docker 数据存储目录
Debug Mode: false
Registry: https://index.docker.io/v1/ registry 地址
Labels:
Experimental: false
Insecure Registries:
127.0.0.0/8
Registry Mirrors: 加速站点
https://m0rsqupc.mirror.aliyuncs.com/
Live Restore Enabled: false
分析docker helloworld流程
- docker run hello-world 回车启动
- docker会在本机寻找镜像,判断本机是否有这个镜像
- 如果有 就使用这个镜像运行
- 如果没有 就去仓库下载
- 如果在仓库找不到镜像则返回错误
- 如果找到镜像,则下载镜像到本地,接着运行
Docker底层原理
Docker是怎么工作的?
- Docker是一个 Client-Server 结构的系统,Docker的守护进程运行在主机上,通过Sockte从客户端访问
- DockerServer 接收到 Docker-Client 的指令,就会执行这个命令
Docker为什么比vm快?
- Docker有着比虚拟机更少的抽象层
- Docker利用的是宿主机的内核,vm需要是Guest OS
- 所以说,我们新建一个容器的时候,docker不需要像vm虚拟机一样重新加载一个操作系统内核,避免引导操作
- 虚拟机加载Guest OS 启动是分钟级别的
- 而Docker是利用宿主机的操作系统。省略了这个复杂的过程,启动是秒级的。