Hugo Post
Introduction 把简书上的博客搬到 GitHub 了,简书上广告越来越多了。
Introduction 把简书上的博客搬到 GitHub 了,简书上广告越来越多了。
查看 maxfiles 设置 launchctl limit 设置一个较大的 maxfiles sudo launchctl limit maxfiles 102400 102400 查看应用资源情况 lsof -n | awk '{print $1}' | uniq -c | sort -rn | head
第一种方法 使用k8s.io/client-go/tools/cache func StartWatchingServices(c *Client) { watchlist := cache.NewListWatchFromClient( c.K8sClientset.CoreV1().RESTClient(), string(v1.ResourceServices), v1.NamespaceAll, fields.Everything(), ) _, controller := cache.NewInformer( watchlist, &v1.Service{}, 0, //Duration is int64 cache.ResourceEventHandlerFuncs{ AddFunc: func(obj interface{}) { fmt.Printf("added: %s \n", obj) }, DeleteFunc: func(obj interface{}) { fmt.Printf(deleted: %s \n", obj) }, UpdateFunc: func(oldObj, newObj interface{}) { fmt.Printf("changed \n") }, }, ) stop := make(chan struct{}) defer close(stop) go controller.Run(stop) for { time.Sleep(time.Second) } } 第二种方法 使用k8s.io/client-go/informers,可以 watch CRD 资源但需要使用 code-generator 生成 clientset 和 informer(指 CRD 资源)。...
本文将详细介绍如何利用 Keycloak 配置 Kubernetes 登录验证,以及 RBAC 管理。 本文全部为测试环境工具。 流程示意 配置 Keycloak 安装配置 生产环境不建议使用 docker 直接部署 Keycloak。如果使用 nginx 需要将PROXY_ADDRESS_FORWARDING配置成true. sudo docker run -e KEYCLOAK_USER=wanglei -e KEYCLOAK_PASSWORD=your_password -e PROXY_ADDRESS_FORWARDING=true -p 8081:8080 -d jboss/keycloak 配置 nginx 将 server_name 配置成你的域名,代理 Keycloak 端口,注意上面PROXY_ADDRESS_FORWARDING=true server { listen 80; server_name key.wanglei.me; location / { proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $http_host; proxy_pass http://localhost:8081; } } 在 Clients 中创建 kubernetes 设置Client ID为kubernetes,Client Protocol选择openid-connect即 OIDC 协议。 设置 Client 将Access Type设置为confidential, Valid Redirect URIs根据需要设置,本文后面用到 kubelogin,需要设置为http://localhost:8000 记录 Client Secret 在 Credentials 中找到 Secret,后面需要用到。 新建 Mapper 选择Mapper Type为User Attribute,选择Claim JSON Type为String,下面开关一律选on(可根据需求更改)。此处Token Claim Name字段设置为groups,后面配置 kube-apiserver 会用到。 为 User 添加 Attribute 添加 key groups, value admin,然后点击 add,再 save。 配置 kubernetes 此处使用 kind(kubernetes in docker) https://github....
由于 Golang 编译之后的文件是二进制,而 scratch 是 docker 最基础的空 image,所以可以使用 scratch 来构建 Go 程序的 docker image,使得最终构建的 image 最小化. 构建 image 过程分为两步: 在 Go 基础 image 中 build. 将 build 好的二进制文件拷贝到 scratch image 中。 无需 cgo 的程序 对于无需 cgo 交叉编译的程序,使用 scratch 来作为最终运行的基础 image 非常合适。 首先,选择合适版本的 golang 基础 image 来 build,这里没有必要选择更小的 golang alpine,build 过程中 pull 一般会有缓存所以 pull 速度差别不大,此外 alpine 中没有 git 和 ssl,我们在构建 image 过程中都有可能用到,况且 alpine 也不会影响最终 image 大小。 FROM golang:1.13 AS builder 禁掉 cgo 交叉编译,我们服务器一般为 linux amd64,build 二进制文件。...
问题 两个不同的域名的 localStorage 不能直接互相访问。那么如何在aaa.com中如何调用bbb.com的 localStorage? 实现原理 1.在aaa.com的页面中,在页面中嵌入一个 src 为bbb.com的iframe,此时这个iframe里可以调用bbb.com的 localStorage。 2.用postMessage方法实现页面与iframe之间的通信。 综合 1、2 便可以实现aaa.com中调用bbb.com的 localStorage。 优化 iframe 我们可以在bbb.com中写一个专门负责共享 localStorage 的页面,例如叫做page1.html,这样可以防止无用的资源加载到iframe中。 示例 以在aaa.com中读取bbb.com中的 localStorage 的item1为例,写同理: bbb.com中page1.html,监听aaa.com通过postMessage传来的信息,读取 localStorage,然后再使用postMessage方法传给aaa.com的接收者。 <!DOCTYPE html> <html lang="en-US"> <head> <script type="text/javascript"> window.addEventListener('message', function(event) { if (event.origin === 'https://aaa.com') { const { key } = event.data; const value = localStorage.getItem(key); event.source.postMessage({wallets: wallets}, event.origin); } }, false); </script> </head> <body> This page is for sharing localstorage. </body> </html> 在aaa.com的页面中加入一个 src 为bbb....
问题描述 三门问题(Monty Hall problem)亦称为蒙提霍尔问题、蒙特霍问题或蒙提霍尔悖论,大致出自美国的电视游戏节目 Let’s Make a Deal。问题名字来自该节目的主持人蒙提·霍尔(Monty Hall)。参赛者会看见三扇关闭了的门,其中一扇的后面有一辆汽车,选中后面有车的那扇门可赢得该汽车,另外两扇门后面则各藏有一只山羊。当参赛者选定了一扇门,但未去开启它的时候,节目主持人开启剩下两扇门的其中一扇,露出其中一只山羊。主持人其后会问参赛者要不要换另一扇仍然关上的门。问题是:换另一扇门会否增加参赛者赢得汽车的机率? 答案 答案是会。不换门的话,赢得汽车的几率是 1/3。换门的话,赢得汽车的几率是 2/3。 争议 有人认为,在主持人排除了一个门之后,汽车只可能在另外两个门中,所以在两扇门的概率各是 1/2。 分析 首先参赛者选定了一扇门,主持人未开启门时,汽车在这扇门的概率为 1/3,在另外两扇门中的概率为 2/3,此时争议不大。而另外两扇门中必定至少有一扇是山羊,所以即使主持人指出这两扇门中一扇是山羊,并不会影响这两扇门的概率,两扇概率和仍为 2/3,此时一扇已知是山羊,所以两扇中的另外一扇是汽车的概率是 2/3。所以换门会提高概率。 思考 如果主持人开启揭露一扇门是山羊后,另外一个人 B 此时在剩下的两扇门中做抉择,并且他不知道其他信息,只知道一扇是汽车,一扇是羊,那么此时 B 选择到汽车的概率是 1/2。 这是因为没有之前的信息,B 不知道那扇门概率大,B 此时是在两扇门中做随机选择,B 可能有 1/2 的概率选择 A(参赛者)开始选择的门,也有 1/2 的概率选择 A 将要换的门。所以 B 选择到汽车的概率为 1/2 _ 1/3 + 1/2 _ 2/3 = 1/2。 程序模拟 package main import ( "fmt" "math/rand" "time" ) func main() { totalTimes := 1000000 aRightTimes := 0 bRightTimes := 0 rand....
在无序数组中寻找中位数,最差复杂度为 O(n). 实现算法为 Median of medians,又叫 BFPRT 算法。 实现原理与复杂度研究:https://en.wikipedia.org/wiki/Median_of_medians 贴一版 JS 实现: export const selectMedian = (arr, compare) => { return selectK(arr, Math.floor(arr.length / 2), compare); }; export const selectK = (arr, k, compare) => { if (!Array.isArray(arr) || arr.length === 0 || arr.length - 1 < k) { return; } if (arr.length === 1) { return arr[0]; } let idx = selectIdx(arr, 0, arr.length - 1, k, compare || defaultCompare); return arr[idx]; }; const partition = (arr, left, right, pivot, compare) => { let temp = arr[pivot]; arr[pivot] = arr[right]; arr[right] = temp; let track = left; for (let i = left; i < right; i++) { // if (arr[i] < arr[right]) { if (compare(arr[i], arr[right]) === -1) { let t = arr[i]; arr[i] = arr[track]; arr[track] = t; track++; } } temp = arr[track]; arr[track] = arr[right]; arr[right] = temp; return track; }; const selectIdx = (arr, left, right, k, compare) => { if (left === right) { return left; } let dest = left + k; while (true) { let pivotIndex = right - left + 1 <= 5 ?...
使用 create-react-app 创建的单页应用(SPA)是在 build 时注入环境变量的。一旦 build 成静态文件便不能动态提供环境变量了。 比如 build 一个单页应用的 docker image,可以在 build 时提供环境变量。但是已经 build 完成,使用 docker run 运行的时候不能再传递环境变量。 本文主要解决在运行时提供环境变量的问题。 原理:通过一段 shell 脚本将指定将 env 转换为 config.js 文件,该文件和 build 好的 static 文件 serve 在同一目录下,在应用中引用 config.js 文件,通过 window._env 获取环境变量。shell 脚本通过 docker image 的 entrypoint 执行。服务使用 go 构建的一个简单服务器,比 nginx 轻量很多。 将如下env.sh文件拷问到项目目录下,在 entrypoint(docker run)时执行,作用是将环境变量转出 config.js #!/bin/sh if [ $CONFIG_VARS ]; then # clear echo -n > ${CONFIG_FILE_PATH}/config.js SPLIT=$(echo $CONFIG_VARS | tr "," "\n") echo "window....
使用 kubectl apply 或者 create 命令创建/更新部署后,其 pod 需要时间完成创建/更新。 如果在 CI 中不等待所有 pod 更新完成,下一步流程很有可能使用更新前的环境。 正确方法 kubectl rollout status 根据实际情况kubectl rollout status命令,能够正确的获取 rollout status。 ATTEMPTS=0 ROLLOUT_STATUS_CMD="kubectl rollout status deployment/myapp -n namespace" until $ROLLOUT_STATUS_CMD || [ $ATTEMPTS -eq 60 ]; do $ROLLOUT_STATUS_CMD ATTEMPTS=$((attempts + 1)) sleep 10 done 以上 shell 脚本经过轮询kubectl rollout status可以很好的解决实际问题。 错误方法 kubectl wait 注意kubectl wait命令不能适用于更新部署。 kubectl wait --for=condition=available --timeout=600s deployment/myapp -n namespace 该命令只能判断 deployment 是否 available,不能用来判断 rollout,即 available 状态的 deployment,很可能老的 pod 还在 terminating,新的 pod 还没创建好。...