sealer,“集群”版本的 Docker,交付复杂度的终结者

VSole2022-08-03 16:18:09

背景

随着时代的发展,单机上跑的单体应用已经越来越少了,分布式应用几乎已经无处不在。Docker 很好的对单机应用进行了镜像化的封装,实现在单机上 Build Ship Run, 从此单机上应用的运行没有什么是一个 docker run 解决不了的。

docker 对比 rpm 之类的工具显然一致性好很多,原因是 docker 把 rootfs 同样封装到了镜像之中,也就是所有的依赖都在镜像中。

再看集群和分布式应用,以前 IaaS 主导的云计算只对资源进行了抽象,显然一个操作系统是承上启下的作用,向上需要有很好的应用管理能力,kubernetes 很符合这一定义。

所以现在假设 kubernetes 是管理所有服务器的操作系统,在这个前提下我们要设计一个 “集群” 版本的 Docker,这就是我们今天的主角 sealer

目前 sealer 也捐献给了 CNCF 基金会,项目地址:https://github.com/sealerio/sealer

(点击文末阅读原文可直接跳转哦~)

快速开始

联想一下 Docker 我们需要启动一个 centos 容器:

docker run centos

所以要用 sealer 启动一个 kubernetes 集群,只需要:

sealer run kubernetes:v1.19.8 \
    --masters 192.168.0.2,192.168.0.3,192.168.0.4 \
    --nodes 192.168.0.5,192.168.0.6,192.168.0.7 --passwd xxx

这样一个六节点的集群就起来了,当然 sealer 同样支持单节点。

同理,我们可以运行分布式软件如:

sealer run mysql-cluster:8.0
sealer run redis:5.0

各种分布式软件一键安装交付。

交付的痛点

想象没有 sealer 交付的故事是什么样的?假设你已经使用了 kubernetes helm 这些工具,当然没使用的只会比以下步骤更痛苦。

  1. 找一个能在离线环境中安装 kubernetes 本身的工具
  2. 加载你事先打包好的所有 docker 镜像
  3. 启动一个私有镜像仓库
  4. 把所有镜像推送到私有镜像仓库中
  5. 修改编排文件中镜像仓库地址
  6. 执行所有的 helm chart

而使用 sealer 交付故事是:

  1. 加载集群镜像
  2. sealer run [集群镜像]

如果的交付文档很长,整个交付面向过程,那就很适合使用 sealer,可以在整个集群一致性上保证交付成功。

那么如何去构建一个自定义的集群镜像呢?

Build 集群镜像

sealer 运行分布式应用很简单,同样要去自定义一个集群镜像也需要很简单,这里采用与 Docker 镜像几乎相同的方式进行构建。

这里以构建一个 dashboard 的集群镜像为例子:

  1. 编写一个类似 Dockerfile 的文件,我们叫 Kubefile
FROM kubernetes:v1.19.8
RUN wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.2.0/aio/deploy/recommended.yaml
CMD kubectl apply -f recommended.yaml

第一行 FROM kubernetes:v1.19.8 可以选择你想要的基础镜像。

RUN 指令只会在 Build 的时候执行,去下载 dashboard 的 yaml 文件。

CMD 指令会在集群启动后执行,所以这里并不关心用户使用什么编排工具,比如 sealer 可以很好的与 helm 搭配使用。

  1. build
sealer build -t dashboard:latest .

这里 sealer 不仅只是把 RUN 命令执行了一下,还会去扫描里面包含的所有 docker 镜像并缓存到集群镜像中,这样启动的时候会直接从缓存的私有镜像仓库中去下载镜像。

  1. Run
sealer run dashboard:latest --masters 192.168.0.2 --passwd xxx
kubectl get pod -A|grep dashboard

现在我们就可以运行这个集群镜像,sealer 会先拉起一个 kubernetes 集群,再在其上面部署 dashboard。

这里神奇的地方是虽然 dashboard 编排文件里面写的是 gcr 仓库的镜像地址,sealer 并不会从公网去拉取,而会检测私有镜像仓库是是否存在该镜像,有的话直接从私有镜像仓库中拉取。如此 即便在离线环境中也可以正常拉到镜像,而且整个过程什么也不需要修改。

  1. Push
sealer push registry.cn-qingdao.aliyuncs.com/sealer-io/dashboard:latest

可以把刚才的集群镜像 push 到任意的 registry 中,比如 docker hub。

配置管理

看到上面你可能会感觉确实简单,但是功能好像不太满足,因为一次交付,几乎会有非常多的配置文件需要管理与调整,这在 sealer 里面如何处理?

sealer 对这块的设计也有充分考虑,答案是使用 Clusterfile。

Clusterfile 说白了是就告诉 sealer 启动整个集群需要的配置是怎样的。

apiVersion: sealer.cloud/v2
kind: Cluster
metadata:
  name: default-kubernetes-cluster
spec:
  image: kubernetes:v1.19.8
  ssh:
    passwd: xxx
  hosts:
    - ips: [ 192.168.0.2,192.168.0.3,192.168.0.4 ]
      roles: [ master ]
    - ips: [ 192.168.0.5 ]
      roles: [ node ]

sealer apply -f Clusterfile 即可启动整个集群。

常见需求,比如想修改一个 podsubnet, sealer 支持 merge 所有 kubeadm 配置文件:

---
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
networking:
  podSubnet: 100.64.0.0/10

你不需要把所有配置写全,只需要写你关心的字段,会自动合并到默认配置中。

业务配置使用更通用的做法:

---
apiVersion: sealer.aliyun.com/v1alpha1
kind: Config
metadata:
  name: mysql-config
spec:
  path: etc/mysql.yaml
  data: |
       mysql-user: root
       mysql-passwd: xxx

data 里面的内容会覆盖镜像内部的 path, 指定的文件,同样支持是直接覆盖还是合并等一些策略,那么这里的内容就很适合是 helm values.

sealer 同样支持用环境变量管理少量配置:

apiVersion: sealer.cloud/v2
kind: Cluster
metadata:
  name: my-cluster
spec:
  image: kubernetes:v1.19.8
  env:
    docker-dir: /var/lib/docker
  hosts:
    - ips: [ 192.168.0.2 ]
      roles: [ master ] # add role field to specify the node role
      env: # overwrite some nodes has different env config
        docker-dir: /data/docker
    - ips: [ 192.168.0.3 ]
      roles: [ node ]

镜像内部的脚本就可以直接使用 docker-dir 环境变量:

#!/bin/bash
echo $docker-dir

插件机制

插件可以帮助用户做一些之外的事情,比如更改主机名,升级内核,或者添加节点标签等……

主机名插件

如果你在 Clusterfile 后添加插件配置并应用它,sealer 将帮助你更改所有的主机名:

---
apiVersion: sealer.aliyun.com/v1alpha1
kind: Plugin
metadata:
  name: hostname
spec:
  type: HOSTNAME
  data: |
    192.168.0.2 master-0
    192.168.0.3 master-1
    192.168.0.4 master-2
    192.168.0.5 node-0
    192.168.0.6 node-1
    192.168.0.7 node-2
Hostname Plugin 将各个节点在安装集群前修改为对应的主机名。

脚本插件

如果你在 Clusterfile 后添加 Shell 插件配置并应用它,sealer 将帮助你执行 shell 命令 (执行路径为镜像 Rootfs 目录):

---
apiVersion: sealer.aliyun.com/v1alpha1
kind: Plugin
metadata:
  name: shell
spec:
  type: SHELL
  action: PostInstall
  'on': node-role.kubernetes.io/master=
  data: |
    kubectl taint nodes node-role.kubernetes.io/master=:NoSchedule
action : [PreInit| PostInstall] # 指定执行shell的时机
  在初始化之前执行命令      |  action: PreInit
  在添加节点之前执行命令    |  action: PreJoin
  在添加节点之后执行命令    |  action: PostJoin
  在执行Kubefile CMD之前  |  action: PreGuest
  在安装集群之后执行命令    |  action: PostInstall
  在清理集群前执行命令      |  action: PreClean
  在清理集群后执行命令      |  action: PostClean
  组合使用                |  action: PreInit|PreJoin
on     : #指定执行命令的机器
  为空时默认在所有节点执行
  在所有master节点上执行   | 'on': master
  在所有node节点上执行     | 'on': node
  在指定IP上执行          | 'on': 192.168.56.113,192.168.56.114,192.168.56.115,192.168.56.116
  在有连续IP的机器上执行    | 'on': 192.168.56.113-192.168.56.116
  在指定label节点上执行(action需为PostInstall或PreClean)  | 'on': node-role.kubernetes.io/master=
data   : #指定执行的shell命令

标签插件

如果你在 Clusterfile 后添加 label 插件配置并应用它,sealer 将帮助你添加 label:

apiVersion: sealer.aliyun.com/v1alpha1
kind: Plugin
metadata:
  name: label
spec:
  type: LABEL
  action: PreGuest
  data: |
    192.168.0.2 ssd=true
    192.168.0.3 ssd=true
    192.168.0.4 ssd=true
    192.168.0.5 ssd=false,hdd=true
    192.168.0.6 ssd=false,hdd=true
    192.168.0.7 ssd=false,hdd=true
节点 ip 与标签之前使用空格隔开,多个标签之间使用逗号隔开。

集群检测插件

由于服务器以及环境因素 (服务器磁盘性能差) 可能会导致 sealer 安装完 kubernetes 集群后,立即部署应用服务,出现部署失败的情况。cluster check 插件会等待 kubernetes 集群稳定后再部署应用服务。

apiVersion: sealer.aliyun.com/v1alpha1
kind: Plugin
metadata:
  name: checkCluster
spec:
  type: CLUSTERCHECK
  action: PreGuest

污点插件

如果你在 Clusterfile 后添加 taint 插件配置并应用它,sealer 将帮助你添加污点和去污点:

apiVersion: sealer.aliyun.com/v1alpha1
kind: Plugin
metadata:
  name: taint
spec:
  type: TAINT
  action: PreGuest
  data: |
    192.168.56.3 key1=value1:NoSchedule
    192.168.56.4 key2=value2:NoSchedule-
    192.168.56.3-192.168.56.7 key3:NoSchedule
    192.168.56.3,192.168.56.4,192.168.56.5,192.168.56.6,192.168.56.7 key4:NoSchedule
    192.168.56.3 key5=:NoSchedule
    192.168.56.3 key6:NoSchedule-
    192.168.56.4 key7:NoSchedule-
data 写法为 ips taint_argument ips : 多个 ip 通过 , 连接,连续 ip 写法为 首 ip - 末尾 ip taint_argument: 同 kubernetes 添加或去污点写法 (key=value:effect #effect 必须为:NoSchedule, PreferNoSchedule 或 NoExecute)。

插件使用步骤

Clusterfile 内容:

apiVersion: sealer.aliyun.com/v1alpha1
kind: Cluster
metadata:
  name: my-cluster
spec:
  image: registry.cn-qingdao.aliyuncs.com/sealer-io/kubernetes:v1.19.8
  provider: BAREMETAL
  ssh:
    # ssh的私钥文件绝对路径,例如/root/.ssh/id_rsa
    pk: xxx
    # ssh的私钥文件密码,如果没有的话就设置为""
    pkPasswd: xxx
    # ssh登录用户
    user: root
    # ssh的登录密码,如果使用的密钥登录则无需设置
    passwd: xxx
  network:
    podCIDR: 100.64.0.0/10
    svcCIDR: 10.96.0.0/22
  certSANS:
    - aliyun-inc.com
    - 10.0.0.2
  masters:
    ipList:
     - 192.168.0.2
     - 192.168.0.3
     - 192.168.0.4
  nodes:
    ipList:
     - 192.168.0.5
     - 192.168.0.6
     - 192.168.0.7
---
apiVersion: sealer.aliyun.com/v1alpha1
kind: Plugin
metadata:
  name: hostname
spec:
  type: HOSTNAME
  data: |
     192.168.0.2 master-0
     192.168.0.3 master-1
     192.168.0.4 master-2
     192.168.0.5 node-0
     192.168.0.6 node-1
     192.168.0.7 node-2
---
apiVersion: sealer.aliyun.com/v1alpha1
kind: Plugin
metadata:
  name: taint
spec:
  type: SHELL
  action: PostInstall
  on: node-role.kubernetes.io/master=
  data: |
     kubectl taint nodes node-role.kubernetes.io/master=:NoSchedule
sealer apply -f Clusterfile #plugin仅在安装时执行,后续apply不生效。
执行上述命令后 hostname,shell plugin 将修改主机名并在成功安装集群后执行 shell 命令。

在 Kubefile 中定义默认插件

很多情况下在不使用 Clusterfile 的情况下也能使用插件,本质上 sealer 会先把 Clusterfile 中的插件配置先存储到 rootfs/plugins 目录,再去使用,所以我们可以在制作镜像时就定义好默认插件。

插件配置文件 shell.yaml:

apiVersion: sealer.aliyun.com/v1alpha1
kind: Plugin
metadata:
name: taint
spec:
type: SHELL
action: PostInstall
on: node-role.kubernetes.io/master=
data: |
  kubectl get nodes
---
apiVersion: sealer.aliyun.com/v1alpha1
kind: Plugin
metadata:
  name: SHELL
spec:
  action: PostInstall
  data: |
    if type yum >/dev/null 2>&1;then
    yum -y install iscsi-initiator-utils
    systemctl enable iscsid
    systemctl start iscsid
    elif type apt-get >/dev/null 2>&1;then
    apt-get update
    apt-get -y install open-iscsi
    systemctl enable iscsid
    systemctl start iscsid
    fi

Kubefile:

FROM kubernetes:v1.19.8
COPY shell.yaml plugin

构建一个包含安装 iscsi 的插件 (或更多插件) 的集群镜像:

sealer build -m lite -t kubernetes-iscsi:v1.19.8 .

通过镜像启动集群后插件也将被执行,而无需在 Clusterfile 中定义插件: sealer run kubernetes-iscsi:v1.19.8 -m x.x.x.x -p xxx

总结

以上对 sealer 的核心能力有了一个整体的介绍,目前 sealer 已经在多家企业中生产落地,阿里内部也有非常多的实践,sealer 未来会重点在性能上做进一步突破,加强生态集群镜像制作,帮助企业和开发者更快进行交付。


kubernetesdocker
本作品采用《CC 协议》,转载必须注明作者和本文链接
网络犯罪组织使用一个称为Weave Scope的合法工具,在目标DockerKubernetes集群上建立了无文件后门。据研究人员称,TeamTNT网络犯罪团伙卷土重来,他们通过滥用一种名为Weave Scope的合法云监控工具攻击DockerKubernetes云实例。但是接下来,攻击者下载并安装 Weave Scope。TeamTNT小组专门研究攻击云,通常使用恶意Docker映像进行攻击,并证明了自己的创新能力。TeamTNT之前也有文档记载在AWS内部署独特且罕见的凭证窃取蠕虫。
目前发现并没有将kubernetesDocker技术产生背景和需求进行比较的文章,本文从最纯正的官方定义角度出发并展开,阐述二者产生背景及与传统技术对比。官方定义2:k8s是一个开源的容器集群管理系统,可以实现容器集群的自动化部署、自动扩缩容、维护等功能。
最近,各大互联网巨头在技术战略层面,都把云原生列为了主要发展方向。大的点就是 Go 语言 + Kubernetes,基本功就是操作系统、网络协议那些。而其中,KubernetesDocker、DevOps 又是重中之中
浅谈云安全之K8S
2021-07-14 05:06:00
Kubernetes 是一个可移植的,可扩展的开源容器编排平台,用于管理容器化的工作负载和服务,方便了声明式配置和自动化。它拥有一个庞大且快速增长的生态系统。Kubernetes 的服务,支持和工具广泛可用。
一旦收集到登录信息,恶意软件就会登录并部署XMRig挖掘工具来挖掘Monero cryptocurrency。这是观察到的第一个专门针对AWS以进行密码劫持的威胁。该域托管恶意软件,其首页名为“ TeamTNT RedTeamPentesting”。TeamTNT多产,并于今年初被发现。4月,趋势科技观察到该组织正在攻击Docker Containers。Cado研究人员建议,为阻止此类攻击,企业应确定哪些系统正在存储AWS凭证文件,并在不需要时将其删除。
“贴身”保护5G边缘计算
风险评估可以识别系统中的安全弱点,然后努力减轻这些风险。反过来,这些数据被用于主动促进风险评估和安全操作。网络安全专业人员必须能够进行数字取证调查,包括恶意软件分析、图像捕获和事件响应分析。将监督审计和评估,以衡量现有数据安全控制的有效性,并向管理层报告审计结果。许多企业要求应聘者熟悉其中一项或多项规定。
聊一聊新版本的几个主要功能更新和改进。
启明星辰堡垒机聚焦特权与会话管理(PASM)、统一身份验证管理(UIAM)、特权提升和托管管理(PEDM)。
近年来,非接触式信贷、理财及保险等金融服务的发展开始提速,金融业务的数字化、云端化及智能化正成为趋势,以人工智能、区块链、云计算及大数据等为代表的数字技术创新发展不断冲击着金融行业的商业模式。2022年1月,人民银行发布《金融科技发展规划(2022—2025年)》,明确提出从战略、组织、管理、目标、路径以及考评等方面将金融数字化打造成金融机构的“第二发展曲线”,积极推进科技赋能,坚持服务乡村振兴、
VSole
网络安全专家