docker 基础命令
启动、重启容器
# docker start 容器id
$ docker start 345678765
# 后台启动 docker run -d 镜像名
$ docker run -d centos #启动后就停止,因为没有前台运行程序,docker把它停掉了
# 启动并进入容器
# docker run -it 容器名称 /bin/bash
$ docker run -it centos /bin/bash
# 重启容器 docker restart 容器id
$ docker restart 345678765
退出容器
# 退出容器
# exit #回停止容器的运行
# 使用 Ctrl+ p +q 不停止容器退出
ning@DESKTOP-1BQCBJ0:~$ docker run -it centos
[root@52a938078f80 /]# ning@DESKTOP-1BQCBJ0:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS
52a938078f80 centos "/bin/bash" 12 seconds ago Up 10 seconds
停止容器
$ docker stop 容器id # 停止当前正在运行的容器
$ docker kill 容器id # 强制停止当前正在运行的容器
查看容器的进程信息 和 容器
# 命令 docker top 容器id
$ docker top 0668b6e0960f
UID PID PPID C STIME
999 2120 2100 0 07:23
# 查看正在运行的容器
$ docker ps
# 查看所有容器,包括历史运行的容器
$ docker ps -a
# 查看所有容器的id
$ docker ps -aq
删除镜像
$ docker rmi 镜像id
删除容器
$ docker rm 容器id #删除指定的容器,不能删除正在运行的容器
$ docker rm -f 容器id # 删除容器
$ docker rm -f $(docker ps -aq) #删除所有的容器
日志
# 查看所有日志 docker logs -tf 容器id
$ docker logs -tf 0668b6e0960f
# 查看多少条数据 docker logs -tf --tail 条数 容器id
docker logs -tf --tail 1 0668b6e0960f
查看容器的元数据和信息
# 查看容器的元数据和信息 docker inspect 容器id
$ docker inspect 0668b6e0960f
进入容器中
# ①进入容器中
# 命令 docker exec -it 容器id /bin/bash
ning@DESKTOP-1BQCBJ0:~$ docker exec -it 0668b6e0960f /bin/bash
root@0668b6e0960f:/#
# ②进入容器
# 命令 docker attach 容器id
$ docker attach 0668b6e0960f
# 区别:
# docker exec 进入容器中,会打开一个新的终端,可以操作
# docker attach 进入容器中正在执行的终端,不会启动新的进程
文件拷贝从容器内拷贝到主机
#创建文件 touch 文件名.类型
$ touch ning.java
# docker cp 容器id:文件绝对路径 要拷贝到的位置
$ docker cp df81fd7552f2:/home/ning.java /home
# 拷贝文件夹下所有内容,递归操作
$ cp -r webapps.dist/* webapps #拷贝webapps下dist目录中所有文件到webapps中
提交镜像
docker commit -m="作者" 容器id 目标镜像名称:[tag]
# 然后docker images就可以看到自己提交的镜像
# 因为docker提供的镜像比较精简小巧,删除了大部分的东西,只保留基础的东西,例如tomcat的webapps下面是空的没# 有应用,这时候自己可以拷贝一份过来,然后提交镜像,之后再使用tomcat就可以使用自己提交的镜像。
容器数据卷
容器数据同步到本地。容器内数据的存储位置映射到本地路径来达到数据安全的目的,保证容器删除数据不丢失;
总的来说就是容器的持久化和同步操作。容器间可以数据共享,这样可以多个容器绑定到一个目录,方便查看管理;
- 使用命令双向绑定目录 -v
# 主机home目录下的test文件夹映射容器内的home文件夹,不论哪边变化都会同步,如果停止容器,
# 在主机文件夹下修改,容器内的文件同样会被同步修改;使用-v,和使用-p类似
# docker run -it -v 主机目录:容器内的目录 容器名称
$ docker run -it -v /home/test:/home centos
不止是同步数据方便,修改容器的配置文件同样,将路径映射,只需要在主机进行配置文件的修改,容器中的配置文件自动同步,不需要每次修改配置文件都进入容器中;
这样的操作存储空间的占用是双倍的;
容器中的目录或者文件删除了,主机的文件或目录不会被删除;
多个挂载的话可以使用多个-v
- 匿名挂载和具名挂载
匿名就是不指定挂载卷的名称,默认是一串数字+字母
# -d 后台运行 -P大写的P随机端口 --name指定容器名称 -v数据卷挂载,随机名称和创建容器一致主机路径
docker run -d -P --name nginx01 -v /ect/nginx nginx
具名挂载就是不指定主机路径,指定挂载卷名称
# 挂载卷名为ning,使用 docker volume ls 查看数据卷可以看到
docker run -d -P --name nginx02 -v ning:/ect/nginx nginx
docker file
命令:
# FROM 指定那种镜像作为创作镜像的基础镜像
# MAINTAINER 指明该镜像的作者和其电子邮件
# RUN 在新镜像内部执行的命令,可以使用\来换行
# COPY 将主机的文件复制到镜像内,如果目的位置不存在,Docker会自动创建所有需要的目录结构
# 注意:需要复制的目录一定要放在Dockerfile文件的同级目录下
# ADD 将主机的文件复制到镜像中,往镜像中添加内容
# EXPOSE 暴露端口为主机做映射
# WORKDIR 镜像的工作目录
# ONBUILD 当一个包含ONBUILD命令的镜像被用作其他镜像的基础镜像时,执行该命令
# VOLUME 挂载目录,数据卷挂载
# CMD 指定容器启动时候运行的命令,只有最后一个生效,命令会被最后一个替代
# ENTRYPOINT 指定容器启动时候运行的命令,不会被覆盖,命令会被追加
# ENV 构建的时候设置环境变量
- 制作一个centos
# 1.编写dockerfile文件
FROM centos
MAINTAINER ning<113202377@qq.com>
EVN MYPATH /usr/local
WORKDID $MYPATH
RUN yum -y install vim
RUN yum -y install net-tools
EXPORE 80
CMD /bin/bash
# 2.通过文件构建镜像 docker build -f dockerfile文件路径 -t 创建的镜像名:版本 .
$ docker build -f ning_centos -t my_centos:1.0 .
# 3.测试运行 运行原来没有的添加上的命令
$ docker run -it my_centos:1.0
查看镜像的制作过程
# 查看镜像的制作过程 docker history 镜像id
$ docker history 8d7e85ea90a9
- 制作Tomcat
FROM centos
MAINTAINER ning<1132023770@qq.com>
COPY 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/jdk1.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
build成功之后,数据卷挂载,双向绑定一下,方便项目的发布和日志文件等等的操作。
- 推送镜像到dockerhub
# 推送镜像到dockerhub
# 1.登录到dockerhub docker login -u 用户名
# 2.推送镜像 docker push 用户名/镜像名称+版本号
springboot 微服务打包docker镜像
- 创建springboot项目,写入测试代码打包
- 创建
Dockerfile
FROM java:8
COPY *.jar /app.jar
CMD ["--server.port=8080"]
EXPOSE 8080
ENTRYPOINT ["java","-jar","app.jar"]
- 上传文件到服务器
- 切换到文件夹位置,执行
Dockerfile
文件,生成镜像
docker build -t springboot-webserver .
- 运行镜像
docker 容器互连
查看网路模式
ning@DESKTOP-1BQCBJ0:~$ docker network ls
NETWORK ID NAME DRIVER SCOPE
1fdad9d9dd06 bridge bridge local
0770dfdc1c7c host host local
c7cc8e75dd17 none null local
容器互连
由于使用ip地址的话每次项目更新或者重启,IP地址都会发生改变,如果像微服务那样可以直接使用微服务名称调用来替代地址就好了,尝试一下:
启动两个镜像,由于没有指定–name,使用它自己生成的condescending_lichterman
和infallible_curran
,
ping一下,不行
ning@DESKTOP-1BQCBJ0:~$ docker exec -it condescending_lichterman ping infallible_curran
ping: infallible_curran: Name or service not known
解决方式
- 使用–link
启动的时候使用–link来指定它连接的容器
# 停止所有的容器
docker stop $(docker ps -aq)
# 启动容器
# 启动一个centos命名为centos01
docker run -it --name centos01 centos
# 再启动一个命名为centos02,并且使用--link连接01
docker run -it --name centos02 --link centos01 centos
# 再ping一下
ning@DESKTOP-1BQCBJ0:~$ docker exec -it centos02 ping centos01
PING centos01 (172.17.0.2) 56(84) bytes of data.
64 bytes from centos01 (172.17.0.2): icmp_seq=1 ttl=64 time=0.839 ms
64 bytes from centos01 (172.17.0.2): icmp_seq=2 ttl=64 time=0.134 ms
64 bytes from centos01 (172.17.0.2): icmp_seq=3 ttl=64 time=0.111 ms
64 bytes from centos01 (172.17.0.2): icmp_seq=4 ttl=64 time=0.114 ms
64 bytes from centos01 (172.17.0.2): icmp_seq=5 ttl=64 time=0.178 ms
64 bytes from centos01 (172.17.0.2): icmp_seq=6 ttl=64 time=0.108 ms
64 bytes from centos01 (172.17.0.2): icmp_seq=7 ttl=64 time=0.109 ms
64 bytes from centos01 (172.17.0.2): icmp_seq=8 ttl=64 time=0.112 ms
--- centos01 ping statistics ---
8 packets transmitted, 8 received, 0% packet loss, time 287ms
rtt min/avg/max/mdev = 0.108/0.213/0.839/0.237 ms
使用01ping一下02
ning@DESKTOP-1BQCBJ0:~$ docker exec -it centos01 ping centos02 centos
ping: centos: Name or service not known
反向的不通,看来是02绑定的01是单向的。
查看一下02的容器id使用inspect
看一下详情
docker inspect 0d40035dd984
并没有和绑定相关的。。。看一下02的hosts
文件:
ning@DESKTOP-1BQCBJ0:~$ docker exec -it centos02 cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2 centos01 ad92ae905a83
172.17.0.3 0d40035dd984
发现02原来是把01的地址配置在hosts
文件里面了,查看一下01:
ning@DESKTOP-1BQCBJ0:~$ docker exec -it centos01 cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2 ad92ae905a83
--link
就是把要连接的容器的ip地址、容器名称和id配置到自己的hosts文件中来实现的。所以02可以ping通01,01没有配置,ping不通02。。。
- 使用自定义网络network
查看命令:
ning@DESKTOP-1BQCBJ0:~$ docker network --help
Usage: docker network COMMAND
Manage networks
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
Run 'docker network COMMAND --help' for more information on a command.
可以看到create
,创建一个网络,查看一下:
ning@DESKTOP-1BQCBJ0:~$ docker network create --help
Usage: docker network create [OPTIONS] NETWORK
Create a network
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
创建自定义网络,使用bridge桥接模式
docker network create -d bridge my-bridge-network
# 可以根据命令指定参数,例如子网、网关等
docker network create \
--driver=bridge \
--subnet=172.28.0.0/16 \
--ip-range=172.28.5.0/24 \
--gateway=172.28.5.254 \
br0
查看网络:
ning@DESKTOP-1BQCBJ0:~$ docker network ls
NETWORK ID NAME DRIVER SCOPE
128ccbd791ce bridge bridge local
0770dfdc1c7c host host local
dfeccced9d2f my-bridge-network bridge local
c7cc8e75dd17 none null local
拿到创建的网络my-bridge-network
的网络id查看其详情:
ning@DESKTOP-1BQCBJ0:~$ docker inspect dfeccced9d2f
[
{
"Name": "my-bridge-network",
"Id": "dfeccced9d2fd706cfb317385e241f35fee9feae6271d1d85cc22dfc4781e125",
"Created": "2021-09-03T06:58:14.9835961Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
使用刚刚创建的网络my-bridge-network
:
启动容器的时候,使用--network
来将容器添加到my-bridge-network
网络中:
# 停止先前的容器
docker stop $(docker ps -aq)
# 删掉这两个容器
docker rm $(docker ps -aq)
# 启动第一个centos命名为centos01并连接到my-bridge-network网络
docker run -it --name centos01 --network=my-bridge-network centos
# 启动第二个centos命名为centos02并连接到my-bridge-network网络
docker run -itd --name centos02 --network=my-bridge-network centos
# ping一下 01到02
ning@DESKTOP-1BQCBJ0:~$ docker exec -it centos01 ping centos02
PING centos02 (172.18.0.3) 56(84) bytes of data.
64 bytes from centos02.my-bridge-network (172.18.0.3): icmp_seq=1 ttl=64 time=0.333 ms
64 bytes from centos02.my-bridge-network (172.18.0.3): icmp_seq=2 ttl=64 time=0.089 ms
64 bytes from centos02.my-bridge-network (172.18.0.3): icmp_seq=3 ttl=64 time=0.113 ms
64 bytes from centos02.my-bridge-network (172.18.0.3): icmp_seq=4 ttl=64 time=0.145 ms
64 bytes from centos02.my-bridge-network (172.18.0.3): icmp_seq=5 ttl=64 time=0.068 ms
# 反向ping一下
ning@DESKTOP-1BQCBJ0:~$ docker exec -it centos02 ping centos01
PING centos01 (172.18.0.2) 56(84) bytes of data.
64 bytes from centos01.my-bridge-network (172.18.0.2): icmp_seq=1 ttl=64 time=0.162 ms
64 bytes from centos01.my-bridge-network (172.18.0.2): icmp_seq=2 ttl=64 time=0.130 ms
64 bytes from centos01.my-bridge-network (172.18.0.2): icmp_seq=3 ttl=64 time=0.076 ms
64 bytes from centos01.my-bridge-network (172.18.0.2): icmp_seq=4 ttl=64 time=0.172 ms
64 bytes from centos01.my-bridge-network (172.18.0.2): icmp_seq=5 ttl=64 time=0.075 ms
补充没有使用ip来ping的原因:
所有的容器都在docker容器中,docker容器的启动会创建一个网络docker0,也就是docker network ls
拿到的数组中的1fdad9d9dd06 bridge bridge local
,桥接的模式,容器内的ip都是它分配的,有种路由器的感觉,类似于内网的使用,处于同一内网下的两个机子可以通信,没有使用ip来ping,因为他们都处在docker0的网络下,一定是可以ping通的;而且每次项目启动或者重启都会重新分配一个新的ip,需要重新配置,使用名称来替代更加的方便。
docker官方文档https://docs.docker.com/reference/