目录
由于需要在外网所以docker的镜像不能直接用pull拉取search也搜索不到,可以从网上提前下载好,如阿里云等镜像站里下载,然后传输给虚拟机,之后用docker load -i 来加载镜像
加-it会直接占用终端,加--rm即在他停止运行时就会自动删除容器
因为在运行的容器内写入内容之后删除该容器,重新开启之后里面添加的内容都会没有
删除之前的centos,运行新v1版本的centos和httpd
可以从网上下载相关的包,之后传输给虚拟机,导入到docker
查看docker的网络,一共有三种类型,如果不指定类型,默认是bridge,指定:--network=类型
在不停止容器运行的情况下,把test2加入到mynet1的网络中
此时就可以进行互通了,ip地址可以用docker inspect 容器名 查看
查看虚拟机里的文件,此时就会查看到在data1下有一个mqw1的文件
之后再运行其他容器时,需要使用该数据卷的模式时可以在运行时指定,此时该容器里就会有之前容器的数据
运行容器,把CPU划分为10000,他满运行占2000(即十分之二),并给他一个运行的进程,让他把资源都运行起来,
也可以在宿主机里查看,同时在这里也可以修改cpu的占用量,用echo来修改里的大小(id可以用docker inspect 容器名来查看)
为了能更好观察实验结果,把虚拟机的CPU个数改为1个(前提你有两个或多个)
此时设定了优先级的CPU使用量被限制了,从原本100%左右变为10&
因为容器的id过长很难看,也可以自建控制器,该目录下会自动加载里面的内容
后台运行进程,并把设定直接写入磁盘,此时速率就会在30M左右
在系统中运行容器,我们会发现资源并没有完全隔离开,容器内还是会显示宿主机的信息
但此时容器的权利太大,等于宿主机的root,为了滥用,会进行限制
如限制他只能修改网络,此时能修该网络,但不能做除网络外的权限,如查看不了磁盘
构建配置文件中定义的服务的镜像。可以指定服务名称来只构建特定的服物
如果你在yml文件里编写了多个服务,可以在后面加服务名称来指定他运行
docker-compose up --build : 启动服务并在启动前重新构建镜像
docker compose up --build 会先构建镜像后 启动容器
docker compose up -d 会去仓库拉去镜 像
端口映射,此时就会把宿主机的8080端口映射到容器的80端口
docker的简介
Docker是一个开源的应用容器引擎,它基于GO语言并遵从Apache2.0协议进行开源。Docker的主要目标是通过容器技术来简化应用程序的开发、部署和管理过程。它允许开发者将应用程序及其依赖项打包到一个轻量级、可移植的容器中,然后发布到任何流行的Linux机器上,从而实现虚拟化。这种技术被称为操作系统层级的虚拟化,与传统的虚拟机技术相比,Docker容器更加轻便、快捷,几乎不占用额外的系统资源,可以在机器和数据中心中轻松运行。Docker的引入解决了传统虚拟化方式资源占用大、部署缓慢的问题,使得开发、测试和部署过程更加高
它使开发者能够自动化应用程序的部署、管理、扩展和运行。Docker 利用容器技术,允许在一个隔离的环境中运行应用程序,并确保不同环境(如开发、测试、生产环境)之间的一致性。这种技术使得应用程序可以在各种不同的操作系统和基础设施上运行,而不必担心兼容性问题。
Docker 的核心概念
镜像(Image)
Docker 镜像是一个只读模板,包含了运行应用程序所需的所有依赖、库、工具和配置文件。镜像类似于虚拟机中的快照,用户可以从镜像启动一个或多个容器。
容器(Container)
容器是 Docker 的一个运行实例,它是基于镜像创建的一个独立、隔离的环境。多个容器可以在同一主机上运行,并共享主机的内核,但彼此之间是完全隔离的。
Dockerfile
Dockerfile 是一个包含一系列指令的文本文件,用于构建 Docker 镜像。每一条指令通常是从基础镜像开始,逐步添加文件、安装软件、配置环境等。
Docker Hub
Docker Hub 是一个公共的镜像仓库,用户可以在上面发布和下载镜像。Docker Hub 提供了丰富的官方镜像和社区镜像,便于快速部署应用。
Docker 的应用场景
微服务架构
Docker 非常适合部署微服务,因为每个微服务都可以独立地打包成一个容器,并且可以独立部署、扩展和更新。
开发环境一致性
开发者可以使用 Docker 创建统一的开发环境,确保团队中的每个人都使用相同的依赖和配置,从而避免环境差异带来的问题。
自动化测试
测试团队可以使用 Docker 快速创建和销毁测试环境,进行不同版本或配置的测试。
云计算和混合云部署
Docker 容器可以在任何支持 Docker 的平台上运行,这使得在不同的云服务提供商之间迁移应用变得更加简单
docker的原理图
docker的安装
可以从官网下载好软件包,通过传输软件传给虚拟机
也可以通过虚拟机自带的来安装
解压
[root@docker-1 ~]# tar zxf docker.tar.gz
安装解压后的rpm包
[root@docker-1 ~]# dnf install *.rpm -y
正在更新 Subscription Management 软件仓库。
无法读取客户身份
本系统尚未在权利服务器中注册。可使用 subscription-manager 进行注册。
上次元数据过期检查:0:06:31 前,执行于 2024年09月23日 星期一 08时59分10秒。
依赖关系解决。
==============================================================
软件包 架构 版本 仓库 大小
==============================================================
安装:
containerd.io x86_64 1.7.20-3.1.el9 @commandline 44 M
docker-buildx-plugin
x86_64 0.16.2-1.el9 @commandline 14 M
docker-ce x86_64 3:27.1.2-1.el9 @commandline 27 M
docker-ce-cli x86_64 1:27.1.2-1.el9 @commandline 7.8 M
docker-ce-rootless-extras
x86_64 27.1.2-1.el9 @commandline 4.0 M
docker-compose-plugin
x86_64 2.29.1-1.el9 @commandline 13 M
事务概要
==============================================================
安装 6 软件包
总计:109 M
安装大小:422 M
下载软件包:
运行事务检查
事务检查成功。
运行事务测试
事务测试成功。
运行事务
准备中 : 1/1
安装 : docker-compose-plugin-2.29.1-1.el9.x86_64 1/6
运行脚本: docker-compose-plugin-2.29.1-1.el9.x86_64 1/6
安装 : docker-buildx-plugin-0.16.2-1.el9.x86_64 2/6
运行脚本: docker-buildx-plugin-0.16.2-1.el9.x86_64 2/6
安装 : docker-ce-cli-1:27.1.2-1.el9.x86_64 3/6
运行脚本: docker-ce-cli-1:27.1.2-1.el9.x86_64 3/6
安装 : containerd.io-1.7.20-3.1.el9.x86_64 4/6
运行脚本: containerd.io-1.7.20-3.1.el9.x86_64 4/6
安装 : docker-ce-rootless-extras-27.1.2-1.el9.x86_64 5/6
运行脚本: docker-ce-rootless-extras-27.1.2-1.el9.x86_64 5/6
安装 : docker-ce-3:27.1.2-1.el9.x86_64 6/6
运行脚本: docker-ce-3:27.1.2-1.el9.x86_64 6/6
验证 : containerd.io-1.7.20-3.1.el9.x86_64 1/6
验证 : docker-buildx-plugin-0.16.2-1.el9.x86_64 2/6
验证 : docker-ce-3:27.1.2-1.el9.x86_64 3/6
验证 : docker-ce-cli-1:27.1.2-1.el9.x86_64 4/6
验证 : docker-ce-rootless-extras-27.1.2-1.el9.x86_64 5/6
验证 : docker-compose-plugin-2.29.1-1.el9.x86_64 6/6
已更新安装的产品。
已安装:
containerd.io-1.7.20-3.1.el9.x86_64 docker-buildx-plugin-0.16.2-1.el9.x86_64 docker-ce-3:27.1.2-1.el9.x86_64
docker-ce-cli-1:27.1.2-1.el9.x86_64 docker-ce-rootless-extras-27.1.2-1.el9.x86_64 docker-compose-plugin-2.29.1-1.el9.x86_64
完毕!
启动docker服务
[root@docker-1 ~]# systemctl enable --now docker
在rhel7中需要开启内核功能
]# vim /etc/sysctl.d/docker.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
]# sysctl --system
]# systemctl restart docker
docker的镜像
由于需要在外网所以docker的镜像不能直接用pull拉取search也搜索不到,可以从网上提前下载好,如阿里云等镜像站里下载,然后传输给虚拟机,之后用docker load -i 来加载镜像
加载镜像
[root@docker-1 ~]# docker load -i busybox-latest.tar.gz
d51af96cf93e: Loading layer 4.495MB/4.495MB
Loaded image: busybox:latest
[root@docker-1 ~]# docker load -i game2048.tar.gz
011b303988d2: Loading layer 5.05MB/5.05MB
36e9226e74f8: Loading layer 51.46MB/51.46MB
192e9fad2abc: Loading layer 3.584kB/3.584kB
6d7504772167: Loading layer 4.608kB/4.608kB
88fca8ae768a: Loading layer 629.8kB/629.8kB
Loaded image: timinglee/game2048:latest
[root@docker-1 ~]# docker load -i nginx-latest.tar.gz
9853575bc4f9: Loading layer [==================================================>] 77.83MB/77.83MB
72db5db515fd: Loading layer [==================================================>] 114MB/114MB
8b87c0c66524: Loading layer [==================================================>] 3.584kB/3.584kB
ec1a2ca4ac87: Loading layer [==================================================>] 4.608kB/4.608kB
55e54df86207: Loading layer [==================================================>] 2.56kB/2.56kB
f4f00eaedec7: Loading layer [==================================================>] 5.12kB/5.12kB
5f0272c6e96d: Loading layer [==================================================>] 7.168kB/7.168kB
Loaded image: nginx:latest
查看加载了的镜像
[root@docker-1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 5ef79149e0ec 5 weeks ago 188MB
busybox latest 65ad0d468eb1 16 months ago 4.26MB
timinglee/game2048 latest 19299002fdbe 7 years ago 55.5MB
查看镜像详细信息
[root@docker-1 ~]# docker image inspect busybox:latest
保存镜像
[root@docker-1 ~]# docker image save nginx -o nginx-latest.tar.gz
删除镜像
[root@docker-1 ~]# docker rmi nginx:latest
保存的镜像可以用docker load -i 来加载
docker的运行
-d #后台运行
-i #交互式运行
-t #打开一个终端
--name #指定容器名称
-p #端口映射 -p 80:8080 把容器8080端口映射到本机80端口
--rm #容器停止自动删除容器
--network #指定容器使用的网络
启动容器
[root@docker-1 ~]# docker run -d --name game -p 80:80 timinglee/game2048
查看运行的容器(加-a可以查看运行和不运行的容器)
[root@docker-1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1d64c3f3a9f8 timinglee/game2048 "/bin/sh -c 'sed -i …" 8 seconds ago Up 8 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp, 443/tcp game
查看运行的容器的详细信息
[root@Docker-node1 ~]# docker inspect test1
停止容器
[root@docker-1 ~]# docker stop game
重新运行
[root@docker-1 ~]# docker start game
也可以用kill杀死运行容器
[root@docker-1 ~]# docker kill game
[root@docker-1 ~]# docker rm centos7 #删除停止的容器
[root@docker-1 ~]# docker rm -f busybox #删除运行的容器
[root@docker-1 ~]# docker container prune -f #删除所有停止的容器
加-it会直接占用终端,加--rm即在他停止运行时就会自动删除容器
[root@docker-1 ~]# docker run -it --name test1 --rm busybox
/ # ls
bin etc lib proc sys usr
dev home lib64 root tmp var
同时按ctrl和p和q会退出该容器的,但不会停止该容器
重新在进入该容器
[root@docker-1 ~]# docker attach test1
容器内容提交
因为在运行的容器内写入内容之后删除该容器,重新开启之后里面添加的内容都会没有
在容器内添加容器
[root@docker-1 ~]# docker run -it --name test1 --rm busybox
/ #
/ #
/ # ls
bin etc lib proc sys usr
dev home lib64 root tmp var
/ # touch mqw
/ # ls
bin etc lib mqw root tmp var
dev home lib64 proc sys usr
/ #
在不停止该容器的情况下提交
[root@docker-1 ~]# docker commit -m "add mqw" test1 busybox:v1
此时在镜像里就会多出一个v1版本的busybox
可以看到v1版本多出来一层
[root@docker-1 ~]# docker image history busybox:v1
IMAGE CREATED CREATED BY SIZE COMMENT
0b1e4376dcaa 2 minutes ago sh 16B add mqw
65ad0d468eb1 16 months ago BusyBox 1.36.1 (glibc), Debian 12 4.26MB
删除之前运行的容器,在重新运行v1版本的容器
此时可以看到之前添加的mqw文件还在
[root@docker-1 ~]# docker run -it --name test1 --rm busybox:v1
/ # ls
bin etc lib mqw root tmp var
dev home lib64 proc sys usr
缺点:此方法不利于企业审计,所以不推荐使用,在企业中我们多用Dockerfile来构建镜像
查看容器内的日志
可以看到在容器内我执行了ls的命令
[root@docker-1 ~]# docker logs test1
/ # ls
bin etc lib mqw root tmp var
dev home lib64 proc sys usr
docker的镜像构建
构建参数,一个镜像最多只能构建127层
在rhel7里实验,配置环境
在官网下载centos:7传到虚拟机,导到docker
[root@docker-1 ~]# docker load -i centos-7.tar.gz
运行centos:7 编辑软件仓库
[root@docker-1 ~]# docker run -it --rm --name test1 centos:7
[root@71929227f38d /]# ls
anaconda-post.log etc lib64 opt run sys var
bin home media proc sbin tmp
dev lib mnt root srv usr
[root@71929227f38d /]# cd ./etc/yum.repos.d/
[root@71929227f38d yum.repos.d]# ls
CentOS-Base.repo CentOS-Sources.repo
CentOS-CR.repo CentOS-Vault.repo
CentOS-Debuginfo.repo CentOS-fasttrack.repo
CentOS-Media.repo CentOS-x86_64-kernel.repo
[root@71929227f38d yum.repos.d]# rm -fr *
[root@71929227f38d yum.repos.d]# ls
[root@71929227f38d yum.repos.d]# vi centos.repo
[centos]
name=centos7
gpgcheck=0
baseurl=http://172.25.254.200:9090/centos7
安装httpd
[root@docker-1 ~]# dnf install httpd -y
正在更新 Subscription Management 软件仓库。
无法读取客户身份
本系统尚未在权利服务器中注册。可使用 subscription-manager 进行注册。
上次元数据过期检查:1:51:19 前,执行于 2024年09月23日 星期一 08时59分10秒。
依赖关系解决。
==============================================================
软件包 架构 版本 仓库 大小
==============================================================
安装:
httpd x86_64 2.4.53-7.el9 AppStream 54 k
安装依赖关系:
apr x86_64 1.7.0-11.el9 AppStream 127 k
apr-util x86_64 1.6.1-20.el9 AppStream 98 k
apr-util-bdb x86_64 1.6.1-20.el9 AppStream 15 k
httpd-core x86_64 2.4.53-7.el9 AppStream 1.5 M
httpd-filesystem noarch 2.4.53-7.el9 AppStream 18 k
httpd-tools x86_64 2.4.53-7.el9 AppStream 89 k
redhat-logos-httpd noarch 90.4-1.el9 AppStream 18 k
安装弱的依赖:
apr-util-openssl x86_64 1.6.1-20.el9 AppStream 17 k
mod_http2 x86_64 1.15.19-2.el9 AppStream 153 k
mod_lua x86_64 2.4.53-7.el9 AppStream 64 k
事务概要
==============================================================
安装 11 软件包
总计:2.1 M
安装大小:5.9 M
下载软件包:
运行事务检查
事务检查成功。
运行事务测试
事务测试成功。
运行事务
准备中 : 1/1
安装 : apr-1.7.0-11.el9.x86_64 1/11
安装 : apr-util-bdb-1.6.1-20.el9.x86_64 2/11
安装 : apr-util-openssl-1.6.1-20.el9.x86_64 3/11
安装 : apr-util-1.6.1-20.el9.x86_64 4/11
安装 : httpd-tools-2.4.53-7.el9.x86_64 5/11
安装 : redhat-logos-httpd-90.4-1.el9.noarch 6/11
运行脚本: httpd-filesystem-2.4.53-7.el9.noarch 7/11
安装 : httpd-filesystem-2.4.53-7.el9.noarch 7/11
安装 : httpd-core-2.4.53-7.el9.x86_64 8/11
安装 : mod_http2-1.15.19-2.el9.x86_64 9/11
安装 : mod_lua-2.4.53-7.el9.x86_64 10/11
安装 : httpd-2.4.53-7.el9.x86_64 11/11
运行脚本: httpd-2.4.53-7.el9.x86_64 11/11
验证 : apr-1.7.0-11.el9.x86_64 1/11
验证 : apr-util-1.6.1-20.el9.x86_64 2/11
验证 : apr-util-bdb-1.6.1-20.el9.x86_64 3/11
验证 : apr-util-openssl-1.6.1-20.el9.x86_64 4/11
验证 : httpd-2.4.53-7.el9.x86_64 5/11
验证 : httpd-core-2.4.53-7.el9.x86_64 6/11
验证 : httpd-filesystem-2.4.53-7.el9.noarch 7/11
验证 : httpd-tools-2.4.53-7.el9.x86_64 8/11
验证 : mod_http2-1.15.19-2.el9.x86_64 9/11
验证 : mod_lua-2.4.53-7.el9.x86_64 10/11
验证 : redhat-logos-httpd-90.4-1.el9.noarch 11/11
已更新安装的产品。
已安装:
apr-1.7.0-11.el9.x86_64
apr-util-1.6.1-20.el9.x86_64
apr-util-bdb-1.6.1-20.el9.x86_64
apr-util-openssl-1.6.1-20.el9.x86_64
httpd-2.4.53-7.el9.x86_64
httpd-core-2.4.53-7.el9.x86_64
httpd-filesystem-2.4.53-7.el9.noarch
httpd-tools-2.4.53-7.el9.x86_64
mod_http2-1.15.19-2.el9.x86_64
mod_lua-2.4.53-7.el9.x86_64
redhat-logos-httpd-90.4-1.el9.noarch
完毕!
编辑配置文件,把端口改为9090
[root@docker-1 ~]# vim /etc/httpd/conf/httpd.conf
在虚拟机里添加多一个rhel7的光驱,之后重启系统
创建目录。挂载镜像
[root@docker-1 ~]# mkdir /var/www/html/centos7
[root@docker-1 ~]# mount /dev/sr0 /var/www/html/centos7/
提交镜像
[root@docker-1 ~]# docker commit -m "add repo" test1 centos7:v1
删除之前的centos,运行新v1版本的centos和httpd
[root@docker-1 ~]# docker rm -f test1
test1
[root@docker-1 ~]# systemctl enable --now httpd
Created symlink /etc/systemd/system/multi-user.target.wants/httpd.service → /usr/lib/systemd/system/httpd.service.
[root@docker-1 ~]# docker run -it --rm centos7:v1
[root@eadd25afdea1 /]#
在浏览器可以查看到此界面就配置完成
创建目录
[root@docker-1 ~]# mkdir docker
在该目录下编辑一个叫Dockerfile的文件
[root@docker-1 ~]# mkdir docker
[root@docker-1 ~]# cd docker/
[root@docker-1 docker]# ls
[root@docker-1 docker]# vim Dockerfile
从nginx官网下载一个nginx的压缩包来进行镜像测试
把他传到docker底下
编辑Dockerfile
FROM centos7:v1
ADD nginx-1.24.0.tar.gz /mnt
WORKDIR /mnt/nginx-1.24.0
RUN yum install -y gcc make pcre-devel openssl-devel
RUN ./configure --with-http_ssl_module --with-http_stub_status_module
RUN make
RUN make install
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
生成镜像
[root@docker-1 docker]# docker build -t nginx:v1 .
[+] Building 35.3s (12/12) FINISHED docker:default
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 375B 0.0s
=> [internal] load metadata for docker.io/library/cen 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 1.11MB 0.0s
=> [1/7] FROM docker.io/library/centos7:v1 0.0s
=> [2/7] ADD NGINX-1.24.0.TAR.GZ /mnt 0.1s
=> [3/7] WORKDIR /MNT/NGINX-1.24.0 0.0s
=> [4/7] RUN yum install -y gcc make pcre-devel ope 5.5s
=> [5/7] RUN ./configure --with-http_ssl_module --w 5.3s
=> [6/7] RUN make 23.5s
=> [7/7] RUN make install 0.2s
=> exporting to image 0.5s
=> => exporting layers 0.5s
=> => writing image sha256:7f085df1c603dc472069e67bca 0.0s
=> => naming to docker.io/library/nginx:v1 0.0s
此时就会多出一个v1版本的nginx
[root@docker-1 docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v1 7f085df1c603 53 seconds ago 355MB
centos7 v1 1e7f23ce0b8b 28 minutes ago 204MB
busybox v1 0b1e4376dcaa 2 hours ago 4.26MB
nginx latest 5ef79149e0ec 5 weeks ago 188MB
busybox latest 65ad0d468eb1 16 months ago 4.26MB
centos 7 eeb6ee3f44bd 3 years ago 204MB
timinglee/game2048 latest 19299002fdbe 7 years ago 55.5MB
不过v1版本占内存太大,可以优化
1,缩减层数,从7层变为4层
FROM centos7:v1
ADD nginx-1.24.0.tar.gz /mnt
WORKDIR /mnt/nginx-1.24.0
RUN yum install -y gcc make pcre-devel openssl-devel && ./configure --with-http_ssl_module --with-http_stub_status_module && make && make install && cd .. && rm -fr nginx1.24.0 && yum clean all
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
生成v2版本的镜像
[root@docker-1 docker]# docker build -t nginx:v2 .
[+] Building 35.6s (9/9) FINISHED docker:default
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 414B 0.0s
=> [internal] load metadata for docker.io/library/cen 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 42B 0.0s
=> [1/4] FROM docker.io/library/centos7:v1 0.0s
=> CACHED [2/4] ADD NGINX-1.24.0.TAR.GZ /mnt 0.0s
=> CACHED [3/4] WORKDIR /MNT/NGINX-1.24.0 0.0s
=> [4/4] RUN yum install -y gcc make pcre-devel op 35.2s
=> exporting to image 0.4s
=> => exporting layers 0.4s
=> => writing image sha256:e25d3769bfb692466d6e999851 0.0s
=> => naming to docker.io/library/nginx:v2
此时v2版本的内存下降了
[root@docker-1 docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v2 e25d3769bfb6 3 minutes ago 312MB
nginx v1 7f085df1c603 10 minutes ago 355MB
centos7 v1 1e7f23ce0b8b 38 minutes ago 204MB
busybox v1 0b1e4376dcaa 2 hours ago 4.26MB
nginx latest 5ef79149e0ec 5 weeks ago 188MB
busybox latest 65ad0d468eb1 16 months ago 4.26MB
centos 7 eeb6ee3f44bd 3 years ago 204MB
timinglee/game2048 latest 19299002fdbe 7 years ago 55.5MB
2,多阶段构建
FROM centos7:v1 AS mqw
ADD nginx-1.24.0.tar.gz /mnt
WORKDIR /mnt/nginx-1.24.0
RUN yum install -y gcc make pcre-devel openssl-devel && ./configure --with-http_ssl_module --with-http_stub_status_module && make && make install && cd .. && rm -fr nginx-1.24.0 && yum clean all
FROM centos:7
COPY --from=mqw /usr/local/nginx /usr/local/nginx
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
生成v3版本,此时内存占用更小了
[root@docker-1 docker]# docker build -t nginx:v3 .
[+] Building 33.9s (12/12) FINISHED docker:default
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 492B 0.0s
=> [internal] load metadata for docker.io/library/cen 0.0s
=> [internal] load metadata for docker.io/library/cen 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 42B 0.0s
=> [stage-1 1/2] FROM docker.io/library/centos:7 0.0s
=> [mqw 1/4] FROM docker.io/library/centos7:v1 0.0s
=> CACHED [mqw 2/4] ADD NGINX-1.24.0.TAR.GZ /mnt 0.0s
=> CACHED [mqw 3/4] WORKDIR /MNT/NGINX-1.24.0 0.0s
=> [mqw 4/4] RUN yum install -y gcc make pcre-deve 33.8s
=> [stage-1 2/2] COPY --from=mqw /usr/local/nginx / 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:064053b8af2cc66b4585b6dc3e 0.0s
=> => naming to docker.io/library/nginx:v3 0.0s
[root@docker-1 docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v3 064053b8af2c 5 seconds ago 210MB
nginx v2 e25d3769bfb6 19 minutes ago 312MB
nginx v1 7f085df1c603 26 minutes ago 355MB
centos7 v1 1e7f23ce0b8b 54 minutes ago 204MB
busybox v1 0b1e4376dcaa 2 hours ago 4.26MB
nginx latest 5ef79149e0ec 5 weeks ago 188MB
busybox latest 65ad0d468eb1 16 months ago 4.26MB
centos 7 eeb6ee3f44bd 3 years ago 204MB
timinglee/game2048 latest 19299002fdbe 7 years ago 55.5MB
3,最简镜像构建
docker的仓库管理
搭建私有仓库
可以从网上下载相关的包,之后传输给虚拟机,导入到docker
[root@docker-1 ~]# docker load -i registry.tag.gz
配置非加密的端口
[root@docker-1 ~]# vim /etc/docker/daemon.json
{
"insecure-registries": ["http://172.25.254.200:5000"]
}
重启docker服务
[root@docker-1 ~]# vim /etc/docker/daemon.json
开启registry仓库
[root@docker-1 ~]# docker run -d -p 5000:5000 --restart=always --name registry registry
给要上传的镜像打上标签
[root@docker-1 ~]# docker tag busybox:latest 172.25.254.200:5000/busybox:latest
用push上传,此时就上传成功
[root@docker-1 ~]# docker push 172.25.254.200:5000/busybox:latest
The push refers to repository [172.25.254.200:5000/busybox]
d51af96cf93e: Pushed
latest: digest: sha256:28e01ab32c9dbcbaae96cf0d5b472f22e231d9e603811857b295e61197e40a9b size: 527
可以查看上传的镜像
[root@docker-1 ~]# curl 172.25.254.200:5000/v2/_catalog
{"repositories":["busybox"]}
加密传输
创建目录把生成密钥和证书放到里面
[root@docker-1 ~]# mkdir /root/certs
[root@docker-1 ~]# openssl req -newkey rsa:4096 -nodes -sha256 -keyout certs/mqw.org.key -addext "subjectAltName = DNS:reg.mqw.org" -x509 -days 365 -out certs/mqw.org.crt
.+............+...+.......+......+..+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*..+....+...+..+...+.+.....+......+.+.........+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.+.....+.+......+........+......+............+....+..............+................+.....+...+.+.................+.......+...+........+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*...+..+.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.........+...+...+...........+...+.+.........+...+..+...............+.+...........+..........+...+.....+......+.....................+.+..+......................+..............+..........+......+......+..+......+.+......+..+.......+...+...........+.........+..........+...........+.+...+.....+...............+......+.........+.+.....+.+...............+.....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:ch
State or Province Name (full name) []:gx
Locality Name (eg, city) [Default City]:gl
Organization Name (eg, company) [Default Company Ltd]:mqw
Organizational Unit Name (eg, section) []:docker
Common Name (eg, your name or your server's hostname) []:reg.mqw.org //这里需要和你指定的备用名称一样,即上面的DNS指定的
Email Address []:admin@mqw.org
修改加密端口,并重启服务
[root@docker-1 ~]# vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://reg.mqw.org"]
}
[root@docker-1 ~]# systemctl restart docker
添加解析
[root@docker-1 ~]# vim /etc/hosts
开启仓库
[root@docker-1 ~]# docker run -d -p 443:443 --restart=always --name registry -v /opt/registry:/var/lib/registry -v /root/certs:/certs -e REGISTRY_HTTP_ADDR=0.0.0.0:443 -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/mqw.org.crt -e REGISTRY_HTTP_TLS_KEY=/certs/mqw.org.key registry
为docker建立证书
创建目录,并复制证书,重启服务
[root@docker-1 ~]# mkdir /etc/docker/certs.d/reg.mqw.org/ -p
[root@docker-1 ~]# cp /root/certs/mqw.org.crt /etc/docker/certs.d/reg.mqw.org/ca.crt
[root@docker-1 ~]# systemctl restart docker
打上标签,并用push上传
[root@docker-1 ~]# docker tag nginx:latest reg.mqw.org/nginx:latest
[root@docker-1 ~]# docker push reg.mqw.org/nginx:latest
The push refers to repository [reg.mqw.org/nginx]
5f0272c6e96d: Pushed
f4f00eaedec7: Pushed
55e54df86207: Pushed
ec1a2ca4ac87: Pushed
8b87c0c66524: Pushed
72db5db515fd: Pushed
9853575bc4f9: Pushed
latest: digest: sha256:127262f8c4c716652d0e7863bba3b8c45bc9214a57d13786c854272102f7c945 size: 1778
可以查看上传的镜像
[root@docker-1 ~]# curl -k https://reg.mqw.org/v2/_catalog
{"repositories":["nginx"]
为其建立登录认证
安装需要的工具包,
[root@docker-1 ~]# dnf install httpd-tools -y
在当前目录创建目录,并生成账户和密码
[root@docker-1 ~]# mkdir auth
[root@docker-1 ~]# htpasswd -Bc auth/htpasswd mqw
New password:
Re-type new password:
Adding password for user mqw
[root@docker-1 ~]# cat auth/htpasswd
mqw:$2y$05$avWqIaDh4gcUFp3nWQpsk.QHaDtQoLL2hk74t1ZpKCBgUDv1iSD.W
开启仓库,并把认证添加
[root@docker-1 ~]# docker run -d -p 443:443 --restart=always --name registry -v /opt/registry:/var/lib/registry -v /root/certs:/certs -e REGISTRY_HTTP_ADDR=0.0.0.0:443 -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/mqw.org.crt -e REGISTRY_HTTP_TLS_KEY=/certs/mqw.org.key -v /root/auth:/auth -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd registry
此时需要登录后才能上传
[root@docker-1 ~]# docker login reg.mqw.org
Username: mqw
Password:
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/#credential-stores
Login Succeeded
[root@docker-1 ~]# docker tag nginx:latest reg.mqw.org/nginx:latest
[root@docker-1 ~]# docker push reg.mqw.org/nginx
Using default tag: latest
The push refers to repository [reg.mqw.org/nginx]
5f0272c6e96d: Layer already exists
f4f00eaedec7: Layer already exists
55e54df86207: Layer already exists
ec1a2ca4ac87: Layer already exists
8b87c0c66524: Layer already exists
72db5db515fd: Layer already exists
9853575bc4f9: Layer already exists
latest: digest: sha256:127262f8c4c716652d0e7863bba3b8c45bc9214a57d13786c854272102f7c945 size: 1778
无论是上传还是拉取都需要登录后
退出登录
[root@docker-1 ~]# docker logout reg.mqw.org
Removing login credentials for reg.mqw.org
构建企业级私有仓库
软件下载地址:https://github.com/goharbor/harbor/releases
传输到虚拟机
创建目录,并把密钥证书复制
[root@docker-1 ~]# mkdir /data/certs/
[root@docker-1 ~]# cp /root/certs /data/ -r
解压,并进入到该目录下,
[root@docker-1 ~]# tar zxf harbor-offline-installer-v2.5.4.tgz
[root@docker-1 ~]# cd harbor/
编辑配置文件
[root@docker-1 harbor]# cp harbor.yml.tmpl harbor.yml
[root@docker-1 harbor]# vim harbor.yml
[root@docker-1 harbor]# ./install.sh --with-chartmuseum
此时可以到浏览器里查看,此时是成功的
创建项目
上传镜像同样需要登录
[root@docker-1 harbor]# docker login reg.mqw.org
Username: admin
Password:
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/#credential-stores
Login Succeeded
[root@docker-1 harbor]# docker tag nginx:latest reg.mqw.org/mqw/nginx:latest
[root@docker-1 harbor]# docker push reg.mqw.org/mqw/nginx:latest
The push refers to repository [reg.mqw.org/mqw/nginx]
5f0272c6e96d: Pushed
f4f00eaedec7: Pushed
55e54df86207: Pushed
ec1a2ca4ac87: Pushed
8b87c0c66524: Pushed
72db5db515fd: Pushed
9853575bc4f9: Pushed
latest: digest: sha256:127262f8c4c716652d0e7863bba3b8c45bc9214a57d13786c854272102f7c945 size: 1778
docker的网络
查看docker的网络,一共有三种类型,如果不指定类型,默认是bridge,指定:--network=类型
bridge模式下容器没有一个公有ip,只有宿主机可以直接访问,外部主机是不可见的
host模式可以让容器共享宿主机网络栈,这样的好处是外部主机与容器直接通信,但是容器的网络缺少 隔离性
none模式是指禁用网络功能,只有lo接口,在容器创建时使用
[root@docker-1 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
bb7da0ff8af5 bridge bridge local
acc36f25dd88 host host local
c8e5d47dcf20 none null local
docker自定义网络
自定义桥接网络,不指定默认为建立birdge
[root@docker-1 ~]# docker network create mynet1
[root@docker-1 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
bb7da0ff8af5 bridge bridge local
acc36f25dd88 host host local
5b31a0d77889 mynet1 bridge local
c8e5d47dcf20 none null local
自定义的桥接和自带的桥接的区别是,自定义的可以dns解析
因为docker引擎在分配ip时时根据容器启动顺序分配到,谁先启动谁用,是动态变更的 多容器互访用ip很显然不是很靠谱,那么多容器访问一般使用容器的名字访问更加稳定
测试
[root@docker-1 ~]# docker run -d --network mynet1 --name web nginx
[root@docker-1 ~]# docker run -it --rm --network mynet1 --name test1 busybox
/ # ls
bin etc lib proc sys usr
dev home lib64 root tmp var
/ # ping web
PING web (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.484 ms
64 bytes from 172.18.0.2: seq=1 ttl=64 time=0.164 ms
64 bytes from 172.18.0.2: seq=2 ttl=64 time=0.117 ms
不同自定义的网络互通
因为不同自定义的网络下的容器是不通的
方法一
运行两个不同自定义网络下的容器
[root@docker-1 ~]# docker run -it --rm --network mynet1 --name test1 busybox
[root@docker-1 ~]# docker run -it --rm --network mynet2 --name test2 busybox
在不停止容器运行的情况下,把test2加入到mynet1的网络中
[root@docker-1 ~]# docker network connect mynet1 test2
此时就可以进行互通了,ip地址可以用docker inspect 容器名 查看
方法二
joined容器网络
运行容器
[root@docker-1 ~]# docker run -it --rm --network mynet1 --name test1 busybox
在运行第二个容器时指定容器1
[root@docker-1 ~]# docker run -it --rm --network container:test1 --name test2 busybox
此时网络就互通了
joined网络示例
可以运行两个容器使他们可以互通
用MySQL加PHP来演示
传输镜像
导入镜像
[root@docker-1 ~]# docker load -i phpmyadmin-latest.tar.gz
[root@docker-1 ~]# docker load -i mysql-5.7.tar.gz
运行PHP和数据库
[root@docker-1 ~]# docker run -d --name mysqladmin --network mynet1 -e PMA_ARBITRARY=1 -p 80:80 phpmyadmin:latest
[root@docker-1 ~]# docker run -d --name mysql -e MYSQL_ROOT_PASSWORD='123' --network container:mysqladmin mysql:5.7
此时在浏览器可以用PHP页面登录到数据库里
容器内外网访问
容器访问外网
外网访问容器
在rhel7中,docker访问外网是通过iptables添加地址伪装策略来完成容器网文外网
在rhel7之后的版本中通过nftables添加地址伪装来访问外网
外网访问容器有两个策略,可以走nat也可以走docker-proxy,两个策略都默认开启,当一个被删除了另一个还可以使用,外网同样可以访问容器
docker跨主机网络
跨主机网络解决方案 docker原生的overlay和macvlan 第三方的flannel、weave、calico
环境
需要两台虚拟机,并每台虚拟机需要两个网卡,且第二个网卡为仅主机模式
打开一个网卡的混杂模式
[root@docker-1 ~]# ip link set eth1 promisc on
[root@docker-1 ~]# ip link set up eth1
此时就打开了
在两台主机上添加macvlan网络
[root@docker-1 ~]# docker network create -d macvlan --subnet 1.1.1.0/24 --gateway 1.1.1.1 -o parent=eth1 macvlan1
在两台主机运行容器,并各自指定IP
[root@docker1 ~]# docker run -it --name t1 --rm --network mac1 --ip 1.1.1.10 busybox
/ #
[root@docker-1 ~]# docker run -it --name t1 --rm --network macvlan1 --ip 1.1.1.20 busybo
测试,此时可以互通
Docker 数据卷管理及优化
docker提供了两种卷:
bind mount
docker managed volume
bind mount 数据卷 是将主机上的目录或文件mount到容器里。 使用直观高效,易于理解。 ,
格式 :-v选项指定的路径,如果不存在,挂载时会自动创建
docker managed volume 不需要指定mount源,docker自动为容器创建数据卷目录
默认创建的数据卷目录都在 /var/lib/docker/volumes 中
如果挂载时指向容器内已有的目录,原有数据会被复制到volume中
测试
运行容器并指定存储目录,并在data1目录下建立一个文件
[root@docker-1 ~]# docker run -it --rm -v /tmp/data1:/data1 -v /tmp/data1:/data2:ro -v /etc/passwd:/data/passwd:ro busybox
/ # ls
bin data1 dev home lib64 root tmp var
data data2 etc lib proc sys usr
/data # cd /data1
/data1 # ls
/data1 # touch mqw1
/data1 # ls
mqw1
查看虚拟机里的文件,此时就会查看到在data1下有一个mqw1的文件
docker managed 数据卷
[root@docker-1 ~]# docker run -d --name db -e MYSQL_ROOT_PASSWORD='123' mysql:5.7
[root@docker-1 ~]# docker inspect db
此时他就会自动加载在虚拟机
[root@docker-1 _data]# pwd
/var/lib/docker/volumes/c2089d028bd484f6d039c960e454dae7c0e473d8e82e25ccea858267ebfb1867/_data
[root@docker-1 _data]# ls
auto.cnf ibdata1 performance_schema
ca-key.pem ib_logfile0 private_key.pem
ca.pem ib_logfile1 public_key.pem
client-cert.pem ibtmp1 server-cert.pem
client-key.pem mysql server-key.pem
ib_buffer_pool mysql.sock sy
清理未使用的数据卷
在执行 docker volume prune 命令之前,请确保你确实不再需要这些数据卷中的数据,因为 该操作是不可逆的,一旦删除数据将无法恢复
如果有重要的数据存储在数据卷中,建议先进行备份,或者确保数据已经被妥善保存到其他地 方。
[root@docker-1 ~]# docker volume prune
自定义数据卷存储位置
建立数据卷,并自运行时指定数据卷的位置
[root@docker-1 ~]# docker run -it --name t1 -v mqw:/usr/share/busybox busybox
/ # ls
bin etc lib proc sys usr
dev home lib64 root tmp var
/ # cd /usr/share/busybox/
/usr/share/busybox # ls
在虚拟机里的mqw目录下添加文件测试
[root@docker-1 ~]# cd /var/lib/docker/volumes/mqw/_data/
[root@docker-1 _data]# ls
[root@docker-1 _data]# echo 111 > 1.txt
[root@docker-1 _data]# ls
1.txt
此时在容器里就会看到该目录已经添加了该文件
可以查看
数据卷容器
数据卷容器(Data Volume Container)是 Docker 中一种特殊的容器,主要用于方便地在多个容器之间 共享数据卷。
运行一个数据卷容器(即使他为停止运行的状态)
[root@docker-1 ~]# docker run -d --name t1 -v /tmp/data1:/data1:rw -v /tmp/data2:/data2:ro -v /etc/resolv.conf:/etc/hosts busybox
之后再运行其他容器时,需要使用该数据卷的模式时可以在运行时指定,此时该容器里就会有之前容器的数据
[root@docker-1 ~]# docker run -it --name t2 --rm --volumes-from t1 busybox
/ # ls
bin data2 etc lib proc sys usr
data1 dev home lib64 root tmp var
/ # cd etc
/etc # ls
group localtime nsswitch.conf shadow
hostname mtab passwd
hosts network resolv.conf
数据备份和迁移
备份数据到宿主机,把数据备份到/backup
[root@docker-1 ~]# docker run --volumes-from t1 -v /backup:/backup busybox tar zcf /backup/data1.tar.gz /data1
查看
把数据迁移到其他的容器
[root@docker-1 ~]# docker run -it --name t2 -v /backup:/backup busybox /bin/sh -c "tar zxf /backup/data1.tar.gz;/bin/sh"
/ # ls
backup data1 etc lib proc sys usr
bin dev home lib64 root tmp var
/ # cd data1
/data1 # ls
mqw1
Docker 的安全优化
1,命名隔离
当docker run启动一个容器时,Docker将在后台为容器创建一个独立的命名空间。命名空间提供了 最基础也最直接的隔离,
2 控制组资源控制的安全
3 内核能力机制
4 Docker服务端防护
docker的资源限制
在rhel9中默认使用cgroup-v2 但是cgroup-v2中不利于观察docker的资源限制情况,所以推荐使用 cgroup-v1
Linux Cgroups 是限制一个进程组能够使用的资源上限,包括 CPU、内存、磁盘、网络带宽等等。
对进程进行优先级设置、审计,以及将进程挂起和恢复等操作。
Linux Cgroups 给用户暴露出来的操作接口是文件系统
它以文件和目录的方式组织在操作系统的 /sys/fs/cgroup 路径下。
在 /sys/fs/cgroup 下面有很多诸如 cpuset、cpu、 memory 这样的子目录,也叫子系统。
执行此命令查看:mount -t cgroup
在rhel9中把v2改为v1,之后重启虚拟机
[root@docker ~]# grubby --update-kernel=/boot/vmlinuz-$(uname -r) --args="systemd.unified_cgroup_hierarchy=0 systemd.legacy_systemd_cgroup_controller"
1,限制cpu
使用ubnutu来测试观察
导入
[root@docker-1 ~]# docker load -i ubuntu-latest.tar.gz
运行容器,把CPU划分为10000,他满运行占2000(即十分之二),并给他一个运行的进程,让他把资源都运行起来,
[root@docker-1 ~]# docker run -it --rm --name test1 --cpu-period 10000 --cpu-quota 2000 ubuntu
root@ee64867cbea0:/# dd if=/dev/zero of=/dev/null &
此时这个容器对CPU的使用大约为20%
也可以在宿主机里查看,同时在这里也可以修改cpu的占用量,用echo来修改里的大小(id可以用docker inspect 容器名来查看)
2,限制cpu的优先级
为了能更好观察实验结果,把虚拟机的CPU个数改为1个(前提你有两个或多个)
[root@docker ~]# echo 0 > /sys/devices/system/cpu/cpu1/onlin
[root@docker-1 ~]# cat /proc/cpuinfo
运行容器,设定CPU的优先级,并给他一个后台运行的进程,
[root@docker-1 ~]# docker run -it --rm --name test1 --cpu-shares 100 ubuntu
root@16058a1c3798:/# dd if=/dev/zero of=/dev/null &
运行另一个容器,并不设定他的CPU优先级
[root@docker-1 ~]# docker run -it --rm --name test2 ubuntu
root@51c6d61ff2da:/# dd if=/dev/zero of=/dev/null &
此时设定了优先级的CPU使用量被限制了,从原本100%左右变为10&
而没被设定优先级的则占了90%
也可以在宿主机里修改
3,限制内存使用
给虚拟机传输查看软件,使能够轻易查看
安装
[root@docker-1 ~]# yum install *.rpm -y
正在更新 Subscription Management 软件仓库。
无法读取客户身份
本系统尚未在权利服务器中注册。可使用 subscription-manager 进行注册。
AppStream 1.5 MB/s | 3.2 kB 00:00
BaseOS 1.4 MB/s | 2.7 kB 00:00
软件包 containerd.io-1.7.20-3.1.el9.x86_64 已安装。
软件包 docker-buildx-plugin-0.16.2-1.el9.x86_64 已安装。
软件包 docker-ce-3:27.1.2-1.el9.x86_64 已安装。
软件包 docker-ce-cli-1:27.1.2-1.el9.x86_64 已安装。
软件包 docker-ce-rootless-extras-27.1.2-1.el9.x86_64 已安装。
软件包 docker-compose-plugin-2.29.1-1.el9.x86_64 已安装。
依赖关系解决。
=============================================================
软件包 架构 版本 仓库 大小
=============================================================
安装:
libcgroup x86_64 0.41-19.el8 @commandline 69 k
libcgroup-tools x86_64 0.41-19.el8 @commandline 91 k
事务概要
=============================================================
安装 2 软件包
总计:160 k
安装大小:375 k
下载软件包:
运行事务检查
事务检查成功。
运行事务测试
事务测试成功。
运行事务
准备中 : 1/1
运行脚本: libcgroup-0.41-19.el8.x86_64 1/2
安装 : libcgroup-0.41-19.el8.x86_64 1/2
运行脚本: libcgroup-0.41-19.el8.x86_64 1/2
安装 : libcgroup-tools-0.41-19.el8.x86_64 2/2
运行脚本: libcgroup-tools-0.41-19.el8.x86_64 2/2
验证 : libcgroup-0.41-19.el8.x86_64 1/2
验证 : libcgroup-tools-0.41-19.el8.x86_64 2/2
已更新安装的产品。
已安装:
libcgroup-0.41-19.el8.x86_64 libcgroup-tools-0.41-19.el8.x86_64
完毕!
运行容器并设定该容器使用内存的大小
[root@docker-1 ~]# docker run -d --name web1 --memory 300M --memory-swap 300M nginx
在宿主机里查看
写入数据测试,此时写入200M的数据可以写入
[root@docker-1 ~]# cd /sys/fs/cgroup/
[root@docker-1 cgroup]# cgexec -g memory:docker/245f47ccaaf9db848a32ad960e9c22a74024847e1c32fa833e5bd5b06ab76920 dd if=/dev/zero of=/dev/shm/bigfile bs=1M count=200
记录了200+0 的读入
记录了200+0 的写出
209715200字节(210 MB,200 MiB)已复制,0.476191 s,440 MB/ss
但写入300M或超过300M的数据时就会失败
[root@docker-1 cgroup]# cgexec -g memory:docker/245f47ccaaf9db848a32ad960e9c22a74024847e1c32fa833e5bd5b06ab76920 dd if=/dev/zero of=/dev/shm/bigfile bs=1M count=300
已杀死
因为容器的id过长很难看,也可以自建控制器,该目录下会自动加载里面的内容
4,限制docker的磁盘io
运行容器,并指定容器使用磁盘io的速率为30M
[root@docker-1 ~]# docker run -it --rm --device-write-bps /dev/nvme0n1:30M ubuntu
后台运行进程,并把设定直接写入磁盘,此时速率就会在30M左右
root@f10b06cb07d4:/# dd if=/dev/zero of=bigfile bs=1M count=100 oflag=direct
100+0 records in
100+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 2.54486 s, 41.2 MB/s
Docker的安全加固
在系统中运行容器,我们会发现资源并没有完全隔离开,容器内还是会显示宿主机的信息
即使已经在限制该容器的内存时,他还是会显示宿主机的信息
[root@docker1 /]# free -m
total used free shared buff/cache available
Mem: 1743 1203 83 11 626 540
Swap: 2047 144 1903
[root@docker1 ~]# docker run --rm -it --name test1 --memory 200M ubuntu
root@269cc4f68f82:/# free -m
total used free shared buff/cache available
Mem: 1743 1181 108 11 622 562
Swap: 2047 144 1903
解决默认隔离性
LXCFS 是一个为 LXC(Linux Containers)容器提供增强文件系统功能的工具。
1,资源可见性: LXCFS 可以使容器内的进程看到准确的 CPU、内存和磁盘 I/O 等资源使用信息。在没有 LXCFS 时,容器内看到的资源信息可能不准确,这会影响到在容器内运行的应用程序对资源的评估和 管理。
2. 性能监控: 方便对容器内的资源使用情况进行监控和性能分析。通过提供准确的资源信息,管理员和开发 人员可以更好地了解容器化应用的性能瓶颈,并进行相应的优化
传输给虚拟机
安装
[root@docker1 ~]# dnf install *.rpm -y
正在更新 Subscription Management 软件仓库。
无法读取客户身份
本系统尚未在权利服务器中注册。可使用 subscription-manager 进行注册。
AppStream 2.6 MB/s | 3.2 kB 00:00
BaseOS 2.7 MB/s | 2.7 kB 00:00
软件包 containerd.io-1.7.20-3.1.el9.x86_64 已安装。
软件包 docker-buildx-plugin-0.16.2-1.el9.x86_64 已安装。
软件包 docker-ce-3:27.1.2-1.el9.x86_64 已安装。
软件包 docker-ce-cli-1:27.1.2-1.el9.x86_64 已安装。
软件包 docker-ce-rootless-extras-27.1.2-1.el9.x86_64 已安装。
软件包 docker-compose-plugin-2.29.1-1.el9.x86_64 已安装。
软件包 libcgroup-0.41-19.el8.x86_64 已安装。
软件包 libcgroup-tools-0.41-19.el8.x86_64 已安装。
依赖关系解决。
=========================================================
软件包 架构 版本 仓库 大小
=========================================================
安装:
lxc-libs x86_64 4.0.12-1.el9 @commandline 535 k
lxc-templates x86_64 4.0.12-1.el9 @commandline 19 k
lxcfs x86_64 5.0.4-1.el9 @commandline 92 k
事务概要
=========================================================
安装 3 软件包
总计:647 k
安装大小:1.5 M
下载软件包:
运行事务检查
事务检查成功。
运行事务测试
事务测试成功。
运行事务
准备中 : 1/1
安装 : lxc-libs-4.0.12-1.el9.x86_64 1/3
运行脚本: lxc-libs-4.0.12-1.el9.x86_64 1/3
安装 : lxc-templates-4.0.12-1.el9.x86_64 2/3
安装 : lxcfs-5.0.4-1.el9.x86_64 3/3
运行脚本: lxcfs-5.0.4-1.el9.x86_64 3/3
验证 : lxcfs-5.0.4-1.el9.x86_64 1/3
验证 : lxc-libs-4.0.12-1.el9.x86_64 2/3
验证 : lxc-templates-4.0.12-1.el9.x86_64 3/3
已更新安装的产品。
已安装:
lxc-libs-4.0.12-1.el9.x86_64
lxc-templates-4.0.12-1.el9.x86_64
lxcfs-5.0.4-1.el9.x86_64
完毕!
运行lxcfs,并在容器运行时添加
[root@docker1 ~]# lxcfs /var/lib/lxcfs/ &
[root@docker1 ~]# docker run -it -m 256m \
-v /var/lib/lxcfs/proc/cpuinfo:/proc/cpuinfo:rw \
-v /var/lib/lxcfs/proc/diskstats:/proc/diskstats:rw \
-v /var/lib/lxcfs/proc/meminfo:/proc/meminfo:rw \
-v /var/lib/lxcfs/proc/stat:/proc/stat:rw \
-v /var/lib/lxcfs/proc/swaps:/proc/swaps:rw \
-v /var/lib/lxcfs/proc/uptime:/proc/uptime:rw \
> ubuntu
此时再运行时就会显示添加时的256M内存和宿主机隔离了
root@82144cf096d6:/# free -m
total used free shared buff/cache available
Mem: 256 1 254 0 0 254
Swap: 512 0 512
容器特权
再容器内即使你是root但还是无法修改一些系统设定
[root@docker1 ~]# docker run --rm -it --name test1 busybox
/ # whoami
root
/ # ip a a 172.25.254.200 dev eth0
ip: RTNETLINK answers: Operation not permitted
再运行时设定容器特权,此时就会添加成功
[root@docker1 ~]# docker run -it --rm --privileged --name test1 busybox
/ # ip a a 172.25.254.200/24 dev eth0
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
83: eth0@if84: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
inet 172.25.254.200/24 scope global eth0
valid_lft forever preferred_lft forever
容器白名单
但此时容器的权利太大,等于宿主机的root,为了滥用,会进行限制
如限制他只能修改网络,此时能修该网络,但不能做除网络外的权限,如查看不了磁盘
[root@docker1 ~]# docker run -it --rm --name test1 --cap-add NET_ADMIN busybox
/ # ip a a 172.25.254.200/24 dev eth0
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
85: eth0@if86: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
inet 172.25.254.200/24 scope global eth0
valid_lft forever preferred_lft forever
/ #
/ # fdisk -l
/ #
容器编排工具Docker Compose
主要功能
1. 定义服务: 使用 YAML 格式的配置文件来定义一组相关的容器服务。每个服务可以指定镜像、端口映射、 环境变量、存储卷等参数。 例如,可以在配置文件中定义一个 Web 服务和一个数据库服务,以及它们之间的连接关系。
2. 一键启动和停止: 通过一个简单的命令,可以启动或停止整个应用程序所包含的所有容器。这大大简化了多容器 应用的部署和管理过程。 例如,使用 docker-compose up 命令可以启动配置文件中定义的所有服务,使用 dockercompose down 命令可以停止并删除这些服务。
3. 服务编排: 可以定义容器之间的依赖关系,确保服务按照正确的顺序启动和停止。例如,可以指定数据库 服务必须在 Web 服务之前启动。 支持网络配置,使不同服务的容器可以相互通信。可以定义一个自定义的网络,将所有相关的 容器连接到这个网络上。
4. 环境变量管理: 可以在配置文件中定义环境变量,并在容器启动时传递给容器。这使得在不同环境(如开发、 测试和生产环境)中使用不同的配置变得更加容易。 例如,可以定义一个数据库连接字符串的环境变量,在不同环境中可以设置不同的值
可以在一个目录下编写
docker-compose up : 启动配置文件中定义的所有服务。
可以使用 -d 参数在后台启动服务。
可以使用-f 来指定yml文件(即你不在编辑文件的目录下,则需要加-f来指定yml编写的目录)
创建目录,并创建文件编辑,并启动
[root@docker1 ~]# mkdir ./docker
[root@docker1 ~]# cd docker/
[root@docker1 docker]# vim docker-compose.ym
services:
web:
image: nginx
ports:
- 80:80
db:
image: ubuntu
[root@docker1 docker]# docker compose up -d
[+] Running 3/3
✔ Network docker_default Created 0.2s
✔ Container docker-web-1 Started 1.1s
✔ Container docker-db-1 Started 0.9s
此时就会同时运行两个容器
停止服务,此时容器会停止运行
[root@docker1 docker]# docker compose stop
[+] Stopping 2/2
✔ Container docker-web-1 Stopped 1.6s
✔ Container docker-db-1 Stopped 0.0s
[root@docker1 docker]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
11bdac533015 ubuntu "/bin/bash" 19 seconds ago Exited (0) 18 seconds ago docker-db-1
0e7735676f2b nginx "/docker-entrypoint.…" 19 seconds ago Exited (0) 5 seconds ago docker-web-1
启动服务,容器会重新运行
[root@docker1 docker]# docker compose start
[+] Running 2/2
✔ Container docker-db-1 Started 0.9s
✔ Container docker-web-1 Started 0.8s
[root@docker1 docker]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
11bdac533015 ubuntu "/bin/bash" About a minute ago Exited (0) 3 seconds ago docker-db-1
0e7735676f2b nginx "/docker-entrypoint.…" About a minute ago Up 3 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp docker-web-1
也可以重启
[root@docker1 docker]# docker compose restart
[+] Restarting 2/2
✔ Container docker-db-1 Started 0.6s
✔ Container docker-web-1 Started 1.1s
如果down,会关闭容器,并删除
[root@docker1 docker]# docker compose down
[+] Running 3/3
✔ Container docker-db-1 Removed 0.0s
✔ Container docker-web-1 Removed 0.2s
✔ Network docker_default Removed 0.2s
[root@docker1 docker]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
以查看指定的服务来查看你日志
构建配置文件中定义的服务的镜像。可以指定服务名称来只构建特定的服物
[root@docker1 docker]# vim Dockerfile
FROM busybox:latest
RUN touch /mqw
~
编辑中指定镜像名,和Dockerfilr文件的位置和名字
[root@docker1 docker]# vim docker-compose.yml
services:
test:
image: busybox:v1
build:
context: /root/docker
dockerfile: Dockerfile
构建
[root@docker1 docker]# docker compose build
[+] Building 0.7s (7/7) FINISHED docker:default
=> [test internal] load build definition from Doc 0.0s
=> => transferring dockerfile: 75B 0.0s
=> [test internal] load metadata for docker.io/li 0.0s
=> [test internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [test 1/2] FROM docker.io/library/busybox:late 0.0s
=> [test 2/2] RUN touch /mqw 0.4s
=> [test] exporting to image 0.1s
=> => exporting layers 0.0s
=> => writing image sha256:b008d4cf375265ea580e5a 0.0s
=> => naming to docker.io/library/busybox:v1 0.0s
=> [test] resolving provenance for metadata file 0.0s
此时查看时,就会看到已经构建了一个v1版本的镜像
如果你在yml文件里编写了多个服务,可以在后面加服务名称来指定他运行
[root@docker1 docker]# docker compose build test
docker-compose up --build : 启动服务并在启动前重新构建镜像
docker compose up --build 会先构建镜像后 启动容器
docker compose up -d 会去仓库拉去镜 像
文件内容解释
文件内编写时要严格注意缩进,
端口映射,此时就会把宿主机的8080端口映射到容器的80端口
[root@docker1 docker]# vim docker-compose.ym
services:
web:
image: nginx
container_name: web1 #指定容器名称
ports:
- 8080:80
环境变量
如在运行MySQL时要指定密码
services:
web:
images:mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: 123
存储卷
同时可以设定文件权限
services:
test:
image: busybox
command: ["/bin/sh","-c","sleep 3000"]
restart: always
container_name: busybox1
volumes:
- /etc/passwd:/tmp/passwd:ro #只读挂在本地文件到指定位置
命令
覆盖容器启动时默认执行的命令。即在启动时就会执行
services:
web:
image: busybox
container_name: busybox
command: ["/bin/sh","-c","sleep10000000"]
网络
可以使用自带的网络
services:
web:
image: nginx
container_name: webserver
network_mode: bridge
可以自定义bridge的网络,可以指定多个
services:
test:
image: busybox
container_name: webserver
command: ["/bin/sh","-c","sleep10000000"]
networks:
- mynet1
- mynet2
networks:
mynet1:
driver: bridge
mynet2:
driver: bridg
如果已经自定义了网络也可以不建立直接调用
services:
web:
image: nginx
container_name: webserver
network_mode: default
networks:
default:
external: true #不建立新的网络而使用外部资源
name: bridge #指定外部资源网络名字
企业级演示
编排完成haproxy和nginx负载均衡架构实施
配置环境
[root@docker1 ~]# docker load -i haproxy-2.3.tar.gz
但编辑时还需要一些文件,此时没有
则下载haproxy,不安装
[root@docker1 docker]# dnf install haproxy -y --downloadonly --downloaddir=/mnt
正在更新 Subscription Management 软件仓库。
无法读取客户身份
本系统尚未在权利服务器中注册。可使用 subscription-manager 进行注册。
上次元数据过期检查:1:42:01 前,执行于 2024年09月30日 星期一 08时47分40秒。
依赖关系解决。
=========================================================
软件包 架构 版本 仓库 大小
=========================================================
安装:
haproxy x86_64 2.4.17-3.el9 AppStream 2.2 M
事务概要
=========================================================
安装 1 软件包
总计:2.2 M
安装大小:6.5 M
DNF将仅会从事务下载软件包。
下载软件包:
完毕!
[root@docker1 docker]# cd /mnt/
[root@docker1 mnt]# ls
haproxy-2.4.17-3.el9.x86_64.rpm hgfs
[root@docker1 mnt]# rpm2cpio haproxy-2.4.17-3.el9.x86_64.rpm | cpio -id
13421 块
[root@docker1 mnt]# ls
etc haproxy-2.4.17-3.el9.x86_64.rpm hgfs usr var
[root@docker1 mnt]# cd etc/
[root@docker1 etc]# ls
haproxy logrotate.d sysconfig
[root@docker1 etc]# cd haproxy/
[root@docker1 haproxy]# ls
conf.d haproxy.cfg
[root@docker1 haproxy]# cp haproxy.cfg /root/docker
编辑该文件
[root@docker1 ~]# cd docker/
[root@docker1 docker]# ls
docker-compose.yml Dockerfile haproxy.cfg
[root@docker1 docker]# vim haproxy.cfg
services:
web1:
image: nginx
container_name: web1
restart: always
networks:
- mynet1
expose:
- 80
volumes:
- /docker/web/html1:/usr/share/nginx/html
web2:
image: nginx
container_name: web2
restart: always
networks:
- mynet2
expose:
- 80
volumes:
- /docker/web/html2:/usr/share/nginx/html
haproxy:
image: haproxy:2.3
container_name: haproxy
restart: always
networks:
- mynet1
- mynet2
volumes:
- /root/docker/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg
ports:
- 80:80
networks:
mynet1:
driver: bridge
mynet2:
driver: bridge
把后面的内容删除,并编辑
运行
[root@docker1 docker]# docker compose up -d
[+] Running 5/5
✔ Network docker_mynet1 Created 0.6s
✔ Network docker_mynet2 Created 0.8s
✔ Container haproxy St... 1.2s
✔ Container web1 Start... 1.2s
✔ Container web2 Start... 1.0s
此时就会看到容器运行了
如果先看到效果,
[root@docker1 ~]# cd /docker/web/
[root@docker1 web]# echo 1 > html1/index.html
[root@docker1 web]# echo 2 > html2/index.html