Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(capture): add managed storage account support #575

Merged
merged 20 commits into from
Aug 23, 2024
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,13 @@ spec:
volumeMounts:
- name: retina-operator-config
mountPath: /retina/
{{- if .Values.operator.capture.enableManagedStorageAccount }}
- name: etc-kubernetes
mountPath: /etc/kubernetes
- name: cloud-config
mountPath: /etc/kubernetes/cloud-config
readOnly: true
{{- end }}
securityContext:
allowPrivilegeEscalation: false
capabilities:
Expand All @@ -92,7 +99,14 @@ spec:
- name: retina-operator-config
configMap:
name: retina-operator-config

{{- if .Values.operator.capture.enableManagedStorageAccount }}
- name: etc-kubernetes
hostPath:
path: /etc/kubernetes
mainred marked this conversation as resolved.
Show resolved Hide resolved
- name: cloud-config
secret:
secretName: azure-cloud-config
{{- end }}
---
apiVersion: v1
kind: ServiceAccount
Expand Down Expand Up @@ -195,10 +209,21 @@ rules:
- namespaces
- pods
- nodes
verbs:
- get
- list
- apiGroups:
- ""
resources:
- secrets
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- batch
resources:
Expand Down Expand Up @@ -278,4 +303,31 @@ data:
remoteContext: {{ .Values.remoteContext }}
captureDebug: {{ .Values.operator.capture.debug }}
captureJobNumLimit: {{ .Values.operator.capture.jobNumLimit }}
enableManagedStorageAccount: {{ .Values.operator.capture.enableManagedStorageAccount }}
{{- if .Values.operator.capture.enableManagedStorageAccount }}
azureCredentialConfig: /etc/kubernetes/cloud-config/azure.json
{{- end }}
---
{{- if .Values.operator.capture.enableManagedStorageAccount }}
apiVersion: v1
kind: Secret
metadata:
name: azure-cloud-config
namespace: kube-system
type: Opaque
stringData:
azure.json: |-
{
"cloud": "AzurePublicCloud",
"tenantId": "<tenant-id>",
mainred marked this conversation as resolved.
Show resolved Hide resolved
"subscriptionId": "<subscription-id>",
"aadClientId": "<client-id>",
"aadClientSecret": "<client-secret>",
"resourceGroup": "<resource-group-name>",
"location": "<location>",
"useManagedIdentityExtension": false,
"userAssignedIdentityID": "",
"useInstanceMetadata": true,
}
{{- end }}
{{- end }}
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ operator:
installCRDs: true
enableRetinaEndpoint: false
capture:
debug: "true"
debug: true
jobNumLimit: 0
enableManagedStorageAccount: false
resources:
limits:
cpu: 500m
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
130 changes: 130 additions & 0 deletions docs/captures/managed-storage-account.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# Managed Storage Account

## Motivation

Retina Capture helps customers capture network packets on Kuberentes cluster to debug network issues. Before Retina Capture can debug the packets, Retina Capture can store the network packets and the customers need to download the packets from Retina Capture supported locations with tools like Wireshark.

To simplify customers' work to decide where to store the packets and then download the packets to local environment, we propose a managed account solution for customer to help customer manage the lifecycle, security when to the storage account and garbage collection of the storage account. Customers can use managed storage account by default, or specify their own storage account ID and Storage Blob Data Owner or higher privilege should be granted to [AKS managed identity or service principal](https://learn.microsoft.com/en-us/azure/aks/use-managed-identity).

## Detailed Design

### Workflow

![Workflow of Retina Capture without managed storage account](img/capture-managed-storage-account.png "Workflow of Retina Capture without managed storage account")

## Setup

To enable the managed storage account, you need to specify the following configuration in the helm command,

```bash
--set operator.enabled=true \
--set operator.capture.enableManagedStorageAccount=true
```

Internally, `enableManagedStorageAccount` will change the following retina-operator configuration and azure credential config as explained in the following two sections.

### Retina-Operator Configuration

#### enableManagedStorageAccount Configuration

`enableManagedStorageAccount` configuration controls whether to use managed storage account or not.

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: retina-operator-config
namespace: kube-system
data:
... ...
enableManagedStorageAccount: true/false
azureCredentialConfig: /etc/kubernetes/cloud-config/azure.json
```

#### Azure credential configuration

The configuration `azureCredentialConfig` in retina-operator-config indicates the Azure credential file path to talk to azure for the managed resources.

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: retina-operator-config
namespace: kube-system
data:
.. ...
enableManagedStorageAccount: true/false
azureCredentialConfig: /etc/kubernetes/cloud-config/azure.json
```

The volume defined in retina-operator deployment mount the secret containing the authentication information to the container.

```yaml
mainred marked this conversation as resolved.
Show resolved Hide resolved
volumeMounts:
- name: etc-kubernetes
mountPath: /etc/kubernetes
- name: cloud-config
mountPath: /etc/kubernetes/cloud-config
readOnly: true
volumes:
- name: etc-kubernetes
hostPath:
path: /etc/kubernetes
- name: cloud-config
secret:
secretName: azure-cloud-config
```

When default storage account is enabled, a managed storage account will be created under the resource group of the sub both specified in the credential file.
In the case of AKS, the resource group will be MC, or node, resource group, and subscription will be the overlay subscription.

#### Azure credential configuration content

Detailed explanation of the auth configuration can be found [here](https://github.com/kubernetes-sigs/cloud-provider-azure/blob/0556803/pkg/azclient/auth_conf.go).

The service principal or managed identity should have `Storage Blob Data Contributor` role to create user delegation SAS, and at least `Storage Account Contributor` role to manage storage account, container and polices in Azure.

- Managed Identity

```json
{
"cloud": "AzurePublicCloud",
"tenantId": "<tenant-id>",
"subscriptionId": "<subscription-id>",
"aadClientId": "msi",
"aadClientSecret": "msi",
"resourceGroup": "<resource-group-name>", // the resource group where the cluster is deployed in
"location": "<location>", // the location where the cluster is deployed in
"useManagedIdentityExtension": true,
"userAssignedIdentityID": "<managed-identity-client-id>",
}
```

- Service Principal

```json
{
"cloud": "AzurePublicCloud",
"tenantId": "<tenant-id>",
"subscriptionId": "<subscription-id>",
"aadClientId": "<client-id>",
"aadClientSecret": "<client-secret>",
"resourceGroup": "<resource-group-name>", // the resource group where the cluster is deployed in
"location": "<location>", // the location where the cluster is deployed in
"useManagedIdentityExtension": false,
"userAssignedIdentityID": "",
}
```

### Storage Account

The storage account, `retina-uuid`, is created under MC resource group and lifecycle management with 7 expiration days is created by Retina Operator if Capture is enabled. AKS customers can enable Retina Capture by upgrading their clusters after this feature is released.

### Container

A container, `capture`, will be created to store the network artifacts after the storage account is ready. And to protect the packets from being deleted or modified, a [retention policy](https://learn.microsoft.com/en-us/azure/storage/blobs/immutable-storage-overview) with 7 days retention period will be applied on this container.

## Create a Retina Capture

Retina-operator will create a container blob SAS URL with expiry time determined from Capture Duration to make sure blob SAS URL is invaid soon after the Capture is completed.
And Retina-operator will update Capture CR with the blob SAL URL to allow the customer read the URL.
4 changes: 4 additions & 0 deletions docs/captures/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ Available after after [installing Retina](../installation/setup.md) with capture

See [Capture CRD](../CRDs/Capture.md) for more details.

#### Managed Storage Account

To simply the user experience, a managed storage account is configurable when setting up Retina, which can manage the storage account, container and Kubernetes secreting container the blob SAS on behalf the user. Check [managed-storage-account.md] for more details.

#### Example

This example creates a Capture and stores the Capture artifacts into a storage account specified by Blob SAS URL.
Expand Down
18 changes: 14 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ require (
github.com/prometheus/client_golang v1.19.1
github.com/spf13/cobra v1.8.1
go.uber.org/zap v1.27.0
k8s.io/client-go v0.30.1
k8s.io/client-go v0.30.3
sigs.k8s.io/cloud-provider-azure/pkg/azclient v0.0.38
sigs.k8s.io/cloud-provider-azure/pkg/azclient/configloader v0.0.20
)

require (
Expand All @@ -17,6 +19,13 @@ require (
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect
github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.7.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerregistry/armcontainerregistry v1.2.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/keyvault/armkeyvault v1.4.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v4 v4.3.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns v1.2.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets v1.1.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.0.0 // indirect
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
github.com/Azure/go-autorest/autorest v0.11.29 // indirect
Expand Down Expand Up @@ -216,7 +225,7 @@ require (
golang.org/x/crypto v0.25.0 // indirect
golang.org/x/mod v0.19.0 // indirect
golang.org/x/text v0.16.0 // indirect
golang.org/x/time v0.5.0 // indirect
golang.org/x/time v0.6.0 // indirect
golang.org/x/tools v0.23.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect
Expand Down Expand Up @@ -254,8 +263,8 @@ require (
google.golang.org/protobuf v1.34.2
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/api v0.30.1
k8s.io/apimachinery v0.30.1
k8s.io/api v0.30.3
k8s.io/apimachinery v0.30.3
k8s.io/klog/v2 v2.120.1 // indirect
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect
k8s.io/utils v0.0.0-20240102154912-e7106e64919e
Expand All @@ -274,6 +283,7 @@ require (
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/monitor/armmonitor v0.11.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v5 v5.2.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.6.0
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.4.0
github.com/Microsoft/hcsshim v0.12.0-rc.3
github.com/Sytten/logrus-zap-hook v0.1.0
Expand Down
Loading
Loading