Docker容器技术基础

文章目录

  • Docker概述
    • 容器
    • 传统虚拟化与容器的区别
    • Namespaces
    • CGroups
    • LXC
    • Docker基本概念
    • Docker工作方式
    • Docker容器编排
    • 什么是Docker
    • OCI与OCF
      • OCI
      • OCF
    • Docker架构
    • Docker镜像与镜像仓库
    • Docker对象
  • 安装及使用Docker
    • Docker常用操作


Docker概述

容器

容器是一种基础工具;泛指任何可以用于容纳其他物品的工具,可以部分或完全封闭,被用于容纳、储存、运输物品;物体可以被放置在容器中,而容器则可以保护内容物;
而Linux 的容器是指一个在单一Linux主机上提供多个隔离的Linux环境的操作系统级虚拟技术。


传统虚拟化与容器的区别

Docker容器技术基础_第1张图片
Docker容器技术基础_第2张图片

传统虚拟化的创建速度很慢,而容器虚拟化创建速度很快。而且传统虚拟化非常占用资源,而容器占用的资源很少。传统虚拟化支持多种操作系统,而容器虚拟化仅支持内核所支持的操作系统。

虚拟化分为以下两类:

  • 主机级虚拟化
    • 全虚拟化
    • 半虚拟化
  • 容器级虚拟化

容器分离开的资源:

  • UTS(主机名与域名)
  • Mount(文件系统挂载树)
  • IPC
  • PID进程树
  • User
  • Network(tcp/ip协议栈)

Namespaces

命名空间(Namespaces)是Linux内核针对实现容器虚拟化而引入的一个强大特性。

每个容器都可以拥有自己独立的命名空间,运行其中的应用都像是在独立的操作系统中运行一样。命名空间保证了容器间彼此互不影响。

namespaces 系统调用参数 隔离内容 内核版本
UTS CLONE_NEWUTS 主机名和域名 2.6.19
IPC CLONE_NEWIPC 信号量、消息队列和共享内存 2.6.19
PID CLONE_NEWPID 进程编号 2.6.24
Network CLONE_NEWNET 网络设备、网络栈、端口等 2.6.29
Mount CLONE_NEWNS 挂载点(文件系统) 2.4.19
User CLONE_NEWUSER 用户和用户组 3.8

CGroups

控制组(CGroups)是Linux内核的一个特性,用来对共享资源进行隔离、限制、审计等。只有能控制分配到容器的资源,Docker才能避免多个容器同时运行时的系统资源竞争。

控制组可以提供对容器的内存、CPU、磁盘IO等资源进行限制。

CGroups能够限制的资源有:

  • blkio:块设备IO
  • cpu:CPU
  • cpuacct:CPU资源使用报告
  • cpuset:多处理器平台上的CPU集合
  • devices:设备访问
  • freezer:挂起或恢复任务
  • memory:内存用量及报告
  • perf_event:对cgroup中的任务进行统一性能测试
  • net_cls:cgroup中的任务创建的数据报文的类别标识符

控制组提供如下功能:

  • 资源限制(Resource Limitting)组可以设置为不超过设定的内存限制。比如:内存子系统可以为进行组设定一个内存使用上限,一旦进程组使用的内存达到限额再申请内存,就会发出Out of Memory警告
  • 优先级(Prioritization)通过优先级让一些组优先得到更多的CPU等资源
  • 资源审计(Accounting)用来统计系统实际上把多少资源用到合适的目的上,可以使用cpuacct子系统记录某个进程组使用的CPU时间
  • 隔离(Isolation)为组隔离命名空间,这样一个组不会看到另一个组的进程、网络连接和文件系统
  • 控制(Control)挂起、恢复和重启等操作

LXC

通过传统方式使用容器功能的话需要我们自己写代码去进行系统调用来实现创建内核,实际上拥有此能力的人廖廖无几。而LXC(LinuX Container)把容器技术做得更加易用,把需要用到的容器功能做成一组工具,从而极大的简化用户使用容器技术的麻烦程度。

LXC虽然极大的简化了容器技术的使用,但比起直接通过内核调用来使用容器技术,其复杂程度其实并没有多大降低,因为我们必须要学会LXC的一组命令工具,且由于内核的创建都是通过命令来实现的,通过批量命令实现数据迁移并不容易。其隔离性也没有虚拟机那么强大。

后来就出现了docker,所以从一定程度上来说,docker就是LXC的增强版。

Docker基本概念

docker是容器技术的一个前端工具,容器是内核的一项技术,docker只是把这一项技术的使用得以简化,使之普及而已。

我们可以尝试着把一个操作系统用户空间需要用到的所有组件,事先准备、编排好,编排好以后整体打包成一个文件,这个文件我们称其为镜像文件(image)。

docker的镜像文件是放在一个集中统一的互联网仓库中的,把一些人们常用的镜像文件放在互联网仓库中,比如最小化的centos系统,有时我们需要在操作系统上安装一些应用,比如nginx,我们就可以在一个最小化的centos系统中安装一个nginx,然后将其打包成镜像,将其放在互联网仓库中,当人们想启动一个容器的时候,docker会到这个互联网仓库中去下载我们需要的镜像到本地,并基于镜像来启动容器。

Docker工作方式

为了使容器的使用更加易于管理,docker采取一个用户空间只跑一个业务进程的方式,在一个容器内只运行一个进程,比如我们要在一台主机上安装一个nginx和一个tomcat,那么nginx就运行在nginx的容器中,tomcat运行在tomcat的容器中,二者用容器间的通信逻辑来进行通信。
Docker容器技术基础_第3张图片

使用docker的优劣:

  • 删除一个容器不会影响其他容器
  • 调试不便,占空间(每个容器中都必须自带调试工具,比如ps命令)
  • 分发容易,真正意义上一次编写到处运行,比java的跨平台更彻底
  • 部署容易,无论底层系统是什么,只要有docker,直接run就可以了
  • 分层构建,联合挂载

Docker容器技术基础_第4张图片

在容器中有数据称作有状态,没有数据称作无状态。在容器的使用中,我们应以有状态为耻,以无状态为荣。数据不应该放在容器中,而应放置于外部存储中,通过挂载到容器中从而进行数据的存储。

Docker容器编排

当我们要去构建一个lnmp架构的时候,它们之间会有依赖关系,哪个应用应该在什么时候启动,在谁之前或之后启动,这种依赖关系我们应该要事先定义好,最好是按照一定的次序实现,而docker自身没有这个功能,所以我们需要一个在docker的基础上,能够把这种应用程序之间的依赖关系、从属关系、隶属关系等等反映在启动、关闭时的次序和管理逻辑中,这种功能被称为容器编排。

有了docker以后,运维的发布工作必须通过编排工具来实现容器的编排,如果没有编排工具,运维人员想去管理容器其实比直接管理程序要更加麻烦,增加了运维环境管理的复杂度。

常见的容器编排工具:

  • machine+swarm(把N个docker主机当一个主机来管理)+compose(单机编排)
  • mesos(实现统一资源调度和分配)+marathon
  • kubernetes --> k8s

什么是Docker

Docker是一个软件容器平台,它是基于Linux 内核提供的 CGroup 功能和 namespace 来实现的,以及 AUFS 类的UnionFS 等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术。

docker中的容器:

lxc --> libcontainer --> runC

OCI与OCF

OCI

开放容器计划(Open Container-initiative)

  • 由Linux基金会主导于2015年6月创立
  • 旨在围绕容器格式和运行时制定一个开放的工业化标准
  • 包含两种规格
    • 运行时规范(runtime-spec)
    • 图像规范(image-spec)

OCF

开放容器格式(Open Container Format)

runC 是一个 CLI 工具,用于根据 OCI 规范生成和运行容器

  • 容器作为 runC 的子进程启动,可以嵌入到各种其他系统中,而无需运行守护进程
  • runC 建立在 libcontainer 之上,同样的容器技术为数百万个 Docker 引擎安装提供支持

docker提供了一个专门容纳容器镜像的站点:https://hub.docker.com

Docker架构

  • Registry是一个用来存放镜像的仓库中心,一个Registry中可以存在多个仓库- (Repository),每个仓库可以包含多个标签,每个标签对应一个镜像。
  • docker_host,一个物理或虚拟的用来执行Docker 守护进程和容器的机器

docker客户端通过命令行或者其他工具与docker守护进程进行交互来制作镜像或者从仓库获取镜像,并使用镜像创建容器或管理容器

Docker镜像与镜像仓库

在docker中仓库的名字是以应用的名称取名的
Docker容器技术基础_第5张图片

镜像是静态的,而容器是动态的,容器有其生命周期,镜像与容器的关系类似于程序与进程的关系。镜像类似于文件系统中的程序文件,而容器则类似于将一个程序运行起来的状态,也即进程。所以容器是可以删除的,容器被删除后其镜像是不会被删除的。

Docker对象

使用Docker 时,你可以创建和使用镜像、容器、网络、卷、插件和其他对象。

  • 镜像
    • 镜像是一个只读模板,其中包含有创建 docker 容器的说明。
    • 通常一个镜像基于另一个镜像,并具有一些额外自定义内容。
    • 可以创建自己的镜像,也可以使用其他人创建并在注册中心中发布的镜像。
  • 容器
    • 容器是镜像的可运行实例
    • 你可以使用Docker API 或 CLI 来创建、运行、停止、移动或删除容器。
    • 可以将容器连接到一个或多个网络,并将存储附加到该容器,甚至可以基于其当前状态创建新的镜像。

安装及使用Docker

docker安装

[root@localhost ~]# cd /etc/yum.repos.d/
[root@localhost yum.repos.d]# wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

[root@localhost yum.repos.d]# yum -y install docker-ce
[root@localhost ~]# systemctl start docker
[root@localhost ~]# systemctl enable docker
Created symlink /etc/systemd/system/multi-user.target.wants/docker.service → /usr/lib/systemd/system/docker.service.

配置加速器
docker-ce的配置文件是/etc/docker/daemon.json,此文件默认不存在,需要我们手动创建并进行配置,而docker的加速就是通过配置此文件来实现的。

docker的加速有多种方式:

  • docker cn
  • 中国科技大学加速器
  • 阿里云加速器(需要通过阿里云开发者平台注册帐号,免费使用个人私有的加速器)

这里我使用的是阿里云的个人镜像加速器,这个加速器只是我个人的。如果你想使用,必须去阿里云注册账号并配置自己的加速器。

[root@localhost ~]# mkdir -p /etc/docker
[root@localhost ~]# tee /etc/docker/daemon.json <<-'EOF'
> {
>   "registry-mirrors": ["https://cj9sucfo.mirror.aliyuncs.com"]
> }
> EOF
{
  "registry-mirrors": ["https://cj9sucfo.mirror.aliyuncs.com"]
}
[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl restart docker
[root@localhost ~]# docker version
Client: Docker Engine - Community
 Version:           20.10.17
 API version:       1.41
 Go version:        go1.17.11
 Git commit:        100c701
 Built:             Mon Jun  6 23:03:11 2022
 OS/Arch:           linux/amd64
 Context:           default
 Experimental:      true

Server: Docker Engine - Community
 Engine:
  Version:          20.10.17
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.17.11
  Git commit:       a89b842
  Built:            Mon Jun  6 23:01:29 2022
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.6.6
  GitCommit:        10c12954828e7c7c9b6e0ea9b0c02b01407d3ae1
 runc:
  Version:          1.1.2
  GitCommit:        v1.1.2-0-ga916309
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

Docker常用操作

命令 功能
docker search 在Docker Hub上搜索镜像
docker pull 从注册中心拉取镜像或仓库
docker images 查看所有镜像
docker create 创建新的容器
docker start 开启一个或多个处于stopped状态的容器
docker run 创建新的容器并运行
docker attach 连接到运行的容器
docker ps 查看所有容器
docker logs 获取容器的日志
docker restart 重启容器
docker stop 停止一个或多个正在运行的容器
docker kill 杀死一个或多个正在运行的容器
docker rm 删除一个或多个容器
docker exec 连接运行的容器并临时指定登录shell
docker info 查看系统的信息
docker inspect 返回Docker对象的低级信息

docker search
在Docker Hub上搜索镜像

[root@localhost ~]# docker search nginx
NAME                                              DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
nginx                                             Official build of Nginx.                        17195     [OK]
linuxserver/nginx                                 An Nginx container, brought to you by LinuxS…   173
bitnami/nginx                                     Bitnami nginx Docker Image                      137                  [OK]
ubuntu/nginx                                      Nginx, a high-performance reverse proxy & we…   55
bitnami/nginx-ingress-controller                  Bitnami Docker Image for NGINX Ingress Contr…   19                   [OK]
rancher/nginx-ingress-controller                                                                  10
webdevops/nginx                                   Nginx container                                 9                    [OK]
ibmcom/nginx-ingress-controller                   Docker Image for IBM Cloud Private-CE (Commu…   4
bitnami/nginx-ldap-auth-daemon                                                                    3
rancher/nginx                                                                                     2

docker pull
从注册中心拉取镜像或仓库

[root@localhost ~]# docker pull nginx:latest
latest: Pulling from library/nginx
a2abf6c4d29d: Pull complete
a9edb18cadd1: Pull complete
589b7251471a: Pull complete
186b1aaa4aa6: Pull complete
b4df32aa5a72: Pull complete
a0bcbecc962e: Pull complete
Digest: sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest

docker images
查看所有镜像

[root@localhost ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
nginx        latest    605c77e624dd   7 months ago   141MB

docker create
创建新的容器

[root@localhost ~]# docker create --name nginx1 nginx
cbc2abe2797a66a2a8c969676084568dec23a54e3abe46e8da1ec3b134615b02
[root@localhost ~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS    PORTS     NAMES
cbc2abe2797a   nginx     "/docker-entrypoint.…"   9 seconds ago   Created             nginx1

docker start
开启一个或多个处于stopped状态的容器

[root@localhost ~]# docker start nginx1
nginx1
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED              STATUS         PORTS     NAMES
cbc2abe2797a   nginx     "/docker-entrypoint.…"   About a minute ago   Up 4 seconds   80/tcp    nginx1

docker run
创建新的容器并启用它

[root@localhost ~]# docker run -d --name nginx2 nginx
018896d302d2bc061749d7e451259f8fb205b671742366153d9915613d993a6c
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS     NAMES
018896d302d2   nginx     "/docker-entrypoint.…"   6 seconds ago   Up 5 seconds   80/tcp    nginx2

docker attach
连接到运行的容器

//使用docker attach连接需要在创建容器时指定交互shell
[root@localhost ~]# docker create -it --name nginx3 nginx /bin/bash
5ffc6e6d88cbe984feadb29736aed01b22e6d6e24268b09a38312f7aac2c029e
[root@localhost ~]# docker start nginx3
nginx3
[root@localhost ~]# docker attach nginx3
root@5ffc6e6d88cb:/#

docker ps
查看运行的容器

[root@localhost ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS     NAMES
018896d302d2   nginx     "/docker-entrypoint.…"   6 minutes ago   Up 6 minutes   80/tcp    nginx2

//查看所有容器
[root@localhost ~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND                  CREATED              STATUS                      PORTS     NAMES
5ffc6e6d88cb   nginx     "/docker-entrypoint.…"   About a minute ago   Exited (0) 11 seconds ago             nginx3
018896d302d2   nginx     "/docker-entrypoint.…"   6 minutes ago        Up 6 minutes                80/tcp    nginx2
cbc2abe2797a   nginx     "/docker-entrypoint.…"   10 minutes ago       Exited (0) 4 minutes ago              nginx1

docker logs
查看容器的日志

[root@localhost ~]# docker logs nginx2
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
...

docker kill
杀死运行的容器

[root@localhost ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS     NAMES
018896d302d2   nginx     "/docker-entrypoint.…"   8 minutes ago   Up 8 minutes   80/tcp    nginx2
[root@localhost ~]# docker kill nginx2
nginx2
[root@localhost ~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS                       PORTS     NAMES
5ffc6e6d88cb   nginx     "/docker-entrypoint.…"   3 minutes ago    Exited (0) 2 minutes ago               nginx3
018896d302d2   nginx     "/docker-entrypoint.…"   8 minutes ago    Exited (137) 4 seconds ago             nginx2
cbc2abe2797a   nginx     "/docker-entrypoint.…"   12 minutes ago   Exited (0) 6 minutes ago               nginx1

docker rm
删除容器

[root@localhost ~]# docker rm nginx2
nginx2
[root@localhost ~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS                      PORTS     NAMES
5ffc6e6d88cb   nginx     "/docker-entrypoint.…"   6 minutes ago    Exited (0) 5 minutes ago              nginx3
cbc2abe2797a   nginx     "/docker-entrypoint.…"   15 minutes ago   Exited (0) 10 minutes ago             nginx1

docker exec
给容器临时指定一个交互shell并连接进去

[root@localhost ~]# docker start nginx1
nginx1
[root@localhost ~]# docker exec -it nginx1 /bin/sh
# pwd
/

docker info
查看docker的信息

[root@localhost ~]# docker info
Client:
 Context:    default
 Debug Mode: false
 Plugins:
  app: Docker App (Docker Inc., v0.9.1-beta3)
  buildx: Docker Buildx (Docker Inc., v0.8.2-docker)
  scan: Docker Scan (Docker Inc., v0.17.0)

Server:
 Containers: 2
  Running: 1
  Paused: 0
  Stopped: 1
 Images: 1

docker inspect
查看容器的信息

[root@localhost ~]# docker inspect nginx1
[
    {
        "Id": "cbc2abe2797a66a2a8c969676084568dec23a54e3abe46e8da1ec3b134615b02",
        "Created": "2022-08-04T06:19:58.219347456Z",
        "Path": "/docker-entrypoint.sh",
        "Args": [
            "nginx",
            "-g",
            "daemon off;"
...

你可能感兴趣的:(docker,运维,容器)