Code cleanup and readme

This commit is contained in:
jillianwilson
2021-10-31 20:57:58 -03:00
parent 591b8949cd
commit fe57e68769
4 changed files with 150 additions and 72 deletions

View File

@@ -1,78 +1,125 @@
## Deploy
# 1Password Secrets Injector for Kubernetes
The 1Password Secrets Injector for Kubernetes provides the ability to integrate Kubernetes with 1Password. The 1Password Secrets Injector implements a mutating webhook to inject 1Password secrets as environment variables into a pod or deployment. This differs from the secert creation provided by the 1Password Kubernetes operator in that a Kubernetes Secret will not be created when injecting a secret into your resource.
1. Create namespace `op-secret-injector` in which the 1Password secret injector webhook is deployed:
## Use with the 1Password Kubernetes Operator
The 1Password Secrets Injector for Kubernetes can be used in conjuction with the 1Password Kubernetes Operator in order to provide automatic deployment restarts when a 1Password item being used by your deployment has been updated.
[Click here for more details on the 1Password Kubernetes Operator](operator/README.md)
## Setup and Deployment
The 1Password Secrets Injector for Kubernetes uses a webhook server in order to inject secrets into pods and deployments. Admission to the webhook server is needs to be s secure operation, thus communication with the webhook server requires a TLS certificate signed by a Kubernetes CA.
For a simple setup we suggest using s script by morvencao for [creating a signed cert for the webook](https://github.com/morvencao/kube-mutating-webhook-tutorial/blob/master/deploy/webhook-create-signed-cert.sh). A copy of this script can also be found in this repo [here](secret-injector/deploy/webhook-create-signed-cert.sh).
Run the script with the following:
```
./deploy/webhook-create-signed-cert.sh \
--service <name of webhook service> \
--secret <name of kubernetes secret where certificate will be stored> \
--namespace <your namespace>
```
This will genrate a Kubernetes Secret with your signed certificate.
Next we must set the webhook configuration. An example of this configuration can be found [here](secret-injector/deploy/mutatingwebhook.sh). If you choose to use this example, replace `${CA_BUNDLE}` file's with the value stored for `client-ca-file` in the Kubernetes Secret you generated in the previous step.
```
# kubectl create ns op-secret-injector
apiVersion: admissionregistration.k8s.io/v1beta1
kind: MutatingWebhookConfiguration
metadata:
name: op-secret-injector-webhook-cfg
labels:
app: op-secret-injector
webhooks:
- name: op-secret-injector.morven.me
clientConfig:
service:
name: op-secret-injector-webhook-svc
namespace: op-secret-injector
path: "/inject"
caBundle: ${CA_BUNDLE} //replace this with your own CA Bundle
rules:
- operations: ["CREATE", "UPDATE"]
apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
namespaceSelector:
matchLabels:
op-secret-injection: enabled
```
2. Create a signed cert/key pair and store it in a Kubernetes `secret` that will be consumed by 1Password secret injector deployment:
You can automate this step using the script by [morvencao](https://github.com/morvencao/kube-mutating-webhook-tutorial).
```
# ./deploy/webhook-create-signed-cert.sh \
--service op-secret-injector-webhook-svc \
--secret op-secret-injector-webhook-certs \
--namespace op-secret-injector
```
3. Patch the `MutatingWebhookConfiguration` by set `caBundle` with correct value from Kubernetes cluster:
```
# cat deploy/mutatingwebhook.yaml | \
cat deploy/mutatingwebhook.yaml | \
deploy/webhook-patch-ca-bundle.sh > \
deploy/mutatingwebhook-ca-bundle.yaml
```
4. Deploy resources:
Lastly, we must apply the deployment, service, and mutating webhook configuration to kubernetes:
```
# kubectl create -f deploy/deployment.yaml
# kubectl create -f deploy/service.yaml
# kubectl create -f deploy/mutatingwebhook-ca-bundle.yaml
kubectl create -f deploy/deployment.yaml
kubectl create -f deploy/service.yaml
kubectl create -f deploy/mutatingwebhook-ca-bundle.yaml
```
## Verify
## Usage
1. The sidecar inject webhook should be in running state:
For every namespace you want the 1Password Secret Injector to inject secrets for, you must add the label `sidecar-injector=enabled` label to the namespace:
```
# kubectl -n sidecar-injector get pod
NAME READY STATUS RESTARTS AGE
sidecar-injector-webhook-deployment-7c8bc5f4c9-28c84 1/1 Running 0 30s
# kubectl -n sidecar-injector get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
sidecar-injector-webhook-deployment 1/1 1 1 67s
kubectl label namespace injection sidecar-injection=enabled
```
2. Create new namespace `injection` and label it with `sidecar-injector=enabled`:
To inject a 1Password secret as an environment variable, your pod or deployment you must add an environment variable to the resource with a value referencing your 1Password item in the format `op://<vault>/<item>[/section]/<field>`. You must also annotate your pod/deployment spec with `operator.1password.io/inject` which expects a comma separated list of the names of the containers to that will be mutated and have secrets injected.
```
# kubectl create ns injection
# kubectl label namespace injection sidecar-injection=enabled
# kubectl get namespace -L sidecar-injection
NAME STATUS AGE SIDECAR-INJECTION
default Active 26m
injection Active 13s enabled
kube-public Active 26m
kube-system Active 26m
sidecar-injector Active 17m
#example
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-example
spec:
selector:
matchLabels:
app: app-example
template:
metadata:
annotations:
operator.1password.io/inject: "app-example,another-example"
labels:
app: app-example
spec:
containers:
- name: app-example
image: my-image
env:
- name: DB_USERNAME
value: op://my-vault/my-item/sql/username
- name: DB_PASSWORD
value: op://my-vault/my-item/sql/password
- name: another-example
image: my-image
env:
- name: DB_USERNAME
value: op://my-vault/my-item/sql/username
- name: DB_PASSWORD
value: op://my-vault/my-item/sql/password
- name: my-app //because my-app is not listed in the inject annotaion above the environment values for this container will not be updated with secret values
image: my-image
env:
- name: DB_USERNAME
value: op://my-vault/my-item/sql/username
- name: DB_PASSWORD
value: op://my-vault/my-item/sql/password
```
3. Deploy an app in Kubernetes cluster, take `alpine` app as an example
## Attributions
```
# kubectl run alpine --image=alpine --restart=Never -n injection --overrides='{"apiVersion":"v1","metadata":{"annotations":{"sidecar-injector-webhook.morven.me/inject":"yes"}}}' --command -- sleep infinity
```
4. Verify sidecar container is injected:
```
# kubectl get pod
NAME READY STATUS RESTARTS AGE
alpine 2/2 Running 0 1m
# kubectl -n injection get pod alpine -o jsonpath="{.spec.containers[*].name}"
alpine sidecar-nginx
```
This project is based on and heavily inspired by [morvencao's Kubernetes Mutating Webhook for Sidecar Injection tutorial](https://github.com/morvencao/kube-mutating-webhook-tutorial).
## Troubleshooting