docker 笔记

基础篇

1 简介

是什么

  1. 从系统环境开始,自底而上打包应用;
  2. 运行文档 + 配置环境 + 运行环境 + 运行依赖包 + 操作系统发行版;

Docker 是一个 C/S 结构的系统,Docker 守护进程运行在主机上,然后通过 Socket 连接从客户端访问,守护进程从客户端接收命令并管理运行在主机上的容器。

能干嘛

  1. 之前的虚拟技术:虚拟机就是带环境安装的一种解决方案,可以在一个操作系统中运行另一种操作系统。对于底层系统来说,虚拟机就是一个普通文件,不需要了就删掉。
  2. 容器虚拟化技术:另一种虚拟化技术:Linux 容器(Linux Containers,LXC)。Linux 容器不是模拟一个完整的操作系统,而是对进程进行隔离。有了容器,就可以把软件运行所需的所有资源打包到一个隔离的容器中。
  3. Docker 和传统虚拟化方式的不同:
  • 传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;
  • 容器内的应用直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟;
  • 每个容器之间互相隔离,每个容器有自己的文件系统,容器之间进程不会相互影响,能区分计算资源。

去哪下

  1. 官网

docker官网:www.docker.com

docker中文网站:www.docker-cn.com

  1. 仓库

docker hub官网:https://hub.docker.com

2 Docker 安装

Docker 的基本组成

  1. 镜像(image)

Docker 镜像(image)就是一个只读的模板,一个镜像可以创建很多容器;

容器与镜像的关系类似于面向对象编程中的对象与类;

  1. 容器(container)

Docker 利用容器(Container)独立运行的一个或一组应用。容器是用镜像创建的运行实例;

它可以被启动、开始、停止、删除,每个容器都是相互隔离的;

可以把容器看做是一个简易版的 Linux 环境(包括 root 用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序;

容器的定义和镜像几乎一摸一样,也是一堆层的统一视角,唯一区别在于容器的最上面那一层是可读可写的;

  1. 仓库(repository)

仓库是集中存放镜像文件的场所。

仓库(Repository)和仓库注册服务器(Register)是有区别的。仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag);

安装步骤

  1. centos6.8 安装 docker
yum install -y epel-release:docker 使用 EPEL 发布,要确保系统有 EPEL 仓库
yum install -y docker-io
安装后的配置文件:/etc/sysconfig/docker
启动 docker后台服务:service docker start
docker version 验证
  1. centos7 安装 docker
根据官网文档安装

永远的 HelloWorld

  1. 阿里云镜像加速/网易云加速
  • 注册一个属于自己的阿里云账号

  • 获得加速器地址链接

  • 配置本机 Docker 运行镜像加速器

  • 重新启动 Docker 后台服务

  • Linux 系统下配置完加速器需要检查是否生效

  1. 启动 Docker 后台容器(测试运行 hello-world)
docker run hello-world
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://1nj0zren.mirror.aliyuncs.com",
"https://docker.mirrors.ustc.edu.cn",
"http://f1361db2.m.daocloud.io",
"https://registry.docker-cn.com"
]
}
EOF

底层原理

  1. Docker 是一个 Client-Server 结构的系统,Docker 守护进程运行在主机上,然后通过 Socket 连接从客户端访问,守护进程从客户端接受命令并管理运行在主机上的容器。容器,是一个运行时环境,就是我们前面说到的集装箱。

  2. 为什么 Docker 比 VM 快

  • docker 有着比虚拟机更小的抽象层,由于 docker 不需要 Hypervisor 实现硬件资源虚拟化,运行在 docker 容器上的程序直接使用的都是实际物理机的硬件资源。因此,在 CPU、内存利用率上 docker 将会在效率上有明显优势;
  • docker 利用的是宿主机的内核,而不需要 Guest OS。因此,当新建一个容器时,docker 不需要和虚拟机一样重新加载一个操作系统内核,从而避免引寻、加载操作系统内核这个比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载 Guest OS,这个新建过程是分钟级别的。而 docker 由于直接利用宿主机的操作系统,则省略了这个过程。
  1. docker容器内的数据存放在宿主机哪里?
docker inspect 容器ID
找到字段GraphDriver,里面有UpperDir字段,这里面就存放这容器的数据

3 Docker 常用命令

帮助命令

  • 启动 docker:systemctl start docker

  • 停止 docker:systemctl stop docker

  • 重启 docker:systemctl restart docker

  • 查看 docker 状态:systemctl status docker

  • 开机启动 docker:systemctl enable docker

  • 查看 docker 概要信息:docker info

  • 查看 docker 总体帮助文档:docker --help

  • 查看 docker 命令帮助文档:docker 具体命令 --help

镜像命令

docker images:列出本地主机上的镜像
repository:表示镜像的仓库源
tag:镜像的标签版本号
image id:镜像id
created:镜像创建时间
size:镜像大小
同一个仓库可以有多个tag,代表这个仓库源的不同个版本,使用 repository:tag 来定义不同的镜像
-a:列出本地所有的镜像(含中间映像层);
-q:只显示镜像ID;
--digests:显示镜像的摘要信息;
--no-trunc:显示完整的镜像信息;
docker search [OPTIONS] 镜像名字
--no-trunc:显示完整的镜像描述
-s:列出收藏数不小于指定值的镜像
--automated:只列出 automated build 类型的镜像
docker pull 镜像名[:TAG]
docker system df 查看镜像/容器/数据卷所占的空间
docker rmi 某个xxx镜像名字ID
删除单个:docker rmi -f 镜像ID
删除多个:docker rmi -f 镜像名1:TAG 镜像名2:TAG
删除全部:docker rmi -f $(docker images -qa)

面试题:谈谈 docker 虚悬镜像是什么?

仓库名、标签都是 <none> 的镜像,俗称虚悬镜像(dangling image)。

容器命令

有镜像才能创建容器,这是根本前提;

  1. 新建并启动容器
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
OPTIONS说明:
--name="容器新名字":为容器指定一个名称;
-d:后台运行容器,并返回容器ID,也即启动守护式容器;
-i:以交互模式运行容器,通常与 -t 同时使用;
-t:为容器重新分配一个伪输入终端,通常与 -i 同时使用;
#如:docker run -it ubuntu /bin/bash
-P:随机端口映射;
-p:指定端口映射,有以下四种格式:
ip:hostPort:containerPort
ip::containerPort
hostPort:containerPort
containerPort
#使用镜像centos:latest以后台模式启动一个容器
docker run -d centos
问题:然后 docker ps -a 进行查看,会发现容器已经退出
很重要的说明一点:Docker 容器后台运行,就必须有一个前台进程
容器运行的命令如果不是那些一直挂起的命令(比如top、tail),就是会自动退出的。
最佳的解决方案是,将你要运行的程序以前台进程的形式运行。
常见就是命令行模式,表示我还有交互操作,别中断
前台交互式启动:docker run -it redis:6.0.8
后台守护式启动:docker run -d redis:6.0.8 #容器不会退出
  1. 列出当前所有 正在运行 的容器
docker ps [OPTIONS]
OPTIONS说明:
-a:列出当前所有正在运行的容器+历史上运行过的
-l:显示最近创建的容器;
-n:显示最近 n 个创建的容器;
-q:静默模式,只显示容器编号;
--no-trunc:不截断输出;
  1. 退出容器
两种退出方式:
1.exit
容器停止退出
2.ctrl+p+q
容器不停止退出
  1. 启动容器
docker start 容器ID或者容器名
  1. 重启容器
docker restart 容器ID或者容器名
  1. 停止容器
docker stop 容器ID或者容器名
  1. 强制停止容器
docker kill 容器ID或者容器名
  1. 删除已停止的容器
docker rm 容器ID
一次性删除多个容器:
docker rm -f $(docker ps -a -q)
docker ps -a -q | xargs docker rm
  1. 重要
  • 启动守护式容器

    docker run -d 容器名
    问题:用 docker ps -a 进行查看,发现容器已经退出
    很重要的要说明的一点:docker 容器后台运行,就必须有一个前台进程
    容器运行的命令如果不是那些一直挂起的命令(比如运行 top、tail)
    这个是 docker 的机制问题,比如你的web容器,我们以 nginx 为例,正常情况下,我们配置启动服务只需要启动相应的 service 即可。例如:service nginx start
    但是,这样做,nginx 为后台进程模式运行,就导致 docker 前台没有运行的应用,
    这样的容器后台启动后,会立即自杀,因为它觉得它没事可做了,
    所以,最佳的解决方案是,将你要运行的程序以前台进程的形式运行;
    docker run -d centos /bin/sh -c "while true;do echo hello zzyy;sleep 2;done"
  • 查看容器日志

    docker logs -f -t --tail 数字 容器ID
    -t:加入时间戳
    -f:跟随最新的日志打印
    --tail 数字:显示最后多少条

    当我们输入 docker logs 的时候,会转换为 Docker Client 向 Docker Daemon 发起请求,Docker Daemon 在运行容器时会去创建一个协程,绑定了整个容器内所有进程的标准输出文件描述符。因此容器内应用的所有只要是标准输出日志,都会被 goroutine 接受。Docker Daemon 会根据容器 id 和日志类型读取日志内容,最终输出到用户终端上并且通过 json 格式存放在 /var/lib/docker/containers 目录下。

    容器日志文件的生命周期:docker logs 是跟随容器而产生的,如果删除了某个容器,相应的日志文件也会随着被删除。

  • 查看容器内部运行的进程

    docker top 容器ID
  • 查看容器内部细节

    docker inspect 容器ID
  • 进入正在运行的容器并以命令行交互

    docker exec -it 容器ID bashShell
    docker attach 容器ID
    上述两个区别:
    exec:是在容器中打开新的终端,并且可以启动新的进程,退出后不会导致容器的停止;
    attach:直接进入容器启动命令的终端,不会启动新的进程,退出后会导致容器的停止;
    一般用 -d 后台启动的程序,再用exec进入对应的容器实例
  • 从容器内拷贝到主机上

    docker cp 容器ID:容器内路径 目的主机路径
  • 导入/导出容器

    export 导出容器的内容留作为一个tar归档文件
    import 从tar包中的内容创建一个新的文件系统再导入为镜像
    docker export 容器ID > 文件名.tar
    cat 文件名.tar | docker import - 镜像用户/镜像名:镜像版本号

小总结

attach:Attach to a running container 当前 shell 下 attach 连接指定运行镜像
build:Build an image from a Dockerfile 通过 Dockerfile 定制镜像
commit:Create a new image from a container changes 提交当前容器为新的镜像
cp:Copy files/folders from the containers filesystem to the host path 从容器中拷贝指定文件或目录到宿主机中
create:Create a new container 创建一个新的容器,同run,单不启动容器
diff:Inspect changes on a container's filesystem 查看 docker 容器变化
events:Get real time events from the server 从 docker 服务器获取实时事件
exec:Run a command in an existing container 在已存在的容器上运行命令
export:Stream the contents of a container as a tar archive 导出容器的内容流作为一个 tar 归档文件[对应 import]
history:Show the history of an image 展示一个镜像形成历史
images:List images 列出系统当前镜像
import:Create a new filesystem images from the contents of a tarball 从tar包中的内容创建一个新的文件系统映像[对应 export]
info:Display system-wide information 显示系统相关信息
inspect:Return low-level information on a container 查看容器详细信息
kill:Kill a running container kill 指定 docker 容器
load:Load an image from a tar archive 从一个 tar 包中加载一个镜像[对应 save]
login:Register of Login to the docker registry server 注册或登录一个 docker 源服务器
logout:Log out from a Docker registry server 从当前 Docker registry 退出
logs:Fetch the logs of a container 输出当前容器日志信息
port:Lookup the public-facing port which is NAT-ed to PRIVATE_PORT 查看映射端口对应的容器内部源端口
pause:Pause all processes within a container 暂停容器
ps:List containers 列出容器列表
pull:Pull an image or a repository from the docker registry server 从docker镜像源服务器拉去指定镜像或者库镜像
push:Push an image or a repository to the docker registry server 推送指定镜像或者库镜像至docker源服务器
restart:Restart a running container 重启运行的容器
rm:Remove one or more containers 移除一个或者多个容器
rmi:Remove one of more containers 移除一个或多个镜像[无容器使用该镜像才可删除,否则需删除相关容器才可继续或 -f 强制删除]
run:Run a command in a new images 创建一个新的容器并运行一个命令
save:Save an image to a tar archive 保存一个镜像为一个 tar 包
search:Search for an image on the Docker Hub 在 docker hub中搜索镜像
start:Start a stopped containers 启动容器
stop:Stop a running containers 停止容器
tag:Tag an image into a repository 给源中镜像打标签
top:Lookup the running processes of a container 查看容器中运行的进程信息
unpause:Unpause a paused container 取消暂停容器
version:Show the docker version information 查看docker版本号
wait:Block until a container stops,then print its exit code 截取容器停止时的退出状态值

4 Docker 镜像

是什么

  1. UnionFS(联合文件系统)

Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directions into a single virtual filesystem)。Union 文件系统是 Docker 镜像的基础镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像;

特性:一次性同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。

  1. Docker 镜像加载原理

docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。

bootfs(boot file system)主要包含 bootloader 和 kernal,bootloader 主要是引导加载 kernal,Linux 刚启动时会加载 bootfs 文件系统,在 Docker 镜像的最底层是 bootfs。这一次与我们典型的 Linux/Unix 系统是一样的,包含 boot 加载器和内核。当 boot 加载完成之后整个内核都在内存中,此时内存的使用权已由 bootfs 转交给内核,此时系统也会卸载 bootfs。

rootfs(root file system),在 bootfs 之上。包含的就是典型 Linux 系统中的 /dev,/proc,/bin,/etc 等标准目录和文件。rootfs 就是各种不同的操作系统发行版,比如 Ubuntu,Centos 等等。

对于一个精简的OS,rootfs 可以很小,只需要包括最基本的命令、工具和程序就可以了,因为底层直接用 Host 的 kernal,自己只需要提供 rootfs 就行了。由此可见,对于不同的 linux 发行版,bootfs 基本是一致的,rootfs 会有差别,因此不同的发行版可以共用 bootfs。

  1. 分层的镜像

  2. 为什么 Docker 镜像要采用这种分层结构呢

最大的好处——共享资源

比如:有多个镜像从相同的 base 镜像构建而来,那么宿主机只需要在磁盘上保存一份 base 镜像,同时内存中也只需要加载一份 base 镜像,就可以为所有容器服务了,而且镜像的每一层都可以被共享;

特点

docker 镜像层都是只读的,容器层是可写的。

当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称作 “容器层”,“容器层”下面的都叫“镜像层”。

5 本地镜像发布到阿里云

本地镜像发布到阿里云流程

镜像的生成方法

  1. docker commit 提交容器副本使之称为一个新的镜像:
docker commit -m "提交的描述信息" -a "作者" 容器ID 要创建的目标镜像名:[标签名]
  1. dockfile 方法

将本地镜像推送到阿里云

将阿里云上的镜像下载到本地

6 本地镜像发布到私有云

  1. 下载镜像 Docker Registry
docker pull registry
  1. 运行私有库 Registry,相当于本地有个私有 Docker hub

  2. 案例演示创建一个新镜像,ubuntu 安装 ifconfig 命令

  3. curl 验证私服库上有什么镜像

  4. 将新镜像 zzyyubuntu:1.2 修改符合私服规范的 Tag

  5. 修改配置文件使之支持 http

  6. push 推送到私服库

  7. curl 验证私服库上有什么镜像

7 Docker 容器数据卷

是什么

卷就是目录或文件,存在于一个或多个容器中,由 docker 挂载到容器,但不属于联合文件系统,因此能够绕过 Union File System 提供一些用于持续存储或共享数据的特性。

卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此 Docker 不会在容器删除时删除其挂载的数据卷。

一句话:有点类似于 Redis 里面的 rdb 和 aof 文件。

将 docker 容器内的数据保存进宿主机的磁盘中。

运行一个带有容器卷存储功能的容器实例:

docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录 镜像名
默认是读写权限
等同于
docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录:rw 镜像名
#如果宿主机目录为空,那容器目录也将为空。容器里的被覆盖了。
只读权限
docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录:ro 镜像名
此时如果宿主机写入内容,可以同步给容器内,容器可以读取到

能干嘛

特点:

  1. 数据卷可在容器之间共享或重用数据,容器数据卷和主机互通互联

  2. 卷中的更改可以直接实时生效

  3. 数据卷中的更改不会包含在镜像的更新中

  4. 数据卷的生命周期一直持续到没有容器使用它为止

卷的继承和共享

docker run -it --peivileged=true --volumes-from 父类 --name=u2 ubuntu /bin/bash

8 Docker 常规安装简介

总体步骤

  • 搜索镜像

  • 拉取镜像

  • 查看镜像

  • 启动镜像 - 服务端口映射

  • 停止容器

  • 移除容器

安装 tomcat

安装 mysql

根据官网的命令来执行安装。记得做容器数据卷,防止容器删除后数据也被删除。

docker run -d -p 3306:3306 --privileged=true
-v /zzyyuse/mysql/log:/var/log/mysql
-v /zzyyuse/mysql/data:/var/lib/mysql
-v /zzyyuse/mysql/conf:/etc/mysql/conf.d
-e MYSQL_ROOT_PASSWORD=root \ # -e 设置环境变量
--name mysql
mysql:5.7

安装 redis

修改 redis.conf 文件,通过容器卷同步给 redis 容器实例。

#开启redis验证 可选
requirepass 123
#允许redis外地连接 必须
注释掉 # bind 127.0.0.1
# 将 daemonize yes 注释起来或者 daemonize no设置,因为该配置和 docker run 中 -d 参数冲突,会导致容器一直启动失败
daemonize no
#开启redis数据持久化 可选
append yes

启动 docker redis 的命令:

ocker run -d -p 6379:6379 --privileged=true
-v /app/redis/redis.conf:/etc/redis/redis.conf
-v /app/redis/data:/data
--name myr3
-d redis:6.0.8 redis-server /etc/redis/redis.conf

安装 Nginx

见高级篇

高级篇

1 Docker 复杂安装详说

安装 mysql 主从复制

  1. 新建主服务器容器实例 3307
docker run -p 3307:3306 --privileged=true --name mysql-master \
-v /mydata/mysql-master/log:/var/log/mysql \
-v /mydata/mysql-master/data:/var/lib/mysql \
-v /mydata/mysql-master/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=root \ #root用户的密码
-d mysql:5.7
  1. 进入 /mydata/mysql-master/conf 目录下新建 my.cnf
[mysqld]
## 同一局域网内注意要唯一
server-id=101
## 指定不需要同步的数据库名称
binlog-ingore-db=mysql
## 开启二进制日志功能
log-bin=mall-master-bin
## 设置二进制日志使用内存大小(事务)
binlog_cache_size=1M
## 设置使用的二进制日志格式(mixed,statement,row)
binlog_format=mixed
## 二进制日志过期清理时间,默认值为0,表示不自动清理
expire_logs_days=7
## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断
## 如:1062错误是指一些主键重复,1032错误是因为主从数据库不一致
slave_skip_errors=1062
  1. 修改完配置后重启 master 实例

  2. 进入 mysql-master 容器

  3. master 容器实例内创建数据同步用户

CREATE USRE 'slave'@'%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO 'slave'@'%';
  1. 新建从服务器容器实例 3308

  2. 进入 /mydata/mysql-slave/conf 目录下新建 my.cnf

[mysqld]
## 同一局域网内注意要唯一
server-id=102
## 指定不需要同步的数据库名称
binlog-ingore-db=mysql
## 开启二进制日志功能,以备 slave 作为其它数据库实例的 master 时使用
log-bin=mall-slave1-bin
## 设置二进制日志使用内存大小(事务)
binlog_cache_size=1M
## 设置使用的二进制日志格式(mixed,statement,row)
binlog_format=mixed
## 二进制日志过期清理时间,默认值为0,表示不自动清理
expire_logs_days=7
## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断
## 如:1062错误是指一些主键重复,1032错误是因为主从数据库不一致
slave_skip_errors=1062
## relay_log 配置中继日志
relay_log=mall-mysql-relay-bin
## log_slave_updates 表示 slave 将复制时间写进自己的二进制日志
log_slave_updates=1
## slave 设置为只读(具有super权限的用户除外)
read_only=1
  1. 修改完配置后重启 slave 实例

  2. 在主数据库中查看主从同步状态

show master status;
  1. 进入 mysql-slave 容器

  2. 在从数据库中配置主从复制

change master to master_host='宿主机ip',master_user='slave',master_password='123456',
master_port=3307,master_log_file='mall-mysql-bin.000001',master_log_pos=617,master_connect_retry=30;
  1. 在从数据库中查看主从同步状态
show slave status \G
  1. 在从数据库中开启主从同步
start slave;
  1. 查看从数据库状态发现已经同步

  2. 主从复制测试

安装 redis 集群(大厂面试题第4季-分布式存储案例真题)

cluster(集群)模式-docker版,哈希槽分区进行亿级数据存储。

面试题

面试题:1~2 亿条数据需要缓存,请问如何设计这个存储案例?

上述问题阿里 P6~P7 工程案例和场景设计类必考题目,一般业界有3种解决方案。

  • 哈希取余分区

  • 一致性哈希算法分区

  • 哈希槽分区

3主3从redis集群配置

  1. 关闭防火墙+启动 docker 后台服务

  2. 新建 6 个 docker 容器实例

docker run -d --name redis-node-1 --net host --privileged=true
-v /data/redis/share/redis-node-1:/data
redis:6.0.8
--cluster-enabled yes
--appendonly yes
--port 6381
  1. 进入容器 redis-node-1, 并为6台机器构建集群关系
redis-cli --cluster create 192.168.111.167.6381 192.168.111.167.6382 192.168.111.167.6383 192.168.111.167.6384
192.168.111.167.6385 192.168.111.167.6386 --cluster-replicas 1
  1. 链接进入 6381 作为切入点,查看集群状态
redis-cli -p 6381 -c

主从容错切换迁移案例

数据读写存储

启动 6 机器构成的集群并通过 exec 进入。

对 6381 新增两个 key。

防止路由失效加参数 -c 并新增两个 key:redis-cli -p 6381 -c

查看集群信息:redis-cli --cluster check 192.168.111.147:6381

容错切换迁移案例
主从扩容案例
  1. 新建 6387、6388 两个节点 + 新建后启动 + 查看是否8节点

  2. 进入6381容器实例内部

  3. 将新增的 6387 节点作为 master 节点加入原集群

  4. 检查集群情况第1次

  5. 重新分配槽号

redis-cli --cluster reshard IP:PORT
  1. 检查集群情况第 2 次

  2. 为主节点 6378 分配从节点 6388

  3. 检查集群情况第3次

主从缩容案例

2 DockerFile 解析

是什么

Dockerfile 是用来构建 Docker 镜像的文本文件,是由一条条构建镜像所需要的指定和参数构成的脚本。

构建三步骤:

  1. 编写 dockerfile 文件

  2. docker build 命令构建镜像

  3. docker run 依镜像运行容器实例

DockerFile 构建过程解析

Dockerfile 内容基础知识

  1. 每条保留字指定都必须为 大写 字母且后面要跟随至少一个参数。

  2. 指令按照从上到下,顺序执行。

  3. # 表示注释。

  4. 每条指定都会创建一个新的镜像成并对镜像进行提交。

Docker 执行 Dockerfile 的大致流程

  1. docker 从基础镜像运行一个容器。

  2. 执行一条指令并对容器做出修改。

  3. 执行类似 docker commit 的操作提交一个新的镜像层。

  4. docker 再基于刚提交的镜像运行一个新容器。

  5. 执行 dockerfile 中的下一条指令直到所有指令都执行完成。

小总结

Dockerfile 常用保留字指令

  • FROM

    基础镜像,当前镜像是基于哪个镜像的,指定一个已经存在的镜像作为模板,第一条必须是 from。

  • MAINTAINER

    镜像维护者的姓名和邮箱地址。

  • RUN

    容器构建时需要运行的命令。

    RUN 是在 docker build 时运行。

    两种格式:

    • shell 格式

      ENTRYPOINT java -jar /app.jar
      CMD ["hello", "world"]
      #shell 格式的 ENTRYPOINT 是由 "/bin/sh -c" 启动的
      #通过 docker inspect 命令看到镜像中实际的 ENTRYPOINT 是
      # ENTRYPOINT ["/bin/sh", "-c", "java -jar /app.jar"]
      #所以与 CMD 连接起来的入口就是 ["/bin/sh", "-c", "java -jar /app.jar", "hello", "world"],
      #"bin/sh" 直接忽略掉后面的 "hello" 与 "world",这就是为什么shell 命令方式无法获取参数。
    • exec 格式

      RUN ["可执行文件","参数1","参数2"]
      # 例如:# RUN ["./test.php","dev","offline"] 等价于 RUN ./test.php dev offline
  • EXPOSE

    当前容器对外暴露出的端口。

  • WORKDIR

    指定在创建容器后,终端默认登录进来的工作目录,一个落脚点。

  • USER

    指定该镜像以什么样的用户去执行,如果都不指定,默认是 root。

  • ENV

    用来在构建镜像过程中设置环境变量。

  • ADD

    将宿主机目录下的文件拷贝进镜像且会自动处理 URL 和解压 tar 压缩包。

  • COPY

    类似 ADD,拷贝文件和目录到镜像中。

    将从构建上下文目录中 <源路径>的文件/目录复制到新的一层镜像内的 <目标路径>位置

  • VOLUME

    容器数据卷,用于数据保存和持久化工作。

  • CMD

    指定容器启动后要干的事情。

    dockerfile 中可以有多个 CMD 指令,但只有 最后一个 生效,CMD 会被 docker run 之后的参数替换。

    和 RUN 命令的区别:

    • CMD 是在 docker run 时运行。

    • RUN 是在 docker build 时运行。

  • ENTRYPOINT

    也是用来指定一个容器启动时要运行的命令。

    类似于 CMD 指令,但是 ENTRYPOINT 不会被 docker run 后面的命令覆盖,而且这些命令行参数会被当做参数送给 ENTRYPOINT 指令指定的程序。

ENTRYPOINT 与 CMD 的关系

  1. 如果没有定义 ENTRYPOINT,CMD 将作为它的 ENTRYPOINT。

  2. 定义了 ENTRYPOINT 的话,CMD 只为 ENTRYPOINT 提供参数

  3. CMD 可由 docker run <image> 后的命令覆盖,同时覆盖参数。

  4. ENTRYPOINT 同样可以被覆盖,如 docker run --entrypoint ls test -l /,将会执行 ls -l / 命令。

容器运行的最终入口是由 ENTRYPOINT 和实际的 CMD 拼接而成。ENTRYPOINT 和 CMD 需转换为实际镜像中的 exec 格式来拼接,合并后的第一个元素是命令,其余是它的参数。

案例

自定义镜像 mycentosjava8

要求
  • centos7 镜像具备 vim+config+jdk8
编写

准备编写 Dockerfile 文件,大写字母 D。

FROM centos
MAINTAINER zzyy<zzyybs@126.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH
#安装vim编辑器
RUN yum -y install vim
#安装ifconfig命令查看网络IP
RUN yum -y install net-tools
#安装java8及lib库
RUN yum -y install glibc.i686
RUN mdkir /usr/local/java
# ADD 是相对路径jar,把jkd-8u171-linux-x86.tar.gz 添加到容器中,安装包必须要和 Dockerfile 文件在同一位置
ADD jkd-8u171-linux-x86.tar.gz /usr/local/java
#配置java环境变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_171
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CALSSPATH
ENV PATH $JAVA_HOME/bin:$PATH
EXPOSE 80
CMD echo $MYPATH
CMD echo "success-----------ok"
CMD /bin/bash
构建
docker build -t 新镜像名字:TAG .
#注意,上面TAG后面有个空格,有个点,代表当前目录
运行
docker run -it -p 端口映射 新镜像名字:TAG
再体会下 UnionFS

虚悬镜像

仓库名、标签都是<none> 的镜像。

FROM ubuntu
CMD echo 'action is success'

小总结

3 Docker 微服务实战

4 Docker 网络

是什么

  • docker 不启动,默认网络情况

  • docker 启动后,网络情况

常用基本命令

  • 查看网络:docker network ls

  • 查看网络数据:docker network inspect 网络名字

  • 删除网络:docker network rm 网络名字

  • 案例

能干嘛

  • 容器间的互联和通信以及端口映射

  • 容器 IP 变动时候可以通过服务名直接网络通信而不受影响

网络模式

总体介绍

网络模式 简介
bridge 为每一个容器分配、设置 IP 等,并将容器连接到一个 docker0 虚拟网桥
默认为该模式
host 容器将不会虚拟出自己的网卡,配置自己的 IP 等,而是使用宿主机的 IP 和端口
none 容器有独立的 Network namespace,但并没有对其进行任何网络设置,没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。
container 新创建的容器不会创建自己的网卡和配置自己的 IP,而是和一个指定的容器共享 IP、端口范围
自定义网络

容器实例内默认网络 IP 生产规则

docker 容器内部的 ip 是有可能会发生改变的。

brideg

docker 服务默认会创建一个 docker0 网桥(其上有一个 docker0 内部接口),该桥接网络的名称为 docker0,它在 内核层 连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到 同一个物理网络。Docker 默认指定了 docker0 接口的 IP 地址和子网掩码,让主机和容器之间可以通过网桥相互通信。

host

直接使用宿主机的 IP 地址与外界进行通信,不再需要额外进行 NAT 转换。

docker run -d --network host --name tomcat83 billygoo.tomcat8-jdk8

不需要指定端口映射,否则会警告。

none

禁用网络功能,只有 lo 标识(就是 127.0.0.1 表示本地回环)

container

自定义网络

自定义桥接网络,自定义网络默认使用的桥接网络 bridge。

自定义网络本身就维护好了主机名和 ip 的对应关系(ip 和 域名都能通)。

  1. 新建自定义网络

  2. 新建容器加入上一步新建的自定义网络

  3. 互相 ping 测试,ping 服务名 可以 ping 通。

5 Docker-compose 容器编排

Compose 是 Docker 公司推出的一个工具软件,可以管理多个 Docker 容器组成一个项目(project)。你需要定义一个 YAML 格式的配置文件 docker-compose.yml,写好多个容器之间的 调用关系。然后,只要一个命令,就能同时启动/关闭这些容器。

compose 核心概念

  • 一文件:docker-compose.yml

  • 两要素:

    • 服务(service):一个个应用容器实例,比如订单微服务、库存微服务、mysql容器、nginx 容器

    • 工程(project):由一组关联的应用容器组成的一个完整业务单元,在 docker-compose.yml 文件中定义

compose 使用的三个步骤

  • 编写 Dockerfile 定义各个微服务应用并构建出对应的镜像文件。

  • 使用 docker-compose.yml 定义一个完整业务单元,安排好整体应用中的各个容器服务。

  • 最后,执行 docker-compose up 命令,来启动并运行整个应用程序,完成一键线上部署。

compose 常用命令

  • docker-compose -h:查看帮助

  • docker-compose up:启动所有 docker-compose 服务

  • docker-compose up -d:启动所有 docker-compose 服务并后台运行

  • docker-compose down:停止并删除容器、网络、卷、镜像

  • docker-compose exec yml里面的服务id:进入容器实例内部

    docker-compose exec yml里面的服务id /bin/bash

  • docker-compose ps:展示当前 docker-compose 编排过的运行的所有容器

  • docker-compose top:展示当前 docker-compose 编排过的容器进程

  • docker-compose yml里面的服务id:查看容器输出日志

  • docker-compose config:检查配置

  • docker-compose config -q:检查配置,有问题才有输出

  • docker-compose start:启动服务

  • docker-compose stop:停止服务

  • docker-compose restart:重启服务

compose 编排微服务

改造升级微服务工程 docker_boot

不用 compose

swagger 测试

使用 Compose

6 Docker 轻量级可视化工具 Portainer

7 Docker 容器监控之 CAdvisor+InfluxDB+Granfana

8 终章总结

参考

https://www.bilibili.com/video/BV1gr4y1U7CY //尚硅谷2022版Docker实战教程  P1-90
https://blog.csdn.net/chenxing109/article/details/85319489 //如何向Docker容器传递参数
https://cloud.tencent.com/developer/article/1644756 //Docker挂了,数据如何找回

posted on   slivermirror  阅读(28)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示