dashboard開發環境搭建

1.dashboard開發環境搭建(Linux -ubuntu 16.04.2)

參考:dashboard工程目錄/docs/devel下的requirements-installation.md和getting-started.mdcss

unbuntu安裝 & java7安裝

1)ubuntu 16.04.2 下載

地址:http://mirror.bjtu.edu.cn/ubuntu-releases/16.04.2/ubuntu-16.04.2-desktop-amd64.iso 虛擬機安裝。html

安裝後升級linux(可選)前端

sudo apt-get update		
sudo apt-get upgrade

其中:
update 是同步 /etc/apt/sources.list 和 /etc/apt/sources.list.d 中列出的源的索引,這樣才能獲取到最新的軟件包。
upgrade 是升級已安裝的全部軟件包,升級以後的版本就是本地索引裏的,所以,在執行 upgrade 以前必定要執行 update, 這樣才能是最新的。java

ubutun 版本驗證命令:uname -rlsb_release -anode

No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 16.04.2 LTS
Release:        16.04
Codename:       xenial

後續命令操做都切換到root下執行su rootpython

2)網絡設置

使用圖形化界面修改,系統設置/硬件/網絡/有線/選項/iov4設置.....linux

3)java(7+)下載安裝:

Ubuntu16.04的安裝源已經默認沒有openjdk7了,因此要本身手動添加倉庫,以下:webpack

add-apt-repository ppa:openjdk-r/ppa   
apt-get update   
apt-get install openjdk-7-jdk
java -version

4) 其餘相關下載

apt-get install curl   
apt-get install git
apt-get install openssh-server

其中:
curl 後續ubuntu下載東西須要用到,版本驗證curl --version
git 以後從github上check出dashboard代碼,版本驗證git --version
openssh-server 使用ssh遠程ubuntugit

Docker(1.10+)安裝&配置

1)升級source列表並保證https和ca證書成功安裝es6

apt-get update
apt-get install apt-transport-https ca-certificates

2)增長新的GPG 密鑰

apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D

3)建立source列表裏的docker.list

$ sudo bash -c 'echo "deb https://apt.dockerproject.org/repo ubuntu-xenial main" > /etc/apt/sources.list.d/docker.list'

4)安裝docker

apt-get install docker.io	#安裝docker
service docker start		#啓動docker
service docker status		#docker是否啓動
docker info			#docker基本信息,包括版本
docker run hello-world		#驗證docker是否可用

5)docker配置

groupadd docker
usermod -aG docker root

6)中國官方鏡像加速
修改 /etc/docker/daemon.json 文件並添加上 registry-mirrors 鍵值。

{
  "registry-mirrors": ["https://registry.docker-cn.com"]
}

修改保存後重啓 Docker 以使配置生效service docker restart

go(1.7+)安裝&環境配置&IDE

下載go1.8

wget https://storage.googleapis.com/golang/go1.8.linux-amd64.tar.gz
tar -C /usr/local -xzf go1.8.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin
echo "export PATH=$PATH:/usr/local/go/bin" >> ~/.profile
echo "export PATH=$PATH:/usr/local/go/bin" >> /etc/profile

驗證

go version
echo $PATH

IDE使用:JetBrains Gogland

前端環境搭建:nodejs(5.1.1+),npm(3+),gulp(3.9+)

nodejs和npm 下載&驗證:

curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
apt-get install -y nodejs	
node -v	 
npm -v

Gulp下載&驗證

npm install --global gulp-cli
npm install --global gulp
gulp -v

npm鏡像

npm install cnpm -g --registry=https://registry.npm.taobao.org

cnpm跟npm用法徹底一致,只是在執行命令時將npm改成cnpm

工程項目概況

從github上下載dashboard源碼:git clone https://github.com/kubernetes/dashboard.git

前端:SPA, ES6/babel, Angular1.6, gulp, bower,karma, BrowerSync 後端:Go

構建

開發環境執行

npm install 設置環境變量KUBE_DASHBOARD_APISERVER_HOST爲k8s的api server的ip端口。 執行gulp serve ,可訪問http://localhost:9090

BrowserSync (9090) ---> Dashboard backend (9091) ---> Kubernetes API server (8080)

生產環節

編譯代碼執行gulp build:編譯,壓縮前臺代碼,編譯後臺代碼到dist目錄。
執行gulp serve:prod,可訪問http://localhost:9090

Dashboard backend (9090) ---> Kubernetes API server (8080)

打包成docker鏡像執行:gulp docker-image:canary

配置文件.babelrc

Babel的配置文件,該文件用來設置轉碼規則和插件,設置ES6

{
  "presets": ["es2015"]
}

相關預備知識

gulp

BrowerSync

Go

ES5 & ES6

ES5:嚴格模式,JSON,添加對象,額外的數組,Function.prototype.bind
ES6:let&const, 解構,箭頭函數,默認參數,rest&spread,字符串模板,集合類型,模塊,Promise,Class,Iterators, Generators, Proxies&Reflecion, Symbols....

Angular1.x

MVVM:視圖 - 模型 - 視圖模型

2.dashboard開發環境搭建(windows)

  • Docker (1.10+)
  • go (1.7+)
  • nodejs (5.1.1+)
  • npm (3+)
  • java (7+)
  • gulp (3.9+)

npm 配置

npm config set prefix "D:\node\node-global"<!--配置全局安裝目錄-->
npm config set cache "D:\node\node-cache"<!--配置緩存目錄-->
配置環境變量NODE_PATH   設置爲node_modules的文件夾路徑  D:\node\node-global\node_modules 
npm config set registry https://registry.npm.taobao.org

安裝python2.7

安裝vs expression 2013 for desk(VS2013_RTM_DskExp_CHS.iso)

npm config set python C:\Python27\python.exe  
npm config set msvs_version 2013 --global  
npm install

再在gitbash裏手動執行build/postinstall.sh

go包管理

go get -u github.com/kardianos/govendor Warning: 須要把 $GOPATH/bin/ 加到 PATH 中。 http://www.javashuo.com/article/p-anloqoxq-gq.html

跨平臺

1)const sourceGopath = ${conf.paths.backendTmp}${path.delimiter}${conf.paths.backendVendor}; 路徑分隔符,文件分隔符
2)gocommad.js裏的which命令改爲where
3)java -Dfile.encoding=utf-8 i18n下文件的編碼問題
-jar F:\WORK\work_go\src\github.com\kubernetes\dashboard.tools\xtbgenerator\bin\XtbGenerator.jar --lang en --xtb_output_file F:\WORK\work_go\src\github.com\kubernetes\dashboard\i18n\messages-en.xtb --js F:\WORK\work_go\src\github.com\kubernetes\dashboard.tmp\serve*.js --js F:\WORK\work_go\src\github.com\kubernetes\dashboard.tmp\messages_for_extraction*.js --translations_file F:\WORK\work_go\src\github.com\kubernetes\dashboard\i18n\messages-en.xtb MalformedByteSequenceException: 3 字節的 UTF-8 序列的字節 3 無

4)18n

let command = `java -Dfile.encoding=utf-8 -jar ${conf.paths.xtbgenerator} --lang ${langKey}` +
  
//let messageVarPrefix = filePath.toUpperCase().split('/').join('_').replace('.HTML', '');
  let messageVarPrefix = filePath.toUpperCase().replace(/\\/g,"\/").split('/').join('_').replace('.HTML', '');
  
/*
* gulp-google-closure-compiler: deploy/helpsection/userhelp.html.js:5: ERROR - Parse error. Hex digit expected
 $templateCache.put('deploy\helpsection\userhelp.html', ' <div ng-transclude class="kd-user-help" layout-align="start center"> </div> ');
 報錯信息說是發現非法16進制數據,這個問題很是蹊蹺,也是windows平臺和linux平臺的路徑分隔符不一致所致,是上面的\userhelp.html形成的,由於\u在js中表明後面接着的是16進制數,打開build/i18n.js,將:
 * */
file.moduleContent = `` +
    `import module from 'index_module';\n\n${file.messages}\n` +
    `module.run(['$templateCache', ($templateCache) => {\n` +
    `    $templateCache.put('${filePath.replace(/\\/g,"\\\\")}', '${content}');\n` +
    `}]);\n`;

5)gocommand.js

import path from 'path';
const sourceGopath = `${conf.paths.backendTmp}${path.delimiter}${conf.paths.backendVendor}`;
// Add the project's required go tools to the PATH.
const devPath = `${process.env.PATH}${path.delimiter}${conf.paths.goTools}/bin`;

6)build.js

let searchPath = [
// To resolve local paths.
path.relative(conf.paths.base, conf.paths.prodTmp),
// To resolve bower_components/... paths.
path.relative(conf.paths.base, conf.paths.base)+'/',
  ];

7)package.json

"babel-core": "~6.24.0",
"babel-loader": "~7.0.0",
"babel-preset-es2015": "~6.24.0",

babel版本問題,1.6.3裏的版本有問題會報錯

8)dashboard ENONE 第一次使用exe結尾,之後不用exe結尾也能夠啓動

9)minikube本地安裝
kubectl config view 獲取kubeconfig
證書訪問https

--insecure-port=9091
--apiserver-host=https://192.168.0.9:8443
--kubeconfig=F:\temp\kubeconfig

安裝minikube https://kubernetes.io/docs/getting-started-guides/minikube/

備忘

"D:\Program_Files\JetBrains\Gogland 171.4694.61\bin\runnerw.exe" D:\Program_Files\nodejs\node.exe F:\WORK\work_go\src\github.com\kubernetes\dashboard\node_modules\gulp\bin\gulp.js --color --gulpfile F:\WORK\work_go\src\github.com\kubernetes\dashboard\gulpfile.babel.js serve-nospawn-backend
[16:49:00] Requiring external module babel-register
[16:50:03] Using gulpfile F:\WORK\work_go\src\github.com\kubernetes\dashboard\gulpfile.babel.js
[16:50:03] Starting 'scripts'...
[16:50:07] Starting 'styles'...
[16:50:07] Starting 'buildExistingI18nCache'...
[16:50:12] Finished 'buildExistingI18nCache' after 4.21 s
[16:50:12] Starting 'angular-templates'...
[16:50:26] Finished 'scripts' after 23 s
[16:50:27] Finished 'styles' after 19 s
[16:50:27] Starting 'index'...
[16:50:27] Finished 'index' after 385 ms
[16:50:28] Finished 'angular-templates' after 17 s
[16:50:28] Starting 'watch-nobackend'...
[16:50:29] Finished 'watch-nobackend' after 702 ms
[16:50:29] Starting 'serve-nospawn-backend'...
[HPM] Proxy created: /api  ->  http://localhost:9091
[16:50:29] Finished 'serve-nospawn-backend' after 116 ms
[BS] [BrowserSync SPA] Running...
[Browsersync] Access URLs:
 ----------------------------------------
       Local: http://localhost:9090/
    External: http://169.254.33.229:9090/
 ----------------------------------------
          UI: http://localhost:3001
 UI External: http://169.254.33.229:3001
 ----------------------------------------
[Browsersync] Serving files from: F:\WORK\work_go\src\github.com\kubernetes\dashboard\.tmp\serve
[Browsersync] Serving files from: F:\WORK\work_go\src\github.com\kubernetes\dashboard\src\app


/**啓動應用Serves the application in development mode. Watches 
for changes in the source files to rebuild development artifacts.*/
gulp.task('serve-nospawn-backend', ['watch-nobackend'], serveDevelopmentMode);  

//啓動browserSync:Serves the application in development mode.
function serveDevelopmentMode() {
  browserSyncInit(
      [
        conf.paths.serve,
        conf.paths.app,  // For assets to work.
      ],
      true);
}

/**Initializes BrowserSync tool. Files are served from baseDir directory list and all API calls
 * are proxied to a running backend instance. When includeBowerComponents is true, requests for
 * paths starting with '/bower_components' are routed to bower components directory.
 * */
function browserSyncInit(baseDir, includeBowerComponents) {
  // Enable custom support for Angular apps, e.g., history management.
  browserSyncInstance.use(browserSyncSpa({
    selector: '[ng-app]',
  }));

  let apiRoute = '/api';
  let proxyMiddlewareOptions = {
    target: `http://localhost:${conf.backend.devServerPort}`,
    // proxy websockets
    ws: true,
  };

  let config = {
    browser: [],       // Needed so that the browser does not auto-launch.
    directory: false,  // Disable directory listings.
    // TODO(bryk): Add proxy to the backend here.
    server: {
      baseDir: baseDir,
      middleware: proxyMiddleware(apiRoute, proxyMiddlewareOptions),
    },
    port: conf.frontend.serverPort,
    startPath: '/',
    notify: false,
  };

  if (includeBowerComponents) {
    config.server.routes = {
      '/bower_components': conf.paths.bowerComponents,
    };
  }

  browserSyncInstance.init(config);
}

//監控前端代碼:Watches for changes in source files and runs Gulp tasks to rebuild them.
gulp.task('watch-nobackend', ['index', 'angular-templates'], function() {
    gulp.watch([path.join(conf.paths.frontendSrc, 'index.html'), 'bower.json'], ['index']);

    gulp.watch(
        [
            path.join(conf.paths.frontendSrc, '**/*.scss'),
        ],
        function(event) {
            if (event.type === 'changed') {
                // If this is a file change, rebuild only styles - nothing more is needed.
                gulp.start('styles');
            } else {
                // If this is new/deleted file, everything has to be rebuilt.
                gulp.start('index');
            }
        });

    gulp.watch(path.join(conf.paths.frontendSrc, '**/*.js'), ['scripts-watch']);
    gulp.watch(path.join(conf.paths.frontendSrc, '**/*.html'), ['angular-templates']);
});

//建立index:Creates frontend application index file with development dependencies injected.
gulp.task('index', ['scripts', 'styles'], function() {
  return createIndexFile(conf.paths.serve, true).pipe(webpackStream(webpackOptions));
});

/**注入CSS, js
 * Creates index file in the given directory with dependencies injected from that directory.*/
function createIndexFile(indexPath, dev) {
  let injectStyles = gulp.src(path.join(indexPath, '**/*.css'), {read: false});

  let injectScripts = gulp.src(path.join(indexPath, '**/*.js'), {read: false});

  let injectOptions = {
    // Make the dependencies relative to the deps directory.
    ignorePath: [path.relative(conf.paths.base, indexPath)],
    addRootSlash: false,
    quiet: true,
  };

  /***bower解決了前端庫及其依賴安裝的問題。至於怎麼把真正所須要的文件引入到html文件中,就須要wiredep來幫忙啦
   * <!-- bower:css -->
   <!-- endbower -->
   在.html文件會把默認bower.json的配置自動注入到下面標籤中去 <!-- bower:js --> <!-- endbower --> <!-- bower:css--> <!-- endbower -->
   */
  let wiredepOptions = {
    // Make wiredep dependencies begin with "bower_components/" not "../../...".
    ignorePath: path.relative(conf.paths.frontendSrc, conf.paths.base),
  };

  if (dev) {
    wiredepOptions.devDependencies = true;
  }

  return gulp.src(path.join(conf.paths.frontendSrc, 'index.html'))
      .pipe(gulpInject(injectStyles, injectOptions))
      .pipe(gulpInject(injectScripts, injectOptions))
      .pipe(wiredep.stream(wiredepOptions))
      .pipe(gulp.dest(indexPath));
}


/**使用webpack打包js
 * Returns function creating a stream that compiles frontend JavaScript files into development
 * bundle located in {conf.paths.serve} directory. This has to be done because currently browsers do **/
gulp.task('scripts', createScriptsStream(true));
function createScriptsStream(throwError) {
  return function() {
    let webpackOptions = {
      devtool: 'inline-source-map',
      module: {
        // ES6 modules have to be preprocessed with Babel loader to work in browsers.
        loaders: [{test: /\.js$/, exclude: /node_modules/, loaders: ['babel-loader']}],
      },
      output: {filename: 'app-dev.js'},
      resolve: {
        // Set the module resolve root, so that webpack knows how to process non-relative imports.
        // Should be kept in sync with respective Closure Compiler option.
        root: conf.paths.frontendSrc,
      },
      quiet: true,
    };
    let compiled = gulp.src(path.join(conf.paths.frontendSrc, 'index_module.js'))
                       .pipe(webpackStream(webpackOptions));
    if (!throwError) {
      // prevent gulp from crashing during watch task in case of JS syntax errors
      compiled = compiled.on('error', function handleScriptSyntaxError(err) {
        compiled.emit('end');
        console.log(err.toString());
      });
    }

    return compiled.pipe(gulp.dest(conf.paths.serve));
  };
}

/**編譯SASS成css
 * Compiles stylesheets and places them into the serve folder. Each stylesheet file is compiled
 * separately.
 */
gulp.task('styles', function() {
  let sassOptions = {
    style: 'expanded',
  };

  return gulp.src(path.join(conf.paths.frontendSrc, '**/*.scss'))
      .pipe(gulpSourcemaps.init())  //當壓縮的JS出錯,能根據這個找到未壓縮代碼的位置 不會一片混亂代碼
      .pipe(gulpSass(sassOptions))  //預編譯Sass
      .pipe(gulpAutoprefixer())     //根據設置瀏覽器版本自動處理瀏覽器前綴
      .pipe(gulpSourcemaps.write('.'))  //map文件命名
      .pipe(gulp.dest(conf.paths.serve))
      // If BrowserSync is running, inform it that styles have changed.
      .pipe(browserSyncInstance.stream());
});

browerSync啓動注入前端代碼,並代理後端服務。
css:browserSyncInstance.stream()
script: webpackStream(webpackOptions)
index: webpackStream(webpackOptions)
注入: .pipe(gulpInject(injectStyles, injectOptions)) .pipe(gulpInject(injectScripts, injectOptions)) .pipe(wiredep.stream(wiredepOptions))

使用到Angular Material,依賴angular-animate, angular-aria(無障礙), angular 使用flex佈局,封裝flex成本身的樣式layout-*,再把layout-*樣式和屬性關聯,使用時直接使用屬性。 支持-sm, -md, -gt等自適應的後綴(600,960,1200)

相關文章
相關標籤/搜索