学习记录 留作参考
祝君好运
参考内容:
Docker 命令大全 | 菜鸟教程 (runoob.com)
尚硅谷3小时速通Docker教程,雷神带练docker部署到实战!_哔哩哔哩_bilibili
Docker - 快速通关 (3h) (yuque.com)
docker run imageName
最简单的创建并启动一个容器的命令。启动之后会一直挂在前台。需要增加更多参数来进行配置镜像启动。
docker run -d --name myName -p 81:80 -v host_dir:container_dir imageName
创建并启动一个容器:
-d 采用进程守护方式——容器启动后会在后台继续运行。
--name myName 指定容器的名称,否则docker会生成一个随机的容器名。
-p 81:80 指定端口映射:将宿主机的81端口映射到容器的80端口。
-v host_dir:container_dir 将宿主机的一个目录挂载到容器的一个目录上,就可以实现内部文件的同步。后面有详细讲。
docker ps
展示当前运行着的容器
docker ps -a
展示所有容器(包含已经停止的容器)
docker start 容器id
docker start 容器名
启动一个容器
docker stop 容器id
docker stop 容器名
停止一个容器
这种可以是修改容器的部分代码,然后打包成一个新的tar包,解压到其他机器上再运行。
docker commit -m '提交备注' myContainer newImage:1.0.0
将现有的容器重新打包成一个新的镜像
myContainer 现有的容器,可以是容器名称,也可以是容器id
newImage:1.0.0 新镜像的名称和版本号,其中版本号可选
上一步使用docker commit
之后,就可以通过 docker images
查看到刚刚提交的image镜像了。
docker save -o abc.tar newImage:1.0.0
使用 docker save 可以将刚刚生成的镜像打包输出到指定的tar文件内,方便传递。
docker save -o abc.tar sha256编号
除了通过镜像名称进行打包之外,还可以使用commit得到的 sha256 编码来进行输出。
通过加载上一步得到的 abc.tar
就可以得到刚刚打包的镜像(可以用来在新机器上部署)
docker load -i abc.tar
-i abc.tar 带加载的tar包文件路径
这样会解压成一个新的镜像,完成后可以通过 docker images 就可以查看到新的镜像
新的镜像仍旧通过 docker run -d --name xxx -p 80:80 image_name 来创建并运行容器
登录docker账号,并将打包号的镜像发布到docker仓库。 -- 2024.7之后docker官网就一直打不开了,这部分仅作学习。
首先到官网注册docker账号。然后在命令行输入 docker login
进行登录。
使用 docker tag
命令来给新打包的镜像起一个新的名字,按照docker的规则,待发布到仓库的镜像名称都是 用户名/镜像名 。
docker tag local-img:v1.0 username/new-img-name:v1.0
将本地名为 local-img ,且版本号为 v1.0 的镜像重新命名(创建别名)为 username/new-img-name 版本号为 v1.0
本操作过后,使用docker images 可以查看到以上的两个镜像,镜像名不同,但是他们的镜像id相同
可以使用该命令,将指定的镜像推到docker hub。
需要注意的是指定标签和latest标签是独立的,需要分两次提交。
docker push username/new-img-name:v1.0
推送指定标签的镜像
docker push username/new-img-name
推送默认标签(latest)的镜像
容器的文件系统,精简了很多命令,所以直接进入容器内修改文件会变得非常不方便。如果修改了容器内的文件,并且删除了该容器,那么下次再使用相同命令创建容器时,所得到的容器与之前的容器是不一致的。
因此docker提供了挂载文件系统的功能,可以进行文件和目录的挂载,来新增和修改容器中的文件(在挂载文件时会有问题,此处描述以挂载目录为准)。当创建容器时使用了挂载目录,之后又对挂载目录内的文件进行了修改,等下次再使用同样命令创建容器时,所得到的容器与之前的容器是一致的。
方法:在 docker run -v host_dir:container_dir
来挂载目录
其中,container_dir
必须是容器内的绝对路径。根据 host_dir
的不同,又分为两种情况:
host_dir
使用绝对路径时,表示将宿主机的当前目录挂载到容器内对应目录。目录内的文件将以宿主机为主。
/etc/nginx
,宿主机对应挂载目录必须已经存在必要的文件,否则容器会因为缺少必要的配置文件而无法启动。host_dir
使用卷名/文件夹名。这种方式挂载的目录,将以容器内对应目录的内容为主。容器内该目录有啥,则宿主机该目录内就有啥,且同步修改。
/var/lib/docker/volumes/卷名
。container_dir
内的文件内容会同步 /var/lib/docker/volumes/卷名/_data
。docker volume ls
查看docker内的所有卷,使用 docker volume inspect 卷名
查看指定卷的信息,使用 docker volume rm 卷名
删除指定卷。docker对卷的操作
docker volume ls
列出docker所有的卷
docker volume inspect 卷名
查看指定卷的信息
docker volume rm 卷名1 <卷名2>
删除指定的卷
安装docker后,会自动在本机创建一个名为 docker0
的网络,可以使用 ip a
具体查看,其ip地址为: 172.17.0.1
。
借助docker的网络,容器之间互相访问不需要再经过宿主机。即
宿主机ip:801
和 宿主机ip:802
进行。docker container inspect 容器名
(或者 docker inspect 容器名
)来查看容器的ip。这样上面两个nginx容器,就可以通过 容器的docker0ip:80
来互相访问。使用 ip + 端口号 来配置容器间互相访问可能会存在一些问题,比如容器重启之后,ip就会发生变化,导致原ip失效,或者访问到别的容器。因此docker提供了另一种解决方案,即域名。
docker支持创建多个网络,在同一网络内,可以将容器名作为该容器在本网络下的域名进行访问。同时也可以正常的使用 域名+端口号。
容器的重启不影响域名的使用。
docker network ls
列出docker内所有网络
docker network create <网络名>
创建一个新的docker网络,docker会为其分配新的网段。
docker network rm <网络名>
删除指定网络。如果还有容器使用该网络,则不能删除。
具体使用域名的操作:
docker network create mynet
创建docker网络 mynet
docker network ls
可以查看到刚刚创建的网络
docker run -d --name app1 -p 801:80 --network mynet nginx
使用nginx镜像创建app1容器,配置宿主机801端口代理容器80端口,容器加入mynet网络
docker run -d --name app2 -p 802:80 --network mynet nginx
使用nginx镜像创建app2容器,配置宿主机802端口代理容器80端口,容器加入mynet网络
docker exec -it app1 bash
采用交互的方式登录app1容器内
app1容器内:curl http://app2
在app1容器内,通过docker网络,使用域名访问app2容器的80端口。
综合上面学习的知识,使用 bitnami 发布的 redis 镜像(比redis官方镜像配置更简单),在单机搭建redis主从复制集群。
# 首先创建docker网络: mynet
docker network create mynet
# 在宿主机创建两个用于保存redis持久化存储的目录
# 如果仅测试,可以省略这一步,并且把下面 docker run 的 -v 一行删掉即可。
# -p 参数表示递归的创建文件夹
# -m 777 表示 rd1、rd2 文件夹,所有人都拥有最大权限
mkdir -p -m 777 /data/bitnami/redis/rd1
mkdir -p -m 777 /data/bitnami/redis/rd1
# 创建redis主机实例,加入mynet网络,容器名为redis01,使用宿主机的8001端口代理容器的6379端口,密码为123456
# -v 表示将宿主机的一个目录挂载到容器内对应目录,用于保存持久化内容。容器内对应目录的位置可以在bitnami的线上文档中查询到
docker run -d -p 8001:6379 --network mynet --name redis01 \
-v /data/bitnami/redis/rd1:/bitnami/redis/data \
-e REDIS_REPLICATION_MODE=master \
-e REDIS_PASSWORD=123456 \
bitnami/redis:latest
# 创建redis从机实例,加入mynet网络,容器名为redis02,使用宿主机的8002端口代理容器的6379端口。
# -v 表示将宿主机的一个目录挂载到容器内对应目录,用于保存持久化内容。容器内对应目录的位置可以在bitnami的线上文档中查询到
# 配置主机的地址为redis01,端口为6379,主机密码为123456。从机的密码为1234567
docker run -d -p 8002:6379 --name redis02 --network mynet \
-v /data/bitnami/redis/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=1234567 \
bitnami/redis:latest
# 执行完上述命令之后,可以查看容器是否正常启动
docker ps
# 查看容器的日志,可以查看运行情况
docker logs 容器名
# 如果想要登录redis容器
docker exec -it docker容器名 redis-cli -a 密码
# 测试完成后,停止并删除相关容器及文件
docker stop redis01 redis02
docker rm redis01 redis02
docker network rm mynet
rm -rf /data/bitnami/
方便doucker批量的管理容器,可以设置多个容器同时创建并运行、指定启动和停止已经创建好的容器、对容器的服务进行扩容、对全部容器进行整体的下线(可以删除所使用到的资源)。
docker compose
的全部操作默认读取当前目录下的 compose.yaml
,可以通过 -f xx.yaml
来指定具体的配置文件。2024-08-14 22:51:57 星期三
docker官方对 compose.yaml 文件定义的文档
# 上线:
# 批量创建并运行容器
# -d 后台运行
# -f ab.yaml 以指定文件运行,默认为当前目录的 compose.yaml
docker compose up -d
# 下线:
# 默认将删除容器和网络,保留卷和镜像。具体可通过 <docker compose down --help> 查看
# -f ab.yaml 以指定文件运行,默认为当前目录的 compose.yaml
# -v 删除容器的所有卷
# rmi local|all 删除镜像
docker compose down
# 启动: 启动指定容器
docker compose start x1 x2 x3
# 停止: 停止指定容器
docker compose stop x1 x3
# 扩容: 指定x2应用启动三份(如果不够就会再启动n个)
# 如果使用扩容,就不能在yaml文件中指定容器的名字
docker compose scale x2=3
myblog
的项目。服务名为 mysql
和 wordpress
。使用到的卷为 mysql-data
和 wordpress
。使用到的网络为 blog
。name: myblog
services:
mysql:
container_name: mysql
image: mysql:latest
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=123456
- MYSQL_DATABASE=wordpress
volumes:
- mysql-data:/var/lib/mysql
- /data/myconf:/etc/mysql/conf.d
restart: always
networks:
- blog
wordpress:
container_name: wordpress
image: wordpress:latest
ports:
- "8080:80"
environment:
- WORDPRESS_DB_HOST=mysql
- WORDPRESS_DB_USER=root
- WORDPRESS_DB_PASSWORD=123456
- WORDPRESS_DA_NAME=wordpress
volumes:
- wordpress:/var/www/html
restart: always
networks:
- blog
depends_on:
- mysql
volumes:
mysql-data:
wordpress:
networks:
blog:
docker采用分层存储。容器启动后,镜像的内容是只读的,用户对容器内部的修改,会记录在镜像外面的读写层。当使用一个镜像运行多个容器时,各自容器只有修改的那部分内容属于自己,其他的都是镜像内公用的。所以,当使用同一个镜像运行多个容器,并不会增加多少磁盘占用。同时,当使用镜像A自己制作一个新的镜像B时,多占用的内容也仅仅是新镜像B修改的部分。参照Git的差异存储。