容器技术基本原理之Namespace

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 容器技术基本原理之Namespace

以前被面试或者面试别人的时候,出现频率比较高的一个问题是:看你简历上写熟悉容器技术,那你是怎么理解容器的?还算可以的回答是:容器技术本身不是新的技术,容器本质上就是宿主机操作系统上的一个特殊的进程,利用Namespace和Cgroup技术实现了资源的隔离与限制,并且实现了容器镜像,解决了应用程序分发的问题。答到这里,可以说对容器的理解还是比较全面的了。

Docker的安装:本不想写网上一搜一堆,且不需要理解的东西,但是看好多文章里写的安装过程,多少有点坑,所以还是写一下,安装过程就在ubuntu上操作,因为CentOS7将来也就不维护了,听说ebay生产环境系统也都用ubuntu了。

step1: 更新ubuntu apt-get源

sudo apt-get update

 

sudo apt-get install \

   ca-certificates \

   curl \

   gnupg \

   lsb-release

step2: 添加Docker官方GPG key

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg


step3: 安装Docker稳定版仓库地址

echo \

 "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \

 $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

step4: 安装Docker

sudo apt-get update

sudo apt-get install docker-ce docker-ce-cli containerd.io

通常安装完Docker就自动运行了,但是很多人想长期用这个Docker作为一个test或staging环境,那么直接用估计会有问题,Docker默认的存储目录在/var/lib/docker/下,有些主机的这个盘很小,尤其是云主机,用一段时间把系统盘占满了,还得迁走,就很麻烦,不如一步到位,把数据存储目录放到较大的盘上,比如/data/docker/。

step5: 编辑/lib/systemd/system/docker.service文件,在ExecStart选项后加上--data-root=/data/docker,这样就自定义了数据目录,结果如下所示:

ExecStart=/usr/bin/dockerd -H fd:// --data-root=/data/docker --containerd=/run/containerd/containerd.sock --log-level warn --log-opt max-size=100m --log-opt max-file=5

然后重新加载systemd并重启Docker进程即可。

systemctl daemon-reload

systemctl restart docker

step6: 验证容器已经安装成功

# docker run hello-world


Hello from Docker!

This message shows that your installation appears to be working correctly.


用Docker运行一个Nginx容器:Docker作为工具来用,其实没有什么复杂的东西,日常只要掌握Dockerfile,会用一些基本的命令就可以了,下面以Nginx为基础,制作我们的镜像并运行。

step1: 编写Dockerfile

# 这里指定你的基础镜像,建议写固定的版本号,不然默认的latest更新可能会导致你的代码不兼容

FROM nginx:1.21.3


# 进入容器后的默认目录

WORKDIR /usr/share/nginx/html


# 把index.html内容改成我们想要的内容

RUN echo "This is my first image base nginx!" > index.html

step2: 生成Docker镜像

docker build -t my_nginx:v1.0 -f Dockerfile .

step3: 查看生成的镜像,并使用该镜像启动容器

# docker images

my_nginx     v1.0      5d0547b2cc8d   3 hours ago              133MB


# docker run -d 5d0547b2cc8d


# docker ps

CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS     NAMES

6961dd4fce83   5d0547b2cc8d   "/docker-entrypoint.…"   18 minutes ago   Up 18 minutes   80/tcp    strange_jepsen

step4:  查看容器IP地址,并使用容器IP访问nginx服务,这里我们介绍使用nsenter命令,场景是我们的nginx镜像中并没有ifconfig命令,但是我们又想查看IP地址,这时就可以通过nsenter命令进入到容器的Namespace,并用宿主机上的命令来调整容器。

[root@iZ2zec5wzaupsrdu55oeaiZ docker]# docker inspect 6961dd4fce83 | grep -i pid

           "Pid": 30176,

           "PidMode": "",

           "PidsLimit": null,

[root@iZ2zec5wzaupsrdu55oeaiZ docker]# nsenter -t 30176 -n ifconfig

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500

       inet 172.18.0.2  netmask 255.255.0.0  broadcast 172.18.255.255

       ether 02:42:ac:12:00:02  txqueuelen 0  (Ethernet)

       RX packets 18  bytes 1256 (1.2 KiB)

       RX errors 0  dropped 0  overruns 0  frame 0

       TX packets 14  bytes 1386 (1.3 KiB)

       TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0


lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536

       inet 127.0.0.1  netmask 255.0.0.0

       loop  txqueuelen 1000  (Local Loopback)

       RX packets 0  bytes 0 (0.0 B)

       RX errors 0  dropped 0  overruns 0  frame 0

       TX packets 0  bytes 0 (0.0 B)

       TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0


[root@iZ2zec5wzaupsrdu55oeaiZ docker]# curl 172.18.0.2

This is my first image base nginx!


转入正题,细说Namespace: Namespace不是一项新技术,它是内核自带的一项功能,Docker之所以能实现资源隔离,就是调用了内核的Namespace功能。该功能对内核资源进行隔离,使得容器进程都可以在单独的命名空间中运行,并且只可以访问当前容器命名空间的资源。

Linux下的资源类型有很多,那么Namespace就也分为下面几类对资源进行限制:

  • PID namespace:用于隔离进程 ID。
  • Network namespace:隔离网络接口,在虚拟的 net namespace 内用户可以拥有自己独立的 IP、路由、端口等。
  • Mount namespace:文件系统挂载点隔离。
  • IPC namespace:信号量、消息队列和共享内存的隔离。
  • UTS namespace:主机名和域名的隔离。
  • User namespace: 用户和组的隔离。

上面列出了各种资源的隔离,下面就拿 PID namespace 来举例,看看这个在Linux操作系统里是如何实现的,Linux 系统中创建进程的系统调用是 clone(),如下代码所示:

int pid = clone(main_function, stack_size, SIGCHLD, NULL);

但是一旦我们传入了 CLONE_NEWPID 参数,新创建的进程就进入了一个独立的空间,在这个空间里它自己的PID是1,在外面看来它就是一个正常的进程,进程号可能是xxx这种,但肯定不是1,因为1号进程是操作系统的systemd进程,如下代码就实现了进程隔离:

int pid = clone(main_function, stack_size, CLONE_NEWPID | SIGCHLD, NULL);

通俗来讲,一个进程在启动后,Namespace就给他一通包装,然后这个进程就在自己的小天地里自由的玩耍了。但齐天大圣终穷逃不出如来的五指山,对于开发者来讲,它仍然是操作系统上的一个进程罢了。

对于大多数人来讲,我们只需要知道Docker是如何实现进程隔离的,如果以后有需要去深入挖掘,就按着操作系统的Namespace功能的方向去找就好了。

相关文章
|
3月前
|
存储 容器
46.[HarmonyOS NEXT RelativeContainer案例三] 打造自适应容器:内容驱动的智能尺寸调整技术
在HarmonyOS NEXT的UI开发中,创建能够根据内容自动调整尺寸的容器是实现灵活布局的关键。RelativeContainer结合自适应尺寸设置,可以实现内容驱动的智能尺寸调整,使UI更加灵活且易于维护。本教程将详细讲解如何创建自适应尺寸的RelativeContainer,帮助你掌握这一实用技术。
127 5
|
1月前
|
Kubernetes Cloud Native 持续交付
Docker:轻量级容器化技术解析
Docker:轻量级容器化技术解析
|
1月前
|
运维 测试技术 Docker
Docker:轻量级容器化技术革命
Docker:轻量级容器化技术革命
|
9月前
|
Kubernetes Cloud Native 微服务
探索云原生技术:容器化与微服务架构的融合之旅
本文将带领读者深入了解云原生技术的核心概念,特别是容器化和微服务架构如何相辅相成,共同构建现代软件系统。我们将通过实际代码示例,探讨如何在云平台上部署和管理微服务,以及如何使用容器编排工具来自动化这一过程。文章旨在为开发者和技术决策者提供实用的指导,帮助他们在云原生时代中更好地设计、部署和维护应用。
|
5月前
|
弹性计算 Java Maven
从代码到容器:Cloud Native Buildpacks技术解析
Cloud Native Buildpacks(CNB)是一种标准化、云原生的容器镜像构建系统,旨在消除手动编写Dockerfile,提供可重复、安全且高效的构建流程。它通过分层策略生成符合OCI标准的镜像,实现应用与基础镜像解耦,并自动化依赖管理和更新。阿里云应用管理支持通过CNB技术一键部署应用至ECS,简化构建和运行流程。
|
6月前
|
存储 虚拟化 Docker
|
6月前
|
开发工具 虚拟化 git
自学软硬件第755 docker容器虚拟化技术youtube视频下载工具
docker容器虚拟化技术有什么用?怎么使用?TubeTube 项目使用youtube视频下载工具
|
9月前
|
Unix Linux Docker
CentOS停更沉寂,RHEL巨变限制源代:Docker容器化技术的兴起助力操作系统新格局
操作系统是计算机系统的核心软件,管理和控制硬件与软件资源,为用户和应用程序提供高效、安全的运行环境。Linux作为开源、跨平台的操作系统,具有高度可定制性、稳定性和安全性,广泛应用于服务器、云计算、物联网等领域。其发展得益于庞大的社区支持,多种发行版如Ubuntu、Debian、Fedora等满足不同需求。
278 5
|
10月前
|
运维 Kubernetes Docker
深入理解容器化技术:Docker与Kubernetes的协同工作
深入理解容器化技术:Docker与Kubernetes的协同工作
254 14
|
10月前
|
持续交付 开发者 Docker
探索容器化技术Docker及其在现代软件开发中的应用
探索容器化技术Docker及其在现代软件开发中的应用
156 10