Docker概述
Docker:用来加速构建分享及运行应用的容器
![](https://i-blog.csdnimg.cn/direct/095a9532a54f4da8a1aac20d4436df1f.png)
虚拟机比较笨重,每个虚拟机都需要完整的操作系统
而Docker容器共享宿主机的内核
也就是说Docker容器类似轻量级别的VM
![](https://i-blog.csdnimg.cn/direct/d6346e6a490547008c53bf9a82136689.png)
安装Docker
![](https://i-blog.csdnimg.cn/direct/c03ceee37cb244d5a4d3cc11f8346506.png)
![](https://i-blog.csdnimg.cn/direct/f82b684c91b143f396c7cf1ae92bee23.png)
![](https://i-blog.csdnimg.cn/direct/4294d25394ec40cebb8df9c3a7cd8380.png)
![](https://i-blog.csdnimg.cn/direct/2dd3005b278143d2ac47b7ebfeefbd49.png)
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
![](https://i-blog.csdnimg.cn/direct/a05de0641e8b4c03ad272d95ece75b61.png)
![](https://i-blog.csdnimg.cn/direct/a5d4bc6ef82940b7934dfa7217cb9603.png)
安装必要工具
sudo yum -y install dnf-plugins-core
设置docker的下载镜像 这个适合国外,国内可能有点慢
sudo yum config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
国内用这个
sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
![](https://i-blog.csdnimg.cn/direct/77315bab62f34fc49dd61287d4c4eb1f.png)
安装最新版本docker 包括
sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
启动Docker
sudo systemctl start docker
设置docker开机自启
sudo systemctl enable docker
![](https://i-blog.csdnimg.cn/direct/983f7dfaf5dd4b068f85a50292688107.png)
配置docker镜像加速器
vim /etc/docker/daemon.json
{
"registry-mirrors": [
"https://mirror.baidubce.com",
"https://docker.m.daocloud.io",
"https://docker.mirrors.sjtug.sjtu.edu.cn"
]
}
加载配置
sudo systemctl daemon-reload
如果无法启动 配置vim /etc/docker/daemon.json的时候格式有误
sudo systemctl restart docker
Docker命令
![](https://i-blog.csdnimg.cn/direct/970d1d070d8443c5a3901983ae085e58.png)
docker pull nginx 下载的是最新版本
docker pull nginx:1.26.0 下载的镜像是指定版本 一般来说不需要 因为直接docker run 命令如果没有该镜像会直接下载
docker images和docker image ls命令作用相同都是查看所有下载的镜像
删除镜像
docker rmi nginx:1.26.0 或者docker rmi 唯一id(通过docker images 可以看到 IMAGE ID就是唯一ID)
![](https://i-blog.csdnimg.cn/direct/1dcd14bdbb324460b155240fb3afe87e.png)
以Nginx示例
docker pull nginx:1.26.0 下载指定版本的nginx镜像
![](https://i-blog.csdnimg.cn/direct/faffbdbef0194cb1b6b29d00ef619b3a.png)
docker run nginx:1.26.0 如果直接docker run nginx 会先下载nginx的最新镜像再启动
但是这样启动会占用控制台操作,ctrl+c退出 nginx容器也就停了 因此要用后台启动
mkdir -p /usr/local/develop/nginx/html
docker run -d --name dcnginx \
-p 80:80 \
-v /usr/local/develop/nginx/html:/usr/share/nginx/html \
nginx:1.26.0
进入容器
docker exec -it dcnginx /bin/bash
![](https://i-blog.csdnimg.cn/direct/98639c4e4d974cd98310ee6a99c277bc.png)
docker commit 可以将修改好的容器打包上传
例如 -m 'update index.html' 提交的信息 dcnginx 提交的容器名 mynginx:v1.0 新的image名和版本
docker commit -m 'update index.html' dcnginx mynginx:v1.0
![](https://i-blog.csdnimg.cn/direct/fe892cf39a904ae5bce85f8c5aa3fbe1.png)
然后docker images就可以看到 自己提交的修改后的容器镜像
![](https://i-blog.csdnimg.cn/direct/e7ac809cac254e95aa0a4c45bf32cfbe.png)
docker save -o mynginx.tar mynginx:v1.0 打包成.tar文件默认就是当前目录
docker save -o /usr/local/nginx/images/mynginx.tar mynginx:v1.0 指定将.tar压缩文件放到某个目录下
这样用于传输 那么其他地方就可以用 docker load来加载
例如
docker load -i mynginx.tar 这样就有这个镜像了 然后用docker run 运行
将镜像推送到镜像仓库 方便别人和自己下载
![](https://i-blog.csdnimg.cn/direct/3e49ca549b774d6987f4ee7fd0546270.png)
三个步骤 登录 命名 推送
先在docker.com登录 然后推送到hub.docker.com
命令
docker login 然后输入邮箱 密码 这里超时了
![](https://i-blog.csdnimg.cn/direct/375e5509d6a34363b5d81a7cc8cd9365.png)
如果登录成功 docker hub有规定 需要签名是用户名
docker tag mynginx:v1.0 hrui/mynginx:v1.0
然后docker images 可以看到 多了一个 hrui/mynginx的镜像
docker push hrui/mynginx:v1.0 就推送到docker hub了 然后在docker hub上添加说明
![](https://i-blog.csdnimg.cn/direct/4868d5bcc7d44f808efec45a36b6c632.png)
别人可以通过 hrui/mynginx 搜索
但是如果别人用docker pull hrui/nginx 无法下载最新 因为你没有上传最新的
因此一般都打包一个最新版本上去
docker tag mynginx:v1.0 hrui/mynginx:latest
docker push hrui/mynginx:latest 这样 别人就可以用 docker pull hrui/mynginx 来下载最新
docker ps 查看所有运行中的容器 docker ps -a 查看所有运行中和停止的容器
docker stop 容器名字或者容器ID(docker ps可以查看) 停止某个容器 id可以明确分别可以写前面几位
docker start 容器名字或者容器ID 启动某个容器 id可以明确分别可以写前面几位
docker restart 容器名字或者容器ID 重启容器 id可以明确分别可以写前面几位
docker status 容器名字或者容器ID 查看容器cpu等占用清空 id可以明确分别可以写前面几位
docker rm 容器名字或者容器ID 删除某个已经停止的容器 id可以明确分别可以写前面几位
docker rm -f 容器名字或者容器ID 删除某个容器 即使在运行中 id可以明确分别可以写前面几位
Docker存储
docker存储就是docker的目录挂载,数据卷,让容器数据不丢失.例如不小心删除了容器
另外一点没有挂载数据卷 每次进入容器内部也不方便
删除所有容器 docker ps -a 是显示所有容器(包括停止) docker ps -aq是显示所有容器ID(包括停止)
docker rm -f $(docker ps -aq) 就是删除所有容器(包括停止的容器)
例如 如果/usr/local/develop/nginx/html不存在 会自动创建 这样需要在html里放前端文件也方便
docker run -d --name dcnginx \
-p 80:80 \
-v /usr/local/develop/nginx/html:/usr/share/nginx/html \
nginx:1.26.0
数据挂载和映射卷的区别
像上面 /usr/local/develop/nginx/html:/usr/share/nginx/html 属于数据挂载
数据挂载的话 宿主机的/usr/local/develop/nginx/html里没有内容那么容器内的也会没有内容
如果你想把nginx的nginx.conf配置文件也通过数据挂载方式是不行的,原因是nginx根本无法启动
因为你宿主机可能都没有nginx.conf文件 另外nginx.conf文件要用到的资源也没有
而卷映射能帮我们搞定这点 就是说你容器内有什么,我宿主机就有什么
例如
-v ngconf:/etc/nginx 要求是不能用./或者/开头
那么映射卷位置在哪里
会统一放在**/var/lib/docker/volumes下面 -v ngconf 那么就在/var/lib/docker/volumes/**ngconf
![](https://i-blog.csdnimg.cn/direct/15b309c13dbe44d58b384de6d7207cdc.png)
docker run -d --name dcnginx \
-p 80:80 \
-v /usr/local/develop/nginx/html:/usr/share/nginx/html \
-v ngconf:/etc/nginx \
nginx:1.26.0
![](https://i-blog.csdnimg.cn/direct/3aea7b1be3db41ca8430996260e30781.png)
docker volume ls 可以查看所有卷
docker volume create haha 创建haha卷 都会放到**/var/lib/docker/volumes下**
docker volume rm xxxx xxxx xxxx 可以删除多个卷
删除容器 都不会删除卷 和目录挂载 因为本身他们的作用就是存储数据(当然也方便使用)
Docker网络
默认情况下 每一个docker容器启动后都会加入docker0网络默认分配一个内部ID 这个内部ID可以用来docker容器之间相互通信(如果你选择用宿主机端口,那么好比他在你面前,你要绕一大圈来访问),但是这样情况存在一个问题,就是当容器停止,启动之后 默认的内部IP是有可能发生变化的
通过docker inspect dcnginx 可以查看一个容器的细节
如何用一种稳定的方式让容器内的应用可以相互之间通信(好比以域名的方式)
docker0默认不支持这种以名字访问方式 但是我们可以自定义一个网络
![](https://i-blog.csdnimg.cn/direct/af21fd38051843a6b4842ec4ff73d6a5.png)
docker network create mynet 自定义创建一个mynet的网络
docker network rm xxx删除一个自定义网络
例如 app1
docker run -d --name app1 \
--network mynet \
-p 80:80 \
-v /usr/local/develop/nginx/html:/usr/share/nginx/html \
-v ngconf:/etc/nginx \
nginx:1.26.0
app2
docker run -d --name app2 \
--network mynet \
-p 81:80 \
-v /usr/local/develop/nginx/html:/usr/share/nginx/html \
-v ngconf:/etc/nginx \
nginx:1.26.0
这样容器之间 就可以通过 http://aa1:容器内部端口 直接通过这种方式访问
简略的Redis主从配置
用的是bitnami的镜像 非官方
![](https://i-blog.csdnimg.cn/direct/f896a93a7f33478b876f7a944200dc50.png)
这里注意 如果/app/rd1是root用户提前创建的 很可能出现权限问题 因为容器内没有root权限
所以既然他会自动创建没有必要提前创建好
docker run -d -p 6379:6379 \
-v /app/rd1/bitnami/redis/data \
-e REDIS_REPLICATION_MODE=master \
-e REDIS_PASSWORD=123456 \
--network mynet --name redis01 \
bitnami/redis
docker run -d -p 6380:6379 \
-v /app/rd2/bitnami/redis/data \
-e REDIS_REPLICATION_MODE=slave \
-e REDIS_MASTER_HOST=redis01 \
-e REDIS_MASTER_PORT_NUMBER=6379 \
-e REDIS_MASTER_PASSWORD=123456 \
-e REDIS_PASSWORD=123456 \
--network mynet --name redis02 \
bitnami/redis
![](https://i-blog.csdnimg.cn/direct/51a181b7963e42968526a9264b32242b.png)
可以开通安全组 往redis01里 例如 set key value 然后在连接6380看看主从同步是否生效
Mysql安装
docker run -d -p 3306:3306 \
-v /app/myconf:/etc/mysql/conf.d \
-v /app/mydata:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
--name dcmysql \
mysql:8.0.37-debian
wordPress安装
![](https://i-blog.csdnimg.cn/direct/9db32f0146b643a18735b1c5e74546f8.png)
创建自定义网络
docker network create blog
运行mysql容器
docker run -d -p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-e MYSQL_DATABASE=wordpress \
-v mysql-data:/var/lib/mysql \
-v /app/myconf:/etc/mysql/conf.d \
--restart always --name mysql \
--network blog \
mysql:8.0
运行wordPress容器
docker run -d -p 8080:80 \
-e WORDPRESS_DB_HOST=mysql \
-e WORDPRESS_DB_USER=root \
-e WORDPRESS_DB_PASSWORD=123456 \
-e WORDPRESS_DB_NAME=wordpress \
-v wordpress:/var/www/html \
--restart always --name wordpress-app \
--network blog \
wordpress:latest
Docker Compose
docker批量管理容器的工具 命令
例如将redis mysql 等都写在一个compose.yaml文件
使用compose命令批量上线(第一次创建使用) 批量下线 或者指定启动哪几个应用
![](https://i-blog.csdnimg.cn/direct/16aa5bf19b7c4f22907e10c4a183f628.png)
例如上面的wordPress安装 每次一个个安装太麻烦
可以用个compose.yaml文件一次写好,以后无论在那台机子上部署,都一次到位
![](https://i-blog.csdnimg.cn/direct/82ddd7c44666446d905f9c2c978ec897.png)
编辑好compose.yaml文件之后
docker compose up -d 默认执行的就是compose.yaml
docker compose -f xxxx.yaml up -d 指定compose文件名
![](https://i-blog.csdnimg.cn/direct/a7dc66205a214802b0e1fda990b8c0a2.png)
如果说compose.yaml中某个值变化了 例如端口 卷 挂载等等
重新运行docker compose up -d 会自动判断 默认会重启修改了的容器
docker compose -f compose.yaml down 所有容器下线docker compose down 默认compose.yaml
下线之后 镜像和卷都还在
如果想全部删除
docker compose -f compose.yaml down --rmi all -v 既移除镜像 也移除卷 挂载的需要手动
Compose示例
name: myblog
services:
mysql:
container_name: mysql
image: mysql:8.0
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=123456
- MYSQL_DATABASE=wordpress
volumes:
- mysql-data:/var/lib/mysql
- /app/myconf:/etc/mysql/conf.d
restart: always
networks:
- blog
wordpress:
image: wordpress
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: mysql
WORDPRESS_DB_USER: root
WORDPRESS_DB_PASSWORD: 123456
WORDPRESS_DB_NAME: wordpress
volumes:
- wordpress:/var/www/html
restart: always
networks:
- blog
depends_on:
- mysql
volumes:
mysql-data:
wordpress:
networks:
blog:
Dockerfile
制作自己的镜像 主要是为我们的例如应用的jar包制作镜像
![](https://i-blog.csdnimg.cn/direct/aa821a10c237491d947a0c3e2b0193ec.png)
![](https://i-blog.csdnimg.cn/direct/6af8cd933c964f98a1ad0fd55e22f3b0.png)
编写一个Dockerfile文件
vim Dockerfile
![](https://i-blog.csdnimg.cn/direct/8f9825ab0b894f6eb77c8645af7d289a.png)
![](https://i-blog.csdnimg.cn/direct/9b6dbb2f6dc5494fa75338a4d408ddd1.png)
Docker的分层存储机制
![](https://i-blog.csdnimg.cn/direct/1054315e21d0438f9fc8c5a18247c6c0.png)
![](https://i-blog.csdnimg.cn/direct/ff515567efc844bebb09f0a84764ee9a.png)
可以通过命令
docker image history nginx 查看 有限是相同的 有些是不同的 就是公用了相同的
看起来很多 但是共用了某些存储 看起来是188M+188M 实际可能是188M+了几KB
![](https://i-blog.csdnimg.cn/direct/ec10b8f649f54f499e0be6f59fa29e12.png)