从零到一k8s(七)Faqs

认证相关问题

目前主流是RBAC认证
官方文档地址
划重点的一段话

  1. 尽管无法通过 API 调用来添加普通用户,Kubernetes 仍然认为能够提供由集群的证书 机构签名的合法证书的用户是通过身份认证的用户。基于这样的配置,Kubernetes 使用证书中的 'subject' 的通用名称(Common Name)字段(例如,"/CN=bob")来 确定用户名。接下来,基于角色访问控制(RBAC)子系统会确定用户是否有权针对 某资源执行特定的操作。进一步的细节可参阅 证书请求 下普通用户主题。

  2. 与此不同,服务账号是 Kubernetes API 所管理的用户。它们被绑定到特定的名字空间, 或者由 API 服务器自动创建,或者通过 API 调用创建。服务账号与一组以 Secret 保存 的凭据相关,这些凭据会被挂载到 Pod 中,从而允许集群内的进程访问 Kubernetes API。

  3. API 请求则或者与某普通用户相关联,或者与某服务账号相关联,亦或者被视作 匿名请求。这意味着集群内外的每个进程在向 API 服务器发起 请求时都必须通过身份认证,否则会被视作匿名用户。这里的进程可以是在某工作站上 输入 kubectl 命令的操作人员,也可以是节点上的 kubelet 组件,还可以是控制面 的成员。

点击查看代码
 openssl x509 -in /etc/kubernetes/pki/front-proxy-ca.crt -noout -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 0 (0x0)
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN = front-proxy-ca
        Validity
            Not Before: Mar  5 11:42:53 2022 GMT
            Not After : Mar  2 11:42:53 2032 GMT
        Subject: CN = front-proxy-ca

下面回用两种方式来创建kubeconfig 文件 sa and ca

sa method

脚本搬运工

点击查看代码
#!/bin/bash
set -e
set -o pipefail

# Add user to k8s using service account, no RBAC (must create RBAC after this script)
if [[ -z "$1" ]] || [[ -z "$2" ]]; then
 echo "usage: $0 <service_account_name> <namespace>"
 exit 1
fi

SERVICE_ACCOUNT_NAME=$1
NAMESPACE="$2"
KUBECFG_FILE_NAME="/tmp/kube/k8s-${SERVICE_ACCOUNT_NAME}-${NAMESPACE}-conf"
TARGET_FOLDER="/tmp/kube"

create_target_folder() {
    echo -n "Creating target directory to hold files in ${TARGET_FOLDER}..."
    mkdir -p "${TARGET_FOLDER}"
    printf "done"
}

create_service_account() {
    echo -e "\\nCreating a service account in ${NAMESPACE} namespace: ${SERVICE_ACCOUNT_NAME}"
    kubectl create sa "${SERVICE_ACCOUNT_NAME}" --namespace "${NAMESPACE}"
}

get_secret_name_from_service_account() {
    echo -e "\\nGetting secret of service account ${SERVICE_ACCOUNT_NAME} on ${NAMESPACE}"
    SECRET_NAME=$(kubectl get sa "${SERVICE_ACCOUNT_NAME}" --namespace="${NAMESPACE}" -o json | jq -r .secrets[].name)
    echo "Secret name: ${SECRET_NAME}"
}

extract_ca_crt_from_secret() {
    echo -e -n "\\nExtracting ca.crt from secret..."
    kubectl get secret --namespace "${NAMESPACE}" "${SECRET_NAME}" -o json | jq \
    -r '.data["ca.crt"]' | base64 -D > "${TARGET_FOLDER}/ca.crt"
    printf "done"
}

get_user_token_from_secret() {
    echo -e -n "\\nGetting user token from secret..."
    USER_TOKEN=$(kubectl get secret --namespace "${NAMESPACE}" "${SECRET_NAME}" -o json | jq -r '.data["token"]' | base64 -D)
    printf "done"
}

set_kube_config_values() {
    context=$(kubectl config current-context)
    echo -e "\\nSetting current context to: $context"

    CLUSTER_NAME=$(kubectl config get-contexts "$context" | awk '{print $3}' | tail -n 1)
    echo "Cluster name: ${CLUSTER_NAME}"

    ENDPOINT=$(kubectl config view \
    -o jsonpath="{.clusters[?(@.name == \"${CLUSTER_NAME}\")].cluster.server}")
    echo "Endpoint: ${ENDPOINT}"

    # Set up the config
    echo -e "\\nPreparing k8s-${SERVICE_ACCOUNT_NAME}-${NAMESPACE}-conf"
    echo -n "Setting a cluster entry in kubeconfig..."
    kubectl config set-cluster "${CLUSTER_NAME}" \
    --kubeconfig="${KUBECFG_FILE_NAME}" \
    --server="${ENDPOINT}" \
    --certificate-authority="${TARGET_FOLDER}/ca.crt" \
    --embed-certs=true

    echo -n "Setting token credentials entry in kubeconfig..."
    kubectl config set-credentials \
    "${SERVICE_ACCOUNT_NAME}-${NAMESPACE}-${CLUSTER_NAME}" \
    --kubeconfig="${KUBECFG_FILE_NAME}" \
    --token="${USER_TOKEN}"

    echo -n "Setting a context entry in kubeconfig..."
    kubectl config set-context \
    "${SERVICE_ACCOUNT_NAME}-${NAMESPACE}-${CLUSTER_NAME}" \
    --kubeconfig="${KUBECFG_FILE_NAME}" \
    --cluster="${CLUSTER_NAME}" \
    --user="${SERVICE_ACCOUNT_NAME}-${NAMESPACE}-${CLUSTER_NAME}" \
    --namespace="${NAMESPACE}"

    echo -n "Setting the current-context in the kubeconfig file..."
    kubectl config use-context "${SERVICE_ACCOUNT_NAME}-${NAMESPACE}-${CLUSTER_NAME}" \
    --kubeconfig="${KUBECFG_FILE_NAME}"
}

create_target_folder
create_service_account
get_secret_name_from_service_account
extract_ca_crt_from_secret
get_user_token_from_secret
set_kube_config_values

echo -e "\\nAll done! Test with:"
echo "KUBECONFIG=${KUBECFG_FILE_NAME} kubectl get pods"
echo "you should not have any permissions by default - you have just created the authentication part"
echo "You will need to create RBAC permissions"
KUBECONFIG=${KUBECFG_FILE_NAME} kubectl get pods

ca method

点击查看代码
mkdir zhengshu
cd zhengshu
cp ~/.kube/config .
编辑当前目录下的config 文件更改用户名为 song
#生产 csr
openssl genrsa -out song.key 2048
openssl req -new -key song.key -out song.csr  -subj "/CN=song/O=lovexlq"
# 获取证书
kubectl certificate approve song123
kubectl get csr song123 -o jsonpath='{.status.certificate}'| base64 -d > myuser.crt
# 生产 csr 对象
cat <<EOF | kubectl apply -f -
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: song123
spec:
  request: `cat song.csr | base64 | tr -d "\n"`
  signerName: kubernetes.io/kube-apiserver-client
  expirationSeconds: 600  # one day
  usages:
  - client auth
EOF
# 生成 rolebind
kubectl create role developer --verb=create --verb=get --verb=list --verb=update --verb=delete --resource=pods
kubectl create rolebinding developer-binding-song --role=developer --user=song
# 设置 rolebind
KUBECONFIG=./config kubectl config set-credentials song --client-certificate=/root/zhengshu/song.crt --client-key=`pwd`/song.key --embed-certs=true
kubectl create rolebinding developer-binding-song --role=developer --user=song

KUBECONFIG=./config kubectl get pod 


证书会不会过期,过期有什么影响

官方文档给你介绍了很多,为了防止集群之间api 错误调用引发的问题。集群之间的通信要依靠tls 双向认证去做。一个集群由一个独立的CA系统提供证书。各个组件启动命令行有 -- bootstrap-config 的配置项,例如向kubelet 这个组件启动流程
在启动 kubelet 时,如果 --kubeconfig 标志所指定的文件并不存在,会使用通过标志 --bootstrap-kubeconfig 所指定的启动引导 kubeconfig 配置来向 API 服务器请求 客户端证书。在证书请求被批复并被 kubelet 收回时,一个引用所生成的密钥和所获得 证书的 kubeconfig 文件会被写入到通过 --kubeconfig 所指定的文件路径下。 证书和密钥文件会被放到 --cert-dir 所指定的目录中。

由于我们的集群体系是以kubeadm 的方式进行的安装,主要组件apiserver controller schedluer kube-proxy 默认运行在容器模式下 启动依赖的kubeconfig 文件中使用的是是token。 理论上我们只需要保证kubelet 和 etcd 集群的证书健康即可。

kubelet 证书自动approve

点击查看代码

kubeadm certs 命令使用

聚合层的apiserver 概念

配置聚合层 可以允许 Kubernetes apiserver 使用其它 API 扩展,这些 API 不是核心 Kubernetes API 的一部分。
通俗一点翻译就是,你可以向apiserver 中注册api 。当有请求到apiserver 时,通过鉴权后这部分流量会转发到对应的服务上,下面已常用的metrics-server 为例子说明一下:

点击查看代码
apiVersion: apiregistration.k8s.io/v1
kind: APIService
metadata:"
  labels:
    k8s-app: metrics-server
  name: v1beta1.metrics.k8s.io
spec:
  group: metrics.k8s.io
  groupPriorityMinimum: 100
  insecureSkipTLSVerify: true
  service:
    name: metrics-server
    namespace: kube-system
    port: 443
  version: v1beta1
  versionPriority: 100
  ---
当有服务要请求v1beta1.metrics.k8s.io流程如下:
1. 请求到达apiserver
2. 进行鉴权(OIDC或者certs),鉴权通过进行下一步,不通过直接返回错误
3. 鉴权通过后使用 front-proxy-client.ca 来进行服务请求到对应的服务metrics-server
4.扩展 apiserver:对来自原始用户的请求鉴权
5. metrics-server 处理请求后返回

image

posted @ 2022-03-10 17:54  萱乐庆foreverlove  阅读(31)  评论(0编辑  收藏  举报