Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows操作系统的机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。
本学习笔记综合了B站【狂神说Java】Docker最新超详细版教程通俗易懂和2022年Docker compose最新超详细版教程通俗易懂两位大神老师的教程总结而成,感谢B站,感谢老师。
运行环境:deepin-desktop-community-20.2.4-amd64
sudo apt-get autoremove docker docker-engine docker.io containerd runc
curl -fsSL https://get.docker.com|bash -s docker --mirror Aliyun
设置国内镜像
# 创建或修改 /etc/docker/daemon.json 文件
{
"registry-mirrors" : [
"https://registry.docker-cn.com",
"https://docker.mirrors.ustc.edu.cn",
"http://hub-mirror.c.163.com",
"https://cr.console.aliyun.com/"
]
}
# 重启docker服务使配置生效
systemctl daemon-reload
systemctl restart docker.service
# 另一种编辑配置文件
vim /etc/docker/daemon.json
{
"registry-mirrors": [
"https://registry.docker-cn.com",
"https://kfwkfulq.mirror.aliyuncs.com",
"https://pee6w651.mirror.aliyuncs.com",
"https://21qq34jg.mirror.aliyuncs.com"
]
}
安装
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
sudo
# 解决环境变量的问题,切记在普通模式下运行以下命令,不要在root下
sudo groupadd docker
sudo usermod -aG docker $USER
newgrp docker
测试hello world
docker run hello-world
docker --help
docker version
docker
pull # 拉取
push # 推
rm # 删除
docker network --help
create # 创建
ls # 查看
rm # 删除
docker [可行参数] run
# 参数使用方法
--name # my_api 自定义名字
--rm # 关闭后自动删除
--net # 网络选择
--shm-size # 指定共享内存
--volume # ${PWD}:/tmp
-it # 容器内部挂载终端
-d # 后台运行
-p # 端口映射
api:v2 # 容器名
bash # 容器要执行的命令
docker ps [可行参数]
-a # 列出当前运行的,顺带历史运行的容器
-n=? # 显示最近创建的
-q # 只显示容器编号
exit # 退出并停止容器
ctrl + p + q # 退出不停止容器
docker rm # 删除容器,不能删除未停止的容器
docker rm -f $(docker ps -aq) # 强制删除所有容器
docker start 容器id # 启动容器
docker stop 容器id # 停止容器
docker restart 容器id # 重启容器
docker kill 容器id # 强制停止容器
Options:
--details Show extra details provided to logs
-f, --follow Follow log output
--since string Show logs since timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes)
-n, --tail string Number of lines to show from the end of the logs (default "all")
-t, --timestamps Show timestamps
--until string
docker run --name xxx_centos -d centos /bin/sh -c 'while true;do echo xxx xxx xxx;sleep 2;done'
docker logs --details -ft --tail 10 xxx_centos
docker top 容器id
UID PID PPID C STIME TTY TIME CMD
root 10593 10573 0 22:26 ? 00:00:00 /bin/sh -c while true;do echo xxx xxx xxx;sleep 2;done
root 10785 10593 0 22:29 ? 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 2
docker inspect 容器id
# 方式1,进程容器并开启一个新的终端
docker exec -it 容器id bash
# 方式2,进入容器后进入正在打开的终端
docker attach 容器id bash
# 前提是要退出容器,ctrl+P+Q,不能用exit
docker cp 容器id:文件名 主机文件路径
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lzpdbV4P-1639837840354)(image/README/1639321448648.png)]
# 1、搜索nginx,建议网站搜索
docker seach nginx
# 2、拉取nginx
docker pull nginx
# 3、启动容器,启动网页服务切记最后不要跟bash
docker run --name nginx01 -d -p 3344:80 nginx
# 4、测试容器
curl 192.168.1.82:3344
# 5、进入容器
docker exec -it nginx01 bash
# 6、查看nginx
whereis nginx
# 更改配置文件,通过-e增加内存限制
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2
# 查看窗口存活状态
docker stats
安装
docker run --name xxx_redis --rm -d -it -p 6379:6379 redis:latest bash
进入redis
docker exec -it xxx_redis bash
启动redis-server
redis-server --requirepass 123456 -p 6379 6379 > redis.log &
slaveof启动redis-cli
redis-server --slaveof 122.178.1.183 --masterauth 123456 > redis.log &
docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A0ehjmt9-1639837840362)(E:\My Code\Vscode\docker-learning\image\README\1639316914715.png)]
UnionFS:联合文件系统,分层技术
# 命令和git原理类似
docker commit -m="描述信息" -a="作者" 容器id 目标镜像:[TAG]
# 启动tomcat
docker start tomcat01
# 进入容器
docker exec -it tomcat01 bash
# 发现官方的tomcat文件webapps下没有文件
cd webapps
ls webapps
# 复制文件到webapps下
cp /webapps.dist/* /webapps
# 提交新镜像
docker commit -a="xxx" -m="add webapps" 51a9fe7ed96d tomcat_xxx:1.0
# 导出镜像
docker image save -o tomcat_xxx.img tomcat_xxx
解决主机与容器之间的数据共享
容器的持久化和数据同步
容器间也可以共享数据
方式一:使用-v参数 -v 主机目录:容器目录
docker run -it -v ~/My-Code/docker/centos:/home centos bash
方式二:使用dockerfile
自己构建镜像的脚本文件
# dockerfile文件脚本
FROM centos
VOLUME ["volume01", "volume02"]
CMD echo "------end------"
CMD /bin/bash
# 构建命令,`.`代表当前目录,不能忘记,而且要用root权限
sudo docker build -f dockerfile01 -t xxx/centos:1.0 .
# 之后启动容器
docker run --it -d --name xxx_centos 容器id bash
# 使用inspect查看详细信息,root权限进入相应目录查看文件同步情况
cd /var/lib/docker/volumes/97f3202f1c7387fd46dc415e5c6019d52c7ac1cbd8fb1d78b1e9bb4758935b60/_data
匿名挂载
docker run -v 容器目录 # 不添加主机目录
具名挂载
docker run -v 卷名:容器目录
如:系统会自动挂载到:/var/lib/docker/volumes/juming-nginx/_data
-v 容器内目录:ro/rw
ro # readonly 只读
rw # readwrite 读写
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZgYuZjwY-1639837840364)(E:\My Code\Vscode\docker-learning\image\README\微信图片_20211214155413.png)]
# 创建新容器,数据卷共享另一个容器数据卷
docker run -it --name docker02 --volumes-from docker01 xxx/centos:1.0
安装mysql
# 搜索mysql镜像
docker search mysql
# 启动mysql容器
docker run -it -d -p 33306:3306 -v ~/mycode/docker/mysql/conf:/etc/mysql/conf.d -v ~/mycode/docker/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name xxx_mysql mysql:5.7
多个mysql共享数据
# 启动mysql01,此方式为匿名挂载
docker run -it -d -p 33306:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name xxx_mysql01 mysql:5.7
# 启动mysql02
docker run -it -d -p 33306:3306 -e MYSQL_ROOT_PASSWORD=123456 --name xxx_mysql02 --volumes-from xxx_mysql01 mysql:5.7
在执行上面语句后,xxx_mysql02服务启动不长时间会断开,进入xxx_mysql02客户端进mysql后提示错误信息:Can’t connect to local MySQL server through socket ‘/var/run/mysqld/mysqld.sock’
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F7dmNwZw-1639837840366)(E:\My Code\Vscode\docker-learning\image\README\微信图片_20211215084637.png)]
容器之间配置信息的传递,数据卷容器的生命周期一直持续到容器停止使用为止。
但如果持久化到本地,则数据不会丢失。
1、编写dockerfile文件;
2、构建image文件;
3、docker run 运行容器;
4、push之前要登录dockerhub
docker login -u 用户名
5、docker push xxx/docker-xxx image:版本号 (dockerhub、阿里镜像云) # 镜像名带版本号
1、每个保留关键字(指令)都必须是大写字母;
2、指令从上到下顺序执行;
3、# 表示注释;
4、每一个指令都会创建一个新的镜像层,并提交。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IQxtsILf-1639837840369)(E:\My Code\Vscode\docker-learning\image\README\微信图片_20211215101857.png)]
dockerfile是面向开发的,发布项目、做镜像都需要编写dockerfile文件,
docker镜像逐渐成为企业交付的标准,必须掌握。
1、dockerfile: 构建镜像文件的底层源代码;
2、docker image: 以dockerfile构建后的镜像文件,最终生成和发布的产品;
3、docker container: 镜像运行的容器,生成以便提供各种需求的服务器
FROM # 构建镜像时指定的基础镜像
MAINTAINER # 指定维护都信息:姓名+邮箱
RUN # 指定运行的命令
ADD # 需要添加的内容,压缩包形式
WORKDIR # 镜像的工作目录
VOLUME # 挂载主机目录
EXPOSE # 对外暴露的端口
CMD # 指定容器运行后输出的命令,只输出最后一个
ENTRYPOINT # 指定容器运行后输出的命令,会追加
ONBUILD # 构建继承的dockerfile,触发指令
COPY # 类似ADD命令,将我们文件拷贝到镜像中
ENV # 配置环境变量
4、docker build:构建自定义镜像
docker build -f dockerfile路径文件名 -t 生成新镜像名:版本号
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HGPN2xxo-1639837840372)(E:\My Code\Vscode\docker-learning\image\README\微信图片_20211215103804.png)]
1、创建dockerfile文件,vim dockerfile-centos
安装过程中出现Unable to locate package vim问题,网上查解决办法需要update,更新源
FROM debian
MAINTAINER xxx<[email protected]>
ENV MYPATH /home
WORKDIR $MYPATH
RUN apt-get -y update && apt-get -y upgrade
RUN apt-get -y install wget
RUN apt-get -y install vim
RUN apt-get -y install net-tools
RUN apt-get -y install inetutils-ping
RUN apt-get -y install curl
RUN apt-get -y install redis
RUN apt-get -y install nginx
RUN apt-get -y install php7.4-fpm
EXPOSE 80
CMD echo $MYPATH
CMD echo "---end---"
CMD /bin/bash
2、build构建镜像,切记.符号,使用root权限
sudo docker build -f dockerfile-debian -t debian:1.0 .
3、run容器测试
docker run -it -d -P --name xxx debian:1.0 bash
4、查看历史信息
docker history 镜像ID
创建一个支持视频回放的UI测试网络
docker network create test_net
搭建
selenium grid
容器,selenium
要指定共享内存
docker run --net test_net --name test_selenium --rm -d -p 4444:4444 -p 6900:5900 --shm-size="2G" selenium/standalone-chrome:latest
启动UI录制容器
docker run --net test_net --name test_video --rm -d -v ~/mycode/selenium/videos:/tmp/workdir selenium/video:latest
安装vnc viewer,访问ip:6900,密码:secret
打通两个容器的连接,需要用到–link
docker run -d -P -it --name debian02 --link debian01 debian/xxx:1.0
但只能用以下方式ping通
docker exec debian02 ping debian01
不能反向ping通
查看debian02配置hosts
docker exec -it debian02 cat /etc/hosts
目录不建议使用–link方法
查看网络列表
docker network ls
bridge:桥接
host:主机
none:无配置网络
新建网络net_test,–driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1
docker network create --driver bridge --subnet 192.168.0.1/16 --gateway 192.168.0.1 net_test
新建两个容器debian-net01和debian-net02
docker run --net net_test -d -P -it --name debian-net01 debian/xxx:1.0
docker run --net net_test -d -P -it --name debian-net02 debian/xxx:1.0
docker自定义网络的优点:
每个集群使用不同的网络,保证集群的安全和健康
docker exec -it debian-net01 ping debian02
docker exec -it debian-net02 ping debian01
此时debian01和deian02可以ping通
新建一个容器debian01
docker run -d -P -it --name debian01 debian/xxx:1.0
打通新的容器debian03和docker自定义网络,一个容器两个IP
docker network connect net_test debian01
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aNbwZb9Q-1639837840374)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20211218175000296.png)]
搭建redis集群,对redis集群还不是很了解,跟着教程做吧,之后再补习redis
创建一个redis网络
docker network create redis_net --subnet 172.20.0.0/16
创建redis配置文件,循环创建6个
for port in $(seq 1 6); \
do \
mkdir -p /home/deepinxxx/mydata/redis/node-${port}/conf
touch /home/deepinxxx/mydata/redis/node-${port}/conf/redis.conf
cat << EOF >/home/deepinxxx/mydata/redis/node-${port}/conf/redis.conf
port 6379
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.20.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done
启动6个redis容器
docker run -it -p 6371:6379 -p 16371:6379 --name redis01 \
-v /home/deepinxxx/mydata/redis/node-1/data:/data \
-v /home/deepinxxx/mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis_net --ip 172.20.0.11 redis:latest redis-server /etc/redis/redis.conf
docker run -p 6372:6379 -p 16372:6379 --name redis02 \
-v /home/deepinxxx/mydata/redis/node-2/data:/data \
-v /home/deepinxxx/mydata/redis/node-2/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis_net --ip 172.20.0.12 redis:latest redis-server /etc/redis/redis.conf
docker run -p 6373:6379 -p 16373:6379 --name redis03 \
-v /home/deepinxxx/mydata/redis/node-3/data:/data \
-v /home/deepinxxx/mydata/redis/node-3/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis_net --ip 172.20.0.13 redis:latest redis-server /etc/redis/redis.conf
docker run -p 6374:6379 -p 16374:6379 --name redis04 \
-v /home/deepinxxx/mydata/redis/node-4/data:/data \
-v /home/deepinxxx/mydata/redis/node-4/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis_net --ip 172.20.0.14 redis:latest redis-server /etc/redis/redis.conf
docker run -p 6375:6379 -p 16375:6379 --name redis05 \
-v /home/deepinxxx/mydata/redis/node-5/data:/data \
-v /home/deepinxxx/mydata/redis/node-5/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis_net --ip 172.20.0.15 redis:latest redis-server /etc/redis/redis.conf
docker run -p 6376:6379 -p 16376:6379 --name redis06 \
-v /home/deepinxxx/mydata/redis/node-6/data:/data \
-v /home/deepinxxx/mydata/redis/node-6/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis_net --ip 172.20.0.16 redis:latest redis-server /etc/redis/redis.conf
进入一个redis终端
docker exec -it redis01 bash或者sh
创建集群
redis-cli --cluster create 172.20.0.11:6379 172.20.0.12:6379 172.20.0.13:6379 172.20.0.14:6379 172.20.0.15:6379 172.20.0.16:6379 --cluster-replicas 1
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 172.20.0.15:6379 to 172.20.0.11:6379
Adding replica 172.20.0.16:6379 to 172.20.0.12:6379
Adding replica 172.20.0.14:6379 to 172.20.0.13:6379
M: bbc8ef8c257763605f3b6a80a6c3da23314d931f 172.20.0.11:6379
slots:[0-5460] (5461 slots) master
M: 8e7b32c9526902cf6c744c7c820fe948b3bd73cc 172.20.0.12:6379
slots:[5461-10922] (5462 slots) master
M: 14dc3a98da8c89d723aa90bd73aa3359079654af 172.20.0.13:6379
slots:[10923-16383] (5461 slots) master
S: d00bf149775f7f55504fa417fca65dc80c35d94b 172.20.0.14:6379
replicates 14dc3a98da8c89d723aa90bd73aa3359079654af
S: 383c33a26e0cf9d9b6a59eb4caff56ae9807a2b9 172.20.0.15:6379
replicates bbc8ef8c257763605f3b6a80a6c3da23314d931f
S: 0fe51f6f92e5d29ff4127b72a523b2402a671d66 172.20.0.16:6379
replicates 8e7b32c9526902cf6c744c7c820fe948b3bd73cc
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
.
>>> Performing Cluster Check (using node 172.20.0.11:6379)
M: bbc8ef8c257763605f3b6a80a6c3da23314d931f 172.20.0.11:6379
slots:[0-5460] (5461 slots) master
1 additional replica(s)
S: 383c33a26e0cf9d9b6a59eb4caff56ae9807a2b9 172.20.0.15:6379
slots: (0 slots) slave
replicates bbc8ef8c257763605f3b6a80a6c3da23314d931f
M: 14dc3a98da8c89d723aa90bd73aa3359079654af 172.20.0.13:6379
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
M: 8e7b32c9526902cf6c744c7c820fe948b3bd73cc 172.20.0.12:6379
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
S: 0fe51f6f92e5d29ff4127b72a523b2402a671d66 172.20.0.16:6379
slots: (0 slots) slave
replicates 8e7b32c9526902cf6c744c7c820fe948b3bd73cc
S: d00bf149775f7f55504fa417fca65dc80c35d94b 172.20.0.14:6379
slots: (0 slots) slave
replicates 14dc3a98da8c89d723aa90bd73aa3359079654af
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
进入客户端
redis-cli -c
查看信息
cluster info
root@5418be7d647b:/data# redis-cli -c
127.0.0.1:6379> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:2294
cluster_stats_messages_pong_sent:2275
cluster_stats_messages_sent:4569
cluster_stats_messages_ping_received:2270
cluster_stats_messages_pong_received:2294
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:4569
查看节点信息
cluster nodes
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BZbCF1YU-1639837840376)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20211218211501282.png)]
安装
apt-get install docker-compose # 安装
yaml文件
Version: '3' # 指定compose版本号
Service:
api_server: # 服务名称
image: api:v2 # 镜像
environment: # 环境变量
- DATABASE_URL='mysql://api_v2:[email protected]/api_v2'
- TEST=1
posts:
- "80:80"