[Docker]Namespace与Cgroups

Posted SkyBiuBiu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Docker]Namespace与Cgroups相关的知识,希望对你有一定的参考价值。

什么是 Namespace?

Namespace 是 Linux 容器技术的一个重要概念,其作用是对运行于其中的进程提供隔离,确保容器和宿主机之间是完全隔离的。Namespace 在 Linux 内核中已经存在了很长一段时间,最初的设计目的是为了更好地支持多用户场景下的文件系统挂载。自那以后,Namespace 已经得到了进一步的扩展和应用,成为了实现容器隔离的主要技术之一。

Namespace 技术的核心思想是将一个进程的视角从全局视图中调整到一个更加狭窄的、虚拟化的空间中,使其认为自己是运行在一个独立的环境中,从而实现进程间的隔离。这种隔离范围不仅包括文件系统、网络、进程编号空间等,还包括主机名、用户等信息。通过使用 Namespace 技术,可以达到企业级隔离和完全隔离的效果。

Namespace 的类型

Linux 中有以下 7 种不同的 namespace,每种 namespace 对于容器技术的实现具有不同的作用和意义:

  1. PID Namespace:PID Namespace 用于隔离容器内的进程编号空间,使得在不同的 PID Namespace 中运行的进程看起来像是在独立的进程空间中运行,而不会彼此混淆。

  2. Mount Namespace:Mount Namespace 用于隔离文件系统挂载点,使得不同的容器之间可以拥有自己独立的文件系统结构,不会相互影响。容器中的文件系统会被 chroot 到指定的目录中,并使用各自的 Mount Namespace 维护文件系统状态。

  3. IPC Namespace:IPC Namespace 用于隔离某些进程间通信(IPC)资源,包括 System V IPC 和 POSIX IPC。在不同的 IPC Namespace 中运行的进程无法相互通信,从而实现了进程间通信隔离。

  4. Net Namespace:Net Namespace 用于隔离网络设备、网络栈、端口和路由信息等。不同的 Net Namespace 中可以拥有自己独立的网络资源,可以实现不同容器的互访与隔离。

  5. UTS Namespace:UTS Namespace 用于隔离主机名和域名等系统识别信息。为不同的容器分配不同的容器名,从而避免名称冲突,提高了容器之间的独立性。

  6. User Namespace:User Namespace 用于隔离用户和用户组的编号空间。(UID 和 GID)。在容器中运行的进程可以拥有唯一的 UID 和 GID,这样做可以避免容器进程干扰宿主机进程,提高容器进程的独立性。

  7. Cgroup Namespace:Cgroup Namespace 用于对应不同的控制组层次结构,可以在应用级别隔离应用程序的资源。每个应用程序会视为一个单独的控制组层级,控制组中运行的进程仅可访问该控制组的资源。

综上所述,Linux 中有 7 种不同的 namespace,每种 namespace 都有自身的独特作用,将容器中的进程、文件系统、网络等资源隔离封装,保证了容器环境之间的相对独立性,从而为容器提供了更高的安全性和可靠性。

Namespace 的实现和使用

在使用 Namespace 时,需要使用系统调用来创建和管理 Namespace。可以使用 clone() 系统调用创建一个新的 Namespace,并使用 setns() 系统调用将一个进程移动到另一个 Namespace 中。这些系统调用提供了官方的程序接口,使得程序员可以在 Linux 内核空间中使用 Namespace 技术,实现容器隔离。

在 Docker 中,Namespace 技术被广泛应用。Docker 使用 Namespace 来提供容器内部的隔离,隔离文件系统、网络设备、进程编号、进程之间通信等等。同时,Docker 还支持用户自定义的 Namespace 类型,因此用户可以根据自己的需求创建自己的 Namespace。

什么是 Cgroups?

Cgroups (control groups) 是 Linux 系统中的一种容器内核技术,它可以限制进程组使用的资源数量和分配,并将它们隔离到一个或多个分层的分组中,以实现对进程、任务或用户组的资源限制。

Cgroups 可以限制多种计算机资源,包括CPU、内存、网络带宽、磁盘I / O等,并允许系统管理员调整和控制该进程组的资源限制。这使得 Cgroups 成为用于容器隔离的关键技术,并可以帮助保护系统免受不安全或恶意代码的破坏。

Cgroups 的特征

Cgroups 是一种强大的容器内核技术,并具有以下特征:

  • 层次结构:Cgroups 可以组合为一个有层次结构的组的集合,并且可以在层次结构中设置各种限制条件,这使得限制和资源管理更加透明和灵活。

  • 动态管理:Cgroups 允许在运行时动态地添加、删除、和更改各个控制组和组中的进程和资源。

  • 用户定义:Cgroups 允许用户定义各种限制条件,以适应特定应用场景,使得 Cgroups 更加适应各种不同的应用。

Cgroups 的使用

Cgroups 是 Linux 内核的一部分,可以通过系统调用(syscalls)实现 Cgroups。在 Cgroups 启用之后,它会根据其自定义的规则来动态地限制诸如 CPU、内存、I/O 等系统资源的进程组。

在使用 Cgroups 时,可能需要先安装 cgroup-tools 和 libcgroup 工具。这些工具提供了访问 Cgroups 功能的实用程序,使得用户可以管理、观察和测试资源限制条件。

在 Docker、Kubernetes 等容器平台中,Cgroups 正在被广泛使用。通过将不同的容器放在 Cgroups 分组中,这些容器之间可以保持资源隔离和独立性,并可以在 OS 级别上分配计算机资源,这提供了更好的容器隔离和性能管理,也成为当前流行的容器的核心技术之一。

总结

Namespace 是 Linux 中的一个重要概念,也是容器技术的核心。它可以将一个进程的视角从系统全局视图调整到一个虚拟化的空间中,实现进程的隔离和保护。Linux 提供了几种不同类型的 Namespace,每种 Namespace 都具有不同的用途和作用。在构建容器时,我们需要使用这些不同类型的 Namespace 来隔离非必要的应用程序和文件系统,提高容器的安全性和可靠性。

Cgroups 是一种强大的容器内核技术,与 Linux 内核一起提供资源管理和限制的功能,可以实现限制进程的资源使用和分配,并保持它们隔离在一个或多个分层的分组中。在 Docker、Kubernetes 等容器平台中,Cgroups 正在被广泛应用,可以帮助实现更好的容器隔离和性能管理。

参考连接

Docker - Docker网络

一、Docker网络介绍

Docker是基于Linux Kernel(内核)的namespace,CGroups,UnionFileSystem等技术封装成的一种自定义容器格式,从而提供了—套虚拟运行环境。

1、namespace:用来做隔离的,比如pid[进程].、net【网络】、mnt【挂载点】

2、cGroups:controller Groups用来做资源限制,比如内存和CPU等

3、union File Systems:用来做Image和Contaliner分层

(一)计算机网络模型

Docker网络官网

Networking overview | Docker Documentation

OSI:开放系统互联参考模型(Open System Interconnect)

TCP/IP:传输控制协议/网际协议(TransmissionControl/nternet Protocol,是指能够在多个不同网络间实现信息传输的协议簇。TCPIP协议不仅仅指的是TCP和IP两个协议,而是指一个由FTP、SMTP、TCP、UDP、IP等协议构成的协议簇,只是因为在TCP/IP协议中TCP协议和IP协议最具代表性,所以被称为TCP/IP协议。

分层思想:分层的基本想法是每一层都在它的下层提供的服务基础上提供更高级的增值服务,而最高层提供能运行分布式应用程序的服务

 

(二)网卡类型

查看网卡类型

ip a

ip link show

ls /sys/class/net/

 自定义添加网卡

cd /etc/sysconfig/network-scripts/

vi ifcfg-eth0

 

 新增某网卡下的IP

 ip addr add 192.168.100.120/24 dev eth0

删除某个网卡下的IP

ip addr delete 192.168.100.120/24 dev eth0

(三)Network NameSpace

Network Namespace 如实现网络虚拟化的重要功能,它能创建多个隔离的网络空间,它们有独自的网络栈信息。不管是虚拟机还是容器,运行的时候仿佛自己就在独立的网络中

添加一个namespace

ip netns add ns1

查看当前具有的namespace

ip netns list

删除namespace

ip netns delete nsl

进入指定命名空间ns1 执行 ip a 命令

ip netns exec ns1 ip a

启动lo网卡

ip netns exec ns1 ifup lo

显示网卡信息

ip netns exec ns1 ip link show

关闭lo网卡

ip netns exec ns1 ifdown lo

设置lo的状态

ip netns exec ns1 ip link set lo down

1、两个命名空间ns1,ns2之间通信

ip netns add ns2

ip netns exec ns2 ifup lo

创建一对连接信息

ip link add veth-ns1 type veth peer name veth-ns2

ip a

ip link set veth-ns1 netns ns1

ip netns exec ns1 ip a

ip netns exec ns1 ifup veth-ns1

ip netns exec ns1 ip link set veth-ns1 up

ip netns exec ns1 ip addr add 192.168.0.11/24 dev veth-ns2

ip netns exec ns1 ip a

这样 ns1 和 ns2 就可以进行通信了

ip netns exec ns1 ping 192.168.0.12

ip netns exec ns2 ping 192.168.0.12

(四)Docker容器默认bridge

Docker之间通信:docker0网卡维护了一对 veth

yum install -y bridge-utils

brctl show

docker network ls

检查bridge

docker network inspect ridge

Docker容器可连接外网

(五)自定义Network

新增一个自定义network

docker network create tomcat-net

删除自定义network

docker network rm tomcat-net

docker network inspect tomcat-net

连接自定义网络

docker network connect tomcat-net tomcat01

docker network disconnect tomcat-net tomcat01

二、Docker实战

(一)MysQL集群搭建

1、拉去境像

docker pu11 percona/percona-xtradb-cluster :5.7.21

2、复制pxc境像【重命名】

docker tag percona/percona-xtr adb-cluster :5.7.21 pxc

3、除原来的镜像

docker rai percona/percona-xtr adb-eluster: 5.7.21

4、创建单独的网段,给MySQL数据库集群便用

docker network create --subnet=172.20.o.0/24 pxc-net

docker network inosect pxc-net #查看详情

docker network rm pxc-net  #除网段

5、创建和制除volume

docker volume create --name v1 #创建volume

docker volume rs v1 #删除volume

docker volune inspect v1 #查看详情

6、搭建pxc集群

准备三个数据卷

docker volume ls

doeker volume create --nane v1

docker volume create --name v2

docker volume create --name v3

docker volume ls

运行3个PXC容器

【CLUSTER_NAME=PXC;集群名字】

【XTRABACKUP_PASSWORD;数据库同步需要用到的密码】

创建第一个主节点

docker run -d -p 3301:3306 -v v1:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456

CLUSTER_NAME=PXC -e

XTRABACKUP_PASSWORD=123456 --privileged --name=node1 --net=pxc-net –ip 172.20.0.2 pxc

创建其他节点注意:-e CLUSTER_JOIM=node1

docker run -d -p 3302:3306 -v v2:/var/lib/mysql -e MYSOL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=PXC -e

XTRABACKUP_PASSWORD=123456 -e CLUSTER_JOIM=node1 --privileged --name=node2 --net=pxc-net --ip 172.20.0.3 pxc

docker run -d -p 3303:3306 -v v3/var/lib/MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=PXC -e

XTRABACKUP_PASSWORD=123456 -e CLUISTER_JOIN=node1 –privileged --name=node3 --net=pxc-net --ip 172.20.0.4 pxc

如果启动报错,或者启动服务之后立马停掉

docker logs 容器ID

(二)负载均衡服务搭建

1、拉取镜像

docker pull haproxy

2、创建haproxy配置文件

touch /tmp/haproxy/haproxy.cfg

global

    #工作目录,这边要和创建容器指定的目录对应

    #chroot /usr / loca1/etc/haproxy

    #日志文件

    1og 127.0.0.1 loca15 info

    #守护进程运行

    daemon
    
defaults

    log global
    
    mode http

    #日志格式

    option httplog

    #日志中不记录负载均衡的心跳检测记录

    option dontlognu11

    #连接超时〈毫秒)

    timeout connect 5000

    #客户端超时〈毫秒)

    timeout client 50000

    #服务器超时(毫秒>

    timeout server 50000

    #监控界面

    listen admin_stats

    #监控界面的访问的IP和端口

    bind 0.0.0.0:8888

    #访问协议

    mode   http

    #URI相对地址

    stats uri  /dbs_monitor

    #统计报告格式

    stats realm Globa7\\ statistics

    #登陆帐户信息

    stats auth admin:admin

    #数据库负载均衡

    listen proxy-mysql

    #访问的IP和端口,haproxy开发的端口为3306

    #假如有人访问haproxy的3306端口,则将请求转发给下面的数据库实例bind 0.0.0.0:3306

    #网络协议

    mode tcp

    #负载t均衡算法(轮询算法)

    #轮询算法:roundrobin

    #权重算法: static-rr

    #最少连接算法:leastconn

    #请求源IP算法: source

    balance roundrobin

    #日志格式

    option tcp1og

    #在MySQL中创建一个没有权限的haproxy用户,密码为空。

    #Haproxy使用这个账户对MySQL数据库心跳检测

    option mysq1-check user haproxy

    server MySQL_1 172.22.0.2:3306 check weight 1 maxconn 2000

    server MySQL_2 172.22.0.3:3306 check weight 1 maxconn 2000

    server MySQL_3 172.22.0.4:3306 check weight 1 maxconn 2000

    #使用keepalive检测死链

    option tcpka

3、创建haproxy容器

docker run -d -p 8888:8888 -p 3306:3306 -v/tmp/haproxy:/usr /loca1/etc/haproxy --name haproxy01 --privileged --net=pxc-net haproxy

4、在MySQL数据库上创建用户,用于心跳检测

CREATE USER 'haproxy'@ '%’IDENTIFIED BY '';

5、win浏览器访问

http://centos_ip: 8888/dbs_monitor

用户名密码都是:admin

6、客户端连接王具连接

ip:centos_ip

(三)SpringBoot+Nginx+MySQL项目服务搭建

1、创建对应的网络

docker network create --subnet=172.24.0.0/24 sbm-net

docker netwoek ls

2、创建SpringBoot项目

通过SpringBoot项目整合MyBatis实现CRUD操作,属性文件中配置的jdbc信息为

#jdbc的相关配置信息

spring.datasource.driverC1assName=com.mysq1.cj.jdbc.Driver

spring.datasource.ur1=jdbc:mysql://192.168.56.10:3306/haproxy-test?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=false

spring.datasource.username=root

spring.datasource.password=123456

#连接池

spring.datasource.type=com.alibaba.druid.poo1.DruidDataSource

# mybatis给package设置别名

mybatis.type-aliases-package=com.bobo.pojo

#指定映射文件的位置

mybatis.mapper-locations=classpath:mapper/*.xm1

3、 对应的项目打成jar包,并上传到centos7中目录放在/tmp/springboot/下然后创建Dockerfile文带

yum install -y lrzsz

FROM openjdk:8

MAINTAINER zm2020

LABEL name="springboot-mybatis" version="1.O" author="zm2020"

COPY springboot-mybatis-demo-0.0.1-SNAPSHOT.jar springboot-mybatis.jar

CMD ["java" , "-jar " , "springboot-mybatis.jar"]

4、基于Dockerfile构建镜像

docker build -t sbm-image .

5、基于image创建container

docker run -d --name sb01 -p 8081:8080 --net=sbm-net --ip 172.24.0.11 sbm-image

快速访问

curl localhost:8081/user/query

6、查看启动日志

docker logs sb01

7、浏览器访问测试

http://IP:8081/user/query

8、创建多个容器

docker run -d --name sb01 -p 8081:8080 --net=pro-net --ip 172.24.0.11 sbm-image

docker run -d --name sb02 -p 8082:8080 --net=pro-net --ip 172.24.0.12 sbm-image

docker run -d --name sb03 -p 8083:8080 --net=pro-net --ip 172.24.0.13 sbm-image

9、Nginx安装

我们通过Nginx来实现负载均衡服务

在centos的/tmp/nginx下新建nginx.conf文件,并进行相应的配置

​
user nginx;

worker_processes 1;

events 

    worker_connections 1024;



http 

    include       /etc/nginx/mime.types;

    defau1t_type  application/octet-stream;

    sendfi1e      on;

    keepalive_timeout    65;

    server 
    
        listen 80;

        location / 

            proxy_pass http://balance;

        

    

    upstream balance

        server 172.24.0.11:8080;

        server 172.24.0.12:8080;

        server 172.24.0.13:8080;
    
    

    include /etc/nginx/conf.d/*.conf;

10、启动Nginx

docker run -d –name my-naginx -p 80:80 -v /tmp/nginx/nginx.conf:/etc/nginx/nginx.conf –network=sbm-net –ip 172.24.0.20 nginx

以上是关于[Docker]Namespace与Cgroups的主要内容,如果未能解决你的问题,请参考以下文章

Docker----LXC,chroot,namespace&cgroups

Docker在ubuntu和centos的安装

Docker之Linux Cgroups

Docker基础 Linux内核之Cgroups

Docker - Docker网络

Docker - Docker网络