5

《前端运维》三、Docker--1镜像与容器 - Zaking

 2 years ago
source link: https://www.cnblogs.com/zaking/p/15008413.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

一、基本概念

  如果我们想要让软件运行起来,首先要保证操作系统的设置,其次还需要依赖各种组件和库的正确安装。那么虚拟机就是一种带环境安装的一种解决方案,它可以实现在一种操作系统里面运行另外一种操作系统,但是虚拟机的缺点也是十分明显的,资源占用多、冗余步骤多、启动速度慢。由于虚拟机存在的这些令人诟病的缺点。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 [你自己刚才生成的镜像名字]

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

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

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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK