Linux之docker容器
一、docker是什么?
Docker 是一个开源的应用容器引擎,基于Go语言并遵从 Apache2.0 协议开源。
Docker 属于 Linux 容器的一种封装,提供简单易用的容器使用接口。它是目前最流行的 Linux 容器解决方案。
Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。对容器进行管理。
容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。
Docker 从 17.03 版本之后分为 CE(Community Edition: 社区版) 和 EE(Enterprise Edition: 企业版)。
1、docker容器的框架
二、docker的安装
官方文档
https://docs.docker.com/engine/install/centos/
- 1.卸载原来安装过的docker,如果没有安装可以不需要卸载
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
- 2.安装yum相关的工具,下载docker-ce.repo文件
[root@cali ~]# yum install -y yum-utils -y
[root@cali ~]#yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
下载docker-ce.repo文件存放在/etc/yum.repos.d
[root@cali yum.repos.d]# pwd
/etc/yum.repos.d
[root@cali yum.repos.d]# ls
CentOS-Base.repo CentOS-Debuginfo.repo CentOS-Media.repo CentOS-Vault.repo docker-ce.repo
CentOS-CR.repo CentOS-fasttrack.repo CentOS-Sources.repo CentOS-x86_64-kernel.repo nginx.repo
[root@cali yum.repos.d]#
- 3.安装docker-ce软件
container engine 容器引擎
docker是一个容器管理的软件
docker-ce 是服务器端软件 server
docker-ce-cli 是客户端软件 client
docker-compose-plugin 是compose插件,用来批量启动很多容器,在单台机器上
containerd.io 底层用来启动容器的
[root@cali yum.repos.d]# yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin -y
[root@cali yum.repos.d]# docker --version
Docker version 20.10.17, build 100c701
[root@cali yum.repos.d]#
- 4.启动docker服务
[root@cali yum.repos.d]# systemctl start docker
[root@cali yum.repos.d]# ps aux|grep docker
root 1892 1.4 1.5 1095108 58972 ? Ssl 11:39 0:00 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
root 2029 0.0 0.0 112824 976 pts/0 S+ 11:40 0:00 grep --color=auto docker
[root@cali yum.repos.d]#
- 5.设置docker服务开机启动
[root@cali yum.repos.d]# systemctl enable docker
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.
[root@cali yum.repos.d]#
三、docker基本命令
1、docker系统信息与版本查看命令
a、docker --version:查看docker版本、docker info:查看详细信息
docker info : 显示 Docker 系统信息,包括镜像和容器数。
[root@docker ~]# docker --version
Docker version 20.10.21, build baeda1f
[root@docker ~]# docker info
Client:
Context: default
Debug Mode: false
Plugins:
app: Docker App (Docker Inc., v0.9.1-beta3)
buildx: Docker Buildx (Docker Inc., v0.9.1-docker)
compose: Docker Compose (Docker Inc., v2.12.2)
scan: Docker Scan (Docker Inc., v0.21.0)
Server:
Containers: 2
Running: 2
Paused: 0
Stopped: 0
Images: 7
Server Version: 20.10.21
Storage Driver: overlay2
Backing Filesystem: xfs
Supports d_type: true
Native Overlay Diff: true
userxattr: false
Logging Driver: json-file
Cgroup Driver: cgroupfs
Cgroup Version: 1
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: inactive
Runtimes: io.containerd.runc.v2 io.containerd.runtime.v1.linux runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 1c90a442489720eec95342e1789ee8a5e1b9536f
runc version: v1.1.4-0-g5fd4c4d
init version: de40ad0
Security Options:
seccomp
Profile: default
Kernel Version: 3.10.0-1160.el7.x86_64
Operating System: CentOS Linux 7 (Core)
OSType: linux
Architecture: x86_64
CPUs: 4
Total Memory: 3.682GiB
Name: docker
ID: NQ7B:XEPS:P3XE:FR7V:OAZA:LKSB:CAEU:YJHL:VLPT:4RW5:QZ6A:SNSR
Docker Root Dir: /var/lib/docker
Debug Mode: false
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false
2、本地镜像管理类命令
a、docker images:查看镜像
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat latest 3500a757f51d 6 days ago 473MB
nginx latest 76c69feac34e 2 weeks ago 142MB
redis latest c2342258f8ca 2 weeks ago 117MB
python 3.9-slim f550e60adaa9 2 weeks ago 125MB
mysql 5.7.39 eb175b0743cc 4 weeks ago 433MB
centos latest 5d0da3dc9764 13 months ago 231MB
python 2.7-slim eeb27ee6b893 2 years ago 148MB
b、docker rmi : 删除本地的一个或多个镜像
docker rmi [OPTIONS] IMAGE [IMAGE…]
OPTIONS说明:
-f :强制删除;
docker rmi -f
docker images -qa
表示删除全部镜像
[root@docker ~]# docker rmi centos
Untagged: centos:latest
Untagged: centos@sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177
Deleted: sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6
Deleted: sha256:74ddd0ec08fa43d09f32636ba91a0a3053b02cb4627c35051aff89f853606b5
c、docker search:查询镜像
[root@docker-three /]# docker search centos
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
centos DEPRECATED; The official build of CentOS. 7422 [OK]
kasmweb/centos-7-desktop CentOS 7 desktop for Kasm Workspaces 26
couchbase/centos7-systemd centos7-systemd images with additional debug… 5 [OK]
dokken/centos-7 CentOS 7 image for kitchen-dokken 4
name:表示镜像名称
description:表示镜像说明
stars:表示点赞数量
official:是否是官方的
automated:表示是否是自动构建的。
d、docker pull : 下载镜像
docker pull imageName
或者 docker pull imageName:tag
默认情况下,不指定版本号的话就会默认下载最新版latest
[root@docker-three /]# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
a603fa5e3b41: Pull complete
c39e1cda007e: Pull complete
90cfefba34d7: Pull complete
a38226fb7aba: Pull complete
62583498bae6: Pull complete
9802a2cfdb8d: Pull complete
Digest: sha256:e209ac2f37c70c1e0e9873a5f7231e91dcd83fdf1178d8ed36c2ec09974210ba
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
[root@docker-three /]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 88736fe82739 2 weeks ago 142MB
[root@docker-three /]#
3、容器管理类命令
a、docker ps:看有哪些docker容器在运行
docker ps 表示列出当前正在运行的容器
docker ps -a 表示列出当前所有正在运行的容器+历史上运行过的容器
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0ed154462de1 nginx "/docker-entrypoint.…" 29 hours ago Up About an hour 0.0.0.0:9900->80/tcp, :::9900->80/tcp xiaowei-1-nginx
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0ed154462de1 nginx "/docker-entrypoint.…" 29 hours ago Up About an hour 0.0.0.0:9900->80/tcp, :::9900->80/tcp xiaowei-1-nginx
cd5b5334aa29 nginx "/docker-entrypoint.…" 29 hours ago Exited (0) 22 seconds ago xiaowei-nginx
[root@docker ~]#
b、docker run :启动容器
1. 启动交互式容器:
docker run -it 镜像名 /bin/bash
例如: docker run -it ubuntu:14.04 /bin/bash
2. 启动后台运行容器(或者是守护式容器):
docker run -d 镜像名 /bin/bash
上述两个命令,并没有给容器命名,则系统会自动分配名字。如果想要自定义容器名,则使用如下命令:
docker run -it --name="容器名" 镜像名 /bin/bash
--name="容器名"
-d:后台运行容器并返回容器ID,即守护式容器
-i:以交互模式运行容器,通常与-t同时使用
-t:为容器重新分配一个伪输入终端
[root@docker-three /]# docker run -it --name xiaowei-nginx bash
Unable to find image 'bash:latest' locally
latest: Pulling from library/bash
^C
[root@docker-three /]# docker run -it --name xiaowei-nginx nginx bash
root@5be5144074a8:/# ls
bin boot dev docker-entrypoint.d docker-entrypoint.sh etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@5be5144074a8:/#
exit
[root@docker-three /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@docker-three /]# docker run -d -p 8080:80 --name xiaowei-nginx-1 nginx
cce420e5de69eb9676ad034a66359962f0b1a3b57e9a7788ae73de17ab7b40d5
[root@docker-three /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cce420e5de69 nginx "/docker-entrypoint.…" 2 seconds ago Up 2 seconds 0.0.0.0:8080->80/tcp, :::8080->80/tcp xiaowei-nginx-1
[root@docker-three /]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cce420e5de69 nginx "/docker-entrypoint.…" 7 seconds ago Up 6 seconds 0.0.0.0:8080->80/tcp, :::8080->80/tcp xiaowei-nginx-1
5be5144074a8 nginx "/docker-entrypoint.…" 42 seconds ago Exited (0) 35 seconds ago xiaowei-nginx
[root@docker-three /]#
c、docker start : 启动已停止运行的容器
docker start 容器名或容器ID
例如,
docker start xiaowei-nginx-1
d、docker restart : 重启容器
docker restart 容器名或容器ID
e、docker stop : 停止容器
docker stop 容器名或容器ID
f、docker kill :强制停止容器
docker kill 容器名或容器ID
g、删除已停止的容器
docker rm 容器名或容器ID
h、进入正在运行的容器
方法一:
docker exec -it 容器ID或者容器名 /bin/bash
[root@docker-three /]# docker exec -it xiaowei-nginx-1 bash
root@cce420e5de69:/# ls
bin boot dev docker-entrypoint.d docker-entrypoint.sh etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@cce420e5de69:/#
exit
[root@docker-three /]#
方法二:
docker attach 容器ID或者容器名
[root@docker-three /]# docker attach xiaowei-nginx-1
attach 直接进入容器启动命令的终端,不会启动新的进程,用exit退出,会导致容器的停止。
exec是在容器中打开新的终端,并且可以启动新的进程,用exit,不会导致容器的停止。
推荐使用docker exec 命令,因为退出容器终端,不会导致容器的停止。
所以,一般流程是使用-d启动容器,再用exec进入对应容器实例。
i、docker top : 查看容器内运行的进程
docker top 容器ID或者容器名
j、docker inspect : 查看容器内部的细节
docker inspect 容器ID或者容器名
十、docker常见面试题
1、docker与虚拟机的比较
- Docker相比于传统虚拟化方式具有的优势和劣势:
docker 启动快速属于秒级别。虚拟机通常需要几分钟去启动
docker 需要的资源更少, docker 在操作系统级别进行虚拟化, docker 容器和内核交互,几乎没有性能损耗,性能优于通过 Hypervisor 层与内核层的虚拟化
docker 更轻量, docker 的架构可以共用一个内核与共享应用程序库,所占内存极小。同样的硬件环境, Docker 运行的镜像数远多于虚拟机数量,对系统的利用率非常高
高可用和可恢复性: docker 对业务的高可用支持是通过快速重新部署实现的。虚拟化具备负载均衡,高可用,容错,迁移和数据保护等经过生产实践检验的成熟保障机制, VMware 可承诺虚拟机 99.999% 高可用,保证业务连续性
快速创建、删除:虚拟化创建是分钟级别的, Docker 容器创建是秒级别的, Docker 的快速迭代性,决定了无论是开发、测试、部署都可以节约大量时间
交付、部署:虚拟机可以通过镜像实现环境交付的一致性,但镜像分发无法体系化。 Docker 在 Dockerfile 中记录了容器构建过程,可在集群中实现快速分发和快速部署
(缺点)与虚拟机相比, docker 隔离性更弱, docker 属于进程之间的隔离,虚拟机可实现系统级别隔离
(缺点)可管理性: docker 的集中化管理工具还不算成熟。各种虚拟化技术都有成熟的管理工具,例如 VMware vCenter 提供完备的虚拟机管理能力
(缺点)安全性: docker 的安全性也更弱。 Docker 的租户 root 和宿主机 root 等同,一旦容器内的用户从普通用户权限提升为root权限,它就直接具备了宿主机的root权限,进而可进行无限制的操作。虚拟机租户 root 权限和宿主机的 root 虚拟机权限是分离的,并且虚拟机利用如 Intel 的 VT-d 和 VT-x 的 ring-1 硬件隔离技术,这种隔离技术可以防止虚拟机突破和彼此交互,而容器至今还没有任何形式的硬件隔离,这使得容器容易受到攻击
- 层次不一样
虚拟机多一层封装
2、docker的底层隔离机制
a、LXC–linux container
1.LXC是什么?
LXC是Linux containers的简称,是一种基于容器的操作系统层级的虚拟化技术。
2.LXC可以做什么?
LXC可以在操作系统层次上为进程提供的虚拟的执行环境,一个虚拟的执行环境就是一个容器。可以为容器绑定特定的cpu和memory节点,分配特定比例的cpu时间、IO时间,限制可以使用的内存大小(包括内存和是swap空间),提供device访问控制,提供独立的namespace(网络、pid、ipc、mnt、uts)。
3.LXC如何实现?
Sourceforge上有LXC这个开源项目,但是LXC项目本身只是一个为用户提供一个用户空间的工具集,用来使用和管理LXC容器。LXC真正的实现则是靠Linux内核的相关特性,LXC项目只是对此做了整合。基于容器的虚拟化技术起源于所谓的资源容器和安全容器。
LXC在资源管理方面依赖与Linux内核的cgroups子系统,cgroups子系统是Linux内核提供的一个基于进程组的资源管理的框架,可以为特定的进程组限定可以使用的资源。LXC在隔离控制方面依赖于Linux内核的namespace特性,具体而言就是在clone时加入相应的flag(NEWNS NEWPID等等)。
4.为什么要选择LXC?
LXC是所谓的操作系统层次的虚拟化技术,与传统的HAL(硬件抽象层)层次的虚拟化技术相比有以下优势:
- 更小的虚拟化开销(LXC的诸多特性基本由内核特供,而内核实现这些特性只有极少的花费,具体分析有时间再说)
- 快速部署。利用LXC来隔离特定应用,只需要安装LXC,即可使用LXC相关命令来创建并启动容器来为应用提供虚拟执行环境。传统的虚拟化技术则需要先创建虚拟机,然后安装系统,再部署应用。
LXC跟其他操作系统层次的虚拟化技术相比,最大的优势在于LXC被整合进内核,不用单独为内核打补丁。
b、Linux namespace
namespace是什么?
- namespace 是 Linux 内核用来隔离内核资源的方式。通过 namespace 可以让一些进程只能看到与自己相关的一部分资源,而另外一些进程也只能看到与它们自己相关的资源,这两拨进程根本就感觉不到对方的存在。具体的实现方式是把一个或多个进程的相关资源指定在同一个 namespace中。
- Linux namespaces 是对全局系统资源的一种封装隔离,使得处于不同 namespace 的进程拥有独立的全局系统资源,改变一个 namespace 中的系统资源只会影响当前 namespace 里的进程,对其他 namespace 中的进程没有影响。
namespace解决了什么问题?
Linux 内核实现 namespace 的一个主要目的就是实现轻量级虚拟化(容器)服务。在同一个namespace 下的进程可以感知彼此的变化,而对外界的进程一无所知。这样就可以让容器中的进程产生错觉,认为自己置身于一个独立的系统中,从而达到隔离的目的。也就是说 linux 内核提供的 namespace 技术为 docker 等容器技术的出现和发展提供了基础条件。
namespace有哪些?
- Mount Namespace隔离了一组进程所看到的文件系统挂载点的集合,因此,在不同MountNamespace的进程看到的文件系统层次结构也不同
- UTS Namespace隔离了uname()系统调用返回的两个系统标示符nodename和domainname,在容器的上下文中,UTS Namespace允许每个容器拥有自己的hostname和NIS domain name,这对于初始化和配置脚本是很有用的,这些脚本根据这些名称来定制它们的操作
- IPC Namespace隔离了某些IPC资源(interprocess community,进程间通信)使划分到不同IPC Namespace的进程组通信上隔离,无法通过消息队列、共享内存、信号量方式通信
- PID Namespace隔离了进程ID号空间,不同的PID Namespace中的进程可以拥有相同的PID。PID Namespace的好处之一是,容器可以在主机之间迁移,同时容器内的进程保持相同的进程ID。PID命名空间还允许每个容器拥有自己的init(PID 1),它是 “所有进程的祖先”,负责管理各种系统初始化任务,并在子进程终止时收割孤儿进程
- Network Namespace提供了网络相关系统资源的隔离,因此,每个Network Namespace都有自己的网络设备、IP地址、IP路由表、/proc/net目录、端口号等。
- User Namespace隔离了用户和组ID号空间,一个进程的用户和组ID在用户命名空间内外可以是不同的,一个进程可以在用户命名空间外拥有一个正常的无权限用户ID,同时在命名空间内拥有一个(root权限)的用户ID
c、Cgroup
什么是cgroup
- cgroup全称是control groups
- control groups:控制组,被整合在了linux内核当中,把进程(tasks)放到组里面,对组设置权限,对进程进行控制。可以理解为用户和组的概念,用户会继承它所在组的权限。
- cgroups是linux内核中的机制,这种机制可以根据特定的行为把一系列的任务,子任务整合或者分离,按照资源划分的等级的不同,从而实现资源统一控制的框架,cgroup可以控制、限制、隔离进程所需要的物理资源,包括cpu、内存、IO,为容器虚拟化提供了最基本的保证,是构建docker一系列虚拟化的管理工具
cgroup解决了什么问题?
- 资源控制:cgroup通过进程组对资源总额进行限制。如:程序使用内存时,要为程序设定可以使用主机的多少内存,也叫作限额
- 优先级分配:使用硬件的权重值。当两个程序都需要进程读取cpu,哪个先哪个后,通过优先级来进行控制
- 资源统计:可以统计硬件资源的用量,如:cpu、内存…使用了多长时间
- 进程控制:可以对进程组实现挂起/恢复的操作