Hot For Coding

关于HTTP Response响应头字段X-Frame-Options

X-Frame-Options

什么是X-Frame-Options

HTTP有一个特殊的Response响应头字段X-Frame-Options,它可以指示是否允许浏览器在<iframe><frame><embed><object>里渲染。许多站点可以利用这个头字段避免clickjacking的攻击,这是一个浏览器安全问题,简单来说就是可以使用程序模拟用户恶意点击页面相关的DOM元素,比如在登录页面点击登录按钮等等,造成页面短时间内登录动作频繁造成服务器有压力从而达到攻击目的。所以才会有[CSRF: Cross-site request forgery](https://en.wikipedia.org/wiki/Cross-site_request_forgery)出现,当然这不是今天讨论的话题,感兴趣的朋友可以去看看。

...

READ ALL

Cume静态博客评论系统发布

full

19年年底博客改版成纯静态页之后,博客评论系统一直找不到合适的,之前国内比较流行的那几个也都关闭服务了。没办法只能使用Disqus,Disqus的确做的很好,唯一的缺点就是国内用不了。于是决定自己写一个静态页博客评论系统,经过一周时间的开发,今天正式上线替换Disqus。

Cume是我用Rust编写的一款静态页博客评论系统,数据库使用NoSQL方案,选用MongoDB。采用Rust编写虽然费时,不过一旦编译好了之后就非常稳定,编译后的二进制文件一共15M,非常容易部署。使用跑分特别猛的Actix作为WebServer,本来想使用Rocket,因为它的首页特别漂亮,最后还是用了Actix。

...

READ ALL

Docker启动Web应用容器外无法访问

full

今天像往常一样准备利用Docker启动一个Web应用docker run -d -p 80:80 --name nginx nginx,结果发现无法访问,docker ps看了一下,容器已经启动了,日志也正常。

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
c0e3ec43f5d3        nginx               "nginx -g 'daemon of…"   5 seconds ago       Up 4 seconds        0.0.0.0:80->80/tcp   nginx

...

READ ALL

Debian apt install Could not get lock 错误

full

我在Debian10安装Mariadb时遇到一个错误

$ apt install mariadb-server
E: Could not get lock /var/lib/dpkg/lock-frontend - open (11: Resource temporarily unavailable)
E: Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), is another process using it?

...

READ ALL

Etcd took too long 问题

full

Kubernetes集群在跑几天之后总会有一两个Etcd节点的系统负载特别高,甚至高达27,ssh进去半天才有响应,之前图省事每当负载高到离谱的时候我就reboot又能坚持几天。

然而这个问题始终反复困扰着我,还是得花点时间彻底解决一下这个系统负载高的问题,通过top命令我得知CPU资源被百分之百占用的程序是Etcd。

这有点奇怪,Kubernetes用Etcd来存储它的一些配置信息,以及ConfigMap等。我的集群目前只有20个节点,所有的Pods加一起也就250个左右,按理说这么点数据量对于三个节点构成高可用集群的Etcd来说不应该存在瓶颈的。

...

READ ALL

Docker run iptables No chain/target/match by that name 错误

full

我使用Docker运行一个HAProxy到多个Kubernetes API Server作为高可用,但经常性的发现某一个Node处于NotReady状态,通过查看kubelet日志发现连接不到Kubernetes API Server。于是赶紧查看以下HAProxy容器,发现HAProxy容器居然已经挂掉了,虽然我设置了--restart=always,但不知道什么原因还能挂掉。

我打算先把容器启动之后再排查,结果发现启动不了

$ docker run k8s-api-haproxy
Error response from daemon: Cannot restart container k8s-api-haproxy: driver failed programming external connectivity on endpoint k8s-api-haproxy (184fc52e77784f545e963bb1a9381586f82c7ac7ec593ed16714a19e8eaa8bc8):  (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 8443 -j DNAT --to-destination 172.17.0.2:8443 ! -i docker0: iptables: No chain/target/match by that name.
 (exit status 1))

...

READ ALL

如何在CentOS7上通过kubeadm快速安装k8s集群

full

本文介绍一下如何在CentOS7上通过kubeadm快速安装k8s集群,以下每一步骤我都亲自测试过,现在要搭建一个k8s集群相比前两年太容易了,只需要使用官方推荐的kubeadm工具即可快速初始化出一个k8s集群

准备

  • CentOS7系统,记得是7
  • 内存不小于2G
  • CPU双核以上
  • 所有机器直接网络互通
  • 唯一的Hostname
  • 防火期推荐关闭,使用外层的防火墙策略
  • Swap关闭

本文机器例子

HostnameIPOS
cp1172.16.11.199CentOS7
worker1172.16.11.198CentOS7
worker2172.16.11.197CentOS7

...

READ ALL

certbot自动续签与更新Dnspod记录脚本

full

Let's Encrypt为了推广HTTPS的普及,提供了免费证书,麻烦的是每三个月就到期,需要重新续签一下。重新续签有两种途径

  • 自动续签
  • 手动续签

自动续签与国际通用的DNS提供商有较好的合作支持,但对于国内比如Dnspod没有在它的自动续签支持里,不过它提供hook,你可以写任意shell脚本完成TXT记录即可实现自动续签。

Dndpod从新版开始token直接采用id,token组合而成,这里需要注意一下,脚本如下

renew.sh

#!/bin/bash
#
# Description:
#   This program will auto obtain a Let's Encrypt certificate for qttc.net with Dnspod
#
# Author: Nicholas Lee <lizhongit@gmail.com>
#
#
# Reference:
#   Certbot https://certbot.eff.org/docs/
# 
# 2020, April 29    First release
#

DNSPOD_TOKEN=[YOUR DNSPOD TOKEN]
DNSPOD_ID=[YOUR DNSPOD ID]

USER_AGENT='Qttc Renew Client/1.0.0(lizhongit@gmail.com)'
DOMAIN=qttc.net


echo "\
CERTBOT_DOMAIN: $CERTBOT_DOMAIN
DOMAIN:         $DOMAIN
VALIDATION:     $CERTBOT_VALIDATION"

if [ -f /tmp/CERTBOT_$CERTBOT_DOMAIN/VALIDATION ]; then
  VALIDATION_PRE=$(cat /tmp/CERTBOT_$CERTBOT_DOMAIN/VALIDATION)
  if [ "$CERTBOT_VALIDATION" = "$VALIDATION_PRE" ]; then  
    echo "Same Validation: $CERTBOT_VALIDATION"
    exit
  fi
fi


# Getting record id of named _acme-challenge

RECORD=$(curl -s -X POST "https://dnsapi.cn/Record.List" \
        -H "User-Agent: $USER_AGENT" \
        -d "login_token=$DNSPOD_ID,$DNSPOD_TOKEN&format=json&domain=$DOMAIN&record_type=TXT&keyword=_acme-challenge&lang=en" \
  | python -c "import sys,json;ret=json.load(sys.stdin);print(ret.get('records',[{}])[0].get('id',ret.get('status',{}).get('message','error')))")

echo "RECORD: $RECORD"

sleep 3

# Updating record with validation value

if [ -n "$RECORD" ]; then
  RET=echo $(curl -s -X POST "https://dnsapi.cn/Record.Modify" \
        -H "User-Agent: $USER_AGENT" \
        -d "login_token=$DNSPOD_ID,$DNSPOD_TOKEN&format=json&domain=$DOMAIN&record_id=$RECORD&sub_domain=_acme-challenge&record_type=TXT&record_line_id=0&value=$CERTBOT_VALIDATION&lang=en" \
  | python -c "import sys,json;sys.stdin = UTF8Reader(sys.stdin);ret=json.load(sys.stdin);print(ret.get('status',{}).get('message', ''))")

else
  RET=$(curl -s -X POST "https://dnsapi.cn/Record.Create" \
        -H "User-Agent: $USER_AGENT" \
        -d "login_token=$DNSPOD_ID,$DNSPOD_TOKEN&format=json&domain=$DOMAIN&sub_domain=_acme-challenge&record_type=TXT&value=$CERTBOT_VALIDATION&lang=en" \
  | python -c "import sys,json;ret=json.load(sys.stdin);print(ret.get('status',{}).get('message', ''))")
fi

echo "Dnspod result: $RET"

# Save info for cleanup
if [ ! -d /tmp/CERTBOT_$CERTBOT_DOMAIN ]; then
  mkdir -m 0700 /tmp/CERTBOT_$CERTBOT_DOMAIN
fi
echo $DOMAIN > /tmp/CERTBOT_$CERTBOT_DOMAIN/DOMAIN
echo $CERTBOT_VALIDATION > /tmp/CERTBOT_$CERTBOT_DOMAIN/VALIDATION 

# Sleep to make sure the change has time to propagate over to DNS
while [ -n "$TXT_RECORD" ]
do
  TXT_RECORD=$(/usr/bin/dig _acme-challenge.qttc.net txt | grep "$CERTBOT_VALIDATION")
  sleep 10
done

sleep 10

...

READ ALL

Kubernetes删除与新增节点

full

End-Of-Life

最近遇到了一件倒霉的事,我使用的CoreOS家的Container Linux居然宣布要在五月终止产品线了,提示在使用这款操作系统的用户尽快切换到其它操作系统,官方推荐了被Red Hat收购后搞起的Fedora CoreOS。这件事对我影响非常大,因为我有一个Kubernetes集群全部20+节点使用了Container Linux操作系统,这意味着我必须把我的集群所有节点都要重新更换操作系统才能让其在安全的环境下继续工作。

...

READ ALL

Kubernetes新节点加入集群后mount错误

full

因为集群的负载有点过重,于是准备加入节点分摊,在kubeadm join结束之后发现分配到新节点的pod一直处于ContainerCreating好长时间。用kubectl describe po <pod-name>看一下原因,发现一直重复出现以下信息

...
Mounting command: systemd-run
Mounting arguments: --description=Kubernetes transient mount for /var/lib/kubelet/pods/45e5a290-077b-4f9b-889b-71de0c7f17bc/volumes/kubernetes.io~nfs/json --scope -- mount -t nfs nfs.server.com:/data /var/lib/kubelet/pods/45e5a290-077b-4f9b-889b-71de0c7f17bc/volumes/kubernetes.io~nfs/json
Output: Running scope as unit: run-rf893345a476c4ac2bebef49266fc63c6.scope
mount: /var/lib/kubelet/pods/45e5a290-077b-4f9b-889b-71de0c7f17bc/volumes/kubernetes.io~nfs/json: bad option; for several filesystems (e.g. nfs, cifs) you might need a /sbin/mount.<type> helper program.
  Warning  FailedMount  33s (x4 over 11m)  kubelet, node15  Unable to attach or mount volumes: unmounted volumes=[json], unattached volumes=[config json default-token-5hhj7]: timed out waiting for the condition
...

...

READ ALL