|
6 | 6 |
|
7 | 7 | 
|
8 | 8 |
|
9 |
| -Access k8s API using time limited access tokens, kube-gateway allow usage of one time access tokens to k8s resources, users |
10 |
| -can use the default kube-gateway web application, or create custom web applications that use the time limited tokens to access the |
| 9 | +Access the k8s API using time-limited access tokens. kube-gateway allows the usage of one-time access tokens to access k8s resources. Users |
| 10 | +can use the default kube-gateway web application or create custom web applications that use the time-limited tokens to access the |
11 | 11 | k8s API.
|
12 | 12 |
|
13 |
| -## What can I do with it ? |
| 13 | +## What can I do with it? |
14 | 14 |
|
15 |
| -- Create one time links to access a k8s resource with a time limited signed token (*). |
16 |
| -- Create custom web applications that can access k8s API using time limited singed tokens. |
| 15 | +- Create one-time links to access a k8s resource with a time-limited signed token (*). |
| 16 | +- Create custom web applications that can access the k8s API using time-limited signed tokens. |
17 | 17 |
|
18 |
| -(*) a signed token gives access to predefined k8s resources during a predefined time window. |
19 |
| -## Build the gateway server with noVNC web application |
| 18 | +(*) A signed token gives access to predefined k8s resources during a predefined time window. |
| 19 | + |
| 20 | +## Build the gateway server with a noVNC web application |
20 | 21 |
|
21 | 22 | ``` bash
|
22 | 23 | # Build the gateway locally:
|
23 | 24 | go build -v ./cmd/...
|
24 | 25 |
|
25 | 26 | # Create and push the image into a container repository:
|
26 |
| -# For example |
27 |
| -#IMG=quay.io/kubevirt-ui/kube-gateway:v0.1.0 make image |
| 27 | +# For example: |
| 28 | +# IMG=quay.io/kubevirt-ui/kube-gateway:v0.1.0 make image |
28 | 29 | IMG=<your image repo>
|
29 | 30 | podman build -t ${IMG} .
|
30 | 31 | podman push ${IMG}
|
31 | 32 | ```
|
32 | 33 |
|
33 | 34 | ## Build a custom web application using the gateway
|
34 | 35 |
|
35 |
| -Add you application to the [/web/public](./web/public) directory and create an image. |
| 36 | +Add your application to the [/web/public](./web/public) directory and create an image. |
36 | 37 |
|
37 | 38 | ``` bash
|
38 |
| -# For example |
39 |
| - |
40 |
| -# Copy your static web application to the ./web/public/ dirctory |
| 39 | +# For example, copy your static web application to the ./web/public/ directory. |
41 | 40 | cp /dev/my-static-web-app/* ./web/public/
|
42 | 41 |
|
43 |
| -# Create a container image and push it into your container repository |
| 42 | +# Create a container image and push it to your container repository. |
44 | 43 | IMG=quay.io/myapps/custom-gateway:v0.0.1 make image
|
45 | 44 | ```
|
46 | 45 |
|
47 |
| -## Deploy service account, secrets and route ( when using openshift ) |
| 46 | +## Deploy service account, secrets, and route resources (when using OpenShift) |
48 | 47 |
|
49 |
| -The [deploy](/deploy) diretory contains example files to help create and example |
| 48 | +The [deploy](/deploy) directory contains example files to help create an example |
50 | 49 | service account with roles and secrets needed for running the gateway.
|
51 | 50 |
|
52 |
| -Running the gateway requires a service account the grants the gateway access to the k8s resources it |
| 51 | +Running the gateway requires a service account that grants the gateway access to the k8s resources it |
53 | 52 | will proxy to the web application and secrets containing the public and private keys used to sign and
|
54 | 53 | verify the tokens.
|
55 | 54 |
|
56 | 55 | ``` bash
|
57 |
| -# Create a namespace for the gateway and service account, using the deploy examples |
| 56 | +# Create a namespace for the gateway and service account using the deploy examples. |
58 | 57 | # The example files will create a namespace called kube-gateway and a service account granting
|
59 |
| -# cluster reading privileges, when deploying, users are encoraged to use minimalistic privileges |
60 |
| -# when creating service account for the gateway proxy. |
| 58 | +# reading privileges on the cluster. When deploying, users are encouraged to use minimal |
| 59 | +# privileges when creating a service account for the gateway proxy. |
61 | 60 | kubectl create -f deploy/namespace.yaml
|
62 | 61 | kubectl create -f deploy/sa.yaml
|
63 | 62 |
|
64 |
| -# Generate public and private keys (the gateway supports RSA Signature with SHA-256) |
| 63 | +# Generate public and private keys (the gateway supports RSA signatures with SHA-256 hashes) |
65 | 64 | openssl genrsa -out tls.key
|
66 | 65 | openssl req -new -x509 -sha256 -key tls.key -out tls.crt -days 3650 -subj "/C=/ST=/L=/O=/OU=/CN=/emailAddress="
|
67 | 66 |
|
68 |
| -# Create two secrets containing the private and public keys, |
69 |
| -# NOTE: the service account running the gateway does not reqiere access to the private key, |
70 |
| -# the public key must be accessible to the web application. |
| 67 | +# Create two secrets containing the private and public keys. |
| 68 | +# NOTE: The service account running the gateway does not require access to the private key, |
| 69 | +# but the public key must be accessible to the web application. |
71 | 70 | kubectl create secret generic kube-gateway-jwt --from-file=tls.crt -n kube-gateway
|
72 | 71 | kubectl create secret generic kube-gateway-jwt-private --from-file=tls.key -n kube-gateway
|
73 | 72 |
|
74 |
| -# Create a serving sertificats for the gateway TLS server |
75 |
| -# NOTE: on openshift this secret is created automatically, when using openshift |
76 |
| -# no need to create this secret manually |
| 73 | +# Create a serving certificate for the gateway TLS server. |
| 74 | +# NOTE: There is no need to create this secret manually if you are using OpenShift, as it is |
| 75 | +# created automatically in that case. |
77 | 76 | kubectl create secret generic kube-gateway-secrets --from-file=tls.key --from-file=tls.crt -n kube-gateway
|
78 | 77 |
|
79 |
| -# Deploy the gateway in the example namespace using the example service account |
| 78 | +# Deploy the gateway in the example namespace using the example service account. |
80 | 79 | kubectl create -f deploy/kube-gateway.yaml
|
81 | 80 | ```
|
82 | 81 |
|
83 | 82 | ``` bash
|
84 |
| -# NOTE: on openshift, you can deploy the example route |
85 |
| -# make sure to edit the route to match your cluster DNS |
| 83 | +# NOTE: On OpenShift, you can deploy the example route, but make |
| 84 | +# sure to edit the route to match your cluster's DNS. |
86 | 85 | oc create -f deploy/route.yaml
|
87 | 86 | ```
|
88 | 87 |
|
89 | 88 | ``` bash
|
90 |
| -# Check deploymet and secrets |
| 89 | +# Check deployment and secrets. |
91 | 90 | kubectl get secrets -n kube-gateway
|
92 | 91 | kubectl get pods -n kube-gateway
|
93 | 92 | kubectl get svc -n kube-gateway
|
94 | 93 |
|
95 |
| -# On minikube, expose the service using |
96 |
| -#minikube service kube-gateway-svc -n kube-gateway |
| 94 | +# On minikube, expose the service using: |
| 95 | +# minikube service kube-gateway-svc -n kube-gateway |
97 | 96 | ```
|
98 | 97 |
|
99 |
| -## Create a singed token |
| 98 | +## Create a signed token |
100 | 99 |
|
101 |
| -Get the k8s bearer token required to access the secret with the private key. |
| 100 | +Obtain the k8s bearer token required to access the secret with the private key. |
102 | 101 |
|
103 | 102 | ``` bash
|
104 |
| -# Get the token of kube-gateway-sa service account (can read kube-gateway-jwt-private secret) |
| 103 | +# Obtain the token of the kube-gateway-sa service account (can read kube-gateway-jwt-private secret). |
105 | 104 | kubectl get secrets -n kube-gateway -o json | jq '[.items[] | select(.metadata.name | contains("kube-gateway-sa")) | select(.type | contains("service-account-token")) | .data.token][0]' | python -m base64 -d > token
|
106 | 105 | ```
|
107 | 106 |
|
108 | 107 | ``` bash
|
109 |
| -# Create a token payload |
| 108 | +# Create a token payload. |
110 | 109 | # Available fields:
|
111 |
| -# URLs - list of allowed API, a `*` postfix indicate any suffix is allowed |
112 |
| -# duration - the duration to token will be valid (default is `1h`) |
113 |
| -# from - RFC3339 time the token will start to be valid, for example "2016-11-01T20:44:39Z" (default is now) |
114 |
| -# verbs - list of allowed verbs, for example ["get","post"] (default is ["get"]) |
| 110 | +# URLs - The list of allowed APIs, a `*` postfix indicates any suffix is allowed |
| 111 | +# duration - The duration for which the token will be valid (default is `1h`) |
| 112 | +# from - The time the token will start to be valid in RFC3339 format. For example: "2016-11-01T20:44:39Z" (default is now) |
| 113 | +# verbs - The list of allowed verbs. For example: ["get","post"] (default is ["get"]) |
115 | 114 | data='{"URLs":["/api/*","/apis/*"],"duration":"30m"}'
|
116 | 115 | token=$(cat token)
|
117 |
| -proxyurl=https://192.168.39.134:30345 # Use the url of the gateway proxy |
| 116 | +proxyurl=https://192.168.39.134:30345 # Use the URL of the gateway proxy |
118 | 117 |
|
119 |
| -# Sign the token using the secret private key |
| 118 | +# Sign the token using the secret private key. |
120 | 119 | curl -sk -H 'Accept: application/json' -H "Authorization: Bearer ${token}" -H "Content-Type: application/json" --request POST --data "${data}" "${proxyurl}/auth/jwt/request" | jq .Token
|
121 | 120 | ```
|
122 | 121 |
|
123 |
| -## Create a signed link to access specific k8s resource |
| 122 | +## Create a signed link to access specific k8s resources |
124 | 123 |
|
125 |
| -Once a token is signed it can be used to access the k8s API wile it is valid, users can only access URLs specified in the token payload, and only if the |
| 124 | +Once a token is signed it can be used to access the k8s API as long as it remains valid. Users can only access URLs specified in the token payload and only if the |
126 | 125 | gateway service account can access them.
|
127 | 126 |
|
128 |
| -In this example we will use the default noVNC web application |
| 127 | +In this example we will use the default noVNC web application. |
129 | 128 |
|
130 | 129 | ``` bash
|
131 |
| -# The example noVNC application requirs kubevirt to be installed, |
132 |
| -# on minikube install kubevirt using minikube addons, on other platforms install |
133 |
| -# as recomended for that platform. |
134 |
| -#minikube addons enable kubevirt |
| 130 | +# The example noVNC application requires KubeVirt to be installed. |
| 131 | +# On minikube, install KubeVirt using minikube addons. On other platforms, install |
| 132 | +# KubeVirt in the manner recommended for that platform. |
| 133 | +# minikube addons enable kubevirt |
135 | 134 |
|
136 |
| -# Wait for kubevirt to finish install and then |
137 |
| -# start the example virtual machine |
| 135 | +# Wait for KubeVirt to finish installing and then start the example virtual machine. |
138 | 136 | kubectl create -f deploy/vm.yaml
|
139 | 137 |
|
140 |
| -# check the virtual machien is running |
| 138 | +# Check that the virtual machine is running. |
141 | 139 | kubectl get vms -n kube-gateway
|
142 | 140 | ```
|
143 | 141 |
|
144 |
| -Now that the virtual machine is running, we can create a signed link to kubevirt noVNC server. |
| 142 | +Now that the virtual machine is running, we can create a signed link to the KubeVirt noVNC server. |
145 | 143 |
|
146 | 144 | ``` bash
|
147 |
| -# Copy the service account bearer token into a local file |
| 145 | +# Copy the service account bearer token into a local file. |
148 | 146 | kubectl get secrets -n kube-gateway -o json | jq '[.items[] | select(.metadata.name | contains("kube-gateway-sa")) | select(.type | contains("service-account-token")) | .data.token][0]' | python -m base64 -d > token
|
149 | 147 |
|
150 |
| -# Create a path to the k8s resource |
| 148 | +# Create a path to the k8s resource. |
151 | 149 | path=/apis/subresources.kubevirt.io/v1/namespaces/kube-gateway/virtualmachineinstances/testvm/vnc
|
152 | 150 |
|
153 |
| -# Create a token payload for accessing the API path for 1 hour, starting now |
| 151 | +# Create a token payload for accessing the API path for 1 hour, starting now. |
154 | 152 | data="{\"URLs\":[\"${path}\"],\"duration\":\"1h\"}"
|
155 | 153 | token=$(cat token) # Use a k8s token that can access the private key for signing the JWT
|
156 |
| -proxyurl=https://192.168.39.134:30345 # Use the url of the gateway proxy |
| 154 | +proxyurl=https://192.168.39.134:30345 # Use the URL of the gateway proxy |
157 | 155 |
|
158 |
| -# Use the /auth/jwt/request endpoint to sign the token payload using the private key secret |
159 |
| -# The service account bearer token used in this command must be able to access the secret holding the private key |
| 156 | +# Use the /auth/jwt/request endpoint to sign the token payload using the private key secret. |
| 157 | +# The service account bearer token used in this command must be able to access the secret holding the private key. |
160 | 158 | jwt=$(curl -sk -H 'Accept: application/json' -H "Authorization: Bearer ${token}" -H "Content-Type: application/json" --request POST --data "${data}" "${proxyurl}/auth/jwt/request" | jq .Token)
|
161 | 159 |
|
162 |
| -# Open the link in a browser |
163 |
| -# The link is sined using ${jwt} and will access the k8s API at ${path} |
| 160 | +# Open the link in a browser. |
| 161 | +# The link is signed using ${jwt} and will access the k8s API at ${path}. |
164 | 162 | signed_link="${proxyurl}/auth/jwt/set?token=${jwt}&then=/noVNC/vnc_lite.html?path=k8s${path}"
|
165 | 163 |
|
166 | 164 | google-chrome "${signed_link}"
|
167 | 165 | ```
|
168 | 166 |
|
169 | 167 | ## Proxy server endpoints
|
170 | 168 |
|
171 |
| -| endpoint | requirs | description |
| 169 | +| Endpoint | Requires | Description |
172 | 170 | |---|----|---|
|
173 | 171 | | / | | web application static files |
|
174 | 172 | | /auth/jwt/set | | endpoint for setting session JWT cookie |
|
175 |
| -| /login | ([/web/public/login](/web/public/login)) | helper page that set the JWT token as a web borwser cookie | |
176 |
| -| /auth/login | flag `-oauth-server-enable` | login path to start OAuth2 authentication process | |
| 173 | +| /login | ([/web/public/login](/web/public/login)) | helper page that sets the JWT token as a web browser cookie | |
| 174 | +| /auth/login | flag `-oauth-server-enable` | login path to start the OAuth2 authentication process | |
177 | 175 | | /auth/callback | flag `-oauth-server-enable` | OAuth2 authentication callback endpoint |
|
178 | 176 | | /auth/jwt/request | flag `-jwt-request-enable` | endpoint for generating JWT access keys |
|
179 | 177 |
|
180 |
| -## Supported JWT Claims |
| 178 | +## Supported JWT claims |
181 | 179 |
|
182 |
| -| Claim | example | description | default | |
| 180 | +| Claim | Example | Description | Default | |
183 | 181 | |---|---|---|---|
|
184 |
| -|URLs | ["/api/v1/pods/*"] | list of allowed API, a `*` postfix indicate any suffix is allowed | |
185 |
| -|duration | "25m" | the duration to token will be valid | "1h" |
186 |
| -|from | "2016-11-01T20:44:39Z" | RFC3339 time the token will start to be valid | now |
| 182 | +|URLs | ["/api/v1/pods/*"] | list of allowed APIs, a `*` postfix indicates any suffix is allowed | |
| 183 | +|duration | "25m" | the duration for which the token will be valid | "1h" |
| 184 | +|from | "2016-11-01T20:44:39Z" | the time at which the token will start to be valid in RFC3339 format | now |
187 | 185 | |verbs | ["get","post"] | list of allowed verbs | ["get"]
|
188 | 186 |
|
189 | 187 | (gopher network image - [egonelbre/gophers](https://github.com/egonelbre/gophers))
|
0 commit comments