Docker学习
Docker学习
看这个会好一点 https://www.kancloud.cn/docker_practice/docker_practice/469763
1. 基础
1.1 Docker概述
1.1.1 内容介绍
Docker是基于 Go语言开发的,是一个开源项目
快速开始:https://docs.docker.com/get-started/overview/
社区:https://www.docker.com/docker-community
百度百科:https://baike.baidu.com/item/Docker/13344470?fr=aladdin
Docker技术 对比 虚拟机技术:
-
虚拟机虚拟出一整套硬件,运行一个完整的操作系统,资源占用多、启动慢;
-
而容器化技术直接运行在宿主机上,本身没有自己的内核,是轻量级的,而每个容器间是相互隔离的
利用 Docker后,可以一键运行、打包镜像、发布测试,实现应用更快速的交付和部署,实现更便捷的升级和扩、缩容。
1.1.2 基本组成
-
镜像(image):类似模板,用于创建容器服务,通过一个镜像可以创建多个容器
-
容器(container):独立运行一个或多个应用,通过镜像来创建
-
仓库(repository):存放镜像的地方,分为 公有仓库和 私有仓库,类似 Maven仓库
1.2 Docker安装
1.2.1 Docker本体安装
官网教程:https://docs.docker.com/engine/install/ubuntu/
具体步骤:
-
解除安装旧的版本(Uninstall old versions)
旧版本的
docker
应用被称为docker
,docker.io
或者docker-engine
,如果这些已经安装了,就卸载它们sudo apt-get remove docker docker-engine docker.io containerd runc
如果执行
apt
命令反馈这些内容没有被安装也是正常的原有的信息一般默认保存在
/var/lib/docker
目录下,如果想要彻底清楚这些内容,可以继续执行以下指令sudo apt-get purge docker-ce docker-ce-cli containerd.io # Uninstall the Docker Engine, CLI, and Containerd packages sudo rm -rf /var/lib/docker sudo rm -rf /var/lib/containerd # delete all images, containers, and volumes
-
选择支持的存储驱动程序
在
Ubuntu
上,Docker Engine
支持以下 3种驱动:overlay2
,aufs
和btrfs
默认使用
overlay2
,如果需要使用其他的就得手动配置 链接 -
正式安装,可以采用不同的方式进行安装:
- 大部分用户会 设置
Docker repositories
并依据其进行安装,这种最简单 - 少部分用户会下载
DEB package
并且手动安装和手动更新,这种方式适合在断网的情况下进行安装 - 在测试和开发环境下,部分用户会使用 脚本语言安装
- 大部分用户会 设置
-
使用
repositories
进行安装-
设置
repository
sudo apt-get update # 更新 apt sudo apt-get install \ apt-transport-https \ ca-certificates \ curl \ gnupg \ lsb-release # 安装相关的包 curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg # 添加 Docker的依赖 echo \ "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null # 创建一个稳定的 repository, 可以在 stable关键词后添加 nightly 或 test关键字实现特殊的安装
-
实际安装
Docker
sudo apt-get update # 更新 apt索引 sudo apt-get install docker-ce docker-ce-cli containerd.io # 安装最新版本的 docker
-
安装旧版本的
Docker
apt-cache madison docker-ce # 列出可以安装的版本 sudo apt-get install docker-ce=<VERSION_STRING> docker-ce-cli=<VERSION_STRING> containerd.io # 安装指定的版本
-
验证安装成功
sudo docker run hello-world
-
-
使用
DEB package
进行安装-
下载
.deb
文件,前往下载网址,选择你的 Ubuntu的版本(通过lsb_release -a
命令得到),选择/pool/stable
,选择amd64
,armhf
,arm64
或者s390x
并且 下载.deb
文件 -
安装
sudo dpkg -i /path/to/package.deb
-
验证
sudo docker run hello-world
-
1.2.2 配置阿里云的镜像加速
阿里云镜像获取地址:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
登陆后,左侧菜单选中镜像加速器就可以看到你的专属地址了

1.2.3 Docker安装 Nginx
- 搜索镜像
docker search nginx
或在dockerhub
上搜索 - 下载镜像
docker pull nginx
- 后台启动
docker run -d --name nginx01 nginx -p 3344:80
- 本机自测
curl localhost:3344
- 进入容器
docker exec -it nginx01 /bin/bash
- 查看配置
whereis nginx
1.2.4 Docker安装 Tomcat
docker run -it --rm tomcat:9.0
即使没有tomcat:9.0
的镜像,也会自动下载,--rm
表示用完就自动删除- 正常下载镜像
docker pull tomcat:9.0
- 启动运行
docker run -d --name tomcat9 tomcat:9.0 -p 3355:8080
- 进入容器
docker exec -it tomcat9 /bin/bash
- 会发现 linux命令缺少
- 也没有 webapp路径
- 是因为阿里云镜像的原因,默认下载最简版,会剔除很多内容
- 解决办法是将
webapps.dist
路径更名为webapp
,webapps.dist
中有正常的 tomcat内容
1.2.5 Docker安装 ES+Kibana
- 在
dockerhub
搜索elasticsearch
docker run -d --name elasticsearch --net somenetwork -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:tag
,--net
表示指定网络配置,因为elasticsearch
需要暴露多个端口所以会有多个-p
,-e
配置环境参数 因为elasticsearch
比较耗内存所以可以通过参数对其进行限制- 查看容器状态
docker stats
1.2.6 可视化工具
Portainer
提供一个图形化界面管理工具
docker run -d -p 8088:9000 \--restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
1.2.7 安装 MySQL
-
docker pull myql:5.7
下载 -
docker run -d -p 3306:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD="zhao" --name mysql01 mysql:5.7
启动-d: 后台运行
-p: 端口映射
-v: 卷挂载
-e: 环境变量
--name: 容器名称
1.2.8 部署 Redis集群
-
创建 Redis网卡
docker network create myredisnet --subnet 172.38.0.0/16
-
通过脚本创建 6个 redis配置
for port in $(seq 1 6); \do \mkdir -p /mydata/redis/node-${port}/conftouch /mydata/redis/node-${port}/conf/redis.confcat << EOF >/mydata/redis/node-${port}/conf/redis.confport 6379bind 0.0.0.0cluster-enabled yescluster-config-file nodes.confcluster-node-timeout 5000cluster-announce-ip 172.38.0.1${port}cluster-announce-port 6379cluster-announce-bus-port 16379appendonly yesEOFdone
-
逐个运行 redis容器
docker run -p 6371:6379 -p 16371:16379 --name redis-1 \ -v /mydata/redis/node-1/data:/data \ -v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf \ -d --net myredisnet --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
-
集群启动
redis-cli --cluster 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1
1.3 Docker命令
官方文档:https://docs.docker.com/reference/
1.3.1 帮助命令
查看 Docker版本
docker version [OPTIONS]# -f, --format 使用指定的 Go语言模板规格化输出内容 docker version --format '{{.Server.Version}}'# --kubeconfig 指定 K8s的配置文件(已弃用)
查看 Docker系统信息
docker info [OPTIONS]# --format, -f 格式化输出 docker --debug info

获取帮助
docker --helpdocker xxx --help

1.3.2 镜像命令
查看镜像
docker images [OPTIONS] [REPOSITORY[:TAG]]# -a, --all 显示所有(默认会隐藏中间镜像)# -q, --quiet 只显示镜像 id# --digests 显示摘要# --no-trunc 不要截断输出# --format 格式化输出 # -f, --filter 根据条件过滤结果 docker images --filter "dangling=true" docker images --filter "label=com.example.version=1.0"
- REPOSITORY: 镜像的仓库源
- TAG: 镜像的标签
- IMAGE ID: 镜像的 id
- CREATED: 镜像的创建时间
- SIZE: 镜像的大小
搜索镜像
docker search [OPTIONS] TERM# --filter, -f 根据条件过滤结果,以键值对的形式进行过滤,如果有多个条件,就用多个 --filter # --format 格式化输出 docker search --filter is-official=true --filter stars=3 busybox# --limit 限制展示的数量# --no-trunc 不要截断输出 docker search --filter=stars=3 --no-trunc busybox

下载镜像
docker pull [OPTIONS] NAME[:TAG|@DIGEST]# --all-tags, -a 下载所有标记的镜像 docker pull debian:jessie# --disable-content-trust 跳过镜像检查 docker pull myregistry.local:5000/testing/test-image# --platform 如果镜像支持多平台,那么就可以指定平台 docker pull --all-tags fedora# --quiet, -q 压制详细输出# 默认下载最新版本 latest,下载过程中采用分层下载 (docker image的核心处)# docker.io/library/mysql:latest 是真实地址 docker pull mysql 等价于 docker pull docker.io/library/mysql:latest
删除镜像
docker rmi [OPTIONS] IMAGE [IMAGE...]# -f, --force 强制删除镜像 docker rmi fd484f19954f# --no-prune 不删除未指定标签的父镜像 docker rmi test1:latest
1.3.3 容器命令
我们只有在有了镜像后才可以创建容器,所以需要先使用 docker pull
命令下载镜像
新建容器并启动
docker run [OPTIONS] IMAGE [COMMAND] [ARG...] # --add-host 指定一个主机 IP映射 docker run -it centos /bin/bash # --attach, -a 关联到 STDIN, STDOUT 和 STDERR # --dns 指定 dns解析 # --name 指定容器名称,用于区分 # --detach, -d 后台运行容器并且打印容器 ID # -- interactive, -i 保存 STDIN的开启,即使没有设置 --attach # --isolation 容器隔离 # --link 添加到另一个容器的链接 # --publish, -p 发布指定容器端口 -p 主机端口:容器端口, -p 容器端口, -p ip:主机端口:容器端口 # --publish-all, -P 随机发布端口
实际的运行步骤:

列出所有运行中的容器
docker ps [OPTIONS]# --all, -a 展示所有的容器,默认只展示正在运行中的容器# --filter, -f 依据条件,过滤输出结果# --format 格式化输出结果# --last, -n 展示 n个上次创建的容器# --latest, -l 展示最新创建的容器# --no-trunc 不截断输出
退出容器
exit # 容器停止并退出Ctrl + p + q # 容器不停止退出
删除容器
docker rm [OPTIONS] CONTAINER [CONTAINER...]# --force, -f 强制删除正在运行的容器(采用 SIGKILL) docker rm --force redis# --link, -l 移除指定的链接 docker rm --link /webapp/redis# --volumes, -v 删除与容器关联的匿名卷 docker rm $(docker ps --filter status=exited -q)
启动和停止容器的操作
docker start [OPTIONS] CONTAINER [CONTAINER...] # 启动容器docker restart [OPTIONS] CONTAINER [CONTAINER...] # 重启容器docker stop [OPTIONS] CONTAINER [CONTAINER...] # 停止当前正在运行的容器docker kill [OPTIONS] CONTAINER [CONTAINER...] # 强行停止当前正在运行的容器
1.3.4 常用的其他命令
后台启动
docker run -d 镜像名称
存在问题:
docker run -d centos
命令执行后,容器自动停止了。因为 docker
容器在后台运行,必须要有一个前台进程。
docker
发现没有前台应用就会自动停止
查看日志
docker logs [OPTIONS] CONTAINER# --details 展示额外的日志细节# --follow, -f 跟随日志输出# --since 从什么时候开始输出日志# --timestamp, -t 展示时间# --tail, -n 从日志末尾展示行数# --until 展示某个时间点前的日志
查看容器中的进程信息
docker top CONTAINER [ps OPTIONS]
查看镜像的元数据
docker inspect [OPTIONS] NAME|ID [NAME|ID...]# --format, -f 格式化输出 docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $INSTANCE_ID# --size, -s 如果类型是容器的话,就展示所有文件的大小# --type 返回 JSON作为指定的格式
进入当前正在运行的容器
docker exec [OPTIONS] CONTAINER COMMAND [ARG...] # 进入容器后开启一个新的终端,可以进行操作(常用)# --interactive , -i 保持 STDIN开启# --detach, -d 在后台运行容器# --tty, -t 设置一个伪TTY# --env, -e 设置环境变量# --user, -u 设置用户名或 用户 ID# --workdir, -w 设置容器内的工作目录# eg: docker exec -d ubuntu_bash touch /tmp/execWorks# docker exec -it ubuntu_bash bash# docker exec -it -e VAR=1 ubuntu_bash bash# docker exec -it ubuntu_bash pwd# docker exec -it -w /root ubuntu_bash pwd
docker attach [OPTIONS] CONTAINER # 进入容器正在执行的终端,不会启动新的进程# --detach-keys 复写分离的容器的键序列# --no-stdin 不链接 STDIN# --sig-proxy 将所有接收到的信号代理到进程# eg: docker attach topdemo
从容器中拷贝内容到主机
docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-docker cp[OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH# --archive, -a 建造模式,拷贝所有的 uid/gid 的信息# --follow-link, -L 永远拷贝源路径下的符号链接
1.4 Docker镜像
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,包含了某个软件所需的所有内容,包括代码、依赖库、环境变量、配置文件。
所有应用都可以直接打包成 docker
镜像,然后直接跑起来。
1.4.1 Docker镜像加载原理
UnionFS(联合文件系统)
Union文件系统是一种分层、轻量级且高性能的文件系统,它支持对文件系统的修改作为一次提交来逐层地叠加。同时可以将不同目录挂载到同一个虚拟文件系统下。
Union文件系统是 Docker镜像的基础,镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次可以同时加载多个文件系统,但是从外面看来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包涵所有底层文件和目录。
Docker镜像加载原理
Docker
镜像实际上就是由 UnionFS
文件系统组成的。
bootfs(boot file system)
主要包含 bootloader
和 kernel
;bootloader
主要是引导加载 kernel
,Linux刚启动的时候会加载 bootfs
文件系统,在 Docker
镜像的最底层是 bootfs
。类似典型的 Linex/Unix
系统,包含 boot
加载器和内核,当 boot
加载完成之后整个内核就在内存中了,此时内存的使用权已由 bootfs
交给了内核,此时系统也会卸载 bootfs
rootfs(root file system)
在 bootfs
之上,包含的就是最典型的 Linux
系统中的 /dev, /proc, /bin, /etc
等标准目录和文件。rootfs
就是各种不同的操作系统发行版,比如 Ubuntu, CentOS
等。
对于一个精简的 OS,rootfs
可以很小,只需要包含最基本的命令、工具和程序库就可以了,因为底层直接使用 Host的 kernel,自己只需要提供 rootfs
就可以了。由此可见,对于不同的 Linux发行版本,bootfs
是基本一致的,rootfs
会有差异,因此不同的发行版可以共用 bootfs
。
1.4.2 分层理解
Docker镜像采用分层结构,方便实现资源的共享。
多个镜像都从相同的基础镜像构建而来,那么宿主机只需要在磁盘上保留一份基础镜像即可,同时内存中也只需要加载一份基础镜像,这样就可以为所有的容器服务了,而且镜像的每一层都是可以被共享的。
查看镜像分层命令
docker image inspect [OPTIONS] IMAGE [IMAGE...]# --format, -f 格式化输出
因此,所有的 Docker镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上,再创建新的镜像层。
如:加入基于 Ubuntu 20.04 LTS创建一个新的镜像,这就是镜像的第一层;如果在该镜像中添加 Python包,就会在基础镜像层之上再创建第二个镜像层;如果再添加一个安全补丁,就会创建第三个镜像层。
在添加额外的镜像层的同时,镜像始终保持当前的所有镜像组合。
此外 Docker镜像都是只读的,当容器启动的时候,一个新的可写层会被加载到镜像的顶部,这一层就是容器层。
1.4.3 提交自己的镜像
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]# --author, -a 标注作者 # --change, -c 将对 dockerfile的简介应用到创建的新的镜像中# --message, -m 提交附带的信息 # --pause, -p 在提交的过程中暂停容器# eg: docker commit --change='CMD ["apachectl", "-DFOREGROUND"]' -c "EXPOSE 80" c3f279d17e0a svendowideit/testimage:version4# docker commit c3f279d17e0a svendowideit/testimage:version3# docker commit --change "ENV DEBUG=true" c3f279d17e0a svendowideit/testimage:version3
1.5 容器数据卷
将 Docker容器中产生的数据同步到本地,实现数据的持久化,即使在容器删除后,也可以保留数据。
容器数据卷技术,就可以实现 目录的挂载,将容器内的目录挂载到宿主机上,实现 容器的持久化和同步操作 及 容器间的数据共享。
1.5.1 使用数据卷
使用命令挂载
docker run -v 主机目录:容器目录 # eg: docker run -v `pwd`:`pwd` -i -t ubuntu pwd# docker run --read-only -v /icanwrite busybox touch /icanwrite/here# docker run -t -i -v /var/run/docker.sock:/var/run/docker.sock -v /path/to/static-docker-binary:/usr/bin/docker busybox sh# docker run -t -i --mount type=bind,src=/data,dst=/data busybox sh
在宿主机中对文件的修改,都会同步到容器中,无论容器是否处于开启状态。
1.5.2 具名挂载和匿名挂载
匿名挂载
docker run -d -P -v /etc/nginx --name nginx01 nginx# -v后只标识了容器中的目录,没有标识宿主机中的目录# 默认会挂载到 /var/lib/docker/volumes/xxx
具名挂载
docker run -d -P -v /jvming:/etc/nginx --name nginx02 nginxdocker run -d -P -v /jvming:/etc/nginx:ro --name nginx02 nginx3# -v后既标识了容器目录也标识了宿主机目录# 如果此时 /jvming路径没有加 根号,那么也会挂载到 /var/lib/docker/volumes/jvming下# ro表示只有宿主机能修改,容器对该路径没有写权限# rw表示容器可读可写
1.6 DockerFile
1.6.1 Dockerfile介绍
Dockerfile就是 Docker镜像的构建文件,通过 Dockerfile脚本文件生成镜像。
A
Dockerfile
is a text document that contains all the commands a user could call on the command line to assemble an image. Usingdocker build
users can create an automated build that executes several command-line instructions in succession.
构建步骤:
- 编写一个 dockerfile文件
- docker build构建成为一个镜像
- docker push发布镜像(dockerhub, 阿里云镜像仓库)
比如 centos
:
FROM scratchADD centos-8-x86_64.tar.xz /LABEL org.label-schema.schema-version="1.0" \ org.label-schema.name="CentOS Base Image" \ org.label-schema.vendor="CentOS"\ org.label-schema.license="GPLv2"\ org.label-schema.build-date="20210915" CMD ["/bin/bash"]
docker build [OPTIONS] PATH | URL | -# --build-arg 设置编译时的变量# --cache-from 作为# --compress 使用 gzip进行压缩# --file, -f Dockerfile的名称(默认是 PATH/Dockerfile)# --force-rm 总是移除中间的容器# --iidfile 将镜像 ID写入文件中# --isolation 容器的隔离级别# --network 设置编译运行时的网络模式# --pull 总是尝试下载最新的镜像# --rm 成功编译后移除中间容器#
1.6.2 构建 Dockerfile
编写要求:
- 每个保留关键字(指令)都必须是大写的
- 执行顺序从上到下
- # 表示注释
- 每一个指令都会创建提交一个新的镜像层,并提交
- dockerfile是开发人员编写的,发布项目时需要编写 dockerfile文件
常用指令:
- FROM:指定基础镜像
- MAINTAINER:指定维护者的信息,姓名+邮箱
- RUN:构建时需要运行的命令,会自动执行
- ADD:构建时需要添加的文件,会自动解压
- WORKDIR:镜像的工作目录
- VOLUME:设置挂载卷的位置,挂载主机目录
- EXPOSE:对外暴露的端口
- CMD:容器启动后运行的命令,在 docker run命令中额外添加 参数时会覆盖 cmd中的内容
- ENTRYPOINT:类似 CMD,在 docker run命令中额外添加的参数会追加到 cmd中的内容之后
- ONBUILD:被继承时触发的指令
- COPY:类似 ADD,将文件拷贝到镜像中
- ENV:构建时设置环境变量
# 构建自己的 CENTOS Dockerfile文件FROM centosMAINTAINER oliq<yuanchuziwen@qq.com>ENV MYPATH /usr/localWORKDIR $MYPATHRUN yum -y install vimRUN yum -y install net-toolsEXPOSE 80CMD echo $MYPATHCMD /bin/bash# 使用 docker build命令构建docker build -f mycentos -t mycentos:1.0 .# 测试运行docker run -it --name myos mycentos:1.0
# 构建自己的 tomcat DockerfileFROM centosMAINTAINER oliq<yuanchuziwen@qq.com>COPY readme.txt /usr/local/readme.txtADD jdk-8u11-linux-x64.tar.gz /usr/localADD apache-tomcat-9.0.22.tar.gz /usr/localRUN yum -y install vimENV MYPATH /usr/localWORKDIR $MYPATHENV JAVA_HOME /usr/local/jdk1.8.0_11ENV CLASSPATH .:$JAVA_HOME/lib:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/rt.jarENV CATALINA_HOME /usr/local/apache-tomcat-9.0.22ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.22ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/binEXPOSE 8080CMD $CATALINA_HOME/bin/startup.sh && tail -F $CATALINA_HOME/logs/catalina.out# 构建镜像docker build -t mytomcat # 如果把 dockerfile文件命名为 Dockerfile,那么就可以不用 -f 指定名称,可以自动识别# 测试运行docker run -d -p 9090:8080 --name mycat mytomcat \ -v /home/mytomcat/webapps:/usr/local/apache-tomcat-9.0.22/webapps \ -v /home/mytomcat/log:/usr/local/apache-tomcat-9.0.22/logs
1.6.3 发布镜像 Dockerhub
-
在 Dockerhub上注册自己的账号
-
在服务器上登陆
docker login [OPTIONS] [SERVER]# --password, -p 密码# --password-stdin 从标准输入中获取密码# --username. -u 用户名# 如果想要登陆一个私人的路径,就需要指定服务器的名称 docker login localhost:8080# 使用 STDIN输入密码 cat ~/my_password.txt | docker login --username foo --password-stdin# Docker引擎能本地保存用户的凭据
-
将镜像发布上去
docker push [OPTIONS] NAME[:TAG] # --all-tags, -a 将所有 tag的镜像都 push上去docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]docker image tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG] # Create a tag TARGET_IMAGE that refers to SOURCE_IMAGEdocker image push [OPTIONS] NAME[:TAG]# eg: docker container commit c16378f943fe rhel-httpd:latest# docker image tag rhel-httpd:latest registry-host:5000/myadmin/rhel-httpd:latest# docker image push registry-host:5000/myadmin/rhel-httpd:latest
1.6.4 发布镜像到阿里云
-
登陆阿里云
-
创建命名空间
-
创建镜像仓库
1.7 Docker网络原理
1.7.1 Docker0
宿主机 每启动一个 Docker容器,就会给每个容器都分配一个 IP;
并且安装 Docker后会创建一个 Docker0网卡,采用桥接模式;
并且每一个新的容器的 IP都会注册到宿主机中,采用 evth-pair技术;
并且容器之间、容器和宿主机之间也可以相互 ping通,不同容器之间网络连接都通过宿主机的 docker0
网卡进行交互
1.7.2 link
将两个容器的网络进行连接,实现依据容器名的 ping通
docker run -d -P --name tomcat03 --link tomcat02 tomcat # 在两个容器的网络之间创建连接docker exec -it tomcat03 ping tomcat02 # 可以成功
实际是修改了容器中的 /etc/hosts文件内容
1.7.3 自定义网络
网络模式
- bridge: 桥接
- null:不配置网络
- host:和宿主机共享
- container:容器网络连通
创建网络
docker network create [OPTIONS] NETWORK# --attachable 开启手动容器连接# --config-from 从哪里拷贝配置# --config-only 创建一个只能配置的网络# --driver, -d 网络驱动(默认是桥接)# --gateway 设置网关# --ingress 创建群路由网状网络# --internal 限制对网络的外部访问# --ip-range 指定容器 ip选择的范围# --ipam-driver 设置 IP地址管理驱动程序# --label 设置网络的元信息#eg: docker run -itd --network=mynet busybox# docker network create --driver=bridge --subnet=192.168.0.0/16 br0# docker network create \# --driver=bridge \# --subnet=172.28.0.0/16 \# --ip-range=172.28.5.0/24 \# --gateway=172.28.5.254 \# br0# docker network create -d overlay \# --subnet=192.168.10.0/25 \# --subnet=192.168.20.0/25 \# --gateway=192.168.10.100 \# --gateway=192.168.20.100 \# --aux-address="my-router=192.168.10.5" --aux-address="my-switch=192.168.10.6" \# --aux-address="my-printer=192.168.20.5" --aux-address="my-nas=192.168.20.6" \# my-multihost-network
使用自定义网络的好处:
- 不同集群使用不同的网络,保证了集群的安全和健康
docker network connect [OPTIONS] NETWORK CONTAINER# --alias 为容器添加网络的别名# --driver-opt 网络驱动配置# --ip IPV4地址# --ip6 IPV6地址# --link 添加对另一个容器的连接# eg: docker network connect multi-host-network container1# docker run -itd --network=multi-host-network busybox# docker network connect --ip 10.10.36.122 multi-host-network container2# docker network connect --link container1:c1 multi-host-network container2
1.8 IDEA 整合 Docker
-
创建 SpringBoot项目
-
编写好测试用的 Controller
/** * @author :OliQ * @date :Created on 2021/9/21 13:56 */@RestControllerpublic class DockerController { @RequestMapping("/docker") public String hello() { return "hello docker"; }}
-
mvn package
-
IDEA 的插件市场中 下载 Docker plugin
-
编写 Dockerfile
FROM java:8COPY *.jar /app.jarCMD ["--server.port=8080"]EXPOSE 8080ENTRYPOINT ["java", "-jar", "/app.jar"]
-
将 jar包 和 Dockerfile传到 虚拟机
-
docker build
-
docker run
2. 进阶
2.1 Docker Compose
2.1.1 Compose介绍
使用 Docker Compose
可以轻松进行高效的容器管理,定义运行多个容器
Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration. To learn more about all the features of Compose, see the list of features.
Compose works in all environments: production, staging, development, testing, as well as CI workflows. You can learn more about each case in Common Use Cases.
Using Compose is basically a three-step process:
- Define your app’s environment with a
Dockerfile
so it can be reproduced anywhere.- Define the services that make up your app in
docker-compose.yml
so they can be run together in an isolated environment.- Run
docker compose up
and the Docker compose command starts and runs your entire app. You can alternatively rundocker-compose up
using the docker-compose binary.
Compose
是 Docker
官方的另一个开源项目,需要额外安装
一个 docker-compose.yml
示例:
version: "3.9" # optional since v1.27.0services: web: build: . ports: - "5000:5000" volumes: - .:/code - logvolume01:/var/log links: - redis redis: image: redisvolumes: logvolume01: {}
2.1.2 Compose安装
Docker Compose
依赖 Docker Engine
,所以实现要保证已经成功安装了本地的或远程的 Docker Engine
-
下载当前最新的
Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
-
为下载的二进制文件赋予可执行权限
sudo chmod +x /usr/local/bin/docker-compose
-
测试安装
docker-compose --version
-
如果安装以后该命令无效,也可能是因为路径的问题,可以自己添加一个软连接
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose # 比如
-
如果要卸载
Dcoker Compose
sudo rm /usr/local/bin/docker-compose # 如果安装了 curl的话pip uninstall docker-compose # 如果安装了 pip的话
2.1.3 Compose初体验
https://docs.docker.com/compose/gettingstarted/
2.1.4 yaml文件编写规则
https://docs.docker.com/compose/compose-file/compose-file-v3/
# 版本号version: "3.9" # 服务services: # 第一个服务 webapp: # 对第一个服务的配置 build: . ports: - "8080:8080" volumes: - .:/code # 第二个服务 redis: # 其他配置(网络、全局规则)configs:networks:
2.1.5 搭建 WordPress博客
https://docs.docker.com/samples/wordpress/
2.2 Docker Swarm
用于集群部署 Docker。多个 Docker节点组成一个网络集群。
2.2.1 搭建集群
-
在主节点处执行命令
docker swarm init --advertise-addr <MANAGER-IP>
-
在主节点处获取加入Swarm的 token
docker swarm join-token workerdocker swarm join-token manager
-
在从节点中或者其他主节点中执行 swarm join
docker swarm join \ --token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c \ 192.168.99.100:2377
-
在主节点处查看集群状态
docker node lsdocker info
2.2.2 Raft一致性协议
集群中主节点个数必须大于等于 3个
2.2.3 Swarm弹性机制
在集群状态下,容器视作服务,一个服务可以有多个副本。
docker service create [OPTIONS] IMAGE [COMMAND] [ARG...]# eg: docker service create --name redis redis:3.0.6# docker service create --mode global --name redis2 redis:3.0.6# docker service create \# --with-registry-auth \# --name my_service \# registry.example.com/acme/my_image:latestdocker service update [OPTIONS] SERVICE# eg: docker service update \# --mount-add type=volume,source=other-volume,target=/somewhere-else \ # myservice # docker service update --mount-rm /somewhere myservice docker service scale SERVICE=REPLICAS [SERVICE=REPLICAS...] # eg: docker service scale frontend=50
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!