From 16306a52c49184856f85b0365add6f307730e258 Mon Sep 17 00:00:00 2001 From: marcel-dempers Date: Wed, 1 Sep 2021 22:15:03 +1000 Subject: [PATCH 1/4] remove --- python/introduction/part-3.json/README.md | 301 --------------------- python/introduction/part-3.json/dockerfile | 8 - python/introduction/part-3.json/src/app.py | 50 ---- 3 files changed, 359 deletions(-) delete mode 100644 python/introduction/part-3.json/README.md delete mode 100644 python/introduction/part-3.json/dockerfile delete mode 100644 python/introduction/part-3.json/src/app.py diff --git a/python/introduction/part-3.json/README.md b/python/introduction/part-3.json/README.md deleted file mode 100644 index b099e66..0000000 --- a/python/introduction/part-3.json/README.md +++ /dev/null @@ -1,301 +0,0 @@ -# Introduction to Python: JSON - -JSON is a very important format for storing data in Software engineering.
-JSON is popular for the following scenarios : - -* Popular standard for data structures in general. -* Applications may talk to each other by passing JSON data back and forth (HTTP Web APIs). -* Applications often store configuration in JSON format as a configuration file. -* Data may be stored in databases or caches in JSON format. -* DevOps engineers may store infrastructure configuration in JSON format. - -## Python Dev Environment - -The same as Part 1, we start with a [dockerfile](./dockerfile) where we declare our version of `python`. - -``` -FROM python:3.9.6-alpine3.13 as dev - -WORKDIR /work -``` - -Let's build and start our container: - -``` -cd python\introduction\part-3.json - -docker build --target dev . -t python -docker run -it -v ${PWD}:/work python sh - -/work # python --version -Python 3.9.6 - -``` - -## Our application - -Firstly we have a class to define what a customer looks like: -``` -class Customer: - def __init__(self, c="",f="",l=""): - self.customerID = c - self.firstName = f - self.lastName = l - def fullName(self): - return self.firstName + " " + self.lastName -``` - -Then we need a function which returns our customers: -``` -def getCustomers(): - customers = { - "a": Customer("a","James", "Baker"), - "b": Customer("b", "Jonathan", "D"), - "c": Customer("c", "Aleem", "Janmohamed"), - "d": Customer("d", "Ivo", "Galic"), - "e": Customer("e", "Joel", "Griffiths"), - "f": Customer("f", "Michael", "Spinks"), - "g": Customer("g", "Victor", "Savkov"), - "h" : Customer("h", "Marcel", "Dempers") - } - return customers -``` - -Here is a function to return a specific customer: -``` -def getCustomer(customerID): - customer = getCustomers() - return customer[customerID] -``` - -Test our functions: - -``` -customers = getCustomers() -customer = customers["h"] - -print(customers) -print(customer.fullName) -``` - -## Files - -In [part-2](../part-2.files/README.md) we learnt about reading and writing to files.
-We changed our functions to get customers from file and update customers by writing the data back to file.
- -Let's do that quick: - -## Get Customers - -``` -import os.path -import csv - -def getCustomers(): - if os.path.isfile("customers.log"): - with open('customers.log', newline='') as customerFile: - reader = csv.DictReader(customerFile) - l = list(reader) - customers = {c["customerID"]: c for c in l} - return customers - else: - return {} -``` - -## Update Customers - -Let's create a function to update our customers: - -``` -def updateCustomers(customers): - fields = ['customerID', 'firstName', 'lastName'] - with open('customers.log', 'w', newline='') as customerFile: - writer = csv.writer(customerFile) - writer.writerow(fields) - for customerID in customers: - customer = customers[customerID] - writer.writerow([customer.customerID, customer.firstName, customer.lastName]) -``` - -## Test - -Let's test our two functions to ensure they work - -``` -customers = { - "a": Customer("a","James", "Baker"), - "b": Customer("b", "Jonathan", "D"), - "c": Customer("c", "Aleem", "Janmohamed"), - "d": Customer("d", "Ivo", "Galic"), - "e": Customer("e", "Joel", "Griffiths"), - "f": Customer("f", "Michael", "Spinks"), - "g": Customer("g", "Victor", "Savkov"), - "h" : Customer("h", "Marcel", "Dempers") -} - -#save it -updateCustomers(customers) - -#see the changes -customers = getCustomers() -for customer in customers: - print(customers[customer]) - -``` - -## JSON - -JSON is a very simple data structure for building objects. -you can define any type of object and data using JSON.
- -In JSON, objects are defined by open and close brackets, like `{}`
-Arrays or lists are defined as square brackets, like `[]`
- -We can therefore define a customer like : -`Notice keys and values have quotes, and separated by colon` - -``` -{ - "customerID" : "a", - "firstName: "Bob", - "lastName": "Smith" -} - -``` -We can define an array of customers in JSON by declaring our array with square brackets and having customer objects inside, separated by commas: - -``` -# Example Array: -[{customer-1},{customer-2},{customer-3},{customer-4} ] -``` - -## JSON Library - -Python provides a library for dealing with JSON.
-Let's take our customer dictionary, and convert it to json structure and -finally write it to file using our update function. - -``` -import json -``` - -Now first things first, we need to convert our customers dictionary to a JSON structured string so we can store it to file.
- -The `json` library allows us to convert dictionaries to files using -the `dumps` function: - -``` -jsonData = json.dumps(customers) -print(jsonData) -``` - -But if we run this we get an error: -`TypeError: Object of type Customer is not JSON serializable` - -That is because the library can only deal with full dictionaries. -Taking a closer look at our dictionary, our customer is a class. - -``` -# our key is a string -# our value is a class -"h" : Customer("h", "Marcel", "Dempers") -``` - -`json.dumps()` only allows full dictionaries so we need our customer object to be in dictionary form like so: - -``` -"h": { "customerID": "h", "firstName" : "Marcel", "lastName" : "Dempers"} -``` - -To fix our dictionary, we can iterate it and build a new one - -``` -# start with an empty one -customerDict = {} - -#populate our new dictionary -for id in customers: - customerDict[id] = customers[id].__dict__ - -#print it -print(customerDict) -``` - -Now we can convert our customer dictionary to json - -``` -customerJSON = json.dumps(customerDict) -print(customerJSON) -``` - -Now we've converted our data into JSON, we can view this in a new tab window and change the language mode to JSON to visualise the data in our new format. - -Now essentially our application will use dictionaries when working with the data -but store and transport it as JSON.
- -Therefore our update function should take a dictionary and convert it to JSON -and store it. - -``` -def updateCustomers(customer): - with open('customers.json', 'w', newline='') as customerFile: - customerJSON = json.dumps(customer) - customerFile.write(customerJSON) -``` - -We also need to change our `getCustomers` function to read the JSON file -and convert that data correctly back to a dictionary for processing. - -``` -def getCustomers(): - if os.path.isfile("customers.json"): - with open('customers.json', newline='') as customerFile: - data = customerFile.read() - customers = json.loads(data) - return customers - else: - return {} -``` - -Finally let's test our functions : - -``` -customers = getCustomers() -print(customers) -``` - -It's also very easy to add a customer to our JSON data using our class and using pythons internal `__dict__` property to convert the object to a dictionary and add it to our customers dictionary - -``` -customers["i"] = Customer("i", "Bob", "Smith").__dict__ -updateCustomers(customers) -``` - -## Docker - -Let's build our container image and run it while mounting our customer file - -Our final `dockerfile` -``` -FROM python:3.9.6-alpine3.13 as dev - -WORKDIR /work - -FROM dev as runtime -COPY ./src/ /app - -ENTRYPOINT [ "python", "/app/app.py" ] - -``` - -Build and run our container. -Notice the `customers.json` file gets created if it does not exist. - -``` -cd python\introduction\part-3.json - -docker build . -t customer-app - -docker run -v ${PWD}:/work -w /work customer-app - -``` \ No newline at end of file diff --git a/python/introduction/part-3.json/dockerfile b/python/introduction/part-3.json/dockerfile deleted file mode 100644 index 7666e03..0000000 --- a/python/introduction/part-3.json/dockerfile +++ /dev/null @@ -1,8 +0,0 @@ -FROM python:3.9.6-alpine3.13 as dev - -WORKDIR /work - -FROM dev as runtime -COPY ./src/ /app - -ENTRYPOINT [ "python", "/app/app.py" ] \ No newline at end of file diff --git a/python/introduction/part-3.json/src/app.py b/python/introduction/part-3.json/src/app.py deleted file mode 100644 index c070912..0000000 --- a/python/introduction/part-3.json/src/app.py +++ /dev/null @@ -1,50 +0,0 @@ -import os.path -import csv -import json - -class Customer: - def __init__(self, c="",f="",l=""): - self.customerID = c - self.firstName = f - self.lastName = l - def fullName(self): - return self.firstName + " " + self.lastName - -def getCustomers(): - if os.path.isfile("customers.json"): - with open('customers.json', newline='') as customerFile: - data = customerFile.read() - customers = json.loads(data) - return customers - else: - return {} - -def updateCustomers(customer): - with open('customers.json', 'w', newline='') as customerFile: - customerJSON = json.dumps(customer) - customerFile.write(customerJSON) - -customers = { - "a": Customer("a","James", "Baker"), - "b": Customer("b", "Jonathan", "D"), - "c": Customer("c", "Aleem", "Janmohamed"), - "d": Customer("d", "Ivo", "Galic"), - "e": Customer("e", "Joel", "Griffiths"), - "f": Customer("f", "Michael", "Spinks"), - "g": Customer("g", "Victor", "Savkov"), - "h" : Customer("h", "Marcel", "Dempers") -} - - -customerDict = {} -for id in customers: - customerDict[id] = customers[id].__dict__ - -updateCustomers(customerDict) - -customers = getCustomers() - -customers["i"] = Customer("i", "Marcel", "Dempers").__dict__ -updateCustomers(customers) - -print(customers) From 9fb836b8d4e6012e7af6563a04b9f293d13a4f9d Mon Sep 17 00:00:00 2001 From: marcel-dempers Date: Mon, 13 Sep 2021 13:28:23 +1000 Subject: [PATCH 2/4] wip --- kubernetes/rbac/README.md | 186 ++++++++++++++++++ kubernetes/rbac/pod.yaml | 9 + kubernetes/rbac/role.yaml | 12 ++ kubernetes/rbac/rolebinding.yaml | 13 ++ kubernetes/rbac/serviceaccount-role.yaml | 9 + .../rbac/serviceaccount-rolebinding.yaml | 12 ++ kubernetes/rbac/serviceaccount.yaml | 4 + 7 files changed, 245 insertions(+) create mode 100644 kubernetes/rbac/README.md create mode 100644 kubernetes/rbac/pod.yaml create mode 100644 kubernetes/rbac/role.yaml create mode 100644 kubernetes/rbac/rolebinding.yaml create mode 100644 kubernetes/rbac/serviceaccount-role.yaml create mode 100644 kubernetes/rbac/serviceaccount-rolebinding.yaml create mode 100644 kubernetes/rbac/serviceaccount.yaml diff --git a/kubernetes/rbac/README.md b/kubernetes/rbac/README.md new file mode 100644 index 0000000..f3262c4 --- /dev/null +++ b/kubernetes/rbac/README.md @@ -0,0 +1,186 @@ +# Introduction to Kubernetes: RBAC + +## Create Kubernetes cluster + + +``` +kind create cluster --name rbac --image kindest/node:v1.20.2 +``` + +## Kubernetes CA Certificate + +Kubernetes does not have a concept of users, instead it relies on certificates and would only +trust certificates signed by its own CA.
+ +To get the CA certificates for our cluster, easiest way is to access the master node.
+Because we run on `kind`, our master node is a docker container.
+The CA certificates exists in the `/etc/kubernetes/pki` folder by default.
+If you are using `minikube` you may find it under `~/.minikube/.` + +Access the master node: + +``` +docker exec -it rbac-control-plane bash + +ls -l /etc/kubernetes/pki +total 60 +-rw-r--r-- 1 root root 1135 Sep 10 01:38 apiserver-etcd-client.crt +-rw------- 1 root root 1675 Sep 10 01:38 apiserver-etcd-client.key +-rw-r--r-- 1 root root 1143 Sep 10 01:38 apiserver-kubelet-client.crt +-rw------- 1 root root 1679 Sep 10 01:38 apiserver-kubelet-client.key +-rw-r--r-- 1 root root 1306 Sep 10 01:38 apiserver.crt +-rw------- 1 root root 1675 Sep 10 01:38 apiserver.key +-rw-r--r-- 1 root root 1066 Sep 10 01:38 ca.crt +-rw------- 1 root root 1675 Sep 10 01:38 ca.key +drwxr-xr-x 2 root root 4096 Sep 10 01:38 etcd +-rw-r--r-- 1 root root 1078 Sep 10 01:38 front-proxy-ca.crt +-rw------- 1 root root 1679 Sep 10 01:38 front-proxy-ca.key +-rw-r--r-- 1 root root 1103 Sep 10 01:38 front-proxy-client.crt +-rw------- 1 root root 1675 Sep 10 01:38 front-proxy-client.key +-rw------- 1 root root 1679 Sep 10 01:38 sa.key +-rw------- 1 root root 451 Sep 10 01:38 sa.pub + +exit the container +``` + +Copy the certs out of our master node: + +``` +cd kubernetes/rbac +docker cp rbac-control-plane:/etc/kubernetes/pki/ca.crt ca.crt +docker cp rbac-control-plane:/etc/kubernetes/pki/ca.key ca.key +``` + +# Kubernetes Users + +As mentioned before, Kubernetes has no concept of users, it trusts certificates that is signed by its CA.
+This allows a lot of flexibility as Kubernetes lets you bring your own auth mechanisms, such as [OpenID Connect](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#openid-connect-tokens) or OAuth.
+ +

This allows managed Kubernetes offerings to use their cloud logins to authenticate.

+ + So on Azure, I can use my Microsoft account, GKE my Google account and AWS EKS my Amazon account.
+ + You will need to consult your cloud provider to setup authentication.
+ Example [Azure AKS](https://docs.microsoft.com/en-us/azure/aks/azure-ad-integration-cli) + +## User Certificates + +First thing we need to do is create a certificate signed by our Kubernetes CA.
+We have the CA, let's make a certificate.
+ +Easy way to create a cert is use `openssl` and the easiest way to get `openssl` is to simply run a container: + +``` +docker run -it -v ${PWD}:/work -w /work -v ${HOME}:/root/ --net host alpine sh + +apk add openssl +``` + +Let's create a certificate for Bob Smith: + + +``` +#start with a private key +openssl genrsa -out bob.key 2048 + +``` + +Now we have a key, we need a certificate signing request (CSR).
+We also need to specify the groups that Bob belongs to.
+Let's pretend Bob is part of the `Shopping` team and will be developing +applications for the `Shopping` + +``` +openssl req -new -key bob.key -out bob.csr -subj "/CN=Bob Smith/O=Shopping" +``` + +Use the CA to generate our certificate by signing our CSR.
+We may set an expiry on our certificate as well + +``` +openssl x509 -req -in bob.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out bob.crt -days 1 +``` + +## Building a kube config + +Let's install `kubectl` in our container to make things easier: + +``` +apk add curl nano +curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl +chmod +x ./kubectl +mv ./kubectl /usr/local/bin/kubectl +``` + +We'll be trying to avoid messing with our current kubernetes config.
+So lets tell `kubectl` to look at a new config that does not yet exists + +``` +export KUBECONFIG=~/.kube/new-config +``` + +Create a cluster entry which points to the cluster and contains the details of the CA certificate: + +``` +kubectl config set-cluster dev-cluster --server=https://127.0.0.1:51972 \ +--certificate-authority=ca.crt \ +--embed-certs=true + +#see changes +nano ~/.kube/new-config +``` + + +kubectl config set-credentials bob --client-certificate=bob.crt --client-key=bob.key + +kubectl config set-context dev --cluster=dev-cluster --namespace=shopping --user=bob + +kubectl config use-context dev + +kubectl get pods +Error from server (Forbidden): pods is forbidden: User "Bob Smith" cannot list resource "pods" in API group "" in the namespace "shopping" + + +## Give Bob Smith Access + +``` +kubectl create ns shopping + +kubectl -n shopping apply -f .\role.yaml +kubectl -n shopping apply -f .\rolebinding.yaml +``` + +## Test Access as Bob + +kubectl get pods +No resources found in shopping namespace. + +# Kubernetes Service Accounts + +So we've covered users, but what about applications or services running in our cluster ?
+Most business apps will not need to connect to the kubernetes API unless you are building something that integrates with your cluster, like a CI/CD tool, an autoscaler or a custom webhook.
+ +Generally applications will use a service account to connect.
+You can read more about [Kubernetes Service Accounts](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/). + + + +``` +# Point to the internal API server hostname +APISERVER=https://kubernetes.default.svc + +# Path to ServiceAccount token +SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount + +# Read this Pod's namespace +NAMESPACE=$(cat ${SERVICEACCOUNT}/namespace) + +# Read the ServiceAccount bearer token +TOKEN=$(cat ${SERVICEACCOUNT}/token) + +# Reference the internal certificate authority (CA) +CACERT=${SERVICEACCOUNT}/ca.crt + +# List pods through the API +curl --cacert ${CACERT} --header "Authorization: Bearer $TOKEN" -s ${APISERVER}/api/v1/namespaces/shopping/pods/ +``` \ No newline at end of file diff --git a/kubernetes/rbac/pod.yaml b/kubernetes/rbac/pod.yaml new file mode 100644 index 0000000..1b7d69e --- /dev/null +++ b/kubernetes/rbac/pod.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Pod +metadata: + name: nginx +spec: + containers: + - image: nginx + name: nginx + serviceAccountName: shopping-api diff --git a/kubernetes/rbac/role.yaml b/kubernetes/rbac/role.yaml new file mode 100644 index 0000000..b42e20f --- /dev/null +++ b/kubernetes/rbac/role.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + namespace: shopping + name: pod-reader +rules: +- apiGroups: [""] + resources: ["pods", "pods/exec"] + verbs: ["get", "watch", "list", "create", "delete"] +- apiGroups: [""] + resources: ["deployments"] + verbs: ["get", "watch", "list", "delete", "create"] \ No newline at end of file diff --git a/kubernetes/rbac/rolebinding.yaml b/kubernetes/rbac/rolebinding.yaml new file mode 100644 index 0000000..5ecf3b3 --- /dev/null +++ b/kubernetes/rbac/rolebinding.yaml @@ -0,0 +1,13 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: read-pods + namespace: shopping +subjects: +- kind: User + name: "Bob Smith" + apiGroup: rbac.authorization.k8s.io +roleRef: + kind: Role + name: pod-reader + apiGroup: rbac.authorization.k8s.io \ No newline at end of file diff --git a/kubernetes/rbac/serviceaccount-role.yaml b/kubernetes/rbac/serviceaccount-role.yaml new file mode 100644 index 0000000..88d8b8b --- /dev/null +++ b/kubernetes/rbac/serviceaccount-role.yaml @@ -0,0 +1,9 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + namespace: shopping + name: shopping-api +rules: +- apiGroups: [""] + resources: ["pods"] + verbs: ["get", "watch", "list"] \ No newline at end of file diff --git a/kubernetes/rbac/serviceaccount-rolebinding.yaml b/kubernetes/rbac/serviceaccount-rolebinding.yaml new file mode 100644 index 0000000..856d424 --- /dev/null +++ b/kubernetes/rbac/serviceaccount-rolebinding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: shopping-api + namespace: shopping +subjects: +- kind: ServiceAccount + name: shopping-api +roleRef: + kind: Role + name: shopping-api + apiGroup: rbac.authorization.k8s.io \ No newline at end of file diff --git a/kubernetes/rbac/serviceaccount.yaml b/kubernetes/rbac/serviceaccount.yaml new file mode 100644 index 0000000..3073199 --- /dev/null +++ b/kubernetes/rbac/serviceaccount.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: shopping-api \ No newline at end of file From 18d9ac2ca0081b25a3328d23a3632f536734fa66 Mon Sep 17 00:00:00 2001 From: marcel-dempers Date: Tue, 14 Sep 2021 12:59:35 +1000 Subject: [PATCH 3/4] rbac --- kubernetes/rbac/README.md | 34 +++++++++++++++++++++++++++----- kubernetes/rbac/pod.yaml | 4 ++-- kubernetes/rbac/role.yaml | 4 ++-- kubernetes/rbac/rolebinding.yaml | 4 ++-- 4 files changed, 35 insertions(+), 11 deletions(-) diff --git a/kubernetes/rbac/README.md b/kubernetes/rbac/README.md index f3262c4..560b3ab 100644 --- a/kubernetes/rbac/README.md +++ b/kubernetes/rbac/README.md @@ -122,7 +122,7 @@ export KUBECONFIG=~/.kube/new-config Create a cluster entry which points to the cluster and contains the details of the CA certificate: ``` -kubectl config set-cluster dev-cluster --server=https://127.0.0.1:51972 \ +kubectl config set-cluster dev-cluster --server=https://127.0.0.1:52794 \ --certificate-authority=ca.crt \ --embed-certs=true @@ -131,9 +131,9 @@ nano ~/.kube/new-config ``` -kubectl config set-credentials bob --client-certificate=bob.crt --client-key=bob.key +kubectl config set-credentials bob --client-certificate=bob.crt --client-key=bob.key --embed-certs=true -kubectl config set-context dev --cluster=dev-cluster --namespace=shopping --user=bob +kubectl config set-context dev --cluster=dev-cluster --namespace=shopping --user=bob kubectl config use-context dev @@ -144,6 +144,7 @@ Error from server (Forbidden): pods is forbidden: User "Bob Smith" cannot list r ## Give Bob Smith Access ``` +cd kubernetes/rbac kubectl create ns shopping kubectl -n shopping apply -f .\role.yaml @@ -163,9 +164,21 @@ Most business apps will not need to connect to the kubernetes API unless you are Generally applications will use a service account to connect.
You can read more about [Kubernetes Service Accounts](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/). - +Let's deploy a service account ``` +kubectl -n shopping apply -f serviceaccount.yaml + +``` +Now we can deploy a pod that uses the service account +``` +kubectl -n shopping apply -f pod.yaml +``` +Now we can test the access from within that pod by trying to list pods: + +``` +kubectl -n shopping exec -it shopping-api -- bash + # Point to the internal API server hostname APISERVER=https://kubernetes.default.svc @@ -183,4 +196,15 @@ CACERT=${SERVICEACCOUNT}/ca.crt # List pods through the API curl --cacert ${CACERT} --header "Authorization: Bearer $TOKEN" -s ${APISERVER}/api/v1/namespaces/shopping/pods/ -``` \ No newline at end of file + +# we should see an error not having access +``` + +Now we can allow this pod to list pods in the shopping namespace +``` +kubectl -n shopping apply -f serviceaccount-role.yaml +kubectl -n shopping apply -f serviceaccount-rolebinding.yaml +``` + +If we try run `curl` command again we can see now we are able to get a json +response with pod information diff --git a/kubernetes/rbac/pod.yaml b/kubernetes/rbac/pod.yaml index 1b7d69e..9f4f963 100644 --- a/kubernetes/rbac/pod.yaml +++ b/kubernetes/rbac/pod.yaml @@ -1,9 +1,9 @@ apiVersion: v1 kind: Pod metadata: - name: nginx + name: shopping-api spec: containers: - image: nginx - name: nginx + name: shopping-api serviceAccountName: shopping-api diff --git a/kubernetes/rbac/role.yaml b/kubernetes/rbac/role.yaml index b42e20f..d5facf2 100644 --- a/kubernetes/rbac/role.yaml +++ b/kubernetes/rbac/role.yaml @@ -2,11 +2,11 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: shopping - name: pod-reader + name: manage-pods rules: - apiGroups: [""] resources: ["pods", "pods/exec"] verbs: ["get", "watch", "list", "create", "delete"] -- apiGroups: [""] +- apiGroups: ["apps"] resources: ["deployments"] verbs: ["get", "watch", "list", "delete", "create"] \ No newline at end of file diff --git a/kubernetes/rbac/rolebinding.yaml b/kubernetes/rbac/rolebinding.yaml index 5ecf3b3..de2b323 100644 --- a/kubernetes/rbac/rolebinding.yaml +++ b/kubernetes/rbac/rolebinding.yaml @@ -1,7 +1,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: - name: read-pods + name: manage-pods namespace: shopping subjects: - kind: User @@ -9,5 +9,5 @@ subjects: apiGroup: rbac.authorization.k8s.io roleRef: kind: Role - name: pod-reader + name: manage-pods apiGroup: rbac.authorization.k8s.io \ No newline at end of file From 5de4cf18c891579eae14d331b63e2fa1c2ac2922 Mon Sep 17 00:00:00 2001 From: marcel-dempers Date: Wed, 15 Sep 2021 19:08:40 +1000 Subject: [PATCH 4/4] update --- kubernetes/rbac/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kubernetes/rbac/README.md b/kubernetes/rbac/README.md index 560b3ab..e1531ad 100644 --- a/kubernetes/rbac/README.md +++ b/kubernetes/rbac/README.md @@ -122,7 +122,7 @@ export KUBECONFIG=~/.kube/new-config Create a cluster entry which points to the cluster and contains the details of the CA certificate: ``` -kubectl config set-cluster dev-cluster --server=https://127.0.0.1:52794 \ +kubectl config set-cluster dev-cluster --server=https://127.0.0.1:52807 \ --certificate-authority=ca.crt \ --embed-certs=true