Kubernetes之ServiceAccount+Secret

第0章、前言 API Server作为Kubernetes网关,是访问和管理资源对象的唯一入口,其各种集群组件访问资源都需要经过网关才能进行正常访问和管理。每一次的访问请求都需要进行合法性的检验,其中...

第0章、前言

API Server作为Kubernetes网关,是访问和管理资源对象的唯一入口,其各种集群组件访问资源都需要经过网关才能进行正常访问和管理。每一次的访问请求都需要进行合法性的检验,其中包括身份验证、操作权限验证以及操作规范验证等,需要通过一系列验证通过之后才能访问或者存储数据到etcd当中。如下图:

attachments-2021-11-M025bCIV618b8a6ca8591,png

每一个用户对API资源进行操作都需要通经过以下三个步骤:


第一步:对客户端访问进行认证操作,确认是否具有访问k8s权限

    token(共享秘钥)

    SSL(双向SSL认证)

....通过任何一个认证即表示认证通过,进入下一步

第二步:授权检查,确认是否对资源具有相关的权限

    ABAC(基于属性的访问控制)

    RBAC(基于角色的访问控制)

    NODE(基于节点的访问控制)

    WEB HOOK(自定义HTTP回调方法的访问控制)

第三步:准入控制(对操作资源相关联的其他资源是否有权限操作)

Kubernetes只对以下的API请求属性进行检查:

user - username,uid

group - user group 

"extra"- 额外信息

API - API资源的对象 

Request path - 请求资源的路径(k8s使用resultful风格接口的API) 

 http://Node_IPaddr:6443/apis/apps/v1/namespaces/namespaces_name/resource_name/

HTTP 请求动作 - HTTP verbs get,post,put,和delete用于非资源请求

HTTP 请求动作映射到 API资源操作-  get,list,create,update,patch,watch,proxy,redirect,delete,和deletecollection用于请求resource

Resource -被访问(仅用于resource 请求)的resource 的ID或名字- *对于使用resource 的请求get,update,patch,和delete,必须提供resource 名称。

Subresource - 正在访问的subresource (仅用于请求resource )

Namespace - 正在访问对象的命名空间(仅针对命名空间的请求资源)

API group - 正在访问的API组(仅用于请求资源)。空字符串指定核心API组。

Secret解决了密码、token、密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者Pod Spec中。Secret可以以Volume或者环境变量的方式使用

第一章、Secret

Secret类型


Secret有三种类型:
Opaque:base64编码格式的Secret,用来存储密码、密钥等;但数据也通过base64 –decode解码得到原始数据,所以加密性很弱。
kubernetes.io/dockerconfigjson:用来存储私有docker registry的认证信息。
kubernetes.io/service-account-token: 用于被serviceaccount引用。serviceaccout创建时Kubernetes会默认创建对应的secret。Pod如果使用了serviceaccount,对应的secret会自动挂载到Pod目录/run/secrets/ kubernetes.io/serviceaccount中。

Opaque Secret

Opaque类型的数据是一个map类型,要求value是base64编码格式:

$ echo -n "admin" | base64

YWRtaW4=

$ echo -n "1f2d1e2e67df" | base64

MWYyZDFlMmU2N2Rm

secrets.yml

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  password: MWYyZDFlMmU2N2Rm
  username: YWRtaW4=

创建secret:kubectl create -f secrets.yml。

# kubectl get secret
NAME                  TYPE                                  DATA      AGE
default-token-cty7p   kubernetes.io/service-account-token   3         45d
mysecret              Opaque                                2         7s


注意:其中default-token-cty7p为创建集群时默认创建的secret,被serviceacount/default引用。

如果是从文件创建secret,则可以用更简单的kubectl命令,比如创建tls的secret:

$ kubectl create secret generic helloworld-tls \

  --from-file=key.pem \

--from-file=cert.pem

Opaque Secret的使用

创建好secret之后,有两种方式来使用它:

以Volume方式

以环境变量方式

以Volume方式挂载制定的key

将Secret挂载到Volume中
apiVersion: v1
kind: Pod
metadata:
  labels:
    name: db
  name: db
spec:
  volumes:
  - name: secrets
    secret:
      secretName: mysecret
  containers:
  - image: gcr.io/my_project_id/pg:v1
    name: db
    volumeMounts:
    - name: secrets
      mountPath: "/etc/secrets"
      readOnly: true
    ports:
    - name: cp
      containerPort: 5432
      hostPort: 5432

查看Pod中对应的信息:
# ls /etc/secrets
password  username
# cat  /etc/secrets/username
admin
# cat  /etc/secrets/password
1f2d1e2e67df

将Secret导出到环境变量中

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: wordpress-deployment
spec:
  replicas: 2
  strategy:
      type: RollingUpdate
  template:
    metadata:
      labels:
        app: wordpress
        visualize: "true"
    spec:
      containers:
      - name: "wordpress"
        image: "wordpress"
        ports:
        - containerPort: 80
        env:
        - name: WORDPRESS_DB_USER
          valueFrom:
            secretKeyRef:
              name: mysecret
              key: username
        - name: WORDPRESS_DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysecret
              key: password

将Secret挂载指定的key

apiVersion: v1
kind: Pod
metadata:
  labels:
    name: db
  name: db
spec:
  volumes:
  - name: secrets
    secret:
      secretName: mysecret
      items:
      - key: password
        mode: 511
        path: tst/psd
      - key: username
        mode: 511
        path: tst/usr
  containers:
  containers:
  - image: nginx
    name: db
    volumeMounts:
    - name: secrets
      mountPath: "/etc/secrets"
      readOnly: true
    ports:
    - name: cp
      containerPort: 80
      hostPort: 5432

创建Pod成功后,可以在对应的目录看到:

# kubectl exec db ls /etc/secrets/tst 
psd
usr

kubernetes.io/dockerconfigjson

可以直接用kubectl命令来创建用于docker registry认证的secret:

$ kubectl create secret docker-registry myregistrykey 

--docker-server=DOCKER_REGISTRY_SERVER

 --docker-username=DOCKER_USER 

 --docker-password=DOCKER_PASSWORD 

 --docker-email=DOCKER_EMAIL


secret "myregistrykey" created.

查看secret的内容:

# kubectl get secret myregistrykey  -o yaml

apiVersion: v1

data:

  .dockercfg: eyJjY3IuY2NzLnRlbmNlbnR5dW4uY29tL3RlbmNlbnR5dW4iOnsidXNlcm5hbWUiOiIzMzIxMzM3OTk0IiwicGFzc3dvcmQiOiIxMjM0NTYuY29tIiwiZW1haWwiOiIzMzIxMzM3OTk0QHFxLmNvbSIsImF1dGgiOiJNek15TVRNek56azVORG94TWpNME5UWXVZMjl0In19

kind: Secret

metadata:

  creationTimestamp: 2017-08-04T02:06:05Z

  name: myregistrykey

  namespace: default

  resourceVersion: "1374279324"

  selfLink: /api/v1/namespaces/default/secrets/myregistrykey

  uid: 78f6a423-78b9-11e7-a70a-525400bc11f0

type: kubernetes.io/dockercfg

也可以直接读取~/.dockercfg的内容来创建:

$ kubectl create secret docker-registry myregistrykey \

  --from-file="~/.dockercfg"

在创建Pod的时候,通过imagePullSecrets来引用刚创建的myregistrykey:

apiVersion: v1

kind: Pod

metadata:

  name: foo

spec:

  containers:

    - name: foo

      image: janedoe/awesomeapp:v1

  imagePullSecrets:

    - name: myregistrykey


kubernetes.io/service-account-token

kubernetes.io/service-account-token: 用于被serviceaccount引用。serviceaccout创建时Kubernetes会默认创建对应的secret。Pod如果使用了serviceaccount,对应的secret会自动挂载到Pod的/run/secrets/kubernetes.io/serviceaccount目录中。


$ kubectl run nginx --image nginx

deployment "nginx" created

$ kubectl get pods

NAME                     READY     STATUS    RESTARTS   AGE

nginx-3137573019-md1u2   1/1       Running   0          13s

$ kubectl exec nginx-3137573019-md1u2 ls /run/secrets/kubernetes.io/serviceaccount

ca.crt

namespace

token


Secret与ConfigMap对比

相同点:

key/value的形式
属于某个特定的namespace
可以导出到环境变量
可以通过目录/文件形式挂载(支持挂载所有key和部分key)
不同点:

Secret可以被ServerAccount关联(使用)
Secret可以存储register的鉴权信息,用在ImagePullSecret参数中,用于拉取私有仓库的镜像
Secret支持Base64加密
Secret分为kubernetes.io/Service Account,kubernetes.io/dockerconfigjson,Opaque三种类型,Configmap不区分类型
Secret文件存储在tmpfs文件系统中,Pod删除后Secret文件也会对应的删除。

第二章、ServiceAccount
User Accounts 与 Service Accounts
Kubernetes区分普通帐户(user accounts)和服务帐户(service accounts)的原因:


-普通帐户是针对(人)用户的,服务账户针对Pod进程。
-普通帐户是全局性。在集群所有namespaces中,名称具有惟一性。
-通常,群集的普通帐户可以与企业数据库同步,新的普通帐户创建需要特殊权限。服务账户创建目的是更轻量化,允许集群用户为特定任务创建服务账户。
-普通帐户和服务账户的审核注意事项不同。
-对于复杂系统的配置包,可以包括对该系统的各种组件的服务账户的定义。

Token controller

TokenController作为controller-manager的一部分运行。异步行为:

-观察serviceAccount的创建,并创建一个相应的Secret 来允许API访问。

-观察serviceAccount的删除,并删除所有相应的ServiceAccountToken Secret

-观察secret 添加,并确保关联的ServiceAccount存在,并在需要时向secret 中添加一个Token。

-观察secret 删除,并在需要时对应 ServiceAccount 的关联


需要使用–service-account-private-key-file 参数选项将Service Account 密匙(key)文件传递给controller-manager中的Token controller。key用于 Service Account Token签名。同样,也需要使用–service-account-key-file 参数选项将相应的(public key)公匙传递给kube-apiserver ,公钥用于在认证期间验证Token。

Service Account Controller
Service Account Controller在namespaces里管理ServiceAccount,并确保每个有效的namespaces中都存在一个名为“default”的ServiceAccount。

什么是serviceaccount
Service Account 用来访问 kubernetes API,通过 kubernetes API 创建和管理,每个 account 只能在一个 namespace 上生效,存储在 kubernetes API 中的 Secrets 资源。kubernetes 会默认创建,并且会自动挂载到 Pod 中的 /run/secrets/kubernetes.io/serviceaccount 目录下。
Service account是为了方便Pod里面的进程调用Kubernetes API或其他外部服务而设计的。它与User account不同:

  1.User account是为人设计的,而service account则是为Pod中的进程调用Kubernetes API而设计;
  2.User account是跨namespace的,而service account则是仅局限它所在的namespace;
  3.每个namespace都会自动创建一个default service account
  4.Token controller检测service account的创建,并为它们创建secret
  5.开启ServiceAccount Admission Controller后
1.每个Pod在创建后都会自动设置spec.serviceAccount为default(除非指定了其他ServiceAccout)
2.验证Pod引用的service account已经存在,否则拒绝创建
3.如果Pod没有指定ImagePullSecrets,则把service account的ImagePullSecrets加到Pod中
4.每个container启动后都会挂载该service account的token和ca.crt到/var/run/secrets/kubernetes.io/serviceaccount/  




  • 发表于 2021-11-10 17:02
  • 阅读 ( 48 )

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
shitian
shitian

662 篇文章

作家榜 »

  1. shitian 662 文章
  2. 石天 437 文章
  3. 每天惠23 33 文章
  4. 小A 29 文章