hualinux 进阶 1.2: centos8 docker CE 入门及安装(一) 手把手入门版

目录

一、docker技术组成

1.1 docker的组成技术

1.1.1 Linux Namespace

1.1.2 Linux Cgroups

1.1.3 根文件系统rootfs

1.2 dokcer的本质

二、其它知识点

2.1 what-什么是容器

容器与虚拟机

2.2 why-为什么需要容器?

容器解决的问题

如何让每种服务能够在所有的部署环境中顺利运行?

Docker 的特性

容器的优势

2.3 How - 容器是如何工作的?

Docker客户端

Docker服务器

Docker镜像

Docker容器

Registry

Docker组件如何协作?

小结

三、docker安装

3.1 安装环境

3.1.1 docker版本及安装环境要求

3.1.2 安装前准备

3.2 docker安装及测试

3.2.1 docker安装

3.2.2 docker测试

3.3 docker镜像加速器

四、docker常用命令及操作

4.1 查找和获取镜像

4.1.1 docker镜像查询docker search

4.1.2 下载镜像docker pull

4.1.3 查看本地镜像

4.2 容器相关操作

4.2.1 运行容器

4.2.2 例1 运行nginx容器

4.2.3 启动/停止/删除容器

4.2.4 查看容器状态

4.2.5 登陆容器docker exec

4.3 其它命令

五、docker其它

5.1 docker注意事项

5.1.1 windows上可以运行linux docker吗

5.1.2 docker时间问题

5.2 多个容器间如何互通


现在运维基本上都会多少接触到docker,如果不会docker,别人会感觉你有点low,放在运维进阶第一篇,我觉得是有意义的。它承着前面的基础,也是新运维的起点,也为后面进阶内容做引路。

推荐书箱

每天5分钟玩转Docker容器技术》:感觉讲得还可以

深入浅出Docker》:也是入门的书籍

修改时间:2020.11.12

一、docker技术组成

简单理解一下docker一些技术也有好处的。

1.1 docker的组成技术

一个“容器”,实际上是一个由 Linux Namespace、Linux Cgroups 和 rootfs 三种技术构建出来的进程的隔离环境。

Namespace 的作用是“隔离”,它让应用进程只能看到该 Namespace 内的“世界”;而 Cgroups 的作用是“限制”,它给这个“世界”围上了一圈看不见的墙。这么一折腾,进程就真的被“装”在了一个与世隔绝的房间里,而这些房间就是 PaaS 项目赖以生存的应用“沙盒”。

根目录系统rootfs,挂载在容器根目录上、用来为容器进程提供隔离后执行环境的文件系统。

1.1.1 Linux Namespace

Linux Namespace:实现环境隔离。基于 Linux Namespace 的隔离机制相比于虚拟化技术也有很多不足之处,其中最主要的问题就是:隔离得不彻底。最典型的就是系统时间,docker主宿主是共享的。

相比于在虚拟机里面可以随便折腾的自由度,在容器里部署应用的时候,“什么能做,什么不能做”,就是用户必须考虑的一个问题。

1.1.2 Linux Cgroups

Linux Cgroups:就是 Linux 内核中用来为进程设置资源限制的一个重要功能。
Linux Cgroups 的全称是 Linux Control Group。它最主要的作用,就是限制一个进程组能够使用的资源上限,包括 CPU、内存、磁盘、网络带宽等等。

Linux Cgroups 的设计还是比较易用的,简单粗暴地理解呢,它就是一个子系统目录加上一组资源限制文件的组合

1.1.3 根文件系统rootfs

容器里的应用进程,理应看到一份完全独立的文件系统。这样,它就可以在自己的容器目录(比如 /tmp)下进行操作,而完全不会受宿主机以及其他容器的影响。

Mount Namespace 跟其他 Namespace 的使用略有不同的地方:它对容器进程视图的改变,一定是伴随着挂载操作(mount)才能生效。

Mount Namespace 正是基于对 chroot 的不断改良才被发明出来的,它也是 Linux 操作系统里的第一个 Namespace。

当然,为了能够让容器的这个根目录看起来更“真实”,我们一般会在这个容器的根目录下挂载一个完整操作系统的文件系统,比如 Ubuntu16.04 的 ISO。这样,在容器启动之后,我们在容器里通过执行 "ls /" 查看根目录下的内容,就是 Ubuntu 16.04 的所有目录和文件。

而这个挂载在容器根目录上、用来为容器进程提供隔离后执行环境的文件系统,就是所谓的“容器镜像”。它还有一个更为专业的名字,叫作:rootfs(根文件系统)

 

需要明确的是,rootfs 只是一个操作系统所包含的文件、配置和目录,并不包括操作系统内核。在 Linux 操作系统中,这两部分是分开存放的,操作系统只有在开机启动时才会加载指定版本的内核镜像

所以说,rootfs 只包括了操作系统的“躯壳”,并没有包括操作系统的“灵魂”。同一台机器上的所有容器,都共享宿主机操作系统的内核。

由于 rootfs 里打包的不只是应用,而是整个操作系统的文件和目录,也就意味着,应用以及它运行所需要的所有依赖,都被封装在了一起。 

对一个应用来说,操作系统本身才是它运行所需要的最完整的“依赖库”。

有了容器镜像“打包操作系统”的能力,这个最基础的依赖环境也终于变成了应用沙盒的一部分。这就赋予了容器所谓的一致性:无论在本地、云端,还是在一台任何地方的机器上,用户只需要解压打包好的容器镜像,那么这个应用运行所需要的完整的执行环境就被重现出来了。

1.2 dokcer的本质

容器是一个“单进程”模型。

由于一个容器的本质就是一个进程,用户的应用进程实际上就是容器里 PID=1 的进程,也是其他后续创建的所有进程的父进程。这就意味着,在一个容器中,你没办法同时运行两个不同的应用,除非你能事先找到一个公共的 PID=1 的程序来充当两个不同应用的父进程,这也是为什么很多人都会用 systemd 或者 supervisord 这样的软件来代替应用本身作为容器的启动进程。

但是,在后面分享容器设计模式时,我还会推荐其他更好的解决办法。这是因为容器本身的设计,就是希望容器和应用能够同生命周期,这个概念对后续的容器编排非常重要。否则,一旦出现类似于“容器是正常运行的,但是里面的应用早已经挂了”的情况,编排系统处理起来就非常麻烦了。

既然docker的本质是进程的话,那么它就要用宿主共用内核,docker镜像的文件系统只是“壳”,没人内核的,所以说windows系统的docker不能安装linux操作系统。

PS:这些不懂不要紧有专业的文章介绍,可以搜索一下,如果搜索不到,可以私聊我。

二、其它知识点

2.1 what-什么是容器

容器是一种轻量级、可移植、自包含的软件打包技术,使应用程序可以在几乎任何地方以相同的方式运行。开发人员在自己笔记本上创建并测试好的容器,无需任何修改就能够在生产系统的虚拟机、物理服务器或公有云主机上运行。

容器与虚拟机

谈到容器,就不得不将它与虚拟机进行对比,因为两者都是为应用提供封装和隔离。

容器由两部分组成:

1.应用程序本身

2.依赖:比如应用程序需要的库或其他软件

容器在 Host 操作系统的用户空间中运行,与操作系统的其他进程隔离。这一点显著区别于的虚拟机。

传统的虚拟化技术,比如 VMWare, KVM, Xen,目标是创建完整的虚拟机。为了运行应用,除了部署应用本身及其依赖(通常几十 MB),还得安装整个操作系统(几十 GB)。

下图展示了二者的区别

上图所示,由于所有的容器共享同一个 Host OS,这使得容器在体积上要比虚拟机小很多。另外,启动容器不需要启动整个操作系统,所以容器部署和启动速度更快,开销更小,也更容易迁移。

2.2 why-为什么需要容器?

为什么需要容器?容器到底解决的是什么问题?

简要的答案是:容器使软件具备了超强的可移植能力。

 

容器解决的问题

我们来看看今天的软件开发面临着怎样的挑战?

如今的系统在架构上较十年前已经变得非常复杂了。以前几乎所有的应用都采用三层架构(Presentation/Application/Data),系统部署到有限的几台物理服务器上(Web Server/Application Server/Database Server)。

而今天,开发人员通常使用多种服务(比如 MQ,Cache,DB)构建和组装应用,而且应用很可能会部署到不同的环境,比如虚拟服务器,私有云和公有云。

一方面应用包含多种服务,这些服务有自己所依赖的库和软件包;另一方面存在多种部署环境,服务在运行时可能需要动态迁移到不同的环境中。这就产生了一个问题:

如何让每种服务能够在所有的部署环境中顺利运行?

于是我们得到了下面这个矩阵:

 

各种服务和环境通过排列组合产生了一个大矩阵。开发人员在编写代码时需要考虑不同的运行环境,运维人员则需要为不同的服务和平台配置环境。对他们双方来说,这都是一项困难而艰巨的任务。

 

如何解决这个问题呢?

聪明的技术人员从传统的运输行业找到了答案。几十年前,运输业面临着类似的问题。

每一次运输,货主与承运方都会担心因货物类型的不同而导致损失,比如几个铁桶错误地压在了一堆香蕉上。另一方面,运输过程中需要使用不同的交通工具也让整个过程痛苦不堪:货物先装上车运到码头,卸货,然后装上船,到岸后又卸下船,再装上火车,到达目的地,最后卸货。一半以上的时间花费在装、卸货上,而且搬上搬下还容易损坏货物。

这同样也是一个 NxM 的矩阵。

幸运的是,集装箱的发明解决这个难题。

任何货物,无论钢琴还是保时捷,都被放到各自的集装箱中。集装箱在整个运输过程中都是密封的,只有到达最终目的地才被打开。标准集装箱可以被高效地装卸、重叠和长途运输。现代化的起重机可以自动在卡车、轮船和火车之间移动集装箱。集装箱被誉为运输业与世界贸易最重要的发明。

Docker 将集装箱思想运用到软件打包上,为代码提供了一个基于容器的标准化运输系统。Docker 可以将任何应用及其依赖打包成一个轻量级、可移植、自包含的容器。容器可以运行在几乎所有的操作系统上。

其实,“集装箱” 和 “容器” 对应的英文单词都是 “Container”。“容器” 是国内约定俗成的叫法,可能是因为容器比集装箱更抽象,更适合软件领域的原故吧。

我个人认为:在老外的思维中,“Container” 只用到了集装箱这一个意思,Docker 的 Logo 不就是一堆集装箱吗?

Docker 的特性

我们可以看看集装箱思想是如何与 Docker 各种特性相对应的。

特性

集装箱

Docker

打包对象

几乎任何货物

任何软件及其依赖

硬件依赖

标准形状和接口允许集装箱被装卸到各种交通工具,整个运输过程无需打开

容器无需修改便可运行在几乎所有的平台上 -- 虚拟机、物理机、公有云、私有云

隔离性

集装箱可以重叠起来一起运输,香蕉再也不会被铁桶压烂了

资源、网络、库都是隔离的,不会出现依赖问题

自动化

标准接口使集装箱很容易自动装卸和移动

提供 run, start, stop 等标准化操作,非常适合自动化

高效性

无需开箱,可在各种交通工具间快速搬运

轻量级,能够快速启动和迁移

职责分工

货主只需考虑把什么放到集装箱里;承运方只需关心怎样运输集装箱

开发人员只需考虑怎么写代码;运维人员只需关心如何配置基础环境

容器的优势

对于开发人员 - Build Once, Run Anywhere

容器意味着环境隔离和可重复性。开发人员只需为应用创建一次运行环境,然后打包成容器便可在其他机器上运行。另外,容器环境与所在的 Host 环境是隔离的,就像虚拟机一样,但更快更简单。

 

对于运维人员 - Configure Once, Run Anything

只需要配置好标准的 runtime 环境,服务器就可以运行任何容器。这使得运维人员的工作变得更高效,一致和可重复。容器消除了开发、测试、生产环境的不一致性。

 

2.3 How - 容器是如何工作的?

首先会介绍 Docker 的架构,然后分章节详细讨论 Docker 的镜像、容器、网络和存储。的。

Docker 的核心组件包括:

  1. Docker 客户端 - Client
  2. Docker 服务器 - Docker daemon
  3. Docker 镜像 - Image
  4. Registry
  5. Docker 容器 - Container

Docker 架构如下图所示:

Docker 采用的是 Client/Server 架构。客户端向服务器发送请求,服务器负责构建、运行和分发容器。客户端和服务器可以运行在同一个 Host 上,客户端也可以通过 socket 或 REST API 与远程的服务器通信。

Docker客户端

最常用的 Docker 客户端是 docker 命令。通过 docker 我们可以方便地在 Host 上构建和运行容器。

docker 支持很多操作(子命令),后面会逐步用到。

[root@vm82 ~]# docker --help
Commands:
  attach      Attach to a running container
  build       Build an image from a Dockerfile
  commit      Create a new image from a container's changes
  cp          Copy files/folders between a container and the local filesystem
  create      Create a new container
…

除了 docker 命令行工具,用户也可以通过 REST API 与服务器通信。

Docker服务器

Docker daemon 是服务器组件,以 Linux 后台服务的方式运行。

Docker daemon 运行在 Docker host 上,负责创建、运行、监控容器,构建、存储镜像。

默认配置下,Docker daemon 只能响应来自本地 Host 的客户端请求。如果要允许远程客户端请求,需要在配置文件中打开 TCP 监听,步骤如下:

1.编辑配置文件 /etc/systemd/system/multi-user.target.wants/docker.service,在环境变量 ExecStart 后面添加 -H tcp://0.0.0.0,允许来自任意 IP 的客户端连接。

 如果使用的是其他操作系统,配置文件的位置可能会不一样。

2.重启 Docker daemon

 服务器 IP 为 192.168.56.102,客户端在命令行里加上 -H 参数,即可与远程服务器通信。

info 子命令用于查看 Docker 服务器的信息。 

Docker镜像

可将 Docker 镜像看着只读模板,通过它可以创建 Docker 容器。

例如某个镜像可能包含一个 Ubuntu 操作系统、一个 Apache HTTP Server 以及用户开发的 Web 应用。

镜像有多种生成方法:

  1. 可以从无到有开始创建镜像
  2. 也可以下载并使用别人创建好的现成的镜像
  3. 还可以在现有镜像上创建新的镜像

我们可以将镜像的内容和创建步骤描述在一个文本文件中,这个文件被称作 Dockerfile,通过执行 docker build <docker-file> 命令可以构建出 Docker 镜像,后面我们会讨论。

Docker容器

Docker 容器就是 Docker 镜像的运行实例。

用户可以通过 CLI(docker)或是 API 启动、停止、移动或删除容器。可以这么认为,对于应用软件,镜像是软件生命周期的构建和打包阶段,而容器则是启动和运行阶段。

Registry

Registry 是存放 Docker 镜像的仓库,Registry 分私有和公有两种。

Docker Hub(https://hub.docker.com/) 是默认的 Registry,由 Docker 公司维护,上面有数以万计的镜像,用户可以自由下载和使用。

出于对速度或安全的考虑,用户也可以创建自己的私有 Registry。后面我们会学习如何搭建私有 Registry

docker pull 命令可以从 Registry 下载镜像。

docker run 命令则是先下载镜像(如果本地没有),然后再启动容器。

Docker组件如何协作?

还记得我们运行的第一个容器吗?现在通过它来体会一下 Docker 各个组件是如何协作的。

容器启动过程如下:

  1. Docker 客户端执行 docker run 命令。
  2. Docker daemon 发现本地没有 httpd 镜像。
  3. daemon 从 Docker Hub 下载镜像。
  4. 下载完成,镜像 httpd 被保存到本地。
  5. Docker daemon 启动容器。

docker images 可以查看到 httpd 已经下载到本地。

docker ps 或者 docker container ls 显示容器正在运行。

小结

Docker 借鉴了集装箱的概念。标准集装箱将货物运往世界各地,Docker 将这个模型运用到自己的设计哲学中,唯一不同的是:集装箱运输货物,而 Docker 运输软件。

每个容器都有一个软件镜像,相当于集装箱中的货物。容器可以被创建、启动、关闭和销毁。和集装箱一样,Docker 在执行这些操作时,并不关心容器里到底装的什么,它不管里面是 Web Server,还是 Database。

用户不需要关心容器最终会在哪里运行,因为哪里都可以运行。

开发人员可以在笔记本上构建镜像并上传到 Registry,然后 QA 人员将镜像下载到物理或虚拟机做测试,最终容器会部署到生产环境。

使用 Docker 以及容器技术,我们可以快速构建一个应用服务器、一个消息中间件、一个数据库、一个持续集成环境。因为 Docker Hub 上有我们能想到的几乎所有的镜像。

 

不知大家是否意识到,潘多拉盒子已经被打开。容器不但降低了我们学习新技术的门槛,更提高了效率。

如果你是一个运维人员,想研究负载均衡软件 HAProxy,只需要执行docker run haproxy,无需繁琐的手工安装和配置既可以直接进入实战。

如果你是一个开放人员,想学习怎么用 django 开发 Python Web 应用,执行 docker run django,在容器里随便折腾吧,不用担心会搞乱 Host 的环境。

不夸张的说:容器大大提升了 IT 人员的幸福指数

 

三、docker安装

3.1 安装环境

3.1.1 docker版本及安装环境要求

根据官方对centos安装docker要求:需要64位(docker不支持32位)的Centos7

PS:如果要升级centos7内核的话可以用下面方法

#升级内核,可以看http://elrepo.org/tiki/tiki-index.php,如无特殊要求请不要升级

为了方便我用的是centos8 yum安装,内存为2.8G的VMware虚拟机,目前docker最新版本为docker-ce v19.03

3.1.2 安装前准备

我这里使用的是centos8安装docker,目前没有el8的安装rpm,但可以使用el7的,也是兼容的,在安装前还有一个很重要的配置

就是要修改内核参数,使它能支持转发功能,要不运行docker后,如果做端口映射会访问不到!

grep net.ipv4.ip_forward /etc/sysctl.conf
#设置转发为1
echo 'net.ipv4.ip_forward=1'>>/etc/sysctl.conf
#使用配置生效
sysctl -p
#查看是否生效
sysctl net.ipv4.ip_forward

ps:如果不生就重启网络,还是不行只能重启服务器( ˇˍˇ )

 

3.2 docker安装及测试

3.2.1 docker安装

按照目前docker官网安装要求,发现只有centos7的,不过测试也适合centos8

#卸载旧版本,如果存在的话

yum remove docker \
     docker-client \
     docker-client-latest \
     docker-common \
     docker-latest \
     docker-latest-logrotate \
     docker-logrotate \
     docker-engine

#官网的很慢,下面的都不要,要其它的

#####################官方配置 开始########################

yum install -y yum-utils device-mapper-persistent-data lvm2 fuse-overlayfs wget

yum-config-manager \

    --add-repo \

https://download.docker.com/linux/centos/docker-ce.repo

 

#指定containerd.io 版本

https://download.docker.com/linux/centos/7/x86_64/stable/Packages/\

containerd.io-1.2.13-3.2.el7.x86_64.rpm

yum install -y containerd.io-1.2.13-3.2.el7.x86_64.rpm

#也可以指定版本

#yum list docker-ce --showduplicates | sort -r

#yum install docker-ce-19.03.10 docker-ce-cli-19.03.10

#如果不指定就默认最新稳定版本

yum install -y docker-ce docker-ce-cli

#####################官方配置 结束########################

PS:其实现在docker官方已经有centos8版本,地址为:https://download.docker.com/linux/centos/8/x86_64/stable/Packages/,所以我直接使用官方centos8的

#因官方资源卡,所以我使用阿里云docker-ce镜像

#安装依赖
dnf install -y dnf-utils device-mapper-persistent-data lvm2 fuse-overlayfs wget
#添加yum源
yum-config-manager --add-repo \
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
#手工下载相关的包,如果直接yum安装还是会安装centos7的el7,需要修改一个yum源文件路径
wget https://mirrors.aliyun.com/docker-ce/linux/centos/8/x86_64/stable/Packages/\
containerd.io-1.3.7-3.1.el8.x86_64.rpm
wget https://mirrors.aliyun.com/docker-ce/linux/centos/8/x86_64/stable/Packages/containerd.io-1.3.7-3.1.el8.x86_64.rpm
wget https://mirrors.aliyun.com/docker-ce/linux/centos/8/x86_64/stable/Packages/docker-ce-19.03.13-3.el8.x86_64.rpm
wget https://mirrors.aliyun.com/docker-ce/linux/centos/8/x86_64/stable/Packages/docker-ce-cli-19.03.13-3.el8.x86_64.rpm

# 安装
yum install -y containerd.io-1.3.7-3.1.el8.x86_64.rpm \
docker-ce-19.03.13-3.el8.x86_64.rpm \
docker-ce-cli-19.03.13-3.el8.x86_64.rpm

 

 

#启动服务

systemctl start docker
#查看运行状态
systemctl status docker
#开机运行
systemctl enable docker

#查看相关信息

[root@vm82 ~]# docker version
Client: Docker Engine - Community
 Version:           19.03.13
 API version:       1.40
 Go version:        go1.13.15
 Git commit:        4484c46d9d
 Built:             Wed Sep 16 17:02:36 2020
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.13
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.13.15
  Git commit:       4484c46d9d
  Built:            Wed Sep 16 17:01:11 2020
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.3.7
  GitCommit:        8fba4e9a7d01810a393d5d25a3621dc101981175
 runc:
  Version:          1.0.0-rc10
  GitCommit:        dc9208a3303feef5b3839f4323d9beb36df0a9dd
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683

3.2.2 docker测试

验证docker,需要能上网,因为本地没有,会自动从Docker Hub下载hell-wold镜像

docker run hello-world

#发现报如下错误:

Unable to find image 'hello-world:latest' locally

docker: Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers).

See 'docker run --help'.

简单一句话就是国外这个链接不给连接呗,如果多试几次不行的话,可以尝试使用国内源

 

3.3 docker镜像加速器

国内访问 Docker Hub 有时会遇到困难,此时可以配置镜像加速器。国内很多云服务商都提供了加速器服务(常用加速器 可见 docker加速器教程),例如:

  1. DaoCloud 加速器
  2. 灵雀云加速器
  3. 华为云(需要登录)
  4. 阿里云docker镜像加速器(需要登录)

我这里使用免费的阿里云 ,点 阿里云docker加速器 会弹出窗口,使用阿里云账号登录即可,没有的话可以注册一个,会发现有镜像加速器的使用

 

 

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<- 'EOF'
{
    "registry-mirrors": ["https://xs363iyg.mirror.aliyuncs.com"]
}
EOF
#重导入配置
sudo systemctl daemon-reload
#重启docker
sudo systemctl restart docker

#备份
cp /etc/docker/daemon.json /etc/docker/daemon.json.orig

 

四、docker常用命令及操作

4.1 查找和获取镜像

4.1.1 docker镜像查询docker search

我们用vm安装centos操作系统一样,首先要搜索一下系统的版本。dokcer提供了一个官方专业放镜像的地方叫仓库,就是Docker Hub, Docker Hub(hub.docker.com/explore)上有大量的高质量的镜像可以用,找开此网址https://hub.docker.com/点“Explore”,能搜索到的仓库是免费的,打开docker官网hub

往下拉也有现成的镜像

上图中可以搜索镜像也可以直接点下面的镜像列表中的镜像,如我点第一个nginx

你点一下上面的Tags,这里就是为不同的镜像打标签的

系统架构一般是指CPU我这里使用的是intel的64,它使用的是amd64,所以只要找支持amd64的即可。

 

为什么要有标签,这里就用到镜像和仓库的关系了,如下:

镜像=<仓库>:[标签]

一个 Docker Registry 中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。上面的截图就是表示nginx两个镜像。

#查看帮助

[root@vm82 ~]# docker search --help

Usage:	docker search [OPTIONS] TERM

Search the Docker Hub for images

Options:
  -f, --filter filter   Filter output based on conditions provided
      --format string   Pretty-print search using a Go template
      --limit int       Max number of search results (default 25)
      --no-trunc        Don't truncate output

简单理解docker search,语法为:

docker search [选项] <镜像id/镜像名>[:版本]

注:

  1. 上面[]表示可选,<>表示必选,
  2. “镜像id”要到后面用dokcer pull命令下载下来,再用docker images才能看到

 

#我们还是拿搜索nginx例子,命令如下:

docker search nginx

镜像名字一般由“<用户名>/<docker>镜像名”,如果只有名字的则表示是官网镜像

#从上面截图我们看到,用命令是看不到镜像的标签名字的,所在我们要下载特定镜像还是得去

# https://hub.docker.com搜索再查看标签名

我们也可以指定版本,根据上面我们用web登陆看查看“Repo info”知道nginx默认为1.19,

如果我想要搜索1.18版本呢,那我就就要用web看一下nginx的“tags”中有没有1.18版本了,

随便找下都发现有好几个,如图:

也可以用命令搜索尝试一下

docker search nginx:1.18

从上图中没有列出nginx官方镜像,只能搜索包含nginx和1.18的一个镜像而已。

 

4.1.2 下载镜像docker pull

上面讲了如何搜索镜像,现在讲如果下载镜像,可以用“docker pull”命令命令格式为:

docker pull [选项] [Docker Registry地址]<仓库名>:<标签>

具体的选项可以通过 docker pull --help 命令看到,这里我们说一下镜像名称的格式。

  • 1.Docker Registry地址:地址的格式一般是 <域名/IP>[:端口号] 。默认地址是Docker Hub。
  • 2.仓库名:如之前所说,这里的仓库名是两段式名称,既 <用户名>/<软件名> 。对于 Docker Hub,如果不给出用户名,则默认为 library ,也就是官方镜像。

还是以nginx为例子我把上面的nginx下载下来

#如果不加标签默认就是latest
docker pull nginx

#如果下下载上面的nginx 1.18版本怎办,上面有1.17-perl和1.18这里下载1.18

[root@vm82 ~]# docker pull nginx:1.18
1.18: Pulling from library/nginx
8559a31e96f4: Pull complete 
9a38be3aab21: Pull complete 
522e5edd83fa: Pull complete 
2ccf5a90baa6: Pull complete 
Digest: sha256:159aedcc6acb8147c524ec2d11f02112bc21f9e8eb33e328fb7c04b05fc44e1c
Status: Downloaded newer image for nginx:1.18
docker.io/library/nginx:1.18

4.1.3 查看本地镜像

#帮助

docker images --help

#查看全部镜像

docker images

#查看指定镜像

#查看本地名字为nginx标签为任意名的镜像

docker images nginx

docker images nginx:latest

docker images nginx:1.18

 

4.2 容器相关操作

4.2.1 运行容器

镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的 类 和 实例 一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。

         容器安装用docker run命令执行,也可以简单理解为用“docker run”命令来运行镜像得到的东西叫“容器”。

#帮助命令

docker run --help

语法:

docker run [选项] <镜像> [命令] [参数...]

#换成另一个形式就是

docker run [选项] <镜像id> [命令] [参数...]

docker run [选项] <仓库>[:标签] [命令] [参数...]

#注:没写标签默认就是latest

#常用的参数如下:

-d:表示以“守护模式”执行,日志不会出现在输出终端上。
--name:给容器起一个名字,以后可以用这个名字去操作容易
-i:表示以“交互模式”运行容器,-i 则让容器的标准输入保持打开
--rm:表示停止退出容器时自动移除容器,这样就不用先docker stop再docker rm
-t:表示容器启动后会进入其命令行,-t 选项让Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上
-v:表示需要将本地哪个目录挂载到容器中,格式:-v <宿主机目录>:<容器目录>,-v 标记来创建一个数据卷并挂载到容器里。在一次 run 中多次使用可以挂载多个数据卷。
-p:表示宿主机与容器的端口映射,[ip:]<宿主端口>:[ip:]<docker端口>,如果不写IP地址表示宿主所有可用接口相当于0.0.0.0,做了映射之后就可以通过外网访问docker相关端口了
-p:参数可以用多个,表示映射多个端口
-P: Docker 会随机映射一个 49000~49900 的端口到内部容器开放的网络端口。
# 不一定要使用“镜像 ID”,也可以使用“仓库名:标签名”

-v是最常用的的参数,为什么呢?

运行docker镜像变成容器之后,一般尽量不要让容器有改动,这样就和镜像一致,这样的好处有:

  1. 方便迁移,因为我没有改过,所以万一那台服务器挂了下载一个镜像再运行马上又可以了。
  2. 如果过多的更新,重要的还要做备份,产生额外的IO,还有容器要是坏了怎搞?用镜像起一个也不能一样?!最坏的情况万一那个容器被误删了怎搞?!

一般经常性变化的不太建议用容器如数据库,本身产生的IO,内存,CPU比较容易造成容器退出!

如果有些东西需要改变呢,那就放在宿主主机目录中用-v做映射这样方便很多。

比如做nginx配置,自己做一个镜像把网站代码和nginx配置放进去,而网站文件就用-v映射到docker中,这样不就怕docker坏掉,大不了我再用那个镜像再起一个容器。

什么时候才用到docker run -it呢

当Dockerfile看默认命令是CMD ["/bin/bash"],关于Dockerfile是CMD命令后面会讲到,这类一般为操作系统比较多,就要用-it参数,要不一下就运行完,容器就退出了。

不能用下面命令运行系统如centos

#下面运行命令是一执行容器就马上结束了
docker run --name centos -d centos:7
#正确的命令
docker run --name centos -it -d centos:7 /bin/bash

4.2.2 例1 运行nginx容器

我在这里直接运行nginx latest,所以后面不用加标签

在运行之前首先看一下docker的专属性网络docker0有没有起来,如果没起来的话就表示内核 net.ipv4.ip_forward=1 没有配置,这样会导致做了端口映射之后也访问不了docker容器

[root@vm82 ~]# ip addr|grep -A 5 docker0
4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:77:e9:7e:43 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:77ff:fee9:7e43/64 scope link 
       valid_lft forever preferred_lft forever

运行一个docker nginx

[root@vm82 ~]# docker run --name nginx -p 81:80 -d nginx
63e01ec33b72c006f7597463302bb4406432ed254fbce256a0d31b1f98b64507
[root@vm82 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
63e01ec33b72        nginx               "/docker-entrypoint.…"   12 seconds ago      Up 7 seconds        0.0.0.0:81->80/tcp   nginx
[root@vm82 ~]# netstat -anltp|grep 81
tcp6       0      0 :::81                   :::*                    LISTEN      26471/docker-proxy  

#用浏览器测试一下我的IP地址为192.168.3.82所以输入http://192.168.3.82:81

#如果上面的例子想本地主机端口是随机的可以把小写的-p改为大写的-P

#停止原来的nginx,为了不和上面的nginx容器名称冲突我改为了t1,

#加多了--rm,表示容器停止就删除

[root@vm82 ~]# docker stop nginx
nginx
[root@vm82 ~]# docker run --rm --name t1 -P -d nginx
418f9caf3067546bf4e838f0f34180de6e61de1fd917c780d24cb6ebeb4e3889
[root@vm82 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                   NAMES
418f9caf3067        nginx               "/docker-entrypoint.…"   10 seconds ago      Up 5 seconds        0.0.0.0:32768->80/tcp   t1

从上面知道是把本机的一个随机端口32768映射为docker的80端口,打开浏览器访问试下:http://192.168.3.82:32768/

 

4.2.3 启动/停止/删除容器

#start 启动容器
docker start <容器ID>|<容器名>
#stop 停止正在运行的容器
docker stop <容器ID>|<容器名>
#restart 重启容器
docker restart <容器ID>|<容器名>
#rm 删除容器
docker rm <容器ID>|<容器名>

例子,停止并删除上面的t1,重新启动nginx容器

[root@vm82 ~]# docker stop t1
t1
[root@vm82 ~]# docker rm t1
Error: No such container: t1   #因为我在docker运行的时间加了--rm,即docker停止就删除
[root@vm82 ~]# docker ps -a  #连不运行的容器也列出来
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                         PORTS               NAMES
63e01ec33b72        nginx               "/docker-entrypoint.…"   21 minutes ago      Exited (0) 14 minutes ago                          nginx
186a65262e50        hello-world         "/hello"                 About an hour ago   Exited (0) About an hour ago                       bold_hodgkin
[root@vm82 ~]# docker start nginx
nginx
[root@vm82 ~]# docker ps   #只查看在运行的容器
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
63e01ec33b72        nginx               "/docker-entrypoint.…"   23 minutes ago      Up 2 minutes        0.0.0.0:81->80/tcp   nginx

4.2.4 查看容器状态

#列出当前所有正在运行的容器
docker ps
#列出所有的容器
docker ps -a
#列出最近一次启动的容器
docker ps -l

4.2.5 登陆容器docker exec

我们知道容器也是有自己的操作系统,如果我们想登陆进去看一下,那怎办?

首先保持容器在运行,然后执行docker exec,语法为:

docker exec [选项] <容器> <命令> [参数...]

一般情况当使用-it /bin/bash时就会登陆容器,如登陆上面的nginx命令为

[root@vm82 ~]# docker exec  -it  nginx /bin/bash
#容器界面
root@63e01ec33b72:/# pwd
/
#容器所使用的操作系统
root@63e01ec33b72:/# cat /etc/issue       
Debian GNU/Linux 10 \n \l
#退出容器
root@63e01ec33b72:/# exit
exit
#宿主界面
[root@vm82 ~]# 

4.3 其它命令

# 在ubuntu中安装docker
$ sudo apt-get install docker.io

# 查看docker的版本信息
$ docker version

# 查看安装docker的信息
$ docker info

# 查看本机Docker中存在哪些镜像
$ docker images

# 检索image
$ docker search ubuntu:14.04

# 在docker中获取ubuntu镜像
$ docker pull ubuntu:14.04

# 显示一个镜像的历史
$ docker history birdben/ubuntu:v1

# 列出一个容器里面被改变的文件或者目
$ docker diff birdben/ubuntu:v1

# 从一个容器中取日志
$ docker logs birdben/ubuntu:v1

# 显示一个运行的容器里面的进程信息
$ docker top birdben/ubuntu:v1

# 从容器里面拷贝文件/目录到本地一个路径
$ docker cp ID:/container_path to_path

# 查看容器的相关信息
$ docker inspect $CONTAINER_ID

# 显示容器IP地址和端口号,如果输出是空的说明没有配置IP地址(不同的Docker容器可以通过此IP地址互相访问)
$ docker inspect --format='{{.NetworkSettings.IPAddress}}' $CONTAINER_ID

# 保存对容器的修改 
$ docker commit -m "Added ssh from ubuntu14.04" -a "birdben" 6s56d43f627f3 birdben/ubuntu:v1

# 参数:
# -m参数用来来指定提交的说明信息;
# -a可以指定用户信息的;
# 6s56d43f627f3代表的时容器的id;
# birdben/ubuntu:v1指定目标镜像的用户名、仓库名和 tag 信息。

# 构建一个容器 
$ docker build -t="birdben/ubuntu:v1" .

# 参数:
# -t为构建的镜像制定一个标签,便于记忆/索引等
# . 指定Dockerfile文件在当前目录下,也可以替换为一个具体的 Dockerfile 的路径。

# 在docker中运行ubuntu镜像
$ docker run <相关参数> <镜像 ID> <初始命令>

# 守护模式启动
$ docker run -it ubuntu:14.04

# 交互模式启动
$ docker run -it ubuntu:14.04 /bin/bash

# 指定端口号启动
$ docker run -p 80:80 birdben/ubuntu:v1

# rmi 删除镜像
$ docker rmi ed9c93747fe1Deleted

# 登录Docker Hub中心
$ docker login

# 发布上传image(push)
$ docker push birdben/ubuntu:v1

#查看docker状态
docker stats

#清理所有处于终止状态的容器
#用 docker ps -a 命令可以查看所有已经创建的包括终止状态的容器,如果数量太多要一个个删除
#可能会很麻烦,可以用下面的命令全部清理掉。
docker rm $(docker ps -a -q)
#注:这个命令其实会试图删除所有的包括还在运行中的容器,
#不过就像上面提过的 docker rm 默认并不会删除运行中的容器。

当利用 docker run 来创建容器时,Docker 在后台运行的标准操作包括:

  1. 检查本地是否存在指定的镜像,不存在就从公有仓库下载
  2. 利用镜像创建并启动一个容器
  3. 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
  4. 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
  5. 从地址池配置一个 ip 地址给容器
  6. 执行用户指定的应用程序
  7. 执行完毕后容器被终止

、docker其它

5.1 docker注意事项

5.1.1 windows上可以运行linux docker吗

不能,因为:

rootfs只包含系统目录结构,还是精简化的,不包括内核,需要和宿主共享内核

5.1.2 docker时间问题

docker上修改了时间,宿主机子上的时间也将会被修改。因为Linux Namespace隔离不彻底导致的。

5.2 多个容器间如何互通

有时间我们应用需要几个docker,怎能互通,解决方法:

1.使用容器编排工具,推荐k8s你

2. 简单的可以使用--Link

比如我一个nginx+php-fpm互相通讯,需要2个docker,可以这样操作

docker run -p 80:80 --name nginx \
-v /disk1/www/hualinux.com:/disk1/www/hualinux.com \
-v /disk1/logs/nginx:/disk1/logs/nginx:rw \
-v /disk1/dockerconf/nginx12/nginx/conf.d:/etc/nginx/conf.d \
--link php -d nginx
docker ps

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值