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就可以使用自己提交的镜像。

容器数据卷

容器数据同步到本地。容器内数据的存储位置映射到本地路径来达到数据安全的目的,保证容器删除数据不丢失;

总的来说就是容器的持久化和同步操作。容器间可以数据共享,这样可以多个容器绑定到一个目录,方便查看管理;

  1. 使用命令双向绑定目录 -v
# 主机home目录下的test文件夹映射容器内的home文件夹,不论哪边变化都会同步,如果停止容器,
# 在主机文件夹下修改,容器内的文件同样会被同步修改;使用-v,和使用-p类似
# docker run -it -v 主机目录:容器内的目录 容器名称
$ docker run -it -v /home/test:/home centos

不止是同步数据方便,修改容器的配置文件同样,将路径映射,只需要在主机进行配置文件的修改,容器中的配置文件自动同步,不需要每次修改配置文件都进入容器中;

这样的操作存储空间的占用是双倍的;

容器中的目录或者文件删除了,主机的文件或目录不会被删除;

多个挂载的话可以使用多个-v

  1. 匿名挂载和具名挂载
    匿名就是不指定挂载卷的名称,默认是一串数字+字母
# -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		  构建的时候设置环境变量
  1. 制作一个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
  1. 制作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成功之后,数据卷挂载,双向绑定一下,方便项目的发布和日志文件等等的操作。

  1. 推送镜像到dockerhub
# 推送镜像到dockerhub 
# 1.登录到dockerhub 	 docker login -u 用户名
# 2.推送镜像  			docker push 用户名/镜像名称+版本号

springboot 微服务打包docker镜像

  1. 创建springboot项目,写入测试代码打包
  2. 创建Dockerfile
FROM java:8
COPY *.jar /app.jar
CMD ["--server.port=8080"]
EXPOSE 8080
ENTRYPOINT ["java","-jar","app.jar"]
  1. 上传文件到服务器
  2. 切换到文件夹位置,执行Dockerfile文件,生成镜像
docker build -t springboot-webserver .
  1. 运行镜像

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_lichtermaninfallible_curran

ping一下,不行

ning@DESKTOP-1BQCBJ0:~$ docker exec -it condescending_lichterman ping infallible_curran
ping: infallible_curran: Name or service not known

解决方式

  1. 使用–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。。。

  1. 使用自定义网络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/