前言:前面写过关于Docker+Kubernetes的部署,主要是针对国产化linux系统的适配问题,并没有对docker进行复习。这里整理一下docker的知识点,用作容器化微服务的起点,主要为日常工作配置使用,本章可能有点长,目录我尽量写详细点。
1、概念简介
1.1、容器概念
容器实际上是一种沙盒技术,类似于一个集装箱,可以将你的应用程序"装"起来。这样一来,不同的应用程序之间有了明确的边界,彼此不会相互干扰。被放置在容器中的应用程序可以轻松地被移动和部署。容器的本质是进程,而容器镜像则相当于操作系统中的可执行安装包(".exe")。
1.2、Docker
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。
传统的部署模式是:安装(包管理⼯具或者源码包编译)->配置->运⾏;
Docker的部署模式是:复制->运⾏一次构建多次发布。
Docker重新定义了应用的开发、测试和部署上线过程,核心理念是"一次构建,多次部署"。它支持将应用程序打包成一个可移植的容器,带来以下几点优势:
- 标准化应用发布:Docker容器包含了运行环境和可执行程序,可以跨平台和主机使用。
- 节约时间:快速部署和启动,相比虚拟机的分钟级启动,Docker容器可以实现秒级启动。
- 便于构建微服务架构系统:通过服务编排,能够实现更好的松耦合,方便管理多个微服务。
- 节约成本:Docker容器的磁盘空间消耗通常较小,相比传统虚拟机可以大幅减少资源占用,从几个GB级别降低到MB级别。
Docker系统:
- Docker系统有两个程序:docker服务端和docker客户端
- Docker服务端:是⼀个服务进程,管理着所有的容器。也叫docker engine
- Docker客户端:扮演着docker服务端的远程控制器,可以⽤来控制docker的服务端进程
- Docker服务端和客户端运⾏在⼀台机器上
Docker三大核心组件:
- Docker 仓库 - Docker registery
- Docker 镜像 - Docker images
- Docker 容器 - Docker containers
容器的三⼤组成要素:
- 名称空间 namespace 容器隔离(pid,net,mnt,user,hostname...)
- 资源限制 cgroups 资源(内存,cpu)
- ⽂件系统 overlay2(UnionFS)
2、docker安装
基础环境准备
Centos7,关闭防火墙,关闭selinux,配置阿里基础源,配置epel扩展源
使用yum安装docker
[root@localhost ~]# yum install -y docker
使用命令查看docker版本,发现版本并非最新
[root@localhost ~]# docker -v
Docker version 1.13.1, build 7d71120/1.13.1
docker卸载方式如下
[root@localhost ~]# rpm -qa | grep docker
docker-common-1.13.1-210.git7d71120.el7.centos.x86_64
docker-client-1.13.1-210.git7d71120.el7.centos.x86_64
docker-1.13.1-210.git7d71120.el7.centos.x86_64
[root@localhost ~]# yum remove -y `rpm -qa | grep docker`
# 这里使用的是反引号取用rpm命令的结果,这样才能卸载干净
CentOS--官⽅安装(非国内网站网速较慢一般不使用)
Docker官⽹:https://www.docker.com/
# 下载官方源安装
# wget https://download.docker.com/linux/centos/docker-ce.repo
# mv docker-ce.repo /etc/yum.repos.d
# yum install -y docker-ce
# 下载RPM包安装
# wget https://download.docker.com/linux/centos/7/x86_64/stable/Packages/docker-ce-17.09.0.ce-1.el7.centos.x86_64.rpm
# yum localinstall docker-ce-17.09.0.ce-1.el7.centos.x86_64.rpm
国内源安装(正常情况下使用最多的方式)
访问阿里巴巴开源镜像站docker-ce镜像,参考给出的操作手册安装,网站地址如下
docker-ce镜像_docker-ce下载地址_docker-ce安装教程-阿里巴巴开源镜像站
41 yum install -y yum-utils device-mapper-persistent-data lvm2
42 yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
43 sed -i 's+download.docker.com+mirrors.aliyun.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo
44 yum makecache fast
45 yum -y install docker-ce
46 docker -v
此时卸载方式为
[root@localhost ~]# yum remove docker*
这里需要重启
查看历史版本和安装指定版本
# 查看历史版本
[root@localhost ~]# yum list docker-ce.x86_64 --showduplicates | sort -r
# 安装指定版本如:
yum install -y --setopt=obsoletes=0 docker-ce-19.03.2 docker-ce-selinux-1
9.03.2
启动检查docker
[root@localhost ~]# systemctl enable docker
[root@localhost ~]# systemctl start docker
[root@localhost ~]# docker -v
[root@localhost ~]# docker version
[root@localhost ~]# docker info
。。。。。。
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 0
。。。。。。
3、镜像
3.1、基础概念
3.1.1、Docker 仓库
Docker 仓库用来保存镜像,类似于代码控制中的代码仓库。和代码仓库类似,Docker 仓库分为公有和私有两种。
最大的公有的 Docker 仓库名字是 Docker Hub(官方),它提供了庞大的镜像集合供用户使用。这些镜像可以是用户自己创建的,也可以基于别人已有的镜像创建。
私有的 Docker 仓库 则可以是个人或者公司部署的库,用于存储和管理私有的镜像资源。
在 Docker 中,仓库(registry)是顶层的集合,存储了多个仓库(repository)。每个仓库可以包含多个镜像,按照版本(tag)来区分不同的镜像版本,例如 docker.io/centos:7
表示从 Docker Hub 中获取 CentOS 镜像的版本为 7。
国内的 Docker 仓库 包括阿里云、腾讯云、DaoCloud等,用来提供更快速的镜像访问服务,特别是对于国内用户而言,能够显著提高镜像下载的速度。
总结来说,Docker Hub 是全球范围内的 Docker 镜像公共仓库,而私有仓库则提供了安全、私密的镜像管理和存储解决方案
3.1.2、Docker 镜像
Docker 镜像是 Docker 容器运行时的只读模板,由一系列层(layers)组成。Docker 使用 UnionFS(联合文件系统)将这些层联合到单独的镜像中。这种设计使得 Docker 极为轻量级。
当你修改一个 Docker 镜像,比如升级某个程序到新版本时,会创建一个新的层。因此,不需要替换整个原先的镜像或重新构建(这在使用虚拟机时常见),只是添加或升级了一个新的层。
在 Docker 的术语中,一个只读层被称为镜像,镜像是永久不会改变的。由于 Docker 使用统一的文件系统,镜像本身是无状态的,因为镜像不可写入。
镜像本身是由⼀层⼀层的镜像合在⼀起的,如上图,最底层的镜像我们称为基础镜像,在这个基础镜像的基础 上还可以在做镜像,在做的镜像称为⼦镜像,对于⼦镜像来讲在谁的基础之上做的就是⽗镜像。
**镜像 ID:**所有的 Docker 镜像都使用一个 64 位的十六进制字符串来唯一标识。为了方便使用,可以使用这个字符串的前 12 个字符作为短ID,在命令行中使用。然而,由于短ID存在碰撞的可能性,因此服务器通常返回完整的 64 位长ID。
简而言之,镜像的完整ID是64位长的唯一标识符,而为了方便使用,可以使用其前12个字符作为短ID,尽管短ID有可能发生冲突。
Docker 容器和⽂件夹很类似,⼀个Docker容器包含了所有的某个应⽤运⾏所需要的环境。每⼀个 Docker 容器都是从 Docker 镜像创建的。Docker 容器可以运⾏、启动、停⽌、移动、删除、暂停(挂 起)。每⼀个 Docker 容器都是独⽴和安全的应⽤平台,Docker 容器是 Docker 的运⾏⼀部分。
列出当前系统中所有的 Docker 镜像
[root@localhost ~]# docker images
[root@localhost ~]# docker image list
# 两条命令效果完全相同
输出结果如下
- REPOSITORY: 镜像的仓库名,通常是由镜像的作者定义的。
- TAG: 镜像的标签,标识了镜像的特定版本或者变体。
- IMAGE ID: 镜像的唯一标识符,通常是一个长字符串。
- CREATED: 镜像创建的时间。
- SIZE: 镜像的大小。
3.2、镜像管理
24年初很多国内镜像源关闭或停止注册,除可以使用科学上网法外,这里使用配置国内云镜像加速地址的方式进行拉取,配置方式如下:
配置/etc/resolv.confdns解析地址为8.8.8.8后
[root@localhost ~]# vim /etc/docker/daemon.json
[root@localhost ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": [
"https://ox288s4f.mirror.aliyuncs.com",
"https://registry.docker-cn.com",
"http://hub-mirror.c.163.com",
"https://mirror.ccs.tencentyun.com"
]
}
[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl restart docker
重启docker后拉取镜像
1)搜索镜像
[root@localhost ~]# docker search tomcat
#查找 star 数⾄少为 100 的镜像,默认不加 s 选项找出所有相关 centos 镜像:
[root@docker-server ~]# docker search tomcat -f stars=100
2)拉取镜像
[root@localhost ~]# docker pull tomcat
Using default tag: latest
latest: Pulling from library/tomcat
0e29546d541c: Pull complete
9b829c73b52b: Pull complete
cb5b7ae36172: Pull complete
6494e4811622: Pull complete
668f6fcc5fa5: Pull complete
dc120c3e0290: Pull complete
8f7c0eebb7b1: Pull complete
77b694f83996: Pull complete
0f611256ec3a: Pull complete
4f25def12f23: Pull complete
Digest: sha256:9dee185c3b161cdfede1f5e35e8b56ebc9de88ed3a79526939701f3537a52324
Status: Downloaded newer image for tomcat:latest
docker.io/library/tomcat:latest
# 不指定版本默认下载最新版
[root@localhost ~]# docker pull mysql:8.0
8.0: Pulling from library/mysql
72a69066d2fe: Already exists
93619dbc5b36: Already exists
99da31dd6142: Already exists
626033c43d70: Already exists
37d5d7efb64e: Already exists
ac563158d721: Already exists
d2ba16033dad: Already exists
688ba7d5c01a: Pull complete
00e060b6d11d: Pull complete
1c04857f594f: Pull complete
4d7cfa90e6ea: Pull complete
e0431212d27d: Pull complete
Digest: sha256:e9027fe4d91c0153429607251656806cc784e914937271037f7738bd5b8e7709
Status: Downloaded newer image for mysql:8.0
docker.io/library/mysql:8.0
# 指定版本拉取镜像
3)查看镜像详细信息
# 查看镜像详细信息
[root@docker-server ~]# docker image inspect 镜像id/镜像名称
[root@docker-server ~]# docker inspect 镜像id/镜像名称
4)删除镜像
#删除⼀个或多个,多个之间⽤空格隔开,可以使⽤镜像名称或id
[root@docker-server ~]# docker rmi daocloud.io/library/mysql
或者
[root@docker-server ~]# docker rmi 81debc
#参数解释:
#rm Remove one or more containers ---移除⼀个或多个容器
#rmi Remove one or more images ---删除⼀个或多个镜像
5)强制删除镜像(工作中不要用)
#如果镜像正在被使⽤中可以使⽤--force强制删除
# docker rmi docker.io/ubuntu:latest --force
-f, --force Force removal of the image
#注意: 容器运⾏中不能删除,将容器停⽌后,删除容器在删除镜像。
6) 只查看所有镜像的id(这个是和清空镜像连用)
[root@docker-server ~]# docker images -q
98ebf73aba75
81debc95563d
d0957ffdf8a2
7)清空所有镜像
[root@docker-server ~]# docker rmi $(docker images -q)
8)查看镜像制作过程
[root@docker-server ~]# docker history nginx
#使⽤镜像名或者镜像ID都可以
3.3、阿里云镜像仓库搭建
访问阿里云首页搜索容器镜像服务,个人版免费
按步骤创建自己的镜像仓库方便日后工作中使用,操作过程有详细教程,或按照提示操作即可,这里略过,腾讯云与之相同
4、容器
4.1、基础概念
使用命令创建一个docker容器,它会在所有的镜像层之上增加⼀个可写层。这个可写层有运⾏在CPU上的进程,⽽且有两个不同的状态:运⾏态(Running)和退出态 (Exited)。这就是Docker容器。当我们使⽤docker run启动容器, Docker容器就进⼊运⾏态,当我们停⽌Docker容器时,它就进⼊退出状态。
当我们有⼀个正在运⾏的Docker容器时,从运⾏态到停⽌态,我们对它所做的⼀切变更都会永久地写到 容器的⽂件系统中。要切记,对容器的变更是写⼊到容器的⽂件系统的,⽽不是写⼊到Docker镜像中的。我们可以⽤同⼀个镜像启动多个Docker容器,这些容器启动后都是活动的,彼此还是相互隔离的。 我们对其中⼀个容器所做的变更只会局限于那个容器本身。如果对容器的底层镜像进⾏修改,那么当前正在运⾏的容器是不受影响的,不会发⽣⾃动更新现象。
4.2、容器管理
1)使用镜像运行一个容器,进入容器内部后退出并删除新创建的容器
bash
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 605c77e624dd 2 years ago 141MB
tomcat latest fb5657adc892 2 years ago 680MB
mysql 5.7 c20987f18b13 2 years ago 448MB
mysql 8.0 3218b38490ce 2 years ago 516MB
ubuntu latest ba6acccedd29 2 years ago 72.8MB
[root@localhost ~]# docker run -it nginx /bin/bash
-it: 这两个选项结合起来,表示创建一个交互式的容器。具体含义如下:
-i, --interactive: 保持标准输入 (stdin) 打开,即使没有附加到容器上。
-t, --tty: 分配一个伪终端 (pseudo-tty)。这使得我们可以与容器的 shell 进行交互。
root@33f13d113201:/# exit
exit
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
33f13d113201 nginx "/docker-entrypoint...." 27 seconds ago Exited (0) 17 seconds ago wizardly_ramanujan
#如果你在执⾏docker run时没有指定--name,那么⾃动⽣成⼀个随机字符串
[root@localhost ~]# docker rm wizardly_ramanujan
wizardly_ramanujan
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2)创建新容器但不启动
bash
[root@localhost ~]# docker create -it nginx /bin/bash
3)容器自启动
bash
[root@docker-server ~]# docker run -it --restart=always nginx /bin/bash
--restart=always: 指定容器的重启策略为始终重启。这意味着当 Docker 引擎重启时,该容器会自动重新启动。
4)自销毁容器(没用过)
bash
--rm: 默认情况下,每个容器在退出时,其文件系统会保留下来,这样可以保存容器产生的数据。然而,有时你可能只需要临时运行一个容器,而不需要保留其产生的数据。这时就可以使用 --rm 参数。
[root@docker-server ~]# docker run -it --rm nginx /bin/bash
root@be2d0a462ce1:/# exit
exit
此时查看容器无法找到刚创建的容器
注意:不能使用 -d 参数与 --rm 和 --restart=always 冲突。
5)容器命名
bash
--name: 为容器分配一个名称。如果不指定名称,Docker 会自动分配一个随机的名称给容器。
示例:
[root@docker-server ~]# docker run -it --name my-nginx-name1 nginx /bin/bash
6)退出容器
bash
这里退出容器有两种方法
一种是exit
一种是ctrl+p+q(摁着ctrl摁一下p摁一下q)
建议使用ctrl+p+q,exit推出可能会影响容器状态
7)查看容器
bash
1、只查看运行状态的容器:
docker ps
这条命令用于列出当前正在运行的 Docker 容器。
2、查看所有容器(包括停止的)
docker ps -a
使用 -a 参数可以列出所有状态的 Docker 容器,包括运行中的和已停止的。
3、只查看所有容器的 ID:
docker ps -a -q
8)停止/删除所有容器
bash
docker stop `docker ps -a -q`
docker rm `docker ps -a -q`
9)查看容器详细信息
bash
[root@docker-server ~]# docker inspect 容器名称/容器ID
#经常查看的参数
id号
Networks网络模式
IPAddress ip地址
10)启动容器
bash
[root@docker-server ~]# docker start name
11)关闭容器
bash
[root@docker-server ~]# docker stop name
[root@docker-server ~]# docker kill name --强制终⽌容器
12)删除容器
bash
要删除一个容器,可以使用其容器 ID 或名称。例如:
# docker rm my-container
如果容器正在运行,需要先停止它然后再删除。可以使用 `-f` 参数强制删除容器,但这样可能会导致数据丢失或其他不良影响,因此慎用:
# docker rm -f my-container
13)状态管理
bash
删除所有已停止的容器:
docker rm $(docker ps -qf status=exited)
通过 docker ps 和 docker rm 命令,删除所有状态为已停止 (exited) 的容器。
docker ps -qf status=exited: 使用 docker ps 命令配合 -q 参数来仅输出容器 ID,并结合 -f 参数来过滤状态为 exited 的容器。
docker rm $(...): 将 docker ps 输出的容器 ID 作为参数传递给 docker rm 命令,从而删除这些容器。
暂停与恢复
pause
: 暂停容器内所有的进程,使得容器内的所有活动都暂时停止。unpause
: 恢复容器内因pause
操作而暂停的进程,使得容器内的活动可以继续进行。
bash
[root@docker-server ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8949f10e895a nginx "/docker-entrypoint...." 23 minutes ago Up 23 minutes 80/tcp nginx1
[root@docker-server ~]# docker pause nginx1
nginx1
[root@docker-server ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8949f10e895a nginx "/docker-entrypoint...." 24 minutes ago Up 24 minutes (Paused) 80/tcp nginx1
[root@docker-server ~]# docker unpause nginx1
nginx1
[root@docker-server ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8949f10e895a nginx "/docker-entrypoint...." 24 minutes ago Up 24 minutes 80/tcp nginx1
14)重启容器
bash
[root@docker-server ~]# docker restart name
15)容器后台运行
bash
[root@docker-server ~]# docker run -dit 镜像ID /bin/bash
-d 后台运⾏必须要加-it
16)容器重命名
bash
[root@docker-server ~]# docker rename 老名字 新名字
17)容器资源使⽤统计
bash
[root@docker-server ~]# docker stats
18)连接容器
bash
1)
docker attach 容器id #前提是容器创建时必须指定了交互shell
2)
1.交互型任务:
[root@docker-server ~]# docker exec -it 容器id /bin/bash
2.后台型任务:不进⼊容器⾥⾯执⾏命令
[root@docker-server ~]# docker exec 容器id touch /testfile
19)容器运行监控
可以使⽤logs、top、wait这些⼦命令
可以通过使⽤docker logs命令来查看容器的运⾏⽇志,其中--tail选项可以指定查看最后⼏条⽇ 志,使⽤-f选项可以跟踪⽇志的输出,直到⼿动停⽌
bash
[root@docker-server ~]# docker logs -f nginx2
# 来查看容器的运⾏⽇志
[root@docker-server ~]# docker top nginx2
# 显示⼀个运⾏的容器⾥⾯的进程信息
wait打印出容器的退出码
bash
打开两个终端窗口
第一个终端窗口
[root@docker-server ~]# docker wait nginx1
此时这个命令会占用此窗口
第二个终端窗口
[root@docker-server ~]# docker stop nginx1
这个命令执行结束后返回第一个窗口查看
[root@docker-server ~]# docker wait nginx1
0
20)宿主机和容器之间相互拷⻉⽂件/⽬录
bash
从容器拷贝到本机
假设有一个正在运行的容器,其容器名为nginx1,需要将容器中的文件 /app/data.txt 拷贝到本机的 /home/user/data/ 目录下:
docker cp nginx1:/app/data.txt /home/user/data/
这条命令将容器中的 /app/data.txt 文件复制到本机的 /home/user/data/ 目录下。
从本机拷贝到容器
假设当前目录下有一个名为 config.json 的文件,需要将该文件复制到正在运行的容器nginx1的 /etc/config/ 目录下:
docker cp config.json webapp:/etc/config/
这条命令将本地的 config.json 文件复制到容器nginx1的 /etc/config/ 目录下。
拷贝目录
[root@docker-server ~]# docker cp -a /opt nginx2:/usr/local/bin/
4.3、容器镜像打包迁移
容器的打包迁移方式有两种
1)先打包,再转化为镜像
bash
[root@docker-server ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fa433a15b7d7 nginx "/docker-entrypoint...." 40 minutes ago Up 15 minutes 80/tcp nginx2
8949f10e895a nginx "/docker-entrypoint...." 3 hours ago Up 15 minutes 80/tcp nginx1
[root@docker-server ~]# docker export -o nginx1_1.tar 8949f10e895a
[root@docker-server ~]# docker export nginx2 > nginx2_1.tar
[root@docker-server ~]# ls -ll
总用量 281308
-rw-------. 1 root root 1347 6月 18 19:49 anaconda-ks.cfg
-rw------- 1 root root 144025600 8月 1 21:30 nginx1_1.tar
-rw-r--r-- 1 root root 144025600 8月 1 21:35 nginx2_1.tar
选一个包复制过去
[root@docker-server ~]# scp nginx1_1.tar 192.168.188.129:/root/
到129主机上
bash
[root@localhost ~]# ls
anaconda-ks.cfg nginx1_1.tar
[root@localhost ~]# docker import nginx1_1.tar nginx:v1996
sha256:49652cb2ce40b2838496863bfa0f85dc0b232ca3401fc1cab1499dc801198aa1
# 版本号瞎写的,防止混淆,工作环境严格遵守命名规则
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v1996 49652cb2ce40 8 seconds ago 140MB
容器包成功转化为另一个主机镜像,后续启动容器过程略
2)先保存为本地镜像
在128主机上
bash
#本机初始镜像
[root@docker-server ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 605c77e624dd 2 years ago 141MB
tomcat latest fb5657adc892 2 years ago 680MB
mysql 5.7 c20987f18b13 2 years ago 448MB
mysql 8.0 3218b38490ce 2 years ago 516MB
ubuntu latest ba6acccedd29 2 years ago 72.8MB
#本机运行的容器
[root@docker-server ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fa433a15b7d7 nginx "/docker-entrypoint...." 55 minutes ago Up 29 minutes 80/tcp nginx2
8949f10e895a nginx "/docker-entrypoint...." 3 hours ago Up 29 minutes 80/tcp nginx1
#将容器转化为镜像
[root@docker-server ~]# docker commit nginx2 nginx:v2024
sha256:61d0976fbf6fb3771f178b7c70397e52ad61e814baf9d3b7fb32414684356959
# 使用commit命令时有以下参数可以使用
# -m 添加注释
# -a 作者
# -p,--pause=true 提交时暂停容器运⾏
#再次查看本机镜像
[root@docker-server ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v2024 61d0976fbf6f 3 seconds ago 141MB
nginx latest 605c77e624dd 2 years ago 141MB
tomcat latest fb5657adc892 2 years ago 680MB
mysql 5.7 c20987f18b13 2 years ago 448MB
mysql 8.0 3218b38490ce 2 years ago 516MB
ubuntu latest ba6acccedd29 2 years ago 72.8MB
#使用save将镜像打包然后scp拷贝到129上
[root@docker-server ~]# docker save -o nginx2_1.tar nginx:v2024
[root@docker-server ~]# ls -ll
总用量 283152
-rw-------. 1 root root 1347 6月 18 19:49 anaconda-ks.cfg
-rw------- 1 root root 144025600 8月 1 21:30 nginx1_1.tar
-rw------- 1 root root 145912832 8月 1 21:51 nginx2_1.tar
[root@docker-server ~]# scp nginx2_1.tar 192.168.188.129:/root/
root@192.168.188.129's password:
nginx2_1.tar 100% 139MB 44.4MB/s 00:03
[root@docker-server ~]#
到129主机上
bash
[root@localhost ~]# docker load < nginx2_1.tar
2edcec3590a4: Loading layer 83.86MB/83.86MB
e379e8aedd4d: Loading layer 62MB/62MB
b8d6e692a25e: Loading layer 3.072kB/3.072kB
f1db227348d0: Loading layer 4.096kB/4.096kB
32ce5f6a5106: Loading layer 3.584kB/3.584kB
d874fd2bc83b: Loading layer 7.168kB/7.168kB
bb48ecfe0df4: Loading layer 9.216kB/9.216kB
Loaded image: nginx:v2024
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v2024 61d0976fbf6f 10 minutes ago 141MB
nginx v1996 49652cb2ce40 17 minutes ago 140MB
5、Dockerfile
Docker 提供了⼀种更便捷的⽅式,叫作 Dockerfile,docker build命令⽤于根据给定的Dockerfile内设置的命令构建一个全新的Docker镜像。
docker build参数详解(重点为-t参数)
--build-arg: 设置构建时的变量。
--no-cache: 默认为 false。设置该选项,将不使用 Build Cache 构建镜像。
--pull: 默认为 false。设置该选项,总是尝试 pull 镜像的最新版本。
--compress: 默认为 false。设置该选项,将使用 gzip 压缩构建的上下文。
--disable-content-trust: 默认为 true。设置该选项,将对镜像进行验证。
--file, -f: Dockerfile 的完整路径,默认值为 PATH/Dockerfile。
--isolation: 默认为 --isolation="default",即 Linux 命名空间;其他选项还有 process 或 hyperv。
--label: 为生成的镜像设置 metadata。
--squash: 默认为 false。设置该选项,将新构建出的多个层压缩为一个新层,但是将无法在多个镜像之间共享新层。
--tag, -t: 镜像的名字及 tag,通常格式为 name:tag 或者 name;可以在一次构建中为一个镜像设置多个 tag。
--network: 默认为 default。设置该选项,为构建过程中的 RUN 指令设置网络模式。
--quiet, -q: 默认为 false。设置该选项,压制构建过程的输出,成功后仅打印镜像 ID。
--force-rm: 默认为 false。设置该选项,总是删除掉中间环节的容器。
--rm: 默认为 --rm=true,即整个构建过程成功后删除中间环节的容器。
根据Dockerfile构建Docker镜像操作如下
1)创建镜像所在的⽂件夹和Dockerfile⽂件
[root@docker-server ~]# mkdir centos7_mini
[root@docker-server ~]# cd centos7_mini/
[root@docker-server centos7_mini]# touch Dockerfile
[root@docker-server centos7_mini]# vim Dockerfile
[root@docker-server centos7_mini]# cat Dockerfile
FROM centos:7
MAINTAINER liumuquan liumuquan@qq.com
RUN touch 1.txt
RUN mkdir /test
[root@docker-server centos7_mini]# vim Dockerfile
[root@docker-server centos7_mini]# docker build -t liumuquan/centos:777 /root/centos7_mini
。。。。。。。。。。。省略过程。。。。。。。。
这里每执行一步都是一次镜像>容器>镜像的过程
[root@docker-server centos7_mini]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
liumuquan/centos 777 c840aba18439 5 minutes ago 204MB
nginx latest 605c77e624dd 2 years ago 141MB
tomcat latest fb5657adc892 2 years ago 680MB
mysql 5.7 c20987f18b13 2 years ago 448MB
mysql 8.0 3218b38490ce 2 years ago 516MB
registry latest b8604a3fe854 2 years ago 26.2MB
ubuntu latest ba6acccedd29 2 years ago 72.8MB
centos 7 eeb6ee3f44bd 2 years ago 204MB
[root@docker-server centos7_mini]#
工作中有一点需要注意,如果是docker官方提供的centos7之前的系统镜像不能直接通过RUN命令使用yum安装,需要更换镜像内的源文件,最好做一个镜像放在阿里云里面
阿里源centos7的镜像dockerfile
[root@docker-server centos7_mini]# cat Dockerfile
FROM centos:7
RUN rm -rf /etc/yum.repo.d/*
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
RUN yum install -y wget
RUN wget -O /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo
如果docker build运行中出错可能会残留一个退出状态的容器或错误的镜像,记得检查删除。
2).创建⼀个jenkins的Dockerfile
[root@docker-server jenkins]# ls
apache-tomcat-9.0.79.tar.gz jdk-11.0.16_linux-x64_bin.tar.gz jenkins.war
[root@docker-server jenkins]# vim Dockerfile
[root@docker-server jenkins]# cat Dockerfile
FROM centos:7
MAINTAINER liumuquan liumuquan@qq.com
ENV JAVA_HOME /usr/local/jdk-11.0.16
ENV TOMCAT_HOME /usr/local/apache-tomcat-9.0.79
ENV PATH=$JAVA_HOME/bin:$PATH
ADD apache-tomcat-9.0.79.tar.gz /usr/local/
ADD jdk-11.0.16_linux-x64_bin.tar.gz /usr/local/
RUN rm -rf /usr/local/apache-tomcat-9.0.79/webapps/*
ADD jenkins.war /usr/local/apache-tomcat-9.0.79/webapps/
RUN rm -rf jdk-11.0.16_linux-x64_bin.tar.gz apache-tomcat-9.0.79.tar.gz
EXPOSE 8080
ENTRYPOINT ["/usr/local/apache-tomcat-9.0.79/bin/catalina.sh","run"]
[root@docker-server jenkins]# docker build -t jenkins:v1 .
[root@docker-server jenkins]# docker run -itd --name jenkins1 -p 8081:8080 jenkins:v1
1cd044e93dfd69cbe3ebdd0209ca8b5fe9eab37eb4899e3f98402d31bb0ae777
此时使用浏览器访问可以看到jenkins网页
这里有一个问题:CMD与ENTRYPOINT区别
Dockerfile中的CMD
-
每个Dockerfile只能包含一个CMD指令。如果存在多个CMD指令,只有最后一个会生效。
-
CMD指令类似于在运行Docker容器时附加的参数。举例来说:
- 如果在命令行中运行
docker run -itd --name test image /bin/bash -c
,那么相当于在Dockerfile中使用了CMD ["/bin/bash", "-c"]
。 - 如果Dockerfile中已经定义了
CMD ["/bin/bash", "-c"]
,那么在运行时不需要再额外添加这些参数。如果添加了额外参数,那么默认的CMD参数将被覆盖失效。
- 如果在命令行中运行
Dockerfile中的ENTRYPOINT
-
每个Dockerfile只能包含一个ENTRYPOINT指令。如果存在多个ENTRYPOINT指令,只有最后一个会生效。ENTRYPOINT指令可以理解为容器启动时要执行的命令,类似于开机启动。
-
举例来说:
- 如果Dockerfile中定义了
ENTRYPOINT ["tail", "-f", "/var/log/nginx/access.log"]
,那么在启动容器时将执行这些命令。如果在启动时附加参数,这些参数将被添加到指定的命令后面执行。
- 如果Dockerfile中定义了
Dockerfile优化
- RUN 命令要尽量写在⼀条⾥,每次 RUN 命令都是在之前的镜像上封装,只会增⼤不会减⼩
- 每次进⾏依赖安装后,记得yum clean all
- 选择⽐较⼩的基础镜像。alpine
6、docker镜像仓库(官方)
私有仓库镜像(官方):
registry, 没有图形界⾯。Docker hub官⽅已提供容器镜像registry,⽤于搭建私有仓库
部署方式:
另找一台全新的环境192.168.188.129,按照上方的方式安装docker,修改网络和docker配置
bash
[root@localhost ~]# docker pull registry
[root@localhost ~]# docker run -itd -v /home/dockerdata/registry:/var/lib/registry --name "pri_registry" --restart=always -p 5000:5000 registry
28c6f198a14dd02d9665672b3d0545203b52a4fcf9dad6279a760ea942c6712b
# 下方为命令解释
-v /home/dockerdata/registry:/var/lib/registry: 这个选项 -v 用来将本地文件系统的目录挂载到容器内部的指定路径。具体来说:
/home/dockerdata/registry 是主机上的目录路径。
/var/lib/registry 是容器内的路径,通常用于存储 Docker Registry 的数据。
这样做的效果是将主机上的 /home/dockerdata/registry 目录挂载到容器内的 /var/lib/registry 目录,使得容器内的数据可以持久化到主机上。
--name "pri_registry": 指定容器的名称为 pri_registry。这样可以方便后续通过容器名称来管理和操作容器,而不必依赖于容器ID。
-p 5000:5000: 将容器的端口 5000 映射到主机的端口 5000。这样,外部网络可以通过主机的 5000 端口访问容器内部运行的服务,通常用于提供对应用程序的访问。
检查连通性
bash
[root@localhost ~]# curl -I http://127.0.0.1:5000
HTTP/1.1 200 OK
Cache-Control: no-cache
Date: Sun, 04 Aug 2024 09:53:19 GMT
[root@localhost ~]#
更换128主机进行以下操作,向私有仓库推送镜像
bash
[root@docker-server ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox latest beae173ccac6 2 years ago 1.24MB
[root@docker-server ~]# docker tag busybox 192.168.188.129:5000/busybox
[root@docker-server ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox latest beae173ccac6 2 years ago 1.24MB
192.168.188.129:5000/busybox latest beae173ccac6 2 years ago 1.24MB
# 此时还无法进行推送,请求默认为https,需要修改配置文件
修改配置文件如下
bash
[root@docker-server ~]# vim /etc/docker/daemon.json
[root@docker-server ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": [
"https://ox288s4f.mirror.aliyuncs.com",
"https://registry.docker-cn.com",
"http://hub-mirror.c.163.com",
"https://mirror.ccs.tencentyun.com"
],
"insecure-registries":["192.168.188.129:5000"]
}
[root@docker-server ~]# systemctl daemon-reload
[root@docker-server ~]# systemctl restart docker
推送刚修改的镜像
bash
[root@docker-server ~]# docker push 192.168.188.129:5000/busybox:latest
The push refers to repository [192.168.188.129:5000/busybox]
01fd6df81c8e: Pushed
latest: digest: sha256:62ffc2ed7554e4c6d360bce40bbcf196573dd27c4ce080641a2c59867e732dee size: 527
查看仓库内容
bash
[root@docker-server ~]# curl http://192.168.188.129:5000/v2/_catalog
{"repositories":["busybox"]}
[root@docker-server ~]# curl http://192.168.188.129:5000/v2/busybox/tags/list
{"name":"busybox","tags":["latest"]}
此时我们去查看仓库的宿主机129查看映射出来的目录
bash
[root@localhost ~]# ls /home/dockerdata/registry/docker/registry/v2/repositories/busybox/_
_layers/ _manifests/ _uploads/
回到128删除本地的busybox镜像
bash
[root@docker-server ~]# docker rmi 192.168.188.129:5000/busybox
[root@docker-server ~]# docker rmi busybox
尝试从私有仓库拉取镜像
bash
[root@docker-server ~]# docker pull 192.168.188.129:5000/busybox:latest
latest: Pulling from busybox
5cc84ad355aa: Pull complete
Digest: sha256:62ffc2ed7554e4c6d360bce40bbcf196573dd27c4ce080641a2c59867e732dee
Status: Downloaded newer image for 192.168.188.129:5000/busybox:latest
192.168.188.129:5000/busybox:latest
7、部署docker web ui应⽤
bash
[root@docker-server ~]# docker pull uifd/ui-for-docker
Using default tag: latest
latest: Pulling from uifd/ui-for-docker
841194d080c8: Pull complete
Digest: sha256:fe371ff5a69549269b24073a5ab1244dd4c0b834cbadf244870572150b1cb749
Status: Downloaded newer image for uifd/ui-for-docker:latest
docker.io/uifd/ui-for-docker:latest
[root@docker-server ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos 7.7 179c4a937f7e 18 hours ago 461MB
192.168.188.129:5000/busybox latest beae173ccac6 2 years ago 1.24MB
nginx latest 605c77e624dd 2 years ago 141MB
tomcat latest fb5657adc892 2 years ago 680MB
mysql 5.7 c20987f18b13 2 years ago 448MB
mysql 8.0 3218b38490ce 2 years ago 516MB
portainer/portainer-ce latest 0df02179156a 2 years ago 273MB
registry latest b8604a3fe854 2 years ago 26.2MB
ubuntu latest ba6acccedd29 2 years ago 72.8MB
centos 7 eeb6ee3f44bd 2 years ago 204MB
uifd/ui-for-docker latest 965940f98fa5 7 years ago 8.1MB
[root@docker-server ~]# docker run -it -d --name docker-web -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock uifd/ui-for-docker
e6d94c2e269d9a98f0b580091a166d894ceccd55ebd17573a120fa4ccc8ad929
使用访问128的9000端口可以进行简单的docker管理
8、harbor仓库
harbor是VMware公司开源的企业级docker registry项目。主要是实现为用户去迅速搭建一个docker registry服务,有可视化界面。
基础环境:
192.168.188.129,防火墙、selinux已关闭,yum源更改为国内源,docker已部署。
所需安装包需要外部网络环境,这里使用以前下载保存在云盘的安装包
bash
链接:https://pan.baidu.com/s/1619AcrAXmhaTKKXS5ahXNQ?pwd=1ee5
提取码:1ee5
8.1、harbor部署
bash
[root@localhost ~]# ls
anaconda-ks.cfg docker-compose-linux-2.2.3-x86_64 harbor-offline-installer-v1.10.10.tgz
[root@localhost ~]# mv docker-compose-linux-2.2.3-x86_64 /usr/local/bin/docker-compose
[root@localhost ~]# chmod +x /usr/local/bin/docker-compose
[root@localhost ~]# tar xf harbor-offline-installer-v1.10.10.tgz
[root@localhost ~]# ls
anaconda-ks.cfg harbor harbor-offline-installer-v1.10.10.tgz
这个harbo内部其实是启动脚本和多个组件的镜像文件,需要先修改harbor配置文件
bash
[root@localhost ~]# ls
anaconda-ks.cfg harbor harbor-offline-installer-v1.10.10.tgz
[root@localhost ~]# cd harbor
[root@localhost harbor]# ls
common.sh harbor.v1.10.10.tar.gz harbor.yml install.sh LICENSE prepare
[root@localhost harbor]# vim harbor.yml
修改内容如下
bash
# 修改ip为本机ip
hostname: 192.168.188.129
# 将https部分内容全部注释
# https related config
#https:
# https port for harbor, default is 443
#port: 443
# The path of cert and key files for nginx
#certificate: /your/certificate/path
#private_key: /your/private/key/path
执行安装脚本
bash
[root@localhost harbor]# ./install.sh
访问harbor的web页面http://192.168.188.129:80(注意此处,我注释掉了https,直接输入ip谷歌火狐会默认补上https)
正常进入harbor页面
在129配置harbor的https访问
bash
[root@localhost ~]# mkdir -p /data/cert/
[root@localhost ~]# openssl genrsa -out /data/cert/server.key 2048
Generating RSA private key, 2048 bit long modulus
..+++
.........................+++
e is 65537 (0x10001)
[root@localhost ~]# openssl req -x509 -new -nodes -key /data/cert/server.key -subj "/CN=192.168.188.129" -days 3650 -out /data/cert/server.crt
[root@localhost ~]# ls /data/cert/
server.crt server.key
[root@localhost ~]# cd /root/harbor
[root@localhost harbor]# ls
common docker-compose.yml harbor.yml LICENSE
common.sh harbor.v1.10.10.tar.gz install.sh prepare
[root@localhost harbor]# vim harbor.yml
将上面注释掉的https部分修改如下
bash
# https related config
https:
# https port for harbor, default is 443
port: 443
# The path of cert and key files for nginx
certificate: /data/cert/server.crt
private_key: /data/cert/server.key
重启harbor加载配置
bash
[root@localhost harbor]# ./prepare
# 以下扩展内容
如果上面方式重启失效,或者执行后https访问仍然失败,可以在harbor目录下使用如下命令重装容器
[root@localhost harbor]# docker-compose down
[root@localhost harbor]# docker-compose up -d
8.2、harbor基础使用
演示时以128主机为客户端,配置如下,此处注意主机名分辨操作对象
bash
[root@docker-server ~]# vim /etc/docker/daemon.json
[root@docker-server ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": [
"https://ox288s4f.mirror.aliyuncs.com",
"https://registry.docker-cn.com",
"http://hub-mirror.c.163.com",
"https://mirror.ccs.tencentyun.com"
],
"insecure-registries":["192.168.188.129"]
}
[root@docker-server ~]# systemctl daemon-reload
[root@docker-server ~]# systemctl restart docker
创建项目(这里创建一个私有的,私有的项目更麻烦可以演示的效果更多)
进入刚创建的项目
创建用户
将新创建的用户添加到centos项目中,并赋予项目管理员权限
使用 128主机向harbor内推送镜像
bash
[root@docker-server ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry latest b8604a3fe854 2 years ago 26.2MB
[root@docker-server ~]# docker tag registry:latest 192.168.188.129/centos/registry:v1996
[root@docker-server ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry latest b8604a3fe854 2 years ago 26.2MB
192.168.188.129/centos/registry v1996 b8604a3fe854 2 years ago 26.2MB
# 因为是非公开(私有)项目,推送前需要先登录
[root@docker-server ~]# docker login -u liumuquan -p Liumuquan@123 192.168.188.129
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
[root@docker-server ~]# docker push 192.168.188.129/centos/registry:v1996
The push refers to repository [192.168.188.129/centos/registry]
aeccf26589a7: Pushed
f640be0d5aad: Pushed
aa4330046b37: Pushed
ad10b481abe7: Pushed
69715584ec78: Pushed
v1996: digest: sha256:36cb5b157911061fb610d8884dc09e0b0300a767a350563cbfd88b4b85324ce4 size: 1363
[root@docker-server ~]#
# 推送成功
推送完成后返回web页面查看
推送另一个版本
bash
[root@docker-server ~]# docker tag registry:latest 192.168.188.129/centos/registry:v2024
[root@docker-server ~]# docker push 192.168.188.129/centos/registry:v2024
The push refers to repository [192.168.188.129/centos/registry]
aeccf26589a7: Layer already exists
f640be0d5aad: Layer already exists
aa4330046b37: Layer already exists
ad10b481abe7: Layer already exists
69715584ec78: Layer already exists
v2024: digest: sha256:36cb5b157911061fb610d8884dc09e0b0300a767a350563cbfd88b4b85324ce4 size: 1363
[root@docker-server ~]#
在客户端拉取镜像命令获取方式(非公开项目需要提前登录)
一个harbor可以有多个项目,一个项目可以有多个仓库,一个仓库可以存放多个镜像
注:公有仓库和私有仓库区别为:
- 私有仓库拉取/推送均需要登陆
- 公有仓库推送需要登陆, 拉取无需登录。
9、Docker资源限制
在使用 Docker 运行容器时,一台主机上可能会同时运行数百个容器。这些容器虽然互相隔离,但它们共享相同的CPU、内存和磁盘资源。如果不对容器使用的资源进行限制,容器之间会相互影响。具体来说,小范围的影响会导致容器资源使用不公平;而大范围的影响可能会耗尽主机和集群的资源,导致服务完全不可用。
CPU 和内存的资源限制已经相对成熟且易于使用,能够满足大部分用户的需求。尽管目前无法动态限制磁盘容量,但限制磁盘读写速度已经能够适应许多场景。
资源限制不仅使得我们能够为容器设置合理的 CPU、内存等资源以便更好地管理,同时也能有效地预防恶意攻击和异常,对容器而言是非常重要的功能。
这里需要引入一个系统压力测试工具stress,可以使用yum安装,这里我们使用一个镜像生成一个stress
9.1、cpu资源限制
什么是cpu share:Docker允许用户为每个容器设置一个 CPU share 数字,默认情况下每个容器的 share 是 1024。这个 share 是相对的,没有具体的绝对意义。在主机上同时运行多个容器时,每个容器占用的 CPU 时间比例取决于其 share 在总额中的比例。Docker会根据主机上运行的容器和进程的动态情况,调整每个容器使用 CPU 时间的比例。简单来说share最大值为1024,share与权重类似,数字越大优先级权重越高。
可以参考下表理解
|----------|----------|----------|----------|
| A容器share | B容器share | A容器所占cpu | B容器所占cpu |
| 1024 | 1024 | 50% | 50% |
| 1024 | 512 | 约等于70% | 约等于30% |
| 该容器被删除 | 512 | / | 100% |
好处:能保证 CPU 尽可能处于运⾏状态,充分利⽤ CPU 资源,⽽且保证所有容器的相对公平;缺点:⽆法指定容器使⽤ CPU 的确定值。
实际操作如下:
bash
[root@docker-server ~]# docker run -d --cpus 1.5 progrium/stress --cpu 3
--cpus 1.5: 这个参数用来限制容器可以使用的 CPU 资源。在这里,指定容器最多可以使用主机 1.5 个 CPU 的资源。通常情况下,这个值应该不超过主机的物理 CPU 核心数,但 Docker 允许超额分配,因此可以指定小数值来实现精确分配。
如果主机有多个 CPU 核心,1 个 CPU 表示一个核心的全部时间。
1.5 表示容器可以使用一个核心加上该核心50%的时间。这种设置在超线程或虚拟化环境中特别有用。
--cpu 3: 这是传递给 progrium/stress 的参数之一。它指示在容器中运行 3 个进程,每个进程不断计算随机数的平方,以模拟 CPU 负载。这将导致容器占用大量的 CPU 资源,具体占用多少取决于主机上可用的物理 CPU 核心数和 --cpus 参数的设置。
总的来说这条命令是:启动三个进程占用cpu,但是占用的总量是150%,也就是平分到每个cpu50%
如果设置的 --cpus 值⼤于主机的 CPU 核数,docker 会直接报错
如果多个容器都设置了 --cpus ,并且它们之和超过主机的 CPU 核数,并不会导致容器失败或者退出, 这些容器之间会竞争使⽤ CPU,具体分配的 CPU 数量取决于主机运⾏情况和容器的 CPU share 值。也就是说 --cpus 只能保证在 CPU 资源充⾜的情况下容器最多能使⽤的 CPU 数。想要任何条件下都保证cpu的完美使用是不可能的。
cpu绑定操作
bash
[root@docker-server ~]# docker run --rm -it --cpuset-cpus=0,1 progrium/stress --cpu 2
可以通过 --cpuset 参数让容器只运⾏在前两个核上
只是官方手册有这种配置方式,工作生产环境中不会这样使用
9.2、mem资源限制
Docker 默认不限制容器内存使用,容器可以使用主机提供的所有内存。这带来了安全风险,因为恶意软件或内存泄漏可能导致主机内存耗尽,使服务不可用。为了避免这种情况,可以为每个容器设置内存使用上限,超过上限时容器会被kill,而不是继续消耗主机资源。
然而,限制内存使用也会带来新的问题。设置过小的内存限制可能导致服务被提前终止,而过大则会浪费资源。
最佳做法包括:
- 在测试阶段对应用进行内存压力测试,理解其正常工作负载下的内存需求。
- 必须为容器设置合理的内存上限,确保主机资源充足。
- 尽量避免使用 swap,因为其使用会增加内存管理的复杂性,并不利于资源调度,国内主流云厂商默认不使用swap。
docker 限制容器内存使⽤量:
docker 启动参数中,和内存限制有关的包括(参数的值⼀般是内存⼤⼩,也就是⼀个正数,后⾯跟着 内存单位 b、k、m、g,分别对应 bytes、KB、MB、和 GB):
-m --memory:容器能使⽤的最⼤内存⼤⼩,最⼩值为 4m
如果限制容器的内存使⽤为 64M,在申请 64M 资源的情况下,容器运⾏正常:
bash
[root@docker-server ~]# docker run --rm -it -m 64m progrium/stress --vm 1 --vm-bytes 64M --vm-hang 0
-m 64m: 这个选项限制容器可以使用的内存量。在这里,64m 表示最大内存为 64 MB。如果容器尝试使用超过这个限制的内存,Docker 将会杀死该容器。这是为了防止容器耗尽主机的内存资源。
--vm 1 --vm-bytes 64M --vm-hang 0: 这些是传递给 progrium/stress 工具的参数:
--vm 1: 启动一个虚拟内存工作集(Virtual Memory working set)。
--vm-bytes 64M: 指定每个工作集的大小为 64 MB。
--vm-hang 0: 表示不让虚拟内存操作挂起。
9.3、io 资源限制
⽬前 docker ⽀持对磁盘的读写速度进⾏限制,但是并没有⽅法能限制容器能使⽤的磁盘容量(⼀旦磁盘 mount 到容器⾥,容器就能够使⽤磁盘的所有容量),这个在工作中完全没有用到过
bash
docker run --rm -it --device-read-bps=/dev/sda:1mb --device-write-bps=/dev/sda:1mb ubuntu
--device-read-bps=/dev/sda:1mb 和 --device-write-bps=/dev/sda:1mb:
限制容器对 /dev/sda 设备的读写速率为每秒 1 MB。这有助于控制容器的磁盘 IO,以防止其对系统其他部分的影响过大。
这一项和cpu时间资源配额(限制了容器每秒可以使用的 CPU 时间),高级网络管理任务授权类似,都是极少在工作生产中使用的。
10、Centos7容器(systemd整合)
因为 systemd 要求 CAPSYSADMIN 权限,从⽽得到了读取到宿主机 cgroup 的能⼒,CentOS7 中已经⽤ fakesystemd 代替了 systemd 。 但是为了方便使⽤systemd,可⽤参考下⾯的 Dockerfile:
dockerfile内容如下
这个7.7是按照上文方法更换过源文件的镜像
bash
[root@docker-server systemd]# cat Dockerfile
FROM centos:7.7
MAINTAINER "liumuquan" liumuquan@qq.com
ENV container docker
RUN yum -y swap -- remove fakesystemd -- install systemd systemd-libs
RUN yum -y update; yum clean all; \
(cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); \
rm -f /lib/systemd/system/multi-user.target.wants/*;\
rm -f /etc/systemd/system/*.wants/*;\
rm -f /lib/systemd/system/local-fs.target.wants/*; \
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
rm -f /lib/systemd/system/basic.target.wants/*;\
rm -f /lib/systemd/system/anaconda.target.wants/*;
VOLUME [ "/sys/fs/cgroup" ]
CMD ["/usr/sbin/init"]
[root@docker-server systemd]#
启动容器的参数也要有所不同
为了运⾏⼀个包含 systemd 的容器,需要使⽤--privileged选项, 并且挂载主机的 cgroups ⽂件夹。
bash
[root@docker-server systemd]# docker run --privileged -tid -v /sys/fs/cgroup:/sys/fs/cgroup:ro local/c7.7-systemd
d13e20b6019a9b90fb8fece87dea5bc0cdd6d9ff03ff5a7b31747239c9f32f9c
[root@docker-server systemd]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d13e20b6019a local/c7.7-systemd "/usr/sbin/init" 25 seconds ago Up 24 seconds fervent_faraday
[root@docker-server systemd]# docker exec --privileged -it fervent_faraday /bin/bash
[root@d13e20b6019a /]# systemctl get-default
multi-user.target
11、Docker数据存储位置
查看和修改Docker数据存储位置方式如下
bash
[root@docker-server ~]# docker info | grep Root
Docker Root Dir: /var/lib/docker
[root@docker-server ~]# mkdir data
[root@docker-server ~]# vim /usr/lib/systemd/system/docker.service
# 修改如下
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --data-root=/data
原文:ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
修改方式为在原文后面加上--data-root=新的镜像路径
[root@docker-server ~]# systemctl daemon-reload
[root@docker-server ~]# systemctl restart docker
[root@docker-server ~]# docker info | grep Root
Docker Root Dir: /data
12、Docker⽹络管理
这里开始下面的内容实际工作上很少用到,这部分工作被k8s替代
查看当前网络类型
bash
[root@docker-server ~]# docker network list
NETWORK ID NAME DRIVER SCOPE
5480147dd1f8 bridge bridge local
5549e6235f77 host host local
3251dab47b08 none null local
12.1、bridge:⽹络桥接
bash
默认情况下启动、创建容器都是⽤该模式,所以每次docker容器重启时会按照顺序获取对应ip地址。
与vm的nat模式十分相似
12.2、none:⽆指定⽹络
bash
启动容器时,可以通过--network=none,docker容器不会分配局域⽹ip
此模式下容器不获取ip
12.3、host:主机⽹络
bash
docker容器和主机共⽤⼀个ip地址。
使⽤host⽹络创建容器:
[root@docker-server ~]# docker run -it --name nginx1 --net host nginx
此时访问宿主机端口可直接看到容器内运行的nginx首页
12.4、⾃定义⽹络类型
bash
[root@docker-server ~]# docker network create --subnet=192.168.0.0/16 staticnet
[root@docker-server ~]# docker network list
NETWORK ID NAME DRIVER SCOPE
5480147dd1f8 bridge bridge local
5549e6235f77 host host local
3251dab47b08 none null local
a65eb8c26796 staticnet bridge local
# 使⽤新的⽹络类型创建并启动容器
[root@docker-server ~]# docker run -itd --name server --net staticnet --ip 192.168.0.2 daocloud.io/library/centos:7.7
# 删除已创建⽹络
[root@docker-server]# docker network rm staticnet
12.5、异主容器互联
拓扑图如下
实现容器互联一般有两个方式:
- 路由⽅式
- 配置open vswitch虚拟交换机
这里作为理解即可