【K8S】【minikube】远程访问汇总

说明

  与原生的k8s不同,minikube默认会在所在主机创建专用的内部网络,导致外部远程主机无法直接访问到minikube,如果minikube使用独立主机部署时,则存在一定的外部访问问题。
如下面这种网络情况如下:
– 局域网:如192.168.1.0/24
– minikube内部网络:如192.168.49.0/24,与局域网不互通
– 外部主机:未安装minikube的工作机,存在minikube所在宿主机相同的局域网中,记ip为192.168.1.3
– minukube宿主机:安装minikube的主机,存在在局域网中,如ip为192.168.1.2;且minikube创建了一个内部网络,只与宿主机192.168.1.2互通,与局域网内其他ip不互通

远程访问方式一览

  • nginx反向代理
    说明:可以只通过流量,不处理证书,且适用范围,支持四层、七层代理方式
    使用方式:
    主机安装nginx,修改nginx.conf文件增加stream模块并配置proxy_pass,如下
# 四层TCP反向代理案例
stream {
  server {
      # 代理服务器,外部流量会通过此处流向内部服务器,如192.168.1.2
      listen 192.168.1.2:80; 
      # 内部服务器,如172.20.1.2
      proxy_pass 172.20.1.2:80;
  }
}
  • kubectl proxy
    说明:可以只通过流量,不处理证书,且适用范围,支持四层、七层代理方式
    常见用法:
kubectl proxy --address=’x.x.x.x’ --port=xx --api-prefix=/ --accept-hosts=’^.*’

--address: 一般是0.0.0.0或者主机的IP
--port:默认为8001
--api-prefix:代理的API服务的前缀,默认是/,也就是全部代理
  • kubectl port-forward
    说明:本地端口的连接转发到 pod 上的端口,支持tcp流量转发,适用范围比kubectl proxy广
    常见用法:
kubectl port-forward 资源类型/资源名称 Pod端口:主机端口 --address='0.0.0.0'

--address: 默认为127.0.0.1,但是在minikube在内网这种情况下,指向的是minikube内部网络,需要指向主机则需要指定0.0.0.0或主机IP

案例

nginx反向代理:使用kubectl外部访问minikube

使用场景

  外部主机(工作机)已安装了独立kubectl,需要访问minikube宿主机上的minikube的api-server

整体思路

参考:A How To Guide: Remotely Accessing Minikube Kubernetes on KVM 改为docker版本

  • minukube宿主机部署minikube,start时指定参数–apiserver-ips,值为当前宿主机局域网IP,即192.168.1.2
  • minikube宿主机直接安装nginx,设置反向代理,配置minikube宿主机ip和特定端口转发到minikube的apiserver的服务ip和端口
  • 修改外部主机kubectl的config文件使用minikube宿主机的IP和端口后也可以访问集群

注1:较新版的nginx允许反向代理时只通过流量而不处理SSL和证书,让我们可以使用minikube生成的kubeconfig证书,在局域网其他主机使用代理的IP与端口访问minikube内部网络的api-server服务)

注2:–apiserver-ips:一组在为 kubernetes 生成的证书中使用的 apiserver IP 地址。如果您希望将此 apiserver设置为可从机器外部访问,则可以使用这组 apiserver IP 地址

执行步骤

minikube start --force --driver=docker --container-runtime=containerd  --cni calico --apiserver-ips=192.168.1.6 --registry-mirror=https://registry.docker-cn.com

参数说明:
–force:满足条件时可选,此处用于docker在root下启动,指定非root用户部署时可不加
–driver=docker:必选,虚拟化引擎指定为docker
–container-runtime=containerd:kuberntest版本大于1.24时看k8s官方弃用dockershim,因此docker drive的CRI必须使用containerd
–cni calico:可选,推荐网络方案使用calico
– minikube就绪后,执行命令的集群信息,获取apiserver服务IP及端口

kubectl cluster-info
# 如返回如下,则apiserver为192.168.49.2:8443
Kubernetes control plane is running at https://192.168.49.2:8443
  • minikube上安装nginx
    说明:安装nginx方法根据实际改变,这个只是使用yum方式举例
# 添加ngixn的yum源
rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
# 安装nginx
yum install -y nginx
# 开启并设置自启动
systemctl start nginx
systemctl enable nginx
nginx配置反向代理
# 找到nginx的配置文件,一般为/etc/nginx/nginx.conf,增加四层tcp反向代理
stream {
  server {
      listen 192.168.1.2:8443; 
      proxy_pass 192.168.49.2:8443;
  }
}
# 重新加载nginx配置文件并重启
nginx -s reload
systemctl restart nginx
  • 修改kubeconfig文件并在minikube宿主机本地测试
# 修改~/.kube/config文件中的server,将192.168.49.2修改为192.168.1.2并保存
# 使用minikube自带的minikube kubectl工具,执行任意kubectl查看是否正常,如
miinikube kubectl -- get node
# 此时执行kubectl cluster-info应该是显示为192.168.1.2,如
minikube kubectl -- cluster-info
返回:
Kubernetes control plane is running at https://192.168.1.2:8443
  • 外部主机安装kubectl工具
    请参考 此处

  • minikube宿主机上查看kubeconfig文件,获取证书地址

# 查看kubeconfig的内容
cat ~/.kube/config
# 查看ca.crt、client-certificate、client-key文件的位置
如
- cluster:
    certificate-authority: /root/.minikube/ca.crt
......
- name: minikube
  user:
    client-certificate: /root/.minikube/profiles/minikube/client.crt
    client-key: /root/.minikube/profiles/minikube/client.key
  • 拷贝kubeconfig文件和https证书到外部主机上配置kubectl
# 在外部主机上创建存放config和https证书的目录,如
mkdir -p /root/.kube/
mkdir -p /root/.minikube/profiles/minikube
# 拷贝minikube宿主机的文件到外部主机上
scp root@192.168.1.2:/root/.kube/config /root/.kube/
scp root@192.168.1.2:/root/.minikube/profiles/minikube/client.crt /root/.minikube/profiles/minikube/
scp root@192.168.1.2:/root/.minikube/profiles/minikube/client.key /root/.minikube/profiles/minikube/
scp root@192.168.1.2:/root/.minikube/ca.crt /root/.minikube/
# 外部主机上执行命令验证,返回与minikube宿主机结果一致
kubectl cluster-info

nginx反向代理:使用https请求带token外部访问minikube

说明

使用 Kubernetes API 访问集群 |Kubernetes
使用 RBAC 鉴权 | Kubernetes

RBAC通俗理解

  翻译下上方两个官方文档的内容,通俗但不准确的介绍:
Kubernetes中使用RBAC模型(Role-Based Access Control):基于角色的访问控制,k8s1.6及以上版本的集群默认开启)来控制用户访问,主要存在这么几类资源:

  • 用户资源
    • serviceaccount: 服务账户,实际存在的k8s资源,用于控制集群内的资源,较轻量化,推荐使用
    • useraccount: 普通账户,更符合我们通常意义上的用户概念,非k8s资源,而且可以说就是个单纯的概念。它不在k8s集群内生成,而是使用集群中的/etc/kubernetes/pki/ca.key证书文件在集群外部通过一些认证工具(如openssl)生成client.crt client.csr client.key前在命令中配置。
      注1:其实还有Group之类的概念,也勉强算是用户资源的概念,可以被权限资源绑定
  • 权限控制资源
    • Role: 命名空间级别的权限声明配置文件,如访问命名空间下哪个资源,如pod(仅限当前命名空间);能进行什么操作,如get、delete
    • ClusterRole: 集群级别的权限声明配置文件,如访问哪种资源,如pod(跨所有命名空间),能进行什么操作,如get、delete
  • 权限绑定资源(类似pod和pv之间绑定用的pvc)
    • RoleBinding:用于绑定用户资源(如serviceaccount)和Role的声明
    • ClusterRoleBinding :用于绑定用户资源(如serviceaccount)和ClusterRoleBinding 的声明

注1:这类权限绑定资源,yaml/json中有subjects字段用于指定用户资源,有roleRef字段用于指定权限控制资源
– 权限绑定资源(类似pod和pv之间绑定用的pvc)
– RoleBinding:用于绑定用户资源(如serviceaccount)和Role的声明
– ClusterRoleBinding :用于绑定用户资源(如serviceaccount)和ClusterRoleBinding 的声明
– 密钥文件
创建时yaml/json中type设置为kubernetes.io/service-account-token;annotations的kubernetes.io/service-account.name的值设置为serviceaccount的名称。创建后会自动创建包含sa绑定的权限的ca.crt和token信息

而我们的api-server访问,则就是通过token进行k8s权限认证,ca.crt文件进行https认证

使用clusterrole、clusterrolebing创建包含集群所有权限的管理员serviceaccount

通过role、rolebing创建包含特定命名空间、pod仅查看权限的serviceaccount

kubectl proxy:dashboard使用kubectl proxy实现http访问

kubectl port-forward:minukube部署的应用暴露tcp服务端口

0 0 投票数
文章评分
订阅评论
提醒
guest
0 评论
内联反馈
查看所有评论
0
希望看到您的想法,请您发表评论x