docker学习笔记

docker学习笔记

介绍

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows操作系统的机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。

本学习笔记综合了B站【狂神说Java】Docker最新超详细版教程通俗易懂和2022年Docker compose最新超详细版教程通俗易懂两位大神老师的教程总结而成,感谢B站,感谢老师。

Docker安装

运行环境: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命令

帮助命令

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
shell脚本运行容器
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、docker 安装 nginx

# 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

2、docker 内存限制

#  更改配置文件,通过-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

3、docker安装redis

安装

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)]

Docker镜像

什么是docker镜像

UnionFS:联合文件系统,分层技术

commit镜像

# 命令和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

自己构建镜像的脚本文件

# 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)]

结论

容器之间配置信息的传递,数据卷容器的生命周期一直持续到容器停止使用为止。

但如果持久化到本地,则数据不会丢失。

Dockerfile

步骤

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

Docker网络

link方式

打通两个容器的连接,需要用到–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)]

Docker-compose

安装

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"

你可能感兴趣的:(docker,docker,容器)