Docker 基础详解

 一、docker 安装(ubuntu22.04)

配置阿里源

sudo sed -i -r 's#http://(archive|security).ubuntu.com#https://mirrors.aliyun.com#g' /etc/apt/sources.list && sudo apt-get update

添加docker库

首先,安装必要的证书并允许 apt 包管理器使用以下命令通过 HTTPS 使用存储库:

sudo apt install apt-transport-https ca-certificates curl software-properties-common gnupg lsb-release

然后,运行下列命令添加 Docker 的官方 GPG 密钥:

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

添加 Docker 官方库:

echo "deb [arch=$(dpkg --print-architecture) 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 

使用命令更新 Ubuntu 源列表

sudo apt update

安装docker

sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin

安装完成后,运行如下命令验证 Docker 服务是否在运行

systemctl status docker

配置加速

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://82m9ar63.mirror.aliyuncs.com"],
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

二、namespace

什么是namespace

namespace是Linux系统的底层概念,在内核层实现,即有一些不同类型的命名空间被部署在核内,各个docker容器运行在同一个docker主进程并且共 用同一个宿主机系统内核,各docker容器运行在宿主机的用户空间,每个容器都要有类似于虚拟机一样的相互隔离的运行空间,但是容器技术是在一个 进程内实现运行指定服务的运行环境,并且还可以保护宿主机内核不受其他进程的干扰和影响,如文件系统空间、网络空间、进程空间等。通俗来说namespace是对全局系统资源的一种封装隔离。这样可以让不同namespace的进程拥有独立的全局系统资源。这样改变一个namespace的系统资源只会影响当前namespace中的进程,对其它namespace中的资源没有影响。

namespace分类

隔离类型功能系统调用参数内核版本
MNT Namespace(mount) 提供磁盘挂载点和文件系统的隔离能力 CLONE_NEWNS Linux 2.4.19
IPC Namespace(Inter-Process Communication) 提供进程间通信的隔离能力 CLONE_NEWIPC Linux 2.6.19
UTS Namespace(UNIX Timesharing System) 提供主机名隔离能力 CLONE_NEWUTS Linux 2.6.19
PID Namespace(Process Identification) 提供进程隔离能力 CLONE_NEWPID Linux 2.6.24
Net Namespace(network) 提供网络隔离能力 CLONE_NEWNET Linux 2.6.29
User Namespace(user) 提供用户隔离能力 CLONE_NEWUSER Linux 3.8
Time Namespace 提供时间隔离能力 CLONE_NEWTIME Linux 5.6
Syslog Namespace 提供syslog隔离能力    
Control group (cgroup) Namespace 提供进程所属的控制组的身份隔离  

 

1、MNT Namespace

提供磁盘挂载点和文件系统的隔离:

每个容器都要有独立的根文件系统,有独立的用户空间,以实现在容器里面启动服务并且使用容器的运行环境,即一个宿主机是ubuntu

的服务器,可以在里面启动一个centos运行环境的容器并且在容器里面启动一个Nginx服务,此Nginx运行时使用的运行环境就是centos

系统目录的运行环境,即在容器里面是不能直接访问宿主机的文件系统。

宿主机是使用了chroot技术把容器锁定到一个指定的运行目录里面并作为容器的根运行环境。image-20221019163747336

 

 

2、IPC Namespace

IPC namespce隔离进程间通 信资源(同一个IPC namespace的进程可实现内存等资源共享,但是不同的IPC namespace则严格隔离)主进程

 

3、UTS Namespace

提供主机名隔离:

UTS namespace(UNIX Timesharing System包含了运行内核的名称、版本、底层体系结构类型等信息)用于系统标识, 其中包含了hostname 和域名 domainname ,它使得一个容器拥有属于自己hostname标识,这个主机名标识独立于宿主 机系统和其上的其他容器。

 

4、PID Namespace

PID namespace隔离非常实用,它对进程PID重新标号,即两个不同namespace下的进程可以有相同的PID。每个PID namespace都

有自己的计数程序。内核为所有的PID namespace维护了一个树状结构,最顶层的是系统初始时创建的,被称为root namespace,它创

建的新PID namespace被称为child namespace(树的子节点),而原来的PID namespace就是新创建的PID namespace的parent

namespace(树的父节点)。通过这种方式,不同的PID namespace会形成一个层级体系。所属的父节点可以看到子节点中的进程,并可以

通过信号等方式对子节点中的进程产生影响。反过来,子节点却不能看到父节点PID namespace中的任何内容,由此产生如下结论。

  1. 每个PID namespace中的第一个进程“PID 1”,都会像全通Linux中的init进程一样拥有特权,其特殊作用。

  2. 一个namespace中的进程,不可能通过kill或ptrace影响父节点或者兄弟节点中的进程,因为其他几点的PID在这个namespace没有任何意义。

  3. 如果你在新的PID namespace中重新挂载/proc文件系统,会发现其下只显示同属一个PID namespace中的其他进程。

  4. 在root namespace中看到所有的进程,并且递归包含所有子节点中的进程。到这里,读者可能已经联想到了一种在Docker外部监控

    运行程序的方法了,就是监控Docker daemon所在的PID namespace下的所有进程及子进程,在进行筛选即可。

5、Net Namespace

提供网络隔离:

每一个容器都类似于虚拟机一样有自己的网卡、监听端口、TCP/IP协议栈等,docker使用 network namespace启动一个vethX接口,

这样你的容器将拥有它自己的桥接ip地址,通常是docker0,而docker0实质就是Linux的虚拟网桥,网桥是在OSI七层模型的数据链路层的

网络设备,通过mac地址对网络进行划分,并且在不同网络直接传递数据。

6、User Namespace

提供用户隔离:

User Namespace允许在各个宿主机的各个容器空间内创建相同的用户名以及相同的用户UID和GID,只是会把用户的作用范围限制在

每个容器内,即A容器和B容器可以有相同的用户名称和ID的账户,但是此用户的有效范围仅是当前容器内,不能访问另外一个容器内的

文件系统,即相互隔离、互不影响。

三、docker 命令详解

镜像管理命令

Commands:

build:从Docker文件构建新的镜像

ps :列出本地的所有镜像

prune :删除本地未使用的镜像

pull :从镜像仓库下载镜像到本地

push :从本地上传镜像到镜像仓库

rmi :删除一个或者多个本地镜像

import :从本地或远程的压缩包等导入镜像,可以指定导入后的镜像名称

history :查询镜像的构建历史

 

 inspect :显示一个或多个镜像的详细信息

 

 

load:从一个tar包或标准输入导入镜像

 

 

 save:保存一个或者多个镜像到一个tar包(默认保存到当前终端的标准输出)

 

 tag :对镜像打一个新的标签

 

基础命令详解

attach : 进入容器命令(不推荐) 进入容器后操作会在多窗口同步且退出后其它终端也会 一起退出。

exec : 进入容器命令 (推荐)

cp:从容器和宿主机相互拷贝文件或目录

 

 

create:创建一个新的容器且创建后的容器处于退出状态 docker create -it --name test1 nginx:1.20.2

diff: 对比容器和镜像有差异的文件或目录 docker diff 8ddf4ce923ef

events: 获取dockerd的实时事件,创建删除容器等操作

info: 显示系统信息

export: 将容器的文件系统导出为一个本地压缩包,非镜像格式

 

 

history: 查看的镜像的构建历史 docker history centos:7.9.2009

inspect: 显示docker对象(镜像、网络、容器等)的详细信息 docker inspect 50fe74b50e0d

kill : 强制关闭所有运行中的容器 docker kill $(docker ps -a -q)

 

logs -f : 持续查看容器标准输出和错误输出的日志 docker logs -f nginx-container-test1

 

docker pause: 暂停一个或者多个容器

docker unpause : 取消暂停

docker pull : 从镜像仓库下载镜像

docker push nginx:1.20.2 : 从本地上传镜像到镜像仓库

docker run

-p 宿主机端口:容器端口

-d 后台运行 :

-it 交互式运行

-v 数据卷

四、docker数据管理

容器创建完成之后会有以下几个目录:

Lower Dir:image镜像层(镜像本身,只读)

Upper Dir:容器的上层(读写) 注:新的数据产生的地方

Merged Dir:容器的文件系统,使用Union FS(联合文件系统)将lowerdir和upper Dir:合并给容器使用。

Work Dir:容器在 宿主机的工作目录

 

数据持久化:需要将容器中的数据保存到宿主机的指定目录

1、数据卷

数据卷实际上就是宿主机上的目录或者是文件,可以被直接mount到容器当中作为容器的本地文件系统使用,实际生产环境中,需要针对不同类型的服务、不同类型的数据存储要求做相应的规划,最终保证服务的可扩展性、稳定性以及数据的安全性。基于数据卷通过将宿主机的文件或目录挂载到容器的指定目录,当容器中的挂载目录产生的新数据即可间接的保存到宿主机以实现持久化的目的。

2、数据卷容器

数据卷容器是将宿主机的目录挂载至一个专用的数据卷容器,然后让其他容器通过数据卷容器继承挂载的目录或文件,以实现将新产生的数据持久化到宿主机的目的。

docker数据卷操作

docker创建数据卷

docker volume create 卷名

docker volume ls :查看卷名

 

 

挂载数据卷:

docker run -it -d -p 80:80 -v nginx-data:/data nginx:1.20.2 nginx-data(数据卷) /data(容器目录)

 

数据目录及配置多卷挂载

nginx多卷挂载(配置文件、数据目录)

docker run -d --name web3 -v /data/testapp:/usr/share/nginx/html/testapp -v

/data/nginx/conf/nginx.conf:/etc/nginx/nginx.conf:ro -p 83:80 nginx:1.20.2

 

数据卷的特点及使用

数据卷是宿主机的目录或者文件,并且可以在多个容器之间共同使用。

在宿主机对数据卷更改数据后会在所有容器里面会立即更新。

数据卷的数据可以持久保存,即使删除使用使用该容器卷的容器也不影响。

在容器里面的写入数据不会影响到镜像本身。

数据卷使用场景:

容器数据持久化(mysql数据、nginx日志等类型)

静态web页面挂载

应用配置文件挂载

多容器间的目录或文件共享

数据卷容器:

--volumes-from

数据卷容器功能是可以让数据在多个docker容器之间共享,即先要创建一个后台运行的A容器作为Server,之后创建的B容器、C容 器等都可以同时访问A容器的内容,因此数据卷容器用于为其它容器提供卷的挂载继承服务,数据卷为其它容器提供数据读写服务,A 容器称为server端、其它容器成为client端 

五、容器网络

Docker服务安装完成之后,默认在每个宿主机会生成一个名称为docker0的网卡其IP地址都是172.17.0.1/16,并且会生成三种不能类型的网络,如下:

 

 

另外会额外创建三个默认网络,用于不同的使用场景:

cda5b9679ad0 bridge bridge local 桥接网络,默认使用的模式,容器基于SNAT进行地址转换访问宿主机以外的环境

07f06bdcddf4 host host local host网络,直接使用宿主机的网络( 不创建net namespace),性能最好,但是容器端口不能冲突

a3f434cba381 none null local 空网络,容器不会分配有效的IP地址(只有一个回环网卡用于内部通信),用于离线数据处理等场景

bridge模式

docker的默认模式即不指定任何模式就是bridge模式,也是目前使用比较多的网络模式,此模式创建的容器会为每一个容器分配自己的网络IP等信息,并将容器连接到一个虚拟网桥与外界通信。

docker network inspect bridge

docker run -it -d --name nginx-web1-bridge-test-container -p 80:80 --net=bridge nginx:1.20.2

 

host模式(几乎不用)

host模式就是直接使用宿主机的IP地址,创建的容器如果指定了使用host模式,那么新创建的容器不会创建自己的虚拟网卡,而是直接使用宿 主机的网卡和IP地址,因此在容器里面查看到的IP信息就是宿主机的信息,访问容器的时候直接使用宿主机IP+容器端口即可,而且某一个端口一旦被其中一个容器占用那么其它容器就不能再监听此端口,不过容器的其它资源比如容器的文件系统、容器系统进程等还是基于namespace相互隔离。

此模式的网络性能最高,但是各容器之间端口不能相同,适用于运行容器端口比较固定的业务。

docker run -it -d --name nginx-web1-host-test-container -p 80:80 --net=host nginx:1.20.2

container模式

Container模式即容器模式,使用参数 --net=container:目标容器名称/ID 指定,使用此模式创建的容器需指定和一个已经存在的容器共享一个网络namespace,而不会创建独立的namespace,即新创建的容器不会创建自己的网卡也不会配置自己的IP,而是和一个已经存在的被指定的目标容器共享对方的IP和端口范围,因此这个容器的端口不能和被指定的目标容器端口冲突,除了网络之外的文件系统、用户信息、进程信息等仍然保持相互隔离,两个容器的进程可以通过lo网卡及容器IP进行通信。

docker run -it -d --name nginx-container -p 80:80 --net=bridge nginx:1.22.0-alpine

docker run -it -d --name php-container --net=container:nginx-container php:7.4.30-fpm-alpine

 

 

 

 

posted @ 2022-10-21 21:39  耿筱诺  阅读(122)  评论(0编辑  收藏  举报