一、安装GO模块
首先下载最新的GO压缩包,国内的节点下载不了了,只能到国外的节点先下载,再传回到服务器上。官网网址如下:https://golang.google.cn/dl/我下载的是现在最新的go1.20.4linux-amd64.tar.gz,上传服务器后解压缩tar -xzf go1.19.linux-amd64.tar.gz,使用mv指令放到/usr/local/src文件夹中。
配置环境变量
vim /etc/profile
export PATH=$PATH:/usr/local/src/go/bin # GO PATH
export GO111MODULE="on" # 开启 Go moudles 特性
export GOPROXY=https://goproxy.cn,direct # 安装 Go 模块时,国内代理服务器设置
立即生效
source /etc/profile
使用下述命令查看环境是否配置成功
go version
go env
二、kubectl 代理
根据k8s官方文档https://kubernetes.io/zh-cn/docs/tasks/extend-kubernetes/http-proxy-access-api/使用如下命令启动K8S API服务器代理:
kubectl proxy --port=8080
在本地使用curl,wget或者浏览器可以访问API。
然后这时候因为我的K8S部署在服务器上,我就想在我的主机上用浏览器访问,然后我在浏览器中输入192.168.1.105:6443(192.168.1.105是我虚拟服务器在局域网中的IP),然后找不到,我在CMD中curl它,报以下错误。
那其实问题已经出来了,需要在前面加HTTPS,然后我就在浏览器中输入https://192.168.1.105:6443/
出现以下结果。
报错说没有权限,那就应该是整数问题,因为我这是集群外的主机,没有K8S集群的证书,下面就要解决这个问题。
三、kubernetes API访问控制
用户使用kubectl,客户端或者构造REST请求来访问K8S API的时候,人类用户和K8S服务账户(服务账号为pod中运行的进程提供身份标识,并且映射到ServiceAccount对象)都可以被鉴权访问K8S API,当请求到达API的时候,他会经历多个阶段,具体如下图所示:
3.1传输安全
在默认情况下,K8S API服务器在第一个非localhost网络端口上进行监听,受到TLS保护。在一个典型的K8S生产集群中,API使用443端口。该端口可以通过 –secure-port 进行变更,监听IP地址可以通过 –bind-address 标志进行变更。
API服务器出示证书,该证书可以使用私有证书颁发机构(CA)的签名,也可以基于链接到公认的CA的公钥基础架构签名。该证书和对应的私钥可以通过使用 –tls-cert-file 和 –tls-private-key-file 标志进行设置。
如果你的集群使用私有证书颁发机构,你需要在客户端的 ~/.kube/config文件中提供该CA证书的副本,以便于你可以行人该连接并确认该连接没有被拦截。
你的客户端可以在此阶段出示TLS客户端证书。
3.2认证
如上图步骤1所示,建立TLS后,HTTP请求将进入认证(Authentication)步骤。集群创建脚本或者集群管理员配置API服务器,使之运行一个或者多个身份认证组件。
认证步骤的输入是整个HTTP请求,但是通常组件只检查头部和客户端证书。
认证模块包含客户端证书,密码,普通令牌,引导令牌和JSON Web令牌(JWT,用于服务账户)。
可以指定多个认证模块,在这种情况下,服务器依次尝试每个验证模块,直到其中一个成功。
如果请求认证不通过,服务器将以HTTP状态码401拒绝该请求。反之,该用户被认证为特定的username,并且该用户名可用于后续步骤以解决在其决策中使用。部分验证器还提供用户的组成员身份,其他则不提供。
3.3鉴权
如上图的步骤2所示,将请求验证为来自特定用户后,请求必须被鉴权。
请求必须包含请求者的用户名,请求的行为以及受到该操作影响的对象。如果现有策略声明用户有权完成请求的操作,那么该请求被鉴权通过。
3.4准入控制
准入控制模块是可以修改或者拒绝请求的软件模块。除了鉴权模块可用的属性外,准入控制模块还可以访问正在创建或者修改的对象的内容。
准入控制器对创建,修改,删除或者通过代理连接连接对象的请求进行操作。准入控制器不会对仅读取对象的请求起作用。有多个准入控制器被配置时,服务器将依次调用他们。
这一操作如上图步骤三所示。
与身份认证和鉴权模块不同,如果任何准入控制器模块拒绝某请求,则该请求将被立刻拒绝。
除了拒绝对象之外,准入控制器还可以为字段设置复杂的默认值。
请求通过所有准入控制器后,将使用检验例程检查对应的API对象,然后将其写入对象存储中,例如上图的步骤4.
四、使用openssl携带CA证书在集群外访问K8S集群
4.1 创建认证信息
4.1.1 首先是安装openssl,且保证接下来的操作都具有ROOT权限
apt-get install openssl
4.1.2 创建一个文件夹叫做openssl-cert /
mkdir -p ~/openssl-cert && cd ~/openssl-cert
4.1.3 执行生成key,根据客户端生成私钥
openssl genrsa -out hjw.key 2048
4.1.4 根据私钥生成csr,/CN指定了用户名是hjw
openssl req -new -key hjw.key -out hjw.csr -subj "/CN=hjw/"
4.1.5 生成证书
openssl x509 -req -in hjw.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out hjw.crt -days 365
如果忘记了证书设置的CN(common name)是啥 可以用下面命令搞定
openssl x509 -noout -subject -in hjw.crt
4.1.6 查看集群的endpoints
root@master-node:/home/hjw/openssl-cert# kubectl get endpoints
NAME ENDPOINTS AGE
kubernetes 192.168.1.105:6443 88d
4.1.7 查看集群的版本
$ curl --cert hjw.crt --key hjw.key --cacert /etc/kubernetes/pki/ca.crt -s https://192.168.1.105:6443/version
{
"major": "1",
"minor": "22",
"gitVersion": "v1.22.0",
"gitCommit": "c2b5237ccd9c0f1d600d3072634ca66cefdf272f",
"gitTreeState": "clean",
"buildDate": "2021-08-04T17:57:25Z",
"goVersion": "go1.16.6",
"compiler": "gc",
"platform": "linux/amd64"
}
4.1.8查看pod
$ curl --cert hjw.crt --key hjw.key --cacert /etc/kubernetes/pki/ca.crt -s https://192.168.1.105:6443/api/v1/pods
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {},
"status": "Failure",
"message": "pods is forbidden: User \"admin\" cannot list resource \"pods\" in API group \"\" at the cluster scope",
"reason": "Forbidden",
"details": {
"kind": "pods"
},
"code": 403
}
能够看到我们的请求被拦截了,原因是禁止访问,这是因为授权没有通过。
4.2加入到kubeconfig
4.2.1把client.crt加入到~/.kube/config。这一步把用户设置到config文件中。也可以加上“–embed-certs=true”选项,直接将文件内容填充到config文件中。
kubectl config set-credentials hjw --client-certificate=hjw.crt --client-key=hjw.key --embed-certs=true
4.2.2添加一个context
kubectl config set-context hjw --cluster=kubernetes --user=hjw
4.2.3切换context:
kubectl config use-context hjw
4.2.4此时访问再次查看pod:
$ kubectl get pods
Error from server (Forbidden): pods is forbidden: User "hjw" cannot list resource "pods" in API group "" in the namespace "default"
能够看到是被禁止访问的。说明我们的请求没有经过授权(Authorization)。
4.3添加角色和绑定角色
4.3.1需要先切换上下文到用户kubernetes-admin下:
kubectl config use-context kubernetes-admin@kubernetes
4.3.2为此我们需要使用RABC为用户admin授予操作权限
$ kubectl create role developer \
--verb=create \
--verb=get \
--verb=list \
--verb=update \
--verb=delete \
--resource=pods
4.3.3绑定角色:
kubectl create rolebinding developer-binding-hjw --role=developer --user=hjw
注意:以上所绑定的role,默认只能访问default命名空间下的POD,添加-n选项,指定能访问的命名空间
4.3.4切回到hjw用户下,创建Nginx POD
kubectl run nginx --image=nginx
4.3.5再次查看POD,请求没有被拦截
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 117s
4.3.6以API方式,访问默认命名空间下的内容,也能正常访问
$ curl --cert hjw.crt \
--key hjw.key \
--cacert /etc/kubernetes/pki/ca.crt \
https://192.168.1.105:6443/api/v1/namespaces/default/pods
{
"kind": "PodList",
"apiVersion": "v1",
"metadata": {
"resourceVersion": "2714"
},
"items": [
{
"metadata": {
"name": "nginx",
"namespace": "default",
"uid": "e5b9381c-a1ca-4632-abb0-afbc9cb56e0b",
"resourceVersion": "2682",
"creationTimestamp": "2022-11-08T13:05:54Z",
"labels": {
"run": "nginx"
},
"managedFields": [
{
...
4.3.7访问default命名空间下的service和deploy
$ kubectl get svc,deploy
Error from server (Forbidden): services is forbidden: User "admin" cannot list resource "services" in API group "" in the namespace "default"
Error from server (Forbidden): deployments.apps is forbidden: User "admin" cannot list resource "deployments" in API group "apps" in the namespace "default"
请求被拦截,没有访问权限。这是因为上面我们在创建角色的时候,指定了只能访问POD,如果想要访问其他资源,修改角色即可。
4.3.8在集群外的windows电脑用CMD进行测试
D:\K8S系统集成\go后端\openssl\openssl-cert>curl -cert hjw.crt -key hjw.key -cacert ca.crt https://192.168.1.105:6443/api/v1/namespaces/default/pods
curl: (6) Could not resolve host: hjw.crt
curl: (6) Could not resolve host: hjw.key
curl: (6) Could not resolve host: ca.crt
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {},
"status": "Failure",
"message": "pods is forbidden: User \"system:anonymous\" cannot list resource \"pods\" in API group \"\" in the namespace \"default\"",
"reason": "Forbidden",
"details": {
"kind": "pods"
},
"code": 403
}
这是因为CMD的CURL有问题,别人的解释如下:
使用git就成功了