容器技术—docker基础

  • 1. 容器化技术
  • 1.1 什么是容器化技术?
  • 1.2 为什么会有容器化技术
  • 1.3 虚拟化和容器化
  • 1.4 容器化的优势
  • 2. Docker
  • 2. 1 什么是docker
  • 2.2 docker架构
  • 3. docker安装
  • 4. docker常用命令命令


1. 容器化技术

1.1 什么是容器化技术?

容器化技术是指为应用程序提供标准化、可移植的打包的技术。就像运输行业使用物理容器来隔离不同的货物,以便通过轮船和火车运输,软件开发技术也越来越多地使用一种称为容器化的方法。

标准软件包 (也称为容器) 将应用程序的代码与相关配置文件、库以及运行应用所需的依赖项捆绑在一起。这使得开发人员和 IT 专业人员能够跨环境无缝部署应用程序。

1.2 为什么会有容器化技术

各位在在软件开发交付的过程中是否遭遇过以下这些情况呢?

一款产品,开发-上线 两套环境,各不相同,维护麻烦!
开发–运维,开发在自己的电脑上运行良好,然后把项目发布打包,丢给运维,运维需要配置各种环境,各种集群,压力超大,而且还很有可能失败!
版本更新,导致服务不可用!

应用程序移动到其他环境就无法正确运行,这个问题从有软件开发就存在了。会出现这种问题,通常是由于各环境的配置基础库要求和其他依赖项存在差异。

容器技术为应用程序打包和部署提供轻量级、不可变的基础结构来解决此问题。应用程序或服务、其依赖项及其配置打包为容器映像。容器化应用程序可以作为一个单元进行测试,并作为容器映像实例部署到主机操作系统。

这样,开发人员和 IT 专业人员利用容器,只需进行少量修改,甚至不需要进行任何修改,即可跨环境部署应用程序。

1.3 虚拟化和容器化

人们考虑虚拟化时,通常会想到虚拟机 (VM)。事实上,虚拟化可以采用多种形式,容器就是其中之一。 那么,VM 和容器之间的区别是什么?

大体说来,VM 虚拟化基础硬件,让多个操作系统 (OS) 实例可以在相同的硬件上运行。每个 VM 运行一个 OS,并有权访问表示基础硬件的虚拟化资源。

VM 有许多好处。其中包括,能够在同一服务器上运行不同操作系统,还可以更高效、更经济地利用物理资源,更快完成服务器配置。另一方面,每个 VM 都包含 OS 映像、库、应用程序等,因此可能会变得相当大。

容器虚拟化基础 OS,并使容器化应用能够感知其本身具备 OS,包括 CPU、内存、文件存储和网络连接。由于对基础 OS 和基础结构的差异进行了抽象,因此只要基本映像一致,就可以在任何地方部署并运行容器。对于开发人员来说,这有很大的吸引力。

由于容器共享主机 OS,因此它们不需要启动 OS 或加载库。这使得容器更加高效和轻量。容器化应用程序可以在几秒钟内启动,与 VM 方案相比,应用程序的更多实例可以适应计算机。共享 OS 方法具有额外的好处,即减少维护 (如修补和更新) 开销。

尽管容器是可移植的,但它们被限制于为其定义的操作系统。例如,适用于 Linux 的容器无法在 Windows 上运行,反之亦然。

物理主机、虚拟机和容器比较:

docker容器 status up docker容器技术_docker

1.4 容器化的优势

  • 灵活
    开发人员生成应用程序并将其打包到容器中,将其提供给 IT 以在标准化平台上运行时,这将减少部署应用程序的总体工作量,并可以简化整个开发和测试周期。这还可以促进开发和运营团队协作,并提升其工作效率,以加快应用交付。
  • 可移植性
    容器提供打包和保存运行所需应用程序的所有必要组件的标准化格式,在运行环境中,应用及其相关的依赖被隔离在容器里,互不干扰,但却共享同一个操作系统内核。这解决了“它能否在我的计算机上正常工作”这一典型问题,实现 OS 平台和云之间的移植。在任何位置部署容器时,它都会在一致的环境中执行,该环境在多次部署中保持不变,你可以从开发箱到生产拥有一致的格式。
  • 可快速伸缩
    由于容器没有 VM 的典型开销(包括单独的 OS 实例),因此同一基础结构上可以支持更多容器。容器的轻量特性意味着可以快速启动和停止它们,从而实现快速伸缩的方案。

云原生时代容器技术得到广泛应用,其中较为主流还是Docker公司下的Docker技术,除此之外还有Garden、Warden、Rocker等。

2. Docker

2. 1 什么是docker

Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。

Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器(可以理解为一个轻量级的linux系统)中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。

Docker 从 17.03 版本之后分为 CE(Community Edition: 社区版) 和 EE(Enterprise Edition: 企业版)

2.2 docker架构

docker容器 status up docker容器技术_运维_02


Docker 包括三个基本概念:

  • 镜像(Image):Docker 镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系统的 root 文件系统。
  • 容器(Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
  • 仓库(Repository):仓库可看成一个代码控制中心,用来保存镜像。

Docker 使用客户端-服务器 (C/S) 架构模式,使用远程API来管理和创建Docker容器。

容器与镜像的关系类似于面向对象编程中的对象与类,通过 Docker 镜像创建Docker 容器。

docker容器 status up docker容器技术_微服务_03

  • Docker 镜像(Images)
    Docker 镜像是用于创建 Docker 容器的模板,比如 Ubuntu 系统。
  • Docker 容器(Container):
    容器是独立运行的一个或一组应用,是镜像运行时的实体。
  • Docker 客户端(Client):
    Docker 客户端通过命令行或者其他工具使用 Docker SDK ( https://docs.docker.com/develop/sdk/) 与 Docker 的守护进程通信。
  • Docker 主机(Host)
    一个物理或者虚拟的机器用于执行 Docker 守护进程和容器。
  • Docker Registry
    Docker 仓库用来保存镜像,可以理解为代码控制中的代码仓库。Docker Hub(https://hub.docker.com) 提供了庞大的镜像集合供使用。一个 Docker Registry 中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。
  • Docker Machine
    Docker Machine是一个简化Docker安装的命令行工具,通过一个简单的命令行即可在相应的平台上安装Docker,比如VirtualBox、 Digital Ocean、Microsoft Azure。

3. docker安装

docker支持Ubuntu、Debian、CentOS、Windows、MacOS等各种操作系统,详细的介绍可阅读以下教程,网上也有很多教程,这里只以 CentOS 7.x 、docker 20.10.13 为例进行简单的介绍。
Docker 教程 | 菜鸟教程 (runoob.com)Docker经典入门学习教程 - 运维派 (yunweipai.com)

手动安装:
(1) 卸载旧版本,较旧的 Docker 版本称为 docker 或 docker-engine 。如果已安装这些程序,请卸载它们以及相关的依赖项。

$ sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine

(2) 安装所需的软件包。yum-utils 提供了 yum-config-manager ,并且 device mapper 存储驱动程序需要 device-mapper-persistent-data 和 lvm2。

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

(3) 设置仓库,在新主机上首次安装 Docker Engine-Community 之前,需要设置 Docker 仓库。之后可以从仓库安装和更新 Docker。

$ sudo yum-config-manager  --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

(4) 安装 Docker Engine-Community

$ sudo yum install docker-ce docker-ce-cli containerd.io

安装完成之后,通过shell命令docker,能够看到以下内容,即代表安装成功。

docker容器 status up docker容器技术_docker_04


(5) 启动docker

Docker 安装完默认未启动,此时使用docker ps等命令的时候,是无法执行的,通过以下方式启动docker

$ sudo systemctl start docker

设置开机自启:

systemctl enable docker.service

(6) 镜像加速
修改/etc/docker/daemon.json 文件(如果文件不存在则新建该文件),写入以下内容:

{"registry-mirrors":["https://reg-mirror.qiniu.com/"]}  // 配置镜像加速器,名称自定义,加速器地址可以在网上找

常用的加速器地址有:
○ 科大镜像:https://docker.mirrors.ustc.edu.cn/
○ 网易:https://hub-mirror.c.163.com/
○ 阿里云:https://<你的ID>.mirror.aliyuncs.com
○ 七牛云加速器:https://reg-mirror.qiniu.com

之后重启服务:

$ sudo systemctl daemon-reload
$ sudo systemctl restart docker

需要注意的是,CentOS 6 因内核太旧,即使支持安装docker,但会有各种问题,不建议安装,推荐在CentOS 7以上版本使用docker。

另外再提一点,如果是windows 或者windows server的话,需要物理机可以支持虚拟化,这是因为Docker 并非是一个通用的容器工具,它依赖于已存在并运行的 Linux 内核环境,其实质上是在已经运行的 Linux 下制造了一个隔离的文件环境,因此它执行的效率几乎等同于所部署的 Linux 主机。因此,Docker 必须部署在 Linux 内核的系统上,如果其他系统想部署 Docker 就必须安装一个虚拟 Linux 环境。并且,在低版本的window系统下,如win7、win8,windows server 2012(相当于win8.1)等,还需利用 docker toolbox 来安装。具体的安装过程这里就不赘述了,请查阅网上教程。

4. docker常用命令命令

  • docker --help
    docker提供了帮助文档,通过上面的命令可以查看docker支持哪些命令和参数
  • docker [command] --help
    查看docker具体某个命令的使用方式

(1) docker镜像相关命令

  • docker search [镜像名称]
    查找镜像,从已配置的镜像仓库中查找,默认Docker Hub,当然也可以直接到镜像仓库网页查找,这里查找到的镜像信息不包含镜像标签,如果需要查看某个仓库下的一个镜像的标签的话,可以使用以下方式
    创建一个sh脚本,名称如list_image_tags.sh
#!/bin/sh
repo_url=https://registry.hub.docker.com/v1/repositories
image_name=$1
curl -s ${repo_url}/${image_name}/tags | json_reformat | grep name | awk '{print $2}' | sed -e 's/"//g'

执行sh脚本

list_image_tags.sh [镜像名称]

docker容器 status up docker容器技术_docker_05


其中,json_reformat 格式化命令需要安装yajl包:

yum install -y yajl
  • docker pull [镜像名称:镜像标签]
    从镜像仓库拉取镜像,没有标签的时候默认最新版本
  • docker images
    列出本地主机上的镜像
  • docker rmi [镜像名称或镜像id]
    删除镜像,存在该镜像创建的容器时,镜像无法删除,必须先停止容器,并将容器删除后才能删除镜像
  • docker commit [容器id] [保存的镜像名称:保存的的镜像标签]
    有些时候,我们启动一个容器之后,可能会在这个容器内部做一些操作,例如安装一些包,如果想将我们特殊处理后的镜像保存下来,我们可以将这个容器保存为一个镜像,如下:
docker commit -m="has update" -a="yyl" db488294c5e4 yyl/ubuntu:v2

docker容器 status up docker容器技术_docker容器 status up_06


这种将当前容器保存为镜像的方式不会覆盖原有的镜像,可以看到两个镜像id是不一样的,命令中的-m 是提交的描述信息,-a是指定镜像作者。这种方式是两种创建镜像方法中的一个。

  • docker tag [镜像id] [新的镜像名称:新的镜像标签]
    镜像添加一个新的标签,这种方式不会复制镜像,只是同一个镜像多了一个不同的标签,从下面也可以看到,镜像id是一样的
  • docker save [镜像id] > [保存路径]
    将镜像保存为压缩文件,以便在不同机器进行迁移
  • docker load < [镜像路径]
    将镜像压缩文件导入docker。里面例子中先将docker中有两个标签的镜像8e2456111ce1删除,再将刚刚保存下来的镜像文件导入

(2)docker容器相关命令

  • docker ps
    列出本地主机上已启动的容器
  • docker ps -a
    列出本地主机上所有的容器
  • docker run [镜像名称:镜像标签]
    通过镜像启动一个容器,首先会查找本地镜像,如果本地没有,则会从镜像仓库拉取
    doker run 命令有很多参数,常用的参数如下,以nacos举例,更多的参数请参考doker run --help或者查阅网上文档:
docker  run 
--name nacos // 容器名称
-itd // i: 使用交互方式运行,t: 开启终端,d: 在后台运行,三者可分开使用,这里只是放在了一起
-p 8848:8848 // 端口映射,前面为宿主机端口,后面为容器内部端口
--privileged=true // 设置是否让容器内部获取宿主机root权限
--memory=1g // 设置给容器分配的最大内容
--cpus=3 // 设置设置cpu个数
--restart=always // 重启模式,设置为always将在容器挂掉之后自动重启
-e JVM_XMS=256m // 环境变量,根据镜像内部开发的参数传入
-e JVM_XMX=256m 
-e MODE=standalone 
-e PREFER_HOST_MODE=hostname 
-v /home/nacos/logs:/home/nacos/logs // 文件映射,映射日志文件到本地文件夹,前面为宿主机路径,后面为docker内部路径
-v /home/nacos/init.d/custom.properties:/home/nacos/init.d/custom.properties // 映射配置文件到本地文件夹
nacos/nacos-server // docker镜像名称
  • docker start [容器id/容器名称]
    启动一个已停止的容器
  • docker stop [容器id/容器名称]
    停止一个容器
  • docker rm [容器id/容器名称]
    删除一个容器
  • docker port [容器id/容器名称]
    查看容器端口映射
  • docker logs [容器id/容器名称]
    查看容器内部的标准输出,可以加上-f参数,像使用 tail -f 一样来输出容器内部的标准输出
  • docker top [容器id/容器名称]
    查看容器内部运行的进程
  • docker exec -it [容器id/容器名称] /bin/bash
    进入容器内部终端,这个命令退出容器终端不会导致容器的停止。
  • docker cp
    文件复制
    将容器内部文件复制到宿主机:
    docker cp 容器id:容器内目录 宿主机目录
    将宿主机文件复制到容器内部:
    docker cp 宿主机目录 容器id:容器内目录
  • docker inspect [容器id/容器名称]
    查看容器的底层信息,它会返回一个 JSON 文件记录着 Docker 容器的配置和状态信息。
  • docker export [容器id] > [保存路径]
    导出本地某个容器
  • cat [文件路径] | docker import - [镜像名称:镜像标签]
    将容器快照文件中导入为镜像,也可以用以下方式:
    docker import [文件路径或url] [镜像名称:镜像标签]