机械境

这里只是我的后花园,随性而写

介绍

之前在 traefik 基于 Treafik 部署 Bitwarden RS 中简单介绍了如何基于 Traefik 部署 Bitwarden RS。Treafik 的官方文档一如既往地混乱,甚至有些地方前后不一致,让人看得云里雾里的。

Traefik v2 的新特性

  • Providers
    是指你正在使用的集群技术 (Kubernetes, Docker, Consul, Mesos 等)
  • Entrypoints
    是最基本的配置,指监听请求的端口.
  • Services
    是在你的基础设施上的运行的软件,通过 services 配置如何路由到真正的应用程序
  • Routers
    将传入的请求和你的 service 连接起来。他们持有的 rules 决定哪个 service 将处理对应的请求
  • Middleware
    中间件是可以在请求被 service 处理之前对其进行更新的组件。Traefik 提供了一些开箱即用的中间件来处理 认证、速率限制、断路器、白名单、缓冲等等

Traefik v2 配置

configuration

配置分为静态配置和动态配置:

  • 静态配置:启动的时候加载。包括 Entrypoints、Provider 连接信息
  • 动态配置:运行时可动态读取改变的。包括 Routes、Services、Middlewares、Certificates
Read more »

缘起

在 Dockerfile 中,如果我们不显式指明用户,进行权限处理,那么默认的 Dockerfile 生成的镜像,在运行时会以 root 身份进入 ENTRYPOINT,进而执行 CMD。因此,以 root 身份启动 container 是一件很危险的事情。尽管,docker 容器内的 root 与宿主 host 本身的 root 并不一定具有一样的权限,但是在容器内部的 root 拥有和宿主机一样的 UID (UID 0)。如果以 priviledge 的方式运行 container,那么两者将会一样,从而产生巨大的安全隐患。

简而言之,出于安全的考虑,需要在 Dockerfile 的 ENTRYPOINT 之前,也就是运行 application 之前,进行用户切换。

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# Build gqlc in a stock Go builder container
FROM qlcchain/go-qlc-builder:latest as builder

ARG BUILD_ACT=build

COPY . /qlcchain/go-qlc
RUN cd /qlcchain/go-qlc && make clean ${BUILD_ACT}

# Pull gqlc into a second stage deploy alpine container
FROM alpine:3.11.3
LABEL maintainer="developers@qlink.mobi"

ENV QLCHOME /qlcchain

RUN apk --no-cache add ca-certificates && \
addgroup qlcchain && \
adduser -S -G qlcchain qlcchain -s /bin/sh -h "$QLCHOME" && \
chown -R qlcchain:qlcchain "$QLCHOME"

USER qlcchain

WORKDIR $QLCHOME

COPY --from=builder /qlcchain/go-qlc/build/gqlc /usr/local/bin/gqlc

EXPOSE 9734 9735 9736

ENTRYPOINT ["gqlc"]

VOLUME ["$QLCHOME"]

主要思路如下:

  • 一阶段构建需要执行的 app 可执行程序
  • 二阶段创建用户及用户组,拷贝一阶段的编译出来的文件
  • 切换到刚创建出来的用户,执行 ENTRYPOINTCMD

---EOF---

环境变量换行

1
2
3
4
# base64 编码
export PRIVATE_KEY=$(cat ~/private_key.gpg | base64)
# 用的时候,base64解码
echo -e "${PRIVATE_KEY}" | base64 -d >"$key_file"

常用别名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# ------------------------------------
# Docker alias and function
# ------------------------------------

# Get latest container ID
alias dl="docker ps -l -q"

# Get container process
alias dps="docker ps"

# Get process included stop container
alias dpa="docker ps -a"

# Get images
alias di="docker images"

# Get container IP
alias dip="docker inspect --format '{{ .NetworkSettings.IPAddress }}'"

# Run deamonized container, e.g., $dkd base /bin/echo hello
alias dkd="docker run -d -P"

# Run interactive container, e.g., $dki base /bin/bash
alias dki="docker run -i -t -P"

# Execute interactive container, e.g., $dex base /bin/bash
alias dex="docker exec -i -t"

# Stop all containers
dstop() { docker stop $(docker ps -a -q); }

# Remove all containers
drm() { docker rm $(docker ps -a -q); }

# Stop and Remove all containers
alias drmf='docker stop $(docker ps -a -q) && docker rm $(docker ps -a -q)'

# Remove all images
dri() { docker rmi $(docker images -q); }

# Dockerfile build, e.g., $dbu tcnksm/test
dbu() { docker build -t=$1 .; }

# Show all alias related docker
dalias() { alias | grep 'docker' | sed "s/^\([^=]*\)=\(.*\)/\1 => \2/"| sed "s/['|\']//g" | sort; }

# Bash into running container
dbash() { docker exec -it $(docker ps -aqf "name=$1") bash; }

---EOF---

缘起

之前一个项目做预研的时候搞了个树莓派 3B,测试完之后,一直处于吃灰状态。刚好最近经常给小朋友打印东西,家里那台老的 HP P1106 不支持无线打印,每次都接 USB 才能打印,让人无比烦躁。于是乎抽空把打印机接到树莓派上,利用 cups 做成无线打印。

安装系统

烧镜像

  • 官网 下载最新的镜像
  • 可以通过 dd 把镜像复制到 SD 卡中,具体方法参考 官方指南
  • 也可以通过 Etcherbrew cask install balenaetcher 即可,傻瓜式操作
    Read more »

思路

cgo 交叉编译 中通过 xgo + Docker 实现 Cgo 的交叉编译。由于原版 xgo 不支持 go mod,而且作者貌似也没支持的打算,所有我自己维护了一个 xgo。使用了一段时间下来看,除了编译速度有点慢意外,其他还好。这也是跟我们的使用方式有关,我们需要根据不同的 tags 来编译不不同的版本,xgo 每次编译都要构建一个 Docker 实例,然后下载引用的库等等一大堆重复操作,导致整个编译时间拉长。

既然有很多重复操作,那就换个思路,只构建一个实例,把编译环境准备好,然后在这个实例中把要编译的内容,一次编译出来。goreleaser,支持编译发布 golang 的二进制文件,同时也支持发布 Docker 镜像,但是这不是重点,这里不再赘述。

实践

由于需要支持 macOS 就需要安装 OSX 的 SDK,在 xgo 是自己构建的基础镜像。这里通过 Docker 官方提供的 golang-cross 来作为基础镜像支持 macOS 平台,顺便规避一下版权的问题。在此基础上安装 mingw 支持 Windows x64/i386,以及 arm-gcc 等。剩下的就是一些常规操作了,比如安装 goreleaser,更新 golang 运行时等,完整的 Dockerfile

使用

1
2
3
4
5
docker run --rm --privileged \
-v $PWD:/go/src/github.com/qlcchain/go-qlc \
-v /var/run/docker.sock:/var/run/docker.sock \
-w /go/src/github.com/qlcchain/go-qlc \
goreng/golang-cross goreleaser --snapshot --rm-dist

当然也是可以添加到 makefile 中的

1
2
3
4
5
6
7
8
snapshot:
docker run --rm --privileged \
-v $(CURDIR):/go-qlc \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $(GOPATH)/src:/go/src \
-w /go-qlc \
goreng/golang-cross:$(GO_BUILDER_VERSION) \
goreleaser --snapshot --rm-dist

使用的时候,只需要执行 make snapshot 即可。

小结

使用新的镜像之后,整体编译速度有了比较大幅度的提升,得益于 goreleaser 对打包的支持,原来自己实现 shell 打包生成 checksum 的操作,都有现成的支持。

---EOF---

前面在 traefik 配置 docker 容器支持 HTTPS 中介绍了如果使用 traefik 为 docker 提供支持 SSL 的反向代理。在示例中,qlc_wallet_server 中 HTTP 和 WebSocket 共用了一个端口,该端口支持 SSL,可以通过 https://api.example.comwss://api.example.com 访问。但是如果在同一个容器中使用不同的端口呢?如果支持,如果实现?

答案显然是可以支持的,但是我翻遍官方文档也没找到具体的说明。其实在 基于 Treafik 部署 Bitwarden RS 中部署 Bitwarden 的时候,已经使用了,在一个容器中,bitwarden-RS 通过 80 端口提供 RESTful 的接口,同时通过 3012 端口提供 Websocket 连接用来推送数据变化的通知。

1
2
3
4
5
6
7
8
labels:
- traefik.enable=true
- traefik.web.frontend.rule=Host:bitwarden.example.com
- traefik.web.port=80
- traefik.hub.frontend.rule=Host:bitwarden.example.com;Path:/notifications/hub
- traefik.hub.port=3012
- traefik.hub.protocol=ws
- traefik.docker.network=traefik

定义两个不同的实例,webhub,分别指定端口,hub 是 WebSocket ,需要手动指定 protocol。一定要注意的是,千万不能手动指定 backend。要不然 traefik 就会这个容器中对这两个端口做负载均衡。

--EOF---

GitHub Actions 由 GitHub 官方推出的工作流工具。典型的应用场景应该是 CI/CD,类似 Travis 的用法。这里介绍响应 git push 事件触发 Hexo 编译静态页面并推送到 GitHub Pages 的用法。

准备工作

  • 生成 ssh 部署私钥
    1
    ssh-keygen -t ed25519 -f ~/.ssh/github-actions-deploy
  • 在 GitHub repo 的 Settings/Deploy keys 中添加刚刚生成的公钥
  • 在 GitHub repo 的 Settings/Secrets 中添加 GH_ACTION_DEPLOY_KEY,值为刚刚生成的私钥

编写 GitHub Actions

  • 在项目的根目录添加 deploy.yml,目录结构如下

    1
    2
    3
    .github
    └── workflows
    └── deploy.yml
  • 步骤

    • 添加部署私钥到 GitHub Actions 执行的容器中
    • 在容器中安装 Hexo 以及相关的插件
    • 更新主题 NexT 的配置
    • 编译静态页面
    • 推送编译好的文件到 GitHub Pages
  • 编写部署的 action

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    name: Main workflow

    on:
    push:
    branches:
    - raw

    jobs:
    build:

    runs-on: ubuntu-18.04

    steps:
    - uses: actions/checkout@v2
    - name: Use Node.js lts
    uses: actions/setup-node@v2-beta
    with:
    node-version: '12.x'
    - name: prepare build env
    env:
    GH_ACTION_DEPLOY_KEY: ${{ secrets.GH_ACTION_DEPLOY_KEY }}
    NEXT_VERSION: v8.0.0-rc.2
    run: |
    mkdir -p ~/.ssh/
    echo "$GH_ACTION_DEPLOY_KEY" > ~/.ssh/id_rsa
    chmod 600 ~/.ssh/id_rsa
    ssh-keyscan github.com >> ~/.ssh/known_hosts
    git config --global user.name 'gythialy'
    git config --global user.email 'gythialy@users.noreply.github.com'
    npm i -g hexo-cli
    npm i
    git clone --branch ${NEXT_VERSION} --depth=10 git@github.com:next-theme/hexo-theme-next.git themes/next
    git checkout -b ${NEXT_VERSION}
    git clone git@github.com:next-theme/theme-next-three --depth=1 themes/next/source/lib/three
    # git clone git@github.com:next-theme/theme-next-fancybox3 --depth=1 themes/next/source/lib/fancybox
    git clone git@github.com:next-theme/theme-next-pace --depth=1 themes/next/source/lib/pace
    - name: deploy to github
    env:
    HEXO_ALGOLIA_INDEXING_KEY: ${{ secrets.HEXO_ALGOLIA_INDEXING_KEY }}
    run: |
    hexo generate && hexo algolia && hexo deploy

小结

总的来说,就部署 Hexo 而言,速度比 Travis 部署 速度更快一点,同时由于现在还处于测试阶段,功能相对还是比较欠缺一点。不过作为一站式的功能来说,还是不错的。

参考链接

  • Workflow syntax for GitHub Actions

---EOF---

背景

Bitwarden 是一个类似 1Password 和 LastPass 的开源密码管理软件,Bitwarden RS 是基于 Rust 语言的一个实现,更轻量一些,可能效率也会更高一点点,并且是完全兼容官方 App 的,比如各种浏览器扩展,手机 App 等。

TL;DR

Bitwarden RS 已完成功能

  • Basic single user functionality
  • Organizations support
  • Attachments
  • Vault API support
  • Serving the static files for Vault interface
  • Website icons API
  • Authenticator and U2F support
  • YubiKey OTP

简而言之就是日常用用是差不多的,离官方实现还有点路要走。

准备工作

  • 一个域名
  • 一台公网服务器
  • docker-compose
    1
    2
    3
    4
    5
    ➜ docker-compose version
    docker-compose version 1.23.2, build 1110ad01
    docker-py version: 3.6.0
    CPython version: 3.6.6
    OpenSSL version: OpenSSL 1.1.0h 27 Mar 2018
  • traefik
    traefik 配置证书,可以参考 traefik 配置 docker 容器支持 HTTPS,这里就不赘述了。
Read more »
0%