docker
前序
没有Docker的时代,Linux上安装配置环境,是一个恶梦; 比如安装Tomcat;
安装Java环境
#下载jdk17 |
安装Tomcat
下载二进制包 |
制作开机启动
sudo vim /etc/systemd/system/tomcat.service |
sudo systemctl daemon-reload |
更多
- 有些软件还要下载 源码,进行编译安装:
make & make install
- 软件换平台迁移更加麻烦;多个操作系统安装方式可能不一样(ubuntu、debian、centos)
容器
传统部署时代:
早期,各个组织是在物理服务器上运行应用程序。 由于无法限制在物理服务器中运行的应用程序资源使用,因此会导致资源分配问题。 例如,如果在同一台物理服务器上运行多个应用程序, 则可能会出现一个应用程序占用大部分资源的情况,而导致其他应用程序的性能下降。 一种解决方案是将每个应用程序都运行在不同的物理服务器上, 但是当某个应用程序资源利用率不高时,剩余资源无法被分配给其他应用程序, 而且维护许多物理服务器的成本很高。
虚拟化部署时代:
因此,虚拟化技术被引入了。虚拟化技术允许你在单个物理服务器的 CPU 上运行多台虚拟机(VM)。 虚拟化能使应用程序在不同 VM 之间被彼此隔离,且能提供一定程度的安全性, 因为一个应用程序的信息不能被另一应用程序随意访问。
虚拟化技术能够更好地利用物理服务器的资源,并且因为可轻松地添加或更新应用程序, 而因此可以具有更高的可扩缩性,以及降低硬件成本等等的好处。 通过虚拟化,你可以将一组物理资源呈现为可丢弃的虚拟机集群。
每个 VM 是一台完整的计算机,在虚拟化硬件之上运行所有组件,包括其自己的操作系统。
容器部署时代:
容器类似于 VM,但是更宽松的隔离特性,使容器之间可以共享操作系统(OS)。 因此,容器比起 VM 被认为是更轻量级的。且与 VM 类似,每个容器都具有自己的文件系统、CPU、内存、进程空间等。 由于它们与基础架构分离,因此可以跨云和 OS 发行版本进行移植。
容器因具有许多优势而变得流行起来,例如:
- 敏捷应用程序的创建和部署:与使用 VM 镜像相比,提高了容器镜像创建的简便性和效率。
- 持续开发、集成和部署:通过快速简单的回滚(由于镜像不可变性), 提供可靠且频繁的容器镜像构建和部署。
- 关注开发与运维的分离:在构建、发布时创建应用程序容器镜像,而不是在部署时, 从而将应用程序与基础架构分离。
- 可观察性:不仅可以显示 OS 级别的信息和指标,还可以显示应用程序的运行状况和其他指标信号。
- 跨开发、测试和生产的环境一致性:在笔记本计算机上也可以和在云中运行一样的应用程序。
- 跨云和操作系统发行版本的可移植性:可在 Ubuntu、RHEL、CoreOS、本地、 Google Kubernetes Engine 和其他任何地方运行。
- 以应用程序为中心的管理:提高抽象级别,从在虚拟硬件上运行 OS 到使用逻辑资源在 OS 上运行应用程序。
- 松散耦合、分布式、弹性、解放的微服务:应用程序被分解成较小的独立部分, 并且可以动态部署和管理 - 而不是在一台大型单机上整体运行。
- 资源隔离:可预测的应用程序性能。
- 资源利用:高效率和高密度。
容器化的几个重要特点:【轻量、快速、隔离、跨平台、高密度】
- 容器类似轻量级的VM
- 容器共享操作系统内核
- 容器拥有自己的文件系统、**
CPU
、内存
、进程空间
**等 - 容器互相隔离
Docker 入门
Docker 架构
- Docker_Host:安装Docker的主机
- Docker Daemon:运行在Docker主机上的Docker后台进程
- Client:操作Docker主机的客户端(命令行、UI等)
- Registry(镜像仓库):Docker Hub(公共仓库)、私有仓库
- Image(镜像): 带环境打包好的程序,可以直接启动运行
- Container(容器):由镜像启动起来正在运行中的程序
交互逻辑:装好Docker,然后去 软件市场 寻找镜像,下载并运行,查看容器状态日志等排错
软件市场:hub.docker.com
Docker 安装
https://docs.docker.com/engine/install/centos/
移除旧版本 |
验证
查看 Docker 中正在运行的容器 |
扩展:window安装docker
https://www.bilibili.com/video/BV15rduYAEV7/
常用命令
一个实验串联 Docker 常用的命令
需求:启动一个nginx
,并将它的首页改为自己的页面,发布出去,让所有人都能使用
- 下载nginx镜像并启动nginx应用
- 修改nginx软件的页面为自己的页面(定制化)
- 把软件发布出去(发布到**软件市场[docker hub]**)
- 别人去市场下载我们发布的软件并使用
以前:完成以上流程,很多命令
- 下载启动nginx:去nginx官方,找到安装包,下载,解压,配置
- 把nginx的内容进行修改
- 把NGINX软件重新打包,放upan或者网盘去分享
- 别人拿到你网盘的文件,自己解压,配置,启动运行
下载镜像
先去 hub.docker.com 搜索你需要的镜像(可以看镜像说明);
如下命令:
- 检索:
docker search
- 下载:
docker pull
- 列表:
docker images
- 删除:
docker rmi
镜像名:标签(版本)
启动容器
根据下载的镜像(就像是软件包),启动容器(就是启动程序);
配合如下命令:
运行: docker run
- 重点注意:端口映射和目录挂载
docker run [
OPTIONS
]
IMAGE
[COMMAND] [ARG...]
:- []代表可选
- options:选项;
COMMAND
:命令;默认运行什么命令容器才能启动;用镜像(软件包)中的哪个命令才能让软件启动(镜像官方默认指定的,除非我们自己要修改)- **
ARG
**:命令要用的参数;(镜像官方默认指定的,除非我们自己要修改) - 最简单的启动命令:**
docker run nginx:1.29.0
** - 比较完整的启动命令:**
docker run -d -p 80:80 --name mynginx nginx:1.29.0
**- **
--name
**:给容器指定名字 - **
-d
**:在后台启动 - **
-p 80:80
**:端口映射,机器外部的80端口,对应容器内部80 - **
--restart awlays
**:只要容器出错、重新开关机,容器都自动启动 - 重复启动一个集群化的;注意以下几点
- 容器名不能重复
- 外部端口不能重复
- **
查看: docker ps
- **
docker ps
**:查看运行中的容器 - **
docker ps -a
**:查看所有容器
- **
停止: docker stop
启动: docker start
重启: docker restart
状态: docker stats
日志: docker logs
进入: docker exec
- **
docker exec -it 容器名/id /bin/bash
**:进入指定容器内部
- **
删除: docker rm
**
docker rm -f 容器名/id
**:强制删除**
docker rm -f $(docker ps -aq)
**:强制删除所有容器(无论是否在运行)**
docker rm -f $(docker ps -q)
**:强制删除所有运行中的容器
修改页面
容器就像是一个小的虚拟机,改容器的内容,需要进入容器里面
- 进入: docker exec
nginx页面在:/usr/share/nginx/html
;这个在官方镜像页面有说明
保存镜像
容器内容发生修改后,可以对其进行保存;用到如下命令
- 提交:
docker commit
- 把容器的修改变更提交;保存成一个新镜像
- **
docker commit -a leifengyang mynginx leinginx:v1.0
**:-a
:指定作者名mynginx
****: 容器名- **
leinginx:v1.0
**:新镜像名
==== 以物理文件方式传递 ====
- 保存: docker save; 把镜像保存成压缩包
docker save -o leinginx.tar leinginx:v1.0
****: 把leinginx:v1.0 制作成一个leinginx.tar
- 加载: docker load; 把压缩包解析为镜像
docker load -i leinginx.tar
- 然后按照这个镜像启动就可以;
分享镜像
镜像可以分享到 hub.docker.com 等地方,方便其他人下载使用
- 登录: docker login:
- 按照提示输入账号密码即可
- 命名: docker tag
leinginx:v1.0
改名为leifengyang/leinginx:v1.0
docker tag leinginx:v1.0 leifengyang/leinginx:v1.0
- 推送: docker push
docker push leifengyang/leinginx:v1.0
- 给镜像写一个readme 说明书;
- 全世界都可以搜到我们的镜像。按照我们的说明书去启动镜像
Docker 存储
Docker中支持多种存储机制。
- Linux挂载机制:
- 万物皆文件。插入Upan。把upan设备得挂载到一个文件夹中,进入文件夹就是读写U盘数据
- Docker挂载进制:
- Docker启动的容器,就是一个小型的Linux系统。
- 把Docker容器中文件系统的某个位置,挂载到宿主机。直接修改宿主机的位置,容器跟着变
常见使用**目录挂载
、数据卷
**,让容器数据不再丢失
目录挂载
-v /xx
或者 -v ./
以路径方式开始的。Docker将会使用目录挂载规则
-v
外部路径
:
容器内部路径
:代表外部路径挂载对应内部的一个位置(文件/文件夹都可以)
外部路径
:- 目录挂载:写
/
开头, 以./
开头,以盘符:/
; 以外边为准,如果外边没有,容器内部也没有;不适合配置文件的挂载。 - 卷映射:
-v haha:/etc/nginx
;以容器内部为准,把内部默认有的内容复制在外边;- haha真实所在的位置是Docker管理的一个位置:
/var/lib/docker/volumes/你的卷名/_data
- 用户不可以指定卷名对应的真实位置。受docker管理的默认空间
- haha真实所在的位置是Docker管理的一个位置:
- 目录挂载:写
这样修改外部就等同于修改内容。内部改变外部也可以看见
卷映射
目录挂载由于是以外部优先。如果外部没有东西,挂载后导致容器内部也没有。如果是一些配置文件,有可能导致因为没有默认配置存在而使得容器启动失败
使用卷映射,Docker启动容器的时候,会以容器内部优先。给外部创建出初始的所有内容。
卷映射的真实位置在Docker自己管理的空间里面:/var/lib/docker/volumes/卷名/_data
Docker 网络
Docker可以通过自定义网络,打通容器集群的访问连通性
docker为每个容器分配唯一ip,使用 容器ip+容器端口 可以互相访问
ip由于各种原因可能会变化
**
docker0
**是默认网络,不支持主机域名创建自定义网络,容器名就是**
稳定域名
**- 创建网络:
docker network create haha
docker network create --subnet 110.101.0.0/16 haha
- 使用网络:
docker run --network haha 镜像名
最佳实践
通过命令启动一个容器,关注这几点:
- 端口:暴露哪些端口
- 挂载:需要把数据挂载外面,防止丢失
- 数据:容器运行时的数据。比如MySQL、Redis等的数据目录
- 配置:每个容器配置文件位置。比如
nginx.conf
- 环境变量:环境变量是临时改变配置的一种方式
- 创建网络:
docker run \ |
windows下的docker
docker run -d -p 3333:3306 -v D:\opt\mysql\data:/var/lib/mysql -v D:\opt\mysql\conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 mysql:8.0.43-debian |
Docker Compose
Docker Compose 是Docker用来**批量管理容器
**(批量创建、启动、销毁等)的技术。
使用方式
编写
compose.yaml
- https://docs.docker.com/reference/compose-file/
- 7个顶级元素:
name、version、services、networks、volumes、configs、secrets
使用以下命令
上线:
docker compose up -d
下线:
docker compose down
启动:
docker compose start x1 x2 x3
停止:
docker compose stop x1 x3
扩容:
docker compose scale x2=3
;docker swarm 小集群
#创建网络 |
docker network create blog |
compose一键启动
compose.yaml 内容如下; 使用 docker compose -f compose.yaml up -d
一键启动所有容器
容器启动:(卷映射、网络、容器 谁先创建好?卷和网络先创建好,再创建容器);
name: myblog |
一键启动超多组件
项目中要用到很多组件:MySQL、Redis、Minio、MongoDB、ElasticSearch、RabbitMQ
使用场景:写一个 compose.yaml 文件,拿到这个文件,一键批量启动即可。开发环境就ok了
Dockerfile
通过编写Dockerfile,我们可以制作自己的镜像
基本语法
Dockerfile
语法:https://docs.docker.com/reference/dockerfile/
打包案例
如下是一个SpringBoot应用,依赖jdk17;把他如何打包成镜像,发布出去
编写Dockerfile
FROM openjdk:17 |
构建镜像
docker build -f Dockerfile -t app:v1.0 . |
-f
:指定Dockerfile
文件名,不写默认是Dockerfile-t
:指定镜像标签名.
:镜像打包的工作目录