Docker概念及安装配置管理

分类:虚拟化    发布时间:2017-11-16 11:35:57
Docker介绍:
Docker 是一个开源工具,它可以让创建和管理 Linux 容器变得简单。容器就像是轻量级的虚拟机,并且可以以毫秒级的速度来启动或停止。Docker 帮助系统管理员和程序员在容器中开发应用程序,并且可以扩展到成千上万的节点。

容器和 VM(虚拟机)的主要区别是,容器提供了基于进程的隔离,而虚拟机提供了资源的完全隔离。虚拟机可能需要一分钟来启动,而容器只需要一秒钟或更短。容器使用宿主操作系统的内核,而虚拟机使用独立的内核。
Docker背后的想法是创建软件程序可移植的轻量容器,让其可以在任何安装了Docker的机器上运行,而不用关心底层操作系统,就像野心勃勃的造船者们成功创建了集装箱而不需要考虑装在哪种船舶上一样。

Docker能做什么?
Docker能够解决虚拟机由于资源要求过高而无法解决的问题。
Docker能处理的事情包括:
    隔离应用依赖
    创建应用镜像并进行复制
    创建容易分发的即启即用的应用

    允许实例简单、快速地扩展

    测试应用并随后销毁它们

Docker背后的想法是创建软件程序可移植的轻量容器,让其可以在任何安装了Docker的机器上运行,而不用关心底层操作系统,就像野心勃勃的造船者们成功创建了集装箱而不需要考虑装在哪种船舶上一样。

一个完整的Docker有以下几个部分组成:
DockerClient客户端
Docker Daemon守护进程
Docker Image镜像
DockerContainer容器

Docker 中包括三个基本的概念:
Image(镜像)
Docker镜像可以看作是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。
镜像就是一堆只读层(read-onlylayer)的统一视角,下面这张图能够帮助读者理解镜像的定义:
[root@localhost ~]# docker history 719e7e45b1e2
IMAGE             CREATED       CREATED BY           SIZE           COMMENT
719e7e45b1e2 7 days ago  /bin/sh -c #(nop) HEALTHCHECK &{["CMD-SHELL…  0B                  
<missing>    7 days ago  /bin/sh -c #(nop) CMD ["/assets/wrapper"]     0B                  
<missing>    7 days ago  /bin/sh -c #(nop) VOLUME [/etc/gitlab /var/…  0B                  
<missing>    7 days ago  /bin/sh -c #(nop)  EXPOSE 22 443 80     0B                  
<missing>    7 days ago  /bin/sh -c #(nop)  ENV TERM=xterm       0B                  
<missing>    7 days ago  /bin/sh -c #(nop)  ENV PATH=/opt/gitlab/embe… 0B                  
<missing>    7 days ago  /bin/sh -c /assets/setup                   1.7GB           
<missing>    7 days ago  /bin/sh -c #(nop) COPY dir:c460cf9350fd1134c… 11.2kB              
<missing>    7 days ago  /bin/sh -c #(nop) COPY file:6b7e1cc261de6ff1… 157B                
<missing>    7 days ago  /bin/sh -c ln -fs /dev/null /run/motd.dynamic 9B                  
<missing>    7 days ago  /bin/sh -c rm -rf /etc/update-motd.d /etc/mo… 0B                  
<missing>    7 days ago  /bin/sh -c apt-get update -q     && DEBIAN_F… 71.7MB              
<missing>    7 days ago  /bin/sh -c #(nop)  ENV LANG=C.UTF-8     0B                  
<missing>    7 days ago  /bin/sh -c #(nop)  SHELL [/bin/sh -c]   0B                  
<missing>    7 days ago  /bin/sh -c #(nop)  MAINTAINER GitLab Inc. <s… 0B                  
<missing>    10 days ago /bin/sh -c #(nop)  CMD ["/bin/bash"]     0B                  
<missing>    10 days ago /bin/sh -c mkdir -p /run/systemd && echo 'do… 7B                  
<missing>    10 days ago /bin/sh -c set -xe && echo '#!/bin/sh' > /…  745B                
<missing>    10 days ago /bin/sh -c rm -rf /var/lib/apt/lists/*        0B                  
<missing>    10 days ago /bin/sh -c #(nop) ADD file:1f70668251e2e58ce…  124MB  
从左边我们看到了多个只读层,它们重叠在一起。除了最下面一层,其它层都会有一个指针指向下一层。这些层是Docker内部的实现细节,并且能够在主机的文件系统上访问到。统一文件系统 (union file system)技术能够将不同的层整合成一个文件系统,为这些层提供了一个统一的视角,这样就隐藏了多层的存在,在用户的角度看来,只存在一个文件系统。我们可以在图片的右边看到这个视角的形式

Container(容器)
容器也是一堆层的统一视角,与镜像的唯一区别在于容器的最上面那一层是可读可写的。
由于容器的定义并没有提及是否要运行容器,所以实际上,容器 = 镜像 + 读写层。

Repository(仓库)
用来集中存放镜像文件,我们有时候会把仓库 (Repository) 和仓库注册服务器 (Registry) 混为一谈,并不严格区分。注册服务器可以理解为GitHub这样的托管服务。实际上,一个 Docker Registry中可以包含多个仓库 (Repository) ,每个仓库可以包含多个标签 (Tag),每个标签对应着一个镜像。

通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本 。我们可以通过<仓库名>:<标签>的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签.。

仓库又可以分为两种形式:
public(公有仓库)
private(私有仓库)
Docker Registry 公有仓库是开放给用户使用、允许用户管理镜像的 Registry 服务。一般这类公开服务允许用户免费上传、下载公开的镜像,并可能提供收费服务供用户管理私有镜像。

Docker官方提供了Docker Registry镜像,可以直接使用做为私有Registry服务。当用户创建了自己的镜像之后就可以使用push命令将它上传到公有或者私有仓库,这样下次在另外一台机器上使用这个镜像时候,只需要从仓库上pull 下来就可以了。

Deocker文件目录
builder  
buildkit  
containerd  
containers  存储容器信息
image/overlay2 存储镜像管理数据的目录,以使用的存储驱动overlay2命名
network  
overlay2  
plugins  
runtimes  
swarm  
tmp  docker临时目录
trust  docker信任目录
volumes  docker卷目录

一、安装Docker
首先关闭selinux和iptables
然后再安装docker
$ wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
$ yum -y install docker-ce-18.06.1.ce-3.el7

二、启动docker
安装完成后,使用下面的命令来启动 docker 服务,并将其设置为开机启动:
[root@localhost ~]# systemctl start docker 
[root@localhost ~]# chkconfig docker on
查看docker运行状态
[root@localhost ~]# systemctl status docker
停止docker
systemctl stop docker
重启docker
systemctl restart docker

三、查看版本
docker -v


四、Docker基本命令

查看版本 docker -v
查看docker详细信息 docker info
登录 docker login
容器资源管理 — docker [volume|network] COMMAND
[root@localhost ~]# 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

[root@localhost ~]# docker volume --help
Usage: docker volume COMMAND
Manage volumes
Commands:
  create      Create a volume
  inspect     Display detailed information on one or more volumes
  ls          List volumes
  prune       Remove all unused local volumes
  rm          Remove one or more volumes


五、镜像操作
更改镜像的下载地址,原镜像在国外特别慢
官方中国加速器:https://registry.docker-cn.com
或下面阿里云加速器
https://xxxxxxxx.mirror.aliyuncs.com 此地址是在阿里云容器镜像服务下的镜像加速器里分配的.
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://xxxxxxxx.mirror.aliyuncs.com"]
}
EOF

查看镜像 docker imanges

搜索镜像 docker search ImageName 解释OFFICIAL: 是否官方发布,stars:类Github的star

下载镜像 docker pull nginx

下载指定版本镜像 docker pull jekins/jenkins:lts

查看指定镜像的创建历史 docker history [REPOSITORY] or [IMAGE ID]

删除镜像 docker rmi image_id

删除TAG名称相同的镜像 docker rmi gitlab/gitlab-ce:1.0.0 使用REPOSITORY:TAG的方法

导入导出镜像
有两种方法:
一种是使用 save 和 load 命令
OPTIONS 说明:
-o :输出到的文件。
实例
将镜像 runoob/ubuntu:v3 生成 my_ubuntu_v3.tar 文档
docker save -o my_ubuntu_v3.tar runoob/ubuntu:v3  导出
docker load < ubuntu.tar  导入

别一种是使用 export 和 import 命令
例子如下:
docker export 98ca36> ubuntu.tar   导出
cat ubuntu.tar | sudo docker import - ubuntu:import   导入

镜像的制作
主要有两种方法:
1、通过docker commit 制作镜像
从已经创建的容器中更新镜像,并且提交这个镜像
在运行的容器内使用apt-get update命令进行更新,完成操作之后输入exit命令来退出该容器。
此时ID为e218edb10161的容器,是按我们的需求更改的容器。通过命令docker commit来提交容器副本。
runoob@runoob:~$ docker commit -m="has update" -a="runoob" e218edb10161 runoob/ubuntu:v2
各个参数说明:
-m: 提交的描述信息
-a: 指定镜像作者
e218edb10161:容器 ID
runoob/ubuntu:v2: 指定要创建的目标镜像名
我们可以使用 docker images 命令来查看我们的新镜像 runoob/ubuntu:v2:
使用我们的新镜像 runoob/ubuntu 来启动一个容器
runoob@runoob:~$ docker run -t -i runoob/ubuntu:v2 /bin/bash

2、通过docker build 制作镜像(Dockerfile)
从零开始来创建一个新的镜像。需要先创建一个Dockerfile文件,其中包含一组指令来告诉
Docker如何构建我们的镜像
runoob@runoob:~$ cat Dockerfile 
FROM    centos:6.7
MAINTAINER      Fisher "fisher@sudops.com"

RUN     /bin/echo 'root:123456' |chpasswd
RUN     useradd runoob
RUN     /bin/echo 'runoob:123456' |chpasswd
RUN     /bin/echo -e "LANG=\"en_US.UTF-8\"" >/etc/default/local
EXPOSE  22   
EXPOSE  80
CMD     /usr/sbin/sshd -D  #容器启动时执行的命令,在构件时并不运行

Dockerfile命令说明:
每一个指令都会在镜像上创建一个新的层(docker history ImageID可查看)每一个指令的前缀都必须是大写的
第一条必须是FROM,指定使用哪个镜像源
MAINTAINER指定镜像的作者信息,包括镜像的所有者和联系信息
RUN 告诉docker在镜像内执行哪些命令,安装什么,运行后所有内容都被持久化,执行完成后退出
    注意:多行命令不要写多个RUN,原因是Dockerfile中每一个指令都会建立一层.
          多少个RUN就构建了多少层镜像,会造成镜像的臃肿、多层,不仅增加了构件部署的时间,还容易出错。
          RUN书写时的换行符是\
EXPOSE 对外暴露端口,不写协议默认为tcp协议,设置后执行run命令依然需要-p选项的映射关系
CMD 镜像设置的默认命令,用户可在 docker run 命令行中替换此默认命令。
其它指令:
ENV 用来设置环境变量,语法有两种1. ENV <key> <value>,2. ENV <key>=<value>
两者的区别是第一种是一次设置一个,第二种是一次设置多个,如有多个用\换行符,别写多个ENV
WORKER 在容器内部设置工作目录,在构建中为后续的指令指定工作目录,Dockerfile中可以多次使用
USER 用来设置在Dockerfile脚本中运行RUN进程的用户,可以是用户名,也可以是UID
ADD 将文件或目录复制到使用Dockerfile构建的镜像中,注意ADD指令自带解压缩功能
COPY 把本地文件拷到容器中,COPY命令支持通配符,语法:COPY <src> <dest>,只能本地文件,建用ADD
LABEL:为镜像添加标签,语法:LABEL <key>=<value> 如有多个建议用换行符\,不要写多个LABEL

ARG:用于指定传递给构建运行时的变量
格式:ARG <name>[=<default value>]
示例:
    ARG site
    ARG build_user=www

ONBUILD:用于设置镜像触发器,这个命令只对当前镜像的子镜像生效。
格式:ONBUILD [INSTRUCTION]
示例:
比如当前镜像为A,在Dockerfile种添加:
ONBUILD RUN ls -al
这个 ls -al 命令不会在A镜像构建或启动的时候执行
此时有一个镜像B是基于A镜像构建的,那么这个ls -al 命令会在B镜像构建的时候被执行。

VOLUME 在镜像中创建挂载点,通过该镜像创建的容器都有挂载点。命令 VOLUME /data/mysql
       运行时会随机在宿主机的目录下生成一个卷目录,通过docker inspect name查看挂载信息
ENTRYPOINT 功能是启动时的默认命令
语法如下:
1. ENTRYPOINT ["executable", "param1", "param2"]   第一种就是可执行文件加参数
2. ENTRYPOINT command param1 param2   第二种就是写shell
与CMD比较说明(这俩命令太像了,而且还可以配合使用):
1. 相同点:
只能写一条,如果写了多条,那么只有最后一条生效,容器启动时才运行,运行时机相同
2. 不同点:
ENTRYPOINT不会被运行的command覆盖,而CMD则会被覆盖
如果我们在Dockerfile种同时写了ENTRYPOINT和CMD,并且CMD指令不是一个完整的可执行命令,那么
CMD指定的内容将会作为ENTRYPOINT的参数.

STOPSIGNAL  作用是当容器推出时给系统发送什么样的指令
语法:STOPSIGNAL signal
提示:信号量可以是数字或者信号量的名字,如9或者SIGKILL

HEALTHCHECK  容器健康状况检查命令
语法有两种:
1. HEALTHCHECK [OPTIONS] CMD command  表示在容器内部运行一个命令来检查容器的健康状况
2. HEALTHCHECK NONE  表示在基础镜像中取消健康检查命令
[OPTIONS]的选项支持以下三中选项:
  --interval=DURATION 两次检查默认的时间间隔为30秒
  --timeout=DURATION 健康检查命令运行超时时长,默认30秒
  --retries=N 当连续失败指定次数后,则容器被认为是不健康的,状态为unhealthy,默认次数是3
注意:
HEALTHCHECK命令只能出现一次,如果出现了多次,只有最后一个生效。
CMD后边的命令的返回值决定了本次健康检查是否成功,具体的返回值如下:
0: success - 表示容器是健康的
1: unhealthy - 表示容器已经不能工作了
2: reserved - 保留值
例子:
HEALTHCHECK --interval=5m --timeout=3s \
CMD curl -f http://localhost/ || exit 1
健康检查命令是:curl -f http://localhost/ || exit 1
两次检查的间隔时间是5秒
命令超时时间为3秒

使用Dockerfile文件,通过docker build命令来构建一个镜像
runoob@runoob:~$ docker build -t runoob/centos:6.7 .
参数说明:
-t :指定要创建的目标镜像名
. :Dockerfile 文件所在目录,可以指定Dockerfile的绝对路径

docker commit的缺点如下:
1.需要在容器内操作麻烦,效率低。
2.这一点也是最重要的,其他人或者过一段时间后自己也不知道这个镜像是怎么做出来的,都安装了什么。上面我们仅看到增加了94.1M。但是使用Dockerfile构建的镜像,我们看到是执行了apt-get install命令。
既然使用docker commit这么不方便,那我们为什么还要学习它呢?其实仔细想一下docker build的每一步构建出来的镜像是不是就是通过docker commit构建出来的。因此学习docker commit可以让我们更好的理解docker build

使用docker images 查看创建的镜像已经在列表中存在,镜像ID为860c279d2fec
runoob@runoob:~$ docker images 
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
runoob/centos       6.7                 860c279d2fec        About a minute ago   190.6 MB
runoob/ubuntu       v2                  70bf1840fd7c        17 hours ago         158.5 MB
ubuntu              14.04               90d5884b1ee0        6 days ago           188 MB

使用新的镜像来创建容器
runoob@runoob:~$ docker run -t -i runoob/centos:6.7  /bin/bash
[root@41c28d18b5fb /]# id runoob
uid=500(runoob) gid=500(runoob) groups=500(runoob)
从上面看到新镜像已经包含我们创建的用户 runoob。

设置镜像标签docker tag
runoob@runoob:~$ docker tag 860c279d2fec runoob/centos:dev
docker tag 镜像ID,这里是 860c279d2fec ,用户名称、镜像源名(repository name)和新的标签名(tag)。

使用 docker images 命令可以看到,ID为860c279d2fec的镜像多一个标签。
runoob@runoob:~$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
runoob/centos       6.7                 860c279d2fec        5 hours ago         190.6 MB
runoob/centos       dev                 860c279d2fec        5 hours ago         190.6 MB
runoob/ubuntu       v2                  70bf1840fd7c        22 hours ago        158.5 MB


六、容器
查看所有容器docker ps -a查看所有容器
创建新容器:
有以下两种方法:
docker create命令从映像创建可写容器并准备运行。 
docker run命令创建容器(与docker create相同)并启动它。  
从技术上讲,docker run = docker create + docker start。
示例:
docker run -d --privileged=true --name jenkins_maven -p 8080:8080 -p 50000:50000 -v /usr/jenkins_home:/var/jenkins_home jenkins-java-maven:1.0.0
参数解释:
-d 后台运行
--privileged=true #特权方式启动容器,可设置容器里的内核参数,如重启容器,会失效,需再次执行
--name 容器名称
-p 映射内部端口到外部,要不然无法访问
-v 数据挂载
最后指定镜像名称和版本号 REPOSITORY:TAG,例如jenkins-java-maven:1.0.0
运行后出现类似以下结果
9d0443587fbfdde7be76f3654a3675bc2c2c9485f9951c9d4bfb9109ede6362a

启动、停止、重启容器 docker start/stop/restart [containerID] or name
杀掉进行中的容器 docker kill -s KILL [containerID] or name
暂停一个或多个容器的所有进程 pause
恢复一个或多个容器内所有被暂停的进程 unpause
重命名一个容器  rename

进入容器:
有以下两种方法:
docker exec -it [containerID] or name /bin/bash #-it表示交互式访问,进入容器建议用此命令
docker attach,可以attach到已运行容器的stdin,如从该stdin中exit,会导致容器停止,不建议用它

导出容器 docker export 1e560fca3906 > ubuntu.tar
导入容器快照 cat docker/ubuntu.tar | docker import - test/ubuntu:v1

查看容器的状态 docker inspect (CONTAINER/IMAGES)name/id

查看运行中容器的进程情况 docker top name/id

将宿主机内的指定文件传输至容器内部的指定地址
docker cp [YourHostFilePath] [containerID]:[DockerPath] 
比如将home目录下的test文件放到cli容器的src目录下: 
docker cp '/home/test' cli:/opt/gopath/src

删除容器 docker rm [containerID]

阻塞运行直到容器停止,然后打印出它的退出代码 docker wait CONTAINER

检查容器里文件结构的更改 docker diff CONTAINER

从服务器获取实时事件 docker events CONTAINER

查看启动日志
docker logs -f 9d044 or name 
参数:
-f 跟踪实时日志
-t 显示时间戳
--tail=100 (返回结尾处100条日志,默认all)



七、私有镜像仓库(以阿里云账户为列)
7.1、登录阿里云Docker Registry
$ sudo docker login --username=xxx registry.cn-xxx.aliyuncs.com
用于登录的用户名为阿里云账号全名,密码为开通服务时设置的密码。

7.2、从Registry中拉取镜像
$ sudo docker pull registry.cn-xxx.aliyuncs.com/xxx/jenkins:[镜像版本号]

7.3、将镜像推送到Registry
$ sudo docker login --username=xxx registry.cn-xxx.aliyuncs.com
$ sudo docker tag [ImageId] registry.cn-xxx.aliyuncs.com/xxx/jenkins:[镜像版本号]
$ sudo docker push registry.cn-xxx.aliyuncs.com/xxx/jenkins:[镜像版本号]
请根据实际镜像信息替换示例中的[ImageId]和[镜像版本号]参数。


八、挂载目录
8.1、镜像挂载目录
VOLUME 在镜像中创建挂载点,通过该镜像创建的容器都有挂载点。命令 VOLUME /data/mysql
       运行时会随机在宿主机的目录下生成一个卷目录,通过docker inspect name查看挂载信息
       通过VOLUME 指令创建的挂载点,无法指定主机上对应的目录,是自动生成的。

8.2、容器挂载目录
     挂载方式有三种:分别是-v,-mount,bind mount
     -v挂载
docker run --name test -it -v /home/xqh/myimage:/data ubuntu /bin/bash
其中的 -v 标记 在容器中设置了一个挂载点 /data(就是容器中的一个目录),并将主机上的
/home/xqh/myimage 目录中的内容关联到 /data下。
     这样在容器中对/data目录下的操作,还是在主机上对/home/xqh/myimage的操作,
     都是完全实时同步的,因为这两个目录实际都是指向主机目录。
    
     -mount挂载
     --mount用法 --mount -src(source)=/xxx,-dst(target)=/xxx
     docker run --name test -it -mount src=/home/xqh/myimage,dst=/data ubuntu /bin/bash
     官方推荐使用--mount进行挂载,原因是--mount支持更多的挂载类型

     -bind mount挂载
     docker run --name test -it -mount type=bind src=/home/xqh,dst=/data ubuntu /bin/bash
     注意:
     如果源目录不存在,会报错,请先创建目录
     如果源目录已存在且有数据,挂载后源目录数据会被隐藏

     多个容器共享同一个挂载目录,既src的目录,可用于nfs共享或上线时做构建项目的共享目录等

     如果创建容器时没有指定挂载的宿主目录,那么会在宿主上随时生成一个挂载目录
     docker volume inspect VolumeName # 查看数据卷详细信息,如挂载目录信息

     docker volume ls 显示所有数据卷



九、Docker网络模式
Docker的网络模式大概可以分为5种类型。安装完 Docker默认,宿主机默认会创建三个网络,分别是
bridge网络,host网络,none网络,可以使用docker network ls命令查看。
9.1、bridge(网桥)模式
容器的默认网络模式,docker在安装时会创建一个名为docker0的Linux bridge,
在不指定--network的情况下,创建的容器都会默认挂到docker0上面。
9.2、host模式
通过命令--network=host指定,使用host模式的容器直接使用宿主机的IP地址与外界通信,容器内部的服务端口也可以使用宿主机的端口,不需要进行NAT,host最大的优势就是网络性能比较好,但是宿主机上已经使用的端口就不能再用了,网络的隔离性不好。
9.3、none模式
    该模式下容器只有lo回环网络,没其他网卡,需要我们手动指定。none网络可以在容器创建时通过--network=none来指定。这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性。
9.4、container模式
创建容器时使用--network=container:NAME_or_ID这个模式在创建新的容器的时候指定容器的网络和一个已经存在的容器共享一个Network Namespace,但是并不为docker容器进行任何网络配置,这个docker容器没有网卡、IP、路由等信息,需要手动的去为docker容器添加网卡、配置IP等。
9.5、user-defined(自定义)模式
用户自定义模式主要可选的有三种网络驱动:bridge、overlay、macvlan。bridge驱动用于创建类似于前面提到的bridge网络;overlay和macvlan驱动用于创建跨主机的网络、IP等。
自定义网络具备内部DNS发现,可以通过容器名或者主机名容器之间网络通信。


     



标签: Docker

阅读(93)┆ 评论(0) ┆ (0) ┆ 返回博客首页


发表我的评论

欢迎您: | 退出登录


文章评论