mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-11-03 12:07:54 +00:00
[DOCS] Add how-to guide for containerize plugins (#24537)
Co-authored-by: Yoko Hyakuna <yoko@hashicorp.com>
This commit is contained in:
@@ -0,0 +1,339 @@
|
|||||||
|
---
|
||||||
|
layout: docs
|
||||||
|
page_title: Add a containerized secrets plugin
|
||||||
|
description: >-
|
||||||
|
Add a containerized secrets plugin to your Vault instance.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Add a containerized secrets plugin to Vault
|
||||||
|
|
||||||
|
@include 'alerts/beta.mdx'
|
||||||
|
|
||||||
|
Run your external secrets plugins in containers to increases the isolation
|
||||||
|
between the plugin and Vault.
|
||||||
|
|
||||||
|
## Before you start
|
||||||
|
|
||||||
|
- **Your Vault instance must be running on Linux**.
|
||||||
|
- **Your Vault instance must have local access to the Docker Engine API**.
|
||||||
|
Vault uses the [Docker SDK](https://pkg.go.dev/github.com/docker/docker) to
|
||||||
|
manage containerized plugins.
|
||||||
|
- **You must have [gVisor](https://gvisor.dev/docs/user_guide/install/)
|
||||||
|
installed**. Vault uses `runsc` as the entrypoint to your container runtime.
|
||||||
|
- **If you are using a container runtime other than gVisor, you must have a
|
||||||
|
`runsc`-compatible container runtime installed**.
|
||||||
|
|
||||||
|
## Step 1: Install your container engine
|
||||||
|
|
||||||
|
Install one of the supported container engines:
|
||||||
|
|
||||||
|
- [Docker](https://docs.docker.com/engine/install/)
|
||||||
|
- [Rootless Docker](https://docs.docker.com/engine/security/rootless/)
|
||||||
|
|
||||||
|
## Step 2: Configure your container runtime
|
||||||
|
|
||||||
|
Update your container engine to use `runsc` for Unix sockets between the host
|
||||||
|
and plugin binary.
|
||||||
|
|
||||||
|
<Tabs>
|
||||||
|
|
||||||
|
<Tab heading="Docker">
|
||||||
|
|
||||||
|
1. Add `runsc` to your
|
||||||
|
[Docker daemon configuration](https://docs.docker.com/config/daemon):
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
$ sudo tee PATH_TO_DOCKER_DAEMON_CONFIG_FILE <<EOF
|
||||||
|
{
|
||||||
|
"runtimes": {
|
||||||
|
"runsc": {
|
||||||
|
"path": "PATH_TO_RUNSC_INSTALLATION",
|
||||||
|
"runtimeArgs": [
|
||||||
|
"--host-uds=all"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Restart Docker:
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
$ sudo systemctl reload docker
|
||||||
|
```
|
||||||
|
|
||||||
|
</Tab>
|
||||||
|
|
||||||
|
<Tab heading="Rootless Docker">
|
||||||
|
|
||||||
|
1. Create a configuration directory if it does not exist already:
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
$ mkdir -p ~/.config/docker
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Add `runsc` to your Docker configuration:
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
$ tee ~/.config/docker/daemon.json <<EOF
|
||||||
|
{
|
||||||
|
"runtimes": {
|
||||||
|
"runsc": {
|
||||||
|
"path": "PATH_TO_RUNSC_INSTALLATION",
|
||||||
|
"runtimeArgs": [
|
||||||
|
"--host-uds=all"
|
||||||
|
"--ignore-cgroups"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Restart Docker:
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
$ systemctl --user restart docker
|
||||||
|
```
|
||||||
|
|
||||||
|
</Tab>
|
||||||
|
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
## Step 3: Update the HashiCorp `go-plugin` library
|
||||||
|
|
||||||
|
You must build your plugin locally with v1.5.0+ of the HashiCorp
|
||||||
|
[`go-plugin`](https://github.com/hashicorp/go-plugin) library to ensure the
|
||||||
|
finished binary is compatible with containerization.
|
||||||
|
|
||||||
|
Use `go install` to pull the latest version of the plugin library from the
|
||||||
|
`hashicorp/go-plugin` repo on GitHub:
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
$ go install github.com/hashicorp/go-plugin@latest
|
||||||
|
```
|
||||||
|
|
||||||
|
<Tip title="The Vault SDK includes go-plugin">
|
||||||
|
|
||||||
|
If you build with the Vault SDK, you can update `go-plugin` with `go install`
|
||||||
|
by pulling the latest SDK version from the `hashicorp/vault` repo:
|
||||||
|
|
||||||
|
`go install github.com/hashicorp/vault/sdk@latest`
|
||||||
|
|
||||||
|
</Tip>
|
||||||
|
|
||||||
|
|
||||||
|
## Step 4: Build the plugin container
|
||||||
|
|
||||||
|
Containerized plugins must run as a binary in the finished container and
|
||||||
|
behave the same whether run in a container or as a standalone application:
|
||||||
|
|
||||||
|
1. Build your plugin binary so it runs on Linux.
|
||||||
|
1. Create a container file for your plugin with the compiled binary as the
|
||||||
|
entry-point.
|
||||||
|
1. Build the image with a unique tag.
|
||||||
|
|
||||||
|
For example, to build a containerized version of the built-in key-value (KV)
|
||||||
|
secrets plugin for Docker:
|
||||||
|
|
||||||
|
1. Clone the latest version of the KV secrets plugin from
|
||||||
|
`hashicorp/vault-plugin-secrets-kv`.
|
||||||
|
```shell-session
|
||||||
|
$ git clone https://github.com/hashicorp/vault-plugin-secrets-kv.git
|
||||||
|
```
|
||||||
|
1. Build the Go binary for Linux.
|
||||||
|
```shell-session
|
||||||
|
$ cd vault-plugin-secrets-kv ; CGO_ENABLED=0 GOOS=linux \
|
||||||
|
go build -o kv cmd/vault-plugin-secrets-kv/main.go
|
||||||
|
```
|
||||||
|
1. Create an empty Dockerfile.
|
||||||
|
```shell-session
|
||||||
|
$ touch Dockerfile
|
||||||
|
```
|
||||||
|
1. Update the empty `Dockerfile` with your infrastructure build details and the
|
||||||
|
compiled binary as the entry-point.
|
||||||
|
```Dockerfile
|
||||||
|
FROM gcr.io/distroless/static-debian12
|
||||||
|
COPY kv /bin/kv
|
||||||
|
ENTRYPOINT [ "/bin/kv" ]
|
||||||
|
```
|
||||||
|
1. Build the container image and assign an identifiable tag.
|
||||||
|
```shell-session
|
||||||
|
$ docker build -t hashicorp/vault-plugin-secrets-kv:mycontainer .
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 5: Register the plugin
|
||||||
|
|
||||||
|
Registering a containerized plugin with Vault is similar to registering any
|
||||||
|
other external plugin that is available locally to Vault.
|
||||||
|
|
||||||
|
1. Store the SHA256 of the plugin image:
|
||||||
|
```shell-session
|
||||||
|
$ export SHA256=$(docker images \
|
||||||
|
--no-trunc \
|
||||||
|
--format="{{ .ID }}" \
|
||||||
|
YOUR_PLUGIN_IMAGE_TAG | cut -d: -f2)
|
||||||
|
```
|
||||||
|
For example:
|
||||||
|
|
||||||
|
<CodeBlockConfig hideClipboard>
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
$ export SHA256=$(docker images \
|
||||||
|
--no-trunc \
|
||||||
|
--format="{{ .ID }}" \
|
||||||
|
hashicorp/vault-plugin-secrets-kv:mycontainer | cut -d: -f2)
|
||||||
|
```
|
||||||
|
|
||||||
|
</CodeBlockConfig>
|
||||||
|
|
||||||
|
1. Register the plugin with `vault plugin register` and specify your plugin
|
||||||
|
image with the `oci_image` flag:
|
||||||
|
```shell-session
|
||||||
|
$ vault plugin register \
|
||||||
|
-sha256="${SHA256}" \
|
||||||
|
-oci_image=YOUR_PLUGIN_IMAGE_TAG \
|
||||||
|
NEW_PLUGIN_TYPE NEW_PLUGIN_ID
|
||||||
|
```
|
||||||
|
For example:
|
||||||
|
|
||||||
|
<CodeBlockConfig hideClipboard>
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
$ vault plugin register \
|
||||||
|
-sha256="${SHA256}" \
|
||||||
|
-oci_image=hashicorp/vault-plugin-secrets-kv:mycontainer \
|
||||||
|
secret my-kv-container
|
||||||
|
```
|
||||||
|
|
||||||
|
</CodeBlockConfig>
|
||||||
|
|
||||||
|
1. Enable the new plugin for your Vault instance with `vault secrets enable` and
|
||||||
|
the new plugin ID:
|
||||||
|
```shell-session
|
||||||
|
$ vault secrets enable NEW_PLUGIN_ID
|
||||||
|
```
|
||||||
|
For example:
|
||||||
|
|
||||||
|
<CodeBlockConfig hideClipboard>
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
$ vault secrets enable my-kv-container
|
||||||
|
```
|
||||||
|
|
||||||
|
</CodeBlockConfig>
|
||||||
|
|
||||||
|
|
||||||
|
<Tip title="Customize container behavior with registration flags">
|
||||||
|
|
||||||
|
You can provide additional information about the image entrypoint, command,
|
||||||
|
and environment with the `-command`, `-args`, and `-env` flags for
|
||||||
|
`vault plugin register`.
|
||||||
|
|
||||||
|
</Tip>
|
||||||
|
|
||||||
|
## Step 6: Test your plugin
|
||||||
|
|
||||||
|
Now that the container is registered with Vault, you should be able to interact
|
||||||
|
with it like any other plugin. Try writing then fetching a new secret with your
|
||||||
|
new plugin.
|
||||||
|
|
||||||
|
|
||||||
|
1. Use `vault write` to store a secret with your containerized plugin:
|
||||||
|
```shell-session
|
||||||
|
$ vault write NEW_PLUGIN_ID/SECRET_PATH SECRET_KEY=SECRET_VALUE
|
||||||
|
```
|
||||||
|
For example:
|
||||||
|
|
||||||
|
<CodeBlockConfig hideClipboard>
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
$ vault write my-kv-container/testing subject=containers
|
||||||
|
Success! Data written to: my-kv-container/testing
|
||||||
|
```
|
||||||
|
|
||||||
|
</CodeBlockConfig>
|
||||||
|
|
||||||
|
1. Fetch the secret you just wrote:
|
||||||
|
```shell-session
|
||||||
|
$ vault read NEW_PLUGIN_ID/SECRET_PATH
|
||||||
|
```
|
||||||
|
For example:
|
||||||
|
|
||||||
|
<CodeBlockConfig hideClipboard>
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
$ vault read my-kv-container/testing
|
||||||
|
===== Data =====
|
||||||
|
Key Value
|
||||||
|
--- -----
|
||||||
|
subject containers
|
||||||
|
```
|
||||||
|
|
||||||
|
</CodeBlockConfig>
|
||||||
|
|
||||||
|
## Use alternative runtimes ((#alt-runtimes))
|
||||||
|
|
||||||
|
You can force Vault to use alternative runtimes provided the runtime is
|
||||||
|
installed locally.
|
||||||
|
|
||||||
|
To use an alternative runtime:
|
||||||
|
|
||||||
|
1. Register and name the runtime with `vault plugin runtime register`. For
|
||||||
|
example, to register the default Docker runtime (`runc`) as `docker-rt`:
|
||||||
|
```shell-session
|
||||||
|
$ vault plugin runtime register \
|
||||||
|
-oci_runtime=runc \
|
||||||
|
-type=container docker-rt
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Use the `--runtime` flag during plugin registration to tell Vault what
|
||||||
|
runtime to use:
|
||||||
|
```shell-session
|
||||||
|
$ vault plugin register \
|
||||||
|
-runtime=RUNTIME_NAME \
|
||||||
|
-sha256="${SHA256}" \
|
||||||
|
-oci_image=YOUR_PLUGIN_IMAGE_TAG \
|
||||||
|
NEW_PLUGIN_TYPE NEW_PLUGIN_ID
|
||||||
|
```
|
||||||
|
For example:
|
||||||
|
|
||||||
|
<CodeBlockConfig hideClipboard>
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
$ vault plugin register \
|
||||||
|
-runtime=docker-rt \
|
||||||
|
-sha256="${SHA256}" \
|
||||||
|
-oci_image=hashicorp/vault-plugin-secrets-kv:mycontainer \
|
||||||
|
secret my-kv-container
|
||||||
|
```
|
||||||
|
|
||||||
|
</CodeBlockConfig>
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Invalid backend version error
|
||||||
|
|
||||||
|
If you run into the following error while registering your plugin:
|
||||||
|
|
||||||
|
<CodeBlockConfig hideClipboard>
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
invalid backend version error: 2 errors occurred:
|
||||||
|
* error creating container: Error response from daemon: error while looking up the specified runtime path: exec: " /usr/bin/runsc": stat /usr/bin/runsc: no such file or directory
|
||||||
|
* error creating container: Error response from daemon: error while looking up the specified runtime path: exec: " /usr/bin/runsc": stat /usr/bin/runsc: no such file or directory
|
||||||
|
```
|
||||||
|
|
||||||
|
</CodeBlockConfig>
|
||||||
|
|
||||||
|
it means that Vault cannot find the executable for `runsc`. Confirm the
|
||||||
|
following is true before trying again:
|
||||||
|
|
||||||
|
1. You have gVisor installed locally to Vault.
|
||||||
|
1. The path to `runsc` is correct in you your Docker configuration.
|
||||||
|
1. Vault has permission to run the `runsc` executable.
|
||||||
|
|
||||||
|
If you still get errors when registering a plugin, the recommended workaround is
|
||||||
|
to use the default Docker runtime (`runc`) as an
|
||||||
|
[alternative runtime](#alt-runtimes).
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
---
|
---
|
||||||
layout: docs
|
layout: docs
|
||||||
page_title: Containerized plugins
|
page_title: Containerized plugins overview
|
||||||
description: External Vault plugins can be run in containers.
|
description: Learn about running external Vault plugins in containers.
|
||||||
---
|
---
|
||||||
|
|
||||||
# Containerized plugins
|
# Containerized plugins overview
|
||||||
|
|
||||||
@include 'alerts/beta.mdx'
|
@include 'alerts/beta.mdx'
|
||||||
|
|
||||||
@@ -14,10 +14,17 @@ description: External Vault plugins can be run in containers.
|
|||||||
|
|
||||||
</Note>
|
</Note>
|
||||||
|
|
||||||
By default, external plugins run as subprocesses that share Vault's user and
|
Vault has a wide selection of builtin plugins to support integrating with other
|
||||||
environment variables. Administrators managing Vault instances on Linux can
|
systems. For example, you can use plugins to exchange app identity information
|
||||||
choose to run external plugins in containers. Running plugins in containers
|
with an authentication service to receive a Vault token, or manage database
|
||||||
increases the isolation between plugins, and between plugins and Vault.
|
credentials. You can also register **external** plugins with your Vault instance
|
||||||
|
to extend the capabilities of your Vault server.
|
||||||
|
|
||||||
|
By default, external plugins run as subprocesses that share the user and
|
||||||
|
environment variables of your Vault instance. Administrators managing Vault
|
||||||
|
instances on Linux can choose to run external plugins in containers. Running
|
||||||
|
plugins in containers increases the isolation between individual plugins and
|
||||||
|
between the plugins and Vault.
|
||||||
|
|
||||||
## System requirements
|
## System requirements
|
||||||
|
|
||||||
@@ -1754,7 +1754,10 @@
|
|||||||
"path": "plugins/plugin-management"
|
"path": "plugins/plugin-management"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "Containerized Plugins",
|
"title": "Containerized plugins",
|
||||||
|
"routes": [
|
||||||
|
{
|
||||||
|
"title": "Overview",
|
||||||
"path": "plugins/containerized-plugins",
|
"path": "plugins/containerized-plugins",
|
||||||
"badge": {
|
"badge": {
|
||||||
"text": "BETA",
|
"text": "BETA",
|
||||||
@@ -1762,6 +1765,17 @@
|
|||||||
"color": "highlight"
|
"color": "highlight"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"title": "Add a containerized plugin",
|
||||||
|
"path": "plugins/containerized-plugins/add-a-containerized-plugin",
|
||||||
|
"badge": {
|
||||||
|
"text": "BETA",
|
||||||
|
"type": "outlined",
|
||||||
|
"color": "highlight"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"title": "Integrations Library",
|
"title": "Integrations Library",
|
||||||
"href": "/vault/integrations"
|
"href": "/vault/integrations"
|
||||||
|
|||||||
Reference in New Issue
Block a user