01. apiserver 启动参数和调试准备
apiserver 的入口:
func main() {
command := app.NewAPIServerCommand()
code := cli.Run(command)
os.Exit(code)
}
命令行工具的功能是使用的 github.com/spf13/cobra 库,不要陷入细节,直接跳到 app.NewAPIServerCommand()
方法。
首先会初始化默认的启动参数,得到 *ServerRunOptions
类型的 s
变量:
s := options.NewServerRunOptions()
打个断点感受下 s
的默认值:
其中各个参数的介绍可以看:https://kubernetes.io/zh-cn/docs/reference/command-line-tools-reference/kube-apiserver/
得到 s
参数后,还要对其进行一系列的处理,才可以使用:
// 设置默认参数选项
completedOptions, err := Complete(s)
if err != nil {
return err
}
设置完后,还需要对参数进行合法性校验:
// 参数选项的校验
if errs := completedOptions.Validate(); len(errs) != 0 {
return utilerrors.NewAggregate(errs)
}
在这里,如果参数不合法就会校验失败,errs
会返回具体的错误:
为了让 apiserver 正常启动,需要设置 etcd 的参数配置(这里为了专注于 k8s 自身组件,etcd 就搭建了一个本地单机版,并且没有使用 tls 认证):
--etcd-servers=http://127.0.0.1:2379
而 apiserver 的 tls 证书配置,可以用 easyrsa 来生成:
curl -LO https://dl.k8s.io/easy-rsa/easy-rsa.tar.gz
tar xzf easy-rsa.tar.gz
cd easy-rsa-master/easyrsa3
./easyrsa init-pki
export MASTER_IP=127.0.0.1
export MASTER_CLUSTER_IP=127.0.0.1
./easyrsa --batch "--req-cn=${MASTER_IP}@`date +%s`" build-ca nopass
./easyrsa --subject-alt-name="IP:${MASTER_IP},"\
"IP:${MASTER_CLUSTER_IP},"\
"DNS:kubernetes,"\
"DNS:kubernetes.default,"\
"DNS:kubernetes.default.svc,"\
"DNS:kubernetes.default.svc.cluster,"\
"DNS:kubernetes.default.svc.cluster.local" \
--days=10000 \
build-server-full server nopass
将生成的证书( pki/ca.crt
、pki/issued/server.crt
和 pki/private/server.key
)拷贝到自定义目录(例如:cert
),并添加到 apiserver 的启动参数中:
--client-ca-file=cert/ca.crt
--tls-cert-file=cert/server.crt
--tls-private-key-file=cert/server.key
另外 pod 访问 kube-apiserver 还需要用到 service account 证书(pki/private/ca.key
),需要指定服务帐号令牌颁发者 :
--service-account-issuer=api
--service-account-key-file=cert/ca.crt
--service-account-signing-key-file=cert/ca.key
总结,启动所需要的基本参数:
--etcd-servers=http://127.0.0.1:2379 --client-ca-file=cert/ca.crt --tls-cert-file=cert/server.crt --tls-private-key-file=cert/server.key --service-account-issuer=api --service-account-key-file=cert/ca.crt --service-account-signing-key-file=cert/ca.key
此时,cert
目录有以下证书文件(包括 ca 证书、服务端证书):
apiserver 启动成功后,可以直接使用 curl 充当一个客户端调用 apiserver 的接口,但是得先为客户端创建客户端证书:
# 生成客户端私钥
openssl genrsa -out cert/client.key 2048
# 生成证书签名请求(CSR)
openssl req -new -key cert/client.key -out cert/client.csr -subj "/CN=<client-name>"
# 使用 kube-apiserver 的 CA 签署 CSR,生成客户端证书
openssl x509 -req -in cert/client.csr -CA cert/ca.crt -CAkey cert/ca.key -CAcreateserial -out cert/client.crt -days 365
有了客户端证书,就可以调用 apiserver 接口了:
$ curl --cacert cert/ca.crt --cert cert/client.crt --key cert/client.key https://127.0.0.1:6443/version
{
"major": "",
"minor": "",
"gitVersion": "v0.0.0-master+$Format:%H$",
"gitCommit": "$Format:%H$",
"gitTreeState": "",
"buildDate": "1970-01-01T00:00:00Z",
"goVersion": "go1.20.3",
"compiler": "gc",
"platform": "linux/amd64"
}
对于 kubectl 的使用,也同样需要使用客户端证书:
# 添加新集群(apiserver地址)
kubectl config set-cluster devk8s --server=https://127.0.0.1:6443 --certificate-authority=cert/ca.crt
# 添加用户(客户端证书)
kubectl config set-credentials devk8s --client-certificate=cert/client.crt --client-key=cert/client.key
# 添加上下文(绑定集群和用户)
kubectl config set-context devk8s --user=devk8s --cluster=devk8s
# 切换当前上下文
kubectl config use-context devk8s
验证 kubectl :
$ kubectl get ns
NAME STATUS AGE
default Active 2d6h
kube-node-lease Active 2d6h
kube-public Active 2d6h
kube-system Active 2d6h
创建一个 pod :
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
如果遇到 pods "nginx" is forbidden: error looking up service account defau lt/default: serviceaccount "default" not found
错误,意味着还没有默认的 serviceaccount
,则先执行:
kubectl create sa default
创建 pod 后观察(控制平面组件未全部启动,处于 Pending 状态为正常现象):
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx 0/1 Pending 0 13s
当然,有了 kubectl ,可以直接使用 proxy 模式转发 apiserver 的接口:
kubectl proxy --port=8080
apiserver 的 API 使用了 openapi 规范,暴露出了 /openapi/v2
接口,所以如果有需要,可以自己搭建一个 swagger-ui 服务导入该接口地址进行调试。
此时,etcd 存储的数据如下(使用 ETCD Keeper 可视化展示):
至此,先告一段落,现在 apiserver 已经成功启动,为了后续方便调试 apiserver ,kubectl
工具,etcd
数据展示也已准备好。
微信公众号
更多内容请关注微信公众号:gopher云原生