1、解决的问题
1.1统一标准
-
应用构建
就是说 市面上有高很多的原生代码写成的程序,需要打成各种各样的软件包取运行,docker构建应用的思想类似于win的将所有软件打包成.exe文件的思路,将所有应用通过docker build ...构建出来,这就是镜像。
-
应用分享
所有的软件镜像放到一个指定的地方 docker hub仓库里面,它就有点类似于安卓手机的应用市场,想要使用哪个软件直接取下载即可。 就有点类似于安卓手机的应用市场,想要使用哪个软件直接取下载即可。
虚拟化技术
容器化技术
1.2资源隔离
- cpu、内存资源隔离与限制
- 访问设备隔离与限制
- 网络隔离与限制
- 用户、用户组隔离与限制
- ...
2、架构
-
Docker_Host:
- 安装docker的主机
-
Docker Daemon:
- 运行在Dokcer主机上的Docker后台进程
-
Client:
- 操作Docker主机的客户端(命令行、UI等)
-
Resgistry:
- 镜像仓库
- Docker Hub
-
Containers:
- 容器,由镜像启动起来正在运行中的程序
3、安装
3.1、centos下安装Docker
3.1.1 移除以前的docker相关包
yum remove docker*
3.1.2 配置yum源
sudo yum install -y yum-utils
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
3.1.3 安装docker
sudo yum install -y docker-ce docker-ce-cli containter.io
3.1.4 启动
systemctl enable docker --now
3.1.5 配置加速
这里添加了docker生产环境和新配置cgroup
https://82m9ar63.mirror.aliyuncs.com 到阿里云上找自己的加速器地址
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<- `EOF`
{
"registry-mirros":["https://82m9ar63.mirror.aliyuncs.com"],
"exec-opts":["native.cgroupdriver=systemd"],
"log-driver":"json-file",
"log-opts":{
"max-size":"100m"
},
"storage-driver":"overlay2"
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
4、基础实战
4.1 找镜像
去hub仓库找到镜像 会有镜像拉去的命令https:///hub.docker.con
docker pull nginx #下载细心版本
# 版本 镜像名:版本名(标签)
docker pull nginx:1.20.1
## 下载来的镜像都在本地
docker images #查看所有镜像
docker rmi nginx #删除镜像 可以写id
4.2启动容器
#docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
#设置项
#-d 后台启动
# --restart=always 设置开机自启动
dcoker run --name=mynginx -d --restart=always -p 88:80 nginx
#查看运行中的程序
docker ps -a
#删除 强制删除 -f
docker rm id/名字
#停止容器
docker stop id/名字
#再次启动
docker start id/名字
#更新某个容器的启动项参数 应用开机自启动
docker upadte id --restart=always
4.3 修改容器内容
4.4.1进容器内修改
#进入容器 其实就是小型linux
docker exec -it 容器ID /bin/bash
#退出
exit
4.4.2 挂载数据到外部修改
4.4提交改变
docker commit -a '作者' -m '描述' 容器ID 镜像名Tag
4.4.1 镜像传输
#保存压缩包
docker save -o abc.tar xxxx:xxx
#别的机器加载
docker load -i abc.tar
4.5 镜像传输
4.4.1 打包传输
#保存压缩包
docker save -o abc.tar xxxx:xxx
#别的机器加载
docker load -i abc.tar
#离线
4.4.2 传到远程仓库
推送到hub
#打标签
docker tag local-image:tagname new-repo:tagname
#登录
docker login
#推送
docker push new-repo:tagname
#退出
docker logout
4.5.3 补充指令
docker logs 容器名/id
docker it 容器名/id /bin/bash
#docker 修改配置文件
docker run -p 80:80 \
-v /data/html:/usr/nginx/html:ro\
-V /data/conf/nginx.conf:/etc/nginx/nginx.conf \
--name nginx2 nginx
#把容器内容复制到外面
#反向写 把外面复制到里面
docker cp 容器ID:/etc/nginx/nginx.conf /data/conf/nginx.conf
5、进阶实战
5.1 将应用打包成镜像
5.1.1 Dockerfile
FROM 后面跟镜像
LABEL 后面是作者
COPY 将jar包拷贝并重命名
ENTRYPOINT 启动命令
FROM oepnjdk:8-jdk-slim
LABEL maintainer=lr
COPY target/*jar /app.jar
ENTRYPOINT ["Java","-jar","/app.jar"
5.1.2 制作镜像
将文件上传到装有docker的机器
#最后的.在当前目录下执行 java-demo 镜像名 v1.0版本
docker build -t java-demo:v1.0 .
6、镜像原理
6.1镜像是什么?
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。
所有的应用,直接打包docker镜像,就可以直接运行起来!
如何得到镜像:
- 从远程仓库下载
- 朋友拷贝给你
- 自己制作一个镜像Dockerfile
6.2 Docker镜像加载原理
unionFS(联合文件系统)
unionFS(联合文件系统):Union文件系统是一种分层、轻量级并且高性能的文件系统,它支撑对文件系统的修改,作为一次提交来一层层的叠加,同时可以将不同的目录挂载到同一个虚拟文件系统下。Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承。基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统堆叠起来,这样最终的文件系统会包含所有底层的文件和目录。
docker镜像的加载原理
docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。
bootfs(boot file system)主要包括bootloader和kernel,bootloader主要是引导加载kernel,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的kernel,自己只需要提供rootfs就可以了。由此可见对于不同的linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以公用bootfs。
分层理解
commit镜像
docker commit 提交容器称为一个新的副本
docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]
7、容器数据卷
7.1什么是容器数据卷
数据不能都在容器中,如果容器删除,数据就丢失!需求:数据可以持久化。容器之间可以有一个数据共享的技术。Docker容器中产生的数据,同步到本地。这就是卷技术!其实就是目录的挂载,将容器内的姆露露挂载到Linux上。
7.2使用数据卷
方式一:直接使用命令来挂载 -v 双向绑定
docker run -it -v 主机目录:容器目录
[root@localhost ~]# docker run -it -v /home/ceshi:/home centos
#查看容器详情
[root@localhost home]# docker inspect a92970c6e2d7
#卷挂载的内容
"Mounts": [
{
"Type": "bind",
"Source": "/home/ceshi",#Host地址
"Destination": "/home",#容器内地址
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
安装MYSQL
#拉取mysql镜像
[root@localhost home]# docker mysql:5.7
#启动容器 安装运行mysql需要配置密码
#官方启动命令
#$ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
[root@localhost home]# docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d \
-v /home.mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name=mysql01 mysql:5.7
#启动成功测试
#在本地创建数据库测试
#删除容器 挂载在本地的数据没有丢失
具名和匿名挂载
#匿名挂载
[root@localhost data]# docker run -d -P --name=nginx01 -v /etc/nginx nginx
[root@localhost data]# docker volume ls
DRIVER VOLUME NAME
local 3cde3976763236089422b48f96abe73723d628d40501f6ad0b3883dd6fb40e3d
#这里发现这种就是匿名挂载,在-v的时候只指定容器内的路径,没有写容器外的路径
#具名挂载 -v 卷名:容器内路径
[root@localhost data]# docker run -d -P -v juming-nginx:/etc/nginx --name=nginx02 nginx
c407eeb3bce36507466f9b6a202dcc9fda4c0aa3b2725328bd05b8ebe1a8f54c
[root@localhost data]# docker volume ls
DRIVER VOLUME NAME
local 3cde3976763236089422b48f96abe73723d628d40501f6ad0b3883dd6fb40e3d
local juming-nginx
[root@localhost data]# docker volume inspect juming-nginx
[
{
"CreatedAt": "2021-11-10T23:47:16+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",
"Name": "juming-nginx",
"Options": null,
"Scope": "local"
}
]
#所有的docker容器内的卷,没有指定目录的情况下都在/var/lib/docker/volumes/juming-nginx/_data这个目录下
#大多数情况下 使用具名挂载
拓展:
#通过 -v 容器内类路径:ro rw 改变读写权限
#ro readonly #只读
#rw readwrite 可读可写
docker run -d -P -v juming-nginx:/etc/nginx:ro --name=nginx02 nginx
docker run -d -P -v juming-nginx:/etc/nginx:rw --name=nginx02 nginx
#只要出现ro 就说明不能在容器内部改变,智能在宿主机改变
方式二 :
#Dockerfile 文件内容
FROM centos
VOLUME ["volume01","volume02"]
CMD echo "----end-----"
CMD /bin/bash
#创建镜像
[root@localhost home]# docker build -f dockerfile1 -t liu/centos:1.0 .
Sending build context to Docker daemon 219.8MB
Step 1/4 : FROM centos
---> 5d0da3dc9764
Step 2/4 : VOLUME ["volume01","volume02"]
---> Running in b3ac4215197f
Removing intermediate container b3ac4215197f
---> 55dc4c63719d
Step 3/4 : CMD echo "----end-----"
---> Running in 3e876214aeea
Removing intermediate container 3e876214aeea
---> 6ecdd77b2f91
Step 4/4 : CMD /bin/bash
---> Running in 607f203d8726
Removing intermediate container 607f203d8726
---> 3394b1bf484f
Successfully built 3394b1bf484f
Successfully tagged liu/centos:1.0
[root@localhost home]#
数据卷容器
多个mysql同步数据!
#启动三个容器
#第一个
docker run -it --name docker01 3394b1bf484f
#第二个 --volumes-from 继承上一个的数据卷 实现数据共享 数据是拷贝的概念
[root@localhost home]# docker run -it --name docker02 --volumes-from docker01 3394b1bf484f