0%

生产环境下,k8s集群对外暴露服务主要有LoadBalancer和Ingress两种方式:

  • LoadBalancer:需要云厂商支持,使用k8s service的负载均衡能力,也就是依靠iptables/ipvs的能力,可用于各种协议
  • Ingress:相对更加灵活,通过反向代理服务器实现负载均衡,仅用于http/https协议,这种场景下需要额外的反向代理服务以及ingress controller,nginx是大家熟知的反向代理,在k8s时代,出现了nginx-ingress,就是nginx+ingress controller的组合,ingress controller负责根据ingress资源生成nginx配置,当配置有变化时重启nginx。同时也出现了云原生的反向代理traefik,它相当于把ingress controller包含到其中合为一体,并且能够动态感知路由规则变化,不需重启。

traefik是一个相对较新的反向代理,网上相关资料不是特别丰富,研究了好几天,才成功访问到k8s dashboard,将其中的关键点记录于此。

阅读全文 »

通过源码编译kubernetes时,可以使用go build(或go install)单独编译某个组件,例如对于apiserver,可以cd到k8s.io/kubernetes/cmd/kube-apiserver,然后执行:

1
go install -i -v -gcflags='-N -l'

编译结果安装到GOBIN下,即GOBIN/kube-apiserver,使用这种方式编译时有一个小问题,版本号是一段奇怪的字符串:

1
2
kube-apiserver --version
Kubernetes v0.0.0-master+$Format:%h$

在遇到一些需要依赖kubernetes版本号的场景就会有问题,例如使用helm安装chart时,有些chart对kubernetes版本号有要求,就会无法安装。

阅读全文 »

在通过kubectl访问pod信息,例如执行kubectl logs,常常会遇到类似如下错误:

Error from server (Forbidden): Forbidden (user=system:anonymous, verb=get, resource=nodes, subresource=proxy) ( pods/log tiller-deploy-6b5ffb6f-lg9jb)

网上搜索可以通过启用anonymous访问,也就是使用–anonymous-auth=true或者配置文件添加:

1
2
3
authentication:
anonymous:
enabled: true

但是设置之后错误依旧,为此我探究了一下kubelet的认证机制,终于将问题解决,其实很简单,答案后面揭晓。

我们知道kubectl只会和apiserver交互,对于kubectl logs、kubectl exec等需要访问pod的这些命令,实际上是apiserver调用kubelet接口完成的,上述错误正是出在这个过程,而不是kubectl到apiserver的过程。

kubelet通过port指定的端口(默认10250)对外暴露服务,这个服务是需要TLS认证的,同时也可以通过 readOnlyPort 端口(默认10255,0表示关闭)对外暴露只读服务,这个服务是不需要认证的。apiserver通过–kubelet-https参数指定调用哪个服务,true为前者,false为后者,此时只能执行只读操作。下面主要说一下前者。

阅读全文 »

喜欢尝鲜的同学可能会注意到最新的kubernetes在执行kubectl get cs时输出内容有一些变化,以前是这样的:

1
2
3
4
5
> kubectl get componentstatuses
NAME STATUS MESSAGE ERROR
controller-manager Healthy ok
scheduler Healthy ok
etcd-0 Healthy {"health":"true"}

现在变成了:

1
2
3
4
5
> kubectl get componentstatuses
NAME Age
controller-manager <unknown>
scheduler <unknown>
etcd-0 <unknown>

起初可能会以为集群部署有问题,通过kubectl get cs -o yaml发现status、message等信息都有,只是没有打印出来。原来是kubectl get cs的输出格式有变化,那么为什么会有此变化,我们来一探究竟。

阅读全文 »

在kubernetes集群的搭建过程中,需要使用许多证书,例如运行kube-apiserver需要指定客户端CA证书、服务端证书和私钥,而客户端组件如kubectl需要指定自己的证书、私钥以及服务端CA证书。

1
kube-apiserver --tls-cert-file=/etc/kubernetes/ssl/kubernetes.pem --tls-private-key-file=/etc/kubernetes/ssl/kubernetes-key.pem --client-ca-file=/etc/kubernetes/ssl/ca.pem

kube-controller-manager组件还需要指定CA私钥,用于为kubelet签名证书。

1
kube-controller-manager --cluster-signing-cert-file=/etc/kubernetes/ssl/ca.pem --cluster-signing-key-file=/etc/kubernetes/ssl/ca-key.pem

这些文件在TLS认证过程中发挥什么作用,关键需要理解CA证书以及自签名证书。

阅读全文 »

在学习一些大型golang项目时,例如kubernetes,通过调试器一边跟踪代码一边学习其原理是很好的方法,一般k8s部署在远程环境,在本机进行开发,很自然对远程调试有迫切需求,这也是和调试一般golang程序最主要的诉求区别点,本文重点介绍远程调试这种场景。

阅读全文 »

golang标准库中的go/build包是用来收集包的一些信息的,例如获取包的源码位置。用来学习golang的交互式教程tour就是使用了go/build定位tour源代码位置,从而在运行时使用其中的文件。但是go/build是有一些使用限制的,主要是在某些情况下无法定位go module的源码位置,那么还有哪些方法可以根据包的importpath获取到包的源代码位置呢,本文详细进行探讨。

阅读全文 »

产品中需要用到sftp,sftp实际上就是ssh的一部分,ssh在Linux系统中是自带的,运行sshd之后就同时也支持sftp了,也是通过22端口连接。但我们的产品需要支持跨平台,需要同时支持Linux和Windows,因此需要寻找一个跨平台的ssh实现,通过寻找发现实际上在Win10 1809和Windows Server 2019开始已经内置了,使用的正是OpenSSH。

阅读全文 »