写点什么

关于 K8s 中 Service Account 的一些笔记:Pod 内部如何访问 K8s 集群

作者:山河已无恙
  • 2022 年 4 月 28 日
  • 本文字数:11665 字

    阅读完需:约 38 分钟

写在前面

「 真正的坚持归于平静,靠的是温和的发力,而不是时时刻刻的刺激。」


学习环境

┌──[root@vms81.liruilongs.github.io]-[~]└─$kubectl get nodesNAME                         STATUS     ROLES                  AGE    VERSIONvms81.liruilongs.github.io   Ready      control-plane,master   134d   v1.22.2vms82.liruilongs.github.io   Ready      <none>                 134d   v1.22.2vms83.liruilongs.github.io   NotReady   <none>                 134d   v1.22.2┌──[root@vms81.liruilongs.github.io]-[~]└─$
复制代码

Service Account 是什么?

学习Service Account之前,我们简单介绍下 K8s 的安全体系,K8s 中通过一系列机制来实现集群的安全控制,其中包括API Server的认证和授(鉴)权,关于认证授(鉴)权,感兴趣小伙伴可以看看之前的博文,我们这里简单介绍下

「关于授(鉴)权,现在用的比较多的是RBAC(Role-Based Access Control,基于角色的访问控制)的方式」

RBACKubernetes的1.5版本中引入,在1.6版本时升级为Beta版本,在1.8版本时升级为GA。现在作为kubeadm安装方式的默认选项,相对于其他访问控制方式,RBAC 对集群中的资源和非资源权限均有完整的覆盖。整个 RBAC 完全由(Role,ClusterRole,RoleBinding,ClusterRoleBinding)API 对象完成,同其他 API 对象一样,可以用 kubectl 或 API 进行操作。可以在运行时进行调整,无须重新启动 API Server。

K8s 的授权策略设置通过通过API Server的启动参数"--authorization-mode"设置。 除了 RBAC 外,授权策略还包括:

「关于认证机制,在 K8s 的认证中,如果按照集群内外认证分的话,分为集群外认证和集群内认证:」

集群外认证一般三种,也可以理解为通过kubectl或者编程语言编写的客户端 API 访问:

  • HTTP Token认证:通过一个Token来识别合法用户。

  • HTTPS 证书认证:基于 CA 根证书签名的双向数字证书认证方式(Kubeconfig 文件)

  • HTTP Base认证:通过用户名+密码的方式认证(用户账户),这个只有1.19之前的版本适用,之后的版本不在支持

集群内的认证也就是我们今天要讲的:Service Account对象,也叫服务账户

所以说Service Account它并不是给Kubernetes集群的用户(系统管理员、运维人员)用的,而是给运行在 K8s 上的 Pod 里的进程用的,为 Pod 里的进程提供认证。

比如我们要编写一个类似kubectl一样的K8s的管理工具,比如一些面板工具(kubernetes-dashboard),而且这个工具是运行在我们的 K8s 环境里的,那么这个时候,我们如何给这个工具访问集群做认证授权,就要用到Service Account,简写为sa,所以我们一般直接叫sa

当我们创建任何一个 Pod 的时候,必须要有 sa,否则创建失败,如果没有显示的指定对应的sa,即服务账户,Pod 会默认使用当前的命令空间的 default 服务账户(每个命名空间都有一个名为 default 的 sa 资源。)

这里要说明的是每个sa服务账户都会生成一个secret,这个secret里面包含一个token凭证。所以说sa实际认证是通过token实现的认证。(token)

┌──[root@vms81.liruilongs.github.io]-[~]└─$kubectl get sa defaultNAME      SECRETS   AGEdefault   1         67d┌──[root@vms81.liruilongs.github.io]-[~]└─$kubectl run podcommon --image=nginx --image-pull-policy=IfNotPresent --labels="name=liruilong" --env="name=liruilong"pod/podcommon created┌──[root@vms81.liruilongs.github.io]-[~]└─$kubectl get pods podcommon  -o yaml | grep serviceAccount  serviceAccount: default  serviceAccountName: default      - serviceAccountToken:┌──[root@vms81.liruilongs.github.io]-[~]└─$
复制代码

可以使用自动挂载给Poddefault服务账户 token 访问 API,但是前提是需要给 default 授权,对于 RBAC 的方式来讲,需要给角色授权,然后绑定角色。

在 1.6 以上版本中,可以通过在 sa 上设置automountServiceAccountToken: false来实现不给服务账号自动挂载 API token

apiVersion: v1kind: ServiceAccountmetadata:  name: build-robotautomountServiceAccountToken: false...
复制代码

在 1.6 以上版本中,你也可以选择不给特定 Pod 自动挂载 API token

apiVersion: v1kind: Podmetadata:  name: my-podspec:  serviceAccountName: build-robot  automountServiceAccountToken: false  ...
复制代码

如果 Pod 和服务账户都指定了automountServiceAccountToken值,则 Pod 的 spec 优先于服务帐户。

下面看一下kubernetes-dashboardsa的应用,下面是一个已经部署好的dashboard

关于kubernetes-dashboard是 K8s 官网提供的 Kubernetes 的 Web UI 网页管理工具,可提供部署应用、资源对象管理、容器日志查询、系统监控等常用的集群管理功能。

┌──[root@vms81.liruilongs.github.io]-[~]└─$kubectl get pods -o wideNAME                                         READY   STATUS    RESTARTS        AGE   IP             NODE         NOMINATED NODE   READINESS GATESdashboard-metrics-scraper-669c88c9d9-2qp62   1/1     Running   8 (7d11h ago)   61d   10.244.88.83   vms81.liruilongs.github.io   <none>           <none>kubernetes-dashboard-5d66bcd8fd-l22jm        1/1     Running   13 (7d3h ago)   61d   10.244.88.80   vms81.liruilongs.github.io   <none>           <none>┌──[root@vms81.liruilongs.github.io]-[~]└─$┌──[root@vms81.liruilongs.github.io]-[~]└─$kubectl get svc  -n kubernetes-dashboardNAME                        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)         AGEdashboard-metrics-scraper   ClusterIP   10.109.92.159   <none>        8000/TCP        67dkubernetes-dashboard        NodePort    10.106.48.37    <none>        443:32360/TCP   67d┌──[root@vms81.liruilongs.github.io]-[~]└─$
复制代码

上面是一个我们之前部署好的面板工具,在部署的过程中,我们要主动创建一个 sa(kubernetes-dashboard),并且为这个 sa 授权,而后,我们的这个面板工具才具有管理 K8s 集群的能力

创建sa的资源文件

apiVersion: v1kind: ServiceAccountmetadata:  labels:    k8s-app: kubernetes-dashboard  name: kubernetes-dashboard  namespace: kubernetes-dashboard
复制代码

查看kubernetes-dashboard sa,可以看到对应的 token

┌──[root@vms81.liruilongs.github.io]-[~]└─$kubectl get saNAME                   SECRETS   AGE......kubernetes-dashboard   1         67d┌──[root@vms81.liruilongs.github.io]-[~]└─$kubectl get secretsNAME                               TYPE                                  DATA   AGE.........kubernetes-dashboard-token-wnqqg   kubernetes.io/service-account-token   3      67d┌──[root@vms81.liruilongs.github.io]-[~]└─$kubectl describe  secrets kubernetes-dashboard-token-wnqqgName:         kubernetes-dashboard-token-wnqqgNamespace:    kubernetes-dashboardLabels:       <none>Annotations:  kubernetes.io/service-account.name: kubernetes-dashboard              kubernetes.io/service-account.uid: 8e209de5-14a0-4dd5-bd19-2264170531f5
Type:  kubernetes.io/service-account-token
Data====token:      eyJhbGciOiJSUzI1NiIsImtpZCI6ImF2MmJVZ3d6M21JRC1BZUwwaHlDdzZHSGNyaVJON1BkUHF6MlhPV2NfX00ifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJrdW....ca.crt:     1099 bytesnamespace:  20 bytes┌──[root@vms81.liruilongs.github.io]-[~]└─$
复制代码

然后对sa授权,一般通过 RBAC 的方式.创建角色

kind: ClusterRoleapiVersion: rbac.authorization.k8s.io/v1metadata:  labels:    k8s-app: kubernetes-dashboard  name: kubernetes-dashboardrules:  # Allow Metrics Scraper to get metrics from the Metrics server  - apiGroups: ["metrics.k8s.io"]    resources: ["pods", "nodes"]    verbs: ["get", "list", "watch"]
复制代码

然后绑定角色到 sa

apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata:  name: kubernetes-dashboardroleRef:  apiGroup: rbac.authorization.k8s.io  kind: ClusterRole  name: kubernetes-dashboardsubjects:  - kind: ServiceAccount      name: kubernetes-dashboard    namespace: kubernetes-dashboard

复制代码

然后pod通过serviceAccountserviceAccountName来绑定sa,当然这两个参数指定一个就可以了。

┌──[root@vms81.liruilongs.github.io]-[~]└─$kubectl get  pod kubernetes-dashboard-5d66bcd8fd-l22jm -o yaml | grep -C 5  serviceAccount  preemptionPolicy: PreemptLowerPriority  priority: 0  restartPolicy: Always  schedulerName: default-scheduler  securityContext: {}  serviceAccount: kubernetes-dashboard  serviceAccountName: kubernetes-dashboard  terminationGracePeriodSeconds: 30
复制代码

通过 yaml 文件我们可以看到,值 sa 为kubernetes-dashboard,当然在资源文件中,是在DeploymentServcie中指定,

如果saautomountServiceAccountTokenPodautomountServiceAccountToken都未显式设置为 false,那么会为对应的 Pod 创建一个volume,在其中包含用来访问 API 的令牌。

如果为 sa 对应的 token 创建了卷,则为 Pod 中的每个容器添加一个volumeSource,挂载在其/var/run/secrets/kubernetes.io/serviceaccount 目录下。

┌──[root@vms81.liruilongs.github.io]-[~]└─$kubectl get  pod kubernetes-dashboard-5d66bcd8fd-l22jm -o yaml | grep -C 20 -i  serviceAccount...........    volumeMounts:...........    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount      name: kube-api-access-8jlj7      readOnly: true.........  serviceAccount: kubernetes-dashboard  serviceAccountName: kubernetes-dashboard.........  volumes:..........  - name: kube-api-access-8jlj7    projected:      defaultMode: 420      sources:      - serviceAccountToken:          expirationSeconds: 3607          path: token........┌──[root@vms81.liruilongs.github.io]-[~]└─$
复制代码

通过配置文件可以看到,token 通过卷的方式挂载到了容器里的/var/run/secrets/kubernetes.io/serviceaccount 目录,但是需要注意的是,这个 token 和 sa 对应的 token 在 1.20 版本之后进行了处理,不一样,在之前的版本中是一样的。

Service Account Demo

创建一个 sa

┌──[root@vms81.liruilongs.github.io]-[~]└─$kubectl create sa  sa-demoserviceaccount/sa-demo created
复制代码

查看对应的 secret 和 token

┌──[root@vms81.liruilongs.github.io]-[~]└─$kubectl get secrets sa-demo-token-pdrs8NAME                  TYPE                                  DATA   AGEsa-demo-token-pdrs8   kubernetes.io/service-account-token   3      43s┌──[root@vms81.liruilongs.github.io]-[~]└─$kubectl describe secrets sa-demo-token-pdrs8Name:         sa-demo-token-pdrs8Namespace:    kubernetes-dashboardLabels:       <none>Annotations:  kubernetes.io/service-account.name: sa-demo              kubernetes.io/service-account.uid: 7003de88-803a-4dae-a6e3-d647d0517c92
Type:  kubernetes.io/service-account-token
Data====ca.crt:     1099 bytesnamespace:  20 bytestoken:      eyJhbGciOiJSUzI1NiIsImtpZCI6ImF2MmJVZ3d6M21JRC1BZUwwaHlDdzZHSGNyaVJON1BkUHF6MlhPV2NfX00ifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJzYS1kZW1vLXRva2VuLXBkcnM4Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6InNhLWRlbW8iLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiI3MDAzZGU4OC04MDNhLTRkYWUtYTZlMy1kNjQ3ZDA1MTdjOTIiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZXJuZXRlcy1kYXNoYm9hcmQ6c2EtZGVtbyJ9.sVAmtpfqFREjUCd9bkQvMuHpasXOcKYLJvVsJLLe6ufP4zs8ZVt6HqH4ylsxbmwtibNXBV9hVNEU_2X3T2enOjOSYuiyaEP4BifDQN7DmZbu2uXQCBglixaNB7ZIIPX_oQsW0ndBNonVqMSMm-ZItYDzLo-QTOxTxc5OQZ3zSBJqITAvWFlshWA7mKntNmWw6m5KunjhYZs14Lpa-NhknYS9G6ur8SKY4XdE44hzQhD7h4y01ZezZGR3IdGd3HktA5dWYTRXXr9H00odey2YtGfj40Vql3rMrdMPJOFbAozjyaWxhmSpjHVGcbXawai8znKPCdGlW4l2aRmbghovsw┌──[root@vms81.liruilongs.github.io]-[~]└─$
复制代码

编写 pod 资源文件,指定 sa 为刚才创建的 sa

┌──[root@vms81.liruilongs.github.io]-[~]└─$kubectl run pod-sa --image=nginx --image-pull-policy=IfNotPresent --dry-run=client  -o yaml > pod-sa.yaml┌──[root@vms81.liruilongs.github.io]-[~]└─$vim pod-sa.yaml┌──[root@vms81.liruilongs.github.io]-[~]└─$cat pod-sa.yamlapiVersion: v1kind: Podmetadata:  creationTimestamp: null  labels:    run: pod-demo  name: pod-demospec:  serviceAccount: sa-demo  containers:  - image: nginx    imagePullPolicy: IfNotPresent    name: pod-demo    resources: {}  dnsPolicy: ClusterFirst  restartPolicy: Alwaysstatus: {}┌──[root@vms81.liruilongs.github.io]-[~]└─$
复制代码

查看创建的 pod

┌──[root@vms81.liruilongs.github.io]-[~]└─$kubectl apply -f pod-sa.yamlpod/pod-demo created┌──[root@vms81.liruilongs.github.io]-[~]└─$kubectl get pods pod-demoNAME       READY   STATUS    RESTARTS   AGEpod-demo   1/1     Running   0          95s┌──[root@vms81.liruilongs.github.io]-[~]└─$
复制代码

对于 deplay 的 sa 修改可以直接通过 set 的方式设置,时间关系这里不多讲啦,文末的资源文件中有 demo

下面我们来看一道Service Account相关习题,这是某一期 CKA 认证的一道考题

创建一个名为 deployment-clusterrole 且仅允许创建以下资源类型的新 ClusterRole:

  • Deployment

  • StatefulSet

  • DaemonSet 在现有的 namespace app-team 中创建一个名为 cicd-token 的新 ServiceAccount。限于 namespace app-team 中,将新的 ClusterRole deployment-clusterrole 绑定到新的 ServiceAccount cicd-token。

题目很简单,一般的生产我们也会涉及,指定权限创建一个集群角色,然后把这个集群角色绑定到一个新建的 sa 上。

# 创建集群角色kubectl create clusterrole deployment-clusterrole --verb=create --resource=deployments,statefulsets,daemonsets# 创建服务账户kubectl -n app-team create serviceaccount cicd-token# 绑定角色到服务账户kubectl -n app-team create rolebinding cicd-token-rolebinding --clusterrole=deployment-clusterrole --serviceaccount=app-team1:cicd-token
复制代码

对应 sa 学习,感觉 kubernetes-dashboard 的是一个很好的 Demo。这里把面板的资源文件贴出来,感兴趣小伙伴可以研究下

# Copyright 2017 The Kubernetes Authors.## Licensed under the Apache License, Version 2.0 (the "License");# you may not use this file except in compliance with the License.# You may obtain a copy of the License at##     http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an "AS IS" BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License.
apiVersion: v1kind: Namespacemetadata:  name: kubernetes-dashboard
---
apiVersion: v1kind: ServiceAccountmetadata:  labels:    k8s-app: kubernetes-dashboard  name: kubernetes-dashboard  namespace: kubernetes-dashboard
---
kind: ServiceapiVersion: v1metadata:  labels:    k8s-app: kubernetes-dashboard  name: kubernetes-dashboard  namespace: kubernetes-dashboardspec:  ports:    - port: 443      targetPort: 8443  selector:    k8s-app: kubernetes-dashboard
---
apiVersion: v1kind: Secretmetadata:  labels:    k8s-app: kubernetes-dashboard  name: kubernetes-dashboard-certs  namespace: kubernetes-dashboardtype: Opaque
---
apiVersion: v1kind: Secretmetadata:  labels:    k8s-app: kubernetes-dashboard  name: kubernetes-dashboard-csrf  namespace: kubernetes-dashboardtype: Opaquedata:  csrf: ""
---
apiVersion: v1kind: Secretmetadata:  labels:    k8s-app: kubernetes-dashboard  name: kubernetes-dashboard-key-holder  namespace: kubernetes-dashboardtype: Opaque
---
kind: ConfigMapapiVersion: v1metadata:  labels:    k8s-app: kubernetes-dashboard  name: kubernetes-dashboard-settings  namespace: kubernetes-dashboard
---
kind: RoleapiVersion: rbac.authorization.k8s.io/v1metadata:  labels:    k8s-app: kubernetes-dashboard  name: kubernetes-dashboard  namespace: kubernetes-dashboardrules:  # Allow Dashboard to get, update and delete Dashboard exclusive secrets.  - apiGroups: [""]    resources: ["secrets"]    resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs", "kubernetes-dashboard-csrf"]    verbs: ["get", "update", "delete"]    # Allow Dashboard to get and update 'kubernetes-dashboard-settings' config map.  - apiGroups: [""]    resources: ["configmaps"]    resourceNames: ["kubernetes-dashboard-settings"]    verbs: ["get", "update"]    # Allow Dashboard to get metrics.  - apiGroups: [""]    resources: ["services"]    resourceNames: ["heapster", "dashboard-metrics-scraper"]    verbs: ["proxy"]  - apiGroups: [""]    resources: ["services/proxy"]    resourceNames: ["heapster", "http:heapster:", "https:heapster:", "dashboard-metrics-scraper", "http:dashboard-metrics-scraper"]    verbs: ["get"]
---
kind: ClusterRoleapiVersion: rbac.authorization.k8s.io/v1metadata:  labels:    k8s-app: kubernetes-dashboard  name: kubernetes-dashboardrules:  # Allow Metrics Scraper to get metrics from the Metrics server  - apiGroups: ["metrics.k8s.io"]    resources: ["pods", "nodes"]    verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1kind: RoleBindingmetadata:  labels:    k8s-app: kubernetes-dashboard  name: kubernetes-dashboard  namespace: kubernetes-dashboardroleRef:  apiGroup: rbac.authorization.k8s.io  kind: Role  name: kubernetes-dashboardsubjects:  - kind: ServiceAccount    name: kubernetes-dashboard    namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata:  name: kubernetes-dashboardroleRef:  apiGroup: rbac.authorization.k8s.io  kind: ClusterRole  name: kubernetes-dashboardsubjects:  - kind: ServiceAccount    name: kubernetes-dashboard    namespace: kubernetes-dashboard
---
kind: DeploymentapiVersion: apps/v1metadata:  labels:    k8s-app: kubernetes-dashboard  name: kubernetes-dashboard  namespace: kubernetes-dashboardspec:  replicas: 1  revisionHistoryLimit: 10  selector:    matchLabels:      k8s-app: kubernetes-dashboard  template:    metadata:      labels:        k8s-app: kubernetes-dashboard    spec:      containers:        - name: kubernetes-dashboard          #image: kubernetesui/dashboard:v2.0.0-beta8          image: registry.cn-hangzhou.aliyuncs.com/kube-iamges/dashboard:v2.0.0-beta8          #imagePullPolicy: Always          imagePullPolicy: IfNotPresent          ports:            - containerPort: 8443              protocol: TCP          args:            - --auto-generate-certificates            - --namespace=kubernetes-dashboard            # Uncomment the following line to manually specify Kubernetes API server Host            # If not specified, Dashboard will attempt to auto discover the API server and connect            # to it. Uncomment only if the default does not work.            # - --apiserver-host=http://my-address:port          volumeMounts:            - name: kubernetes-dashboard-certs              mountPath: /certs              # Create on-disk volume to store exec logs            - mountPath: /tmp              name: tmp-volume          livenessProbe:            httpGet:              scheme: HTTPS              path: /              port: 8443            initialDelaySeconds: 30            timeoutSeconds: 30          securityContext:            allowPrivilegeEscalation: false            readOnlyRootFilesystem: true            runAsUser: 1001            runAsGroup: 2001      volumes:        - name: kubernetes-dashboard-certs          secret:            secretName: kubernetes-dashboard-certs        - name: tmp-volume          emptyDir: {}      serviceAccountName: kubernetes-dashboard      nodeSelector:        "kubernetes.io/os": linux      # Comment the following tolerations if Dashboard must not be deployed on master      tolerations:        - key: node-role.kubernetes.io/master          effect: NoSchedule
---
kind: ServiceapiVersion: v1metadata:  labels:    k8s-app: dashboard-metrics-scraper  name: dashboard-metrics-scraper  namespace: kubernetes-dashboardspec:  ports:    - port: 8000      targetPort: 8000  selector:    k8s-app: dashboard-metrics-scraper
---
kind: DeploymentapiVersion: apps/v1metadata:  labels:    k8s-app: dashboard-metrics-scraper  name: dashboard-metrics-scraper  namespace: kubernetes-dashboardspec:  replicas: 1  revisionHistoryLimit: 10  selector:    matchLabels:      k8s-app: dashboard-metrics-scraper  template:    metadata:      labels:        k8s-app: dashboard-metrics-scraper      annotations:        seccompProfile: 'runtime/default'    spec:      containers:        - name: dashboard-metrics-scraper          #image: kubernetesui/metrics-scraper:v1.0.1          image: registry.cn-hangzhou.aliyuncs.com/kube-iamges/metrics-scraper:v1.0.1          imagePullPolicy: IfNotPresent          ports:            - containerPort: 8000              protocol: TCP          livenessProbe:            httpGet:              scheme: HTTP              path: /              port: 8000            initialDelaySeconds: 30            timeoutSeconds: 30          volumeMounts:          - mountPath: /tmp            name: tmp-volume          securityContext:            allowPrivilegeEscalation: false            readOnlyRootFilesystem: true            runAsUser: 1001            runAsGroup: 2001      serviceAccountName: kubernetes-dashboard      nodeSelector:        "kubernetes.io/os": linux      # Comment the following tolerations if Dashboard must not be deployed on master      tolerations:        - key: node-role.kubernetes.io/master          effect: NoSchedule      volumes:        - name: tmp-volume          emptyDir: {}
复制代码


发布于: 刚刚阅读数: 4
用户头像

CSDN博客专家,华为云云享专家,RHCE/CKA认证 2022.01.04 加入

Java 后端一枚,技术不高,前端、Shell、Python 也可以写一点.纯种屌丝,不热爱生活,热爱学习,热爱工作,喜欢一直忙,不闲着。喜欢篆刻,喜欢吃好吃的,喜欢吃饱了晒太阳。

评论

发布
暂无评论
关于K8s中Service Account的一些笔记:Pod内部如何访问K8s集群_k8s_山河已无恙_InfoQ写作社区