Windows 使用 docker-compopse 报错 driver failed programming external connectivity

windows下使用docker的这个问题困扰我很久了,docker-compose 报错无法绑定相关的端口,重启docker也没有办法解决。

image-20200922124839628

解决的办法只有重启电脑或修改 docker-compose 中暴露的端口。不管哪种方式都非常的不灵活。

在Linux中其实也遇到过这样的问题,在docker正常运行后清除iptables也会得到类似的告警。这时候只要重启 docker 服务即可,相关的iptables链会重新生成,就没有问题了。

今天稍微查了相关资料,Windows下其实也是类似的做法,然而重启docker 应用并不能重启网络,这个就头疼的。最后解决的步骤如下:

  1. 停止相关应用

    docker-compose down
    
  2. 关闭docker服务。

    Close docker desktop.

    image-20200922125444744

  3. 任务管理器中杀死docker.service

    如下:

    68081121-b554ac80-fe43-11e9-9dd5-c09d59d38304

  4. 启动docker,会收到提示,运行docker服务。

    image-20200922125706615

    image-20200922125730931

  5. 启动应用

    docker-compose up -d
    
  6. 完成


kubernetes 准入策略 —— Kyverno

官方github地址:https://github.com/nirmata/kyverno

logo

做过运维的同学应该有过这种体会,假如我们维护了某些组件,这些组件所在的机器如果任由各个团队自己管理,一旦出问题定位很麻烦,没有人知道机器曾经发生了什么事。 这种场景同样适用于kubernetes集群运维。没有规矩不成方圆,而我们又没办法要求所有人的用户都能按照标准写yaml,要统一化集群环境:

  1. 要么我们将yaml收藏,只提供UI界面
  2. 要么我们在用户提交yaml前进行标准化验证,不符合标准的调整为标准的或拒绝运行

第一种办法未免过于粗暴,还是使用方法2。kubernetes 提供了 Admission Controller 对资源进行审查,我们可以基于 Admission Controller 进行开发完成我们的逻辑。

有需求就有市场! Kyverno 就是这样一个工具:

  • 验证资源:对资源定义进行检查,不符合条件的资源拒绝创建,从而保证集群资源的合规性。
  • 修改资源:在资源定义中进行注入,强制资源部分行为的一致性。
  • 生成资源:在资源创建时,同时创建相关的资源。

除了 Kyverno,cncf 也官宣了 Open Policy Agent (OPA) 用作 Kubernetes 准入控制器,个人感觉目前 OPA 过于灵活,并且目前还不支持generate和mutate,等待社区慢慢完善了。目前先使用 kyverno 解决手头的麻烦。

一、安装

kubectl create -f https://raw.githubusercontent.com/nirmata/kyverno/master/definitions/release/install.yaml

这是我当时的拉到的安装文件,做个备份https://cdn.kelu.org/blog/2020/08/kyverno.yaml

默认会安装在 kyverno 这个namespace下。

1598255025850

可以看到 kyverno 生成了很多crd和权限相关的资源。安装完成后,可以在 configmap 中修改不需要处理的资源类型,格式为:[<Kind>,<Namespace>,<Name>]

每个 kyverno policy 包含一个或者多个规则,每个规则都有一个matchexclude可选,以及一个mutatevalidategenerate

二、用法

常用命令:

经常要看事件来确定规则是否生效:

kubectl get events -A -w

查看已经配置的规则:

kubectl get ClusterPolicy
kubectl get cpol

快速生成pod:

kubectl run busybox --image=busybox  --restart=Never -- sleep 1000000

快速生成pod的yaml:

kubectl run busybox --image=busybox  --restart=Never --dry-run -o yaml  -- sleep 1000000 > pod.yaml

快速生成deployment:

kubectl create deployment nginx --image=nginx

hostpath:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: test
  name: test-hp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: test
  template:
    metadata:
      labels:
        app: test
    spec:
      volumes:
        - name: test-volume
          hostPath:
            path: /app/kelu/test-volume  
            type: ""
      containers:
      - image: nginx
        name: test-hp
        volumeMounts:
        - mountPath: /test-pd
          name: test-volume

三、实践

相关实践在官方GitHub上有详细解说,这里我记录其中的一部分,并做了一小部分调整。

1. 默认添加 namespace 的 quotas/limitrange

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: add-ns-quota
spec:
  rules:
  - name: generate-resourcequota
    match:
      resources:
        kinds:
        - Namespace
    generate:
      kind: ResourceQuota
      name: default-resourcequota
      namespace: ""
      data:
        spec:
          hard:
            requests.cpu: '1'
            requests.memory: '1Gi'
            limits.cpu: '1'
            limits.memory: '1Gi'
            persistentvolumeclaims: "20"
            requests.storage: 100Gi
            pods: "100"
            services: "100"
  - name: generate-limitrange
    match:
      resources:
        kinds:
        - Namespace
    generate:
      kind: LimitRange
      name: default-limitrange
      namespace: ""
      data:
        spec:
          limits:
          - default:
              cpu: 200m
              memory: 200Mi
            defaultRequest:
              cpu: 200m
              memory: 200Mi
            type: Container

2. pod必须包含 rquest 和 limit 才允许运行

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-pod-requests-limits
spec:
  validationFailureAction: enforce
  rules:
  - name: validate-resources
    match:
      resources:
        kinds:
        - Pod
    validate:
      message: "CPU and memory resource requests and limits are required"
      pattern:
        spec:
          containers:
          - resources:
              requests:
                memory: "?*"
                cpu: "?*"
              limits:
                memory: "?*"

3. 禁止绑定 docker sock

需要绑定的容器,得在kyverno生成的init-config里添加。

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: disallow-docker-sock-mount
spec:
  validationFailureAction: enforce
  rules:
  - name: validate-docker-sock-mount
    match:
      resources:
        kinds:
        - Pod
    validate:
      message: "Use of the Docker Unix socket is not allowed"
      pattern:
        spec:
          =(volumes):
            - =(hostPath):
                path: "!/var/run/docker.sock"

4. 禁止特权容器

因为默认不对 kube-system 进行应用,所以可以放心对所有容器禁止特权。

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: disallow-privileged
spec:
  validationFailureAction: enforce
  rules:
  - name: validate-privileged
    match:
      resources:
        kinds:
        - Pod
    validate:
      message: "Privileged mode is not allowed. Set privileged to false"
      pattern:
        spec:
          containers:
          - =(securityContext):
              =(privileged): false
  - name: validate-allowPrivilegeEscalation
    match:
      resources:
        kinds:
        - Pod
    validate:
      message: "Privileged mode is not allowed. Set allowPrivilegeEscalation to false"
      pattern:
        spec:
          containers:
          - securityContext:
              allowPrivilegeEscalation: false

使用 kind 低成本练习 kubernetes

kind 是一个使用 Docker 容器节点运行本地 Kubernetes 集群的工具(CLI)。最近在开发一些周边组件,急需一个集群进行验证,使用kind非常方便。这篇文章记录我使用的步骤。

一、安装

kind 就是一个二进制包,Linux mac Windows都可以快速安装:

Linux

curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.8.1/kind-linux-amd64 chmod +x ./kind mv ./kind /some-dir-in-your-PATH/kind

Mac

brew install kind

或者

curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.8.1/kind-darwin-amd64

Windows

curl.exe -Lo kind-windows-amd64.exe https://kind.sigs.k8s.io/dl/v0.8.1/kind-windows-amd64 Move-Item .\kind-windows-amd64.exe c:\some-dir-in-your-PATH\kind.exe

或者使用 Chocolatey (https://chocolatey.org/packages/kind)

choco install kind

二、使用

使用如下配置文件 kind.yaml

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
networking:
  # https://kind.sigs.k8s.io/docs/user/configuration/
  apiServerAddress: "10.19.0.54"
  apiServerPort: 888
nodes:
  - role: control-plane
    image: kindest/node:v1.17.5@sha256:ab3f9e6ec5ad8840eeb1f76c89bb7948c77bbf76bcebe1a8b59790b8ae9a283a
#featureGates:
#  FeatureGateName: true

这个配置文件中,我配置了单节点集群的 IP、apiserver 对外暴露的端口,k8s的版本 v1.17.

image相关信息来这里找:https://github.com/kubernetes-sigs/kind/releases

创建集群:

kind create cluster --config kind.yaml

> kind create cluster
Creating cluster "kind" ...
 ✓ Ensuring node image (kindest/node:v1.17.5) 🖼
 ✓ Preparing nodes 📦
 ✓ Writing configuration 📜
 ✓ Starting control-plane 🕹️
 ✓ Installing CNI 🔌
 ✓ Installing StorageClass 💾
Set kubectl context to "kind-kind"
You can now use your cluster with:kubectl cluster-info --context kind-kind Have a nice day! 👋

如果你集群恰好使用了 同版本的 kubectl,可以使用下面命令行在宿主机快速操作k8s:

kubectl cluster-info --context kind-kind 

不同版本的kubectl 会导致意外的。当然,你还有其他方式进行操作:

命令行使用

进入主容器:

docker exec -it kind-control-plane /bin/bash

配置kubectl:

export KUBECONFIG=/etc/kubernetes/admin.conf

可以直接操作了!

ui界面使用(lens)

查看kind的相关命令:

kind -h

kind获得配置:

kind get kubeconfig --name xxx # 如果是默认名字kind,不需要--name

将配置写入lens配置界面配置:

1598253646399

完成!界面如下所示。

1598253691029

获得一个简单容器的 yaml:

kubectl run busybox --image=busybox  --restart=Never --dry-run -o yaml  -- sleep 1000000 > pod.yaml

得到 pod.yaml :


apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: busybox
  name: busybox
spec:
  containers:
  - args:
    - sleep
    - "1000"
    image: busybox
    imagePullPolicy: IfNotPresent
    name: busybox
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Never
status: {}

运行:

kubectl apply -f pod.yaml

浅谈人工智能:现状、任务、构架与统一 - 朱松纯

原文链接:http://www.stat.ucla.edu/~sczhu/Blog_articles/浅谈人工智能.pdf

朱松纯

加州大学洛杉矶分校UCLA

统计学和计算机科学教授

视觉、认知、学习与自主机器人中心主任

VCLA@UCLA

2017年11月02日 刊登于 《视觉求索》微信公众号

img

目录

引言

第一节 现状:正视现实

第二节 未来:一只乌鸦给我们的启示

第三节 历史:从“春秋五霸”到“战国六雄”

第四节 统一:“小数据、大任务”范式与认知构架

第五节 学科一:计算视觉 — 从“深”到“暗”

第六节 学科二:认知推理 — 走进内心世界

第七节 学科三:语言通讯 — 沟通的认知基础

第八节 学科四:博弈伦理 — 获取、共享人类的价值观

第九节 学科五:机器人学 — 构建大任务平台

第十节 学科六:机器学习 — 学习的终极极限与“停机问题”

第十一节 总结: 智能科学 — 牛顿与达尔文的统一

附录 中科院自动化所报告会上的问答与互动摘录

鸣谢

引言

“人工智能”这个名词在沉寂了近30年之后,最近两年“咸鱼翻身”,成为了科技公司公关的战场、网络媒体吸睛的风口,随后受到政府的重视和投资界的追捧。于是,新闻发布会、高峰论坛接踵而来,政府战略规划出台,各种新闻应接不暇,宣告一个“智能为王”时代的到来。

到底什么是人工智能?现在的研究处于什么阶段?今后如何发展?这是大家普遍关注的问题。由于人工智能涵盖的学科和技术面非常广,要在短时间内全面认识、理解人工智能,别说非专业人士,就算对本行业研究人员,也是十分困难的任务。

所以,现在很多宣传与决策冲到认识之前了,由此不可避免地造成一些思想和舆论的混乱。

自从去年用了微信以来,我就常常收到亲朋好友转来的惊世骇俗的新闻标题。我发现很多议论缺乏科学依据,变成了“娱乐AI”。一个在1970年代研究黑洞的物理学博士,从来没有研究过人工智能,却时不时被抬出来预测人类末日的到来。某些公司的公关部门和媒体发挥想象力,动辄把一些无辜的研究人员封为“大师”、“泰斗”。最近,名词不够用了。九月初,就有报道把请来的一位美国教授称作“人工智能祖师爷”。这位教授的确是机器学习领域的一个领军人物,但人工智能是1956年开始的,这位教授也才刚刚出生。况且机器学习只是人工智能的一个领域而已,大部分其它重要领域,如视觉、语言、机器人,他都没有涉足,所以这样的封号很荒唐(申明一点:我对这位学者本人没有意见,估计他自己不一定知道这个封号)。当时我想,后面是不是有人会搬出“达摩老祖、佛祖如来、孔雀王、太上老君、玉皇大帝”这样的封号。十月初,赫然就听说达摩院成立了,宣称要碾压美国,舆情轰动!别说一般老百姓担心丢饭碗,就连一些业内的研究人员都被说得心慌了,来问我有什么看法。

我的看法很简单:大多数写报道和搞炒作宣传的人,基本不懂人工智能。这就像年轻人玩的传话游戏,扭曲的信息在多次传导过程中,逐级放大,最后传回来,自己吓到自己了。下面这个例子就说明公众的误解到了什么程度。今年9月我在车上听到一家电台讨论人工智能。两位主持人谈到硅谷脸书公司,有个程序员突然发现,两台电脑在通讯过程中发明了一种全新的语言,快速交流,人看不懂。眼看一种“超级智能”在几秒之内迅速迭代升级(我加一句:这似乎就像宇宙大爆炸的前几秒钟),程序员惊恐万状。人类现在只剩最后一招才能拯救自己了:“别愣着,赶紧拔电源啊!…”终于把人类从鬼门关又拉回来了。

回到本文的正题。全面认识人工智能之所以困难,是有客观原因的。

其一、人工智能是一个非常广泛的领域。当前人工智能涵盖很多大的学科,我把它们归纳为六个:

(1)计算机视觉(暂且把模式识别,图像处理等问题归入其中)、

(2)自然语言理解与交流(暂且把语音识别、合成归入其中,包括对话)、

(3)认知与推理(包含各种物理和社会常识)、

(4)机器人学(机械、控制、设计、运动规划、任务规划等)、

(5)博弈与伦理(多代理人agents的交互、对抗与合作,机器人与社会融合等议题)。

(6)机器学习(各种统计的建模、分析工具和计算的方法),

这些领域目前还比较散,目前它们正在交叉发展,走向统一的过程中。我把它们通俗称作“战国六雄”,中国历史本来是“战国七雄”,我这里为了省事,把两个小一点的领域:博弈与伦理合并了,伦理本身就是博弈的种种平衡态。最终目标是希望形成一个完整的科学体系,从目前闹哄哄的工程实践变成一门真正的科学Science of Intelligence。

由于学科比较分散,从事相关研究的大多数博士、教授等专业人员,往往也只是涉及以上某个学科,甚至长期专注于某个学科中的具体问题。比如,人脸识别是计算机视觉这个学科里面的一个很小的问题;深度学习属于机器学习这个学科的一个当红的流派。很多人现在把深度学习就等同于人工智能,就相当于把一个地级市说成全国,肯定不合适。读到这里,搞深度学习的同学一定不服气,或者很生气。你先别急,等读完后面的内容,你就会发现,不管CNN网络有多少层,还是很浅,涉及的任务还是很小。

各个领域的研究人员看人工智能,如果按照印度人的谚语可以叫做“盲人摸象”,但这显然是言语冒犯了,还是中国的文豪苏轼游庐山时说得有水准:

“横看成岭侧成峰,远近高低各不同

不识庐山真面目,只缘身在此山中。”

其二,人工智能发展的断代现象。由于历史发展的原因,人工智能自1980年代以来,被分化出以上几大学科,相互独立发展,而且这些学科基本抛弃了之前30年以逻辑推理与启发式搜索为主的研究方法,取而代之的是概率统计(建模、学习)的方法。留在传统人工智能领域(逻辑推理、搜索博弈、专家系统等)而没有分流到以上分支学科的老一辈中,的确是有很多全局视野的,但多数已经过世或退休了。他们之中只有极少数人在80-90年代,以敏锐的眼光,过渡或者引领了概率统计与学习的方法,成为了学术领军人物。而新生代(80年代以后)留在传统人工智能学科的研究人员很少,他们又不是很了解那些被分化出去的学科中的具体问题。

这种领域的分化与历史的断代, 客观上造成了目前的学界和产业界思路和观点相当“混乱”的局面,媒体上的混乱就更放大了。但是,以积极的态度来看,这个局面确实为现在的年轻一代研究人员、研究生提供了一个很好的建功立业的机会和广阔的舞台。

鉴于这些现象,《视觉求索》编辑部同仁和同行多次催促我写一篇人工智能的评论和介绍材料。我就免为其难,仅以自己30年来读书和跨学科研究的经历、观察和思辨,浅谈什么是人工智能;它的研究现状、任务与构架;以及如何走向统一。

我写这篇文章的动机在于三点:

(1)为在读的研究生们、为有志进入人工智能研究领域的年轻学者开阔视野。

(2)为那些对人工智能感兴趣、喜欢思考的人们,做一个前沿的、综述性的介绍。

(3)为公众与媒体从业人员,做一个人工智能科普,澄清一些事实。

本文来历: 本文技术内容选自我2014年来在多所大学和研究所做的讲座报告。2017年7月,微软的沈向洋博士要求我在一个朋友聚会上做一个人工智能的简介,我增加了一些通俗的内容。2017年9月,在谭铁牛和王蕴红老师的要求下,我参加了中科院自动化所举办的人工智能人机交互讲习班,他们派速记员和一名博士生整理出本文初稿。如果没有他们的热情帮助,这篇文章是不可能写成的。原讲座两个半小时,本文做了删减和文字修饰。仍然有四万字,加上大量插图和示例。很抱歉,无法再压缩了。

本文摘要:文章前四节浅显探讨什么是人工智能和当前所处的历史时期,后面六节分别探讨六个学科的重点研究问题和难点,有什么样的前沿的课题等待年轻人去探索,最后一节讨论人工智能是否以及如何成为一门成熟的科学体系。

诚如屈子所言:“路漫漫其修远兮,吾将上下而求索”。

第一节 现状评估:正视现实

人工智能的研究,简单来说,就是要通过智能的机器,延伸和增强(augment)人类在改造自然、治理社会的各项任务中的能力和效率,最终实现一个人与机器和谐共生共存的社会。这里说的智能机器,可以是一个虚拟的或者物理的机器人。与人类几千年来创造出来的各种工具和机器不同的是,智能机器有自主的感知、认知、决策、学习、执行和社会协作能力,符合人类情感、伦理与道德观念。

抛开科幻的空想,谈几个近期具体的应用。无人驾驶大家听了很多,先说说军用。军队里的一个班或者行动组,现在比如要七个人,将来可以减到五个人,另外两个用机器来替换。其次,机器人可以用在救灾和一些危险的场景,如核泄露现场,人不能进去,必须靠机器人。医用的例子很多:智能的假肢或外骨架(exoskeleton)与人脑和身体信号对接,增强人的行动控制能力,帮助残疾人更好生活。此外,还有就是家庭养老等服务机器人等。

img

但是,这方面的进展很不尽人意。以前日本常常炫耀他们机器人能跳舞,中国有一次春节晚会也拿来表演了。那都是事先编写的程序,结果一个福岛核辐射事故一下子把所有问题都暴露了,发现他们的机器人一点招都没有。美国也派了机器人过去,同样出了很多问题。比如一个简单的技术问题,机器人进到灾难现场,背后拖一根长长的电缆,要供电和传数据,结果电缆就被缠住了,动弹不得。有一次,一位同事在餐桌上半开玩笑说,以现在的技术,要让一个机器人长时间像人一样处理问题,可能要自带两个微型的核电站,一个发电驱动机械和计算设备,另一个发电驱动冷却系统。顺便说一个,人脑的功耗大约是10-25瓦。

看到这里,有人要问了,教授说得不对,我们明明在网上看到美国机器人让人叹为观止的表现。比如,这一家波士顿动力学公司(Boston Dynamics)的演示,它们的机器人,怎么踢都踢不倒呢,或者踢倒了可以自己爬起来,而且在野外丛林箭步如飞呢,还有几个负重的电驴、大狗也很酷。这家公司本来是由美国国防部支持开发出机器人来的,被谷歌收购之后、就不再承接国防项目。可是,谷歌发现除了烧钱,目前还找不到商业出路,最近一直待售之中。您会问,那谷歌不是很牛吗?DeepMind下围棋不是也一次次刺激中国人的神经吗?有一个逆天的机器人身体、一个逆天的机器人大脑,它们都在同一个公司内部,那为什么没有做出一个人工智能的产品呢?他们何尝不在夜以继日的奋战之中啊。


linux run 目录满了,100%

服务器创建不了容器!

检查发现服务器 /run 100%。但是我真的不知道这意味着什么。

往常我都是直接重启了事。今天搜了一下,发现了应该是 journal 引起的,可用这个命令可以解决:

udevadm info --cleanup-db

参考资料


那些实现 Docker 的底层 Linux 技术

Docker 是现在最流行的虚拟化技术,解决了棘手的机器资源共享的问题,同时不需要特别了解原理也能轻松上手,所以自问世之后就不断蔓延开来。作为从业人员,为了对底层进行一定的修改,就不得不了解与它相关的技术。这篇文章我整理了相关的资料做个备忘。由于血衫的技术能力有限,如果有错误的地方,也请大家指正。

一、关于docker

Docker 技术使用 Linux内核 和内核功能(例如 Cgroupsnamespace)来隔离进程,以便它们可以独立运行。这种独立性使得我们更好地管理应用程序,同时又保留了单独系统所具有的安全性

1. docker和Linux容器的区别

docker和 传统的Linux容器是不相同的。

容器技术最初是建立在 LXC 技术上的。LXC是轻量级的虚拟化。LXC起源于cgroup和namespaces,使得进程之间相互隔离,即进程虚拟化。

img

如上图示意,LXC是一种基于容器的操作系统层级的虚拟化技术,包含了完整的操作系统。LXC 真正的实现是靠 Linux 内核的相关特性,LXC项目对此做了整合,可以

  • 为容器绑定特定的cpu和memory节点
  • 分配特定比例的cpu时间、IO时间
  • 限制可以使用的内存大小(包括内存和是swap空间)
  • 提供device访问控制
  • 提供独立的namespace(网络、pid、ipc、mnt、uts)

Docker 容器将应用和其依赖环境全部打包到一个单一对象中,在不包含完整的操作系统的情况下就能运行普通应用,更加轻量级,可移植性更好。Docker是一个应用程序容器,在2014年6月召开的 DockerCon 2014 技术大会上,吸引了 IBM、Google、RedHat 等业界知名公司的关注和技术支持。无论是从 GitHub 上的代码活跃度,还是开源巨头红帽宣布在 RHEL7 中正式支持 Docker 技术,都可以说明 Docker 技术是一项创新型的技术解决方案,就连 Google 公司的 Compute Engine 也很快支持 Docker 在其之上运行。国内 BATJ也相继推出容器服务紧追云计算发展趋势。

Docker 技术解决以下问题:

  • 复杂的环境配置管理:从各种 OS 环境到各种中间件环境以及各种应用环境。

    img

  • 新的软件管理方法:云计算时代的到来,解决了硬件管理的问题,然而软件配置和管理相关的问题依然存在。

  • 虚拟化手段的变化:云时代无论是 KVM 还是 Xen,在 Docker 看来都在浪费资源,因为用户需要的是高效运行环境而非 OS,GuestOS 既浪费资源又难于管理,轻量级的 LXC 更加灵活和快速。

    img

  • 容器技术的便携性。LXC 在 Linux2.6 的 Kernel 里就已经存在了,但是其设计之初并非为云计算考虑的,缺少标准化的描述手段和容器的可便携性,决定其构建出的环境难于分发和标准化管理(相对于 KVM 之类 image 和 snapshot 的概念)。Docker 就在这个问题上做出了实质性的创新方法。

2. Docker底层技术

早期Docker用LXC(Linux Container)做底层,所以LXC中使用到的技术,Docker基本也都使用了。 namespace,cgroup,chroot,UnionFS都用到了。【前两个是内核特性】

  • namespace:用于资源隔离,通过使用独立的namespace来实现进程隔离,网络隔离,挂载隔离(文件隔离)等。
  • cgroup:用于资源限制,对一组进程的cpu/内存/网络/IO等资源进行分配限制。
  • UnionFS:AUFS是一种联合文件系统(UnionFS),可以将多个目录合并 再mount到一个目录上。DockerFile 镜像分层结构具体就是利用了AUFS的特性。每一层都是一个目录。镜像的构建过程可以简单理解为将多个目录进行合并【Docker支持众多UnionFS,AUFS只是其中一种。】

二、Linux namespace

每个用户实例之间相互隔离,互不影响。一般的硬件虚拟化方法给出的方法是 VM,而 LXC 给出的方法是 container,更细一点讲就是 kernel namespace。其中 pid、net、ipc、mnt、uts、user 等 namespace 将 container 的进程、网络、消息、文件系统、UTS(“UNIX Time-sharing System”)和用户空间隔离开。

Linux 的命名空间机制提供了以下七种不同的命名空间,包括

  • CLONE_NEWCGROUP
  • CLONE_NEWIPC
  • CLONE_NEWNET
  • CLONE_NEWNS
  • CLONE_NEWPID
  • CLONE_NEWUSER
  • CLONE_NEWUTS

通过这七个选项我们能在创建新的进程时设置新进程应该在哪些资源上与宿主机器进行隔离。

pid namespace

不同用户的进程就是通过 pid namespace 隔离开的,且不同 namespace 中可以有相同 pid。所有的 LXC 进程在 Docker中的父进程为 Docker 进程,每个 lxc 进程具有不同的 namespace。同时由于允许嵌套,因此可以很方便的实现 Docker in Docker。

net namespace

有了 pid namespace,每个 namespace 中的 pid 能够相互隔离,但是网络端口还是共享 host 的端口。网络隔离是通过 net namespace 实现的,每个 net namespace 有独立的 network devices,IP addresses,IP routing tables,/proc/net 目录。这样每个 container 的网络就能隔离开来。Docker 默认采用 veth 的方式将 container 中的虚拟网卡同 host 上的一个 docker bridge:docker0连接在一起。

ipc namespace

container 中进程交互还是采用 linux 常见的进程间交互方法(interprocess communication - IPC),包括常见的信号量、消息队列和共享内存。然而同 VM 不同的是,container 的进程间交互实际上还是 host 上具有相同 pid namespace 中的进程间交互,因此需要在 IPC 资源申请时加入 namespace 信息——每个 IPC 资源有一个唯一的32位 ID。

mnt namespace

类似 chroot,将一个进程放到一个特定的目录执行。mnt namespace 允许不同 namespace 的进程看到的文件结构不同,这样每个 namespace 中的进程所看到的文件目录就被隔离开了。同 chroot 不同,每个 namespace 中的 container 在/proc/mounts 的信息只包含所在 namespace 的 mount point。

uts namespace

UTS(“UNIX Time-sharing System”)namespace 允许每个 container 拥有独立的 hostname 和 domain name,使其在网络上可以被视作一个独立的节点而非 Host 上的一个进程。

user namespace

每个 container 可以有不同的 user 和 group id,也就是说可以在 container 内部用 container 内部的用户执行程序而非 Host 上的用户。

三、Linux cgroup

cgroups 实现了对资源的配额和度量。 cgroups 的使用非常简单,提供类似文件的接口,在/cgroup 目录下新建一个文件夹即可新建一个 group,在此文件夹中新建 task 文件,并将pid 写入该文件,即可实现对该进程的资源控制。groups 可以限制 blkio、cpu、cpuacct、cpuset、devices、freezer、memory、net_cls、ns 九大子系统的资源,以下是每个子系统的详细说明:

  1. 有序列表 blkio 这个子系统设置限制每个块设备的输入输出控制。例如:磁盘,光盘以及 usb 等等。
  2. cpu 这个子系统使用调度程序为 cgroup 任务提供 cpu 的访问。
  3. cpuacct 产生 cgroup 任务的 cpu 资源报告。
  4. cpuset 如果是多核心的 cpu,这个子系统会为 cgroup 任务分配单独的 cpu 和内存。
  5. devices 允许或拒绝 cgroup 任务对设备的访问。
  6. freezer 暂停和恢复 cgroup 任务。
  7. memory 设置每个 cgroup 的内存限制以及产生内存资源报告。
  8. net_cls 标记每个网络包以供 cgroup 方便使用。
  9. ns 名称空间子系统。

以上九个子系统之间也存在着一定的关系。详情请参阅官方文档。