Docker(一)理论知识
前言
一直在用docker,没系统的捋一遍。这准备简历,所以重新弄一遍,本篇只涵盖使用的知识。后面会有实战部署笔记和底层技术。
什么是Docker
基本概念
流程:研发镜像(image)->上传到镜像仓库(Registry)->通过Docker引擎down下来->运行down下来的容器(container)
Docker是一个容器引擎,用于管理容器的声明周期
容器:包含用于运行一个软件的环境(包含了目标软件运行所需的所有依赖)和需要运行的软件,镜像的实例
镜像:容器的安装包,必须先有镜像,才能运行容器
仓库:用于存放镜像,对镜像进行统一管理
打个比方:仓库是软件商店,镜像是软件安装包,容器是安装成功后的软件
Docker与虚拟机对比理解
Docker的架构
C/S架构:Client客户端,Server服务端
Docker Client
Docker客户端,向服务端发起请求,比如下载镜像,管理容器声明周期
Docker Daemon
Docker的后台守护程序,包含:
Docker Server:服务端,接收请求
Engine:容器引擎,负责执行任务
Docker Registry
镜像仓库
Docker入门
基础命令
镜像
docker search jdk 用于查找jdk镜像的版本
docker pull openjdk:11 把jdk的镜像拉取到本地,冒号用于指定版本
docker images 查看本地镜像
docker rmi 123456 删除id号为123456的本地镜像
容器
docker ps 查看当前运行的容器
docker ps -a 查看当前所有容器名称
docker run [容器名称] 运行目标名称的容器,默认前台运行
前台运行vs后台运行
前台运行:启动容器时,将容器的输入输出与宿主机的终端相连,用户可以直接在当前终端与容器进行交互
后台运行:容器在后台独立运行,不与宿主机的终端直接关联。容器启动后,命令行会立即返回,你可以继续在宿主机终端执行其他操作
docker run -d -p 80:81 [容器名称] 运行目标名称的容器,-d指定后台运行,-p指定容器监听主机80端口,若有请求则转发到容器内81端口
因为资源隔离,所以容器内外网络不互通,eg内外都有80port,所以用到-p参数标识路由转发
docker run -d -P [容器名称] -P 参数的作用是让 Docker 自动在宿主机上选取一个可用的端口,并将其映射到容器内暴露(EXPOSE)的端口上,暴露端口指的是在Dockerfile里通过EXPOSE命令声明的容器内监听的端口
docker rm 123456 删除id为123456的停止的容器,id不一定为123456,只要123456能定位到一个唯一id的容器即可
docker rm -f 123456 强制删除id为123456的容器,无论是否运行中
docker stop 123456 停止id为123465的容器
docker start 123456 启动id为123456的容器
docker run -d -name cont01 [容器名称] 启动目标容器并指定名称为cont01,后续操作可用名字代替id
docker run --rm [容器名称] 运行容器,rm标识该容器停止后会自动删除
docker run -d --restart on-failure:3 [容器名称] --restart标识重启策略,默认不重启;on-failure失败时重启,可以加上:3表示第三次部署失败就不重启了;always表示只要已关闭就自动重启
docker run -d -P -e JAVA_ENV=dev -e JAVA_VM=G1 nginx 启动 nginx 容器时设置 JAVA_ENV=dev 和 JAVA_VM=G1 这两个环境变量
docker inspect NAME|ID 查看docker对象的详细信息
docker exec -it cont01 env exec命令是指定cont01容器,基于容器内终端(it),来执行env命令(显示环境变量)
-m 8m 限制内存最大为8mb,--cpus 1 限制cpu最多用一个
docker logs cont01 输出cont01容器的所有日志
docker exec -it cont01 bash 进入容器cont01内部,并使用bash
Docker进阶
数据卷Volume
基本概念
是容器外部的独立存储空间,即使容器被删除,数据卷仍会保留。
同一个数据卷可被多个容器同时挂载,所有容器对卷内数据的读写操作是实时同步的
容器可通过数据卷直接访问宿主机文件系统,高性能
绑定方式
匿名绑定
docker run -v /app/data nginxDocker 自动创建无名称卷,存储路径为宿主机的 Docker 数据目录/volumes/随机哈希
容器删除后卷仍然存在,需要手动清理
容器启动时加
--rm,停止后卷会自动删除
具名绑定
docker run -d -v my-named-volume:/app/data my-image 不关心存放的位置,只想持久化存储一些内容
有自定义的名字,能够轻松识别和管理卷
除非手动删除,否则会一直存在
Bind Mount
把宿主机的目录直接映射到容器内的目录
docker run -v /host/path:/container/path my-image /host/path 是宿主机上的路径,/container/path 是容器内的挂载路径
只要宿主机上的文件或目录存在,即使容器被删除,数据也不会丢失
可以挂载宿主机上的任意文件或目录,不受 Docker 卷存储管理的限制
宿主机和容器内的文件修改会实时同步
数据卷管理
1 | Commands: |
网络Network
基本概念
是什么
是Docker对容器网络隔离的一项技术,提供了多种不同模式供用户使用,选择不同的网络模式来实现容器网络的互通以及的隔离
需求
容器间的网络隔离
实现部分容器之间的网络隔离
管理多个子网下的容器ip
作用
提供了多种模式,可以定制化的为每个容器制定不同的网络
自定义网络模式,划分不同的子网|网关|dns等配置
实现网络互通
实现不同子网之间的网络互通
基于容器名(主机名)的方式在网络内访问
网络模式
bridge桥接模式(默认模式)
在主机中创建一个Docker0的网桥,在Docker0创建一对虚拟网卡,有一半在主机上vethxxx,有一半在容器内eth0
host模式
容器不再拥有自己的网络空间,而是直接与主机共享网络空间,基于该模式创建的容器对应的ip实际及时与主机为同一个子网,同一个网段
none模式
Docker会拥有自己的网络空间,不与主机共享,在这个网络模式下的容器,不会被分配网卡&ip&路由等相关信息
完全隔离,与外部任何机器都无网络访问,只与自己的io,本地网络127.0.0.1
绝对安全
Container模式
不会创建自己的网络,与其他容器共享网络空间,直接使用指定容器的ip/端口
自定义网络模式(推荐)
不适用Docker自带的网络模式,而是自己定制化自己持有的网络模式
命令:docker network COMMOND
Manage networks
Commands:
connect Connect a container to a network
create Create a network
disconnect Disconnect a container from a network
inspect Display detailed information on one or more networks
ls List networks
prune Remove all unused networks
rm Remove one or more networks
为什么自定义网路中的容器能通过容器名ping通,但是bridge模式不行
在Docker自定义网络中,DNS被深度集成以实现容器间的自动服务发现。当容器加入自定义网络时,Docker会将其容器名和ip地址注册到DNS服务器
bridge模式不嵌入DNS
不同模式下的链接
docker network connect wolfcode net1
Dockerfile文件
基本概念
是什么
构建镜像用的
Docker为我们提供的一个用于自定义构建镜像的一个配置文件:描述如何构建一个对象利用
Docker提供的build命令,指定Dockerfile文件,就可以按照配置的内容将镜像构建出来
为什么需要
作为开发者,需要将自己开发好的项目打包成
Docker镜像,便于后面直接作为Docker容器运行作为运维人员,需要构建更精简的基础设施服务镜像,满足公司的需求以及尽可能减少冗余的功能占用过多的资源
能做什么
可以自定义镜像内容
构建公共基础镜像减少其他镜像配置
开源程序快速部署
实现企业内容项目快速交付
常用指令
FROM
指定以什么镜像为基础镜像,在改进项的基础之上构建新的镜像
如果不想以任何镜像为基础:FROM scratch
语法:
FROM <image>FROM <image>:<tag>FRom <image>:<digest>
以上三种写法,后两者为指定具体版本,第一种则使用latest也就是最新版
MAINTAINER
指定镜像的维护者
MAINTAINER John Doe <johndoe@example.com>
MAINTAINER 指令指定了镜像的维护者是 John Doe,其邮箱为 johndoe@example.com
Docker官方现已弃用MAINTAINER命令,他的功能可以用LABEL指令更灵活的实现
LABEL
为镜像|容器|卷添加元数据
语法
LABEL <key>=<value> <key>=<value> <key>=<value> ...
可以在一条 LABEL 指令中定义多个键值对,也能使用多条 LABEL 指令。键值对之间用空格分隔,键和值之间用等号连接
eg
LABEL maintainer="John Doe <johndoe@example.com>"
ENV
设置容器的环境变量,可以设置多个
语法:
ENV <key> <value>ENV <key>=<value> <key>=<value>...
RUN
RUN 指令在构建镜像期间执行,在 Dockerfile 中可以有多个 RUN 指令,每个 RUN 指令都会在镜像中创建一个新的层。为了减少镜像的层数和体积,建议将相关的命令组合在一个 RUN 指令中执行
语法:
RUN <command>RUN ["executable","param1","param2"]
第一种写法直接写shell脚本即可
第二种写法类似于函数调用,第一个参数为可执行文件,后面的都是参数
eg
RUN ["/bin/bash", "-c", "echo hello"]
-c 后面跟着的 "echo hello" 会被当作 shell 命令来执行,所以直接调用 /bin/bash 来执行 echo hello 命令
ADD
复制命令,把src的文件复制到镜像的dest位置(从主机复制到容器)
语法:
ADD <src> <dest>ADD ["<src>","<dest>"
WORKDIR
设置并cd到容器中的工作目录,如果该目录不存在则自动创建。
语法:
WORKDIR /app
在根目录下创建app目录
VOLUME
设置挂载目录,可以将主机中的指定目录挂载到容器中
语法:
VOLUME ["<dir>"]VOLUME <dir>VOLUME <dir> <dir>
EXPOSE
设置容器启动后要暴露的端口(容器在运行时会监听的网络端口)
语法:
EXPOSE <port> [<port>/<protocol> ...]
<port>表示容器要监听的端口号,<protocol>是可选参数,用于指定端口使用的协议,默认值为 tcp,也可以设置为 udp
注意:EXPOSE只是暴露端口,并没有与主机的端口形成映射。映射行为是在容器run的时候加-p参数实现的
CMD
CMD 指令在容器启动时执行,在 Dockerfile 中只能有一个 CMD 指令,若有多个 CMD 指令,只有最后一个会生效
语法:
CMD echo "Hello world!"CMD ["echo","Hello world!"]
ENTRYPOINT
用来设置容器启动时要执行的命令,并且这个命令不能被 docker run 后面的参数直接覆盖,它提供了一种固定容器启动行为的方式,常用于设置容器的主命令
CMD和ENTRYPOINT的区别
单独使用
ENTRYPOINT,docker run后面添加的参数会被当作ENTRYPOINT命令的参数单独使用
CMD,如果docker run后面添加了其他命令,CMD指定的命令会被覆盖当
ENTRYPOINT和CMD结合使用时,CMD提供的参数会作为ENTRYPOINT命令的默认参数,若docker run后面添加了参数,这些参数会替换CMD的默认参数
构建镜像
commit
基于一个现有的容器,构建一个新的镜像(image)
定制化操作不方便!
build
自己构建两个镜像练练手
eg
# 使用Python 3.9作为基础镜像
FROM python:3.9-slim
# 设置工作目录
WORKDIR /app
# 复制当前目录下的所有文件到工作目录
COPY . /app
# 安装应用所需的依赖
RUN pip install --no-cache-dir -r requirements.txt
# 暴露应用运行的端口
EXPOSE 5000
# 设置环境变量
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
# 定义容器启动时执行的命令
CMD ["flask", "run"]
仓库Registry
用于管理
Docker的镜像快速交付
便于镜像的重复利用
常见仓库
Docker HubAliyunNexusHarbor
容器编排
这块没啥理论上的,实际部署一下就会了
针对容器声明周期的管理,对容器声明周期进行更快速方便的方式进行管理
依赖管理,当一个容器必须在另一个容器运行完成后才能运行时,就需要进行依赖管理
副本数控制,容器有时候也需要集群,快速对容器集群进行弹性伸缩
配置共享,通过配置文件统一描述需要运行的服务相关信息,自动化的解析配置内容,并构建对应服务
更简单的使用容器
Docker Compose(单机)
基于构建好的镜像来创建和管理多个容器
需求:在一台机器上部署多个容器
Docker-Compose可以高效便捷的管理单机上运行的所有容器,通过yaml配置文件的方式完成之前执行docker run命令所设置的所有参数。
服务services
需要运行的容器配置,可以理解为原先用docker run命令后面跟的一系列配置信息,都配在这里面
网络networks
docker-compose公共自定义网络管理,配置好以后,可以直接在services中引用该网络配置,这个配置可以多个services使用
数据卷volums
docker-compose下的统一数据卷管理,可以给多个services使用
Swarm(分布式)
做docker的公司写的,与k8s竞争
Portainer可视化工具
很推荐啊,天天只在命令行docker来docker去,快docker抑郁了
PS C:\Users\flypiggy> docker --version
Docker version 28.0.1, build 068a01e
PS C:\Users\flypiggy> docker volume create portainer_data
portainer_data
PS C:\Users\flypiggy> docker run -d -p 9000:9000 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce
Unable to find image 'portainer/portainer-ce:latest' locally
latest: Pulling from portainer/portainer-ce
e2e06b27b87e: Pull complete
1fed1531b45b: Pull complete
04de093ad5ed: Pull complete
86a7cce72d42: Pull complete
e09df2601140: Pull complete
eae3ebf29ea8: Pull complete
c12aa3fbd31a: Pull complete
f111bda3f9a6: Pull complete
81021110ed01: Pull complete
4f4fb700ef54: Pull complete
Digest: sha256:7f10a26bfdda3fc58295ea09b860117ecd86a642d66fb94ce1f27a4c221d4649
Status: Downloaded newer image for portainer/portainer-ce:latest
61cbab51c68ba3134921a2d7beb1ce320716682cac10f2094c0f08f3ae01c4d8








