Think Deep,Work Lean

使用远程kind

Posted on By zack

前言

上一篇,讲了如何在本地使用kind。

但是不甘心,觉得肯定可以使用kubectl来操作远程的kind集群。

折腾了一下,因此有了本篇文章。

安装kind

在亚太二区安装kind。

把Kind的~/.kube/config拷贝到本地,修改apiserver的地址,无法成功使用kubectl,原因是配置中端口不通。

远程的apiserver端口,只绑定了127.0.0.1:

[root@ssa3 ~]# ss -alntp|grep 37308
LISTEN     0      128    127.0.0.1:37308                    *:*                   users:(("docker-proxy",pid=18813,fd=4))

检查源码,可以发现,其实可以使用kind配置文件,来修改绑定的地址:

// ClusterOptions holds cluster creation options
type ClusterOptions struct {
	Config       *config.Cluster
  ...
}
  ...
	apiServerPort := cfg.Networking.APIServerPort
	apiServerAddress := cfg.Networking.APIServerAddress

这种方式适合于用配置文件来创建的集群。

对于已经存在的集群的修改,其实也很容易解决:

  1. 在远程服务器上配置端口转发
  2. apiserver证书授权要访问的apiserver的外部IP

配置端口转发

检查 kubeconfig的文件,看到apisever的端口为 $Port (37308),在服务器上配置时,将入口端口加1改为 $PortNew 37309 ,避免端口冲突,执行 ssh 转发时,会监听这个端口。

把远端 kubeconfig 拷备到本地时,把apisever的 ip 改为 远程的地址 $remoteHostIp, 端口改为 $PortNew 37309

在服务器上执行:

[root@ssa3 ~]# ssh -Nf -L 0.0.0.0:37309:127.0.0.1:37308 127.0.0.1

此时可以看到37309已经被监听,防火墙放行这个端口,从本地连接时提示x509校验失败。

或者使用iptables做DNAT

[root@ssa3 ~]# iptables -t nat -A PREROUTING -d 192.168.0.13 -p tcp -m tcp --dport 37309 -j DNAT --to-destination 172.18.0.2:6443
➜  /tmp k get po
Unable to connect to the server: x509: certificate is valid for kind-control-plane, kubernetes, kubernetes.default, kubernetes.default.svc, kubernetes.default.svc.cluster.local, localhost, not ssa3

证书放行IP

kind代码定义了cert的目录:

// run kubeadm
cmd := node.Command(
  // init because this is the control plane node
  "kubeadm", "init",
  "--skip-phases="+skipPhases,
  // specify our generated config file
  "--config=/kind/kubeadm.conf",
  "--skip-token-print",
  // increase verbosity for debugging
  "--v=6",
)

可以看到,本质上也是使用kubeadm安装的集群,kubeadm的配置文件在/kind目录。

进入kind容器,授权IP

[root@ssa3 ~]# docker exec -ti `docker ps | grep kind | awk '{print $1}'` sh

# apt install vim 

把节点IP加入配置文件

# vi /kind/kubeadm.conf
apiServer:
  certSANs:
  - localhost
  - 127.0.0.1
  - 192.168.0.13 # 增加该项

备份证书

# cd /etc/kubernetes/pki
# mv apiserver.crt apiserver.crt.bak
# mv apiserver.key apiserver.key.bak

生成证书

# kubeadm init phase certs apiserver --config /kind/kubeadm.conf

检查证书已经更新

# openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -text

apiServer:
  certSANs:
  - localhost
  - 127.0.0.1
  - 192.168.0.13

此时访问正常

➜  zackzhangkai.github.io git:(master) ✗ kubectl get po -A
NAMESPACE            NAME                                         READY   STATUS    RESTARTS   AGE
kube-system          coredns-f9fd979d6-c2nft                      1/1     Running   0          5h39m
kube-system          coredns-f9fd979d6-h2qxt                      1/1     Running   0          5h39m
kube-system          etcd-kind-control-plane                      1/1     Running   0          5h39m
kube-system          kindnet-kn54k                                1/1     Running   0          5h39m
kube-system          kube-apiserver-kind-control-plane            1/1     Running   0          5h39m
kube-system          kube-controller-manager-kind-control-plane   1/1     Running   0          5h39m
kube-system          kube-proxy-rwlgt                             1/1     Running   0          5h39m
kube-system          kube-scheduler-kind-control-plane            1/1     Running   0          5h39m
local-path-storage   local-path-provisioner-78776bfc44-zvwdt      1/1     Running   0          5h39m

从上面可以看到Kind本质上也是调用kubeadm来创建的集群,kind可以使用配置文件来自定义一些安装需求。但是也可以进入容器中去操作。