Kubernetes_梳理出ServiceAccount服务账号一条线:天天头条
看图,如下:
左下角的Pod需要访问k8s的资源,需要通过中间 apiserver 的认证、授权、准入控制 三个东西,这就需要一个serviceAccount,帮助它完成这个过程,才能访问k8s的资源。
(资料图)
一、每个命名空间都会一个有个serviceAccount
serviceAccount的作用是是给集群内pod里面的进程使用,用来访问集群内的资源,所以每个ns都会一个一个名称为default的命名空间,如下:
同时也可以自定义serviceAccount
为什么使用了serviceAccount就可以认证集群,因为每个sa下面都会拥有的一个加密的token,使用 secrets 存储,
这个secrets(加密token)本质上等同于userAccount的认证集群的三种凭证文件:X509客户端证书,静态token文件,静态账号密码文件。
既然这个ns-monitor命名空间下,有这样一个名为default的serviceAccount,我们就来使用一下这个serviceAccount,如下,新建一个Pod使用这个serviceAccount:
查看一下正在运行的 kind: daemonSet 资源 node-exporter,但是没有找到对serviceAccount的引用,因为任何拉取镜像的运行资源 (pod replicaset deployment statefulset deamonset job/cronjob) ,对于serviceAccount(serviceAccount类型的secrets)的引用,都是在底层的Pod里面的,所以要看pod,如下:
查看daemonset底层运行的pod,找到了对于serviceAccount类型type的secrets的引用,如下:至此,这个名为default的serviceAccount就被pod使用了,这个pod使用了这个serviceAccount(其实是加载了这个serviceAccount关联的secrets)之后,就可以访问k8s集群内的资源。
那么,为什么pod启动通过volume加载了type类型为serviceAccount的secrets之后,就可以访问到k8s里面资源呢?我们看一下这个secrets到底存储的哪些数据data (secrets类似一个加密的configmap,可以简单理解为配置文件,里面存储了数据)
一个 secrets (type:serviceAccount) 里面包含的data是:加密的ca.crt、加密的namespace、加密的token,如下:
二、Secret三种typeKubernetes提供了Secret来处理敏感信息,目前Secret的类型有3种,通过type属性指定:Opaque(default): 任意字符串,使用base64编码存储信息,可以通过base64 --decode解码获得原始数据,因此安全性弱。kubernetes.io/service-account-token: 作用于ServiceAccount,就是上面说的。kubernetes.io/dockercfg: 作用于Docker registry,用户下载docker镜像认证使用。
type类型 | 创建secret的方式 | 使用这个secret的方式 |
---|---|---|
Opaque(default) | kubectl 命令手动创建 | 拉取镜像的Pod yaml文件中,volume文件挂盘或者env使用 |
kubernetes.io/service-account-token | 新建命名空间会自动新建一个默认的serviceAccount,这个serviceAccount里面会自动新建一个type为serviceAccount的secret;kubectl 命令手动创建,自定义的serviceAccount被创建起来,会自动新建一个type为serviceAccount的secret | 运行的Pod通过volume文件挂盘使用这个type为serviceAccount的secret |
kubernetes.io/dockercfg | kubectl 命令手动创建 | 所有需要拉取镜像的场景/kind类型,可以是Pod,也可以是replicasets deployment statefulset daemonset job/cronjob,yaml文件中被imagePullSecrets属性使用,用来拉取镜像的账号密码 |
2.1.1 Secret创建的两种方式创建方式1:从文件中创建SecretOpaque类型的Secret的value为base64位编码后的值
echo -n "admin" > ./username.txtecho -n "1f2d1e2e67df" > ./password.txt
kubectl create secret generic db-user-pass --from-file=./username.txt --from-file=./password.txt
kubectl get secret
演示如下:
创建方式2:使用yaml文件创建Secret(1)对数据进行64位编码
echo -n "admin" | base64echo -n "1f2d1e2e67df" | base64
(2)定义mysecret.yaml文件
apiVersion: v1kind: Secretmetadata: name: mysecrettype: Opaquedata: username: YWRtaW4= password: MWYyZDFlMmU2N2Rm
(3)根据yaml文件创建资源并查看
kubectl create -f ./secret.yamlkubectl get secretkubectl get secret mysecret -o yaml
演示如下:
2.1.2 Secret使用的两种方式以Volume方式
以环境变量方式
使用方式1:以Volume方式使用Secretkubectl apply -f mypod.yaml
apiVersion: v1kind: Podmetadata: name: mypodspec: containers: - name: mypod image: redis volumeMounts: - name: foo mountPath: "/etc/foo" readOnly: true volumes: - name: foo secret: secretName: mysecret
kubectl exec -it pod-name bash ## 进去ls /etc/foocat /etc/foo/usernamecat /etc/foo/password
以Volume方式使用Secret,演示如下:
使用方式2:将Secret设置为环境变量kubectl get secret mysecret -o yamlvi secret-env-pod.yamlkubectl apply -f secret-env-pod.yamlkubectl get pod kubectl exec -it 具体pod名称 bash
apiVersion: v1kind: Podmetadata: name: secret-env-podspec: containers: - name: mycontainer image: redis env: - name: SECRET_USERNAME valueFrom: secretKeyRef: name: mysecret key: username - name: SECRET_PASSWORD valueFrom: secretKeyRef: name: mysecret key: password restartPolicy: Never
演示如下:
小结:secret两种方式被创建,创建完之后都可以被pod里面的container去使用
使用的方式:环境变量(container下面的env)、参数(container下面的args)、volume目录挂载(container下面的volume)
2.2 kubernetes.io/service-account-token一般来说,k8s资源有不同的kind。configmap secret user usergroup serviceAccount 不需要运行具体的程序,所以不需要 image: 属性拉取镜像pod replicasets deployment statefulset daemonset job/cronjob 需要运行具体的程序,所以需要 image: 属性拉取镜像
2.3 kubernetes.io/dockercfg另外,从来没有一种kind: UserAccount类型的资源
在需要安全验证的环境中拉取镜像的时候,需要通过用户名和密码。
apiVersion: v1kind: Secretmetadata: name: myregistrykey namespace: awesomeappsdata: .dockerconfigjson: UmVhbGx5IHJlYWxseSByZWVlZWVlZWVlZWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGx5eXl5eXl5eXl5eXl5eXl5eXl5eSBsbGxsbGxsbGxsbGxsbG9vb29vb29vb29vb29vb29vb29vb29vb29vb25ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubmdnZ2dnZ2dnZ2dnZ2dnZ2dnZ2cgYXV0aCBrZXlzCg==type: kubernetes.io/dockerconfigjson
或者直接通过命令创建
kubectl create secret docker-registry myregistrykey \ --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER \ --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL
接下来拉取镜像的时候,就可以使用了
apiVersion: v1kind: Podmetadata: name: foo namespace: awesomeappsspec: containers: - name: foo image: janedoe/awesomeapp:v1 imagePullSecrets: - name: myregistrykey
其实本质上还是kubelet把这个认证放到了docker的目录下面,如下:
cat ~/.docker/config.json { "auths": { "10.39.0.118": { "auth": "Y2hlbm1vOmNtMTM4MTE2NjY3ODY=" }, "10.39.0.12:5000": { "auth": "dXNlcjAxOjEyMzQ1YQ==" }, "http://10.39.0.12:5000": { "auth": "dXNlcjAxOjEyMzQ1YQ==" } }}三、自定义ServiceAccount再分析一遍3.1 Service Account创建
#查看serviceaccount资源[root@k8s-master ~]# kubectl get sa NAME SECRETS AGEdefault 1 7d19h#创建一个名为admin的serviceaccount资源[root@k8s-master ~]# kubectl create serviceaccount admin serviceaccount/admin created#查看serviceaccount资源[root@k8s-master ~]# kubectl get sa NAME SECRETS AGEadmin 1 7sdefault 1 7d19h#查看serviceaccount资源admin的详细信息,可以看出已经自动生成了一个Tokens:admin-token-lc826[root@k8s-master ~]# kubectl describe sa/admin Name: adminNamespace: defaultLabels:3.2 在Pod中使用自定义的service accountAnnotations: Image pull secrets: Mountable secrets: admin-token-lc826Tokens: admin-token-lc826Events: #查看secret,可以查看也生成了一个admin-token-lc826的secret资源[root@k8s-master ~]# kubectl get secret NAME TYPE DATA AGEadmin-token-lc826 kubernetes.io/service-account-token 3 50s......
每个Pod对象均可附加其所属名称空间中的一个Service Account资源,且只能附加一个。不过,一个Service Account资源可由所属名称空间中的多个Pod对象共享使用。创建Pod时,通过“spec.serviceAccountName”进行定义。示例如下:
[root@k8s-master manfests]# vim pod-sa-demo.yaml #编辑资源清单文件apiVersion: v1kind: Podmetadata: name: pod-sa-demo namespace: default labels: app: myapp tier: frontendspec: containers: - name: myapp image: ikubernetes/myapp:v1 ports: - name: http containerPort: 80 serviceAccountName: admin #指定serviceAccount资源名称 [root@k8s-master manfests]# kubectl apply -f pod-sa-demo.yaml pod/pod-sa-demo created[root@k8s-master manfests]# kubectl get pods -l app=myappNAME READY STATUS RESTARTS AGEpod-sa-demo 1/1 Running 0 9s[root@k8s-master manfests]# [root@k8s-master manfests]# kubectl describe pods/pod-sa-demoName: pod-sa-demoNamespace: default......Volumes: admin-token-lc826: Type: Secret (a volume populated by a Secret) SecretName: admin-token-lc826 #这里可以看出挂载token就是上面创建的sa所生成的那个 Optional: false......总结
总结一下,梳理出ServiceAccount服务账号一条线,kind: serviceAccount 作为k8s集群内的一类资源,每个命名空间都会一个名为default的默认的serviceAccount,默认不指定的情况下,这个命名空间下所有的pod都是使用名为default的默认的serviceAccount,这个serviceAccount是通过secrets存储的,这个secrets等效加密的configmap,就是配置文件一类东西,type是serviceAccount,包含的data是:加密的namespace、加密的ca.crt、加密的token,有了这些data,这个命名空间下的Pod在启动的时候通过volume挂盘的方式,将secrets加载到整个Pod里面,Pod的进程就可以访问k8s集群内的资源了。
然后,这种用在serviceAccount上的secrets只是一种类型type的secrets,secrets还有两种其他类型type的,普通字符串和imagePullSecrets,顺便一起学习了。
最后,还可以自定义ServiceAccount,再重新分析一遍,加深理解。
这里面有一个难以搞清的概念,那就是对于一一对应关系的serviceAccount和secrets,其实不用分的这么清楚,serviceAccount是一个账号,secrets是这个账号里面存储的数据,然后一一绑定在一起,甚至简单点理解,两个东西作为一个整体,任何是一个东西都可以(因为很难分开)。
相关阅读
-
世界热推荐:今晚7:00直播丨下一个突破...
今晚19:00,Cocos视频号直播马上点击【预约】啦↓↓↓在运营了三年... -
NFT周刊|Magic Eden宣布支持Polygon网...
Block-986在NFT这样的市场,每周都会有相当多项目起起伏伏。在过去... -
环球今亮点!头条观察 | DeFi的兴衰与...
在比特币得到机构关注之后,许多财务专家预测世界将因为加密货币的... -
重新审视合作,体育Crypto的可靠关系才能双赢
Block-987即使在体育Crypto领域,人们的目光仍然集中在FTX上。随着... -
简讯:前端单元测试,更进一步
前端测试@2022如果从2014年Jest的第一个版本发布开始计算,前端开发... -
焦点热讯:刘强东这波操作秀
近日,刘强东发布京东全员信,信中提到:自2023年1月1日起,逐步为...