Linux namespace技术
namespace是Linux系统的底层概念,在内核层实现,即有一些不同类型的命名空间被部署在核内,docker容器运行在docker主进程下边,共用Linux内核,各docker容器运行在类似于虚拟机一样的相互隔离的运行空间,还可以保证宿主机内核不受其他进程的干扰和影响,目前有以下容器运行空间的相互隔离:
隔离类型 | 功能 | 系统调用参数 | 内核版本 |
---|---|---|---|
MNT Namespace(mount) | 提供磁盘挂载点和文件系统的隔离能力 | CLONE_NEWNS | Linux 2.4.19 |
IPC Namespace(Inter-Process Communication) | 提供进程间通信的隔离能力 | CLONE_NEWIPC | Linux 2.6.19 |
UTS Namespace(UNIX Timesharing System) | 提供主机名隔离能力 | CLONE_NEWUTS | Linux 2.6.19 |
PID Namespace(Process Identification) | 提供进程隔离能力 | CLONE_NEWPID | Linux 2.6.24 |
Net Namespace(network) | 提供网络隔离能力 | CLONE_NEWNET | Linux 2.6.29 |
User Namespace(user) | 提供用户隔离能力 | CLONE_NEWUSER | Linux 3.8 |
MNT Namespace:可以通过chroot把容器锁定到一个指定的运行目录里边。
IPC Namespace:允许一个容器内的不同进程的(内存、缓存等)数据访问,不允许跨容器访问其他容器的数据。
UTS Namespace:使容器拥有属于自己的hostname标识,这个主机名标识独立于宿主机系统和其上的其他容器。
PID Namespace:进程隔离,使多个容器的进程通过PID Namespace进行隔离。
Net Namespace:给每个容器分配一个独立的虚拟网卡。
User Namespace:容器内用户和用户组隔离,不同容器都可以出现同名的用户和用户组不会互相影响。
Linux control groups:cgroup可以进行资源限制,对CPU、内存、磁盘、网络等进行限制,还可以对进程进行优先级设置,以及将进程挂起和回复等操作,cgroup可以对容器进行限制,防止容器过度占用资源。
编排工具
容器早期有使用lxc,但目前主要使用docker,所以只总结一下docker。
docker启动容器需要镜像,而镜像是分层的,镜像的最顶层是可写层,docker对外提供服务的时候必然会写入数据,可写层就是用来写入数据的,可写层以下都是只读层,只读层有很多层,比方说一个nginx镜像,最底层是基础的库文件,往上一层是nginx程序,再往上一层是可写层,可以写入数据。
容器 runtime
runtime是真正运行容器的地方,因此为了运行不同的容器 runtime 需要和操作系统内核紧密合作相互在支持,以便为容器提供相应的运行环境。
目前主流的三种 runtime:
Lxc:linux 上早期的 runtime,Docker 早期就是采用 lxc 作为 runtime。
runc:目前 Docker 默认的 runtime,runc 遵守 OCI 规范,因此可以兼容 lxc。
rkt:是 CoreOS 开发的容器 runtime,也符合 OCI 规范,所以使用 rktruntime也可以运行 Docker 容器
容器镜像
OCI 容器镜像主要包含以下内容:
manifest 文件:描述有哪些 layer,tag 标签及 config 文件名称。
config 文件:是一个以hash命名的json文件,保存了镜像平台,容器运行时容器运行时需要的一些信息,比如环境变量、工作目录、命令参数等。
index 文件:可选的文件,指向不同平台的
manifest 文件,这个文件能保证一个镜 像可以跨平台使用,每个平台拥有不同的
manifest 文件使用 index 作为索引。
父镜像:大多数层的元信息结构都包含一个parent 字段,指向该镜像的父镜像。
参数:
ID:镜像 ID,每一层都有 ID
tag 标签:标签用于将用户指定的、具有描述性的名称对应到镜像 ID
仓库:Repository 镜像仓库
os:定义类型
architecture :定义 CPU 架构
author:作者信息
create:镜像创建日期
容器管理工具:
lxc 是 lxd 的管理工具。
Runc 的管理工具是docker engine,docker engine包含后台deamon和cli两部分,大家经常提到的Docker就是指的docker engine。
Rkt 的管理工具是 rkt cli。
容器定义工具
Docker image:是docker容器的模板,runtime依据docker image创建容器。
Dockerfile:包含 N 个命令的文本文件,通过dockerfile创建出docker image。
ACI(App container image):与docker image类似,是CoreOS开发的rkt容器的镜像格式。
Registry:
统一保存镜像而且是多个不同镜像版本的地方,叫做镜像仓库。
Image registry:docker官方提供的私有仓库部署工具。
Docker hub:docker 官方的公共仓库,已经保存了大量的常用镜像,可以方便大家直接使用。
Harbor:vmware 提供的自带 web 界面自带认证功能的镜像仓库,目前有很多公司使用。
编排工具
当多个容器在多个主机运行的时候,单独管理容器是相当复杂而且很容易出错,而且也无法实现某一台主机宕机后容器自动迁移到其他主机从而实现高可用的目的,也无法实现动态伸缩的功能,因此需要有一种工具可以实现统一管理、动态伸缩、故障自愈、批量执行等功能,这就是容器编排引擎。
容器编排通常包括容器管理、调度、集群定义和服务发现等功能。
Docker swarm:docker 开发的容器编排引擎。
Kubernetes:google 领导开发的容器编排引擎,内部项目为 Borg,且其同时支持 docker 和 CoreOS。
Mesos+Marathon:通用的集群组员调度平台,mesos(资源分配)与 marathon(容器编排平台)一起提供容器编排引擎功能。
docker(容器)的依赖技术:
容器网络:
docker 自带的网络 docker network 仅支持管理单机上的容器网络,当多主机运行的时候需要使用第三方开源网络,例如 calico、flannel 等
服务发现:
容器的动态扩容特性决定了容器 IP 也会随之变化,因此需要有一种机制可以自动识别并将用户请求动态转发到新创建的容器上,kubernetes 自带服务发现功能,需要结合 kube-dns服务解析内部域名。
容器监控:
可以通过原生命令 docker ps/top/stats 查看容器运行状态,另外也可以使heapster/ Prometheus 等第三方监控工具监控容器的运行状态。
数据管理:
容器的动态迁移会导致其在不同的 Host 之间迁移,因此如何保证与容器相关的数据也能随之迁移或随时访问,可以使用逻辑卷/存储挂载等方式解决。
日志收集:
docker 原生的日志查看工具 docker logs,但是容器内部的日志需要通过 ELK等专门的日志收集分析和展示工具进行处理。
docker常用命令
docker login 登录镜像仓库
docker pull 拉取镜像
docker pull nginx
docker push 推送镜像
docker push nginx
docker images 查看已下载镜像
docker run 启动容器
docker run -d –name web1 -p 80:80 nginx
docker ps 查看已启动镜像
docker ps -a 查看所有容器包括停止的
docker rm 删除容器
docker rmi 删除镜像
docker save nginx > nginx.tar 将镜像保存到本地文件并命名为nginx.tar
docker load -I nginx.tar 将本地镜像文件nginx.tar加载到docker上
基于dockerfile制作一个nginx镜像
docker pull centos
mkdir dockerfile/nginx && cd dockerfile/nginx
vim Dockerfile
#写入如下内容
#nginx
#定义基础镜像
FROM centos:latest
#定义镜像为护着信息
LABEL maintainer="study 123@study.com"
#安装yum源
ADD epel-release-latest-8.noarch.rpm /root/
RUN cd /root && rpm -ivh epel-release-latest-8.noarch.rpm
RUN rm -rf /etc/yum.repos.d/Cent*
ADD CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo
#安装基础软件包
RUN yum install -y vim wget tree lrzsz gcc gcc-c++ make automake pcre pcre-devel zlib zlib-devel openssl openssl-devel iproute net-tools iotop
#添加nginx源码到镜像并解压
ADD nginx-1.20.2.tar.gz /usr/local/src
#编译nginx
RUN cd /usr/local/src/nginx-1.20.2/ && ./configure --prefix=/usr/local/nginx --with-http_sub_module && make && make install
RUN cd /usr/local/nginx
#修改配置文件,将root目录设置为/data/html,开启nginx前台运行功能
ADD nginx.conf /usr/local/nginx/conf/nginx.conf
RUN ln -sv /usr/local/nginx/sbin/nginx /usr/sbin/nginx
RUN mkdir -p /data/html && echo 'hello-world' > /data/html/index.html
RUN echo nginx > /root/nginx.sh && chmod +x /root/nginx.sh
EXPOSE 80 443
ENTRYPOINT ["nginx"]
docker build -t nginx:v1 .
docker run -itd --name nginx -p 80:80 nginx:v1
然后访问宿主机IP就可以看到测试内容
搭建配置harbor私有仓库
#下载harbor离线安装包
https://github.com/goharbor/harbor/releases/download/v2.7.1/harbor-offline-installer-v2.7.1.tgz
#解压
tar xf harbor-offline-installer-v2.7.1.tgz
#更改配置文件
cp harbor.yml.tmpl harbor.yml
vim harbor.yml
#执行安装脚本
。/install.sh
docker网络
docker在安装完成后会生成一个名为docker0的网卡,IP为172.17.0.1/16,并且会生成三种不同的网络,如下
第一个bridge类型,容器内会生成一个新网卡,这个网卡会和docker0创建网桥
第二个host类型,使用这个类型容器会和主机共享网卡和端口
第三个none类型,容器内只有一个回环网卡,用于不需要网络的环境
安装docker-compose,并创建多容器服务
yum install -y python39-pip
pip install docker-compose
#前提
一个可以转发的nginx
一个tomcat
#写一个docker-compose文件
tomcat-web:
image: tomcat
container_name: tomcat-app1
expose:
- 8080
nginx-web:
image: nginx:v1
container_name: nginx-app1
expose:
- 80
- 443
ports:
- "88:80"
- "443:443"
links:
- tomcat-web
#启动容器
docker-compose up -d
查看结果