We can enable multiple authenticators, and the first module to successfully authenticate the request
short-circuits the evaluation.
In order to be successful, you should enable at least two methods: the service account tokens authenticator
and one of the user authenticators.
{
"apiVersion": "abac.authorization.kubernetes.io/v1beta1",
"kind": "Policy",
"spec": {
"user": "student",
"namespace": "lfs158",
"resource": "pods",
"readonly": true
}
}
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: lfs158
name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"]
verbs: ["get", "watch", "list"]
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: pod-read-access
namespace: lfs158
subjects:
- kind: User
name: student
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
$ minikube delete
* Deleting "minikube" in virtualbox ...
* Removed all traces of the "minikube" cluster.
$ ls .minikube
addons ca.crt ca.pem certs client.key files machines proxy-client-ca.key
apiserver.crt ca.crt.encoded cache client.crt client.key.encoded key.pem profiles proxy-client.crt
apiserver.key ca.key cert.pem client.crt.encoded config logs proxy-client-ca.crt proxy-client.key
$ minikube start --extra-config=controller-manager.ClusterSigningCertFile=".minikube/ca.crt" --extra-config=controller-manager.ClusterSigningKeyFile=".minikube/ca.key"
$ kubectl config view
apiVersion: v1
clusters:
- cluster:
certificate-authority: C:\Users\Kone\.minikube\ca.crt
server: https://192.168.99.105:8443
name: minikube
contexts:
- context:
cluster: minikube
user: minikube
name: minikube
current-context: minikube
kind: Config
preferences: {}
users:
- name: minikube
user:
client-certificate: C:\Users\Kone\.minikube\client.crt
client-key: C:\Users\Kone\.minikube\client.key
$ kubectl create namespace lfs158
namespace/lfs158 created
$ mkdir rbac
$ cd rbac
$ openssl genrsa -out student.key 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
......................+++++
...........................................................................................+++++
e is 65537 (0x010001)
$ ls
student.key
$ openssl req -new -key student.key -out student.csr -subj "/CN=student/O=learner"
$ ls
student.csr student.key
$ cat student.csr | base64 | tr -d '\n'
LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ2FUQ0NBVkVDQVFBd0pERVFNQTRHQTFVRUF3d0hjM1IxWkdWdWRERVFNQTRHQTFVRUNnd0hiR1ZoY201bApjakNDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFOby9ac0wvQWZXcWcyNHN1SHpPCjRKL210ckdxMEM2OWpUZ3A4WTJMZ1ZJN1JacnJFQ2tFMjdCa3UxaWh4NktZRkdqRDFVM09qcFdpOWk1OXVtVUwKWE9ydnJvL3ExK0FVbnBaWGFrNi9QZ3QvV0tiaUZxVTZzbUJwTXNhUmdEa1ZPektJQ2pZWUZwWkpSRXVPelg2bAo0OHg2eVpvNmpLUnNISjZvbFA2T2x5ZzNpNUZUdk4xdDFvODVIYk9EY1lVN3ZVY01vaWUvY1BVcmFXeWlIN1BnCkJseWJlWjRGRDFoeEdpa0R0TXo4UXp0dGFNMHRvaWRUUXFoZ3Rid2ZyejZuelZuS1I2M2R2VUt1dWYySFk3K24KU3dVdml6V2M3TGIxdEh5aHF0bGNoWTJrM25WRXFCNUlsdmo4R3B4Y0xjRk4zaGJCc0hFNGE4aDlqMkc3SEhLawp0cWtDQXdFQUFhQUFNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUFvQnRnd2JmTmRlVXR6QTRYemhycEJjQ2tGClJscUUxcjVnK3YwTDMzRVBkUUJoa01RckRnbU9pdEozRGJSRWRPZ1Z5WmhVWkhSS0VEUGoyTWVoVS9sQlptZmwKVUZjYldudlBSb05tKy81V2hjbzFnQzMzbUd3V0VPdStLaUdLSWkrVWNpQm9nS214WFZCTFcvd2FUa3djRnY5agpYWTMzWlFVSUY5S2ErekNETGMzMTgzTjdoMGU5cUNFa3hZd3BVWTJ6ZnF6TlBBU3RjRWZ4RGlVdlJKc3hDVWFyCkdxSkNNN0IzMk0rdlNFNmcvRmxuUzQwTDZWaFRGRm9OUnN2NzgxUVhmYnRESlVLSVFtalZhVWFzNUhBbm9WRE8KemhJa05xK3FoU0dSZ0tMdmhiK1YvZE5XZjU3TDRpU0lGZUdsbE1jYy95d3VLSDVrMGRCTkErMS9ERzJlCi0tLS0tRU5EIENFUlRJRklDQVRFIFJFUVVFU1QtLS0tLQo=
$ vi signing-request.yaml
$ cat signing-request.yaml
apiVersion: certificates.k8s.io/v1beta1
kind: CertificateSigningRequest
metadata:
name: student-csr
spec:
group:
- system:authenticated
request: LS0tLS1CRUdJTiBD...tLS0tLQo=
usages:
- digital signature
- key encipherment
- client auth
$ kubectl apply -f signing-request.yaml
certificatesigningrequest.certificates.k8s.io/student-csr created
$ kubectl get csr
NAME AGE REQUESTOR CONDITION
student-csr 22s minikube-user Pending
$ kubectl certificate approve student-csr
certificatesigningrequest.certificates.k8s.io/student-csr approved
$ kubectl get csr
NAME AGE REQUESTOR CONDITION
student-csr 2m47s minikube-user Approved,Issued
$ kubectl get csr student-csr -o jsonpath='{.status.certificate}'
'LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMrVENDQWVHZ0F3SUJBZ0lSQUs3UHQ1L3NZYzh1bEtOZlpjdDJFcVF3RFFZSktvWklodmNOQVFFTEJRQXcKRlRFVE1CRUdBMVVFQXhNS2JXbHVhV3QxWW1WRFFUQWVGdzB5TURBeU1qVXhOVEl4TVRCYUZ3MHlNVEF5TWpReApOVEl4TVRCYU1DUXhFREFPQmdOVkJBb1RCMnhsWVhKdVpYSXhFREFPQmdOVkJBTVRCM04wZFdSbGJuUXdnZ0VpCk1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRRGFQMmJDL3dIMXFvTnVMTGg4enVDZjVyYXgKcXRBdXZZMDRLZkdOaTRGU08wV2E2eEFwQk51d1pMdFlvY2VpbUJSb3c5Vk56bzZWb3ZZdWZicGxDMXpxNzY2UAo2dGZnRko2V1YycE92ejRMZjFpbTRoYWxPckpnYVRMR2tZQTVGVHN5aUFvMkdCYVdTVVJManMxK3BlUE1lc21hCk9veWtiQnllcUpUK2pwY29ONHVSVTd6ZGJkYVBPUjJ6ZzNHRk83MUhES0ludjNEMUsybHNvaCt6NEFaY20zbWUKQlE5WWNSb3BBN1RNL0VNN2JXak5MYUluVTBLb1lMVzhINjgrcDgxWnlrZXQzYjFDcnJuOWgyTy9wMHNGTDRzMQpuT3kyOWJSOG9hclpYSVdOcE41MVJLZ2VTSmI0L0JxY1hDM0JUZDRXd2JCeE9HdklmWTlodXh4eXBMYXBBZ01CCkFBR2pOVEF6TUE0R0ExVWREd0VCL3dRRUF3SUZvREFUQmdOVkhTVUVEREFLQmdnckJnRUZCUWNEQWpBTUJnTlYKSFJNQkFmOEVBakFBTUEwR0NTcUdTSWIzRFFFQkN3VUFBNElCQVFDQmY3OHlRcm1HL2FzRlJLUHhKaGZpMGo2bgo1Ym5oYk1UaGlJdWN6NmZJT0E1bDRsbFF3OHpaU0grNnU4aWt1ZmRwVi83aWhYbm1nZkQxMGV1KzJlZlhGd2taClhFOHI4YkcvZDByUzIxQWFNMHB3a2dRUUpEUHRidEZCYnQydXA0Y0VsOVQwVUladWxLK3k4U2RNOTNLVmxHZGkKcmdYOEp3TzhRa0lZZmI0czY0T0tHT2VjL2lIYytvT2JVUVA0aDlGMG1aS3FqS0RkZVB0Qk1XMWltMUVkb2k4MApRcjB6NTlWK0ZBajNSTndDbFpFYjRuYlZ4bEJqN2JhMGN1ajY1QVZvTnRhVVoxVEFDeWhhSnhidHJxdmNsTkNZCk5lTE8zbWkrKzZWVjVsTzlBZmNIZEt0aHc0Y1BiZXdSaHBKenVTaDlaMTQ2K1dPcHUvSjF4RkJKVVdENAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg=='
$ kubectl get csr student-csr -o jsonpath={.status.certificate} | base64 -d
-----BEGIN CERTIFICATE-----
MIIC+TCCAeGgAwIBAgIRAK7Pt5/sYc8ulKNfZct2EqQwDQYJKoZIhvcNAQELBQAw
FTETMBEGA1UEAxMKbWluaWt1YmVDQTAeFw0yMDAyMjUxNTIxMTBaFw0yMTAyMjQx
NTIxMTBaMCQxEDAOBgNVBAoTB2xlYXJuZXIxEDAOBgNVBAMTB3N0dWRlbnQwggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaP2bC/wH1qoNuLLh8zuCf5rax
qtAuvY04KfGNi4FSO0Wa6xApBNuwZLtYoceimBRow9VNzo6VovYufbplC1zq766P
6tfgFJ6WV2pOvz4Lf1im4halOrJgaTLGkYA5FTsyiAo2GBaWSURLjs1+pePMesma
OoykbByeqJT+jpcoN4uRU7zdbdaPOR2zg3GFO71HDKInv3D1K2lsoh+z4AZcm3me
BQ9YcRopA7TM/EM7bWjNLaInU0KoYLW8H68+p81Zyket3b1Crrn9h2O/p0sFL4s1
nOy29bR8oarZXIWNpN51RKgeSJb4/BqcXC3BTd4WwbBxOGvIfY9huxxypLapAgMB
AAGjNTAzMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDAjAMBgNV
HRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQCBf78yQrmG/asFRKPxJhfi0j6n
5bnhbMThiIucz6fIOA5l4llQw8zZSH+6u8ikufdpV/7ihXnmgfD10eu+2efXFwkZ
XE8r8bG/d0rS21AaM0pwkgQQJDPtbtFBbt2up4cEl9T0UIZulK+y8SdM93KVlGdi
rgX8JwO8QkIYfb4s64OKGOec/iHc+oObUQP4h9F0mZKqjKDdePtBMW1im1Edoi80
Qr0z59V+FAj3RNwClZEb4nbVxlBj7ba0cuj65AVoNtaUZ1TACyhaJxbtrqvclNCY
NeLO3mi++6VV5lO9AfcHdKthw4cPbewRhpJzuSh9Z146+WOpu/J1xFBJUWD4
-----END CERTIFICATE-----
$ kubectl get csr student-csr -o jsonpath={.status.certificate} | base64 -d > student.crt
$ kubectl config set-credentials student --client-certificate=student.crt --client-key=student.key
User "student" set.
$ kubectl config set-context student-context --cluster=minikube --namespace=lfs158 --user=student
Context "student-context" created.
$ kubectl config view
apiVersion: v1
clusters:
- cluster:
certificate-authority: C:\Users\Kone\.minikube\ca.crt
server: https://192.168.99.105:8443
name: minikube
contexts:
- context:
cluster: minikube
user: minikube
name: minikube
- context:
cluster: minikube
namespace: lfs158
user: student
name: student-context
current-context: minikube
kind: Config
preferences: {}
users:
- name: minikube
user:
client-certificate: C:\Users\Kone\.minikube\client.crt
client-key: C:\Users\Kone\.minikube\client.key
- name: student
user:
client-certificate: ..\k8spractice\rbac\student.crt
client-key: ..\k8spractice\rbac\student.key
$ kubectl -n lfs158 create deployment nginx --image=nginx:apline
deployment.apps/nginx created
$ kubectl get pods
No resources found in default namespace.
$ kubectl --context=student-context get pods
Error from server (Forbidden): pods is forbidden: User "student" cannot list resource "pods" in API group "" in the namespace "lfs158"
$ kubectl create role pod-reader --resource=pods --verb=get --verb=watch --verb=list -o yaml > role.yaml
$ cat role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
creationTimestamp: "2020-02-25T16:07:27Z"
name: pod-reader
namespace: default
resourceVersion: "12886"
selfLink: /apis/rbac.authorization.k8s.io/v1/namespaces/default/roles/pod-reader
uid: a7197eea-f16e-4f80-9d8f-6dd715d38fa2
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- watch
- list
$ cat role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
namespace: lfs158
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- watch
- list
$ kubectl create -f role.yaml
role.rbac.authorization.k8s.io/pod-reader created
$ kubectl -n lfs158 get roles
NAME AGE
pod-reader 41s
$ kubectl create rolebinding pod-read-access --namespace=lfs158 --role=pod-reader --user=student -o yaml > rolebinding.yaml
$ cat rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
creationTimestamp: "2020-02-25T16:39:34Z"
name: pod-read-access
namespace: lfs158
resourceVersion: "17102"
selfLink: /apis/rbac.authorization.k8s.io/v1/namespaces/lfs158/rolebindings/pod-read-access
uid: 86ce7094-8a0f-45dc-8287-1fbe207fe183
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: pod-reader
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: student
$ kubectl create -f rolebinding.yaml
rolebinding.rbac.authorization.k8s.io/pod-read-access created
$ kubectl -n lfs158 get rolebinding
NAME AGE
pod-read-access 92s
$ kubectl --context=student-context get pods
NAME READY STATUS RESTARTS AGE
nginx-68bb64c59b-cj5jq 0/1 ImagePullBackOff 0 60m
$ kubectl get pods
No resources found in default namespace.
$ kubectl -n lfs158 get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 0/1 1 0 65m
$ kubectl -n lfs158 set image deployment/nginx nginx=nginx:1.16-apline
deployment.apps/nginx image updated
$ kubectl -n lfs158 get pods
NAME READY STATUS RESTARTS AGE
nginx-579f667d9c-58hft 0/1 ImagePullBackOff 0 13m
nginx-68bb64c59b-cj5jq 0/1 ImagePullBackOff 0 87m
$ kubectl -n lfs158 describe pod nginx-68bb64c59b-cj5jq
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning Failed 8m13s (x344 over 88m) kubelet, minikube Error: ImagePullBackOff
Normal BackOff 3m1s (x367 over 88m) kubelet, minikube Back-off pulling image "nginx:apline"
// Sorry no nginx:apline. it should be alpine (misspelling)
# for the followin is also misspelling.
$ kubectl -n lfs158 describe pod nginx-579f667d9c-58hft
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 15m default-scheduler Successfully assigned lfs158/nginx-579f667d9c-58hft to minikube
Normal Pulling 14m (x4 over 15m) kubelet, minikube Pulling image "nginx:1.16-apline"
Warning Failed 14m (x4 over 15m) kubelet, minikube Failed to pull image "nginx:1.16-apline": rpc error: code = Unknown desc = Error response from daemon: manifest for nginx:1.16-apline not found: manifest unknown: manifest unknown
Warning Failed 14m (x4 over 15m) kubelet, minikube Error: ErrImagePull
Warning Failed 10m (x19 over 15m) kubelet, minikube Error: ImagePullBackOff
Normal BackOff 49s (x62 over 15m) kubelet, minikube Back-off pulling image "nginx:1.16-apline"
$ kubectl -n lfs158 set image deployment/nginx nginx=nginx:alpine
deployment.apps/nginx image updated
$ kubectl --context=student-context get pods
NAME READY STATUS RESTARTS AGE
nginx-5b6fb6dd96-wfk98 1/1 Running 0 18s
$ kubectl -n lfs158 describe pod nginx-5b6fb6dd96-wfk98
Name: nginx-5b6fb6dd96-wfk98
Namespace: lfs158
Priority: 0
Node: minikube/192.168.99.105
Start Time: Wed, 26 Feb 2020 00:26:08 +0700
Labels: app=nginx
pod-template-hash=5b6fb6dd96
Annotations: <none>
Status: Running
IP: 172.17.0.4
IPs:
IP: 172.17.0.4
Controlled By: ReplicaSet/nginx-5b6fb6dd96
Containers:
nginx:
Container ID: docker://003066d4b35a4da3672e45a622eee937aa8f330fe957677314968b4221288701
Image: nginx:alpine
Image ID: docker-pullable://nginx@sha256:9e81b8f9cef5a095f892183688798a5b2c368663276aa0f2be4b1cd283ace53d
Port: <none>
Host Port: <none>
State: Running
Started: Wed, 26 Feb 2020 00:26:21 +0700
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-xpjxl (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-xpjxl:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-xpjxl
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
---- ------ ---- ---- -------
Normal Scheduled 85s default-scheduler Successfully assigned lfs158/nginx-5b6fb6dd96-wfk98 to minikube
Normal Pulling 83s kubelet, minikube Pulling image "nginx:alpine"
Normal Pulled 72s kubelet, minikube Successfully pulled image "nginx:alpine"
Normal Created 72s kubelet, minikube Created container nginx
Normal Started 72s kubelet, minikube Started container nginx