kubernetes集群中账户分为两类,Kubernetes管理的serviceaccount(服务账户)和useraccount(用户账户)。
k8s创建两套独立的账号系统,原因如下:
(1)面向的对象不同。useraccount给用户用,我们使用kubectl时用的就是userAccount。
Service Account是给Pod里的进程使用的。Pod容器的进程需要访问API Server时用的就是ServiceAccount账户
(2)useraccount是全局性的,在集群所有namespaces中,名称具有唯一性。用户名称可以在kubeconfig中查看。
Service Account则属于某个具体的Namespace
(3)useraccount是与后端的用户数据库同步的,创建一个新用户通常要走一套复杂的业务流程才能实现,Service Account的创建则需要极轻量级的实现方式,集群管理员可以很容易地为某些特定任务创建一个Service Account
(4)对于一个复杂的系统来说,多个组件通常拥有各种账号的配置信息,Service Account是Namespace隔离的,可以针对组件进行一对一的定义,同时具备很好的“便携性”
我这里是kubernetes-admin(主节点)
[root@master ~]# cat ~/.kube/config apiVersion: v1 clusters: - cluster: certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN5RENDQWJDZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJek1EZ3lOVEV3TURNd01Gb1hEVE16TURneU1qRXdNRE13TUZvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTU94ClFQMVo0dHk3SGZiNVFHRDkrbDZXZUU4RXBSREVqL2MzNWdKWGtlbjlXRCtNbXVuMVhoUStEYXUzMjMvVVNJOVIKQlEvYU5FT3FYdlFDS1JYTUFBYWRSVFMwd0kwNDJVV1RPR0pFV0dOY1hWdjdFa21KaTAxRmd5dy9nYlI5eCttOApQMTNJdStkYjdtZmxjZ2lXb0c4eG9GblVmQTMyeWdWTzBBTy9WaEtPd3h4QTNybndWWVlTdkdWckR4YTZ3WUtQCjYyNTE4VTRiSStmYU9SMUNpbDcyekZpR3FEZ0F3eW1tNlR4LzNKVm05aG40cjFROVBkeDl3c3lOclZLMmw4RTcKL0xDODNMWk5nRGhvNEVvcE5uUi9NK2ZmbHJmRDNsbzZzOWNKZXNPamQ1U1lEWWtTb3g5K0lVU0o2SitIdkdXeQpiaGxlL1licCswK3hOM1JkVnNFQ0F3RUFBYU1qTUNFd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFJeW9IdU9rN3hXL0xkSnhoYVJjc3lDRW1DVXkKOUZGbys1K1JEQkpLanlzK0dnc3FmSHh0dUJkYlJhSlA5SGFGVFBpT24wenNBbXJMK291VjNJODNBcVdYYnVqbwo1b2JFUEwvNTl3K04vT1FIS2RmcmJ0UHJLWDB6SDU2R3htc3cramUvNEdXWEZpcDJKbWRYV0tGelNZenN3UmFQCnRRNE1LeUVHQjdSdlB1bnJkeStscjdIbXRTRGFRTE51czBzTlptSGhvZGNtbXUzQjZKZ2k1Wmd0RDBXVjNhYUQKc1UxaGFveC82V000aGJhYlU0Q0hJNGpkOVR5ZXVlRkRrcTFaK1E5TGppdTFnK3NGc3hTT0h4OXMxdDlLSGRmWAp4b0dFditIV09tNGdkNEN1UVljWC9RQkg1L2czM2NBckNQNXlVZjJHNlpBV1YycjRqeGF1ejNUTGFPMD0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= server: https://192.168.174.139:6443 name: kubernetes contexts:
Service Account
Controller Manager创建了ServiceAccount Controller和Token Controller这两个安全相关的控制器。其中ServiceAccount Controller一直监听Service Account和Namespace的事件,
每个Namespace下都有一个名为default的默认的 Service Account对象
如果在一个Namespace中没有default Service Account,那么Service Account会给Namespace创建一个默认(default)的Service Account。
每创建一个ServiceAccount ,就会对应创建一个secret。
这个secret,会和Service Account里面有一个名为Tokens的字段关联,当Pod启动时候,这个Secret会自动Mount到Pod的指定目录下,用来完成Pod中的进程访问API server时的身份认证过程。
[root@node1 nginx]# kubectl get sa,secret NAME SECRETS AGE serviceaccount/default 1 11d serviceaccount/mydemo 1 24m serviceaccount/mytest 1 25m NAME TYPE DATA AGE secret/default-token-jdgfp kubernetes.io/service-account-token 3 11d secret/mydemo-token-88szx kubernetes.io/service-account-token 3 24m secret/mytest-token-ddb56 kubernetes.io/service-account-token 3 25m [root@node1 nginx]# kubectl get serviceaccount,secret NAME SECRETS AGE serviceaccount/default 1 11d serviceaccount/mydemo 1 25m serviceaccount/mytest 1 26m NAME TYPE DATA AGE secret/default-token-jdgfp kubernetes.io/service-account-token 3 11d secret/mydemo-token-88szx kubernetes.io/service-account-token 3 25m secret/mytest-token-ddb56 kubernetes.io/service-account-token 3 26m
创建serviceaccount k8s会自动关联secret
[root@node1 nginx]# kubectl get serviceaccount,secret NAME SECRETS AGE serviceaccount/default 1 11d serviceaccount/mydemo 1 25m serviceaccount/mytest 1 26m NAME TYPE DATA AGE secret/default-token-jdgfp kubernetes.io/service-account-token 3 11d secret/mydemo-token-88szx kubernetes.io/service-account-token 3 25m secret/mytest-token-ddb56 kubernetes.io/service-account-token 3 26m [root@node1 nginx]# kubectl create sa demo serviceaccount/demo created [root@node1 nginx]# kubectl describe sa/demo Name: demo Namespace: default Labels: <none> Annotations: <none> Image pull secrets: <none> Mountable secrets: demo-token-97f7p Tokens: demo-token-97f7p Events: <none>
使用serviceAccount
apiVersion: v1 kind: Pod metadata: name: test-sa spec: containers: - name: test-sa image: nginx:1.22.0 imagePullPolicy: IfNotPresent ports: - containerPort: 80 serviceAccountName: mytest
查看使用详情
[root@node1 nginx]# kubectl get pod -A NAMESPACE NAME READY STATUS RESTARTS AGE default test-sa 1/1 Running 0 12m
[root@node1 nginx]# kubectl describe pod test-sa -n default pullable://nginx@sha256:f0d28f2047853cbc10732d6eaa1b57f1f4db9b017679b9fd7966b6a2f9ccc2d1 Port: 80/TCP Host Port: 0/TCP State: Running Started: Wed, 06 Sep 2023 17:33:11 +0800 Ready: True Restart Count: 0 Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from mytest-token-ddb56 (ro) Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: mytest-token-ddb56: Type: Secret (a volume populated by a Secret) SecretName: mytest-token-ddb56 Optional: false QoS Class: BestEffort Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s node.kubernetes.io/unreachable:NoExecute for 300s Events: Type Reason Age From Message ---- ------ ---- ---- -------
有以下几条原则:
(1)如果spec.serviceAccount域没有被设置,则Kubernetes默认为其指定名称为default的Service Account。
(2)如果指定了spec.serviceAccountName并且不是default,但是此Service Account不存在,则该Pod操作失败。
(3)如果在Pod中没有指定ImagePullSecrets,那么这个spec.serviceAccount域指定的Service Account的ImagePullSecrets会自动加入到该Pod中。
(4)会给Pod添加一个特殊的Volume,在该Volume中包含ServiceAccount Secret中的Token,并将Volume挂载到Pod中所有容器的指定目录下(/var/run/secrets/kubernetes.io/serviceaccount)。
接下来就是使用私有镜像了。
此时使用私有仓库就需要配置否则 imagePullSecrets。否则会拉取失败。
此时我们需要创建一个secret,存储harbor的用户名密码。
之后有两种选择
- 在Deployment的yaml使用imagePullSecrets
- 创建一个绑定该secret的serviceAccount,在deployment的yaml中使用这个serviceAccount。或者把这个secret直接patch给default sa。
1.创建secret
kubectl create secret docker-registry harborpaas -n dev --docker-server=harbor.com --docker-username=paas --docker-password=XXXXX --docker-email=xxx@xxx.com
2.创建sa
apiVersion: v1 kind: ServiceAccount metadata: name: harbor-sa namespace: dev secrets: imagePullSecrets: - name: harborpaas
3.deployment使用sa
apiVersion: apps/v1 kind: Deployment metadata: name: test-sa namespace: dev spec: serviceAccountName: harbor-sa
根据这一条,如果在Pod中没有指定ImagePullSecrets,那么这个spec.serviceAccount域指定的Service Account的ImagePullSecrets会自动加入到该Pod中。
所以pod是可以拉取到镜像的。