Docker使用笔记
docker常用命令小结:
docker version # 显示docker版本版本信息
docker info # 显示docker的系统信息,包括镜像和容器的数量
docker 命令 --help # 帮助命令
docker ps #获取容器ID
docker stop <the-container-id> #停止容器
docker rm <the-container-id> #容器停止后,删除容器。还可以在Docker Dashboard中删除容器
docker port # 查看映射端口对应的容器内部源端口
docker pause # 暂停容器
docker pull # 从docker镜像源服务器拉取指定镜像或者库镜像
docker push # 推送指定镜像或者库镜像至docker源服务器
docker restart # 重启运行的容器
docker rmi # 移除一个或多个镜像 (无容器使用该镜像才可删除,否则需要删除相关容器才可继续或 -f 强制删除)
docker run # 创建一个新的容器并运行一个命令
docker save # 保存一个镜像为一个 tar 包【对应 load】
docker search # 在 docker hub 中搜索镜像
docker start # 启动容器
docker tag # 给源中镜像打标签
docker top # 查看容器中运行的进程信息
docker unpause # 取消暂停容器
docker wait # 截取容器停止时的退出状态值
1. docker 镜像命令:
docker images
# 查看所有本地主机上的镜像
[root@xxx /]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker/getting-started latest 083d7564d904 7 weeks ago 28MB
hello-world latest d1165f221234 5 months ago 13.3kB
#解释
REPOSITORY #镜像仓库源
TAG #镜像标签,版本
IMAGE ID #镜像ID
CREATED #镜像创建时间
SIZE #镜像大小
#可选项
-a, --all Show all images (default hides intermediate images)
--digests Show digests
-f, --filter filter Filter output based on conditions provided
--format string Pretty-print images using a Go template
--no-trunc Don't truncate output
-q, --quiet Only show image IDs
docker search
搜索镜像
[root@xxx /]# docker search mysql
# 可选项
-f, --filter filter Filter output based on conditions provided
--format string Pretty-print search using a Go template
--limit int Max number of search results (default 25)
--no-trunc Don't truncate output
docker pull
下载镜像
# 下载镜像 docker pull 镜像名[:tag]
[root@xxx /]# docker pull mysql
Using default tag: latest #如果不写tag,默认是latest
latest: Pulling from library/mysql
33847f680f63: Pull complete #分层下载,docker image的核心,联合文件系统
5cb67864e624: Pull complete
1a2b594783f5: Pull complete
b30e406dd925: Pull complete
48901e306e4c: Pull complete
603d2b7147fd: Pull complete
802aa684c1c4: Pull complete
715d3c143a06: Pull complete
6978e1b7a511: Pull complete
f0d78b0ac1be: Pull complete
35a94d251ed1: Pull complete
36f75719b1a9: Pull complete
Digest: sha256:8b928a5117cf5c2238c7a09cd28c2e801ac98f91c3f8203a8938ae51f14700fd #签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest #真实地址
#两个等价
docker pull mysql
docker pull docker.io/library/mysql:latest
docker rmi
删除镜像
docker rmi -f 镜像id #删除指定镜像,可通过镜像ID和镜像名称删除
docker rmi -f 镜像id 镜像id 镜像id #删除多个镜像
docker rmi -f $(docker images -aq) #删除全部镜像
2. docker容器命令
docker run [可选参数] image
:新建容器并启动
# docker run [可选参数] image
#参数说明
--name="Name" #容器名字,tomcat01,tomcat02,用来区分容器
-d #后台运行
-it #使用交互方式运行,进入容器查看内容
-p #指定容器的端口
-p ip:主机端口:容器端口
-p 主机端口:容器端口(常用)
-p 容器端口
容器端口
-P #随机指定端口
#例子:docker run -d --name nginx01 -p 80:80 nginx
#启动并进入容器
[C:\Users\qianxxx]# docker run -it centos /bin/bash
[root@a1d6fa87df54 /]# ls #查看容器内的centos,基础版本,很多命令都是不完善的!
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@a1d6fa87df54 /]# exit #从容器中退出,返回主机
docker ps
:列出所有运行的容器
# docker ps #列出正在运行的容器
-a #列出当前正在运行的容器+带出历史运行过的容器
-n=? #显示最近创建的容器。?=1,2,3
-q #只显示容器的编号
退出容器
exit #容器停止,退出
Ctrl+P+Q #容器不停止,退出
删除容器
docker rm 容器id #删除指定容器,不能删除正在运行的容器
docker rm -f $(docker ps -aq) #删除所有容器
启动和停止容器
docker start 容器id #启动容器
docker restart 容器id #重启容器
docker stop 容器id #停止当前正在运行的容器
docker kill 容器id #强制停止当前容器
3. docker其他常用命令
docker run -d 镜像名
:后台启动命令
Tips: 容器使用后台运行,就必须要有一个前台进程,docker发现没有应用,就会自动停止。
docker logs
:查看日志信息
docker top
:查看容器中运行的进程id
docker inspect 容器id
:查看镜像的元数据
docker exec -it 容器id bashshell
: 进入当前正在运行的容器。进入容器后开启一个新的终端,可以在里面操作(常用)
docker attach 容器id
:进入当前正在运行的容器。进入容器正在执行的终端,不会启动新的进程
docker cp 容器id:容器内路径 目的主机路径
:从容器拷贝文件到主机
commit镜像
docker commit #提交容器成为一个新的副本
#命令和git原理类似
docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[tag]
#实战测试
#1.启动一个默认的tomcat
#2.发现这个默认的tomcat没有webapps应用,镜像的原因,官方的镜像webapps下面是没有文件的!
#3.自己拷贝进去基本的文件
#4.将我们自己操作过的容器通过commit提交为一个镜像!我们以后就使用我们自己修改过的镜像即可,这就是我们自己的一个修改的镜像
Docker精髓:容器数据卷、Dockerfile、Docker网络
容器数据卷
将应用和环境打包成一个镜像!
数据?如果数据都在容器中,那么我们容器删除,数据就会丢失!需求:数据可以持久化
MySQL,容器删了,删库跑路!需求:MySQL数据可以存储在本地!
容器之间可以有一个数据共享的技术!Docker容器中产生的数据,同步到本地!这就是卷技术。目录的挂载,将我们容器的目录,挂载到linux上面!
总结一句话:容器的持久化和同步操作!容器间也是可以数据共享的!
#使用数据卷
#方式一:直接使用命令来挂载 -v
# docker run -it -v 主机目录:容器内目录
docker run -it -v /home/ceshi:/home centos /bin/bash
#启动之后可以通过docker inspect 容器id 查看是否挂载成功,在"Mounts"中
好处:修改可以只在本地修改即可,容器会自动同步!双向共享!
具名和匿名挂载
#匿名挂载
# 通过 -v 容器内路径
docker run -d -P --name nginx01 -v /etc/nginx nginx
docker volume ls 查看所有volume的情况
#这里发现,这种就是匿名挂载,我们在-v只写了容器内的路径,没有写容器外的路径!
#具名挂载
#通过 -v 卷名:容器内路径
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
所有docker容器内的卷,没有指定目录情况下都是在 /var/lib/docker/volumes/xxxx/_data
通过具名挂载可以方便的找到我们的一个卷,大多数情况使用具名挂载
#如何确定是具名挂载,还是匿名挂载,还是指定路径挂载?
-v 容器内路径 # 匿名挂载
-v 卷名:容器内路径 # 具名挂载
-v /宿主机路径:容器内路径 # 指定路径挂载
拓展:
#通过-v 容器内路径:ro rw 改变读写权限
ro #readonly 只读
rw #readwrite 可读可写
#一旦设置了容器的权限,容器对我们挂载出来的内容就有限定了!
docker run -d -p --name nginx02 -vjuming-nginx:/etc/nginx:ro nginx
docker run -d -p --name nginx02 -vjuming-nginx:/etc/nginx:rw nginx
#ro 只要看到ro,就说明这个路径只能通过宿主机来操作,容器内部是无法操作的!
数据卷容器
通过 --volumes-from
实现
docker run -it --name docker01 centos #启动docker01容器
docker run -it --name docker02 --volumes-from docker01 centos#启动docker02容器,并与docker01绑定,docker01叫数据卷容器,docker01内容变化,docker02也会变,双向拷贝
#删除docker01,docker02内容依然存在
结论:容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止。但是一旦持久化到了本地,这个时候,本地的数据是不会删除的。
Dockerfile
Dockerfile介绍:
dockerfile是用来构建docker镜像的文件!命令参数脚本!
构建步骤:
1.编写一个dockerfile文件
2.docker build 构建成为一个镜像
3.docker run 运行镜像
4.docker push 发布镜像(DockerHub、阿里云镜像仓库)
很多官方镜像都是基础包,很多功能都没有,我们通常需要搭建自己的镜像!
Dockerfile构建过程:
基础知识:
1.每个保留关键字(命令)都必须是大写字母
2.执行从上到下顺序执行
3.#表示注释
4.每个指令都会创建提交一个新的镜像层,并提交
Dockerfile是面向开发的,我们以后要发布项目,做镜像,就需要编写dockerfile文件,这个文件十分简单!
Docker镜像逐渐成为企业交付的标注,必须要掌握!
Dockerfile:构建文件,定义了一切的步骤,源代码
DockerImages:通过Dockerfile构建生成的镜像,最终发布和运行的产品!
Docker容器:容器就是镜像运行起来提供服务器
Dockerfile的指令
FROM #基础镜像,一切从这里开始构建
MAINTAINER #镜像是谁写的,姓名+邮箱
RUN #镜像构建的时候需要执行的命令
ADD #步骤,搭建tomcat镜像,这个tomcat压缩包就是添加内容
WORKDIR #镜像的工作目录
VOLUME #挂载的目录
EXPOSE #暴露端口
CMD #指定这个容器启动时要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT #指定这个容器启动时要运行的命令,可以追加命令
ONBUILD #当构建一个被继承dockerfile,这个时候就会运行ONBUILD的指令,触发指令
COPY #类似ADD,将我们的文件拷贝到镜像中
ENV #构建的时候设置环境变量
一个例子:
#1. 编写Dockerfile文件 mydockerfiel-centos
FROM centos
MAINTAINER xxx<xxx@qq.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH #$取地址符
RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 80 #镜像暴露的端口
CMD echo $MYPATH #echo:输出
CMD echo "....end...."
CMD /bin/bash #启动之后进入/bin/bash
#2.
#docker build -f dockerfile文件路径 -t 镜像名:[tag]
docker build -f mydockerfile-centos -t centos .
#3. 测试运行
docker history 镜像id
:列出本地进行的镜像变更历史。我们平时拿到一个镜像,可以研究一下它是怎么做的
CMD和ENTRYPOINT的区别:
FROM centos
CMD ["ls", "-a"] #通过[]添加命令
#docker build -f 3c4c9621ed91 -l 会报错。正确写法:docker build -f 3c4c9621ed91 -al
FROM centos
ENTRYPOINT ["ls", "-a"]
#docker build -f 3c4c9621ed91 -l 正常运行。等同于docker build -f 3c4c9621ed91 -al
#即,ENTRYPOINT的追加命令,是直接拼接在ENTRYPOINT命令后面的
Dockerfile中很多命令都十分相似,我们需要了解他们的区别,我们最好的学习就是对比学习他们,然后测试效果!
实战:Tomcat镜像
1.准备镜像文件tomcat压缩包,jdk压缩包
2.编写dockerfile文件,官方命名Dockerfile
,build
会自动寻找这个文件,就不需要 -f
指定了
3.构建镜像
4.启动镜像
5.访问测试
6.发布项目(由于做了卷挂载,我们直接在本地编写项目就可以发布了)
#编写dockerfile
FROM centos
MAINTAINER xxx<xxx@qq.com>
COPY readme.txt /usr/local/readme.txt #把readme.txt拷贝进/usr/local/readme.txt容器中
ADD jdk-8ull-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.22.tar.gz /usr/local
RUN yum -y install vim
ENV MYPATH /usr/local
WORKDIR $MYPATH
ENV JAVA_HOME /usr/local/jdkl.8.0_11
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.22
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.22
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080
CMD /usr/local/apache-tomcat-9.0.22/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.22/bin/logs/catalina.out
#docker build
docker build -t diytomcat . # docker build 构建一个容器镜像
# -t 标记镜像
# . 告诉Docker应该在当前目录下搜索Dockerfile
#docker run
docker run -d -p 9090:8080 --name xxxtomcat -v /home/xxx/build/tomcat/test:/usr/local/apache-tomcat-9.0.22/webapps/test diytomcat
发布镜像到DockerHub
1.地址https://hub.docker.com/注册自己的账号
2.确定这个账号可以登录
3.在我们的服务器上提交自己的镜像
#docker login --help
Usage:
docker login [OPTIONS] [SERVER] [flags]
docker login [command]
Available Commands:
azure Log in to azure
Flags:
-h, --help Help for login
-p, --password string password
--password-stdin Take the password from stdin
-u, --username string username
4.登录完毕就可以提交镜像了,docker push 作者/镜像名
提交失败可以 docker tag 镜像id 镜像名:1.0
,自己发布镜像尽量带上版本号
发布镜像到阿里云容器服务器
1.登录阿里云
2.找到容器镜像服务
3.创建命名空间
4.创建容器镜像
5.浏览阿里云
小结:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DuhPGWmC-1663680997721)(C:\Users\qianyifei\Desktop\docker.jpg)]
配置阿里云镜像加速
1.登录阿里云,找到容器服务
2.找到镜像加速地址
3.配置使用
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://vymuo4tl.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
Docker网络
理解Docker 0
三个网络:lo
本机回环地址、eth0
阿里云内网地址、docker0
docker0地址
问题:docker是如何处理容器网络访问的
[C:\Users]# docker run -d -P --name tomcat01 tomcat
#查看容器内部网络地址:docker exec -it tomcat01 ip addr,发现容器启动的时候会得到一个eth0@if9 ip地址,docker分配的!
[C:\Users]#docker exec -it tomcat01 ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000
link/ipip 0.0.0.0 brd 0.0.0.0
3: sit0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000
link/sit 0.0.0.0 brd 0.0.0.0
8: eth0@if9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
#思考,Linux能不能ping通容器内部?
[C:\Users]# ping 172.17.0.2
#linux可以ping通docker容器内部 #我没ping通
原理
1.我们每启动一个docker容器,docker就会给docker容器分配一个ip,我们只要安装了docker,就会有一个网卡docker0,桥接模式,使用的技术 evth-pair 技术!
2.再启动一个容器测试,会发现又多了一对网卡!容器带来网卡都是一对一对的,这就是evth-pair技术,就是一对的虚拟设备接口,它们都是成对出现的,一段连着协议,一段彼此相连。正因为有这个特性,evth-pair充当一个桥梁,连接各种虚拟网络设备。OpenStac,Docker容器之间的连接,OVS的连接都是使用evth-pair技术
3.我们来测试一下tomcat01,tomcat02是否可以ping通? tomcat01和tomcat02是公用的一个路由器,docker0。
结论:容器和容器之间是可以相互ping通的。所有的容器不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可用IP。
小结
Docker使用的是linux的桥接,宿主机中是一个Docker容器的网桥docker0
Docker中所有的网络接口都是虚拟的,虚拟的转发效率高!(内网传递文件)
容器互联 --link
思考一个场景,我们编写了一个微服务,database url=ip;项目不重启,数据库ip换了,我们希望可以处理这个问题,可以用名字来进行访问容器?
docker exec -it tomcat02 ping tomcat01
#发现ping不通
docker run -d -P --name tomcat03 --link tomcat02 tomcat
#发现通过--link就可以ping通了
#本质探究:--link 就是我们在hosts配置中增加了一个映射
#我们现在玩docker已经不建议使用--link了
docker0问题:不支持容器名连接访问
自定义网络
docker network ls
: 查看所有的docker网络
[C:\Users]# docker network ls
NETWORK ID NAME DRIVER SCOPE
117f3ac98340 bridge bridge local
d6018c4418e5 host host local
ce196206d421 none null local
#bridge: 桥接docker(默认,自己创建也使用bridge模式)
#none: 不配置网络
#host: 和宿主机共享网络
#container:容器网络连通(用的少局限性很大)
#测试
#我们直接启动的命令 --net bridge,而这个就是我们的docker0, 下面两个等同
docker run -d -P --name tomcat01 tomcat
docker run -f -P --name tomcat01 --net bridge tomcat
#docker0特点,默认,域名不能访问, --link可以打通连接
#我们可以自定义一个网络
#--driver bridge
#--subnet 192.168.0.0/16 #子网 所有的请求支持192.168.0.2到192.168.255.255
#--gateway 192.168.0.1 #路由器网络
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
#docker network命令
[C:\Users]# docker network --help
Commands:
connect Connect a container to a network
create Create a network
disconnect Disconnect a container from a network
inspect Display detailed information on one or more networks
ls List networks
prune Remove all unused networks
rm Remove one or more networks
#docker network create可选项
Options:
--attachable Enable manual container attachment
--aux-address map Auxiliary IPv4 or IPv6 addresses used by
Network driver (default map[])
--config-from string The network from which to copy the configuration
--config-only Create a configuration only network
-d, --driver string Driver to manage the Network (default "bridge")
--gateway strings IPv4 or IPv6 Gateway for the master subnet
--ingress Create swarm routing-mesh network
--internal Restrict external access to the network
--ip-range strings Allocate container ip from a sub-range
--ipam-driver string IP Address Management Driver (default "default")
--ipam-opt map Set IPAM driver specific options (default map[])
--ipv6 Enable IPv6 networking
--label list Set metadata on a network
-o, --opt map Set driver specific options (default map[])
--scope string Control the network's scope
--subnet strings Subnet in CIDR format that represents a
network segment
结论:不使用 --link
也可以ping通。我们自定义的网络docker,都已经帮我们维护好了对应的关系,推荐我们平时这样使用网络!
网络联通
#docker network connect [option] NETWORK CONTAINER
#测试打通tomcat01 - mynet
#连通之后就是将tomcat01放到了mynet网络下
#也就是一个容器两个ip地址
结论:假设要跨网络操作别人,就需要使用docker network connect 连通!
p[])
–ipv6 Enable IPv6 networking
–label list Set metadata on a network
-o, --opt map Set driver specific options (default map[])
–scope string Control the network’s scope
–subnet strings Subnet in CIDR format that represents a
network segment
结论:不使用 `--link ` 也可以ping通。我们自定义的网络docker,都已经帮我们维护好了对应的关系,推荐我们平时这样使用网络!
##### 网络联通
~~~dockerfile
#docker network connect [option] NETWORK CONTAINER
#测试打通tomcat01 - mynet
#连通之后就是将tomcat01放到了mynet网络下
#也就是一个容器两个ip地址
结论:假设要跨网络操作别人,就需要使用docker network connect 连通!