Docker 简介
2008 年LXC(LinuX Contiainer)发布,但是没有行业标准,兼容性非常差
docker2013年首次发布,由Docker, Inc开发
什么是 Docker
Docker是管理容器的引擎,为应用打包、部署平台,而非单纯的虚拟化技术,它具有以下几个重要特点和优势:
1、轻量级虚拟化
Docker 容器相较于传统的虚拟机更加轻量和高效,能够快速启动和停止,节省系统资源。
2、一致性
确保应用程序在不同的环境中(如开发、测试、生产)具有一致的运行表现。
无论在本地还是云端,应用的运行环境都能保持相同,减少了因环境差异导致的问题。
3、可移植性
可以轻松地将 Docker 容器从一个平台迁移到另一个平台,无需担心依赖和环境配置的差异。
4、高效的资源利用
多个 Docker 容器可以共享主机的操作系统内核,从而更有效地利用系统资源。
5、易于部署和扩展:能够快速部署新的应用实例,并且可以根据需求轻松地进行水平扩展。
总之,Docker 极大地简化了应用程序的开发、部署和管理流程,提高了开发效率和运维的便利性。
它在现代软件开发和云计算领域得到了广泛的应用。
Docker 在企业中的应用
在企业中docker作为业务的最小载体而被广泛应用
通过docker企业可以更效率的部署应用并更节省资源
1、IaaS(Infrastructure as a Service)基础设施服务
2、PaaS是(Platform as a Service)平台服务
3、SaaS(Software as a Service)软件运营服务
Docker 与传统虚拟化对比
Docker 和传统的虚拟化方式的不同之处:
1、传统方式是在硬件层面实现虚拟化,需要有额外的虚拟机管理应用和虚拟机操作系统层。
2、Docker 容器是在操作系统层面上实现虚拟化,直接复用本地主机的操作系统,因此更加轻量级轻量级。
传统虚拟机 与Docker 的特点:
1、操作系统
宿主机上运行虚拟机OS (虚拟机)
共享宿主机OS(Docker)
2、存储
镜像较大(GB )(虚拟机)
镜像小(MB)(Docker)
3、性能
操作系统额外的cpu、内存消耗 (虚拟机)
几乎无性能损耗(Docker)
4、移植性
笨重、与虚拟化技术耦合度高 (虚拟机)
轻量、灵活迁移(Docker)
5、隔离性
完全隔离 (虚拟机)
安全隔离(Docker)
6、部署
慢、分钟级 (虚拟机)
快速、秒级(Docker)
7、运行密度
一般几十个 (虚拟机)
单机支持上千容器(Docker)
Docker 安装
本次实验使用 Red Hat 9 Linux 系统
1、配置docker软件仓库
[root@docker1 yum.repos.d]# vim docker.repo
[docker]
name=docker-ce
baseurl=https://mirrors.aliyun.com/docker-ce/linux/rhel/9/x86_64/stable/
gpgcheck=0
#docker软件源的配置,使用的是阿里云的资源
#如果使用rhel7或者centos7的Linux系统时,该源解决 centos7/rhel7 的docker依赖关系
#[centos]
#name=extras
#baseurl=https://mirrors.aliyun.com/centos/7.9.2009/extras/x86_64/
#gpgcheck=0
2、安装Docker软件
[root@docker1 yum.repos.d]# yum makecache
#更新yum源缓存
[root@docker1 yum.repos.d]# yum install docker-ce -y
#下载安装docker软件
3、启用Docker
[root@docker1 ~]# systemctl enable --now docker
4、查看docker的信息
[root@docker1 system]# docker info
红帽七版本需要进行网络内核的修改:
[root@docker1 ~]# 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
[root@docker1 ~]# sysctl --system
#查看参数,是否已修改成功
[root@docker1 ~]# systemctl enable --now docker
#启用docker服务
5、配置docker默认的镜像拉取地址(这里使用的是阿里云)
[root@docker1 docker]# vim daemon.json
{
"registry-mirrors": ["https://2xj7y0kz.mirror.aliyuncs.com"]
}
[root@docker1 docker]# systemctl daemon-reload
#重新加载
[root@docker1 docker]# systemctl restart docker.service
#重启docker服务
Docker 的基本操作
镜像相关操作
搜索镜像
[root@docker1 ~]# docker search nginx
NAME:镜像名称
DESCRIPTION:镜像说明
STARS:点赞数量
OFFICIAL:是否是官方的
拉取镜像
[root@docker1 ~]# docker pull busybox
#某些镜像后跟有alpine的参数,代表最小安装发型版本,例如:nginx:1.26-alpine
查看镜像信息
[root@docker1 ~]# docker image inspect nginx:latest
导出镜像
[root@docker1 ~]# docker image save nginx:latest -o nginx.tar.gz
[root@docker1 ~]# docker save `docker images | awk 'NR>1{print "$1":"$2"}'` -o images.tar.gz
#将全部镜像导入一个压缩包内
#可将多个镜像导出至同一个压缩包内
参数说明:
-o:指定镜像导出的位置(指定 .tar.gz 可以导出并压缩)
导入本地镜像
[root@docker1 packages]# docker load -i ubuntu-latest.tar.gz
删除镜像
[root@docker1 ~]# docker rmi timinglee/mario:latest
#删除镜像时,报错某个容器正在使用,应先将该容器删除,之后可删除镜像
容器相关操作
启动容器
参数声明:
-d :后台运行
-i :交互式运行
-t :打开一个终端
–name :指定容器名称
-p :端口映射 -p 80:8080 把容器8080端口映射到本机80端口
–rm :容器停止自动删除容器
–network :指定容器使用的网络
[root@docker1 ~]# docker run -t -d --name test busybox
#创建并启动一个容器,打开一个可在本地运行的终端并让其在后台运行,将其容器命名为test
[root@docker1 ~]# docker exec -it test sh
#进入运行在后台的容器,并创建一个可交互式的终端
[root@docker1 ~]# docker run -it --name centos7 centos:7
#运行容器,打开一个终端并进入交互模式
在容器内时,按+退出并停止容器
按+退出但不停止容器
[root@docker1 ~]# docker attach test
#此命令仅可进入使用<ctrl>+<pq>退出的容器
[root@docker1 ~]# docker exec -it test ifconfig
查看容器运行信息
[root@docker1 ~]# docker ps -a
#查看所有的容器
[root@docker1 ~]# docker ps
#查看当前运行的容器
[root@docker1 ~]# docker inspect busybox:latest
#查看运行容器的详细信息
运行/停止容器
容器内的第一个进程必须一直处于运行的状态,否则这个容器,就会处于退出状态
[root@docker1 ~]# docker start/stop ID/名称
#运行或者停止容器
[root@docker1 ~]# docker kill busybox #杀死容器,可以使用信号
删除容器
[root@Docker-node1 ~]# docker rm centos7
#删除停止的容器
[root@Docker-node1 ~]# docker rm -f busybox
#删除运行的容器
[root@Docker-node1 ~]# docker container prune -f
#删除所有停止的容器
容器的操作持久化
默认情况下,容器被删除后,在容器中的所有操作都会被清理,包括要保存的文件;
如果想永久保存,那么我们需要把动作提交,提交后会生成新的镜像;
当我们在运行新镜像后即可看到我们提交的内容。
此方法不利于企业审计,所以不推荐使用,在企业中我们多用Dockerfile来构建镜像。
[root@docker1 ~]# docker commit -m "add file" test busybox:v1
#提交动作:添加文件file,;(test)容器名称;(busybox:v1)镜像名称:标签
#从而生成一个新镜像为:镜像名:标签
本地文件与容器内文件互传
[root@docker1 ~]# docker cp anaconda-ks.cfg test:/
#把本机文件复制到容器中指定文件下
[root@docker1 ~]# docker cp test:/anaconda-ks.cfg /root/docker/
Successfully copied 2.56kB to /root/docker/
#把容器中的文件复制到本机指定位置
查询容器内部日志
[root@docker1 ~]# docker logs test
#web 为容器名称
Docker 的镜像构建
Docker的镜像结构
Docker的结构和特点:
1、共享宿主机的kernel
2、base镜像提供的是最小的Linux发行版
3、同一docker主机支持运行多种Linux发行版
4、采用分层结构的最大好处是:共享资源
Docker 镜像的运行原理
1、Copy-on-Write 可写容器层
2、容器层以下所有镜像层都是只读的
3、docker从上往下依次查找文件
4、容器层保存镜像变化的部分,并不会对镜像本身进行任何修改
5、一个镜像最多127层
获取镜像的方式
1、基本镜像通常由软件官方提供
2、企业镜像可以用官方镜像 + Dockerfile来生成
3、系统关于镜像的获取动作有两种:
(1)docker pull 镜像地址
(2)docker load –i 本地镜像包
镜像的构建
构建的参数
1、指定base镜像,由哪个镜像创建
FROM
FROM busybox:version
2、复制文件,需指定文件存储的路径,复制的文件需在Dockerfile文件的同一目录下
COPY
COPY file /file
COPY [“file”,“/”]
3、指定作者信息
MAINTAINER
MAINTAINER user@example.com
在最新版的docker中用
LABEL KEY=“VALUE” 代替
4、功能和copy相似,指定压缩文件(会自动解压)或url (自动下载 url 内的文件)到指定路径下,添加的文件需在Dockerfile文件的同一目录下
ADD
ADD *.tar /mnt
ADD http://ip/test.tar /mnt
5、指定环境变量
ENV
ENV FILENAME test
6、暴漏容器端口
EXPOSE
EXPOSE 80
7、申明数据卷,通常指数据挂载点,通过数据卷可实现数据的备份和持久化,默认数据卷路径为:/var/lib/docker/volumes/
VOLUME
VOLUME /var/
8、切换路径,在容器运行时切换到指定的路径
WORKDIR
WORKDIR /mnt
9、在创建镜像时运行的指令
RUN
RUN touch file
10、在容器启动时,运行该指令,此动作可以被覆盖
CMD
CMD [“/bin/sh”,“echo $FILENAME”] #会调用shell解析
CMD [“bin/sh”,“-c”,“echo $FILENAME”] #不调用 shell 解析
11、和CMD功能和用法类似,动作不可被覆盖
ENTRYPOINT
ENTRYPOINT [“bin/sh”,“-c”,“echo $FILENAME”]
Dockerfile 编写
1、创建用于构建镜像的目录
[root@docker1 docker]# touch /root/Dockerfile
#默认构建镜像时检测的文件为Dockerfile,可加参数(-f)更改检测的文件:docker build -f test1 -t nginx:v1 .
2、编辑 Dockefile 内容
FROM centos:repo
LABEL NAME=tym
ADD nginx-1.26.1.tar.gz /mnt
WORKDIR /mnt/nginx-1.26.1
RUN yum install -y gcc make pcre-devel openssl-devel
RUN ./configure --prefix=/usr/local/nginx --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;"]
使用 Dockerfile 生成镜像
1、生成镜像
[root@docker1 docker]# docker build -t nginx:v1 .
2、测试镜像是否可用
[root@docker1 docker]# docker run -d --name web nginx:v1
3、查看容器的详细信息
[root@docker1 docker]# docker inspect nginx:v1
镜像的优化
镜像的优化有如下三点:
1、选择最精简的基础镜像
2、减少镜像的层数
3、清理镜像构建的中间产物
缩减镜像层数
将执行的 RUN 合并为单个命令,并将构建镜像过程中产生的多余文件在后期进行删除
FROM centos:repo
LABEL NAME=tym
ADD nginx-1.26.1.tar.gz /mnt
WORKDIR /mnt/nginx-1.26.1
RUN yum install -y gcc make pcre-devel openssl-devel && ./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_stub_status_module && make && make install
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
效果对比:
多阶段构建
将构建镜像分为两个阶段,第一阶段生成运行容器需要的全部内容,第二阶段生成镜像
FROM centos:repo AS built
ADD nginx-1.26.1.tar.gz /mnt
WORKDIR /mnt/nginx-1.26.1
RUN yum install -y gcc make pcre-devel openssl-devel && ./configure --prefix=/usr/local/nginx - -with-http_ssl_module --with-http_stub_status_module && make && make install && rm -rf /mnt/ngi nx-1.26.1 && yum clean all
FROM centos:repo
LABEL NMAE=tym
COPY --from=built /usr/local/nginx /usr/local/nginx
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
效果对比:
使用最精简镜像
使用google提供的最精简镜像
利用最精简镜像进行重新构建
FROM nginx:1.23 AS base
RUN mkdir -p /opt/var/cache/nginx && \
cp -a --parents /usr/lib/nginx /opt && \
cp -a --parents /usr/share/nginx /opt && \
cp -a --parents /var/log/nginx /opt && \
cp -aL --parents /var/run /opt && \
cp -a --parents /etc/nginx /opt && \
cp -a --parents /etc/passwd /opt && \
cp -a --parents /etc/group /opt && \
cp -a --parents /usr/sbin/nginx /opt && \
cp -a --parents /usr/sbin/nginx-debug /opt && \
cp -a --parents /lib/x86_64-linux-gnu/ld-* /opt && \
cp -a --parents /usr/lib/x86_64-linux-gnu/libpcre* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libz.so.* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libc* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libdl* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libpthread* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libcrypt* /opt && \
cp -a --parents /usr/lib/x86_64-linux-gnu/libssl.so.* /opt && \
cp -a --parents /usr/lib/x86_64-linux-gnu/libcrypto.so.* /opt && \
cp /usr/share/zoneinfo/${TIME_ZONE:-ROC} /opt/etc/localtime
FROM gcr.io/distroless/base-debian11
COPY --from=base /opt /
EXPOSE 80 443
ENTRYPOINT ["nginx", "-g", "daemon off;"]
效果对比:
由此镜像为基础的容器可正常运行:
Docker 镜像仓库的管理
什么是 Docker 仓库
1、Docker仓库(Docker Registry) 是用于存储和分发 Docker 镜像的集中式存储库。
2、它就像是一个大型的镜像仓库,开发者可以将自己创建的 Docker 镜像推送到仓库中,也可以从仓库中拉取所需的镜像。
3、Docker 仓库可以分为公共仓库和私有仓库。
4、通过 Docker 仓库,开发者能够方便地共享和复用镜像,加速应用的开发和部署过程。
公共仓库:
如 Docker Hub,任何人都可以访问和使用其中的镜像。许多常用的软件和应用都有在Docker Hub 上提供的镜像,方便用户直接获取和使用。
例如,您想要部署一个 Nginx 服务器,就可以从 Docker Hub 上拉取 Nginx 的镜像。
私有仓库:
是由组织或个人自己搭建和管理的,用于存储内部使用的、不希望公开的镜像。
比如,一家企业为其特定的业务应用创建了定制化的镜像,并将其存储在自己的私有仓库中,以保证安全性和控制访问权限。
官方 Docker hub 仓库
官网:https://hub.docker.com/
Docker Hub 是 Docker 官方提供的一个公共的镜像仓库服务。
它是 Docker 生态系统中最知名和广泛使用的镜像仓库之一,拥有大量的官方和社区贡献的镜像。
以下是 Docker Hub 的一些关键特点和优势:
1、丰富的镜像资源:涵盖了各种常见的操作系统、编程语言运行环境、数据库、Web 服务器等众多应用的镜像。
2、官方支持:提供了由 Docker 官方维护的一些重要镜像,确保其质量和安全性。
3、社区贡献:开发者们可以自由上传和分享他们创建的镜像,促进了知识和资源的共享。
4、版本管理:对于每个镜像,通常都有多个版本可供选择,方便用户根据需求获取特定版本。
5、便于搜索:用户可以通过关键词轻松搜索到所需的镜像。
Docker 仓库的工作原理
仓库中的三个角色:
1、index:
docker 索引服务,负责并维护有关用户帐户、镜像的校验以及公共命名空间的信息
2、registry
docker仓库,是镜像和图表的仓库,它不具有本地数据库以及不提供用户认证,通过Index Auth service 的 Token 的方式进行认证
3、Registry Client
Docker 充当 registry 客户端来维护推送和拉取,以及客户端的授权
pull 原理
镜像拉取分为以下几步:
1、docker 客户端向 index 发送镜像拉去请求并完成与 index 的认证
2、index 发送认证 token 和镜像位置给 dockerclient
3、dockerclient 携带 token 和根据 index 指引的镜像位置取连接 registry
4、Registry 会根据 client 持有的 token 跟 index 核实身份合法性
5、index 确认此 token 合法性
6、Registry 会根据 client 的请求传递镜像到客户端
push 原理
镜像上传的步骤:
1、client 向 index 发送上传请求并完成用户认证
2、index 会发放 token 给 client ,证明 client 的合法性
3、client 携带 index 提供的 token 连接 Registry
4、Registry 向 index 核实 token 的合法性
5、index 证实 token 的合法性
6、Registry 开始接收客户端上传过来的镜像
创建本地镜像仓库
Docker hub 虽然方便,但是还是有限制:
1、需要internet连接,速度慢
2、所有人都可以访问
3、由于安全原因企业不允许将镜像放到外网
好消息是docker公司已经将registry开源,我们可以快速构建企业私有仓库
地址: https://docs.docker.com/registry/deploying/
Registry 仓库非加密传输
1、拉取仓库镜像
[root@docker1 packages]# docker pull registry
#如果不指定版本,则默认拉取最新镜像
2、运行本地仓库镜像
[root@docker1 packages]# docker run -d -p 5000:5000 --restart=always --name hub.tym registry
#在后台运行仓库镜像,将本地5000端口映射到镜像端口5000,如果镜像关闭则自动重启
3、将要上传的镜像打上标签
[root@docker1 packages]# docker tag nginx:latest 172.25.254.10:5000/nginx:tym
#(nginx:latest)需要上传的镜像;
#(172.25.254.10:5000/nginx:tym)仓库IP地址/镜像标签
4、修改上传镜像的方式,使用非加密端口,当其它设备需从本机的本地仓库获取镜像时,也需进行相应的修改
[root@docker1 packages]# vim /etc/docker/daemon.json
{
"insecure-registries" : ["http://172.25.254.10:5000"]
}
[root@docker1 packages]# systemctl restart docker
#重启docker服务
5、推送镜像至仓库
[root@docker1 packages]# docker push 172.25.254.10:5000/nginx:tym
6、查看仓库内镜像
[root@docker1 packages]# curl 172.25.254.10:5000/v2/_catalog
Registry 仓库加密传输
1、生成证书和秘钥
[root@docker1 packages]# openssl req -newkey rsa:4096 \#创建证书秘钥
-nodes -sha256 -keyout /root/certs/tym.org.key \#创建秘钥并指定存放路径
-addext "subjectAltName = DNS:reg.tym.org" \#证书备用域名
-x509 -days 365 -out /root/certs/tym.org.crt
2、将证书秘钥加入到容器内
[root@docker1 ~]# docker run -d -p 443:443 \
--restart=always \
--name registry \
-v /root/certs/:/certs \#将本地的证书(/root/certs)挂载到容器内的指定路径(/crets)
-e REGISTRY_HTTP_ADDR=0.0.0.0:443 \#监控端口
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/tym.org.crt \#容器内证书所在路径
-e REGISTRY_HTTP_TLS_KEY=/certs/tym.org.key \#容器内秘钥所在路径
registry:latest
3、将生成的证书文件复制至docker的认证文件路径下
[root@docker1 docker]# cp /root/certs/tym.org.crt /etc/docker/certs.d/reg.tym.org/
4、重启服务
[root@docker1 docker]# systemctl restart docker
5、添加本地域名解析
[root@docker1 ~]# vim /etc/hosts
172.25.254.10 reg.tym.org
6、登录本地仓库
[root@docker1 ~]# docker login reg.tym.org
7、推送镜像至仓库
[root@docker1 crt]# docker tag nginx:latest reg.tym.org/nginx:tym
#将要推送的镜像打上标签
[root@docker1 docker]# docker push reg.tym.org/nginx:tym
#将镜像推送至本地仓库
8、查看本地仓库是否上传镜像
[root@docker1 docker]# curl -k https://reg.tym.org/v2/_catalog
{"repositories":["nginx"]}
为仓库建立登录认证
1、安装建立认证文件的工具包
[root@docker1 docker]# yum install httpd-tools -y
2、建立认证文件
[root@docker1 auth]# htpasswd -Bc /root/auth/htpasswd tym
New password:
Re-type new password:
Adding password for user tym
#-B 强制使用最安全的加密方式,默认MD5加密;当需要添加新用户时,应将参数 c 删除,否则会覆盖原有的用户
3、添加认证至 registry 容器内
[root@docker1 auth]# docker run -d -p 443:443 \
--restart=always \
--name registry \
-v /root/certs/:/certs \
-e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/tym.org.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/tym.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:latest
4、登录仓库
[root@docker1 ~]# docker login reg.tym.org
5、推送镜像
[root@docker1 crt]# docker tag nginx:latest reg.tym.org/nginx:v1
#将要推送的镜像打上标签
[root@docker1 docker]# docker push reg.tym.org/nginx:v1
#将镜像推送至本地仓库
个人 HarBor 仓库搭建
Harbor 是由vmware公司开源的企业级 Docker Registry 项目。
它提供了以下主要功能和特点:
1、基于角色的访问控制(RBAC):可以为不同的用户和用户组分配不同的权限,增强了安全性和管理的灵活性。
2、镜像复制:支持在不同的 Harbor 实例之间复制镜像,方便在多个数据中心或环境中分发镜像。
3、图形化用户界面(UI):提供了直观的 Web 界面,便于管理镜像仓库、项目、用户等。
4、审计日志:记录了对镜像仓库的各种操作,有助于追踪和审查活动。
5、垃圾回收:可以清理不再使用的镜像,节省存储空间。
HarBor 仓库部署
1、创建证书秘钥
[root@Docker-hub harbor]# openssl req -newkey rsa:4096 \
-nodes -sha256 -keyout /root/certs/tym.org.key \
-addext "subjectAltName = DNS:reg.tym.org" \
-x509 -days 365 -out /root/certs/tym.org.crt
2、下载harbor仓库软件并进行解压
[root@Docker-hub ~]# tar xzf harbor-offline-installer-v2.5.4.tgz
3、生成harbor仓库安装的配置文件
[root@Docker-hub harbor]# cp harbor.yml.tmpl harbor.yml
#生成配置文件
4、修改配置文件内容
[root@Docker-hub harbor]# vim harbor.yml
......
hostname: reg.tym.org
......
certificate: /data/certs/tym.org.crt
private_key: /data/certs/tym.org.key
......
harbor_admin_password: 123
......
5、将生成的证书秘钥复制至 docker 和 harbor 的配置目录下,为后续认证做准备
[root@Docker-hub harbor]# mkdir /etc/docker/certs.d/reg.tym.org/ -p
[root@Docker-hub harbor]# cp /root/certs/tym.org.crt /etc/docker/certs.d/reg.tym.org/
#将证书复制至docker的认证目录下;(reg.tym.org)自己仓库的域名
[root@Docker-hub harbor]# mkdir /data/certs/ -p
[root@Docker-hub harbor]# cp /root/certs/tym.org.crt /data/certs/
[root@Docker-hub harbor]# cp /root/certs/tym.org.crt /data/certs/
#将证书秘钥复制至修改harbor配置时指定的路径下
6、安装harbor仓库
[root@Docker-hub harbor]# ./install.sh --help
Please set --with-notary #证书签名
Please set --with-trivy #安全扫描
Please set --with-chartmuseum if needs enable Chartmuseum in Harbor
[root@Docker-hub harbor]# ./install.sh --with-chartmuseum
7、添加域名解析至本地主机
添加本地虚拟机的域名解析:
[root@Docker-hub ~]# vim /etc/hosts
172.25.254.253 reg.tym.org
添加浏览器所在主机的域名解析:
修改本地主机的域名解析:C:\Windows\System32\drivers\etc
8、通过浏览器登陆至harbor仓库,并进行登陆
登陆:
创建新的项目:
9、将镜像推送至仓库内
登陆仓库:
[root@Docker-hub harbor]# docker login reg.tym.org
Username: admin
Password:
将镜像打上标签并推送至仓库内:
[root@Docker-hub harbor]# docker tag goharbor/harbor-exporter:v2.5.4 reg.tym.org/tym.img/hub:v1
#(goharbor/harbor-exporter:v2.5.4)镜像;(reg.tym.org/tym.img/)仓库域名/项目名称;(hub:v1)标签
[root@Docker-hub harbor]# docker push reg.tym.org/tym.img/hub:v1
#推送:(reg.tym.org/tym.img/)仓库域名/项目名称;(hub:v1)标签
查看仓库内镜像:
10、获取镜像
修改docker获取镜像的默认路径:
[root@Docker-hub ~]# vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://reg.tym.org"]
}
#将获取镜像的默认路径修改为本地 harbor 仓库
获取镜像:
root@Docker-hub harbor]# docker pull reg.tym.org/tym.img/hub:v1
#(reg.tym.org/tym.img/hub:v1)仓库的域名/项目名/镜像:标签
Docker 网络
docker安装后会自动创建3种网络:bridge、host、none
[root@docker1 ~]# docker network ls
Docker 原生网络 bridge
docker安装时会创建一个名为 docker0 的Linux bridge,新建的容器会自动桥接到这个接口
[root@docker1 ~]# ip link show type bridge
bridge模式下,容器没有一个公有ip,只有宿主机可以直接访问,外部主机是不可见的。
容器通过宿主机的NAT规则后可以访问外网
下图设备为容器使用 bridge 模式时的网卡设备:
Docker 原生网络 host
host网络模式需要在容器创建时指定(–network host)
host模式可以让容器共享宿主机网络栈,这样的好处是外部主机与容器直接通信,但是容器的网络缺少隔离性
如果公用一个网络,那么所有的网络资源都是公用的,比如启动了nginx容器那么真实主机的80端口就会被占用,在启动第二个nginx容器时就会失败
下图为容器使用 host 模式时的网络设备详情:
[root@docker1 ~]# docker run -it --rm --name test --network host busybox
Docker 原生网络 none
none 模式是指禁用网络功能,只有环回接口( lo )
[root@docker1 ~]# docker run -it --rm --name test --network none busybox
Docker 自定义网络
自定义网络模式,docker提供了三种自定义网络驱动:
1、bridge
bridge驱动类似默认的bridge网络模式,但增加了一些新的功能,例如DNS域名解析等
2、overlay
3、macvlan
overlay和macvlan是用于创建跨主机网络
自定义网络的好处:
使用自定义网络可以实现控制哪些容器之间可以相互通信
还可以自动 DNS 解析容器名称到 IP 地址,利于容器的管理和访问等
自定义桥接网络
在建立自定义网络时,默认使用桥接模式
[root@docker1 ~]# docker network create my.net2
添加多个自定义桥接网络时,其网络的 IP 地址范围是默认单向递增的
在创建自定义网络时,也可自定义其子网和网关
[root@docker1 ~]# docker network create my_net3 --subnet 192.168.0.0/24 --gateway 192.168.0.10
自定义桥接网络的作用
原因:
1、docker 引擎在分配 IP 时是根据容器启动顺序分配的,谁先启动谁分配到 IP 地址,是动态变更的
2、docker 原生网络是不支持 DNS 解析的
3、当使用 IP 地址访问到的设备宕机时,此 IP 会自动分配给此时启动的其它容器;当再次使用此 IP 去访问时,会导致访问的设备不一致
自定义网络的作用:
自定义网络会内嵌 DNS 解析,从而使我们可以直接使用容器的名称去访问容器,避免了容器 IP 变更带来的困扰
注意:自定义网络之间是不能进行通信的
实现不同自定义网络之间的通信
可通过将另一个容器的网络设备加入到本地容器内,实现通信
[root@docker1 ~]# docker run -it --name test1 --network my_net1 busybox
[root@docker1 ~]# docker run -it --name test2 --network my_net2 busybox
#使用不同的自定义网络创建容器
[root@docker1 ~]# docker network connect my_net1 test2
#将容器1内的网络设备加入到容器2内
效果演示:
joined 容器网络
1、Joined 容器一种较为特别的网络模式,在容器创建时使用(–network=container:vm1)指定(vm1指定的是运行的容器名)
2、处于这个模式下的 Docker 容器会共享一个网络栈,这样两个容器之间可以使用 localhost 高效快速通信
[root@docker1 ~]# docker run -it --name test1 --network my_net1 busybox
[root@docker1 ~]# docker run -it --name test2 --network container:test1 busybox
#容器2将与容器1共享同一个网络栈
joined 网络实例
当容器之间耦合性特别高时,实现容器之间的互联
利用容器部署 phpmyadmin 管理 mysql 数据库
运行 phpmysqladmin:
[root@docker1 ~]# docker run -d --name mysqladmin --network my_net1 \
-e PMA_ARBITRARY=1 \ #在web页面中可以手动输入数据库地址和端口
-p 80:80 \
phpmyadmin:latest
运行数据库:
[root@docker1 ~]# docker run -d --name mysql \
-e MYSQL_ROOT_PASSWORD='123' \ #设定数据库密码
--network container:mysqladmin \ #phpmyadmin容器与数据库容器共享网络栈
mysql:5.7
效果演示:
开启的phpmyadmin容器中是没有数据库的
这里填写的localhost:3306是因为mysql容器和phpmyadmin容器共用一个网络栈
登录容器数据库,并创建库:
[root@docker ~]# docker exec -it mysgl sh
sh-4.2# mysql -uroot -p123
可在网页管理界面(phpmyadmin)查看到相应的信息:
容器内外网的访问
容器访问外网
在rhel7中,docker访问外网是通过 iptables 添加地址伪装策略来完成容器网文外网
在rhel7之后的版本中通过 nftables 添加地址伪装来访问外网
内网访问外网的策略:
效果演示:
将Docker重启之后,iptable策略会自动恢复
外网访问容器
docker-proxy 和 dnat 在容器建立端口映射后都会开启,哪个传输速录高走那个
Docker-proxy 策略实现外网访问内网:
iptable 策略:
当删除其中一种的策略时,外网可通过另一个策略进行内网的访问
Docker 跨主机网络
在生产环境中,我们的容器不可能都在同一个系统中,所以需要容器具备跨主机通信的能力
跨主机网络解决方案:
1、docker原生的overlay和macvlan
2、第三方的flannel、weave、calico
众多网络方案是如何与docker集成在一起的:
1、libnetwork docker容器网络库
2、CNM (Container Network Model)这个模型对容器网络进行了抽象
CNM
CNM(Container Network Model) 分三类组件:
1、Sandbox:容器网络栈,包含容器接口、dns、路由表(namespace)
2、Endpoint:作用是将sandbox接入network (veth pair)
3、Network:包含一组endpoint,同一network的endpoint可以通信
macvlan 实现跨主机通信
macvlan 网络方式:
1、Linux kernel提供的一种网卡虚拟化技术
2、无需Linux bridge,直接使用物理接口,性能极好
3、容器的接口直接与主机网卡连接,无需NAT或端口映射
4、macvlan会独占主机网卡,但可以使用vlan子接口实现多macvlan网络
5、vlan可以将物理二层网络划分为4094个逻辑网络,彼此隔离,vlan id取值为1~4094
macvlan网络间的隔离和连通:
1、macvlan网络在二层上是隔离的,所以不同macvlan网络的容器是不能通信的
2、可以在三层上通过网关将macvlan网络连通起来
3、docker本身不做任何限制,像传统vlan网络那样管理即可
实现方法如下:
1、在两台docker主机上各添加一块网卡,打开网卡混杂模式:
[root@docker1 ~]# docker network create -d macvlan --subnet 1.1.1.0/24 --gateway 1.1.1.1 -o parent=eth1 macvlan1
#eth1为真实网卡的名称;打开eth1网卡的混杂模式;划分子网范围和设定网关;(macvlan1)设定该子网和网关属于哪一个macvlan
2、创建并运行容器时添加上 macvlan 网络
[root@docker1 ~]# docker run -it --name busybox --network macvlan1 --ip 1.1.1.100 --rm busybox
[root@docker2 packages]# docker run -it --name busybox --network macvlan1 --ip 1.1.1.200 --rm busybox
3、实现不同主机之间的容器可相互通信:
Docker 数据卷管理
Docker 数据卷是一个可供容器使用的特殊目录,它绕过了容器的文件系统,直接将数据存储在宿主机上。
这样可以实现以下几个重要的目的:
1、数据持久化
即使容器被删除或重新创建,数据卷中的数据仍然存在,不会丢失。
2、数据共享
多个容器可以同时挂载同一个数据卷,实现数据的共享和交互。
3、独立于容器生命周期
数据卷的生命周期独立于容器,不受容器的启动、停止和删除的影响。
使用数据卷原因
1、docker 分层文件系统
1、性能差
2、生命周期与容器相同
2、docker 数据卷
mount到主机中,绕开分层文件系统
和主机磁盘性能相同,容器删除后依然保留
仅限本地磁盘,不能随容器迁移
3、docker 提供了两种卷:
bind mount
docker managed volume
bind mount 数据卷
是将主机上的目录或文件mount(挂载)到容器内
使用直观高效,易于理解
使用 -v 选项指定路径
[root@docker1 ~]# docker run -it --rm --name busybox \
-v /root/auth:/tym \
-v /root/anaconda-ks.cfg:/tym/an:ro \#对于挂载的文件设定只读权限
busybox:latest
# -v选项指定的路径,如果不存在,挂载时会自动创建
# 挂载时可选择本地主机的目录或文件
# 挂载时可对其文件或目录进行权限的设定;(:rw/ro)可读可写/只读
# 可修改挂载在容器内的目录或文件名称
自动创建目录:
挂载时修改名称:
设定目录或文件的权限:
docker managed 数据卷
docker managed 数据卷优势:
1、bind mount 必须指定 host 文件系统路径,限制了移植性
2、docker managed volume 不需要指定 mount 源,docker自动为容器创建数据卷目录
docker managed 数据卷的特点:
1、默认创建的数据卷目录都在 /var/lib/docker/volumes 中
2、如果挂载时指向容器内的位置已有目录,则会将目录原有数据都复制到volume 中
3、只能挂载目录,不能挂载文件
4、当容器被删除数,数据卷内的数据仍保留,且可直接被其它容器使用
[root@docker1 volumes]# docker run -d --name mysql \
-e MYSQL_ROOT_PASSWORD='lee' \
mysql:5.7
数据的持久化:
建立数据卷
[root@docker1 ~]# docker volume create tym
#创建数据卷
[root@docker1 ~]# ll /var/lib/docker/volumes/
#数据卷默认生成路径
使用创建好的数据卷
[root@docker1 ~]# docker run -it --rm --name test \
> -v tym:/tym \# 无需写数据卷的路径,系统可自动识别数据卷名称
> busybox
bind mount 与 docker managed 数据卷的对比
相同点:
两者都是 host 文件系统中的某个路径
不同的点:
1、volume位置
可任意指定(bind mount)
/var/lib/docker/volumes/…(docker managed)
2、对已有mount point影响
隐藏并替换为volume(bind mount)
原有数据复制到volume(docker managed)
3、是否支持单个文件
支持(bind mount)
不支持,只能是目录(docker managed)
4、权限控制
可设置为只读,默认为读写权限(bind mount)
无控制,均为读写权限(docker managed)
5、移植性
移植性弱,与host path绑定(bind mount)
移植性强,无需指定host目录(docker managed)
清理未使用的数据卷
[root@docker1 ~]# docker volume prune
1、在执行 docker volume prune 命令之前,请确保你确实不再需要这些数据卷中的数据,因为该操作是不可逆的,一旦删除数据将无法恢复。
2、如果有重要的数据存储在数据卷中,建议先进行备份,或者确保数据已经被妥善保存到其他地方。
数据卷容器
数据卷容器(Data Volume Container)是 Docker 中一种特殊的容器,主要用于方便地在多个容器之间共享数据卷
1、建立数据卷容器
[root@docker1 ~]# docker run -d --name datavol \
-v /tmp/data1:/data1:rw \
-v /tmp/data2:/data2:ro \
-v /etc/resolv.conf:/etc/hosts \
busybox
2、使用数据卷容器
[root@docker1 ~]# docker run -it --rm --name test \
--volumes-from datavol \
busybox
数据卷的备份和迁移
备份数据卷:
[root@docker ~]# docker run --volumes-from datavol \
-v `pwd`:/backup \# 把当前目录挂载到容器中
busybox
#建立新的容器,并将数据卷容器内的数据打包压缩至指定的路径下
tar zcf /backup/data1.tar.gz /data1
# (/backup/data1.tar.gz)指定压缩包的路径/名称
# (/data1)指定需要打包压缩的目录文件
数据的恢复:
[root@docker1 /]# docker run -it --name test \
-v volume:/data1 \
-v `pwd`:/backup busybox /bin/sh \
-c "tar zxf /backup/data1.tar.gz;/bin/sh"
Docker 安全控制
Docker容器的安全性,很大程度上依赖于Linux系统自身
评估Docker的安全性时,主要考虑以下几个方面:
1、Linux内核的命名空间机制提供的容器隔离安全
2、Linux控制组机制对容器资源的控制能力安全
3、Linux内核的能力机制所带来的操作权限安全
4、Docker程序(特别是服务端)本身的抗攻击性
5、其他安全增强机制对容器安全性的影响
在 rhel9 中默认使用 cgroup-v2 ;但是 cgroup-v2 中不利于观察 docker 的资源限制情况,所以推荐使用cgroup-v1
修改内核参数:
[root@docker1 ~]# grubby --update-kernel=/boot/vmlinuz-$(uname -r) \
--args="systemd.unified_cgroup_hierarchy=0 systemd.legacy_systemd_cgroup_controller"
[root@docker1 ~]# mount -t cgroup
# 可通过该命令查看内核开启的是cgroup1还是2;
命名空间隔离的安全
1、当docker run启动一个容器时,Docker将在后台为容器创建一个独立的命名空间
2、命名空间提供了最基础也最直接的隔离
3、与虚拟机方式相比,通过Linux namespace 实现的隔离并不是那么彻底
4、容器只是运行在宿主机上的一种特殊的进程,那么多个容器之间使用的就还是同一个宿主机的操作系统内核
5、在 Linux 内核中,有很多资源和对象是不能被 Namespace 优化的,比如:磁盘,内存等等
[root@docker1 ~]# docker run -d --name web nginx
f86df2ded12fb87f0c2051441b9f0236ad9c3c5088ea200d35d2339cb80a0bd9
控制组资源控制的安全
1、当docker run启动一个容器时,Docker将在后台为容器创建一个独立的控制组策略集合。
2、Linux Cgroups提供了很多有用的特性,确保各容器可以公平地分享主机的内存、CPU、磁盘IO等资源。
3、确保当发生在容器内的资源压力不会影响到本地主机系统和其他容器,它在防止拒绝服务攻击(DDoS)方面必不可少
内核能力机制
1、能力机制(Capability)是Linux内核一个强大的特性,可以提供细粒度的权限访问控制。
2、大部分情况下,容器并不需要“真正的”root权限,容器只需要少数的能力即可。
3、默认情况下,Docker采用“白名单”机制,禁用“必需功能”之外的其他权限。
Docker服务端防护
1、使用Docker容器的核心是Docker服务端,确保只有可信的用户才能访问到Docker服务。
2、将容器的root用户映射到本地主机上的非root用户,减轻容器和主机之间因权限提升而引起的安全问题。
3、允许Docker 服务端在非root权限下运行,利用安全可靠的子进程来代理执行需要特权权限的操作。
4、这些子进程只允许在特定范围内进行操作。
Docker 的资源限制
Linux Cgroups 的全称是 Linux Control Group:
是限制一个进程组能够使用的资源上限,包括 CPU、内存、磁盘、网络带宽等等
对进程进行优先级设置、审计,以及将进程挂起和恢复等操作
Linux Cgroups 给用户暴露出来的操作接口是文件系统:
它以文件和目录的方式组织在操作系统的 /sys/fs/cgroup 路径下
执行此命令查看:mount -t cgroup
cgroup 子系统:
在 /sys/fs/cgroup 下面有很多诸如 cpuset、cpu、 memory 这样的子目录,也叫子系统
在每个子系统下面,为每个容器创建一个控制组(即创建一个新目录)
控制组下面的资源文件里填上什么值,就靠用户执行 docker run 时的参数指定
限制 CPU 的使用
限制CPU的使用量:
[root@docker1 ~]# docker run -it --rm --name test \
--cpu-period 100000 \ #设置 CPU 周期的长度,单位为微秒(通常为
100000,即 100 毫秒)
--cpu-quota 20000 \
ubuntu #设置容器在一个周期内可以使用的 CPU 时间,单位也是微秒
查看设定之后的效果:
root@5797d76b20f5:/# dd if=/dev/zero of=/dev/null &
#进入容器内,将CPU的调度设定为最大
root@5797d76b20f5:/# top
#查看系统性能
也可在文件内进行手动修改数值:
限制CPU的优先级:
1、关闭cpu的核心,当cpu都不空闲下才会出现争抢的情况,为了实验效果我们可以关闭一个cpu核心
root@docker ~]# echo 0 > /sys/devices/system/cpu/cpu1/online
2、限制其容器使用核心优先级
[root@docker1 ~]# docker run -it --rm --cpu-shares 100 ubuntu
#设定cpu优先级,最大为1024,值越大优先级越高
root@dc066aa1a1f0:/# dd if=/dev/zero of=/dev/null &
root@dc066aa1a1f0:/# top
#将CPU调度最大;查看系统信息
3、开启另一个容器,不做限制:
[root@docker1 ~]# docker run -it --rm ubuntu
4、效果展示:
限制了CPU优先级的性能:
不做限制的容器性能:
限制内存的使用
开启容器并限制容器使用内存大小
[root@docker1 ~]# docker run -d --name test --memory 200M --memory-swap 200M nginx
#查看容器内存使用限制
[root@docker ~]# cat /sys/fs/cgroup/memory/docker/...fe/memory.limit_in_bytes
测试:
测试容器内存限制,在容器中我们测试内存限制效果不是很明显,可以利用工具模拟容器在内存中写入数据;在系统中/dev/shm这个目录被挂载到内存中
cgexec -g memory:doceker/容器id
-g表示使用指定控制器类型
[root@docker1 ~]# cgexec -g memory:docker/...fe dd if=/dev/zero of=/dev/shm/bigfile bs=1M count=150
限制 Docker 磁盘 io 速率
[root@docker1 ~]# docker run -it --rm --name ubuntu \
> --device-write-bps \# 指定容器使用磁盘io的速率
> /dev/nvme0n1:30M \# /dev/nvme0n1是指定系统的磁盘,30M即每秒30M数据
> ubuntu:latest
Docker 的安全加固
Docker 默认隔离性
在系统中运行容器,我们会发现资源并没有完全隔离开
即使我们限制了容器的内存大小,但在查看的信息中并没有隔离开
修改默认隔离性
LXCFS 是一个为 LXC(Linux Containers)容器提供增强文件系统功能的工具;主要功能有:
1、资源可见性
LXCFS 可以使容器内的进程看到准确的 CPU、内存和磁盘 I/O 等资源使用信息。在没有 LXCFS时,容器内看到的资源信息可能不准确,这会影响到在容器内运行的应用程序对资源的评估和管理。
2、性能监控
方便对容器内的资源使用情况进行监控和性能分析。通过提供准确的资源信息,管理员和开发人员可以更好地了解容器化应用的性能瓶颈,并进行相应的优化。
1、安装 lxcfs
在 rhel9 中 lxcfs 是被包含在 epel 源中,我们可以直接下载安装包进行安装
2、运行 lxcfs 并解决容器隔离性
[root@docker1 ~]# lxcfs /var/lib/lxcfs &
#将程序打入后台运行
[root@docker ~]# 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
#挂载程序文件并运行容器
3、效果展示
容器特权
在容器中默认情况下即使我是容器的超级用户也无法修改某些系统设定,比如网络等信息
这是因为容器使用的很多资源都是和系统真实主机公用的,如果允许容器修改这些重要资源,系统的稳定性会变的非常差
但是由于某些需要求,容器需要控制一些默认控制不了的资源,如何解决此问题,这时我们就要设置容器特权
–privileged :开放绝大多数的权限,接近于宿主机的root用户权限
[root@docker1 ~]# docker run --rm -it --privileged busybox
容器特权的白名单
–privileged=true 的权限非常大,接近于宿主机的权限,为了防止用户的滥用,需要增加限制,只提供给容器必须的权限。此时Docker 提供了权限白名单的机制,使用 --cap-add 添加必要的权限
capabilities手册地址:
http://man7.org/linux/man-pages/man7/capabilities.7.html
进行添加权限白名单:
[root@docker1 ~]# docker run --rm -it --cap-add NET_ADMIN busybox
效果展示:
Docker Compose
Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。
是官方的一个开源项目,托管到github上
主要功能
1、定义服务
使用 YAML 格式的配置文件来定义一组相关的容器服务。每个服务可以指定镜像、端口映射、环境变量、存储卷等参数。
例如,可以在配置文件中定义一个 Web 服务和一个数据库服务,以及它们之间的连接关系。
2、一键启动和停止
通过一个简单的命令,可以启动或停止整个应用程序所包含的所有容器。这大大简化了多容器应用的部署和管理过程。
例如,使用 docker compose up 命令可以启动配置文件中定义的所有服务,使用 docker compose down 命令可以停止并删除这些服务。
3、服务编排
可以定义容器之间的依赖关系,确保服务按照正确的顺序启动和停止。例如,可以指定数据库服务必须在 Web 服务之前启动。
支持网络配置,使不同服务的容器可以相互通信。可以定义一个自定义的网络,将所有相关的容器连接到这个网络上。
4、环境变量管理
可以在配置文件中定义环境变量,并在容器启动时传递给容器。这使得在不同环境(如开发、测试和生产环境)中使用不同的配置变得更加容易。
例如,可以定义一个数据库连接字符串的环境变量,在不同环境中可以设置不同的值。
工作原理
1、读取配置文件
Docker Compose 读取 YAML 配置文件,解析其中定义的服务和参数
2、创建容器
根据配置文件中的定义,Docker Compose 调用 Docker 引擎创建相应的容器。它会下载所需的镜像(如果本地没有),并设置容器的各种参数。
3、管理容器生命周期
Docker Compose 监控容器的状态,并在需要时启动、停止、重启容器。
它还可以处理容器的故障恢复,例如自动重启失败的容器。
Docker Compose 中的管理层
1、服务 (service) 一个应用的容器,实际上可以包括若干运行相同镜像的容器实例
2、项目 (project) 由一组关联的应用容器组成的一个完整业务单元,在 docker-compose.yml 文件中定义
3、 容器(container)容器是服务的具体实例,每个服务可以有一个或多个容器。容器是基于服务定义的镜像创建的运行实例
Docker Compose 的常用命令参数
最简单的YML文件编写:
version: “1.0”
#在rhel7的及以前的版本需要指定compose的版本
services:
web: #未指定容器名称时,默认为:当前YML文件所在目录-web-1
image: nginx #指定使用的镜像
ports: #指定暴露的端口
- “80:80”
db: #这里为第二个容器的描述
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: le
常用的 compose 命令:
1、docker compose up
启动配置文件中定义的所有服务。
可以使用 -d 参数在后台启动服务。
[root@docker1 docker]# docker compose up -d
#默认读取当前路径下的compose.yml文件
可以使用 -f 来指定yml文件(需在指定文件所在目录输入命令)
例如: docker compose -f *.yml up -d
[root@docker1 docker]# docker compose -f test.yml up -d
2、docker compose down
停止并删除配置文件中定义的所有服务以及相关的网络和存储卷
[root@docker1 docker]# docker compose down
#默认读取当前路径下的compose.yml文件
#可使用 -f 指定.yml文件
3、docker compose start
启动已经存在的服务,但不会创建新的服务
[root@docker1 docker]# docker compose start
4、docker compose stop
停止正在运行的服务,但并不会删除相关的服务
[root@docker1 docker]# docker compose stop
5、docker compose restart
重启服务
[root@docker1 docker]# docker compose restart
6、docker compose ps
列出正在运行的服务以及它们的状态,包括容器 ID、名称、端口映射等信息。
[root@docker1 docker]# docker compose ps
7、docker compose logs
查看服务的日志输出。可以指定服务名称来查看特定服务的日志。
[root@docker1 docker]# docker compose logs test
8、docker compose exec
在正在运行的服务容器中执行命令。
[root@docker1 docker]# docker compose exec -it test sh
9、docker compose pull
拉取配置文件中定义的服务所使用的镜像。
[root@docker1 docker]# docker compose -f test.yml pull
10、docker compose config
验证并查看解析后的 Compose 文件内容
[root@docker1 docker]# docker compose -f test.yml config
#可添加参数 -p 来忽略检测成功后打印出的内容
Docker Compose 的 yml 文件
Docker Compose 的 YAML 文件用于定义和配置多容器应用程序的各个服务。
服务(services)
1、服务名称(service1_name/service2_name等)
每个服务在配置文件中都有一个唯一的名称,用于在命令行和其他部分引用该服务。
services:
web:
# 服务1的配置
mysql:
# 服务2的配置
2、镜像(image)
指定服务所使用的 Docker 镜像名称和标签。
例如:image: nginx:latest 表示使用 nginx镜像的最新版本
services:
web:
images:nginx
mysql:
images:mysql:5.7
3、端口映射(ports)
将容器内部的端口映射到主机的端口,以便外部可以访问容器内的服务。
例如:- “80:80” 表示将主机的 80端口映射到容器内部的 80 端口。
services:
web:
image: timinglee/mario
container_name: game #指定容器名称
restart: always #docekr容器自动启动
expose:
- 1234 #指定容器暴露那些端口,些端口仅对链接的服务可见,不会映射到主机的端口
ports:
- "80:8080"
4、环境变量(environment)
为容器设置环境变量,可以在容器内部的应用程序中使用。
例如:VAR1: value1 设置环境变量 VAR1 的值为 value1
services:
web:
images:mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: 123
5、存储卷(volumes)
将主机上的目录或文件挂载到容器中,以实现数据持久化或共享。
例如: - /host/data:/container/data 将主机上的 /host/data 目录挂载到容器内的 /container/data 路径。
services:
test:
image: busybox
command: ["/bin/sh","-c","sleep 3000"]
restart: always
container_name: busybox1
volumes:
- /etc/passwd:/tmp/passwd:ro #只读挂在本地文件到指定位置
6、网络(networks)
将服务连接到特定的网络,以便不同服务的容器可以相互通信
services:
web:
image: nginx
container_name: webserver
network_mode: bridge #使用本机自带bridge网络
services:
test:
image: busybox
container_name: webserver
command: ["/bin/sh","-c","sleep10000000"]
network_mode: mynet2 #使用自定义网络
networks:
- mynet1
- mynet2
networks:
mynet1:
driver: bridge
mynet2:
driver: bridge
7、命令(command)
覆盖容器启动时默认执行的命令。
例如:command: python app.py 指定容器启动时运行 python app.py 命令
services:
web:
image: busybox
container_name: busybox
network_mode: mynet2
command: ["/bin/sh","-c","sleep 10000000"]
网络(networks)
定义 Docker Compose 应用程序中使用的网络。可以自定义网络名称和驱动程序等属性。
默认情况下docker compose 在执行时会自动建立网络
services:
test:
image: busybox1
command: ["/bin/sh","-c","sleep 3000"]
restart: always
network_mode: default
container_name: busybox
test1:
image: busybox2
command: ["/bin/sh","-c","sleep 3000"]
restart: always
container_name: busybox1
networks:
- mynet1
test3:
image: busybox3
command: ["/bin/sh","-c","sleep 3000"]
restart: always
container_name: busybox1
networks:
- mynet2
networks:
mynet1:
driver: bridge #使用桥接驱动,也可以使用macvlan用于跨主机连接
default:
external: true #不建立新的网络而使用外部资源
name: bridge #指定外部资源网络名字
mynet2:
ipam:
driver: default
config:
- subnet: 172.28.0.0/16
gateway: 172.28.0.254
存储卷(volumes)
定义 Docker Compose 应用程序中使用的存储卷。可以自定义卷名称和存储位置等属性。
services:
test:
image: busybox
command: ["/bin/sh","-c","sleep 3000"]
restart: always
container_name: busybox1
volumes:
- data:/test #挂载data卷
- /etc/passwd:/tmp/passwd:ro #只读挂在本地文件到指定位置
volumes:
data:
name: test #指定建立卷的名字
Docker Compose 企业示例
1、下载 HAProxy 软件包
[root@docker1 docker]# yum install haproxy.x86_64 --downloadonly --downloaddir=/root/
2、将需要的文件拷贝至指定目录下
[root@docker1 docker]# cp /root/etc/haproxy/haproxy.cfg /docker/conf/haproxy/
#将HAProxy的配置文件拷贝至指定目录
修改HAProxy的配置文件
listen web
bind *:80
mode http
balance roundrobin
server web1 web1:80 check inter 2 fall 3 rise 5
server web2 web2:80 check inter 2 fall 3 rise 5
编辑Nginx的发布页内容
[root@docker1 docker]# echo this is web1 /docker/web/html1/index.html
[root@docker1 docker]# echo this is web2 /docker/web/html2/index.html
3、编辑 YML 文件
[root@docker1 docker]# vim haproxy.yml
services:
webservice1:
image: nginx:latest
container_name: web1
restart: always
networks:
- mynet1
expose:
- 80
volumes:
- /docker/web/html1:/usr/share/nginx/html
webservice2:
image: nginx:latest
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:
- /docker/conf/haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg
ports:
- 80:80
networks:
mynet1:
driver: bridge
mynet2:
driver: bridge
4、效果演示