docker容器入门
1.1 容器介绍
容器技术是一种操作系统级的虚拟化技术,它允许在一个物理或虚拟机上运行多个隔离的应用程序实例,每个实例都被封装在一个独立的容器中。每个容器都包含应用程序及其依赖的运行时环境,如操作系统、库文件和配置文件,它们共享主机操作系统的内核,但相互之间是隔离的。
简单来说,容器技术就是可以把你想跑的配置文件“打包”,然后在任何计算机节点上都可以始终这个打好的包。因为有了容器,可以一条命令让你把自己想跑的服务跑起来,实现了一次打包,遍地使用,就比如,我们可以把整套zabbix
环境(httpd+php+mysql+zabbix-server
)一起打包,然后给它搬到其它机器上直接运行。
1.2容器基本概念
Linux Containers(LXC)是一种基于Linux内核的容器化技术,提供了一种轻量级的虚拟化解决方案。它利用Linux内核的命名空间(namespace)和控制组(cgroup)功能,实现了应用程序和其依赖的隔离运行环境。Docker/Podman等容器技术,都是在LXC基础之上开发的三方工具。
LXC可以在操作系统层次上为进程提供虚拟的执行环境,一个虚拟的执行环境就是一个容器。可以为容器绑定特定的cpu和memory节点,分配特定比例的cpu时间、IO时间,限制可以使用的内存大小(包括内存和是swap空间),提供device访问控制,提供独立的namespace(网络、pid、ipc、mnt、uts)。
1.3容器的隔离
容器有效地将操作系统管理的资源划分到独立的组中,并把各个独立的组进行隔离,可以让各自的组占用独立的资源,完成自己独立的任务。
因为容器最终执行的命令也是调用统一的os api来实现,是基于整个os来实现的,所以不需要单独操作系统的编译系统、执行解释器,一切工作都是基于os 的基础上来完成的。
容器通过提供一种创建和进入容器的方式,让程序像跑在独立机器那样在容器中运行,并且相互之间不影响,而且还可以共享底层的资源。
1.4容器的共享:
容器提供环境隔离的前提下,还提供了资源共享的机制,所以容器比真正kvm 虚拟机的资源要节省许多;
1.5容器核心技术
chroot:创建一个虚拟的根目录文件系统,其实质还是调用底层的文件系统,不过是建立一个虚拟的、可以跟其他容器的虚拟文件系统相互隔离、但共享底层的文件系统。
namespace:命名空间,可以提供一个进程相互隔离的独立网络空间,不同的容器空间进程pid可以相同,进程并不冲突影响,但可以共享底层的计算和存储资源。
cgroups:实现了对容器的资源分配和限制,比如容器A分配4核cpu,8G内存,那么这个容器最多用这么多的资源,如果内存超过8G就会启动swap,效率降低,也可能会被调度系统kill掉。
1.6企业为什么要使用容器技术
提升效率:
容器可以快速移植,这就意味着企业在开发和部署阶段可以快速搭建开发、测试环境,并部署到生产环境中。
节省资源:
一个物理机可以运行成百上千个容器,传统的虚拟技术根本做不到。
节省运维成本:
使用主流的容器编排和管理工具(K8s),可以很大程度的降低企业运维成本,因为K8S本身集成了高可用,负载均衡、监控、自动修复等诸多功能,一旦上线,几乎不用花额外的运输成本。
1.7跟容器相关的工具
1)Docker
docker是一个开源的应用容器引擎,基于go语言开发并遵循apache2.0协议开源。
docker诞生于2013年,它的出现推动了容器技术发展的步伐,可以说没有docker就没有后续的k8s、云原生。
学K8S之前,需要先学习docker,学会镜像、容器、卷等概念。
2)Podman
Podman是一个开源项目,在Github上已经有12K+Star,可以在大多数Linux平台使用。
Podman是一个无守护进程的容器引擎,用在Linux系统上开发、管理和运行OCI容器和容器镜像。
Podman提供了一个与Docker兼容的命令行工具,可以简单地为docker命令取别名为podman即可使用,所以说如果你会docker就可以轻松上手Podman。
目前在RHEL系统里默认自带了Podman,说明红帽公司更倾向与Podman。
2.1 k8s废弃Docker怎么回事
有一些误解可能导致人们认为k8s废弃了Docker。实际上,Docker在过去是k8s最常用的容器运行时之一,因为Docker提供了易用的工具和接口来构建、打包和管理容器镜像。
自Kubernetes1.5版本开始,k8s社区在容器运行时接口(Container Runtime Interface,简称CRI)上引入了一种新的标准化接口,称为CRI-O。CRI-O是一个专注于k8s的轻量级容器运行时,它专门为k8s设计并实现了CRI接口,以提供更高效、可靠和安全的容器运行环境。
这导致一些误解,认为k8s不再支持Docker。实际上,k8s仍然可以与Docker集成,并且仍然可以使用Docker作为容器运行时。只要Docker安装和配置正确,并且与k8s集群的CRI接口兼容,就可以继续使用Docker作为容器运行时。
所以k8s并没有废弃Docker,而是引入了更多的容器运行时选项,并提供了与这些运行时集成的能力。Docker仍然是一种常见的容器运行时选择,可以与k8s配合使用,以构建和管理容器化应用程序。
2.2Containerd
Docker意识到Kubernetes的改变,为了迎合Kubernetes,将Docker Engine拆分成多个模块,其中Docker Daemon部分也就是说Containerd捐献给了CNCF。
所以,Containerd实际上是Docker引擎拆出来的一个模块。
Containerd 作为 CNCF 的托管项目,自然是要符合 CRI 标准的。但当时的Docker 出于自己诸多原因的考虑,它只是在 Docker Engine 里调用了 containerd,外部的接口仍然保持不变,也就是说还不与 CRI 兼容。
在当时的Kubernetes版本里,有两种方法调用容器:
第一种是用 CRI 调用 dockershim,然后 dockershim 调用 Docker,Docker 再走 containerd 去操作容器。
第二种是用 CRI 直接调用 containerd 去操作容器。
2.3 Kubernetes移除dockershim后对Docker的影响
尽管Kubernetes不再默认支持Docker作为容器运行时,但Docker仍然可以在Kubernetes中以其他形式存在,并与Kubernetes共存。
由于容器镜像格式已经标准化为OCI规范,因此Docker镜像仍然可以在Kubernetes中正常使用。用户可以继续使用Docker镜像,并使用Docker Hub获取镜像,或使用Dockerfile构建镜像。这意味着开发、测试和CI/CD流程不需要做太多改动,仍然可以与Docker一起使用。
Docker是一个完整的容器生态系统,不仅包括容器运行时(containerd),还包括构建、分发和测试等多个服务。Docker Desktop甚至内置了Kubernetes。对于容器开发的便利性而言,Docker仍然是一个难以替代的工具。广大云原生开发者可以在熟悉的Docker环境中继续工作,并利用Docker来开发在Kubernetes中运行的应用程序。
虽然Kubernetes不再包含dockershim,但Docker公司将该代码接管,并创建了一个名为cri-dockerd的项目。cri-dockerd的作用类似于dockershim,它将Docker Engine适配为CRI接口,使kubelet可以通过它来操作Docker。这样一来,就可以实现Kubernetes与Docker的集成,就像没有发生任何变化一样。
尽管Docker在容器编排领域输给了Kubernetes,并被边缘化,但它仍然具有强大的生命力。众多忠实用户和大量的应用镜像是Docker的重要资产和支持,足以让它在与Kubernetes不直接竞争的领域继续前行。对于初学者来说,Docker便捷易用,具有完善的工具链和友好的交互界面,很难找到其他能与其媲美的软件。因此,Docker仍然是学习容器技术和云原生的首选工具之一。
3.3 Docker安装
在Rocky8上,可以先配置对应版本的yum仓库,然后使用yum工具安装Docker
1)先安装yum-utils工具
yum install -y yum-utils
2)配置Docker官方的yum仓库
yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
3)查看Docker版本
yum list docker-ce --showduplicates | sort -r
4)安装指定版本Docker
yum install docker-ce-20.10.9-3.el8
如果不指定版本,就安装最新版
yum install docker-ce
5)启动服务
systemctl start docker
systemctl enable docker
4-6 Docker镜像和容器
关于镜像这个词,大家并不陌生,比如系统安装盘就叫镜像,另外我们常见的Ghost技术做的GHO系统镜像和这个Docker镜像非常像。我们可以将GHO镜像安装到任何计算机上,这样就拿到了跟源系统一模一样的系统。
当然Docker镜像也有它独特之处,比如它是分层的,这个后续在拉取镜像时可以看到。
Docker镜像拉取下来后,可以直接运行,运行后的东西我们叫做容器,一个镜像可以启动很多容器。
容器就是镜像启动后的状态,在Linux系统里看就是一个进程,但容器是可以进入得,就像进入了一个虚拟机里。
1)配置加速器
编写/etc/docker/daemon.json
cat > /etc/docker/daemon.json <<EOF
{
"registry-mirrors": ["https://dhq9bx4f.mirror.aliyuncs.com"]
}
EOF
重启docker服务
systemctl restart docker
检查是否生效
docker info |grep -A 3 'Registry Mirrors'
2)拉取镜像
docker pull busybox ##这个busybox就是系统镜像名字,它是从[hub.docker.com](http://hub.docker.com/)去拉取镜像
3)查看当前系统镜像
docker image ls
4)搜索镜像
docker search ubuntu
如果要查询镜像版本,可以访问https://hub.docker.com/,搜索对应的镜像名字,然后点tag进行查看
拉取指定版本镜像
docker pull nginx:1.23.2
5)给镜像打标签
docker tag busybox:latest aminglinux:1.2.3 #会新出来一个镜像,原本的不会被删除,image id是确定唯一性的
6)启动容器
docker run -itd busybox ##把镜像启动为容器,-i表示让容器的标准输入打开,-t表示分配一个伪终端,-d表示后台启动,要把-i -t -d 放到镜像名字前面
7)查看容器
docker ps -a ##如果不加-a,则不显示已经停止的容器
8)停止容器
docker stop de1fb9c8902e ##后面这一串字符串为容器ID,可以通过docker ps查看
9)删除容器
docker rm de1fb9c8902e ##如果容器未停止,会报错,需要加-f选项
10)删除镜像
docker rmi aminglinux:1.2.3 ##这里因为aminglinux:1.2.3为busybox的一个tag,所以此操作只会删除此tag,并不会真正删镜像,如果该镜像没有tag,则直接删除镜像
也可以直接指定镜像ID
docker rmi beae173ccac6
11)拉取镜像+启动容器
docker run -itd redis
12)启动容器时,给容器自定义名字
docker run --name web01 -itd ubuntu
13)容器运行后直接退出并删除,30秒后
docker run --rm -it ubuntu bash -c "sleep 30"
14)进入容器操作
docker exec -it web01 bash
进去后,相当于进入了一个虚拟机一样,安装个nginx
apt update
apt install -y nginx
15)将容器重新打包成新镜像
docker commit -m "install nginx" -a "aming" web01 nginx_ubuntu:1.0 ##这里的web01可以改为容器id
-m "install nginx":这是提交信息(commit message),用于描述此次提交的更改内容。在这种情况下,它表示在容器中安装了Nginx。
-a "aming":这是作者信息(author),表示提交此更改的作者是"aming"。
web01:这是要提交更改的容器名称或容器ID。它指定了要保存更改的源容器。
nginx_ubuntu:1.0:这是要创建的新镜像的名称和标签。在这种情况下,它被命名为nginx_ubuntu,标签为1.0。
执行该命令后,Docker将会创建一个新的镜像nginx_ubuntu:1.0,其中包含了基于web01容器的更改,这些更改包括安装了Nginx。
再次docker images查看镜像列表,发现多了一个nginx_ubuntu:1.0
16)将镜像保存为一个文件
docker save nginx -o nginx.img #nginx是镜像名称,可以修改,也可以是redis啥的,将现有的镜像导出一个文件。
17)将导出的镜像文件导入
docker load --input nginx.img
18)将容器导出为一个文件
docker export web01 > web01.tar
19)将导出的文件导入为新的镜像
docker import - ubuntu_test < web01.tar #就不能导出为容器了,只能导出为镜像,就只有一层了
20)docker save和docker export的差异
docker save保存的是镜像,docker export保存的是容器
docker save会保留镜像所有的历史记录,docker export不会,即没有commit历史
docker load用来载入镜像包,docker import用来载入容器包,但两者都会恢复为镜像;
docker load不能对载入的镜像重命名,而docker import可以为镜像指定新名称。
docker info
[root@docker-slave3 ~]# docker info
Containers: 45 #容器的数量
Running: 44 #正在运行的数量
Paused: 0 #暂停的数量
Stopped: 1 #已经停止的数量
Images: 264 #镜像数量
Server Version: 1.12.5 #docker server的版本
Storage Driver: devicemapper #存储驱动程序
Pool Name: docker-253:0-537427328-pool #pool name的值根据Data file的模式改变 # direct-lvm 模式(Pool Name 为 docker-thinpool )
Pool Blocksize: 65.54 kB #pool块大小
Base Device Size: 10.74 GB #基本存储大小
Backing Filesystem: xfs #支持的文件系统
Data file: /dev/loop0 #使用的模式为loop-lvm 生产中不推荐使用(loop-lvm性能比较差) 使用 direct-lvm 模式(配置过程在最后面)
Metadata file: /dev/loop1 #元数据文件位置
Data Space Used: 86.78 GB #数据使用的空间 direct-lvm 模式 direct-lvm 模式
Data Space Total: 107.4 GB #数据的总空间
Data Space Available: 20.6 GB #数据的可用空间
Metadata Space Used: 159.8 MB #元数据使用的空间
Metadata Space Total: 2.147 GB #元数据的总空间
Metadata Space Available: 1.988 GB #元数据的可用空间
Thin Pool Minimum Free Space: 10.74 GB # Thin pool(瘦供给池)的最小可用空间 *下面有瘦供给的解释
Udev Sync Supported: true
Deferred Removal Enabled: false
Deferred Deletion Enabled: false
Deferred Deleted Device Count: 0
Data loop file: /var/lib/docker/devicemapper/devicemapper/data #数据loop文件的位置
WARNING: Usage of loopback devices is strongly discouraged for production use. Use `--storage-opt dm.thinpooldev` to specify a custom block storage device. #警告信息
Metadata loop file: /var/lib/docker/devicemapper/devicemapper/metadata #元数据loop文件的位置
Library Version: 1.02.135-RHEL7 (2016-09-28)
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins: #插件
Volume: local
Network: host null bridge overlay
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Security Options: seccomp #内核安全组件
Kernel Version: 3.10.0-514.el7.x86_64 #内核版本
Operating System: CentOS Linux 7 (Core) #操作系统
OSType: linux #操作系统类型
Architecture: x86_64 #系统架构
CPUs: 4 #CPU数
Total Memory: 30.96 GiB #总空间
Name: docker-slave3.ctrm #主机名
ID: POZH:PSTG:ULR2:S75Y:OW57:ETGA:Z7RU:WEQA:VGNE:4JMJ:PJ3N:LXZW
Docker Root Dir: /var/lib/docker #docker根目录
Debug Mode (client): false #调试模式(client)
Debug Mode (server): false #调试模式(server)
Registry: https://index.docker.io/v1/ #镜像仓库
Insecure Registries: #非安全镜像仓库
15.116.20.134:5000
15.116.20.104:80
15.116.20.115:80
127.0.0.0/8
————————————————
原文链接:https://blog.csdn.net/m0_61443457/article/details/124420827
核心知识点/面试考点:
● Docker容器的隔离与限制;
容器有效地将操作系统管理的资源划分到独立的组中,并把各个独立的组进行隔离,可以让各自的组占用独立的资源,完成自己独立的任务。
因为容器最终执行的命令也是调用统一的os api来实现,是基于整个os来实现的,所以不需要单独操作系统的编译系统、执行解释器,一切工作都是基于os 的基础上来完成的。
容器通过提供一种创建和进入容器的方式,让程序像跑在独立机器那样在容器中运行,并且相互之间不影响,而且还可以共享底层的资源。
● 加速器的主要作用是?如何配置加速器?daemon.json还有哪些参数?
加速器(Accelerator)在Docker中起到加快镜像下载速度的作用。Docker镜像通常存储在镜像仓库中,例如Docker Hub,但由于网络环境的限制,从远程镜像仓库下载镜像可能会很慢。加速器可以将镜像下载流量重定向到一个更快的镜像仓库,从而提高下载速度。
要配置加速器,可以按照以下步骤进行操作:
-
打开 Docker 配置文件
daemon.json
。该文件通常位于以下位置之一:- Linux:
/etc/docker/daemon.json
- Windows Server:
C:\ProgramData\docker\config\daemon.json
- macOS:
/etc/docker/daemon.json
(需要手动创建文件)
- Linux:
-
如果
daemon.json
文件不存在,可以创建一个新文件。 -
在
daemon.json
文件中,添加一个名为registry-mirrors
的键,并将其值设置为加速器的 URL。例如:{ "registry-mirrors": ["https://<加速器地址>"] } ``` 注意:如果 `daemon.json` 中已经存在其他配置项,只需将 `registry-mirrors` 加入到现有的配置中即可,确保 JSON 格式的正确性。
-
保存
daemon.json
文件。 -
重新启动 Docker 服务,以使配置生效。
配置加速器后,Docker 将会从加速器地址下载镜像,提高下载速度。
除了 registry-mirrors
参数,daemon.json
文件还支持其他一些参数来配置 Docker 守护进程的行为。这些参数包括:
log-level
:设置 Docker 日志的详细级别。log-opts
:配置 Docker 日志的选项,例如日志的最大大小和最大文件数。storage-driver
:设置 Docker 使用的存储驱动程序。iptables
:配置 Docker 是否管理 iptables 规则。default-ulimits
:设置容器的默认资源限制。insecure-registries
:配置允许不安全的镜像仓库地址。debug
:启用或禁用 Docker 的调试模式等。
这只是一小部分可用于 daemon.json
文件的参数,更多的参数可以在 Docker 官方文档中找到。使用这些参数可以对 Docker 守护进程进行更多的配置和调整,以满足特定需求和场景的要求。
● 必须很熟悉docker镜像的操作;
○ 容器创建 run 参数;
docker run -itd nginx #把镜像启动为容器
docker run是运行容器的命令。
-i选项表示在交互模式下(标准输入打开)运行容器
-t分配一个伪终端(pseudo-TTY)。
-d选项表示在后台(detached)模式下运行容器,即容器将在后台运行并返回容器ID。
nginx是要运行的容器镜像的名称。在这种情况下,它是官方提供的Nginx镜像。
○ 镜像导入导出;
将镜像保存为一个文件
docker save nginx -o nginx.img
将导出的镜像文件导入
docker load --input nginx.img
○ commit的场景;
将容器重新打包成新镜像
docker commit -m "install nginx" -a "aming" web01 nginx_ubuntu:1.0 ##这里的web01可以改为容器id
-m "install nginx":这是提交信息(commit message),用于描述此次提交的更改内容。在这种情况下,它表示在容器中安装了Nginx。
-a "aming":这是作者信息(author),表示提交此更改的作者是"aming"。
web01:这是要提交更改的容器名称或容器ID。它指定了要保存更改的源容器。
nginx_ubuntu:1.0:这是要创建的新镜像的名称和标签。在这种情况下,它被命名为nginx_ubuntu,标签为1.0。