Docker
基本信息
-
官网:
Docker
-
仓库地址:
Docker Hub
- Docker和VMware差不多,只不过是轻量级的
Docker的基本组成
- Images:镜像
- Containers:容器,相当于一台虚拟机
- Registry:Docker仓库
常用命令
- 帮助命令
docker version # 显示Docker版本信息
docker info # 显示Docker系统信息,包括镜像和容器数
docker --help # Docker所有命令
docker [command] --help # 指定命令的使用信息
- 镜像命令
docker images # 查看本地镜像
docker search [name]# 在仓库里搜索镜像
docker pull # 下载镜像,不写tag,默认就是latest
docker rmi -f 镜像id # 强制删除镜像
docker rmi -f 镜像名:tag # 强制删除镜像
docker rmi -f $(docker images -qa) # 删除所有镜像
- 容器命令
docker run -itd [镜像id/镜像名:tag] --name hello -p 3305:3306 /bin/bash # 创建新的容器
# i:允许键盘输入,t:使用虚拟终端,d:设置可以后台运行,--name:给容器起名,-p:指定端口,3305是服务器的端口,3306是容器的端口,/bin/bash:初始命令,使用exit退出(没有设置后台运行会关闭容器)或者ctrl+p+q退出(不关闭容器退出)
# 如果设置为-d,前台没有程序运行,就会立即关闭容器
docker run
docker ps # 查看本地容器
docker start [容器id/容器名] # 启动容器
docker restart [容器id/容器名] # 重启容器
docker stop [容器id/容器名] # 关闭容器
docker kill [容器id/容器名] # 强制关闭容器
docker rm [容器id/容器名] # 删除容器
docker rm -f $(docker ps -qa) # 删除所有容器
# 进入正在运行的虚拟机
docker exec -it [容器id/容器名] /bin/bash # 退出不会关闭容器(推荐)
docker attach [容器id/容器名] # 退出时会关闭容器
- 其他
docker logs [容器id/容器名] # 查看日志
docker top [容器id/容器名] # 查看进程信息
docker inspect [容器id/容器名] # 查看容器的元信息
docker cp [文件名/目录] [容器id/容器名]:[目录] # 主机文件移动到容器里
docker cp [容器id/容器名]:[文件名/目录] [目录] # 容器文件移动到主机里
# 发布镜像
docker commit -m [描述] -a [作者] [容器id/容器名] [目标镜像名/目标镜像名:标签名] # 根据容器创建一个新的镜像
docker login -u [用户名] # 登录Docker仓库
docker tag [源镜像名] [用户名]/[新镜像名] # 打标签,必须包含作者信息,否则无法push
docker push [镜像名] # 发布至Docker仓库
######################### 踩个坑
# docker run -itd --name mynginx -p 80:80 nginx /bin/bash 这条指令创建的容器,80端口不能访问
# 因为/bin/bash把DockerFile里的CMD替换掉了,导致容器的80端口没有启动,去掉即可
数据卷
docker -itd --name mycentos -v /home/centos:/home centos /bin/bash # /home/centos是主机目录,/home是容器目录
docker volume ls # 查看挂载,创建的是匿名挂载
docker -itd --name mycentos -v guazai:/home centos /bin/bash # 这个是具名挂载
# 挂载目录是 /var/lib/docker/volumes/VOLUME-NAME/_data
docker -itd --name mycentos -v guazai:/home[:ro/rw] centos /bin/bash # 这个是具名挂载,对容器,ro是只读,rw是读写
docker -itd --name docker1 -v data:/home centos /bin/bash
docker -itd --name docker2 -volumes-from docker1 centos /bin/bash # 数据卷容器,容器之间实现数据共享
docker -itd --name docker3 -volumes-from docker1 centos /bin/bash
# 如果挂载出现cannot open directory Permission denied
# 解决办法:在挂载目录后多加一个--privileged=true参数即可
DockerFile
- DockerFile指令
关键字 | 说明 |
---|---|
FROM | 基础镜像,当前新镜像是基于哪个镜像的 |
MAINTAINER | 镜像维护者的姓名混合邮箱地址 |
RUN | 容器构建时需要运行的命令 |
EXPOSE | 当前容器对外保留出的端口 |
WORKDIR | 指定在创建容器后,终端默认登录的进来工作目录,一个落脚点 |
ENV | 用来在构建镜像过程中设置环境变量 |
ADD | 将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar压缩包 |
COPY | 类似ADD,拷贝文件和目录到镜像中 |
VOLUME | 容器数据卷,用于数据保存和持久化工作 |
CMD | 指定一个容器启动时要运行的命令,DockerFile中可以有多个CMD指令,但只有最后一个生效 |
ENTRYPOINT | 指定一个容器启动时要运行的命令,和CMD一样 |
ONBUILD | 当构建一个被继承的DockerFile时运行命令,父镜像在被子镜像继承后,父镜像的 ONBUILD被触发 |
- CMD和ENTRYPOINT的区别
# docker run 之后的参数会替换CMD,就像上面说的踩坑
# docker run 之后的参数会被当做参数传递给ENTRYPOINT,之后形成新的命令组合
# CMD和ENTRYPOINT可以写成CMD ls -a,ENTRYPOINT ls -a的形式或者CMD ["ls","-a"],ENTRYPOINT ["ls","-a"]的形式
# ENTRYPOINT命令的时候还是用["ls","-a"]这种形式吧,因为ENTRYPOINT如果写成ENTRYPOINT ls -a,不会拼接docker run后的参数
# 如果CMD,ENTRYPOINT都写了,并且 CMD 指令不是一个完整的可执行命令,那么 CMD 指定的内容将会作为 ENTRYPOINT 的参数
# 如果CMD,ENTRYPOINT都写了,并且 CMD 是一个完整的指令,那么它两会互相覆盖,谁在最后谁生效
- 构建一个镜像
docker build -f [Dockerfile文件路径] -t [镜像名/镜像名:标签名] .
# 最后那个点就是当前目录,也可以写成./,默认会找这个目录下的Dockerfile文件,这样就不用加-f了
- Centos构建
# 原本的centos没有vim和ip,现在把他加上,注意centos版本是7哦
FROM centos:7
MAINTAINER dippersinan<dippersinan@gmail.com>
RUN yum -y install vim
RUN yum -y install initscripts
CMD /bin/bash # 这个可以不用加,使用docker history [镜像名]分析历史改动的时候,他自己会在最开始添加一个CMD /bin/bash
- Tomcat构建
# 在centos中添加jdk和tomcat
FROM centos:7
MAINTAINER dippersinan<dippersinan@gmail.com>
RUN yum -y install vim
ADD jdk-18_linux-x64_bin.tar.gz /usr/local # 貌似文件只能和Dockerfile在同一目录下
ADD apache-tomcat-9.0.67.tar.gz /usr local
ENV MYPATH /usr/local
WORKDIR $MYPATH
ENV JAVA_HOME $MYPATH/jdk-18
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME $MYPATH/apache-tomcat-9.0.67
ENV CATALINA_BASE $MYPATH/apache-tomcat-9.0.67
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080
CMD $MYPATH/apache-tomcat-9.0.67/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.67/logs/catalina.out
- SpringBoot项目构建
# 将SpringBoot项目添加到Java8中
FROM java:8
MAINTAINER dippersinan<dippersinan@gmail.com>
COPY hello.jar /app.jar
EXPOSE 8080
CMD ["java", "-jar", "/app.jar"]
网络
[外链图片转存失败,源站可能有防盗链机
https://imgblog.csdnimg.cn/9caab7dd3cb34041bd6aad6c9ddc917b.png)]
- 基本概念
docker network ls # 查看所有网络
docker network inspect [网络id] # 查看一个具体的网络的详细信息
# docker0是默认的网桥,新建的容器都会放在docker0下
网络模式 | 配置 | 说明 |
---|---|---|
bridge | –net=bridge | 默认值,在 Docker 网桥 docker0 上为容器创建新的网络栈 |
none | –net=none | 不配置网络,用户可以稍后进入容器,自行配置 |
container | – net=[容器名/容器id] | 容器和另外一个容器共享Network namespace |
host | –net=host | 容器和宿主机共享Network namespace |
用户自定义 | –net=自定义网络 | 用户自己使用network相关命令定义网络,创建容器的 时候可以指定为自己定义的网络 |
- 自定义网络
docker network create -d bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
# -d bridge:设置为网桥模式,--subnet:设置子网,--gateway:设置网关
docker run -itd --name hello --net mynet centos /bin/bash # 使用自定义网络
- 网络连通
# 我们自定义了mynet网桥,但是mynet和docker0是不互通的,所以mynet下的容器不能访问docker0下的容器
docker network connect mynet [docker0下的容器名] # 这样该容器就同时在docker0和mynet两个网络中了
版权声明:本文为h1429541165原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。