参考文档 https://jiajially.gitbooks.io/dockerguide/content/chapter_fastlearn/docker_run/–volumes-from.html
容器技术、虚拟化技术已经成为一种被大家广泛认可的服务器资源共享方式,容器技术可以在按需构建操作系统实例的过程当中为系统管理员提供极大的灵活性。由于hypervisor虚拟化技术仍然存在一些性能和资源使用效率方面的问题,因此容器技术(Container)结合虚拟化技术的解决方案正在我们的业务使用中高频使用。
虚拟机 :是通过管理系统Hypervisor模拟出CPU、内存、网络等硬件,然后在硬件的基础上创建内核和操作系统。
优点:
缺点:
资源占用十分大,虚拟机实例过大,资源首先,无法启动过多
虚拟机的创建流程复杂
虚拟机的启动时间过长
容器:是通过Linux内核的Namespace技术实现了文件系统、进程、设备以及网络的隔离,然后通过Cgourps对CPU、内存等资源进行限制,实现容器之间的隔离
Namespace是linux内核用来隔离内核资源的方式,是对全局系统资源的一种封装隔离,是的处于不同namespace 的进程拥有独立的全局系统资源,改变一个namespace中的系统资源只会影响当前namespace里的进程,对其他namespace的进程没有影响
优点:
架构: docker是CS架构,由client客户端和server服务端组成
组成:
镜像(image):镜像就是一个只读的root文件通模板,可以通过这个模板创建容器服务,一个镜像可以创建多个容器
**容器(container):**Docker利用容器技术,独立运行的一个或一组应用。容器是用镜像创建的运行实例。
**仓库(repository):**仓库是集中存放镜像文件的场所。仓库和仓库注册服务器(Registry)是有区别的,仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签
仓库分为**公开仓库(public)和私有仓库(private)**两种形式
最大的开放仓库是国外的 Docker Hub,存放了数量庞大的镜像供用户下载。
国内的公开仓库包括阿里云,网易云都有容器服务器(需要配置镜像加速)等
docker适合centos 7 或者 8 的版本,通过以下命令查看系统配置:
uname -r
cat /etc/os-release
安装
安装gcc相关依赖
yum -y install gcc
yum -y install gcc-c++
卸载旧版本
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine
安装需要的软件包
yum install -y yum-utils device-mapper-persistent-data lvm2
设置stable镜像仓库
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
更新yum软件索引
centos7: sudo yum makecache fast
centos8执行: dnf makecache
安装docker
yum -y install docker-ce
期间遇到问题参考博客:https://blog.csdn.net/test1280/article/details/119523583
sudo yum erase podman buildah
启动docker
systemctl start docker
开机自启
systemctl enable docker
测试
docker version #查看版本
docker run hello-world #运行hello-world镜像
docker ps #查看运行容器
配置阿里云镜像加速,如果不配的话镜像下载会从国外下载,会很慢。
mkdir -p /etc/docker #新建一个目录
vim /etc/docker/daemon.json # 新建编辑json文件
打开文件后输入
{
"registry-mirrors": ["https://5hrp3vzq.mirror.aliyuncs.com"]
}
然后退出保存,继续执行
systemctl daemon-reload
systemctl restart docker
配置完成
卸载
# 1、卸载Docker依赖: Docker Engine,CLI和Containerd软件包
sudo yum remove docker-ce docker-ce-cli containerd.io
# 2、删除Docker资源: 所有镜像,容器和卷(主机上的镜像,容器,卷或自定义配置文件不会自动删除)
sudo rm -rf /var/lib/docker
Client-Server
结构的系统,Docket 的守护进程运行在主机上,通过Socket从客户端访问Docker有着比虚拟机更少的抽象层,由于Docker不需要Hypervisor实现硬件资源虚拟化,运行在Docker容器上的程序直接使用的都是实际物理机的硬件资源,因此在Cpu、内存利用率上Docker将会在效率上有明显优势。
Docker利用的是宿主机的内核,而不需要Guest OS,因此,当新建一个容器时,Docker不需要和虚拟机一样重新加载一个操作系统,避免了引导、加载操作系统内核这个比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载Guest OS,这个新建过程是分钟级别的,而Docker由于直接利用宿主机的操作系统则省略了这个过程,因此新建一个Docker容器只需要几秒钟。
Docker容器 | 虚拟机(VM) | |
---|---|---|
操作系统 | 与宿主机共享OS | 宿主机OS上运行虚拟机OS |
存储大小 | 镜像小,便于存储与传输 | 镜像庞大(vmdk等) |
运行性能 | 几乎无额外性能损失 | 操作系统额外的cpu、内存消耗 |
移植性 | 轻便、灵活、适用于Linux | 笨重、与虚拟化技术耦合度高 |
硬件亲和性 | 面向软件开发者 | 面向硬件运维者 |
帮助指令
# 显示docker的版本信息
docker version
# 显示docker的系统信息(包括镜像和容器数量)
docker info
# 帮助命令
docker 命令 --help
镜像指令
# 查看本地主机所有的镜像
docker images
#可选项
--all , -a 列出所有镜像
--quiet , -q 只显示镜像ID
# 搜索镜像
docker search 镜像名
# 可选项
-f, --filter filter 根据提供的条件过滤输出
# 例如搜索STARS大于3000的
docker search mysql -f STARS=3000
# 下载镜像
docker pull 镜像名[:tag]
docker pull mysql:latest
# 删除镜像
docker rmi
# 可选项
-f, --force #强制删除
docker rmi -f 镜像id #删除指定镜像
docker rmi -f 镜像id 镜像id 镜像id #删除指定多个镜像
docker rmi -f $(docker images -aq) #删除全部镜像
# 镜像标签
docker tag 镜像id/镜像全名 新标签
docker tag centos:latest centos:xiao7
容器指令
docker pull centos # 先拉取一个镜像
# 新建容器并启动
docker run [可选参数] image
# 参数说明
--name="Name" 容器名字,用于区分容器
-d 后台方式运行
-it 使用交互方式运行,进入容器查看内容
-p 指定容器端口(小写)
-p ip:主机端口:容器端口
-p 主机端口:容器端口(最常用)
-P 容器端口
-P 随机执行端口(大写)
-e 设置容器的环境属性配置,比如设置es的内存配置:-e ES_JAVA_OPTS="-Xms64m -Xmx512m"
# 重启容器
docker restart 容器id
# 容器停止并退出
exit
# 容器不停止退出
Ctrl+p+q
# 列出所有运行的容器
docker ps [可选参数]
# 参数说明
-a 列出当前正在运行以及历史运行过的容器
-n=? 显示最近创建的容器
-q 只显示容器编号
# 停止容器
docker stop 容器id # 停止正在运行的容器
docker kill 容器id # 强制停止当前容器
# 删除指定容器,不能删除正在运行的容器,强制删除用rm -f
docker rm 容器id/容器的name
# 删除所有容器
docker rm -f $(docker ps -aq)
docker ps -a -q|xargs docker rm
# 查看容器日志
docker logs [可选参数] 容器ID
--details 显示提供给日志的其他详细信息
-f, --follow 跟踪日志输出
-n, --tail string 指定要显示的日志条数 (默认为全部)
-t, --timestamps 显示时间戳
docker run --name centos -d centos /bin/bash -c "while true;do echo zsr;sleep 1;done"
docker logs -t -n 10 centos
# 查看容器中的进程
docker top 容器ID
# 查看镜像元数据
docker inspect 镜像id\容器id
# 方式一: 进入容器后开启一个新的终端,可在里面进行操作(常用)
docker exec -it 容器id /bin/bash
# 方式二: 进入容器正在执行的终端,不会启动新的进程
docker attach --sig-proxy=false 容器id # control+c可以退出而不停止容器
# 容器的导入导出
docker export 容器id > centos.tar # 导出
docker save 容器id > centos.tar # 导出
docker import - 新镜像名 < centos.tar # 导入
docker load < centos.tar # 导入
# 从容器内拷贝文件到主机
docker cp 容器id:容器内路径 目的主机路径
# 根据容器创建新镜像
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
-a :提交的镜像作者;
-c :使用Dockerfile指令来创建镜像;
-m :提交时的说明文字;
-p :在commit时,将容器暂停。
docker commit -a "xiao7" -m "测试提交" centos centos:xiao7
# 查看容器的状态
docker stats 容器id
镜像: 是一种轻量级,可执行的软件包,用来打包软件运行环境和基于运行软件开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。
Docker 的镜像实际上由一层一层的文件系统组成,这种层级的文件系统就是 UnionFS 。
**UnionFS(联合文件系统):**一种分层、轻量级且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不通目录挂载到同一个虚拟文件系统下(unite serveral directories into a single virtual filesystem)。
Union 文件系统是 Docker 镜像的基础,镜像可以通过分层来继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
**特性:**一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。
bootfs(boot file system): 主要包含bootloader和kernel,bootloader主要是引导加载kerel
,Linux
刚启动时会加载 bootfs
文件系统,在Docker
镜像的最底层时bootfs
。这一层与我们典型的Linux/Unix
内核是一样的,包含boot
加载器和内核。当boot加
载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs
转交给内核,此时系统也会卸载bootfs
**rootfs(root file system):**在bootfs
之上,包含的就是典型的 Linux
系统中的 /dev、/proc、/bin、/etc
等标准文件。rootfs
就是各种不同的操作系统发行版。
对于一个精简的 OS
,rootfs
可以很小,只需要包含最基本的命令、工具和程序库就可以了,因为底层使用的是主机的Kernel
,自己只需要提供rootfs
就可以了。由此可见,对于不同linux
发行版,bootfs
是基本一致的,rootfs
会有差别,因此不同的发行版可以公用bootfs
下载示例,可以看到,是一层一层的在下载
为什么Docker镜像要采取这种分层的结构呢?
**资源共享:**如果有多个镜像从相同的Base镜像构建而来,那么宿主机只需要在磁盘上保留一份base镜像,同时内存中也只需要加载一份base镜像,这样就可以为所有的容器服务,且每一层的镜像都可以被共享。
所有的 Docker镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上创建新的镜像层
举一个简单的例子,假如基于 Ubuntu Linux 16.04 创建一个新的镜像,这就是新镜像的第一层;如果要在该镜像中添加python包,就会在基础镜像层之上创建了新的一个镜像层;如果继续添加一个安全补丁,就会创建第三个镜像层
下图中展示了一个稍微复杂的三层镜像,在外部看来整个镜像只有 6 个文件,这是因为最上层中的文件7 是文件 5 的一个更新版本
这种情况下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中。
Docker 通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统。
运行原理
Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部!
这一层就是我们通常说的容器层,容器之下的都叫镜像层!
数据卷:我们希望Docker容器产生的数据可以自动同步到本地,这样容器删了数据并不会丢失;同时数据也可在容器之间共享。这就是卷技术,也就是目录的挂载,将容器内的目录挂载到linux
上
使用指令:
# 启动容器时指定挂载的数据卷目录
docker run -it -v 主机目录:容器内目录 镜像id
# 不指定路径,匿名挂载
docker run --name centos-2 -v centos-2:/home -d centos /bin/bash -c "while true;do echo zsr;sleep 1;done"
# 查看挂载的数据卷
docker volume ls
# 删除数据卷
docker volume rm 容器卷id
# 查看数据卷的具体内容
docker volume inspect centos-2
# 数据卷容器之间的共享
docker run -it --name centos-1 --volumes-from 被共享的容器id centos
# 清除无用容器卷
docker volume pure
数据卷特点: 主机和容器之间的数据会互相同步
数据卷容器特点: 容器共享另一个容器的数据卷
dockerfile是用来构建docker
镜像的文件
基础知识:
#
代表注释可参考文档:https://www.runoob.com/docker/docker-dockerfile.html
每种指令的用法
# 1、FROM
FROM java:8 # 挂载java基础镜像环境
# 2、MAINTAINER
MAINTAINER xioa7<[email protected]> # 设置姓名邮箱
# 3、RUN 编译镜像时执行的脚本 是在 docker build的时候执行
# RUN <命令行命令>
RUN yum -y install wget
RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"
RUN tar -xvf redis.tar.gz # 创建三层镜像
RUN yum -y install wget \
&& wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
&& tar -xvf redis.tar.gz # 只创建一层镜像
# RUN ["可执行文件", "参数1", "参数2"]
RUN ["./test.php", "dev", "offline"] # 等价于 RUN ./test.php dev offline
# 4、CMD设置容器的启动命令,在docker run 时运行。如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。
CMD
CMD ["<可执行文件或命令>","","",...]
CMD ["","",...] # 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数
# 5、LABEL 设置镜像标签
LABEL = = = ...
LABEL org.opencontainers.image.authors="runoob"
# 6、EXPOSE 设置镜像暴露的端口
EXPOSE <端口1> [<端口2>...] # 仅仅只是声明端口。帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射。
# 7、ENV 设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量。
ENV NODE_VERSION 7.2.0
RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \
&& curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc"
# 8、ADD、COPY 构建镜像时复制内容到镜像中
COPY [--chown=:] <源路径1>... <目标路径>
COPY hom* /mydir/
COPY hom?.txt /mydir/
# 9、ENTRYPOINT 设置程序入口
ENTRYPOINT ["","","",...]
优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。
注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。
例子:
FROM nginx
ENTRYPOINT ["nginx", "-c"] # 定参
CMD ["/etc/nginx/nginx.conf"] # 变参是给上面的提供默认参数
# 9、VOLUME 设置容器的挂载卷
VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>
# 10、USER 设置执行后续命令的用户
USER <用户名>[:<用户组>]
# 11、WORKDIR 设置工作目录
WORKDIR <工作目录路径>
# 12、ARG 构建参数,与 ENV 作用一致。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量。
ARG <参数名>[=<默认值>]
# 13、ONBUILD 用于延迟构建命令的执行。简单的说,就是 Dockerfile 里用 ONBUILD 指定的命令,在本次构建镜像的过程中不会执行(假设镜像为 test-build)。当有新的 Dockerfile 使用了之前构建的镜像 FROM test-build ,这时执行新镜像的 Dockerfile 构建时候,会执行 test-build 的 Dockerfile 里的 ONBUILD 指定的命令。
ONBUILD <其它指令>
# 14、STOPSINGLE 指令设置将发送到容器以退出的系统调用信号。这个信号可以是一个有效的无符号数字,与内核的syscall表中的位置相匹配,例如9,或者是SIGNAME格式的信号名,例如SIGKILL。
STOPSINGLE 15
例子
FROM centos
MAINTAINER zsr<[email protected]>
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 8088
CMD echo $MYPATH
CMD echo "----end----"
CMD /bin/bash
构建镜像
docker build -f 文件名 -t 镜像名:[tag] .
拉取运行
docker run -d -p 8088:9000 \
--restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
打开服务远程连接
连接不上需要开放2375端口
1. 编辑docker.service
vim /usr/lib/systemd/system/docker.service
找到 ExecStart字段修改如下
#ExecStart=/usr/bin/dockerd-current -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock
2. 重启docker重新读取配置文件,重新启动docker服务
systemctl daemon-reload
systemctl restart docker
3. 开放防火墙端口
firewall-cmd --zone=public --add-port=6379/tcp --permanent
4.刷新防火墙
firewall-cmd --reload
**登录仓库 **
docker login -u 账号名
打上标签
docker tag centos:xiao7 15625764185/centos:xiao7
docker tag 原镜像 账户名/镜像名:版本号 # 格式
推送到仓库
docker push 15625764185/centos:xiao7
安装docker-compose,建议手动下载上传
# 下载github的文件,连接不上的话配置hosts 进入/etc/hosts,先去https://www.ipaddress.com查询指定域名的ip
140.82.112.3 github.com
185.199.108.133 raw.githubusercontent.com
185.199.109.133 raw.githubusercontent.com
185.199.110.133 raw.githubusercontent.com
185.199.111.133 raw.githubusercontent.com
151.101.1.194 github.global.ssl.fastly.net
# 这个命令下载了个错的
sudo curl -L "https://github.com/docker/compose/releases/download/v2.16.0/docker-compose--$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 指定具体的文件
sudo curl -L "https://github.com/docker/compose/releases/download/v2.16.0/docker-compose-linux-aarch64" -o /usr/local/bin/docker-compose
sudo curl -L "https://github.com/docker/compose/releases/download/v2.16.0/docker-compose-linux-x86_64" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version
安装harbor
**https相关配置参考:**https://glory.blog.csdn.net/article/details/127817508?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EOPENSEARCH%7ERate-2-127817508-blog-87954438.pc_relevant_3mothn_strategy_and_data_recovery&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EOPENSEARCH%7ERate-2-127817508-blog-87954438.pc_relevant_3mothn_strategy_and_data_recovery&utm_relevant_index=3
# 下载压缩包
wget https://github.com/goharbor/harbor/releases/download/v2.5.3/harbor-offline-installer-v2.5.3.tgz
# 解压
tar -vxf harbor-offline-installer-v2.6.3.tar
#修改配置文件
cd harbor
cp harbor.yml.tmpl harbor.yml
vi harbor.yml
hostname:改成自己的域名或者ip
https相关注释掉,局域网不需要
harbor_admin_password:设置管理后台密码
# 安装
./install.sh
# 登录仓库地址
docker login 仓库ip+端口
# 推送 docker push <仓库ip:端口>/<项目名称>/<镜像名>:
docker push 192.168.101.20/baozi/dotnet6demo:v1
当我们用ip addr
命令查看服务器内部网络地址时,可以发现三个地址:
127.0.0.1
本机回环地址10.211.55.3
服务器内网IP地址172.17.0.1
docker0
地址这里的docker0
地址就是安装docker
时,采用 桥接模式 使用 evth-pair
技术分配的地址
ip
地每次新增的网络地址都是一对一对的70/71
,这就是evth-pair
技术,就是一对虚拟设备接口,成对出现,一段连着协议,一段彼此相连;容器内的70连接了主机的71;
evth-pair
充当了一个桥梁,实现了主机可以ping
通容器内部ip
地址,用于连接各种虚拟网络设备
可用docker netowork
命令查看该网桥中的所有配置
[root@localhost ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
d5c5483d1a8e bridge bridge local
34d522c7863f host host local
dcd894499677 none null local
[root@localhost ~]# docker network inspect bridge
[
{
"Name": "bridge",
"Id": "d5c5483d1a8ed4d862cd515f582324d469ef645ffc577b5d3deb84a516c64ac2",
"Created": "2023-02-10T18:35:24.437139277-05:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"29939ea09b2d6926d4dd2fb6ef19f75180fb1381d64030fa88f52feba04faf08": {
"Name": "centos",
"EndpointID": "3dccf14953bdcc76899cd2493ac22411576d2fd6f36fa321eca419c947d9803b",
"MacAddress": "02:42:ac:11:00:03",
"IPv4Address": "172.17.0.3/16",
"IPv6Address": ""
}
},
"Options": {
"com.docker.network.bridge.default_bridge": "true",
"com.docker.network.bridge.enable_icc": "true",
"com.docker.network.bridge.enable_ip_masquerade": "true",
"com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
"com.docker.network.bridge.name": "docker0",
"com.docker.network.driver.mtu": "1500"
},
"Labels": {}
}
]
**结论:**容器和容器之间是可以互相ping通的
所有的容器不指定网络的情况下,都是通过 docker0
路由的,docker
会给容器分配一个默认的可用ip
Docker
使用的是Linux
的桥接,宿主机中是一个Docker
容器的网桥docker0
Docker
中所有的网络接口都是虚拟的,转发效率高,只要容器删除,对应的网桥就删除
如果我们编写了一个微服务,连接数据库的ip地址变化了,此时数据连接就会断开,服务不可用;如果此时能够通过容器名字连接数据库,就可以解决数据库连接的问题;
#如果tomcat01直接通过pingtomcat02的容器名,会报错
[root@zsr ~]# docker exec -it tomcat01 ping tomcat02
ping: tomcat02: Name or service not known
那么如何解决这个问题呢?可以在创建容器时用--link指定连接的容器,此时就可以通过容器名来ping通了
[root@zsr ~]# docker run -d -P --name tomcat03 --link tomcat01 tomcat
1cc06da893c10d4ef1bdf7e590860b44cf55a0c506b57b64dda44551ef06d816
[root@zsr ~]# docker exec -it tomcat03 ping tomcat01
PING tomcat01 (172.18.0.2) 56(84) bytes of data.
64 bytes from tomcat01 (172.18.0.2): icmp_seq=1 ttl=64 time=0.127 ms
64 bytes from tomcat01 (172.18.0.2): icmp_seq=2 ttl=64 time=0.103 ms
64 bytes from tomcat01 (172.18.0.2): icmp_seq=3 ttl=64 time=0.103 ms
但是反过来ping则无法ping通
[root@zsr ~]# docker exec -it tomcat01 ping tomcat03
ping: tomcat03: Name or service not known
**原理:**通过–link 使tomcat03 在本地hosts中配置了 tomcat02的ip与容器名的映射
网络模式
bridge
:桥接(默认)none
:不配置网络host
:主机模式,和宿主机共享网络container
:容器网络联通(使用少!)建议自定义一个网络,所有的服务都在自定义的网络中进行使用!
创建一个网络mynet,采用默认的桥接模式,子网地址192.168.0.0,网关192.168.0.1
[root@zsr ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
2e6be259e1f43f884fbf9e24aa3cc1b238b91bd1e9be3ba0abcfbefd3e106450
[root@zsr ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
81fa37acd3b5 bridge bridge local
d1c3276f2d1f host host local
2e6be259e1f4 mynet bridge local
40b12350fa4a none null local
我们指定使用自定义网络mynet
来启动两个容器
[root@zsr ~]# docker run -d -P --name mynet-tomcat01 --net mynet tomcat
2795bf15cd21ec608c02840bd7488942da4838d47662b0b204e663003fa49a3b
[root@zsr ~]# docker run -d -P --name mynet-tomcat02 --net mynet tomcat
41b416dbf35eb55164ffe024d120a17db60aa0a501f20ef3ce40d3c180a67517
再次测试ping连接,发现自定义的网络解决了docker0的缺点,可以直接通过容器名来访问
应用场景:
不同的集群(redis
,mysql
)用不同的网络,使用自己的子网,保证集群的安全及健康
参考文档:https://yeasy.gitbook.io/docker_practice/compose/compose_file、https://www.runoob.com/docker/docker-compose.html
Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。
# 下载github的文件,连接不上的话配置hosts 进入/etc/hosts,先去https://www.ipaddress.com查询指定域名的ip
140.82.112.3 github.com
185.199.108.133 raw.githubusercontent.com
185.199.109.133 raw.githubusercontent.com
185.199.110.133 raw.githubusercontent.com
185.199.111.133 raw.githubusercontent.com
151.101.1.194 github.global.ssl.fastly.net
# 这个命令下载了个错的
sudo curl -L "https://github.com/docker/compose/releases/download/v2.16.0/docker-compose--$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 指定具体的文件
sudo curl -L "https://github.com/docker/compose/releases/download/v2.16.0/docker-compose-linux-aarch64" -o /usr/local/bin/docker-compose
sudo curl -L "https://github.com/docker/compose/releases/download/v2.16.0/docker-compose-linux-x86_64" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version
# 配置示例
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
- logvolume01:/var/log
docker-compose up
指定本 yml
依从的 compose
哪个版本制定的。
指定为构建镜像上下文路径:
例如 webapp 服务,指定为从上下文路径 ./dir/Dockerfile 所构建的镜像:
version: "3.7"
services:
webapp:
build: ./dir
或者,作为具有在上下文指定的路径的对象,以及可选的 Dockerfile 和 args:
version: "3.7"
services:
webapp:
build:
context: ./dir
dockerfile: Dockerfile-alternate
args:
buildno: 1
labels:
- "com.example.description=Accounting webapp"
- "com.example.department=Finance"
- "com.example.label-with-empty-value"
target: prod
context
:上下文路径。dockerfile
:指定构建镜像的 Dockerfile 文件名。args
:添加构建参数,这是只能在构建过程中访问的环境变量。labels
:设置构建镜像的标签。target
:多层构建,可以指定构建哪一层。添加或删除容器拥有的宿主机的内核功能。
cap_add:
- ALL # 开启全部权限
cap_drop:
- SYS_PTRACE # 关闭 ptrace权限
为容器指定父 cgroup 组,意味着将继承该组的资源限制。
cgroup_parent: m-executor-abcd
覆盖容器启动的默认命令。
command: ["bundle", "exec", "thin", "-p", "3000"]
指定自定义容器名称,而不是生成的默认名称。
container_name: my-web-container
设置依赖关系。
version: "3.7"
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres
**注意:**web 服务不会等待 redis db 完全启动 之后才启动。
指定与服务的部署和运行有关的配置。只在 swarm 模式下才会有用。
version: "3.7"
services:
redis:
image: redis:alpine
deploy:
mode:replicated
replicas: 6
endpoint_mode: dnsrr
labels:
description: "This redis service label"
resources:
limits:
cpus: '0.50'
memory: 50M
reservations:
cpus: '0.25'
memory: 20M
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
可以选参数:
endpoint_mode:访问集群服务的方式。
endpoint_mode: vip
# Docker 集群服务一个对外的虚拟 ip。所有的请求都会通过这个虚拟 ip 到达集群服务内部的机器。
endpoint_mode: dnsrr
# DNS 轮询(DNSRR)。所有的请求会自动轮询获取到集群 ip 列表中的一个 ip 地址。
labels:在服务上设置标签。可以用容器上的 labels(跟 deploy 同级的配置) 覆盖 deploy 下的 labels。
mode:指定服务提供的模式。
replicated:复制服务,复制指定服务到集群的机器上。
global:全局服务,服务将部署至集群的每个节点。
图解:下图中黄色的方块是 replicated 模式的运行情况,灰色方块是 global 模式的运行情况。
replicas:mode 为 replicated 时,需要使用此参数配置具体运行的节点数量。
resources:配置服务器资源使用的限制,例如上例子,配置 redis 集群运行需要的 cpu 的百分比 和 内存的占用。避免占用资源过高出现异常。
restart_policy:配置如何在退出容器时重新启动容器。
rollback_config:配置在更新失败的情况下应如何回滚服务。
update_config:配置应如何更新服务,对于配置滚动更新很有用。
注:仅支持 V3.4 及更高版本。
指定设备映射列表。
devices:
- "/dev/ttyUSB0:/dev/ttyUSB0"
自定义 DNS 服务器,可以是单个值或列表的多个值。
dns: 8.8.8.8
dns:
- 8.8.8.8
- 9.9.9.9
自定义 DNS 搜索域。可以是单个值或列表。
dns_search: example.com
dns_search:
- dc1.example.com
- dc2.example.com
覆盖容器默认的 entrypoint。
entrypoint: /code/entrypoint.sh
也可以是以下格式:
entrypoint:
- php
- -d
- zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20100525/xdebug.so
- -d
- memory_limit=-1
- vendor/bin/phpunit
从文件添加环境变量。可以是单个值或列表的多个值。
env_file: .env
也可以是列表格式:
env_file:
- ./common.env
- ./apps/web.env
- /opt/secrets.env
添加环境变量。您可以使用数组或字典、任何布尔值,布尔值需要用引号引起来,以确保 YML 解析器不会将其转换为 True 或 False。
environment:
RACK_ENV: development
SHOW: 'true'
暴露端口,但不映射到宿主机,只被连接的服务访问。
仅可以指定内部端口为参数:
expose:
- "3000"
- "8000"
添加主机名映射。类似 docker client --add-host。
extra_hosts:
- "somehost:162.242.195.82"
- "otherhost:50.31.209.229"
以上会在此服务的内部容器中 /etc/hosts 创建一个具有 ip 地址和主机名的映射关系:
162.242.195.82 somehost
50.31.209.229 otherhost
用于检测 docker 服务是否健康运行。
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"] # 设置检测程序
interval: 1m30s # 设置检测间隔
timeout: 10s # 设置检测超时时间
retries: 3 # 设置重试次数
start_period: 40s # 启动后,多少秒开始启动检测程序
指定容器运行的镜像。以下格式都可以:
image: redis
image: ubuntu:14.04
image: tutum/influxdb
image: example-registry.com:4000/postgresql
image: a4bc65fd # 镜像id
服务的日志记录配置。
driver:指定服务容器的日志记录驱动程序,默认值为json-file。有以下三个选项
driver: "json-file"
driver: "syslog"
driver: "none"
仅在 json-file 驱动程序下,可以使用以下参数,限制日志得数量和大小。
logging:
driver: json-file
options:
max-size: "200k" # 单个文件大小为200k
max-file: "10" # 最多10个文件
当达到文件限制上限,会自动删除旧得文件。
syslog 驱动程序下,可以使用 syslog-address 指定日志接收地址。
logging:
driver: syslog
options:
syslog-address: "tcp://192.168.0.42:123"
设置网络模式。
network_mode: "bridge"
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"
network_mode: "container:[container name/id]"
networks
配置容器连接的网络,引用顶级 networks 下的条目 。
services:
some-service:
networks:
some-network:
aliases:
- alias1
other-network:
aliases:
- alias2
networks:
some-network:
# Use a custom driver
driver: custom-driver-1
other-network:
# Use a custom driver which takes special options
driver: custom-driver-2
aliases :同一网络上的其他容器可以使用服务名称或此别名来连接到对应容器的服务。
restart: "no"
restart: always
restart: on-failure
restart: unless-stopped
注:swarm 集群模式,请改用 restart_policy。
存储敏感数据,例如密码:
version: "3.1"
services:
mysql:
image: mysql
environment:
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/my_secret
secrets:
- my_secret
secrets:
my_secret:
file: ./my_secret.txt
修改容器默认的 schema 标签。
security-opt:
- label:user:USER # 设置容器的用户标签
- label:role:ROLE # 设置容器的角色标签
- label:type:TYPE # 设置容器的安全策略标签
- label:level:LEVEL # 设置容器的安全等级标签
指定在容器无法处理 SIGTERM (或者任何 stop_signal 的信号),等待多久后发送 SIGKILL 信号关闭容器。
stop_grace_period: 1s # 等待 1 秒
stop_grace_period: 1m30s # 等待 1 分 30 秒
默认的等待时间是 10 秒。
设置停止容器的替代信号。默认情况下使用 SIGTERM 。
以下示例,使用 SIGUSR1 替代信号 SIGTERM 来停止容器。
stop_signal: SIGUSR1
设置容器中的内核参数,可以使用数组或字典格式。
sysctls:
net.core.somaxconn: 1024
net.ipv4.tcp_syncookies: 0
sysctls:
- net.core.somaxconn=1024
- net.ipv4.tcp_syncookies=0
在容器内安装一个临时文件系统。可以是单个值或列表的多个值。
tmpfs: /run
tmpfs:
- /run
- /tmp
覆盖容器默认的 ulimit。
ulimits:
nproc: 65535
nofile:
soft: 20000
hard: 40000
将主机的数据卷或着文件挂载到容器里。
version: "3.7"
services:
db:
image: postgres:latest
volumes:
- "/localhost/postgres.sock:/var/run/postgres/postgres.sock"
- "/localhost/data:/var/lib/postgresql/data"
创建SpringBoot项目,maven的配置,其余参考:https://blog.csdn.net/weixin_38650898/article/details/105158143
<build>
<finalName>${project.artifactId}finalName>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
<version>${springboot-maven.version}version>
plugin>
<plugin>
<groupId>com.spotifygroupId>
<artifactId>docker-maven-pluginartifactId>
<version>${docker-maven-plugin.version}version>
<configuration>
<imageName>117.50.173.172/${project.build.finalName}:${project.version}imageName>
<dockerDirectory>${project.basedir}/src/main/dockerdockerDirectory>
<dockerHost>117.50.173.172dockerHost>
<resources>
<resource>
<targetPath>/targetPath>
<directory>${project.build.directory}directory>
<include>${project.build.finalName}.jarinclude>
resource>
resources>
<buildArgs>
<JAR_FILE>${project.build.finalName}.jarJAR_FILE>
buildArgs>
<pushImage>truepushImage>
configuration>
plugin>
plugins>
build>