• 《前端运维》三、Docker1镜像与容器


    一、基本概念

      如果我们想要让软件运行起来,首先要保证操作系统的设置,其次还需要依赖各种组件和库的正确安装。那么虚拟机就是一种带环境安装的一种解决方案,它可以实现在一种操作系统里面运行另外一种操作系统,但是虚拟机的缺点也是十分明显的,资源占用多、冗余步骤多、启动速度慢。由于虚拟机存在的这些令人诟病的缺点。Linux发展出了另一种虚拟化技术,Linux Containers,即Linux容器,缩写为LXC。

      Linux容器并没有虚拟一个完整的操作系统,而是对进程进行隔离。或者说,在正常进程的外面套了一层保护层。对于容器里面的进程来说,它接触到的各种资源都是虚拟的,从而实现与底层系统的隔离。Linux的容器也十分明显,体积小、启动快、资源占用也是极少的。

      Docker属于Linux容器的一种封装,提供简单易用的容器使用接口。它是目前最流行的Linux容器解决方案。Docker将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里面运行,就好像在真实的物理机上运行一样。

      同时Docker的应用场景也十分广泛,比如:单项目打包、整套项目打包、新开源技术、环境一致性、持续集成、微服务、弹性伸缩等。

      下面我们来看一张图,来学习下Docker体系的结构:

      我们看上图哦,Docker通过Docker Client的客户端发送指令,驱动Docker Engine引擎来启动容器,然后通过Containerd来管理对应容器的内容,然后,shim只用来管理每个独立的容器,通过runC这个轻量级的工具来启动容器。在启动容器的时候,可能会去Image Repository镜像仓库中去取对应的依赖。

      Docker提供了一些内部的组件,我们也需要了解一下:

    • namespaces,命名空间,Linux内核提供的一种对进程资源隔离的机制,例如进程、网络、挂载等资源。
    • cgroups,控制组,linux内核提供的一种限制进程资源的机制,例如cpu、内存等资源。
    • unonFS,联合文件系统,支持将不同位置的目录挂载到同一虚拟文件系统中,形成一种分层的模型。

    二、Docker安装

      首先docker的版本类型上,分为企业版和社区版,咱们用社区版就可以了,企业版是付费的。它的安装文档地址在:https://docs.docker.com/engine/install/centos/

      我们通过下面的命令来安装下docker:

      先安装docker的一些依赖:

    yum install -y yum-utils   device-mapper-persistent-data   lvm2

      再安装docker的安装源:

    yum-config-manager     --add-repo     https://download.docker.com/linux/centos/docker-ce.repo

      最后安装docker:

    yum install docker-ce docker-ce-cli containerd.io -y

      这样,我们的docker就安装好了。然后我们看下常用的一些命令:

    # 启动docker
    systemctl start docker
    # 查看docker信息
    docker version
    docker info
    # 卸载docker
    yum remove docker
    # 删除docker相关的文件夹
    rm -rf /var/lib/docker

      我们也可以把相关的软件依赖改成阿里云的镜像地址,这样下载的时候会快一些,我就不多说了,因为我没改:

    # 创建一个文件
    sudo mkdir -p /etc/docker
    # 写入一些配置
    sudo tee /etc/docker/daemon.json <<-'EOF'
    {
      "registry-mirrors": ["https://fwvjnv59.mirror.aliyuncs.com"]
    }
    EOF
    # 重载所有修改过的配置文件 
    # daemon-reload: 重新加载某个服务的配置文件
    sudo systemctl daemon-reload
    sudo systemctl restart docker

    三、Docker镜像

       Docker把应用程序及其依赖,打包再image镜像文件里面,只有通过这个文件,才能生成Docker容器。image镜像文件可以看作是容器的模板。Docker根据image镜像文件生成容器的实例。同一个image镜像文件,可以生成多个同时运行的image实例。镜像文件不是一个单一的文件,而是有多层次的结构。容器其实就是在image镜像的最上面一层加了一层读写层。在运行容器里做的任何文件改动,都会写到这个读写层里。如果容器删除了,最上面的读写层也就删除了,改动也就丢失了。

      我们可以通过docker history [id/name] 查看镜像中各层级的内容及大小,每层对应着dockerfile中的一条指令。

      下面我们来学习下一些基本的命令:

    1. docker image ls,查看全部镜像。字段含义如下:
      REPOSITORY 仓库地址
      TAG 标签
      IMAGE_ID 镜像ID
      CREATED 创建时间
      SIZE 镜像大小
    2. docker search [imageName],查找镜像。字段含义如下:
      字段含义
      NAME 名称
      DESCRIPTION 描述
      STARTS 星星的数量
      OFFICIAL 是否官方源
    3. docker history [imageName],查看镜像历史。
    4. docker inspect [imageName],显示一个或多个镜像信息。
    5. docker pull [imageName],拉取镜像。
    6. docker push [imageName],推送一个镜像到镜像仓库。
    7. docker rmi [imageName],删除镜像。
    8. docker image prune,移除未使用的镜像,没有标记或被任何容器引用。
    9. tag,标记本地镜像,将其归入某一仓库
      • 语法:docker tag [OPTIONS] IMAGE[:TAG] [REGISTRYHOST/][USERNAME/]NAME[:TAG]。
      • 例子:docker tag centos:7 zaking/centos:v1。
    10. export,将容器文件系统作为一个tar归档文件导出到STDOUT。
      • 语法:docker export [OPTIONS] CONTAINER。
      • docker export -o hello-world.tar b2712f1067a3。
    11. import,导入容器快照文件系统tar归档文件并创建镜像。
      • 语法:docker import [OPTIONS] file/URL/- [REPOSITORY[:TAG]。
      • 例子:docker import hello-world.tar。
    12. save,将指定文件保存成tar文件。
      • 语法:docker save [OPTIONS] IMAGE [IMAGE...]。
      • docker save -o hello-world.tar hello-world:latest。
    13. load,加载tar文件并创建镜像。
      • 例子:docker load -i hello-world.tar。
    14. build,根据Dockerfile构建镜像。
      • 语法:docker build [OPTIONS] PATH / URL / -。
      • 例子:docker build -t zf/ubuntu:v1。

      然后,我们学习了一些相关的命令,下面我们来拿这些命令做一些实践:

      首先,我们查找一下centos镜像:

    docker search centos

      然后,我们把centos的镜像拉取到本地,如果你这里下载很慢的话,请回头安装阿里源,嘻嘻:

    docker pull centos

      然后,我们可以使用fs命令,查看下现在有哪些镜像:

    docker image ls

      下一步我们从远程镜像仓库拉取一个docker官方的例子镜像到本地的镜像仓库:

    docker pull docker.io/hello-world

      然后,可以通过rmi命令,删除本地镜像:

    docker rmi hello-world

    四、Docker容器

       首先,我们来学习下一些有关于容器的基本概念。docker run 命令会从image镜像文件中生成一个正在运行的容器实例。该命令具有自动抓取image镜像文件的功能,如果发现本地没有指定的image文件,就会从仓库自动抓取。输出提示后,实例就会停止运行,容器自动终止,当然,并不是所有的容器都会自动终止。同过image镜像文件生成的生成的容器实例,本身也是一个文件,成为容器文件。生成了容器后,就会同时存在两个文件,image镜像文件和容器文件。关闭容器并不会删除容器文件,只是停止容器的运行。

      下面,我们来学习一下容器有关的命令:

    1. docker run:启动容器。
      • 例子:docker run ubuntu /bin/echo 'hello world'。这句话的意思就是,通过ubuntu镜像生成一个容器,在容器中执行/bin/echo 'helloworld'的命令。我们看下图,当我们想要执行的命令在容器中打印后,该容器就自动终止了。这就是我们上面说到的含义。另外,如果本地没有对应的镜像,docker会自动去docker hub拉取。
      • 参数:
        • -i,--interactive:交互式。
        • -t,-tty:分配一个伪终端。
        • -d,--detach:运行容器到后台。
        • -a,--attach list:附加到运行的容器。
        • -e,--env list:设置环境变量。
        • -p,--publish list:发布容器端口到主机。
        • -P,--publish-all:。
    2. docker ps:查看容器。
      • 参数:
        • -a:显示所有的容器,包括已停止的。
        • -l:显示最新的那个容器。
          字段含义
          CONTAINER ID 容器ID
          IMAGE 使用的镜像
          COMMAND 使用的命令
          CREATED 创建时间
          STATUS 状态
          PORTS 端口号
          NAMES 自动分配的名称
    3. docker run -i -t ubuntu /bin/bash:运行交互式的容器。可以通过exit命令或CTRL+D退出交互界面。
      • -t=--interactive 在新容器内指定一个伪终端或终端。
      • -i=--tty 允许你对容器内的标准输入 (STDIN) 进行交互。
    4. docker kill:kill是不管容器同不同意,直接执行kill -9,强行终止;stop的话,首先给容器发送一个TERM信号,让容器做一些退出前必须的保护性、安全性操作,然后让容器自动停止运行,如果在一段时间内,容器还是没有停止,再进行kill -9,强行终止。
      • 例子:docker kill 5a5c3a760f61。
    5. docker rm:删除容器
      • 例子:docker rm 5a5c3a760f61。
      • docker rm $(docker ps -a -q)。删除所有的容器,-a,所有的,-q显示id号。就是批量删除所有的意思。
    6. docker start [containerId]:启动容器
    7. docker stop [containerId]:停止容器。
    8. docker attach [containerID]:进入一个容器。
    9. docker container -exec -it [containerID] /bin/bash:进入一个正在进行中的容器。
    10. docker container cp [containerID]/readme.md .:拷贝文件。
    11. docker run --rm ubuntu /bin/bash:自动删除。
    12. docker container stats:显示容器资源使用统计。
    13. docker container top:显示一个容器运行的进程。
    14. docker update -m 500m 6d1a25f95132:更新一个或多个容器配置。
    15. 列出指定的容器的端口映射:
      docker run -d -p 8080:80 nginx 
      docker container port containerID 
    16. docker logs [containerId]:查看docker容器的输出。

      下面,我们把上面学习的命令来实践一下:

      刚才我们在学习run命令的时候已经启动了一个容器并打印出了命令,那个是最基础的方法,那下面,我们来查看下我们的容器都有哪些:

    docker ps -a

       哈,只有一个,就是我们刚才执行的那个。下面我们来试一下启动一个交互式的容器:

    docker run -i -t ubuntu /bin/bash 

      我们就进入了交互式容器的伪终端里,可以进行命令交互。然后我们执行下面的命令:

    docker run centos ping www.baidu.com

      执行了这个命令后,就会一直ping www.baidu.com,别的事就干不了了,只能看着:

      此时,我们就需要--detach参数,进入后台运行:

    docker run --detach centos ping www.baidu.com

      然后,这个容器就会在后台运行:

       那,我想要查看这个容器里面的日志怎么办呢,通过下面的命令就可以查看对应容器里的日志了:

    docker logs --follow [id/name]

      当然,我们也可以通过attach,重新进入这个容器。

    docker attach [id]

      然后,可以通过stop命令,停止某个正在运行中的容器:

    docker stop [containerId]

       docker stop是否能停止,是由容器内部指定的,需要运行完一些必要的容器才会停止。如果你希望可以立即杀死该容器,直接强行终止,就使用kill命令。停止了以后,我们可以通过docker start来重新启动。

      然后,我们可以通过rm命令,删除已有的容器:

    docker ps -a

      先通过ps命令看下目前容器的id,然后通过rm删除:

    docker rm [id]

      这样一个一个删除太慢了,我们可以通过下面的命令批量删除:

    docker rm $(docker ps -a -q)

      很简单吧。

    1、其它命令实践:

      下面我们来练习下其他命令,我们先启动个hello-world的容器:

    docker run hello-world

      然后我们把这个容器导出:

    docker export -o hello-world.tar [cantainerId]

      然后我们看下这个文件:  

       删除这个容器:

    docker rm [containerId]

      然后镜像文件也删除掉:

    docker rmi hello-world

       然后,我们可以通过import命令,把刚才导出的tar包,再导入回来:

    docker import hello-world.tar

       就是这个了。

       save命令可以把指定镜像打包成tar文件:

    docker save -o redis.tar redis:latest

      然后删除你刚才打包成tar的镜像,怎么删除我就不说了啊。删除了之后,我们可以通过load命令,把刚才的tar包下载回来。

    docker load -i redis.tar

      用户既可以使用 docker load 来导入镜像存储文件到本地镜像库,也可以使用 docker import 来导入一个容器快照到本地镜像库。这两者的区别在于容器(import)快照文件将丢弃所有的历史记录和元数据信息(即仅保存容器当时的快照状态),而镜像(load)存储文件将保存完整记录,体积也要大。此外,从容器(import)快照文件导入时可以重新指定标签等元数据信息。

     2、下面我们来实践一些容器相关的:

      我们先后台跑起来前面的那个ping命令:

    docker run --detach centos ping www.baidu.com

      然后,我们来用stats看下它的状态:

    docker stats [containerId]

       然后可以通过top命令,查看一个运行中容器的进程:

    docker top [containerId]

       我们还可以使用update命令更新一个或多个容器的配置,看stats那个图,LIMIT是1.7G左右,我们来通过update命令,限制一下它的内存:

    docker update -m 500m [containerId]

       可惜报错了,他跟你说还要同时设置memoryswap,设置一下呗:

       然后LIMIT就变成了500M,简单吧。

    3、下面我们来实践下如何映射指定容器的端口:

      先使用下面的命令,启动一个docker容器中的nginx:

    docker run -d -P nginx

      这样会自动指定与宿主机的端口映射。

       图中红框的部分就是自动指定的与宿主机的映射,我们也可以手动设置:

    docker run -d -p 8080:80

       这个意思就是说宿主机的ip是8080端口映射到docker容器的nginx的80端口。

    4、学习下如何commit命令制作个性化镜像:

      我们先停止并删除之前所有的容器:

    docker stop $(docker ps -a -q)
    docker rm $(docker ps -a -q)

      然后像之前的例子一样,启动一个nginx容器。

      通过下面的命令进入到容器的伪终端中:

    docker exec -it [containerId]/bin/bash

      然后,我们进入到容器的nginx存储html文件的目录,/usr/share/nginx/html:

    cd /usr/share/nginx/html

      创建一个html文件:

    echo hello > hello.html

      然后我们再打开一个命令行,访问一下刚才的nginx服务,要注意查看端口号哦:

       这样就成功了。下面看下如何基于这个容器,建一个新的镜像:

    docker commit -m'zakings nginx' -a'zaking' 0a90e57ca86b zaking/zakingnginx

      这段代码是什么意思呢,docker commit -m'描述信息' -a'作者信息' [containerId] [包名]。

       我们可以查看下:

       多了我们刚才生成的镜像。下面我们清空下容器,使用我们自己创建的镜像创建容器:

       不多说了,实践好多遍了。

      然后呢,实际上就是跟之前的方式一样,创建nginx容器,并自动设置端口号就好了:

    docker run -d -P [你自己刚才生成的镜像名字]

       然后,在另一个终端访问下:

       直接就出来了,不需要我们再重新创建了。当然,如果要发布到远程仓库,需要注册账号。这个我就不多说了,大家有兴趣可以自己试一下。

      好啦,关于容器和镜像的部分。就先到这里了。

  • 相关阅读:
    Python网络编程 —— 粘包问题及解决方法
    Python网络编程 —— socket(套接字)及通信
    Python网络编程 —— 网络基础知识
    Python
    MySQL 之 数据的导出与导入
    MySQL 之 慢查询优化及慢日志管理
    MySQL 之 索引进阶
    MySQL 之 索引
    MySQL 之 事务
    MySQL 之 表的存储引擎
  • 原文地址:https://www.cnblogs.com/zaking/p/15008413.html
Copyright © 2020-2023  润新知