Learning docker
Learning Docker
背景概要
- $2005 \Rightarrow 2015$:Cloud(云技术)时代,为Container打下基础,带来土壤
- $2015 \Rightarrow\ Now$:Container(容器)时代,最出名的代表就是Docker
Container的概念
- 简述:复制了一遍你的运行环境,别人拿过来能直接跑对应的程序,不用再折腾配环境这种司马事情了
安装
Windows
- 
Docker官网,下载桌面版 
- 
注意安装前开启 BIOS虚拟化
- 
如果开启 wsl2能省去很多事情(
- 
最终验证:命令行运行 
Linux
- get.docker.com
- 下载后跑脚本即可
 
|  |  | 
- 最终验证:命令行运行
|  |  | 
创建与操作容器
- 镜像(image):包含OS和应用的对象,类似虚拟机的模板(装系统用的那种,比如系统盘!),只能读
- 容器(container):和镜像几乎一样,但是比镜像多了一层Read-Write Layer,这样就可以写了
创建容器
- 
先检测 Client和Server是否都启动docker version(docker桌面版要挂着)
- 
创建命令 docker container run <image name>(容器里面是对应的image name)
- 
例子 
|  |  | 
- Docker Hub:官方镜像社区,里面有大量制作好的镜像(创建容器就是上上面先拉取镜像,然后制作成镜像装在- Docker里面)
查看正在运行的容器
|  |  | 
查看所有容器
|  |  | 
启动容器
|  |  | 
停止正在运行的容器
|  |  | 
删除容器
|  |  | 
- 上面的命令可以省略container不过为了强调container平时不做删除(与image区分)
多容器操作
- 一次停掉多个容器的思路
- 查看所有容器的id
 
- 查看所有容器的
|  |  | 
- 然后利用指令组合
|  |  | 
- 
命令组合的思路可以用到很多 docker需要批量处理的情况下
- 
删除正在运行的容器会报错! - 强制删除:docker container rm <id> -f
 
- 强制删除:
端口映射与主/被动模式
端口映射
- 目的:让容器能过在外网访问到
|  |  | 
- 检测是否启动
- 浏览器中访问127.0.0.1:80
 
- 浏览器中访问
主动模式(默认)
- 
相当于命令行里面的子进程,会打印日志信息 
- 
容易被误操作停掉(关掉命令行或者不小心 Ctrl + c)
- 
调试时使用 
被动模式(后台运行)
|  |  | 
- 
不再打印日志 
- 
不会因为关掉命令行而终止 
- 
使用 docker container ls就能查看到
转换成主动模式
|  |  | 
detached模式下查看日志的方法
|  |  | 
- 跟踪日志(变成终端的子进程,不会自动停止,Ctrl + C终止)
|  |  | 
交互模式
- 先启动容器
|  |  | 
- 进入容器终端
|  |  | 
 
    - exit退出后容器也会关闭
如何exit后不关闭容器
- 使用detached模式
|  |  | 
|  |  | 
镜像获取/Image Registry
获取镜像的三个途径
- 
pull from registry- 常见registry:Docker Hub,quay.io
 
- 常见
- 
Dockerfile (online)
- 
自有文件导入 (offline)
- 
使用官方认证的镜像:安全 
镜像的拉取和删除
- 拉取:官网找命令
 
    |  |  | 
- 新版本可以加上image前缀(强调,和container作区分)
|  |  | 
- 实际效果(默认最新版,如果要其他版本去tag里面找对应版本的命令)
 
    查看现有镜像
|  |  | 
查看镜像详细信息
|  |  | 
- 关注对应的OS和架构
删除镜像
|  |  | 
image的导入/导出
- 
image导出
- 
在要保存的位置执行 1 2 3docker image save <image name>:<tag> -o <new image name>.image # example docker image save busybox:latest -o mybusybox.image
- 
image导入
- 
也是在对应镜像的位置 1 2 3docker image load -i <load image name>.image # 例子 docker image load -i .\mybusybox.image
Dockerfile
- Dockerfile:使用组合映像命令的文本文档,用于- DIY自己的- image
- 例子ubuntu执行python程序
- hello.py
|  |  | 
- Dockerfile
|  |  | 
- 
FROM:引入系统
- 
RUN:安装环境(build的时候执行)
- 
ADD:将本机文件加入到image中,默认加入到image的根目录
- 
CMD:相当于使用shell命令(build后执行)
构建Dockerfile
|  |  | 
- 
将镜像上传到 Docker Hub上面- 规则:<Hub name>/<image name>
 
- 规则:
- 
更改名字使其能够上传 
|  |  | 
- 通过id/name上传
|  |  | 
FROM语法
- 
引入基础镜像 
- 
三个基本原则 - 
官方镜像优于非官方镜像(安全性) 
- 
固定版本的 Tag,而不是每次都使用latest(稳定)
- 
功能满足的情况下使用体积小的镜像(让自己的镜像变得简洁) 
 
- 
RUN命令
- 
接 shell命令
- 
坑 
|  |  | 
- 
不建议这么写:每个 RUN都会生成一个新的“层”,打包的体积会变大- rm -rf的命令也会无效:上面的文件已经嵌入到上一层里面了
 
- 
正确写法:改成 && \的组合
|  |  | 
- 变成了只有一层,体积会变小
文件操作
- 
COPY1COPY index.js /app/index.js- 将当前目录下的index.js文件拷贝到镜像中的/app/index.js(镜像中没有对应文件会自动创建)
 
- 将当前目录下的
- 
ADD- 基本效果和COPY相同,但是会自动解压缩
 1ADD index.tar /app/- 运行后会发现容器/app/文件夹里面就是index.tar里面被压缩文件的内容
 
- 基本效果和
- 
WORKDIR- 切换目录
 1 2 3FROM ubuntu:20.04 WORKDIR /app COPY hello.py hello.py- 和上面效果相同,最后文件都在/app这个目录下
- 相当于cd
 
- 
变量声明(类似宏定义,使得代码更简介) 
- 
例子 
|  |  | 
ENV
- ENV key=value(中间不要加空格,有坑)
- 使用value:${key}$
- 效果
|  |  | 
ARG
- 语法和ENV一样- 和ENV不同的地方- ENV声明的变量会带入镜像内部(比如- Linux的- env命令,或者直接- echo $key也能打出来),而- ARG不会
- ARG可以动态添加
 
 
- 和
|  |  | 
CMD
- 
三个基本原则 - 容器启动时默认执行的命令
- 如果没有,对应拉取的官方镜像会有默认的CMD,比如ubuntu会自带CMD["bash"]
 
- 如果没有,对应拉取的官方镜像会有默认的
- 如果启动容器所用的命令是docker container run {commandline}- 比如docker container run -it <image name> <command> => docker container run -it ipinfo-base ipinfo version:对于容器ipinfo-base容器的默认CMD就是ipinfo version
 
- 比如
- 一个Dockerfile定义了多个CMD命令,只会执行最后一个
 
- 容器启动时默认执行的命令
- 
两种写法 1 2CMD [ "python3","hello.py" ] CMD python3 hello.py
- 
清除不再使用的容器 
|  |  | 
- 清除不再使用的镜像
|  |  | 
ENTRYPOINT
- 
和 CMD功能相似
- 
区别 - CMD会被命令行启动模式后面接的命令覆盖掉,而- ENTRYPOINT不会,一定会被执行
- CMD和- ENTRYPOINT可以联合使用
 
- 
1 2 3FROM ubuntu:21.04 ENTRYPOINT ["echo"] CMD []- 命令行docker container run -rm -it demo-both "hello world"执行效果=> hello world
 
- 命令行
- 数据持久化:VOLUME- 数据库,日志等如何存到本地?
 
|  |  | 
- 
保留镜像下面的 /data目录,没有会自动创建
- 
保存在本地的持久化数据使用 docker volume系列的命令查看
|  |  | 
- Mountpoint就是本地存储的位置
|  |  | 
- 这个时候VOLUME NAME和Mountpoint就是你自己刚才指定的名字了,不会是一串大段的加密码了
- 这个既可以让容器的数据保存的主机,反过来,如果主机对应的目录下面有文件,再次运行新的容器的时候,该容器可以复用主机对应部分的数据
- Bind Mount自定义- Windows实现数据持久化
- 用容器运行本机的程序,本机无需再需要安装环境
 
|  |  | 
- 本机修改数据的时候会同步到容器中,相当于完全绑定
- 网络端口映射
|  |  | 
- 
-p <主机端口>:<容器端口>:映射
- 
查看容器的端口 
|  |  | 
- 主要关注Config.ExposedPorts下面的内容
Docker-compose
- 
相当于 shell脚本,集成了命令
- 
两个部分 - 配置yml文件
- 运行文件的命令
 
- 配置
- 
检测环境 
|  |  | 
yml文件的基本语法
- docker-compose.yml
|  |  | 
- 实践
|  |  | 
- 
version:有关信息
- 
执行 compose命令(在同级目录)
|  |  | 
- compose镜像的构建和拉取
|  |  | 
- 只拉取镜像,不启动容器,下次docker compose up的时候会很快
|  |  | 
网络配置
- 
主要信息在配置文件里面的 Networks部分
- 
内网地址: IPAddress
- 
网关: Gateway:通常是主机地址
- 
使用容器集群的时候要进行网络配置 - 
查看 1docker network ls
- 
三种模式 - bridge:桥接模式(网桥),为每一个容器分配和设置一个- ip地址,并将容器连接到- docker0上面(- linux下使用- ip addr查看)
- host:使用主机的网络地址,容器自己没有- ip和网关,全部依赖宿主
- container:使用其他网络配置好了的容器的网络
- null:不对网络进行任何配置,也可以自定义
 
 
- 
|  |  | 
- 创建host类型的容器
|  |  | 
- 创建null类型的容器
|  |  | 
- container
|  |  | 
- 如果container对应的容器关闭,或者关闭之后开启,container的容器的网都会断开