Docker 笔记
介绍
学习 Docker
的笔记,包括镜像、容器、其他常用命令、Dockerfile
和 Docker0
。
帮助命令
docker version # docker version
docker info # 显示 docker 的系统信息,包括镜像和容器的数量
docker --help # 帮助命令
镜像命令
查看镜像
docker images # 查看所有镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql 5.7 9cfcce23593a 4 days ago 448MB
mysql latest be0dbf01a0f3 4 days ago 541MB
docker images -a # 查看所有镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql 5.7 9cfcce23593a 4 days ago 448MB
mysql latest be0dbf01a0f3 4 days ago 541MB
docker images -q # 只列出镜像id
搜索镜像
docker search mysql # 搜索 mysql 镜像
docker search mysql -f=stars=3000 # 过滤,只查 stars3000 以上的
下载镜像
docker pull mysql # 下载最新 mysql
docker pull mysql:5.7 # 指定下载 mysql5.7,版本必须是 dockerhub 上写的,要不出错
删除镜像
docker rmi -f be0dbf01a0f3 # 删除镜像,指定 id
docker rmi -f $(docker images -aq) # 删除全部命令
提交镜像
docker commit -a="作者名" -m="消息" 容器id 自定义的容器名:版本号
容器命令
docker pull centos # 下载 centos
启动容器
docker run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND]
--name # 容器名字
-d # 后台方式运行
-it # 使用交互方式运行,进入容器查看内容
-p # 指定容器的端口,例如-p 8080:8080,前面是主机端口后面是容器端口
退出容器
exit # 退出容器,停止运行
ctrl + q + p # 不停止运行退出
列出容器
docker ps # 查看当前运行容器
-a # 查看所有运行过的容器
-n=? # 查看最近的一个
-q # 只显示 id
删除容器
docker rm 容器id
docker rm -f 容器id # 强制删除
docker rm -f $(docker ps -aq) # 删除所有容器
启动和停止容器
docker start 容器id # 启动
docker restart 容器id # 重启
docker stop 容器id # 停止
docker kill 容器id # 强制停止
其他命令
后台启动容器
docker run -d 容器id # 如果没有前台应用,容器启动后会自动启动
查看日志
docker logs -ft -tail 10 容器id # 查看最近 10 条日志
查看进程
docker top 容器id # 查看进程 id
查看进程元数据
docker inspect 容器id # 查看进程元数据,包括状态、主机配置、网络等等
进入当前正在运行容器
docker exec -it 容器id /bin/bash # 开启一个新的终端
docker attach 容器id # 进入容器正在执行的容器,不会新建新的进程
从容器内拷贝文件到主机上
比如在 centos
的 hoome
目录创建 hello.java
,然后拷贝到主机的 home
目录下。
docker cp 容器id:/home/hello.java /home
拷贝是一个手动过程,未来使用 -v 卷的技术,可以实现自动同步。
查看CPU
docker stats
数据卷挂载
docker run -v 主机目录:容器目录 镜像名 # 绑定容器的文件到主机中,不管容器是否运行只要修改文件内容两端都会更新,一端删除后两端都删,但删除容器后主机的文件不会被删
匿名挂载和具名挂载。
docker run -d -P --name nginx01 -v /etc/nginx nginx # 匿名挂载,只写容器的路径,没写容器外的
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx # 具名挂载,指定了名字,方便在主机中
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx # ro 只读,rw 读写。ro 只能在主机改,不能再容器内改
查看卷,未指定主机位置默认在 /var/lib/docker/volumes/挂载名/_data
。
docker volume ls # 查看所有挂载
docker volume inspect juming-nginx # 查看 juming-nginx 这个挂载的位置
Dockerfile
初识Dockerfile
创建一个文件 dockerfile1,内容如下。
FROM centos
VOLUME ["volume1","volume2"]
CMD echo "-----end-----"
CMD /bin/bash
构建镜像。
docker build -f dockerfile1 -t mycentos . # 注意最后有“.”,使用 dockerfile1 创建一个名为 mycentos 的镜像,其中 volume1 和 volume2 是两个匿名挂载的卷
基本命令
命令 | 解释 |
---|---|
FROM | 需要的基础镜像 |
MAINTAINER | 作者,姓名+邮箱 |
RUN | 构建时运行的命令 |
ADD | 需要的文件,COPY 文件,会自动解压 |
WORKDIR | 工作目录,进入容器后的目录 |
VOLUME | 设置卷、挂载到主机的目录 |
EXPOSE | 指定对外的端口 |
CMD | 容器启动时要运行的命令,只有最后一个会运行,其他的会被替代 |
ENTRYPOINT | 容器启动时要运行的命令,可以直接追加命令 |
ONBUILD | 当构建新的继承 Dockerfile 时运行改命令 |
COPY | 复制到容器内,和 ADD 类似 |
ENV | 环境变量,docker 自动设置 |
简单示例
编写配置文件 Dockerfile
(这个文件名是官方标准的,构建时不需要加 -f
),这个镜像可以用 vim
,进入容器后默认目录是 /usr/local
,内容如下。
FROM centos
MAINTANINER gdp<197.316213@qq.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 80
CMD echo $MYPATH
CMD echo "-----end-----"
CMD /bin/bash
还可以查看怎么构建的。
docker history # 查看构建的过程
运行时追加命令。
# 配置文件其中的一行
ENTRYPOINT ["ls", "-a"]
docker run 镜像id -l # 结果解释执行了 ls -al,如果是 CMD 就必须写 ls -al,因为 CMD 是覆盖
复杂示例
Dockerfile文件如下。
FROM centos
MAININTAINER gdp<1970316213@qq.com>
COPY readme.txt /usr/local/readme.txt
ADD jdk-8u11-linux-x64.tar.gz /usr/local/
RUN yum install vim -y
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 PATH $JAVA_HOME/bin
CMD java -version
构建。
docker builder -t centos-java
Docker0
简介
ip addr
显示 docker0
网卡,桥接模式,使用 veth-pair
技术。
docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN
link/ether 02:42:82:2b:d1:53 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
每 -P
一个端口号就创建两个网卡,主机一个,内部一个,docker0相当于交换机,容器间属于内网。
查看所有网络。
docker network ls
网络模式
bridge
桥接模式none
不配置网络host
共享主机网络container
容器网络互通(用的少,局限性大)
使用容器名访问
在 run
的后面加 --link 容器名
,这样容器就能通过容器名而不是 ip
访问,但这知识单向的,本质上就是修改了 hosts
的配置。
自定义网络
创建一个网络。
docker network create mynet --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 # 定义模式、子网、网管
创建两个tomcat。
docker run -d -P --name tomcat01 --net mynet tomcat # 网络在 mynet 下
docker run -d -P --name tomcat02 --net mynet tomcat # 网络在 mynet 下
查看网络里的容器,container
中显示两个 tomcat
。
docker network inspect mynet
测试能否 ping
通,结果是通过 ip
和容器名都能 ping
通。
docker exec -it tomcat01 ping 192.168.0.2
docker exec -it tomcat01 ping tomcat02
不同网络容器连接
就是直接添加到另一个网络中。
docker network connect tomcat03 mynet # tomcat03 连接到 mynet 中
总结
算是入门了,谢谢狂神的教程。