Docker容器

docker容器技术基础入门

本文主要是介绍docker容器技术基础入门,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

容器(Container)

  • 容器是一种基础工具;泛指任何可以用于容纳其他物品的工具,可以部分或完全封闭,被用于容纳、储存、运输物品;物体可以被放置在容器中,而容器则可以保护内容物;
  • 人类使用容器的历史至少有十万年,甚至可能有数百万年的历史;
  • 容器的类型
    • 瓶 - 指口部比腹部窄小、颈长的容器
    • 罐 - 指那些开口较大、一般为近圆筒形的器皿
    • 箱 - 通常是立方体或圆柱体。形状固定
    • 篮 - 以条状物编织而成
    • 桶 - 一种圆柱形的容器
    • 袋 - 柔性材料制成的容器,形状会受内容物而变化
    • 瓮 - 通常是指陶制,口小肚大的容器
    • 碗 - 用来盛载食物的容器
    • 柜 - 指一个由盒组成的家具
    • 鞘 - 用于装载刀刃的容器

传统虚拟化与容器的区别

 

 

 

 

 

 

虚拟化分为以下两类:

  • 主机级虚拟化      // 指的是虚拟机
    • 全虚拟化     // 在真机上面直接装虚拟化的软件,然后在软件上直接装系统
    • 半虚拟化     // 在系统上装虚拟化软件,在虚拟机的软件上装一个虚拟机 跑运用
  • 容器级虚拟化

容器分离开的资源:  虚拟机能隔离开的资源,容器也一样的能隔离开,而且消耗的资源比虚拟机少

  • UTS(主机名与域名)
  • Mount(文件系统挂载树)      // linux由2棵树组成:1文件系统树:根下面的/bin/dev/etc/..... 主要存放文件    2进程树:主要是把程序文件启动,执行得出进程,一个静态一个动态    
  • IPC   //  共享
  • PID进程树  // A主机上启动的进程,B主机是看不到的
  • User     //  用户
  • Network(tcp/ip协议栈)  //  ip地址

Linux容器技术

Linux容器其实并不是什么新概念。最早的容器技术可以追遡到1982年Unix系列操作系统上的chroot工具(直到今天,主流的Unix、Linux操作系统仍然支持和带有该工具)。

Linux 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

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

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

CGroups能够限制的资源有:

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

具体来看,控制组提供如下功能:

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

安装Docker后,用户可以在/sys(伪文件系统)/fs/cgroup/memory/docker/目录下看到对Docker组应用的各种限制项,包括

用户可以通过修改这些文件值来控制组限制Docker应用资源。

LXC

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

LXC是最早一批真正把完整的容器技术用一组简易使用的工具和模板来极大的简化了容器技术使用的一个方案。

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

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

常见的LXC命令:

  1 [root@zengqing yum.repos.d]# yum install epel-release -y配置epel源
  2 [root@zengqing ~]# yum -y install lxc lxc-templates bridge-utils lxc-libs libcgroup libvirt    安装lxc软件包和依赖包
  3         lxc           主程序包
  4     lxc-templates  lxc的配置模板
  5     bridge-utils  网桥管理工具
  6     lxc-libs      lxc所需的库文件
  7     libcgroup     cgroup是为Linux内核提供任务聚集和划分的机制,通过一组参数集合将一些任务组织成一个或多个子系统。
  8     libvirt       管理Linux的虚拟化功能所需的服务器端守护程序。 需要针对特定驱动程序的管理程序。
  9 [root@zengqing ~]# systemctl start lxc libvirtd    启动服务
 10 [root@zengqing ~]# ss -antl
 11 State             Recv-Q            Send-Q                       Local Address:Port                        Peer Address:Port            Process            
 12 LISTEN            0                 32                           192.168.122.1:53                               0.0.0.0:*                                  
 13 LISTEN            0                 128                                0.0.0.0:22                               0.0.0.0:*                                  
 14 LISTEN            0                 128                                0.0.0.0:111                              0.0.0.0:*                                  
 15 LISTEN            0                 128                                   [::]:22                                  [::]:*                                  
 16 LISTEN            0                 128                                   [::]:111                                 [::]:*                                 
 17 [root@zengqing ~]# systemctl status lxc   查看状态
 18 ● lxc.service - LXC Container Initialization and Autoboot Code
 19    Loaded: loaded (/usr/lib/systemd/system/lxc.service; disabled; vendor preset: disabled)
 20    Active: active (exited) since Sat 2022-04-23 20:28:00 CST; 5min ago
 21      Docs: man:lxc-autostart
 22            man:lxc
 23   Process: 6381 ExecStart=/usr/libexec/lxc/lxc-containers start (code=exited, status=0/SUCCESS)
 24   Process: 6377 ExecStartPre=/usr/libexec/lxc/lxc-apparmor-load (code=exited, status=0/SUCCESS)
 25  Main PID: 6381 (code=exited, status=0/SUCCESS)
 26     Tasks: 0 (limit: 11175)
 27    Memory: 0B
 28    CGroup: /system.slice/lxc.service
 29 
 30 4月 23 20:28:00 zengqing systemd[1]: Starting LXC Container Initialization and Autoboot Code...
 31 4月 23 20:28:00 zengqing systemd[1]: Started LXC Container Initialization and Autoboot Code.
 32 [root@zengqing ~]# lxc-checkconfig  检查系统是否满足容器使用要求
 33 Kernel configuration not found at /proc/config.gz; searching...
 34 Kernel configuration found at /boot/config-4.18.0-365.el8.x86_64
 35 --- Namespaces ---
 36 Namespaces: enabled
 37 Utsname namespace: enabled
 38 Ipc namespace: enabled
 39 Pid namespace: enabled
 40 User namespace: enabled
 41 Warning: newuidmap is not setuid-root
 42 Warning: newgidmap is not setuid-root
 43 Network namespace: enabled
 44 
 45 --- Control groups ---
 46 Cgroups: enabled
 47 
 48 Cgroup v1 mount points: 
 49 /sys/fs/cgroup/systemd
 50 /sys/fs/cgroup/cpuset
 51 /sys/fs/cgroup/perf_event
 52 /sys/fs/cgroup/freezer
 53 /sys/fs/cgroup/net_cls,net_prio
 54 /sys/fs/cgroup/cpu,cpuacct
 55 /sys/fs/cgroup/memory
 56 /sys/fs/cgroup/pids
 57 /sys/fs/cgroup/rdma
 58 /sys/fs/cgroup/devices
 59 /sys/fs/cgroup/hugetlb
 60 /sys/fs/cgroup/blkio
 61 
 62 Cgroup v2 mount points: 
 63 
 64 
 65 Cgroup v1 clone_children flag: enabled
 66 Cgroup device: enabled
 67 Cgroup sched: enabled
 68 Cgroup cpu account: enabled
 69 Cgroup memory controller: enabled
 70 Cgroup cpuset: enabled
 71 
 72 --- Misc ---
 73 Veth pair device: enabled, not loaded
 74 Macvlan: enabled, not loaded
 75 Vlan: enabled, not loaded
 76 Bridges: enabled, loaded
 77 Advanced netfilter: enabled, loaded
 78 CONFIG_NF_NAT_IPV4: missing
 79 CONFIG_NF_NAT_IPV6: missing
 80 CONFIG_IP_NF_TARGET_MASQUERADE: enabled, not loaded
 81 CONFIG_IP6_NF_TARGET_MASQUERADE: enabled, not loaded
 82 CONFIG_NETFILTER_XT_TARGET_CHECKSUM: enabled, loaded
 83 CONFIG_NETFILTER_XT_MATCH_COMMENT: enabled, not loaded
 84 FUSE (for use with lxcfs): enabled, loaded
 85 
 86 --- Checkpoint/Restore ---
 87 checkpoint restore: enabled
 88 CONFIG_FHANDLE: enabled
 89 CONFIG_EVENTFD: enabled
 90 CONFIG_EPOLL: enabled
 91 CONFIG_UNIX_DIAG: enabled
 92 CONFIG_INET_DIAG: enabled
 93 CONFIG_PACKET_DIAG: enabled
 94 CONFIG_NETLINK_DIAG: enabled
 95 File capabilities: 
 96 
 97 Note : Before booting a new kernel, you can check its configuration
 98 usage : CONFIG=/path/to/config /usr/bin/lxc-checkconfig
 99 [root@zengqing ~]#  ls /usr/share/lxc/templates/查看当前系统中可用的LXC模板容器
100 lxc-busybox  lxc-download  lxc-local  lxc-oci

 

docker基本概念

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

LXC进行大规模创建容器很难,想在另一台主机上复刻一个一模一样的容器也很难,而docker就是从这方面着手去找解决方案。所以docker早期的版本其核心就是一个LXC,docker对其进行了二次封装,功能的实现是通过LXC做容器管理引擎,但是在创建容器时,不再是像LXC一样用模板去现场安装,而是事先通过一种类似镜像技术,就像在KVM中一样,将一个操作系统打包成一个镜像,然后将这个镜像拷贝到目标主机上直接部署启动。

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

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

自docker 0.9版本起,docker除了继续支持LXC外,还开始引入自家的libcontainer,试图打造更通用的底层容器虚拟化库。如今的docker基本上都已经是使用libcontainer而非LXC了。

从操作系统功能上看,docker底层依赖的核心技术主要包括Linux操作系统的命名空间、控制组、联合文件系统和Linux虚拟网络支持。

docker工作方式

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

LXC是把一个容器当一个用户空间使用,当虚拟机一样使用,里面可以运行N个进程,这就使得我们在容器内去管理时极为不便,而docker用这种限制性的方式,在一个容器中只运行一个进程的方式,使得容器的管理更加方便。

 

 

使用docker的优劣:

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

  

 

 

 

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


 

 

 

 

 

这篇关于docker容器技术基础入门的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!