docker简介及基本命令

版权声明:转载请著明出处 https://blog.csdn.net/weixin_40543283/article/details/88622252

一、docker

以下内容来自百度百科

1.简介

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。

一个完整的Docker有以下几个部分组成:

  • dockerClient客户端

  • Docker Daemon守护进程

  • Docker Image镜像

  • DockerContainer容器

2.起源

Docker 是 PaaS提供商 dotCloud 开源的一个基于 LXC 的高级容器引擎,源代码托管在 Github 上, 基于go语言并遵从Apache2.0协议开源。

 docker设想是交付运行环境如同海运,OS如同一个货轮,每一个在OS基础上的软件都如同一个集装箱,用户可以通过标准化手段自由组装运行环境,同时 集装箱的内容可以由用户自定义,也可以由专业人员制造。这样,交付一个软件,就是一系列标准化组件的集合的交付,如同乐高积木,用户只需要选择合适的积木 组合,并且在最顶端署上自己的名字(最后一个标准化组件是用户的app)。这也就是基于docker的PaaS产品的原型。

3.架构

Docker采用 C/S架构 Docker daemon 作为服务端接受来自客户的请求,并处理这些请求(创建、运行、分发容器)。 客户端和服务端既可以运行在一个机器上,也可通过 socket 或者RESTful API 来进行通信。

Docker daemon 一般在宿主主机后台运行,等待接收来自客户端的消息。 Docker 客户端则为用户提供一系列可执行命令,用户用这些命令实现跟 Docker daemon 交互。

4.局限

  • Docker是基于Linux 64bit的,无法在32bit的linux/Windows/unix环境下使用
  • LXC是基于cgroup等linux kernel功能的,因此container的guest系统只能是linux base的
  • 隔离性相比KVM之类的虚拟化方案还是有些欠缺,所有container公用一部分的运行库
  • 网络管理相对简单,主要是基于namespace隔离
  • cgroup的cpu和cpuset提供的cpu功能相比KVM的等虚拟化方案相比难以度量(所以dotcloud主要是按内存收费)
  • Docker对disk的管理比较有限
  • container随着用户进程的停止而销毁,container中的log等用户数据不便收集

5.原理

Docker核心解决的问题是利用LXC来实现类似VM的功能,从而利用更加节省的硬件资源提供给用户更多的计算资源。同VM的方式不同, LXC其并不是一套硬件虚拟化方法 - 无法归属到全虚拟化、部分虚拟化和半虚拟化中的任意一个,而是一个操作系统级虚拟化方法, 理解起来可能并不像VM那样直观。所以我们从虚拟化到docker要解决的问题出发,看看他是怎么满足用户虚拟化需求的。

用户需要考虑虚拟化方法,尤其是硬件虚拟化方法,需要借助其解决的主要是以下4个问题:

  • 隔离性 - 每个用户实例之间相互隔离, 互不影响。 硬件虚拟化方法给出的方法是VM, LXC给出的方法是container,更细一点是kernel namespace

  • 可配额/可度量 - 每个用户实例可以按需提供其计算资源,所使用的资源可以被计量。硬件虚拟化方法因为虚拟了CPU, memory可以方便实现, LXC则主要是利用cgroups来控制资源

  • 移动性 - 用户的实例可以很方便地复制、移动和重建。硬件虚拟化方法提供snapshot和image来实现,docker(主要)利用AUFS实现

  • 安 全性 - 这个话题比较大,这里强调是host主机的角度尽量保护container。硬件虚拟化的方法因为虚拟化的水平比较高,用户进程都是在KVM等虚拟机容器 中翻译运行的, 然而对于LXC, 用户的进程是lxc-start进程的子进程, 只是在Kernel的namespace中隔离的, 因此需要一些kernel的patch来保证用户的运行环境不会受到来自host主机的恶意入侵, dotcloud(主要是)利用kernel grsec patch解决的.

6.Linux Namespace

LXC所实现的隔离性主要是来自kernel的namespace, 其中pid, net, ipc, mnt, uts 等namespace将container的进程, 网络, 消息, 文件系统和hostname 隔离开。

pid namespace

之前提到用户的进程是lxc-start进程的子进程, 不同用户的进程就是通过pidnamespace隔离开的,且不同 namespace 中可以有相同PID。具有以下特征:

  1. 每个namespace中的pid是有自己的pid=1的进程(类似/sbin/init进程)

  2. 每个namespace中的进程只能影响自己的同一个namespace或子namespace中的进程

  3. 因为/proc包含正在运行的进程,因此在container中的pseudo-filesystem的/proc目录只能看到自己namespace中的进程

  4. 因为namespace允许嵌套,父namespace可以影响子namespace的进程,所以子namespace的进程可以在父namespace中看到,但是具有不同的pid

正是因为以上的特征,所有的LXC进程在docker中的父进程为docker进程,每个lxc进程具有不同的namespace。同时由于允许嵌套,因此可以很方便的实现 LXC in LXC

net namespace

有了 pid namespace, 每个namespace中的pid能够相互隔离,但是网络端口还是共享host的端口。网络隔离是通过netnamespace实现的,

每个net namespace有独立的 network devices, IP addresses, IP routing tables, /proc/net 目录。这样每个container的网络就能隔离开来。

LXC在此基础上有5种网络类型,docker默认采用veth的方式将container中的虚拟网卡同host上的一个docker bridge连接在一起。

ipc namespace

container中进程交互还是采用linux常见的进程间交互方法 (interprocess communication - IPC), 包括常见的信号量、消息队列和共享内存。然而同VM不同,container 的进程间交互实际上还是host上具有相同pid namespace中的进程间交互,因此需要在IPC资源申请时加入namespace信息 - 每个IPC资源有一个唯一的 32bit ID。

mnt namespace

类似chroot,将一个进程放到一个特定的目录执行。mnt namespace允许不同namespace的进程看到的文件结构不同,这样每个 namespace 中的进程所看到的文件目录就被隔离开了。同chroot不同,每个namespace中的container在/proc/mounts的信息只包含所在 namespace的mount point。

uts namespace

UTS(“UNIX Time-sharing System”) namespace允许每个container拥有独立的hostname和domain name,
  使其在网络上可以被视作一个独立的节点而非Host上的一个进程。

user namespace

每个container可以有不同的 user 和 group id, 也就是说可以以container内部的用户在container内部执行程序而非Host上的用户。

有了以上6种namespace从进程、网络、IPC、文件系统、UTS和用户角度的隔离,一个container就可以对外展现出一个独立计算机的能力,并且不同container从OS层面实现了隔离。

7.Control Groups

cgroups 实现了对资源的配额和度量。 cgroups 的使用非常简单,提供类似文件的接口,在 /cgroup目录下新建一个文件夹即可新建一个group,在此文件夹中新建task文件,并将pid写入该文件,即可实现对该进程的资源控制。具体的 资源配置选项可以在该文件夹中新建子 subsystem ,{子系统前缀}.{资源项} 是典型的配置方法,

如memory.usage_in_bytes 就定义了该group 在subsystem memory中的一个内存限制选项。

另外,cgroups中的 subsystem可以随意组合,一个subsystem可以在不同的group中,也可以一个group包含多个subsystem - 也就是说一个 subsystem。

关于术语定义

A *cgroup* associates a set of tasks with a set of parameters for one
  or more subsystems.
  A *subsystem* is a module that makes use of the task grouping
  facilities provided by cgroups to treat groups of tasks in
  particular ways. A subsystem is typically a "resource controller" that
  schedules a resource or applies per-cgroup limits, but it may be
  anything that wants to act on a group of processes, e.g. a
  virtualization subsystem.

我们主要关心cgroups可以限制哪些资源,即有哪些subsystem是我们关心。

cpu : 在cgroup中,并不能像硬件虚拟化方案一样能够定义CPU能力,但是能够定义CPU轮转的优先级,因此具有较高CPU优先级的进程会更可能得到CPU运算。
  通过将参数写入cpu.shares,即可定义改cgroup的CPU优先级 - 这里是一个相对权重,而非绝对值。当然在cpu这个subsystem中还有其他可配置项,手册中有详细说明。

cpusets : cpusets 定义了有几个CPU可以被这个group使用,或者哪几个CPU可以供这个group使用。在某些场景下,单CPU绑定可以防止多核间缓存切换,从而提高效率

memory : 内存相关的限制

blkio : block IO相关的统计和限制,byte/operation统计和限制(IOPS等),读写速度限制等,但是这里主要统计的都是同步IO

net_clscpuacct , devices , freezer 等其他可管理项。

二、docker的使用

环境:

docker1:rhel7.0

软件:docker ==> 点击下载  提取码: swwp

docker镜像:tar镜像 ==> 点击下载  提取码: h49n

1.安装docker

[root@docker1 ~]# cd docker/
[root@docker1 docker]# ls
container-selinux-2.21-1.el7.noarch.rpm
docker-ce-18.06.1.ce-3.el7.x86_64.rpm
libsemanage-2.5-8.el7.x86_64.rpm
libsemanage-python-2.5-8.el7.x86_64.rpm
pigz-2.3.4-1.el7.x86_64.rpm
policycoreutils-2.5-17.1.el7.x86_64.rpm
policycoreutils-python-2.5-17.1.el7.x86_64.rpm
[root@docker1 docker]# yum install * -y
[root@docker1 docker]# systemctl start docker        ##开启docker
[root@docker1 docker]# docker version                ##查看docker版本

2.尝试加载一个dokcer镜像

[root@docker1 images]# docker load -i game2048.tar                        ##导入镜像
011b303988d2: Loading layer   5.05MB/5.05MB
36e9226e74f8: Loading layer  51.46MB/51.46MB
192e9fad2abc: Loading layer  3.584kB/3.584kB
6d7504772167: Loading layer  4.608kB/4.608kB
88fca8ae768a: Loading layer  629.8kB/629.8kB
Loaded image: game2048:latest
[root@docker1 images]# docker run -d --name game -p 8080:80 game2048     ##将2048映射到8080端口
84c385fdc463edf76bded96e54a83dd8e58e55ecc1f1f08398b8b6a749c8fcd3    

在浏览器查看

3.docker基本指令

1.镜像指令

[root@docker1 ~]# docker ps -a                     ##查看所有的容器
[root@docker1 ~]# docker ps                        ##查看所有的正在运行的容器
[root@docker1 ~]# docker images                    ##查看已经导入的镜像
[root@nelws docker]# docker pull nginx             ##从公有库下载nginx
[root@nelws docker]# docker run -d --name game -p 8080:80 game2048      ##运行指定的镜像    
  -d  后台运行   
  -p 8800:80 是指定对外暴露的端口  容器内部用80 对应外部的8800  代理一样
  --name指定容器的名字  最后的nginx 代码要运行的镜像名字  有tag的加上tag 如 game2048:xxx  默认为latest
然后访问宿主主机地址+8800端口
[root@docker1 ~]# docker run -it --name vm1 ubuntu
    -i:交互
    -t:终端
[root@docker1 images]# docker run -it --name  vm1 nginx bash    ##加一个bash可以调出shell
[root@docker1 images]# docker container exec -it vm1 bash       ##后台开启时调动shell的方法
[root@docker1 ~]# docker export vm1 > vm1.tar       ##导出镜像
[root@docker1 ~]# docker import vm1.tar image       ##导入镜像

2.容器操作指令

[root@docker1 images]# docker start nginx                ##开启nginx容器
[root@docker1 images]# docker restart nginx              ##重启nginx容器
[root@docker1 images]# docker stop nginx                 ##停止nginx容器
[root@docker1 images]# docker rm nginx                   ##删除nginx容器
[root@docker1 images]# docker prune                      ##删除不用的docker
[root@docker1 images]# docker rmi nginx                  ##删除nginx镜像
[root@docker1 images]# docker kill vm1                   ##强制干掉容器
[root@docker1 images]# docker attach vm1                 ##连接容器,需要先开启容器
[root@docker1 images]# docker logs vm1                   ##查看容器指令输出 -f 参数可以实时查看
[root@docker1 images]# docker inspect vm1                ##查看容器详情
[root@docker1 images]# docker stats vm1                  ##查看容器资源使用率
[root@docker1 images]# docker diff vm1                   ##查看容器修改
[root@docker1 images]# docker pause/unpause vm1          ##暂停恢复容器
[root@docker1 images]# docker rm -f `docker ps -aq`      ##删除所有的容器

3.替换为国内的docker仓库,具体方法:

[root@docker1 docker]# cat >/etc/docker/daemon.json << EOF
> {
> "registry-mirrors": ["https://registry.docker-cn.com"]
> }
> EOF
[root@docker1 docker]# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://registry.docker-cn.com"]
}

 然后重启docker服务即可使用国内库

更多指令可以docker --help查看

猜你喜欢

转载自blog.csdn.net/weixin_40543283/article/details/88622252