Docker学习笔记

前言

本文是在学习Docker路上的踩坑记录…

正文

Docker概述

Docker是基于Go语言实现的开源容器项目,诞生于2013年初,基于 Linux 内核的 cgroup,namespace,以及AUFS 类的 Union FS等技术,对进程进行封装隔离,属于 操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。

Docker 在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极大的简化了容器的创建和维护。使得 Docker 技术比虚拟机技术更为轻便、快捷。

下面的图片比较了 Docker 和传统虚拟化方式的不同之处:

V3q0ns.png

V3LFgg.png

传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便;

Docker镜像

在 Docker 的术语里,一个只读层被称为镜像,一个镜像是永久不会变的。由于 Docker 使用一个统一文件系统,Docker 进程认为整个文件系统是以读写方式挂载的。 但是所有的变更都发生在顶层的可写层,而下层的原始的只读镜像文件并未变化。由于镜像不 可写,所以镜像是无状态的。

Docker容器

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

容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间。因此容器可以拥有自己的 root 文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样(类似沙盒)。这种特性使得容器封装的应用比直接在宿主运行更加安全。

Docker仓库

镜像构建完成后,可以很容易的在当前宿主机上运行,但是,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry 就是这样的服务。

一个 Docker Registry 中可以包含多个 仓库Repository);每个仓库可以包含多个 标签Tag);每个标签对应一个镜像。

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

Docker hub

目前 Docker 官方维护了一个公共仓库 Docker Hub,其中已经包括了数量超过 15,000 的镜像。大部分需求都可以通过在 Docker Hub 中直接下载镜像来实现。

Docker安装

声明

环境:CentOS7 Minimal

参考:官方手册

由于 Docker 的局限性,Docker 只能运行在64位的系统中,所以只能在CentOS6.5及以上的系统才可以安装,需要内核版本是 2.6.32-431 或者更高版本 ;

本地安装Docker

1.Docker 软件包已经包含在默认的 CentOS-Extras 软件源里,安装命令如下:

1
$ sudo yum -y install docker

2.安装完成以后可以查看下载的Docker版本

1
$ docker -v

3.安装完成以后启动Docker

1
$ sudo service docker start

4.如果希望 Docker 默认开机启动,如下操作:

1
$ sudo chkconfig docker on

使用镜像加速器

没有镜像和容器的Docker是没有灵魂的,所以我们要去拉取镜像来创建容器,但是经过之前的踩坑,发现拉取Docker的官方镜像实在是太慢了,所以在拉取镜像之前可以使用阿里云的镜像加速器来解决拉取镜像速度太慢的问题,每个人的阿里云账号的容器镜像服务里应该都有一个镜像加速器地址;

V3BPLn.png

vim修改/etc/docker/daemon.json的地址如下:

1
2
3
{
"registry-mirrors": ["https://xxxxxxx.mirror.aliyuncs.com"]
}

然后使配置生效:

1
$ sudo systemctl daemon-reload

重启Docker

1
$ sudo service docker restart

使用docker用户组

一遍一遍地sudo都快烦死我了…为什么每次都需要sudo???

docker 进程通过监听一个 Unix Socket 来替代 TCP 端口。在默认情况下,docker 的 Unix Socket属于root用户,当然其他用户可以使用sudo方式来访问。因为这个原因, docker 进程就一直是root用户运行的。为了在使用 docker 命令的时候前边不再加sudo,我们需要创建一个叫 docker 的用户组,并且为用户组添加用户。然后在 docker 进程启动的时候,我们的 docker 群组有了 Unix Socket 的所有权,可以对 Socket 文件进行读写。

创建docker用户组

1
$ sudo groupadd docker

将用户添加到docker用户组

1
$ sudo gpasswd -a gard3nia docker

重启系统登录即可

1
$ reboot

Docker使用

镜像操作

1.搜索镜像

1
docker search imagename

2.拉取镜像

1
docker pull imagename

3.列出本地镜像

1
docker images

4.删除镜像

1
docker rmi imagename

容器操作

1.新建容器

1
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

经常会用到的参数

  • -it: 其中,-t 选项让Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上, -i 则让容器的标准输入保持打开;
  • –name: 为容器指定一个名称;
  • -p: 指定端口映射,格式为:主机(宿主)端口:容器端口
  • -P: 随机端口映射,容器内部端口随机映射到主机的高端口;
  • -v:指定文件夹映射,格式为:主机(宿主)文件夹:容器文件夹
  • -d: 后台运行容器,并返回容器ID;

用拉取的centos镜像新建容器并进入bash终端:

1
$ docker run --name centos1 -it centos /bin/bash

退出交互式终端:

1
$ exit

2.查看容器

1
docker ps [-a] [-l]
  • -a :显示所有的容器,包括未运行的。
  • -l :显示最近创建的容器。
  • 没有参数默认查看运行容器的进程

3.停止容器

1
2
docker stop 容器name
docker kill 容器name

第一种是等待容器内进程结束再关闭,另外一种是直接强制结束容器

4.开启容器

1
docker start 容器name

5.重启容器

1
docker restart 容器name

6.后台运行

一般的话我们在运行一个交互式的bash的时候,用的是 ctrl+Pctrl+Q键去退出这样就会在后台一直运行

7.重新进入后台运行的容器

1.docker attach

1
docker attach [OPTIONS] CONTAINER

2.docker exec

1
docker exec [-d] [-i] [-t] CONTAINER [command]

8.删除容器

1
docker rm [OPTIONS] CONTAINER
  • -f :通过SIGKILL信号强制删除一个运行中的容器
  • -l :移除容器间的网络连接,而非容器本身
  • -v :-v 删除与容器关联的卷

Docker的强大还需更多学习,本文会做到动态更新!

Author: Gard3nia
Link: https://gardenia30.top/2019/06/02/Docker学习笔记/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.