├── .hugo_build.lock ├── .gitignore ├── exampleSite ├── content │ ├── search │ │ └── placeholder.md │ ├── archive │ │ └── index.md │ ├── notes │ │ └── index.md │ ├── post │ │ ├── 2017-11-03-hello-world.md │ │ ├── 2018-02-09-docker-without-sudo.md │ │ ├── 2018-03-13-use-docker-behind-http-proxy.md │ │ ├── 2018-02-09-vim-tips.md │ │ ├── 2018-05-24-set_up_my_ubuntu_desktop.md │ │ ├── 2018-05-23-service_2_service_auth.md │ │ ├── 2018-04-11-service-mesh-vs-api-gateway.md │ │ ├── 2017-11-07-istio-traffic-shifting.md │ │ ├── 2018-06-02-istio08.md │ │ ├── 2018-05-23-external_system_auth.md │ │ ├── 2018-05-23-istio-auto-injection-with-webhook.md │ │ ├── 2018-05-22-user_authentication_authorization.md │ │ ├── 2018-05-01-may-day-jiulonghu.md │ │ ├── 2018-05-21-algolia-integration-with-jekyll.md │ │ └── 2025-07-06-mathematical-formulae.md │ └── about │ │ ├── index-zh.md │ │ └── index.md ├── .gitignore ├── build_algolia_index.sh ├── static │ └── img │ │ ├── tn.png │ │ ├── post.png │ │ ├── 404-bg.jpg │ │ ├── disqus.png │ │ ├── favicon.ico │ │ ├── favicon.png │ │ ├── rewards.png │ │ ├── search.png │ │ ├── tag-bg.jpg │ │ ├── contact-bg.jpg │ │ ├── sitesearch.png │ │ ├── home-bg-jeep.jpg │ │ ├── zhaohuabing.png │ │ ├── fullscreenshot.png │ │ ├── post-bg-coffee.jpeg │ │ ├── wechat_qrcode.jpg │ │ └── post-bg-unix-linux.jpg ├── deploy.sh └── hugo.toml ├── layouts ├── shortcodes │ ├── rawhtml.html │ ├── mind.html │ ├── bilibili.html │ ├── notice.html │ ├── figure.html │ ├── post-image.html │ ├── gallery.html │ ├── load-photoswipe.html │ └── load-photoswipe-theme.html ├── index.html ├── taxonomy │ ├── tag.html │ ├── category.html │ └── terms.html ├── partials │ ├── category.html │ ├── portfolio.html │ ├── multilingual-sel.html │ ├── search-pagefind.html │ ├── pagination.html │ ├── posts.html │ ├── math │ │ ├── katex-css.html │ │ └── katex-fonts.html │ ├── header.html │ ├── post_list.html │ ├── reward.html │ ├── comments.html │ ├── search-algolia.html │ ├── nav.html │ ├── head.html │ └── page_view_counter.html ├── _markup │ ├── render-codeblock-mermaid.html │ ├── render-codeblock-chem.html │ ├── render-codeblock-math.html │ └── render-passthrough.html ├── _default │ ├── _markup │ │ └── render-image.html │ ├── page.html │ ├── baseof.html │ ├── list.algolia.json │ ├── archive.html │ ├── section.html │ ├── top.html │ ├── post.html │ └── single.html ├── 404.html ├── search │ └── list.html └── top │ └── single.html ├── go.mod ├── images ├── tn.png ├── disqus.png ├── post.png ├── archive.png ├── bilibili.png ├── mindmap.png ├── plantuml.png ├── rewards.png ├── screenshot.png ├── sitesearch.png └── fullscreenshot.png ├── static ├── img │ ├── favicon.ico │ ├── search.png │ └── reward │ │ ├── alipay-1.png │ │ ├── alipay-10.png │ │ ├── alipay-100.png │ │ ├── alipay-2.png │ │ ├── alipay-5.png │ │ ├── alipay-50.png │ │ ├── alipay-btn.png │ │ ├── wechat-1.png │ │ ├── wechat-10.png │ │ ├── wechat-100.png │ │ ├── wechat-2.png │ │ ├── wechat-5.png │ │ ├── wechat-50.png │ │ └── wechat-btn.png ├── css │ ├── fonts │ │ ├── FontAwesome.otf │ │ ├── fontawesome-webfont.eot │ │ ├── fontawesome-webfont.ttf │ │ ├── fontawesome-webfont.woff │ │ └── fontawesome-webfont.woff2 │ ├── hugo-easy-gallery.min.css │ ├── zanshang.min.css │ ├── zanshang.css │ ├── mindmap.css │ └── hugo-easy-gallery.css ├── webfonts │ ├── fa-brands-400.woff │ ├── fa-solid-900.woff2 │ └── fa-brands-400.woff2 └── js │ ├── mindmap.min.js │ ├── mindmap.js │ ├── hux-blog.min.js │ ├── reward.js │ ├── jquery.tagcloud.js │ ├── load-photoswipe.js │ ├── hux-blog.js │ ├── fitvids.js │ ├── jquery.nav.js │ └── lazysizes.min.js ├── archetypes └── post.md ├── .github ├── stale.yml └── FUNDING.yml └── theme.toml /.hugo_build.lock: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /exampleSite/content/search/placeholder.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /exampleSite/.gitignore: -------------------------------------------------------------------------------- 1 | .hugo_build.lock 2 | /public/ -------------------------------------------------------------------------------- /exampleSite/build_algolia_index.sh: -------------------------------------------------------------------------------- 1 | npm run algolia 2 | -------------------------------------------------------------------------------- /layouts/shortcodes/rawhtml.html: -------------------------------------------------------------------------------- 1 | 2 | {{.Inner}} 3 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/zhaohuabing/hugo-theme-cleanwhite 2 | 3 | go 1.21 4 | -------------------------------------------------------------------------------- /images/tn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/images/tn.png -------------------------------------------------------------------------------- /layouts/index.html: -------------------------------------------------------------------------------- 1 | {{ define "main" }} 2 | {{ partial "portfolio.html" . }} 3 | {{ end }} 4 | -------------------------------------------------------------------------------- /images/disqus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/images/disqus.png -------------------------------------------------------------------------------- /images/post.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/images/post.png -------------------------------------------------------------------------------- /layouts/taxonomy/tag.html: -------------------------------------------------------------------------------- 1 | {{ define "main" }} 2 | {{ partial "category.html" . }} 3 | {{ end }} 4 | -------------------------------------------------------------------------------- /images/archive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/images/archive.png -------------------------------------------------------------------------------- /images/bilibili.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/images/bilibili.png -------------------------------------------------------------------------------- /images/mindmap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/images/mindmap.png -------------------------------------------------------------------------------- /images/plantuml.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/images/plantuml.png -------------------------------------------------------------------------------- /images/rewards.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/images/rewards.png -------------------------------------------------------------------------------- /layouts/taxonomy/category.html: -------------------------------------------------------------------------------- 1 | {{ define "main" }} 2 | {{ partial "category.html" . }} 3 | {{ end }} 4 | -------------------------------------------------------------------------------- /images/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/images/screenshot.png -------------------------------------------------------------------------------- /images/sitesearch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/images/sitesearch.png -------------------------------------------------------------------------------- /static/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/static/img/favicon.ico -------------------------------------------------------------------------------- /static/img/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/static/img/search.png -------------------------------------------------------------------------------- /images/fullscreenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/images/fullscreenshot.png -------------------------------------------------------------------------------- /exampleSite/static/img/tn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/exampleSite/static/img/tn.png -------------------------------------------------------------------------------- /exampleSite/static/img/post.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/exampleSite/static/img/post.png -------------------------------------------------------------------------------- /static/css/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/static/css/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /static/img/reward/alipay-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/static/img/reward/alipay-1.png -------------------------------------------------------------------------------- /static/img/reward/alipay-10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/static/img/reward/alipay-10.png -------------------------------------------------------------------------------- /static/img/reward/alipay-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/static/img/reward/alipay-100.png -------------------------------------------------------------------------------- /static/img/reward/alipay-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/static/img/reward/alipay-2.png -------------------------------------------------------------------------------- /static/img/reward/alipay-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/static/img/reward/alipay-5.png -------------------------------------------------------------------------------- /static/img/reward/alipay-50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/static/img/reward/alipay-50.png -------------------------------------------------------------------------------- /static/img/reward/alipay-btn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/static/img/reward/alipay-btn.png -------------------------------------------------------------------------------- /static/img/reward/wechat-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/static/img/reward/wechat-1.png -------------------------------------------------------------------------------- /static/img/reward/wechat-10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/static/img/reward/wechat-10.png -------------------------------------------------------------------------------- /static/img/reward/wechat-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/static/img/reward/wechat-100.png -------------------------------------------------------------------------------- /static/img/reward/wechat-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/static/img/reward/wechat-2.png -------------------------------------------------------------------------------- /static/img/reward/wechat-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/static/img/reward/wechat-5.png -------------------------------------------------------------------------------- /static/img/reward/wechat-50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/static/img/reward/wechat-50.png -------------------------------------------------------------------------------- /static/img/reward/wechat-btn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/static/img/reward/wechat-btn.png -------------------------------------------------------------------------------- /exampleSite/static/img/404-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/exampleSite/static/img/404-bg.jpg -------------------------------------------------------------------------------- /exampleSite/static/img/disqus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/exampleSite/static/img/disqus.png -------------------------------------------------------------------------------- /exampleSite/static/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/exampleSite/static/img/favicon.ico -------------------------------------------------------------------------------- /exampleSite/static/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/exampleSite/static/img/favicon.png -------------------------------------------------------------------------------- /exampleSite/static/img/rewards.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/exampleSite/static/img/rewards.png -------------------------------------------------------------------------------- /exampleSite/static/img/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/exampleSite/static/img/search.png -------------------------------------------------------------------------------- /exampleSite/static/img/tag-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/exampleSite/static/img/tag-bg.jpg -------------------------------------------------------------------------------- /layouts/partials/category.html: -------------------------------------------------------------------------------- 1 | {{ $paginator := .Paginate (where .Data.Pages "Section" "post") }} 2 | {{ partial "posts.html" . }} 3 | -------------------------------------------------------------------------------- /static/webfonts/fa-brands-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/static/webfonts/fa-brands-400.woff -------------------------------------------------------------------------------- /static/webfonts/fa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/static/webfonts/fa-solid-900.woff2 -------------------------------------------------------------------------------- /exampleSite/static/img/contact-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/exampleSite/static/img/contact-bg.jpg -------------------------------------------------------------------------------- /exampleSite/static/img/sitesearch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/exampleSite/static/img/sitesearch.png -------------------------------------------------------------------------------- /static/webfonts/fa-brands-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/static/webfonts/fa-brands-400.woff2 -------------------------------------------------------------------------------- /exampleSite/static/img/home-bg-jeep.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/exampleSite/static/img/home-bg-jeep.jpg -------------------------------------------------------------------------------- /exampleSite/static/img/zhaohuabing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/exampleSite/static/img/zhaohuabing.png -------------------------------------------------------------------------------- /exampleSite/static/img/fullscreenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/exampleSite/static/img/fullscreenshot.png -------------------------------------------------------------------------------- /exampleSite/static/img/post-bg-coffee.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/exampleSite/static/img/post-bg-coffee.jpeg -------------------------------------------------------------------------------- /exampleSite/static/img/wechat_qrcode.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/exampleSite/static/img/wechat_qrcode.jpg -------------------------------------------------------------------------------- /static/css/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/static/css/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /static/css/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/static/css/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /static/css/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/static/css/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /static/css/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/static/css/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /exampleSite/content/archive/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Posts Archive" 3 | layout: archive 4 | type: archive 5 | description: Archive of historical posts. 6 | --- -------------------------------------------------------------------------------- /layouts/partials/portfolio.html: -------------------------------------------------------------------------------- 1 | {{ $paginator := .Paginate (where (where .Site.Pages "Type" "post") "IsPage" true) }} 2 | {{ partial "posts.html" . }} 3 | -------------------------------------------------------------------------------- /exampleSite/static/img/post-bg-unix-linux.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaohuabing/hugo-theme-cleanwhite/HEAD/exampleSite/static/img/post-bg-unix-linux.jpg -------------------------------------------------------------------------------- /layouts/_markup/render-codeblock-mermaid.html: -------------------------------------------------------------------------------- 1 |
2 |   {{ .Inner | htmlEscape | safeHTML }}
3 | 
4 | {{ .Page.Store.Set "hasMermaid" true }} 5 | -------------------------------------------------------------------------------- /exampleSite/content/notes/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | --- 4 | 5 | ## [Go 语言学习笔记](https://zhaohuabing.com/learning-golang) 6 | 7 | ## [Envoy 学习笔记](https://zhaohuabing.com/learning-envoy) 8 | 9 | -------------------------------------------------------------------------------- /archetypes/post.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "An Example Post" 3 | subtitle: "" 4 | description: "" 5 | date: 2018-06-04 6 | author:     "" 7 | image: "" 8 | tags: ["tag1", "tag2"] 9 | categories: ["Tech" ] 10 | --- 11 | -------------------------------------------------------------------------------- /layouts/partials/multilingual-sel.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /layouts/_default/_markup/render-image.html: -------------------------------------------------------------------------------- 1 | {{ if .Title }} 2 |
3 | {{ .Text }} 4 |
{{ .Title }}
5 |
6 | {{ else }} 7 | {{ .Text }} 8 | {{ end }} 9 | -------------------------------------------------------------------------------- /layouts/partials/search-pagefind.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /exampleSite/content/post/2017-11-03-hello-world.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "Welcome to Zhaohuabing Blog" 4 | subtitle: "Hello World, Hello Blog" 5 | date: 2017-11-04 6 | author: "赵化冰" 7 | URL: "/2017/11/03/hello-world/" 8 | image: "https://img.zhaohuabing.com/post-bg-2015.jpg" 9 | --- 10 | 11 | > “Yeah It's on. ” 12 | 13 | 14 | ## Hello World! 15 | -------------------------------------------------------------------------------- /layouts/shortcodes/mind.html: -------------------------------------------------------------------------------- 1 | {{ $_hugo_config := `{ "version": 1 }` }} 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | {{.Inner}} 12 |
13 | -------------------------------------------------------------------------------- /layouts/_markup/render-codeblock-chem.html: -------------------------------------------------------------------------------- 1 | {{ $opts := dict "output" "htmlAndMathml" "displayMode" (not (eq ($.Type) "inline")) -}} 2 | {{ with try (transform.ToMath .Inner $opts) -}} 3 | {{ with .Err -}} 4 | {{ errorf "Unable to render mathematical markup to HTML using the transform.ToMath function. The KaTeX display engine threw the following error: %s: see %s." . $.Position -}} 5 | {{ else -}} 6 | {{ .Value -}} 7 | {{ $.Page.Store.Set "hasMath" true -}} 8 | {{ end -}} 9 | {{ end -}} 10 | -------------------------------------------------------------------------------- /layouts/_markup/render-codeblock-math.html: -------------------------------------------------------------------------------- 1 | {{ $opts := dict "output" "htmlAndMathml" "displayMode" (not (eq ($.Type) "inline")) -}} 2 | {{ with try (transform.ToMath .Inner $opts) -}} 3 | {{ with .Err -}} 4 | {{ errorf "Unable to render mathematical markup to HTML using the transform.ToMath function. The KaTeX display engine threw the following error: %s: see %s." . $.Position -}} 5 | {{ else -}} 6 | {{ .Value -}} 7 | {{ $.Page.Store.Set "hasMath" true -}} 8 | {{ end -}} 9 | {{ end -}} 10 | -------------------------------------------------------------------------------- /layouts/_markup/render-passthrough.html: -------------------------------------------------------------------------------- 1 | {{ $opts := dict "output" "htmlAndMathml" "displayMode" (not (eq ($.Type) "inline")) -}} 2 | {{ with try (transform.ToMath .Inner $opts) -}} 3 | {{ with .Err -}} 4 | {{ errorf "Unable to render mathematical markup to HTML using the transform.ToMath function. The KaTeX display engine threw the following error: %s: see %s." . $.Position -}} 5 | {{ else -}} 6 | {{ .Value -}} 7 | {{ $.Page.Store.Set "hasMath" true -}} 8 | {{ end -}} 9 | {{ end -}} 10 | -------------------------------------------------------------------------------- /layouts/partials/pagination.html: -------------------------------------------------------------------------------- 1 | 2 | {{ $pag := $.Paginator }} 3 | {{ if gt $pag.TotalPages 1 }} 4 | 16 | {{ end }} 17 | -------------------------------------------------------------------------------- /exampleSite/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo -e "\033[0;32mDeploying updates to GitHub...\033[0m" 4 | 5 | # Build the project. 6 | hugo # if using a theme, replace with `hugo -t ` 7 | 8 | # Go To Public folder 9 | cd public 10 | # Add changes to git. 11 | git add . 12 | 13 | # Commit changes. 14 | msg="rebuilding site `date`" 15 | if [ $# -eq 1 ] 16 | then msg="$1" 17 | fi 18 | git commit -m "$msg" 19 | 20 | # Push source and build repos. 21 | git push origin master 22 | 23 | # Come Back up to the Project Root 24 | cd .. 25 | -------------------------------------------------------------------------------- /layouts/partials/posts.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 | 5 |
12 | {{ partial "post_list.html" . }} 13 | {{ partial "pagination.html" . }} 14 |
15 | {{ partial "sidebar.html" . }} 16 |
17 |
18 | -------------------------------------------------------------------------------- /layouts/404.html: -------------------------------------------------------------------------------- 1 | {{ define "main" }} 2 | 3 |
4 |
5 |
6 |
7 |
8 |

404

9 | {{ .Site.Params.title_404 }} 10 |
11 |
12 |
13 |
14 |
15 | 16 | 19 | {{ end }} 20 | -------------------------------------------------------------------------------- /layouts/search/list.html: -------------------------------------------------------------------------------- 1 | {{ define "main" }} 2 |
3 |
4 | 5 | 6 |
13 | {{ if .Site.Params.algolia_search }} 14 | {{ partial "search-algolia.html" . }} 15 | {{ else }} 16 | {{ partial "search-pagefind.html" . }} 17 | {{ end }} 18 |
19 | {{ partial "sidebar.html" . }} 20 |
21 |
22 | {{ end }} 23 | -------------------------------------------------------------------------------- /static/js/mindmap.min.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function(){$(".mindmap").each(function(){MM_FUNCS.drawMindMap(this)})});var MM_FUNCS={li2jsonData:function(c){var a;var b=c.children("a:first");if(b.length!==0){a={"data":{"text":b.text(),"hyperlink":b.attr("href")}}}else{a={"data":{"text":c[0].childNodes[0].nodeValue.trim()}}}c.find("> ul > li").each(function(){if(!a.hasOwnProperty("children")){a.children=[]}a.children.push(MM_FUNCS.li2jsonData($(this)))});return a},drawMindMap:function(a){var d=$(a).find(">ul:first");var c={"root":{}};var b=new kityminder.Minder({renderTo:a});c.root=MM_FUNCS.li2jsonData(d.children("li:first"));b.importData("json",JSON.stringify(c));b.disable();b.execCommand("hand");$(d).hide()}}; -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Number of days of inactivity before an issue becomes stale 2 | daysUntilStale: 60 3 | # Number of days of inactivity before a stale issue is closed 4 | daysUntilClose: 7 5 | # Issues with these labels will never be considered stale 6 | exemptLabels: 7 | - pinned 8 | - security 9 | # Label to use when marking an issue as stale 10 | staleLabel: wontfix 11 | # Comment to post when marking an issue as stale. Set to `false` to disable 12 | markComment: > 13 | This issue has been automatically marked as stale because it has not had 14 | recent activity. It will be closed if no further activity occurs. Thank you 15 | for your contributions. 16 | # Comment to post when closing a stale issue. Set to `false` to disable 17 | closeComment: false 18 | -------------------------------------------------------------------------------- /layouts/partials/math/katex-css.html: -------------------------------------------------------------------------------- 1 | {{ $cssFile := cond hugo.IsProduction "katex.min.css" "katex.css" -}} 2 | {{ $cssUrl := printf "https://unpkg.com/katex@latest/dist/%s" $cssFile -}} 3 | {{ with try (resources.GetRemote $cssUrl) -}} 4 | {{ with .Err -}} 5 | {{ errorf "Could not retrieve KaTeX css file from CDN. Reason: %s." . -}} 6 | {{ else with .Value -}} 7 | {{ with resources.Copy (printf "css/%s" $cssFile) . -}} 8 | {{ $cssHash := . | fingerprint "sha512" -}} 9 | 10 | {{ end -}} 11 | {{ else -}} 12 | {{ errorf "Could not retrieve css file %q from CDN. Reason: invalid KaTeX version %q." $cssUrl "latest" -}} 13 | {{ end -}} 14 | {{ end -}} 15 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: zhaohuabing 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 14 | -------------------------------------------------------------------------------- /theme.toml: -------------------------------------------------------------------------------- 1 | # theme.toml template for a Hugo theme 2 | # See https://github.com/spf13/hugoThemes#themetoml for an example 3 | 4 | name = "Clean White" 5 | license = "Apache" 6 | licenselink = "https://github.com/zhaohuabing/hugo-theme-cleanwhite/blob/master/LICENSE" 7 | description = "A clean, elegant blog theme for hugo" 8 | homepage = "https://github.com/zhaohuabing/hugo-theme-cleanwhite" 9 | tags = [ "minimal", "responsive", "blog","light", "clean", "search"] 10 | features = ["disqus", "site search", "responsive", "google analytics", "side bar"] 11 | min_version = 0.10 12 | 13 | [author] 14 | name = "Huabing Zhao" 15 | homepage = "https://github.com/zhaohuabing" 16 | 17 | # If porting an existing theme 18 | [original] 19 | name = "huxblog" 20 | homepage = "https://github.com/Huxpro/huxpro.github.io" 21 | -------------------------------------------------------------------------------- /exampleSite/content/post/2018-02-09-docker-without-sudo.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "如何使用非root用户执行docker命令" 4 | subtitle: "" 5 | description: "如何使用非root用户执行docker命令" 6 | excerpt: "如何使用非root用户执行docker命令" 7 | date: 2018-02-09 10:00:00 8 | author: "赵化冰" 9 | image: "/img/docker.jpg" 10 | publishDate: 2018-02-09 10:00:00 11 | showtoc: false 12 | tags: 13 | - Tips 14 | - Docker 15 | URL: "/2018/02/09/docker-without-sudo/" 16 | categories: [ Tips ] 17 | --- 18 | 19 | ### Add the docker group if it doesn't already exist: 20 | 21 | sudo groupadd docker 22 | 23 | ### Add the connected user "$USER" to the docker group. Change the user name to match your preferred user if you do not want to use your current user: 24 | 25 | sudo gpasswd -a $USER docker 26 | 27 | ### Either do a newgrp docker or log out/in to activate the changes to groups. 28 | -------------------------------------------------------------------------------- /layouts/shortcodes/bilibili.html: -------------------------------------------------------------------------------- 1 | {{ $videoID := index .Params 0 }} 2 | {{ $pageNum := index .Params 1 | default 1}} 3 | 4 | 16 | 17 | {{ if (findRE "^[bB][vV][0-9a-zA-Z]+$" $videoID) }} 18 |
19 | 20 |
21 | {{ else }} 22 |
23 | 24 |
25 | {{ end }} 26 | -------------------------------------------------------------------------------- /exampleSite/content/post/2018-03-13-use-docker-behind-http-proxy.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "如何配置docker使用HTTP代理" 4 | subtitle: "" 5 | description: "如何配置docker使用HTTP代理" 6 | date: 2018-03-13 18:00:00 7 | author: "赵化冰" 8 | image: "/img/docker.jpg" 9 | publishDate: 2018-03-13 18:00:00 10 | tags: 11 | - Tips 12 | - Docker 13 | URL: "/2018/03/13/use-docker-behind-http-proxy/" 14 | categories: [ Tips ] 15 | --- 16 | ## Ubuntu 17 | ### 设置docker使用http proxy 18 | ``` 19 | sudo /etc/default/docker 20 | 21 | export http_proxy="http://127.0.0.1:3128/" 22 | export https_proxy="http://127.0.0.1:3128/" 23 | export HTTP_PROXY="http://127.0.0.1:3128/" 24 | export HTTPS_PROXY="http://127.0.0.1:3128/" 25 | ``` 26 | 27 | ### 加载配置并重启docker 28 | ``` 29 | sudo service docker restart 30 | ``` 31 | ## CentOS 32 | ### 设置docker使用http proxy 33 | ``` 34 | sudo mkdir -p /etc/systemd/system/docker.service.d 35 | 36 | echo ' 37 | [Service] 38 | Environment="HTTP_PROXY=http://proxy.foo.bar.com:80/" 39 | ' | sudo tee /etc/systemd/system/docker.service.d/http-proxy.conf 40 | ``` 41 | 42 | ### 加载配置并重启docker 43 | ``` 44 | sudo systemctl daemon-reload 45 | sudo systemctl restart docker 46 | ``` 47 | -------------------------------------------------------------------------------- /layouts/partials/header.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | {{ if ( ne .Site.Title "" ) }} 4 | {{ .Site.Title }} 5 | {{ end }}
6 |
7 | 10 | 11 | 12 | 29 | -------------------------------------------------------------------------------- /layouts/partials/math/katex-fonts.html: -------------------------------------------------------------------------------- 1 | {{ $fontFiles := slice -}} 2 | {{ $data := dict -}} 3 | {{ $url := ( printf "https://unpkg.com/katex@latest/dist/fonts?meta" ) -}} 4 | {{ with try (resources.GetRemote $url) -}} 5 | {{ with .Err -}} 6 | {{ errorf "%s" . -}} 7 | {{ else with ( .Value | unmarshal ) -}} 8 | {{ range .files -}} 9 | {{ $fontFiles = $fontFiles | append .path -}} 10 | {{ end -}} 11 | {{ else -}} 12 | {{ errorf "Unable to get fonts meta data %q from CDN. Reason: invalid KaTeX version %q." $url "latest" -}} 13 | {{ end -}} 14 | {{ end -}} 15 | 16 | {{ range $fontFile := $fontFiles -}} 17 | {{ $fontUrl := (printf "https://unpkg.com/katex@latest%s" $fontFile) -}} 18 | {{ with try (resources.GetRemote $fontUrl) -}} 19 | {{ with .Err -}} 20 | {{ errorf "Could not retrieve KaTeX font file from CDN. Reason: %s." . -}} 21 | {{ else with .Value -}} 22 | {{ with resources.Copy (printf "css/fonts/%s" (replace $fontFile "/dist/fonts/" "")) . -}} 23 | {{ .Publish -}} 24 | {{ end -}} 25 | {{ else -}} 26 | {{ errorf "Could not retrieve font file %q from CDN. Reason: invalid KaTeX version %q." $fontUrl "latest" -}} 27 | {{ break -}} 28 | {{ end -}} 29 | {{ end -}} 30 | {{ end -}} 31 | -------------------------------------------------------------------------------- /layouts/top/single.html: -------------------------------------------------------------------------------- 1 | 2 | {{ define "main" }} 3 | 4 |
5 |
6 |
7 | 8 |
14 | {{ if eq (.Param "multilingual") true }} 15 | {{ partial "multilingual-sel.html" . }} 16 | 17 | 18 |
19 | {{$file := "/top/about-zh.md"}} 20 | {{ $file | readFile | markdownify}} 21 |
22 | 23 | 24 |
25 | {{ .Content }} 26 |
27 | {{ else }} 28 | {{ .Content }} 29 | {{ end }} 30 | 31 | {{ partial "comments.html" . }} 32 | 33 |
34 | 35 | {{ partial "sidebar.html" . }} 36 |
37 |
38 |
39 | 40 | {{ end }} 41 | 42 | 43 | -------------------------------------------------------------------------------- /layouts/_default/page.html: -------------------------------------------------------------------------------- 1 | 2 | {{ define "main" }} 3 | 4 |
5 |
6 |
7 | 8 |
14 | {{ if eq (.Param "multilingual") true }} 15 | {{ partial "multilingual-sel.html" . }} 16 | 17 | 18 |
19 | {{$file := "/about/index-zh.md"}} 20 | {{ $file | readFile | markdownify}} 21 |
22 | 23 | 24 |
25 | {{ .Content }} 26 |
27 | {{ else }} 28 | {{ .Content }} 29 | {{ end }} 30 | 31 | {{ partial "comments.html" . }} 32 | 33 |
34 | 35 | {{ partial "sidebar.html" . }} 36 |
37 |
38 |
39 | 40 | {{ end }} 41 | 42 | 43 | -------------------------------------------------------------------------------- /static/js/mindmap.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function() { 2 | $('.mindmap').each(function() { 3 | MM_FUNCS.drawMindMap(this); 4 | }); 5 | }); 6 | 7 | var MM_FUNCS = { 8 | // 将 li 节点转换为 JSON 数据 9 | li2jsonData: function(liNode) { 10 | var liData; 11 | var aNode = liNode.children("a:first"); 12 | if (aNode.length !== 0) { 13 | liData = { 14 | "data": { 15 | "text": aNode.text(), 16 | "hyperlink": aNode.attr("href") 17 | } 18 | }; 19 | } else { 20 | liData = { 21 | "data": { 22 | "text": liNode[0].childNodes[0].nodeValue.trim() 23 | } 24 | }; 25 | } 26 | 27 | liNode.find("> ul > li").each(function() { 28 | if (!liData.hasOwnProperty("children")) { 29 | liData.children = []; 30 | } 31 | liData.children.push(MM_FUNCS.li2jsonData($(this))); 32 | }); 33 | 34 | return liData; 35 | }, 36 | // 绘制脑图 37 | drawMindMap: function(ulParent) { 38 | var ulElement = $(ulParent).find(">ul:first"); 39 | var mmData = {"root": {}}; 40 | var minder = new kityminder.Minder({ 41 | renderTo: ulParent 42 | }); 43 | 44 | mmData.root = MM_FUNCS.li2jsonData(ulElement.children("li:first")); 45 | minder.importData('json', JSON.stringify(mmData)); 46 | minder.disable(); 47 | minder.execCommand('hand'); 48 | $(ulElement).hide(); 49 | } 50 | }; -------------------------------------------------------------------------------- /static/js/hux-blog.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Clean Blog v1.0.0 (http://startbootstrap.com) 3 | * Copyright 2015 Start Bootstrap 4 | * Licensed under Apache 2.0 (https://github.com/IronSummitMedia/startbootstrap/blob/gh-pages/LICENSE) 5 | */ 6 | $(function(){$("[data-toggle='tooltip']").tooltip()}),$(document).ready(function(){$("table").wrap("
"),$("table").addClass("table")}),$(document).ready(function(){$('iframe[src*="youtube.com"]').wrap('
'),$('iframe[src*="youtube.com"]').addClass("embed-responsive-item"),$('iframe[src*="vimeo.com"]').wrap('
'),$('iframe[src*="vimeo.com"]').addClass("embed-responsive-item")}),jQuery(document).ready(function(s){if(s(window).width()>1170){var e=s(".navbar-custom").height(),i=s(".intro-header .container").height();s(window).on("scroll",{previousTop:0},function(){var a=s(window).scrollTop(),o=s(".side-catalog");a0&&s(".navbar-custom").hasClass("is-fixed")?s(".navbar-custom").addClass("is-visible"):s(".navbar-custom").removeClass("is-visible is-fixed"):(s(".navbar-custom").removeClass("is-visible"),a>e&&!s(".navbar-custom").hasClass("is-fixed")&&s(".navbar-custom").addClass("is-fixed")),this.previousTop=a,o.show(),a>i+41?o.addClass("fixed"):o.removeClass("fixed")})}}); -------------------------------------------------------------------------------- /layouts/_default/baseof.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{ partial "head.html" . }} 4 | {{ partial "nav.html" . }} 5 | 6 | {{ block "header" .}} 7 |
8 |
9 |
10 |
11 |
12 |

{{ .Site.Title}}

13 | 14 | {{ .Site.Params.slogan }} 15 |
16 |
17 |
18 |
19 |
20 | {{ end }} 21 | 22 | {{ block "main" . }} 23 | {{ end }} 24 | 25 | {{ partial "footer.html" . }} 26 | {{ if .Store.Get "hasMermaid" }} 27 | 28 | 30 | 35 | {{ end }} 36 | 37 | 38 | -------------------------------------------------------------------------------- /layouts/_default/list.algolia.json: -------------------------------------------------------------------------------- 1 | {{/* Generates a valid Algolia search index */}} 2 | {{- $.Scratch.Add "index" slice -}} 3 | {{- $section := $.Site.GetPage "section" .Section }} 4 | {{- range .Site.AllPages -}} 5 | {{- if and (and (.IsDescendant $section) (and (not .Draft) (not .Params.private))) $section.IsHome -}} 6 | {{- if and .File (not .Params.search_exclude) -}} {{/* ⟵ exclude by flag */}} 7 | {{- $.Scratch.Add "index" (dict 8 | "objectID" .File.UniqueID 9 | "date" .Date.UTC.Unix 10 | "dir" .File.Dir 11 | "expirydate" .ExpiryDate.UTC.Unix 12 | "fuzzywordcount" .FuzzyWordCount 13 | "keywords" .Keywords 14 | "kind" .Kind 15 | "lang" .Lang 16 | "lastmod" .Lastmod.UTC.Unix 17 | "permalink" .Permalink 18 | "publishdate" .PublishDate 19 | "readingtime" .ReadingTime 20 | "relpermalink" .RelPermalink 21 | "html" .Params.Description 22 | "title" .Title 23 | "type" .Type 24 | "url" .RelPermalink 25 | "weight" .Weight 26 | "wordcount" .WordCount 27 | "section" .Section 28 | "tags" .Params.Tags 29 | "categories" .Params.Categories 30 | "author" .Params.authors 31 | "content" (truncate 1000 .Plain) 32 | ) -}} 33 | {{- end -}} 34 | {{- end -}} 35 | {{- end -}} 36 | {{- $.Scratch.Get "index" | jsonify -}} 37 | -------------------------------------------------------------------------------- /layouts/partials/post_list.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | {{ range $index, $element := $.Paginator.Pages }} 4 |
5 | 6 |

7 | {{ .Title }} 8 |

9 | {{with .Params.subtitle }} 10 |

11 | {{ . }} 12 |

13 | {{ end }} 14 |
15 | {{ with .Description }} 16 | {{ . }} 17 | {{ else }} 18 | {{ .Summary}} 19 | {{ end }} 20 |
21 |
22 | 39 | 40 |
41 |
42 | {{ end }} 43 |
44 | -------------------------------------------------------------------------------- /layouts/_default/archive.html: -------------------------------------------------------------------------------- 1 | {{ define "main" }} 2 | {{ $pages := (where (where .Site.Pages "Type" "post") "IsPage" true) }} 3 | 4 |
5 |
6 |
13 |
14 | {{ range ($pages.GroupByDate "2006") }} 15 | {{ if gt .Key 1 }} 16 | {{ $.Scratch.Set "count" 1 }} 17 | {{ range .Pages }} 18 | {{ if (eq ($.Scratch.Get "count") 1) }} 19 | {{ $.Scratch.Set "count" 0 }} 20 |

{{ .Date.Format "2006" }}

21 | {{ end }} 22 | {{ end }} 23 | 24 | 34 | 35 | {{ end }} 36 | {{ end }} 37 |
38 |
39 | {{ partial "sidebar.html" . }} 40 |
41 |
42 | 43 | 44 |
45 | {{ end }} -------------------------------------------------------------------------------- /exampleSite/content/post/2018-02-09-vim-tips.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "Vim Tips" 4 | subtitle: "" 5 | description: "Vim Tips and tricks" 6 | date: 2018-02-09 11:00:00 7 | author: "赵化冰" 8 | image: "/img/2018-02-09-vim-tips/matrix.jpg" 9 | publishDate: 2018-02-09 11:00:00 10 | tags: 11 | - Tips 12 | - Vim 13 | URL: "/2018/02/09/vim-tips/" 14 | categories: [ Tips ] 15 | --- 16 | ## vim graphical cheat sheet 17 | 18 | ![](//img/2018-02-09-vim-tips/vi-vim-cheat-sheet.svg) 19 | 20 | ## Vim Jumps 21 | 22 | * ^ — Move to start of line 23 | * $ — Move to end of line 24 | * b — Move back a word 25 | * w — Move forward a word 26 | * e — Move to the end of the next word 27 | * Ctrl-o and Ctrl-i to go to the previous/next location you jumped to 28 | * ``(two backticks) jump back to where you were 29 | * gi go back to the last place you inserted a text and enter insert mode 30 | 31 | ## Vim Navigations 32 | 33 | * { and } jump paragraph back and forth 34 | * Ctrl-F/B move one screen back and forth 35 | * Search the word under cursor, then n/p to jump to next/previous 36 | 37 | 38 | ## Enable Vim mode in bash 39 | vi ~/.inputrc 40 | set editing-mode vi 41 | 42 | ## Enable system clipboard support 43 | 44 | See if system clipboard is supported: 45 | ``` 46 | $ vim --version | grep clipboard 47 | -clipboard +iconv +path_extra -toolbar 48 | +eval +mouse_dec +startuptime -xterm_clipboard 49 | ``` 50 | 51 | Rinstall vim as vim-gnome: 52 | ``` 53 | sudo apt-get install vim-gnome 54 | ``` 55 | Select what you want using the mouse - then type to copy to clipboard: 56 | ``` 57 | "+y 58 | ``` 59 | 60 | To paste to vim from clipboard type: 61 | ``` 62 | "+p 63 | ``` 64 | ## Others 65 | * Ex: open the current directory 66 | * set number: show line number 67 | -------------------------------------------------------------------------------- /layouts/shortcodes/notice.html: -------------------------------------------------------------------------------- 1 | {{ $_hugo_config := `{ "version": 1 }` }} 2 | 61 |
{{ .Inner }}
62 | -------------------------------------------------------------------------------- /static/js/reward.js: -------------------------------------------------------------------------------- 1 | function ZanShang(){ 2 | this.popbg = $('.zs-modal-bg'); 3 | this.popcon = $('.zs-modal-box'); 4 | this.closeBtn = $('.zs-modal-box .close'); 5 | this.zsbtn = $('.zs-modal-btns .btn'); 6 | this.zsPay = $('.zs-modal-pay'); 7 | this.zsBtns = $('.zs-modal-btns'); 8 | this.zsFooter = $('.zs-modal-footer'); 9 | var that = this; 10 | $('.show-zs').on('click',function(){ 11 | //点击赞赏按钮出现弹窗 12 | that._show(); 13 | that._init(); 14 | }) 15 | } 16 | ZanShang.prototype._hide = function(){ 17 | this.popbg.hide(); 18 | this.popcon.hide(); 19 | } 20 | ZanShang.prototype._show = function(){ 21 | this.popbg.show(); 22 | this.popcon.show(); 23 | this.zsBtns.show(); 24 | this.zsFooter.show(); 25 | this.zsPay.hide(); 26 | } 27 | ZanShang.prototype._init = function(){ 28 | var that = this; 29 | this.closeBtn.on('click',function(){ 30 | that._hide(); 31 | }) 32 | this.popbg.on('click',function(){ 33 | that._hide(); 34 | }) 35 | this.zsbtn.each(function(el){ 36 | $(this).on('click',function(){ 37 | var num = $(this).attr('data-num'); //按钮的对应的数字 38 | var type = $('.zs-type:radio:checked').val();//付款方式 39 | //根据不同付款方式和选择对应的按钮的数字来生成对应的二维码图片,你可以自定义这个图片的路径,默认放在/img/reward目录中 40 | //假如你需要加一个远程路径,比如我的就是 41 | //http://zhaohuabing.com/img/reward/'+type+'-'+num+'.png'; 42 | var src = '/img/reward/'+type+'-'+num+'.png'; 43 | var text = $(this).html(); 44 | var payType=$('#pay-type'), payImage = $('#pay-image'),payText = $('#pay-text'); 45 | if(type=='alipay'){ 46 | payType.html('支付宝'); 47 | }else{ 48 | payType.html('微信'); 49 | } 50 | payImage.attr('src',src); 51 | payText.html(text); 52 | that.zsPay.show(); 53 | that.zsBtns.hide(); 54 | that.zsFooter.hide(); 55 | 56 | }) 57 | }) 58 | } 59 | var zs = new ZanShang(); 60 | -------------------------------------------------------------------------------- /layouts/shortcodes/figure.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | {{- if not ($.Page.Scratch.Get "figurecount") }} 8 | {{ end }} 9 | {{- $.Page.Scratch.Add "figurecount" 1 -}} 10 | 11 | {{- $thumb := .Get "src" | default (printf "%s." (.Get "thumb") | replace (.Get "link") ".") }} 12 |
14 |
16 |
18 | 20 |
21 | {{ with .Get "link" | default (.Get "src") }}{{ end }} 22 | {{- if or (or (.Get "title") (.Get "caption")) (.Get "attr")}} 23 |
24 | {{- with .Get "title" }}

{{.}}

{{ end }} 25 | {{- if or (.Get "caption") (.Get "attr")}} 26 |

27 | {{- .Get "caption" -}} 28 | {{- with .Get "attrlink"}}{{ .Get "attr" }}{{ else }}{{ .Get "attr"}}{{ end -}} 29 |

30 | {{- end }} 31 |
32 | {{- end }} 33 |
34 |
35 | -------------------------------------------------------------------------------- /layouts/partials/reward.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | {{ if .Site.Params.reward_guide }} 4 |

「{{ .Site.Params.reward_guide }}」

5 | {{ else }} 6 |

「真诚赞赏,手留余香」

7 | {{ end }} 8 | 9 |
10 |
11 |
12 |
13 | 14 | {{ .Site.Title }} 15 | {{ if .Site.Params.reward_guide }} 16 |

{{ .Site.Params.reward_guide }}

17 | {{ else }} 18 |

真诚赞赏,手留余香

19 | {{ end }} 20 | 21 |
22 |
23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
32 | 33 |

使用微信扫描二维码完成支付

34 | 35 |
36 |
37 | 41 |
42 | 43 | -------------------------------------------------------------------------------- /exampleSite/content/post/2018-05-24-set_up_my_ubuntu_desktop.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "Everything about Setting Up My Ubuntu Desktop" 4 | description: "Everything about setting up my own ubuntu desktop, it's just a Note in case I need it later" 5 | excerpt: "Everything about setting up my own ubuntu desktop, it's just a Note in case I need it later" 6 | date: 2018-05-24 7 | author:     "赵化冰" 8 | image: "/img/2018-05-23-service_2_service_auth/background.jpg" 9 | publishDate: 2018-05-24 10 | tags: 11 | - ubuntu 12 | URL: "/2018/05/24/set_up_my_ubuntu_desktop/" 13 | categories: [ "Tips" ] 14 | --- 15 | 16 | ## Generate SSH Key Pair 17 | 18 | ``` 19 | ssh-keygen -C "zhaohuabing@gmail.com" 20 | ``` 21 | 22 | ## Shadowsocks 23 | 24 | Install shadowsokcs 25 | 26 | ``` 27 | sudo apt-get install python3-pip 28 | 29 | sudo pip3 install shadowsocks 30 | ``` 31 | 32 | Create config at ```config/shadowsocks.json```, with the following content: 33 | 34 | ``` 35 | { 36 | "server":"remote-shadowsocks-server-ip-addr", 37 | "server_port":443, 38 | "local_address":"127.0.0.1", 39 | "local_port":1080, 40 | "password":"your-passwd", 41 | "timeout":300, 42 | "method":"aes-256-cfb", 43 | "fast_open":false, 44 | "workers":1 45 | } 46 | ``` 47 | 48 | Start a local socks proxy 49 | 50 | ``` 51 | sudo sslocal -c config/shadowsocks.json -d start 52 | ``` 53 | 54 | In case there is an openssl error, modify shadowsocks source file. 55 | 56 | ``` 57 | sudo vi /usr/local/lib/python3.6/dist-packages/shadowsocks/crypto/openssl.py 58 | 59 | :%s/cleanup/reset/gc 60 | ``` 61 | 62 | Convert shadowsocks socks proxy to http proxy 63 | 64 | ``` 65 | sudo apt-get install polipo 66 | 67 | echo "socksParentProxy = localhost:1080" | sudo tee -a /etc/polipo/config 68 | sudo service polipo restart 69 | ``` 70 | 71 | Http proxy now is available at port 8123 72 | 73 | # Set bing wallpaper as desktop background 74 | 75 | ``` 76 | sudo add-apt-repository ppa:whizzzkid/bingwallpaper 77 | sudo apt-get update 78 | sudo apt-get install bingwallpaper 79 | ``` 80 | 81 | # Use vim mode in bash 82 | 83 | ``` 84 | echo 'set -o vi'>> ~/.bashrc 85 | ``` 86 | -------------------------------------------------------------------------------- /layouts/_default/section.html: -------------------------------------------------------------------------------- 1 | {{ define "main" }} 2 | 3 |
4 |
5 |
6 | 7 |
11 | 12 | {{ .Content }} 13 | {{ partial "comments.html" . }} 14 | 15 |
16 | 17 | 53 |
54 |
55 |
56 | 57 | {{ end }} 58 | 59 | 60 | -------------------------------------------------------------------------------- /layouts/taxonomy/terms.html: -------------------------------------------------------------------------------- 1 | {{ define "main" }} 2 | 3 |
4 |
5 |
6 | 7 |
11 | 12 | {{ .Content }} 13 | {{ partial "comments.html" . }} 14 | 15 |
16 | 17 | 53 |
54 |
55 |
56 | 57 | {{ end }} 58 | 59 | 60 | -------------------------------------------------------------------------------- /layouts/partials/comments.html: -------------------------------------------------------------------------------- 1 | {{ if .Site.Params.giscus }} 2 | 15 | {{ end }} 16 | {{ if .Site.Params.disqus_proxy }} 17 | 18 |
19 | 20 | 31 | {{ else if .Site.Config.Services.Disqus.Shortname }} 32 | 33 |
34 | {{ template "_internal/disqus.html" . }} 35 | {{ else if .Site.Params.twikoo_env_id }} 36 |
37 | 38 | 44 | {{ end }} 45 | 46 | 47 | {{ if .Site.Params.artalk_enable }} 48 | 49 | 50 | 51 | 52 |
53 | 54 | 63 | 64 | {{ end }} -------------------------------------------------------------------------------- /layouts/shortcodes/post-image.html: -------------------------------------------------------------------------------- 1 | {{ $image := (.Page.Resources.GetMatch (index .Params.image)) }} 2 | {{ $alt := .Get "alt" }} 3 | {{ $width := .Get "width" }} 4 | {{ $borderless := .Get "borderless" }} 5 | {{ $placeholder := ($image.Resize "48x q20") | images.Filter (images.GaussianBlur 6) }} 6 | {{ $src := $image }} 7 | {{ $src_set := ""}} 8 | 9 | {{ $src_set = (print $image.RelPermalink " " $image.Width "w") }} 10 | {{ $src := $image }} 11 | 12 | {{ if ge $image.Width "500"}} 13 | {{ $x_small := $image.Resize "500x" }} 14 | {{ $src_set = (print $src_set ", " $x_small.RelPermalink " 500w") }} 15 | {{ end }} 16 | 17 | {{ if ge $image.Width "800"}} 18 | {{ $small := $image.Resize "800x" }} 19 | {{ $src_set = (print $src_set ", " $small.RelPermalink " 800w") }} 20 | {{ end }} 21 | 22 | {{ if ge $image.Width "1200"}} 23 | {{ $medium := $image.Resize "1200x" }} 24 | {{ $src_set = (print $src_set ", " $medium.RelPermalink " 1200w") }} 25 | {{ end }} 26 | 27 | {{ if gt $image.Width "1500"}} 28 | {{ $large := $image.Resize "1500x" }} 29 | {{ $src_set = (print $src_set ", " $large.RelPermalink " 1500w") }} 30 | {{ end }} 31 | 32 | {{ $border_class := "image-border" }} 33 | {{ if $borderless}} 34 | {{ $border_class = "" }} 35 | {{ end }} 36 | 37 | 38 | 57 | 58 |
59 | {{ if .Get "lightbox" }} 60 | 61 | {{ end }} 62 | {{ $alt }} 65 | {{ if .Get "lightbox" }} 66 | 67 | {{ end }} 68 | {{ if .Inner }} 69 |
70 | {{ .Inner }} 71 |
72 | {{ end }} 73 |
-------------------------------------------------------------------------------- /static/css/hugo-easy-gallery.min.css: -------------------------------------------------------------------------------- 1 | .gallery .box,figure{position:relative}.gallery,figure{overflow:hidden}.gallery{margin:10px;max-width:768px}.gallery .box{float:left;width:100%;padding-bottom:100%}@media only screen and (min-width :365px){.gallery .box{width:50%;padding-bottom:50%}}@media only screen and (min-width :480px){.gallery .box{width:33.3%;padding-bottom:33.3%}}@media only screen and (min-width :9999px){.box{width:25%;padding-bottom:25%}}.fancy-figure:not(.caption-effect-appear) figcaption,.gallery.hover-effect-zoom .img,.gallery.hover-transition figure,.gallery:not(.caption-effect-appear) figcaption{-webkit-transition:.3s ease-in-out;-moz-transition:.3s ease-in-out;-o-transition:.3s ease-in-out;transition:.3s ease-in-out}.gallery figure{position:absolute;left:5px;right:5px;top:5px;bottom:5px}.gallery .img,figure a{position:absolute;bottom:0;left:0;right:0}.gallery.hover-effect-grow figure:hover,.gallery.hover-effect-zoom figure:hover .img{transform:scale(1.05)}.gallery.hover-effect-shrink figure:hover{transform:scale(.95)}.gallery.hover-effect-slidedown figure:hover{transform:translateY(5px)}.gallery.hover-effect-slideup figure:hover{transform:translateY(-5px)}.gallery .img{top:0;background-size:cover;background-position:50% 50%;background-repeat:no-repeat}.fancy-figure.caption-position-none figcaption,.gallery img,.gallery.caption-position-none figcaption{display:none}figure a{top:0}.fancy-figure figcaption,.gallery figcaption{position:absolute;bottom:0;left:0;right:0;background:rgba(0,0,0,.5);color:#fff;text-align:center;font-size:75%;opacity:1;cursor:pointer}.fancy-figure.caption-position-center figcaption,.gallery.caption-position-center figcaption{top:0;padding:40% 5px}.fancy-figure.caption-position-bottom figcaption,.gallery.caption-position-bottom figcaption{padding:5px}.fancy-figure.caption-effect-appear figure:not(:hover) figcaption,.fancy-figure.caption-effect-fade figure:not(:hover) figcaption,.gallery.caption-effect-appear figure:not(:hover) figcaption,.gallery.caption-effect-fade figure:not(:hover) figcaption{background:rgba(0,0,0,0);opacity:0}.fancy-figure.caption-effect-slide.caption-position-bottom figure:not(:hover) figcaption,.gallery.caption-effect-slide.caption-position-bottom figure:not(:hover) figcaption{margin-bottom:-100%}.fancy-figure.caption-effect-slide.caption-position-center figure:not(:hover) figcaption,.gallery.caption-effect-slide.caption-position-center figure:not(:hover) figcaption{top:100%}figcaption p{margin:auto} 2 | -------------------------------------------------------------------------------- /static/js/jquery.tagcloud.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | 3 | $.fn.tagcloud = function(options) { 4 | var opts = $.extend({}, $.fn.tagcloud.defaults, options); 5 | tagWeights = this.map(function(){ 6 | return $(this).attr("rel"); 7 | }); 8 | tagWeights = jQuery.makeArray(tagWeights).sort(compareWeights); 9 | lowest = tagWeights[0]; 10 | highest = tagWeights.pop(); 11 | range = highest - lowest; 12 | if(range === 0) {range = 1;} 13 | // Sizes 14 | if (opts.size) { 15 | fontIncr = (opts.size.end - opts.size.start)/range; 16 | } 17 | // Colors 18 | if (opts.color) { 19 | colorIncr = colorIncrement (opts.color, range); 20 | } 21 | return this.each(function() { 22 | weighting = $(this).attr("rel") - lowest; 23 | if (opts.size) { 24 | $(this).css({"font-size": opts.size.start + (weighting * fontIncr) + opts.size.unit}); 25 | } 26 | if (opts.color) { 27 | // change color to background-color 28 | $(this).css({"backgroundColor": tagColor(opts.color, colorIncr, weighting)}); 29 | } 30 | }); 31 | }; 32 | 33 | $.fn.tagcloud.defaults = { 34 | size: {start: 14, end: 18, unit: "pt"} 35 | }; 36 | 37 | // Converts hex to an RGB array 38 | function toRGB (code) { 39 | if (code.length == 4) { 40 | code = jQuery.map(/\w+/.exec(code), function(el) {return el + el; }).join(""); 41 | } 42 | hex = /(\w{2})(\w{2})(\w{2})/.exec(code); 43 | return [parseInt(hex[1], 16), parseInt(hex[2], 16), parseInt(hex[3], 16)]; 44 | } 45 | 46 | // Converts an RGB array to hex 47 | function toHex (ary) { 48 | return "#" + jQuery.map(ary, function(i) { 49 | hex = i.toString(16); 50 | hex = (hex.length == 1) ? "0" + hex : hex; 51 | return hex; 52 | }).join(""); 53 | } 54 | 55 | function colorIncrement (color, range) { 56 | return jQuery.map(toRGB(color.end), function(n, i) { 57 | return (n - toRGB(color.start)[i])/range; 58 | }); 59 | } 60 | 61 | function tagColor (color, increment, weighting) { 62 | rgb = jQuery.map(toRGB(color.start), function(n, i) { 63 | ref = Math.round(n + (increment[i] * weighting)); 64 | if (ref > 255) { 65 | ref = 255; 66 | } else { 67 | if (ref < 0) { 68 | ref = 0; 69 | } 70 | } 71 | return ref; 72 | }); 73 | return toHex(rgb); 74 | } 75 | 76 | function compareWeights(a, b) 77 | { 78 | return a - b; 79 | } 80 | 81 | })(jQuery); 82 | -------------------------------------------------------------------------------- /layouts/shortcodes/gallery.html: -------------------------------------------------------------------------------- 1 | 5 | 6 | {{- if not ($.Page.Scratch.Get "figurecount") }} 7 | {{ end }} 8 | {{- $.Page.Scratch.Add "figurecount" 1 }} 9 | {{ $baseURL := .Site.BaseURL }} 10 | 48 | -------------------------------------------------------------------------------- /static/js/load-photoswipe.js: -------------------------------------------------------------------------------- 1 | /* 2 | Put this file in /static/js/load-photoswipe.js 3 | Documentation and licence at https://github.com/liwenyip/hugo-easy-gallery/ 4 | */ 5 | 6 | /* Show an alert if this js file has been loaded twice */ 7 | if (window.loadphotoswipejs) { 8 | window.alert("You've loaded load-photoswipe.js twice. See https://github.com/liwenyip/hugo-easy-gallery/issues/6") 9 | } 10 | var loadphotoswipejs = 1 11 | 12 | /* TODO: Make the share function work */ 13 | $( document ).ready(function() { 14 | /* 15 | Initialise Photoswipe 16 | */ 17 | var items = []; // array of slide objects that will be passed to PhotoSwipe() 18 | // for every figure element on the page: 19 | $('figure').each( function() { 20 | if ($(this).attr('class') == 'no-photoswipe') return true; // ignore any figures where class="no-photoswipe" 21 | // get properties from child a/img/figcaption elements, 22 | var $figure = $(this), 23 | $a = $figure.find('a'), 24 | $img = $figure.find('img'), 25 | $src = $a.attr('href'), 26 | $title = $img.attr('alt'), 27 | $msrc = $img.attr('src'); 28 | // if data-size on tag is set, read it and create an item 29 | if ($a.data('size')) { 30 | var $size = $a.data('size').split('x'); 31 | var item = { 32 | src : $src, 33 | w : $size[0], 34 | h : $size[1], 35 | title : $title, 36 | msrc : $msrc 37 | }; 38 | console.log("Using pre-defined dimensions for " + $src); 39 | // if not, set temp default size then load the image to check actual size 40 | } else { 41 | var item = { 42 | src : $src, 43 | w : 800, // temp default size 44 | h : 600, // temp default size 45 | title : $title, 46 | msrc : $msrc 47 | }; 48 | console.log("Using default dimensions for " + $src); 49 | // load the image to check its dimensions 50 | // update the item as soon as w and h are known (check every 30ms) 51 | var img = new Image(); 52 | img.src = $src; 53 | var wait = setInterval(function() { 54 | var w = img.naturalWidth, 55 | h = img.naturalHeight; 56 | if (w && h) { 57 | clearInterval(wait); 58 | item.w = w; 59 | item.h = h; 60 | console.log("Got actual dimensions for " + img.src); 61 | } 62 | }, 30); 63 | } 64 | // Save the index of this image then add it to the array 65 | var index = items.length; 66 | items.push(item); 67 | // Event handler for click on a figure 68 | $figure.on('click', function(event) { 69 | event.preventDefault(); // prevent the normal behaviour i.e. load the hyperlink 70 | // Get the PSWP element and initialise it with the desired options 71 | var $pswp = $('.pswp')[0]; 72 | var options = { 73 | index: index, 74 | bgOpacity: 0.8, 75 | showHideOpacity: true 76 | } 77 | new PhotoSwipe($pswp, PhotoSwipeUI_Default, items, options).init(); 78 | }); 79 | }); 80 | }); -------------------------------------------------------------------------------- /static/js/hux-blog.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Clean Blog v1.0.0 (http://startbootstrap.com) 3 | * Copyright 2015 Start Bootstrap 4 | * Licensed under Apache 2.0 (https://github.com/IronSummitMedia/startbootstrap/blob/gh-pages/LICENSE) 5 | */ 6 | 7 | // Tooltip Init 8 | $(function() { 9 | $("[data-toggle='tooltip']").tooltip(); 10 | }); 11 | 12 | 13 | // make all images responsive 14 | /* 15 | * Unuse by Hux 16 | * actually only Portfolio-Pages can't use it and only post-img need it. 17 | * so I modify the _layout/post and CSS to make post-img responsive! 18 | */ 19 | // $(function() { 20 | // $("img").addClass("img-responsive"); 21 | // }); 22 | 23 | // responsive tables 24 | $(document).ready(function() { 25 | $("table").wrap("
"); 26 | $("table").addClass("table"); 27 | }); 28 | 29 | // responsive embed videos 30 | $(document).ready(function () { 31 | $('iframe[src*="youtube.com"]').wrap('
'); 32 | $('iframe[src*="youtube.com"]').addClass('embed-responsive-item'); 33 | $('iframe[src*="vimeo.com"]').wrap('
'); 34 | $('iframe[src*="vimeo.com"]').addClass('embed-responsive-item'); 35 | }); 36 | 37 | // Navigation Scripts to Show Header on Scroll-Up 38 | jQuery(document).ready(function($) { 39 | var MQL = 1170; 40 | 41 | //primary navigation slide-in effect 42 | if ($(window).width() > MQL) { 43 | var headerHeight = $('.navbar-custom').height(), 44 | bannerHeight = $('.intro-header .container').height(); 45 | $(window).on('scroll', { 46 | previousTop: 0 47 | }, 48 | function() { 49 | var currentTop = $(window).scrollTop(), 50 | $catalog = $('.side-catalog'); 51 | //check if user is scrolling up 52 | if (currentTop < this.previousTop) { 53 | //if scrolling up... 54 | if (currentTop > 0 && $('.navbar-custom').hasClass('is-fixed')) { 55 | $('.navbar-custom').addClass('is-visible'); 56 | } else { 57 | $('.navbar-custom').removeClass('is-visible is-fixed'); 58 | } 59 | } else { 60 | //if scrolling down... 61 | $('.navbar-custom').removeClass('is-visible'); 62 | if (currentTop > headerHeight && !$('.navbar-custom').hasClass('is-fixed')) $('.navbar-custom').addClass('is-fixed'); 63 | } 64 | this.previousTop = currentTop; 65 | 66 | //adjust the appearance of side-catalog 67 | $catalog.show() 68 | if (currentTop > (bannerHeight + 41)) { 69 | $catalog.addClass('fixed') 70 | } else { 71 | $catalog.removeClass('fixed') 72 | } 73 | }); 74 | } 75 | }); 76 | -------------------------------------------------------------------------------- /exampleSite/content/post/2018-05-23-service_2_service_auth.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | 4 | title: "微服务安全沉思录之二" 5 | subtitle: "服务间认证与鉴权" 6 | description: "除来自用户的访问请求以外,微服务应用中的各个微服务相互之间还有大量的访问,根据应用系统数据敏感程度不同,对于系统内微服务的访问也需要进行相应的安全控制。" 7 | showonlyimage: false 8 | excerpt: "除来自用户的访问请求以外,微服务应用中的各个微服务相互之间还有大量的访问,根据应用系统数据敏感程度不同,对于系统内微服务的访问也需要进行相应的安全控制。" 9 | author:     "赵化冰" 10 | date: 2018-05-23T15:00:00 11 | image: "/img/2018-05-23-service_2_service_auth/background.jpg" 12 | publishDate: 2018-05-23T15:00:00 13 | tags: 14 | - Microservice 15 | - Security 16 | URL: "/2018/05/23/service_2_service_auth/" 17 | categories: [ Tech ] 18 | --- 19 | 20 | 21 | ## 服务间认证与鉴权 22 | 23 | 除来自用户的访问请求以外,微服务应用中的各个微服务相互之间还有大量的访问,包括下述场景: 24 | * 用户间接触发的微服务之间的相互访问
25 | 例如在一个网上商店应用中,用户访问购物车微服务进行结算时,购物车微服务可能需要访问用户评级微服务获取用户的会员级别,以得到用户可以享受购物折扣。 26 | * 非用户触发的微服务之间的相互访问
27 | 例如数据同步或者后台定时任务导致的微服务之间的相互访问。 28 | 29 | 根据应用系统的数据敏感程度的不同,对于系统内微服务的相互访问可能有不同的安全要求。 30 | 31 | ### 对微服务之间的相互访问不进行安全控制 32 | 在某些场景下,可以假设同一应用中微服务之间的相互访问都是可信的。在这种情况下,应用依赖于内部网络的防火墙及其他网络安全措施来保证安全性。在这种情况对入侵者攻击进入内部网络后没有保护措施。入侵者可以对微服务间的通信进行典型的中间人攻击,例如窃听通信内容,伪造和修改通信数据,甚至假装为一个合法的微服务进行通信。 33 | 34 | ### 采用Service Account(服务账号)进行安全控制 35 | “内部网络中微服务之间的所有通信都是可信的”这个假设在某些场景下是不成立的,特别是在微服务中保存有用户信息这种非常重要的数据的情况下。将敏感信息直接暴露在内部攻击下的做法是非常危险的。 解决该问题的一种方案是使用服务账号来对微服务之间的相互访问进行控制。 36 | 37 | 用户权限控制的一个普遍方法是使用”用户账号(User Account)”来标识一个系统用户,并对其进行身份认证和操作鉴权。类似地,可以为系统中每一个服务也创建一个账号,称为”服务账号(Service Accout)“。 该服务账号表示了微服务的身份,以用于控制该微服务对系统中其它微服务的访问权限,如可以对哪些微服务的哪些资源进行何种操作。当一个微服务访问另一个微服务时,被访问的微服务需要验证访问者的服务账号,以确定其身份和资源操作权限。 38 | 39 | #### SPIFEE标准 40 | [Secure Production Identity Framework For Everyone (SPIFFE)](https://spiffe.io/)是一套服务之间相互进行身份识别的标准,主要包含以下内容: 41 | * SPIFFE ID标准,SPIFFE ID是服务的唯一标识,实现为统一资源标识"Uniform Resource Identifier (URI)”符。 42 | * SVID(SPIFFE Verifiable Identity Document)标准,将SPIFFE ID编码到一个加密的可验证文档中。 43 | * 颁发/撤销 SVID的一套API标准。 44 | 45 | SPIFFE SVID目前支持的实现方式是X.509数字证书,在x.509 SVID中,采用X.509数字证书的SAN(Subject Alternative Name)扩展字段来保存SPIFFE ID。 46 | 47 | #### Istio Auth开源实现 48 | Istio服务网格项目的Auth组件实现了SPIFFE标准,可以为网格中服务颁发符合SPIFFE SVID标准的证书,并为服务提供身份认证,细粒度的操作鉴权以及通信加密。Istio的架构如下图所示: 49 | ![](/img/2018-05-23-service_2_service_auth/auth.png) 50 | 51 | Istio Auth采用了Kubernetes的service account来作为服务标识,其SPIFFE ID的格式为spiffe://<domain>/ns/<namespace>/sa/<serviceaccount>,其中各组成部分如下: 52 | * domain 域名 53 | * namespace kubernetes service account所在的Namespace 54 | * serviceaccount kubernetes中定义的service account名 55 | 56 | Istio Auth提供了一个用于颁发证书的CA。在服务部署时,CA监听Kubernetes API Server, 为集群中的每一个Service Account创建一对密钥和证书。当Pod创建时,Kubernetes根据该Pod关联的Service Account将密钥和证书以Kubernetes Secrets资源的方式加载为Pod的Volume,以供Envoy使用。 57 | 58 | 在服务运行时,服务间的通信被Envoy接管,Envoy使用证书在服务间进行双向SSL握手验证通信双方服务的身份,并提供加密的通信通道。 59 | 60 | ### 采用用户身份进行安全控制 61 | 采用服务账号进行服务间交互的鉴权不能控制到用户粒度的访问权限,这在某些场景下可能出现数据泄露问题。 62 | 63 | 例如在网上商店应用中,用户访问购物车微服务进行结算时,购物车微服务需要访问另一个微服务中的用户历史购物数据。如果只采用服务账号对购物车微服务进行安全控制,存在用户A通过购物车微服务向后端微服务发起一个获取用户B历史购物数据请求的风险。因为后端的微服务并不能得知发起请求的是哪一个用户,因此会不加判断地返回购物车微服务请求的用户历史购物数据。 64 | 65 | 解决方案是将用户信息从用户直接访问的第一个微服务向后传递到调用链上的每一个微服务,调用链上的每一个微服务都使用该用户信息对用户能访问的资源进行判断。在一个大型的微服务系统中,一个调用链可能会非常长,导致该方案的实现比较复杂。 66 | 67 | 我们需要根据应用的使用场景,每个微服务中数据的敏感程度来决定选择哪一种服务间安全的实施方式。 68 | -------------------------------------------------------------------------------- /layouts/partials/search-algolia.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 |
10 | 11 | 75 | 76 | 110 | -------------------------------------------------------------------------------- /exampleSite/content/post/2018-04-11-service-mesh-vs-api-gateway.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "Service Mesh 和 API Gateway的关系探讨(译文)" 4 | subtitle: "" 5 | description: "API Gateway和Service Mesh的关系是我最近一直在思考的问题,也和同事及社区的朋友之间进行了一些讨论。这篇短文很清晰地总结了两者之间的相似之处以及这两者在微服务架构中的不同用途。" 6 | excerpt: "API Gateway和Service Mesh的关系是我最近一直在思考的问题,也和同事及社区的朋友之间进行了一些讨论。这篇短文很清晰地总结了两者之间的相似之处以及这两者在微服务架构中的不同用途。" 7 | date: 2018-04-11 09:32:00 8 | author: "赵化冰" 9 | image: "/img/2018-04-11-service-mesh-vs-api-gateway/background.jpg" 10 | publishDate: 2018-04-11 09:32:00 11 | tags: 12 | - Microservice 13 | - Service Mesh 14 | - API Gateway 15 | URL: "/2018/04/11/service-mesh-vs-api-gateway/" 16 | categories: [ Tech ] 17 | --- 18 | 19 | ## Service Mesh vs API Gateway 20 | 21 | 在[前一篇关于Service Mesh的文章](https://medium.com/microservices-in-practice/service-mesh-for-microservices-2953109a3c9a)中,我提到了几个关于Service Mesh和API Gateway之间关系的问题,在本篇文章中,我打算就Service Mesh和API Gateway的用途进行进一步讨论。 22 | 23 | 为了区分API Gateway和Service Mesh,让我们先分别看看两者各自的关键特征。 24 | 25 | ## API Gateway: 将服务作为被管理的API向外部暴露 26 | 27 | 28 | 使用API Gateway的主要目的是将微服务作为被管理的API暴露(给外部系统)。因此,我们在API Gateway层开发的API或者边界服务对外提供了业务功能。 29 | 30 | API/边界服务调用下游的组合或者原子微服务,通过组合/混装多个下游微服务的方式来提供业务逻辑。 31 | 32 | 在API/Edge服务调用下游服务时,需要采用一种可靠的通信方式,应用了断路器,超时,负载均衡/故障转移等可靠性模式。因此大部分的API Gateway解决方案都内置了这些特性。 33 | 34 | API Gateway也内置了以下特性的支持,包括:服务发现,分析(可见性:性能指标,监控,分布式日志,分布式调用追踪)和安全。 35 | 36 | API Gateway和API管理生态系统的其他组件的关系紧密,比如: API 市场/商店, API 发布门户。 37 | 38 | ## Service Mesh:微服务的网络通信基础设施 39 | 40 | 现在我们来看看Service Mesh有哪些不同。 41 | 42 | Service Mesh是一个网络通信基础设施, 可以用于将应用层的网络通信功能从你的服务代码中剥离出来。 43 | 44 | 采用Service Mesh, 你不用在服务代码中实现用于可靠通信的模式如断路,超时等,类似地,Service Mesh也提供了服务发现,服务可见性等其他功能。 45 | 46 | ## API Gateway和Service Mesh实践 47 | 48 | API Gateway和Service Mesh之间的主要不同点:API Gateway是暴露API/边界服务的关键组件,而Service Mesh则仅仅是一个服务间通信的基础设施,并不了解应用中的业务逻辑。 49 | 50 | 下图说明了API Gateway和Service Mesh的关系。如同前面所说,这两者之间也有一些重叠的部分(例如断路器等),但重要的是需要理解这两者是用于完全不同的用途。 51 | 52 | 53 | 图1: API Gateway和Service Mesh实践 54 | 55 | ![](/img/2018-04-11-service-mesh-vs-api-gateway/service-mesh-vs-api-gateway.png) 56 | 57 | 如上图所示,Service Mesh作为Sidecar(边车)和服务一起部署,它是独立于服务的业务逻辑的。 58 | 59 | 另一方面,API Gateway 提供了所有的API服务(这些API服务有明确定义的业务功能),它是应用业务逻辑的一部分。API Gateway可以具有内建的服务间通信能力,但它也可以使用Service Mesh来调用下游服务(API Gateway->Service Mesh->Microservices)。 60 | 61 | 在API管理层次,你可以使用API Gateway内建的服务间通信能力;也可以通过Service Mesh来调用下游服务,以将应用网络通信功能从应用程序转移到Service Mesh中。 62 | 63 | ## 译者按 64 | 65 | API Gateway和Service Mesh的关系是我最近一直在思考的问题,也和同事及社区的朋友之间进行了一些讨论。这篇短文很清晰地总结了两者之间的相似之处以及这两者在微服务架构中的不同用途。 66 | 67 | 文章中提到“可以使用API Gateway内建的服务间通信能力;也可以通过Service Mesh来调用下游服务”。在和同事讨论时,大家提到一个比较重要的考虑因素是在API Gateway处引入一个Sidecar可能带来的额外延迟。 68 | 69 | API Gateway作为微服务引用的流量入口,其对效率要求较高,如果随API Gateway部署一个Sidecar,可能对效率有一定影响。 70 | 71 | 我对此未进行测试,但从理论上来说,服务发现,重试,断路等逻辑无论放到API Gateway还是Service Mesh中耗时应该是差不多的,部署Sidecar只是增加了创建一个本地链接的消耗,如下图所示: 72 | ![](/img/2018-04-11-service-mesh-vs-api-gateway/api-gateway-with-service-mesh.png) 73 | 74 | 将API Gateway和Service Mesh的功能进行清晰划分,API Gateway负责应用逻辑,Service Mesh负责服务通讯,Metrics收集等微服务基础设施,这样划分后在架构上更为清晰。对于效率问题,我们可以考虑对API Gateway进行水平扩展来解决。 75 | 76 | ## 原文 77 | 78 | 本译文发表已征得原作者同意,原文参见 [Service Mesh vs API Gateway](https://medium.com/microservices-in-practice/service-mesh-vs-api-gateway-a6d814b9bf56) 79 | 80 | -------------------------------------------------------------------------------- /exampleSite/content/post/2017-11-07-istio-traffic-shifting.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "使用Istio实现应用流量转移" 4 | subtitle:   "本文翻译自istio官方文档" 5 | description: "本任务将演示如何将应用流量逐渐从旧版本的服务迁移到新版本。通过Istio,可以使用一系列不同权重的规则(10%,20%,··· 100%)将流量平缓地从旧版本服务迁移到新版本服务。" 6 | excerpt: "本任务将演示如何将应用流量逐渐从旧版本的服务迁移到新版本。通过Istio,可以使用一系列不同权重的规则(10%,20%,··· 100%)将流量平缓地从旧版本服务迁移到新版本服务。" 7 | date: 2017-11-07 8 | author:     "赵化冰" 9 | image: "/img/istio-traffic-shifting/crossroads.png" 10 | categories: [ "Tech"] 11 | tags: 12 | - Istio 13 | URL: "/2017/11/07/istio-traffic-shifting/" 14 | --- 15 | 16 | 关于Istio的更多内容请参考[istio中文文档](http://istio.doczh.cn/)。 17 | 18 | 原文参见[Traffic Shifting](https://istio.io/docs/tasks/traffic-management/traffic-shifting.html)。 19 | 20 | 本任务将演示如何将应用流量逐渐从旧版本的服务迁移到新版本。通过Istio,可以使用一系列不同权重的规则(10%,20%,··· 100%)将流量平缓地从旧版本服务迁移到新版本服务。 21 | 22 | 为简单起见,本任务将采用两步将流量从`reviews:v1` 迁移到 `reviews:v3`,权重分别为50%,100%。 23 | 24 | 25 | # 开始之前 26 | 27 | * 参照文档[安装指南](http://istio.doczh.cn/docs/setup/kubernetes/index.html)中的步骤安装Istio。 28 | 29 | * 部署[BookInfo](http://istio.doczh.cn/docs/guides/bookinfo.html) 示例应用程序。 30 | 31 | > 请注意:本文档假设示采用kubernetes部署示例应用程序。所有的示例命令行都采用规则yaml文件(例如`samples/bookinfo/kube/route-rule-all-v1.yaml`)指定的kubernetes版本。如果在不同的环境下运行本任务,请将`kube`修改为运行环境中相应的目录(例如,对基于Consul的运行环境,目录就是`samples/bookinfo/consul/route-rule-all-v1.yaml`)。 32 | 33 | 34 | # 基于权重的版本路由 35 | 36 | 1. 将所有微服务的缺省版本设置为v1. 37 | 38 | ```bash 39 | istioctl create -f samples/bookinfo/kube/route-rule-all-v1.yaml 40 | ``` 41 | 42 | 1. 在浏览器中打开http://$GATEWAY_URL/productpage, 确认`reviews` 服务目前的活动版本是v1。 43 | 44 | 可以看到浏览器中出现BooInfo应用的productpage页面。 45 | 注意`productpage`显示的评价内容不带星级。这是由于`reviews:v1`不会访问`ratings`服务。 46 | 47 | > 请注意:如果之前执行过 [配置请求路由](http://istio.doczh.cn/docs/tasks/traffic-management/request-routing.html)任务,则需要先注销测试用户“jason”或者删除之前单独为该用户创建的测试规则: 48 | 49 | ```bash 50 | istioctl delete routerule reviews-test-v2 51 | ``` 52 | 53 | 1. 首先,使用下面的命令把50%的流量从`reviews:v1`转移到`reviews:v3`: 54 | 55 | ```bash 56 | istioctl replace -f samples/bookinfo/kube/route-rule-reviews-50-v3.yaml 57 | ``` 58 | 59 | 注意这里使用了`istioctl replace`而不是`create`。 60 | 61 | 1. 在浏览器中多次刷新`productpage`页面,大约有50%的几率会看到页面中出现带红星的评价内容。 62 | 63 | > 请注意:在目前的Envoy sidecar实现中,可能需要刷新`productpage`很多次才能看到流量分发的效果。在看到页面出现变化前,有可能需要刷新15次或者更多。如果修改规则,将90%的流量路由到v3,可以看到更明显的效果。 64 | 65 | 1. 当v3版本的`reviews`服务已经稳定运行后,可以将100%的流量路由到`reviews:v3`: 66 | 67 | ```bash 68 | istioctl replace -f samples/bookinfo/kube/route-rule-reviews-v3.yaml 69 | ``` 70 | 71 | 此时,以任何用户登录到`productpage`页面,都可以看到带红星的评价信息。 72 | 73 | # 理解原理 74 | 75 | 在这个任务中,我们使用了Istio的带权重路由的特性将流量从老版本的`reviews`服务逐渐迁移到了新版本服务中。 76 | 77 | 注意该方式和使用容器编排平台的部署特性来进行版本迁移是完全不同的。容器编排平台使用了实例scaling来对流量进行管理。而通过Istio,两个版本的`reviews`服务可以独立地进行scale up和scale down,并不会影响这两个版本服务之间的流量分发。 78 | 79 | 想了解更多支持scaling的按版本路由功能,请查看[Canary Deployments using Istio](https://istio.io/blog/canary-deployments-using-istio.html)。 80 | 81 | # 清理 82 | 83 | * 删除路由规则。 84 | 85 | ```bash 86 | istioctl delete -f samples/bookinfo/kube/route-rule-all-v1.yaml 87 | ``` 88 | 89 | * 如果不打算尝试后面的任务,请参照[BookInfo cleanup](http://istio.doczh.cn/docs/guides/bookinfo.html#cleanup) 中的步骤关闭应用程序。 90 | 91 | 92 | # 进阶阅读 93 | 94 | * 更多的内容请参见[请求路由](http://istio.doczh.cn/docs/concepts/traffic-management/rules-configuration.html)。 95 | -------------------------------------------------------------------------------- /layouts/partials/nav.html: -------------------------------------------------------------------------------- 1 | 2 | {{ if or (eq .Params.navstyle "invert") (eq .Params.headerstyle "text") }} 3 |