赞
踩
- Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化。
- 容器是完全使用沙箱机制,相互之间不会有任何接口
- docker是client-server结构的系统,守护进程运行在主机上,通过socker与客户端访问
Docker和虚拟机
镜像是一种轻量级的、可执行的软件包,用来打包软件运行环境的和基于运行环境开发的软件,包含某个软件运行时需要的所有内容,包括代码,运行时的库、环境变量和配置文件。
(1) 概念
(2)Unions FS 联合文件系统
UnionsFS是轻量级高性能的文件系统,支持对文件系统的修改作为一次提交来一层层叠加,可以同时将不同目录挂载到同一个虚拟文件系统下。Unions文件系统是docker镜像的基础。镜像可以通过分层来继承,基于基础镜像制作各种特定功能的镜像
(3)分层存储
镜像包含操作系统完整的 root 文件系统,体积往往很庞大, Docker是利用 Union FS 技术,将其设计为分层存储的架构
严格来说,镜像只是一个虚拟的概念,实际体现并不是由一个文件组成,而是由一组文件系统组成,或者说由多层文件系统联合组成。
镜像构建时会一层层构建。每一层构建完成后不会再发生改变,后一层的任何改变只发生在自己这一层。比如,删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除。最终容器运行的时候,虽然不会看到这个文件,但是实际上该文件会一直跟随镜像。
在构建镜像的时候,每一层尽量只包含该层需要添加的东西,任何额外的东西应该在该层构建结束前清理掉。
分层存储、分层下载的特征还使得镜像的复用、定制变的更为容易。当两个应用有相同的层时可以直接复用
(1) 概念
(2)镜像和容器的关系
镜像和容器的关系就像是面向对象程序设计中的类和实例 一样,镜像是静态的定义,容器是镜像运行时的实体。
(3)容器存储层
(1)概念
镜像构建完成后,可以很容易的在当前宿主机上运行,但是,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务
存放镜像的地方,分为公用仓库或者私有仓库。默认的是Docker Hub,国内有容器服务器,可以配置镜像加速
在容器中进行操作后,还可以将容器commit成一个镜像,传到远程仓库后让别人使用
安装前首先要确认你的linux版本,这里以Ubantu为例,具体安装的要求和安装的方法可以在https://docs.docker.com/engine/install/ubuntu/官网查看,比较全面和细节
安装后可能会遇到的问题
docker进程使用Unix Socket而不是TCP端口。而默认情况下,Unix socket属于root用户,需要root权限才能访问,而在Ubuntu18.04安装docker之后,默认以登陆用户身份启动docker,这时候运行docker命令会出错
解决办法
安装docker时,会创建了一个名为docker的用户组,守护进程启动的时候,会默认赋予用户组docker读写Linux socket的权限
所以只要将当前用户加入到docker用户组中,当前用户就有权限访问Linux socket了,进而就可以执行docker相关命令
# 方法一:
sudo gpasswd -a [USER] docker #将登陆用户加入到docker用户组中
newgrp docker #更新用户组
sudo systemctl restart docker #重启docker
#方法二:
sudo passwd root #设置切换root用户的密码
su #切换成root用户
cd /home #进入到home目录
如果用户组docker不存在(安装完一般就有了),则可先创建该用户组:
sudo groupadd docker #创建docker用户组
使用hello-world进行简单测试
docker run hello-world
docker run的流程
log解读
如上显示,说明docker安装测试成功
本篇文章列出的只是部分的docker命令,docker命令尤其的多,想详细了解可以去官方文档查看https://docs.docker.com/engine/reference/commandline/run/
某个镜像的详细部署细节可以在官方仓库去搜索查看https://hub.docker.com/
(1)搜索镜像
docker search mysql
(2)下载镜像
docker pull mysql[版本]
#不选择版本,默认最新版
(3) 查看镜像
docker image ls
(4)删除镜像
docker rmi [image id]
docker rmi -f $(docker image -aq) # 以docker image -aq的查询结果未删除条件,删除相应的镜像
#注意删除镜像前需要先删除镜像对应的容器,不然会报错
有了镜像才可以创建容器,这里先下载centos镜像 docker pull centos
(1)新建容器并启动
docker run [可选参数] image # docker run -it centos /bin/bash
# --name="name" 定义容器名字
# -d 后台方式运行
# -it 前台模式交互运行
# -p 指定容器端口:-p 8080:8080
# -P 随机指定端口
docker run:运行容器,-it:前台交互运行,centos:启动的镜像,/bin/bash :通过bash脚本来执行交互命令
(2)查看运行的容器
# 查看正在运行的容器
docker ps # docker container ls 这俩一样
#查看正在和曾经运行过的容器
docker ps -a
(3)启动和停止容器
docker start 容器id #启动容器
docker restart 容器id #重启容器
docker stop 容器id #停止容器
docker kill 容器id #强制停止容器
(4)查看日志
docker logs
docker logs --tail number # 查看日志的条数
(5)后台启动容器
docker run -d centos # 后台启动
前台启动
Docker会在容器中启动进程,同时将当前的命令行窗口附着到容器的标准输入、标准输出和标准错误中。也就是说容器中所有的输出都可以在当前窗口中看到
后台启动
此时所有I/O数据只能通过网络资源或者共享卷组来进行交互。因为容器不再监听执行docker run的这个终端命令行窗口。但你可以通过执行docker attach
来重新附着到该容器的会话中。
当用后台运行非持续性服务时,比如上面的hello-world,run完之后输出了一个Hello from docker之后容器就会自动退出,容器变成exited状态
(6)查看容器中的进程信息
docker top 容器id
(7)查看容器的元数据
docker inspect 容器id
#docker inspect a7e2c2cd27e4
(8)进入正在运行的容器
# 进入容器后开启一个新的进程,可以在里面进行操作
docker exec -it 容器id /bin/bash
# 进入容器正在执行的终端,不会启动新的进程
docker attach 容器id
(9)从容器内拷贝文件到宿主机上
docker cp 容器id:/文件路径 目标路径 #docker cp 0a534ad32482:/usr/share/nginx/html/index.html ~/
# linux中~/表示根目录
#从宿主机将文件拷贝到容器内
docker cp ~/index.html 0a534ad32482:/usr/share/nginx/html/index.html
(10)退出容器
exit # 直接容器停止并退出
ctrl+p+q # 容器不停止就退出
(11) 删除容器
docker rm [container id] # docker rm 080fdb857a8a
#删除正在运行的容器需要强制 rm -f
docker rm $(docker ps -aq) # 以docker ps -aq为查询条件删除所有容器
docker search nginx
docker pull nginx
docker image ls
docker run -d --name nginx001 -p 8080:80 nginx
# -d后台运行 --name给容器命名 -p 宿主机端口:容器内端口
curl localhost:8080
访问localhost:8080也能看到搭建成功
访问原理
docker stop 080fdb857a8a
容器关闭后,再通过localhost:8080就没法访问了
当你想保存一个容器的状态时,可以将其commit成一个镜像,以后可以直接使用该镜像
下面为构建镜像的原理图,先从远程仓库里push下来我们需要的基础镜像,然后在这些镜像上面加一层可写容器进行自定义功能开发,然后将整体commit成一个镜像,供日后使用。
用nginx为例,将修改过的容器commit成镜像
docker pull nginx
docker run -it -p 8080:8080 nginx
/usr/share/nginx/html/index.html
,这里简单对其进行修改# 进入默认web目录
cd usr/share/nginx/html
# 将需要修改的文件拷贝到宿主机上
docker cp 0a534ad32482:/usr/share/nginx/html/index.html ~/ahua
# 然后在宿主机上对文件进行修改
vim index.html
#将修改后的内容拷贝回容器
docker cp ~/ahua/index.html 0a534ad32482:/usr/share/nginx/html/
# 进入容器
docker exec -it 0a534ad32482 /bin/bash
# 进入默认web目录
cd usr/share/nginx/html
# 查看index.html文件修改情况
cat index.html
宿主机打开localhost:8080
查看
# 和git类似
docker commit -m='描述信息' -a='作者' 容器id 提交后的镜像名:[tag]
#docker commit -m='alter nginx for test docker' -a='ahua' d7c72ba9e6e5 nginx-ahua
# 查看commit后的镜像
docker image ls
-v 宿主机路径:容器路径
docker run -it -v 主机目录:容器目录
# docker run -it -v ~/docker-container:/home centos
# docker run -it -v ~/docker-container:/home:ro centos 只读,只能通过宿主机来改变
# docker run -it -v ~/docker-container:/home:rw centos 可读可写
# 查看容器详细信息
docker inspect 容器id
找到mount可以查看宿主机和容器内的文件是否挂载成功
进入容器测试
# 进入容器
docker attach 0bceb638e588
# 进入挂载的容器目录
cd home
# 查看目录和宿主机内的文件
ls
# 在宿主机或者容器目录内创建一个新文件
touch ahua.js
如果看到宿主机和容器内同时出现了创建的ahua.js文件,则说明挂载成功
相同的,在宿主机这边修改文件,容器这边也会同步,即使是容器已经关闭了,再次启动容器查看,修改也会同步
所以,如果需要修改容器内的文件,只需要将其挂载到本地,通过本地进行修改即可实时同步,不用cp出去再cp回来那么麻烦了
-v 卷名:容器内路径
# 不指定主机目录,指定容器内目录和挂载的数据卷名字
docker run -d -P --name nginx000 -v nginx-name:/ect/nginx nginx
# -P:随机匹配端口 nginx-name:指定数据卷的名字 /ect/nginx:容器内进行数据挂载的目录
# 查看卷挂载情况
docker volume ls
#查看数据卷挂载到宿主机的位置
docker inspect [volume name]
# docker inspect nginx-name
可以cd到宿主机中检查是否有这样的目录
-v容器路径
#不指定主机目录,只有容器内目录
docker run -d -P --name nginx007 -v /ect/nginx nginx
# nginx007:指定的容器名
# volume name就是匿名挂载卷的名字
实现两个或者多个容器间的数据共享,一样是利用一个容器和另一个容器共享数据
# 开启第一个容器(父容器)
docker run -it --name container-centos01 ec971a4e3402 /bin/bash
# container-centos01:自定义容器名 ec971a4e3402:镜像id(镜像名也行)
# 开启第二个容器
docker run -it --name container-centos02 --volumes-from container-centos01 ec971a4e3402 /bin/bash
# container-centos02 --volumes-from container-centos01 :container-centos02和container-centos01绑定(02继承01)
# 开启第三个容器
docker run -it --name container-centos03 --volumes-from container-centos01 ec971a4e3402 /bin/bash
这里volume01和volume02为三个容器的共享数据卷,是通过dockerFile创建的,具体创建方法在下文有讲到
三个容器共享数据卷里的内容会保持同步,停掉或者删除一个容器不会影响其他容器内的数据。容器共享卷之间的数据共享是一种双向拷贝。只有所有容器全部停止数据卷才会消失。实现数据持久化可以将数据挂载到本地
用来构建docker镜像的构建文件,是一个命令参数脚本。这个也可以去官网https://hub.docker.com/搜索具体某个镜像去查看其对应的dockerFile
构建步骤
1. 要求
1. 每个指令必须大写
2. 从上到下执行
3. #表示注释
4. 每个指令都会创建一个新的镜像层并提交
2. 具体命令
指令 | 含义 |
---|---|
FROM | 基础镜像,后面的搭建都基于这里 |
MAINTAINER | 作者信息 名字+邮箱 |
RUN | 镜像构建时需要运行的命令 |
ADD | 添加内容 |
WORKDIR | 指定容器的工作目录,容器启动后会进入该目录 |
VOLUME | 指定数据卷挂载目录的名字 |
EXPOSE | 暴露的端口 |
CMD | 指定容器启动的时候需要运行的命令 ,在容器中追加的命令会替换掉CMD的命令 |
ENTRYPOINT | 指定容器启动时运行的命令,可以在容器中追加命令 |
ONBUILD | 构建一个被继承的DockerFile时, 会运行ONBUILD指令 |
COPY | 将文件copy到镜像中 |
ENV | 构建时设置环境变量 |
# base image FROM centos # author MAINTAINER ahua<aaahua163@163.com> # Environment Variables # MYPATH is mean the path after entering ENV MYPATH /usr/local # workspace WORKDIR &MYPATH # Execution of commands RUN yum -y install vim RUN yum -y install net-tools # Exposed ports EXPOSE 80 CMD echo $MYPATH CMD echo "------end-------" CMD /bin/bash
docker build -f dockerFile文件路径 -t 镜像名:版本号 .
# docker build -f dockerFile-centos-ahua -t centos-ahua:1.0 .
# -f 指定是哪个文件 -t 生成的目标镜像 . 当前目录下
构建过程
4. 测试运行
查看镜像
docker image ls
结果
运行容器
docker run -it centos-ahua /bin/bash
安装的vim和net-tools工具都可以使用了(docker中的centos是精简版,没有集成vim和net-tools)
还可以通过docker history 镜像id
去查看镜像的构建历史
tomcat:https://tomcat.apache.org/download-10.cgi#10.0.14
jdk:https://www.oracle.com/java/technologies/downloads/#java8-linux
# base image FROM centos # author MAINTAINER ahua<aaahua163@163.com> COPY readme.md /usr/local/readme.md # add and decompress jdk to /usr/local ADD jdk-8u311-linux-x64.tar.gz /usr/local ADD apache-tomcat-9.0.56.tar.gz /usr/local # Environment Variables # MYPATH is mean the path after entering ENV MYPATH /usr/local # workspace WORKDIR &MYPATH ENV JAVA_HOME /usr/local/jdk1.8.0_311 ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ENV CALALINA_HOME /usr/local/apache-tomcat-9.0.56 ENV CALALINA_BASE /usr/local/apache-tomcat-9.0.56 ENV PATH $PATH:$JAVA_HOME/bin:$CALALINA_HOME/lib:$CALALINA_HOME/bin # Execution of commands RUN yum -y install vim RUN yum -y install net-tools # Exposed ports EXPOSE 8080 # start tomcat and show the logs CMD /usr/local/apache-tomcat-9.0.56/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.56/bin/logscatalina.out
docker build -t aaahua/tomcat-ahua:1.0 .
# 因为Dockerfile是标准文件名 所以不需要-f指定文件
# aaahua 用户名 1.0版本号
构建成功
4. 创建容器
docker run -d -p 9090:8080 --name ahua-tomcat -v /home/ahua/tomcat-ahua/test:/usr/local/apache-tomcat-9.0.56/webapps/test -v /home/ahua/tomcat-ahua/logs:/usr/local/apache-tomcat-9.0.56/logs tomcat-ahua
# /home/ahua/tomcat-ahua/test:/usr/local/apache-tomcat-9.0.56/webapps/test 表示将tomcat的test挂载到主机上进行数据共享
#/home/ahua/tomcat-ahua/logs:/url/local/pache-tomcat-9.0.56/logs 表示将tomcat的日志挂载到主机上
curl localhost:9090
浏览器访问localhost:9090
6. 本地项目构建
因为运行容器的时候已经将本地的/home/ahua/tomcat-ahua/test
文件夹和容器的/usr/local/apache-tomcat-9.0.56/webapps/test
文件夹挂载到了一起,所以可以直接在本地的test文件夹中创建自己的项目
# 查看容器的信息
docker inspect 容器id
可以看到数据挂载的详细信息
在text目录下创建index.html文件
cd home/ahua/tomcat-ahua/test vim index.html # index.html中的内容 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <p3>hello,阿花!</p3> </body> </html>
浏览器测试,访问localhost:9090/test
docker login -u 用户名
输入密码即可
(2)提交镜像
docker push aaahua/tomcat-ahua:1.0
发布成功,可以用docker search 搜索到
(3)将镜像打成压缩包
dockers save -o 路径
(4)使用压缩好的镜像
docker load
docker整体流程图
mkdir dockerFile-volume
2. 创建文件夹及编写脚本文件
# 进入文件夹
cd dockerFile-volume
# 创建脚本文件
vim dockerFile01
# 编写脚本
FROM centos
VOLUME ["volume01","volume02"]
CMD echo'---------end--------------'
CMD /bin/bash
docker build -f dockerFile01 -t ahua-centos .
# dockerFile01:脚本文件 ahua-centos:镜像名字
镜像生成过程也是分层的,每个命令就是一层
4. 启动容器查看数据卷是否创建成功
docker image ls
docker run -it 容器id /bin/bash
ls
这volume01和volume02就是生成的数据卷
5. 回到宿主机查看挂载情况
# 可以看到mounts里面有对应的宿主机地址
docker inspect 容器id
docker运行的命令图
这部分我感觉官方写的很详细很好懂,虽然是英文的,翻译软件用一下或者直接跟着代码盲敲也不会有问题
docker网络相关命令
docker network ls #查看所有docker网络
docker network inspect 网络名 #查看该网络的详细信息
docker network rm 网络名 #删除该网络
利用docker network进行容器间通信,相当于创建了一个虚拟以太网网桥,
bridge也是docker-compose默认创建网络的方式
① 创建docker network
docker network create [ option ] network名 # docker network create my-net
② 将容器添加到docker network
# 1. 将容器container-ahua加入 my-net 网络
docker network connect my-net container-ahua
# 2. 运行container-ahua容器并加入网络使用--network参数
docker -d --network my-net container-ahua
③ 从网络中移除容器
docker network disconnect my-net container-ahua
host模式下容器和宿主机共ip,通过访问宿主机ip可以访问到容器。
例如宿主机ip为192.168.152.143
,容器开放端口80,那么在宿主机80端口没有被占用的情况下访问192.168.152.143:80
就可以访问到主机,缺点是主机和容器间无法通信
使用host方式可以在使用--network host
来指定
docker run -d --network my-net image
在docker-compose中通过 network_mode: "host"
指定
顾名思义,没有网络,默认是什么都没有只有IO,通过--network none
指定即可。
docker save -o 压缩包名.tar 镜像名[版本]
# docker save -o mongo.tar mongo:3.6.8
docker load -i mongo.tar
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。