概念
- docker是一个开源的应用容器引擎
- 诞生于2013年,基于Go语言实现
- Docker可以让开发者打包他们的应用以及依赖包到一个轻量级,可移植的容器中,然后发布到任何流行的linux机器上
- 容器是完全使用沙箱机制,相互隔离
- 容器性能开销极低
- Docker从17.03版本之后分为CE(社区版)和EE(企业版)
docker架构
Docker原理
- docker镜像本质是什么?
是一个分层文件系统 - docker中的一个centos镜像为什么只有200MB,而一个centos操作系统的iso文件有几个G?
centos的ios镜像包含bootfs和rootfs,而docker的centos镜像服用操作系统的bootfs,只有rootfs和其他镜像曾 - docker中一个tomcat镜像为什么有500MB,而一个tomcat安装包只有70多MB?
由于docker中镜像是分层的,tomcat虽然只有70多MB,但他需要依赖于父镜像和基础镜像,所有整个对外暴露的tomcat镜像大小有500多MB
知识补充:
linux文件系统由bootfs和rootfs两部分组成
- bootfs: 包含bootloader(引导加载程序)和kernel(内核)
- rootfs: root文件系统,包含的就是典型的linux系统中的/dev, /proc, /bin, /etc等标准目录和文件
- 不同的linux发行版,bootfs基本一样,而rootfs不同,如ubuntu,centos等
docker安装
- yum包更新到最新
yum update - 安装需要的软件包,yum-util提供yum-config-manager功能,另外两个是devicemapper驱动依赖的
yum install -y yum-utils device-mapper-persistent-data lvm2 - 设置yum源
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo - 安装docker
yum install -y docker-ce - 查看docker版本,验证是否安装成功
docker -v
默认情况下,从docker hub上下载docker镜像太慢,一般都会配置镜像加速器:
阿里云搜索镜像加速服务(免费), 阿里云官网会提供地址和命令
docker命令
服务相关命令
- 启动docker
systemctl start docker - 停止docker
systemctl stop docker - 重启docker
systemctl restart docker - 查看docker服务状态
systemctl status docker - 设置开机启动docker服务
systemctl enable docker
镜像相关命令
- 查看镜像: 查看本地所有镜像
docker images
docker images -q # 查看镜像id - 搜搜镜像: 从网络中查找需要的镜像
docker search 镜像名称 - 拉取镜像: 从docker仓库下载镜像到本地,镜像名称格式为名称:版本号,如果版本号不指定则是最新的版本,如果不知道版本,可以去docker hub上搜索对应的镜像查看
docker pull 镜像名称 - 删除镜像
docker rmi 镜像id
docker rmidocker images -q
# 删除本地所有镜像
容器相关命令
-
查看容器
docker ps # 查看正在运行的容器
docker ps -a # 查看所有容器(包括已经停止运行的) -
创建并启动容器
docker run 参数 (docker run -it --name=c1 centos:7 /bin/bash)
参数说明
-i
: 保持容器运行.通常与-t同时使用.加入it这两个参数后,容器创建后自动进入容器中,退出容器后,容器自动关闭
-t
: 为容器重新分配一个伪输入终端,通常与-i同时使用
-d
: 以守护(后台)模式运行容器. 创建一个在后台运行,需要使用docker exec进入容器.退出后,容器不会关闭
-it
: 创建的容器一般称为交互式容器,-id创建的容器一般称为守护式容器
--name
: 为创建的容器命名 -
进入容器
docker exec 参数 # 退出容器,容器不会关闭
案例: docker exec -it test /bin/bash -
停止容器
docker stop 容器名称 -
启动容器
docker start 容器名称 -
删除容器, 如果容器是运行状态则删除失败,需要停止容器才能删除
docker rm 容器名称
docker rmdocker ps -aq
删除所有容器
数据卷
数据卷概念
数据卷
- 数据卷是宿主机中的一个目录或文件
- 当容器目录和数据卷目录绑定后,对方的修改会立即同步
- 一个数据卷可以被多个容器同时挂载
- 一个容器也可以被挂载多个数据卷
数据卷作用 - 容器数据持久化
- 外部机器和容器简介通信
- 容器之间数据交换
配置数据卷
- 创建启动容器时,使用-v参数 设置数据卷
docker run … -v 宿主机目录(文件):容器内目录(文件)… - 注意事项
(1)目录必须是绝对路径
(2)若目录不存在,会自动创建
(3)可以挂载多个数据卷
数据卷容器
概念:
- 创建一个容器,挂在一个目录,让其他容器继承自该容器(–volume-from)
- 通过简单方式实现数据卷配置
案例:
多容器进行数据交换
- 多个容器挂载同一个数据卷
- 数据卷容器c3
具体做法
3. 创建启动c3数据卷容器,使用-v参数设置数据卷
docker run -it --name=c3 -v /volume centos:7 bin/bash
4. 创建启动c1 c2容器,使用–volumes-from参数 设置数据卷
docker run -it --name=c1 --volumes-from c3 centos:7 /bin/bash
docker run -it --name=c2 --volumes-from c3 centos:7 /bin/bash
案例
mysql
需求:
在docker容器中部署mysql,并通过外部mysql客户端操作mysql server
实现步骤:
- 搜索mysql镜像
- 拉取mysql镜像
- 创建容器
- 操作容器中的mysql
知识:
5. 容器内的网络服务和外部机器不能直接通信
6. 外部机器和宿主机可以直接通信
7. 宿主机和容器可以直接通信
8. 当容器中的网络服务需要被外部机器访问时,可以将容器中提供服务的端口映射到宿主机端口上.
9. 这种操作称之为: 端口映射
# 搜索mysql镜像
docker search mysql
# 拉取mysql镜像
docker pull mysql:5.6
# 创建容器,设置端口映射,目录映射
mkdir ~/mysql
cd ~/mysql
docker run -id \
-p 3307:3306 \
--name=c_mysql \
-v $PWD/conf:/etc/mysql/conf.d \ # 当前目录/conf映射到容器内conf.d目录. 配置目录
-v $PWD/logs:logs \ # 宿主机当前目录/logs挂载到容器的/logs. 日志目录
-v $PWD/data:/var/lib/mysql \ # 当前目录data挂载到容器/var/lib/mysql. 数据目录
-e MYSQL_ROOT_PASSWORD=123321 \ # 初始化root用户的密码
mysql:5.6
tomcat
需求:
在docker容器中部署tomcat,并通过外部机器访问tomcat部署的项目
docker search tomcat
docker pull tomcat
# 创建容器,设置端口映射,目录映射
mkdir ~/tomcat
cd ~/tomcat
docker run -id --name=c_tomcat \
-p 8080:8080 \
-v $PWD:/usr/local/tomcat/webapps \
tomcat
然后
cd ~/tomcat
mkdir test
cd test
touch index.html
# 输入<p>hello world</p>
vim index.html
然后在外部机器即可访问该网页
redis
docker pull redis:5.0
docker run -id --name=c_redis -p 6379:6379 redis:5.0
# 使用外部机器链接redis
./redis-cli.exe -h ip地址 -p 6379
nginx
需求:创建一个nginx容器,修改容器内的html目录内的index.html内容
分析:上个案例中,我们进入nginx容器内部,已经知道nginx的html目录所在位置/usr/share/nginx/html ,我们需要把这个目录挂载到html这个数据卷上,方便操作其中的内容。
提示:运行容器时使用 -v 参数挂载数据卷
步骤:
① 创建容器并挂载数据卷到容器内的HTML目录
docker run --name mn -v html:/usr/share/nginx/html -p 80:80 -d nginx
② 进入html数据卷所在位置,并修改HTML内容
# 查看html数据卷的位置
docker volume inspect html
# 进入该目录
cd /var/lib/docker/volumes/html/_data
# 修改文件
vi index.html
Dockerfile
docker镜像制作的两种方法
- 容器转为镜像
docker commit 容器id 镜像名称:版本号
docker save -o 压缩文件名称 镜像名称:版本号
docker load -i 压缩文件名称
- dockerfile
dockerfile概念
- dockerfile时一个文本文件
- 包含一条条的指令
- 每一条指令用于构建一层,基于基础镜像,最终构建出一个新的镜像
常用命令
- FROM 指定父镜像
- MAINTAINER 作者
- LABEL 标签
- RUN 执行命令
- CMD 提供容器启动时的默认命令
- COPY 复制文件(build过程中复制文件到image中)
- ADD 添加文件(不仅局限于build上下文,可以源自远程服务)
- ENV 环境变量
- ARG 构建参数
案例
- 本地创建springboot项目
- maven package打包
- 将jar包上传到
~/
目录下
cd ~
mkdir docker-files
cd docker-files
mv ~/xx.jar springboot_app.jar # jar包拷贝到当前文件夹下
docker pull openjdk:11
vim app_dockerfile
[
FROM openjdk:11
MAINTAINER yfx
ADD springboot_app.jar app.jar
CMD java -jar app.jar
]
docker build -f ./app_dockerfile -t app .
docker run -id -p 9000:8080 app
即可在外部机器通过9000端口访问该springboot项目
docker 服务编排
服务编排概念
微服务架构的应用系统中一般包含若干个微服务,每个微服一般都会部署多个实例(为了高可用),如果每个微服务都要手动启停,维护工作量很大
- 要从dockerfile build image 或者从dockerhub拉取image
- 创建多个container
- 管理这些container(启动停止删除)
服务编排: 按照一定的业务规则批量管理容器
docker compose概述
Docker Compose是一个编排多容器分布式部署的工具,提供命令集管理容器化应用的完整开发周期,包括服务构建,启动和停止.使用步骤:
- 利用Dockerfile定义运行环境镜像
- 使用docker-compose.yml定义组成应用的个服务
- 运行docker-compose up启动应用
与k8s区别:
- docker compose: 专注于单个主机上的容器编排
- k8s: 专注于多主机配置的容器集群管理。
安装
# 先安装docker,二进制包方式安装(无法下载,就去github下载,再上传到服务器)
curl -L https://github.com/docker/compose/releases/download/v2.21.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
# 或者尝试
yum install -y docker-compose
# 设置文件可执行权限
chmod +x /usr/local/bin/docker-compose
# 查看版本信息
docker-compose -v
# 卸载
rm /usr/local/bin/docker-compose
案例
需求: 使用docker-compose 编排nginx+springboot项目
- 创建docker-compose目录
mkdir ~/docker-compose
cd ~/docker-compose
- 编写dokcer-compose.yml文件
version: '3'
services:
nginx:
image: nginx
ports:
- 80:80
links:
- app
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
app:
image: app
expose:
- "8080"
- 创建./nginx/conf.d目录
mkdir -p ./nginx/conf.d
- 在./nginx/conf.d目录下 编写xxx.conf文件
server {
listen 80;
access_log off;
location / {
proxy_pass http://app:8080;
}
}
# 注: docker同一网段可以用容器名访问
知识补充(来自chatgpt):
在Docker Compose中,links 参数用于定义服务之间的连接,以建立容器之间的网络通信。该参数已经过时(deprecated),不建议在新的Compose文件版本中使用,而是应该使用 Docker Compose 网络(networks)来实现容器之间的通信。
在较早的Docker Compose版本中,links 参数用于在容器之间创建连接,允许一个容器可以通过另一个容器的名称来访问该容器的服务。这种连接允许容器之间建立网络通信,以便服务可以相互访问。
例如,以下是一个使用 links 参数的Docker Compose示例:
Copy code
version: '2'
services:
webapp:
image: my-webapp
ports:
- "8080:8080"
database:
image: postgres
links:
- webapp
在上面的示例中,database 容器链接到了 webapp 容器。这意味着 database 容器可以通过 webapp 容器的名称来访问 webapp 提供的服务,例如通过 http://webapp:8080 来访问 webapp 服务。
然而,随着Docker Compose的发展,推荐使用更灵活和强大的网络定义方式,即使用 networks 参数来定义自定义网络,并将容器连接到这些网络。这种方式更清晰、更可控,并提供更多选项,例如可以将多个容器连接到同一个网络,实现更复杂的网络拓扑。
下面是一个示例,演示如何使用 networks 参数连接容器:
Copy code
version: '3'
services:
webapp:
image: my-webapp
ports:
- "8080:8080"
networks:
- mynetwork
database:
image: postgres
networks:
- mynetwork
networks:
mynetwork:
在这个示例中,我们定义了一个名为 mynetwork 的自定义网络,并将 webapp 和 database 容器连接到这个网络。这种方式更加灵活,使网络拓扑更易于管理。因此,对于新的Compose文件,推荐使用 networks 来代替 links 参数。
docker私有仓库
搭建私有仓库
# 1. 拉取私有仓库镜像
docker pull registry
# 2. 启动私有仓库镜像
docker run -id --name=registry -p 5000:5000 registry
# 3. 打开浏览器 输入地址http://私有仓库服务器ip:5000/v2/_catalog,看到{"repositories":[]} 表示私有仓库搭建成功
# 4. 修改daemon.json
vim /etc/docker/daemon.json
# 在上述文件中添加一个key,保存退出.此步用于让docker信任私有仓库地址,注意将私有仓库服务器ip修改为自己私有仓库服务真实ip
{"insecure-registries":["私有仓库服务器ip:5000"]}
# 5.重启docker服务
systemctl restart docker
docker start registry
上传镜像到私有仓库
# 1. 标记镜像为私有仓库镜像
docker tag centos:7 私有仓库IP:5000/centos:7
# 2. 上传标记的镜像
docker push 私有仓库服务器ip:5000/centos:7
从私有仓库拉取镜像
# 拉取镜像
docker pull 私有仓库ip:5000/centos:7
参考资料: 链接