Docker学习整理

分类专栏:
docker相关

文章标签:
Java自学
docker
原创

Docker学习整理

docker安装方法见-->>安装方法点我鸭

一.Docker常用命令

Docker帮助命令

docker version #显示docker的版本信息

docker info    #显示docker的系统信息,包括镜像和容器的数量

docker --help  #帮助命令

Docker镜像命令

1)docker images  #列出本地主机上的镜像
REPOSITORY #表示镜像的仓库源
TAG #镜像的标签
IMAGE ID #镜像ID
CREATED #镜像创建时间
SIZE #镜像大小
#同一仓库源可以有多个 TAG,代表这个仓库源的不同个版本,我们使用 REPOSITORY:TAG 来定义不同的镜像
#如果你不指定一个镜像的版本标签,例如你只使用 ubuntu,docker将默认使用 ubuntu:latest

选项说明:
a  #列出本地所有的镜像
q  #只显示镜像ID
digests  #显示镜像的摘要信息
no-trunc  #显示完整的镜像信息

2)docker search [OPTIONS] 镜像名 #搜索某个镜像

#docker仓库:https://hub.docker.com

选项说明:
no-trunc  #显示完整的镜像描述
s  #列出收藏数不小于指定值的镜像
automated  #只列出 automated build类型的镜像

3)docker pull 镜像名   #下载镜像

4)docker rmi 镜像名ID  #删除镜像
docker rmi -f 镜像ID #删除单个
docker rmi -f 镜像名1:TAG 镜像名2:TAG #删除多个
docker rmi -f $(docker images -qa)  #删除全部

容器命令

1)docker pull 镜像名  #有镜像才能创建容器

2)docker run 镜像名   #新建容器并启动

选项说明:
--name="容器新名字" #为容器指定一个名称;
-d  #后台运行容器,并返回容器ID,也即启动守护式容器;
-i  #以交互模式运行容器,通常与 -t 同时使用;
-t  #为容器重新分配一个伪输入终端,通常与 -i 同时使用;
-P(大写P)  #随机端口映射;
-p  #指定端口映射,有以下四种格式:
      ip:hostPort:containerPort
      ip::containerPort
      hostPort:containerPort
      containerPort
      
 docker run -it 镜像名 /bin/bash  #使用镜像以交互模式启动一个容器,在容器内执行/bin/bash命令
 
 3)docker ps #列出所有运行的容器
 
 选项说明:
 -a  #列出当前所有正在运行的容器+历史上运行过的
-l  #显示最近创建的容器。
-n #显示最近n个创建的容器。
-q  #静默模式,只显示容器编号。
--no-trunc  #不截断输出

4)exit  #容器停止退出
   Ctrl+P+Q  #容器不停止退出
   
5)docker start 容器ID或容器名  #启动容器

6)docker restart 容器ID或容器名 #重启容器

7)docker stop 容器ID或容器名  #停止容器

8)docker kill 容器ID或容器名  #强制停止容器

9)docker rm 容器ID  #删除已停止的容器
   #删除所有容器:
   docker -rm -f $(docker ps -a -q)
   docker ps -a -q | xargs docker rm
   
10)docker run -d 容器名 #启动守护式容器 后台运行
   
#举例使用镜像centos:latest以后台模式启动一个容器
docker run -d centos
#然后docker ps -a 进行查看,会发现容器已经退出
#很重要的要说明的一点,Docker容器后台运行,就必须有一个前台进程
#容器运行的命令如果不是那些一直挂起的命令(比如运行top,tail),就是会自动退出的
#这个是docker的机制问题,比如你的web容器,我们以nginx为例,正常情况下,我们配置启动服务只需要启动响#应的service即可
#例如service nginx start
#但是,这样做,nginx为后台进程模式运行,就导致docker前台没有运行的应用,
#这样的容器后台启动后,会立即自杀因为他觉得他没事可做了.
#所以,最佳的解决方案是,将你要运行的程序以前台进程的形式运行

11)docker logs -f -t --tail 容器ID #查看容器启动日志
   选项说明:
   -t #加入时间戳
   -f #跟随最新的日志打印
   --tail 数字 #显示日志条数

12)docker top 容器ID #查看容器内运行的进程

13)docker inspect 容器ID #查看容器内部细节

14)docker exec -it 容器ID bashshell #直接进入容器启动命令的终端,不会启动新的进程
    docker attach 容器ID  #在容器中打开新的终端,可以启动新的进程
    
15)docker cp 容器ID:容器内路径 主机目的路径

其余常用命令:
build   #通过 Dockerfile 定制镜像
commit  #提交当前容器为新的镜像
create  #创建一个新的容器,同 run,但不启动容器
diff    # 查看 docker 容器变化
events  # 从 docker 服务获取容器实时事件
export  #导出容器的内容流作为一个 tar 归档文件[对应 import ]
history #展示一个镜像形成历史
import  #从tar包中的内容创建一个新的文件系统映像[对应export]
load    #从一个 tar 包中加载一个镜像[对应 save]
login   #注册或者登陆一个 docker 源服务器
logout  #从当前 Docker registry 退出
port    #查看映射端口对应的容器内部源端口
pause   #暂停容器
save    #保存一个镜像为一个 tar 包[对应 load]
tag     # 给源中镜像打标签
unpause #取消暂停容器
wait    #截取容器停止时的退出状态值
 

二.Docker镜像

镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件

UnionFS(联合文件系统):

Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)
Union 文件系统是 Docker 镜像的基础
镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录

Docker镜像加载原理:

docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS
bootfs(boot file system)主要包含bootloader和kernel, bootloader主要是引导加载kernel, Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs
这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核
当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs
rootfs (root file system) ,在bootfs之上,包含的就是典型 Linux 系统中的 /dev, /proc, /bin, /etc 等标准目录和文件
rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等

分层理解:

共享资源,比如:有多个镜像都从相同的 base 镜像构建而来,那么宿主机只需在磁盘上保存一份base镜像,同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了,而且镜像的每一层都可以被共享

特点:

Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部
这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”

Commit镜像

docker commit #提交容器副本成为一个新的镜像
docker commit -m=“提交的描述信息” -a=“作者” 容器ID 要创建的目标镜像名:[标签名]

三.Docker容器数据卷

卷就是目录或文件,存在于一个或多个容器中,由docker挂载到容器,但不属于联合文件系统
因此能够绕过Union File System提供一些用于持续存储或共享数据的特性
卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷

特点:

1)数据卷可在容器之间共享或重用数据
2)卷中的更改可以直接生效
3)数据卷中的更改不会包含在镜像的更新中
4)数据卷的生命周期一直持续到没有容器使用它为止

相关操作

docker run -it -v /主机目录:/容器内目录 镜像名 #使用命令挂载
docker inspect 容器ID #查看容器内部细节  查看挂载相关信息 Mounts
#容器内部发生变化 外部也会发生变化,数据同步
#停止容器,宿主机上修改文件,然后在启动容器,容器内数据依旧同步

具名挂载与匿名挂载

匿名挂载(匿名卷),即在进行数据卷挂载的时候不指定宿主机的数据卷目录,-v命令之后直接跟上容器内数据卷所在的路径
具名挂载(命名卷)即在进行数据卷挂载的时候既指定宿主机数据卷所在路径,又指定容器数据卷所在路径

DockerFile初步认识

dockerfile就是用来构建docker镜像的构建文件,命令参数脚本
通过脚本生成镜像,镜像是一层一层的,脚本一个个的命令,每一个命令都是一层
#在根目录下新建一个mydocker文件
#创建一个dockerfile文件,文件中的内容 指令(大写) 参数

FROM centos
VOLUME ["Volume1","Volume2"]
CMD echo "finished,--------success"
CMD /bin/bash
#这里每一个命令就是镜像的一层

#build后生成镜像
docker build -f /mydocker/dockerfile -t pz/centos .

#启动自己生成的镜像 查看里面有两个目录就是生成镜像时自动挂载的数据卷目录
docker run -it 容器ID /bin/bash 
#卷和外部一定有一个同步的目录 查看一个卷挂载的路径
docker inspect 容器ID

#构建镜像时没有挂载卷,要手动镜像挂载 -v 卷名:容器内路径

注意:

Docker挂载主机目录Docker访问出现cannot open directory .: Permission denied
解决办法:在挂载目录后多加一个--privileged=true参数即可

数据卷容器

#通过命令
docker run -it --name 其他容器名 --volumes-from 父容器名
命名的容器挂载数据卷,其它容器通过挂载这个(父容器)实现数据共享,挂载数据卷的容器,称之为数据卷容器
容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止,一旦持久化,本地数据不会删除

四.Dockerfile深入认识

dockerfile是用来构建docker镜像的文件,命令参数脚本

构建步骤:

#编写一个dockerfile

docker build  #构建成为一个镜像

docker run    #运行镜像

docker push   #发布镜像(DockerHub或阿里云镜像仓库)

注意:

1)每个保留关键字(指令)都是必须大写字母,后面要跟随至少一个参数
2)执行从上到下顺序
3)#表示注释
4)每一个指令都会创建提交一个新的镜像层,并提交

在这里插入图片描述

从应用软件的角度来看,Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段:

Dockerfile是软件的原材料
Docker镜像是软件的交付品
Docker容器则可以认为是软件的运行态
Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及部署与运维,三者缺一不可,合力充当Docker体系的基石
Dockerfile,需要定义一个Dockerfile,Dockerfile定义了进程需要的一切东西。Dockerfile涉及的内容包括执行代码或者是文件、环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、服务进程和内核进程(当应用进程需要和系统服务和内核进程打交道,这时需要考虑如何设计namespace的权限控制)等等
Docker镜像,在用Dockerfile定义一个文件之后,docker build时会产生一个Docker镜像,当运行 Docker镜像时,会真正开始提供服务
Docker容器,容器是直接提供服务的

DockerFile指令

BUILD BOTH RUN
FROM(基础镜像,从这里开始创建) WORKDIR(镜像的工作目录) CMD(指定容器启动时要运行的命令,可被替换,最后一个生效)
MAINTAINER(镜像是谁写的 姓名+邮箱) USER(指定容器执行程序的用户身份默认root用户) ENV(构建时设置环境变量)
COPY(类似ADD,将我们文件拷贝到镜像) EXPOSE(保留端口配置)
ADD(步骤 ,添加内容) VOLUME(挂载的)
RUN(镜像构建时需要运行的命令) ENTRYPOINT(指定容器启动时要运行的命令,可追加命令)
ONBUILD(构建一个被继承dockerfile时,就会触发指令)
.dockerignore(管理镜像构建上下文或者COPY/ADD的例外文件列表)

举例1:

docker pull centos #从dockerhub上拉取centos镜像 
docker run -it centos #使用镜像以交互模式启动一个容器
#发现这个centos很干净 vim ifconfig等基础命令都没有
进入mydocker目录编写dockerfile文件centosfile,创建一个自己的CentOS
FROM  centos   #基础镜像(官网拉取的centos)
MAINTAINER PZ<pz1999pz@163.com>  #添加作者姓名和邮箱

ENV MYPATH /usr/local   #设置环境变量

RUN yum install vim -y    #镜像构建时安装vim
RUN yum install net-tools -y  #镜像构建时安装ifconfig所需的net-tools包

EXPOSE 80  #80端口

CMD echo $MYPATH   
CMD echo "success-----end"  
CMD /bin/bash
构建 在mydocker文件夹下
docker build -f centosfile -t mycentos:0.1 .  #创建mycentos:0.1
docker images #查看镜像会发现我们创建的进行mycentos
docker run -it mycentos:0.1 #运行mycentos 安装的vim和net-tools有效

docker history 容器ID #查看mycentos的构建过程 

举例2:

编写一个dockfile文件 命名为dockerfile
FROM centos #基础镜像(官网拉取的centos)
MAINTAINER pz<pz1999pz@163.com>  #添加作者姓名和邮箱

COPY readme.txt /usr/local/readme.txt  #拷贝文件到指定路径

ADD jdk-8u11-linux-x64.tar.gz /usr/local   #添加jdk
ADD apache-tomcat-9.0.22.tar.gz /usr/local #添加tomcat

RUN yum install vim -y   #镜像构建时安装vim

ENV MYPATH /usr/local   #设置环境变量
WORKDIR $MYPATH     #设置工作目录

#ENV构建环境变量
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 #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
构建并启动测试
docker build -t diytomcat .  #由于dockerfile文件命名为dockerfile 省略-f
docker images #查看到自己定义的diytomcat
docker run -d -p 9090:8080 --name pztomcat -v /pztomcat -v /home/pz/build/tomcat/test:/usr/local/apache-tomcat-9.0.22/webapps/test -v /home/pz/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.22/logs diytomcat

docker exec -it 容器名 /bin/bash  #进入 执行ll 能看到tomcat目录结构

ip+9090  #打开浏览器能查看到tomcat界面

发布镜像

1.发布到dockerhub
#注册一个dockerhub账号
docker login -u 账号名 #执行后输入命令
#登录成功 会显示login Succeeded 
docker images #查看本地有哪些镜像
docker push pz/diytomcat:1.0  #push自己镜像到dockerhub上面 一层一层的push
2.发布到阿里云镜像仓库
#登录到阿里云 找到容器镜像服务
#创建命名空间
#创建镜像仓库(本地仓库)
#点开仓库里面有阿里云官方操作指南(详细的一B)

在这里插入图片描述

五.Docker网络

ipaddr #查看本地ip地址
lo   #loopback,是回环地址,经常被分配到127.0.0.1地址上,用于本机通信,经过内核处理后直接返回,不会在任何网络中出现
etho  #网卡名
docker0  #docker网卡
举例 :
docker run -d -p  --name tomcat7 tomcat
docker exec -d -it tomcat7 ip addr #查看容器内部网络地址,发现容器启动会得到一个新的ip地址
docker分配的,linux可以ping通docker容器内部
Docker使用的是linux的桥接,宿主机中是一个Docker容器的断桥 docker0
所有的容器不指定网络情况下,都由docker0路由
evth-pair 就是一对的虚拟设备接口,成对的,一段连着协议,一段彼此相连 。充当一个桥梁,连接各种虚拟网络设备
OpenStac,Docker容器之间的连接,OVS的连接都使用evth-pair技术
容器和容器之间亦可相互ping通
Docker中所有网络接口都是虚拟的(转发效率高)
容器删除对应网桥一对也随之删除

查看docker0

docker network ls  #查看所有docker网络
docker network inspect ID(里面name为bridge的 NETWORK ID) #config里面的gateway
解决网络连通问题

自定义网络

docker network ls  #查看所有docker网络

bridge    #桥接(默认)
none      #不配置网络
host      #和宿主机共享网络
container #容器网络连通
docker run -d -p  --name tomcat7 tomcat
docker run -d -p  --name tomcat7  --net bridge tomcat 
#上面直接启动的命令 --net bridge 就是docker0
#docker0 默认 域名不能访问 --link可以打通连接

举例自定义网络:

docker network create --driver bridge --subent xxx(根据自己查看docker0的Subnet) --gateway xxx(自定义Subnet下的) mynet

docker network inspect mynet #查看自定义网络相关信息
docker run -d -p  --name tomcat-net-7 --net mynet tomcat #启动走自定义网络mynet
docker run -d -p  --name tomcat-net-9 --net mynet tomcat #启动走自定义网络mynet
docker network inspect mynet #查看自定义网络相关信息能看到我们走自定义网络的两个容器
docker exec  -it tomcat-net-7 ping tomcat-net-9
亦可保证不同集群使用不同网络,保证集群安全与健康

网络连通

举例:

docker network connect mynet tomcat7 #打通docker0下的tomcat7与mynet
docker network inspect mynet  #连通后就是将tomcat7放在mynet网络下
#一个容器两个IP地址
docker exec -it tomcat7 ping tomcat-net-7  #上面连接后两个容器不同网络下连通成功 
#docker network connect连通后,就可跨网操作

六.Docker Compose

官方文档
传统的 docker 服务,我们一般通过编写 Dockerfile 文件,通过 build 命令创建一个镜像,再通过 run 命令建立一个容器
这种对于单个应用来说可能比较方便和快捷,那么假设有一个项目,包含了 100 个微服务,这 100 个微服务之间还存在相互依赖关系,那以上的方式就显得特别鸡肋,费时费力
因此,我们可以通过 Docker Compose 来轻松高效地管理容器(定义运行多个容器)
Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration. To learn more about all the features of Compose, see the list of features.
 
Compose works in all environments: production, staging, development, testing, as well as CI workflows. You can learn more about each case in Common Use Cases.
 
Using Compose is basically a three-step process:
 
    1.Define your app’s environment with a Dockerfile so it can be reproduced anywhere.
 
    2.Define the services that make up your app in docker-compose.yml so they can be run together in an isolated environment.
 
    3.Run docker-compose up and Compose starts and runs your entire app.
        
        
#翻译后
        
Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YAML 文件来配置应用程序的服务。然后,使用一个命令,就可以从配置中创建并启动所有服务。要了解有关 Compose 的所有功能的更多信息,请参阅功能列表。
 
Compose 可在所有环境中工作:生产,演示,开发,测试以及 CI 工作流。您可以在“ 通用用例”中了解有关每种用例的更多信息。
 
使用 Compose 基本上有三个过程:
 
1.使用定义您的应用环境,Dockerfile 以便可以在任何地方复制。
 
2.定义组成应用程序的服务,docker-compose.yml 以便它们可以在隔离的环境中一起运行。
 
3.运行 docker-compose up 和 Compose start 以运行您的整个应用程序。
Compose 是 Docker 官方的开源项目,需要手动安装
Compose yml 文件编写例子如下(官网例子):
version: '2.0'
services:
  web:
    build: .
    ports:
    - "5000:5000"
    volumes:
    - .:/code
    - logvolume01:/var/log
    links:
    - redis
  redis:
    image: redis
volumes:
  logvolume01: {}

Compose 重要的两个概念

服务 Service :不同的容器(应用)组成项目(如:mysql、web、nginx 等)
项目 Project :即为一组关联的容器

Docker Compose 安装

#下载 Compose
curl -L http://get.daocloud.io/docker/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose 
#.赋予 docker-compose 执行权限
chmod +x /usr/local/bin/docker-compose
#查看版本
docker-compose version

Docker Compose 体验

官方示例 Compose 项目体验Python计数器 Redis

停止命令
docker-compose stop
docker-compose down
Crtl+C

默认规则

文件名_服务名_num #num表示副本数量

Docker Compose配置编写规则

#yaml规则 docker-compose.yml 核心三层
1)version #版本
2)services #服务
      服务1:redis
           具体配置
        服务2:nginx
           具体配置
        服务3:web
           具体配置
3)其他配置 #网络/卷 全局配置
volumes:
networks:
configs:

版本(向下兼容)

在这里插入图片描述

官方实例:

version: "3.8"
services:
 
  redis:
    image: redis:alpine
    ports:
      - "6379"
    networks:
      - frontend
    deploy:
      replicas: 2
      update_config:
        parallelism: 2
        delay: 10s
      restart_policy:
        condition: on-failure
 
  db:
    image: postgres:9.4
    volumes:
      - db-data:/var/lib/postgresql/data
    networks:
      - backend
    deploy:
      placement:
        max_replicas_per_node: 1
        constraints:
          - "node.role==manager"
 
  vote:
    image: dockersamples/examplevotingapp_vote:before
    ports:
      - "5000:80"
    networks:
      - frontend
    depends_on:
      - redis
    deploy:
      replicas: 2
      update_config:
        parallelism: 2
      restart_policy:
        condition: on-failure
 
  result:
    image: dockersamples/examplevotingapp_result:before
    ports:
      - "5001:80"
    networks:
      - backend
    depends_on:
      - db
    deploy:
      replicas: 1
      update_config:
        parallelism: 2
        delay: 10s
      restart_policy:
        condition: on-failure
 
  worker:
    image: dockersamples/examplevotingapp_worker
    networks:
      - frontend
      - backend
    deploy:
      mode: replicated
      replicas: 1
      labels: [APP=VOTING]
      restart_policy:
        condition: on-failure
        delay: 10s
        max_attempts: 3
        window: 120s
      placement:
        constraints:
          - "node.role==manager"
 
  visualizer:
    image: dockersamples/visualizer:stable
    ports:
      - "8080:8080"
    stop_grace_period: 1m30s
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    deploy:
      placement:
        constraints:
          - "node.role==manager"
 
networks:
  frontend:
  backend:
 
volumes:
  db-data:

官方实例部署WP博客点我鸭

  • 作者:潘震
  • 评论

    留言