sealer是阿里巴巴开源的基于kuberentes的集群镜像开源技术,能够把整个集群整体打包。

Sealer Cloud能够在线化帮忙用户进行集群打包分享和运行,Sealer cloud前后端也应用了十分先进的
rust+wasm技术实现。

sealer cloud会与docker registry交互,将来你甚至能够把sealer cloud当作docker hub应用。

定义数据结构

能够看到registry返回的数据:

curl http://localhost:5000/v2/_catalog{"repositories":["centos","golang"]}

所以对应返回的数据咱们定义个数据结构:

#[derive(Deserialize, Debug, Clone)]pub struct RegistryCatalog {    pub repositories: Vec<String>,}

这个构造体用来接管后盾返回的数据,咱们还须要Model的构造体:

pub struct Images {    // props: Props,    pub repos: Option<Vec<String>>,    pub error: Option<String>,    pub link: ComponentLink<Self>,    pub task: Option<FetchTask>}

音讯枚举,通过不同的音讯在页面更新时判断应该做什么样的动作:

#[derive(Debug)]pub enum Msg {    GetRegistryCatelog(Result<RegistryCatalog, anyhow::Error>),}

页面首次初始化

首次初始化的时候向后盾申请数据:

fn rendered(&mut self, first_render: bool) {    if first_render {        ConsoleService::info("view app");        let request = Request::get("http://localhost:8001/v2/_catalog")            .body(Nothing)            .expect("could not build request.");        let callback = self.link.callback(            |response: Response<Json<Result<RegistryCatalog, anyhow::Error>>>| {                let Json(data) = response.into_body();                Msg::GetRegistryCatelog(data)            },        );        let task = FetchService::fetch(request, callback).expect("failed to start request");        self.task = Some(task);    }}
  • first_render用于判断是不是第一次渲染,不写在这外面可能会导致页面渲染死循环。
  • ConsoleService::info 能够帮忙咱们往控制台打印调试信息
  • 定义一个request和一个申请胜利后的回调函数callback
  • callback外部接管到数据后返回对应的音讯类型即可触发update函数(前面介绍)
  • fetch函数触发http申请调用,传入request与callback
  • 重中之重,肯定要把task存到self.task外面,不然task立马被回收会触发一个The user aborted a request的谬误

页面更新接口

在first render的时候咱们向后盾申请了数据,callback函数会触发update的调用。
把音讯带过来交给update函数解决。

fn update(&mut self, msg: Self::Message) -> ShouldRender {    use Msg::*;    match msg {        GetRegistryCatelog(response) => match response {            Ok(repos) => {                ConsoleService::info(&format!("info {:?}", repos));                 self.repos = Some(repos.repositories);            }            Err(error) => {                ConsoleService::info(&format!("info {:?}", error.to_string()));             },        },    }    true}

msg能够有多种音讯类型,此处就写一个

#[derive(Debug)]pub enum Msg {    GetRegistryCatelog(Result<RegistryCatalog, anyhow::Error>),}

response就是Result<RegistryCatalog, anyhow::Error>类型,Ok时把它放到构造体中保留就好。

最初渲染到页面上:

fn view(&self) -> Html {    html! {        <div class="container column is-10">        { self.image_list() }        </div>    }}fn image_list(&self) -> Html {    match &self.repos {        Some(images) => {            html! {             <div class="columns is-multiline">               {                   for images.iter().map(|image|{                       self.image_info(image)                   })               }             </div>            }        }        None => {            html! {              <p> {"image not found"} </p>            }        }    }}

如此就实现了整个数据申请的绑定渲染。

理论运行

因为申请docker registry会有跨域问题,所以整个nginx代理:

docker run -p 5000:5000 -d --name registry registry:2.7.1

nginx.conf:

user  nginx;worker_processes  1;error_log  /var/log/nginx/error.log warn;pid        /var/run/nginx.pid;events {    worker_connections  1024;}http {    include       /etc/nginx/mime.types;    default_type  application/octet-stream;    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '                      '$status $body_bytes_sent "$http_referer" '                      '"$http_user_agent" "$http_x_forwarded_for"';    access_log  /var/log/nginx/access.log  main;    sendfile        on;    #tcp_nopush     on;    keepalive_timeout  65;    server {        listen       8000;  #监听8000端口,能够改成其余端口        server_name  localhost; # 以后服务的域名        location / {          if ($request_method = 'OPTIONS') {            add_header 'Access-Control-Allow-Origin' '*' always;            add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE' always;            add_header 'Access-Control-Allow-Headers' '*' always;            add_header 'Access-Control-Max-Age' 1728000 always;            add_header 'Content-Length' 0;            add_header 'Content-Type' 'text/plain; charset=utf-8';            return 204;          }          if ($request_method ~* '(GET|POST|DELETE|PUT)') {            add_header 'Access-Control-Allow-Origin' '*' always;          }          proxy_pass http://172.17.0.3:5000; # the registry IP or domain name          proxy_http_version 1.1;        }    }    #gzip  on;    include /etc/nginx/conf.d/*.conf;}
docker run -d --name registry-proxy -p 8001:8000 \  -v /Users/fanghaitao/nginx/nginx.conf:/etc/nginx/nginx.conf nginx:1.19.0

测试registry api是否能通:

curl http://localhost:8001/v2/_catalog{"repositories":["centos","golang"]}

而后代码外面拜访nginx代理的这个地址即可
kubernetes一键装置

sealer集群整体打包!