Skip to content

Commit

Permalink
Merge pull request #55 from Azure/jose/use-available-data
Browse files Browse the repository at this point in the history
config: Use data from config file when available
  • Loading branch information
blanquicet authored Feb 5, 2024
2 parents 0eb3c4d + b31da3d commit 76393e0
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 33 deletions.
28 changes: 14 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ against the cluster nodes, regardless of the control plane's state.
It's important to note that this plugin does not replace the Azure CLI,
[az](https://learn.microsoft.com/en-us/cli/azure/?view=azure-cli-latest).
Instead, it complements it by offering additional commands and providing users
with a kubectl-like experience. In practice, users will use az to create and
delete their AKS cluster, and then use kubectl and kubectl-aks to interact with
and debug it.
with a kubectl-like experience. In practice, users will use `az` to create and
delete their AKS cluster, and then use `kubectl` and `kubectl-aks` to interact
with and debug it.

Going through the following documentation will help you to understand each
available command and which one is the most suitable for your case:
Expand All @@ -21,17 +21,17 @@ available command and which one is the most suitable for your case:
- [check-apiserver-connectivity](docs/check-apiserver-connectivity.md)
- [config](docs/config.md)

Consider `kubectl-aks` expects the cluster to use virtual machine scale sets,
which is the case of an AKS cluster. And, the use of the `--node` flag requires
the Kubernetes control plane to up and running, because the VMSS instance
information of the node will be retrieved from the Kubernetes API server.

However, in case of issues with the Kubernetes control plane, you can reuse the
already stored VMSS instance information, see [config](docs/config.md) command.
Or, if it is a cluster you have never used before on that host, you can retrieve
such information from the [Azure portal](https://portal.azure.com/) and pass it
to the commands using the `--id` flag or separately with the `--subscription`,
`--node-resource-group`, `--vmss` and `--instance-id` flags.
Take into account that `kubectl-aks` expects the cluster to use virtual machine
scale sets, which is the case of an AKS cluster.

You can get the node information needed to execute the commands directly from
the [Azure portal](https://portal.azure.com/) or you can let `kubectl-aks` get
that information for you. If you already have such a information, you can pass
it using the flags or environment variables. If you don't have it, `kubectl-aks`
can retrieve it either from the Azure API or the Kubernetes API server. If you
expect to use the same node multiple times, it is recommended to import the node
information in the configuration file and set it as the default node, see the
[config](docs/config.md) command for further details.

## Install

Expand Down
11 changes: 11 additions & 0 deletions cmd/utils/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,14 @@ func (c *config) CurrentConfig() (*config, bool) {
}
return &config{Viper: c.Sub("nodes." + currentNode)}, true
}

// GetNodeConfig returns the configuration for the given node if it exists
func (c *config) GetNodeConfig(node string) (*config, bool) {
if err := c.ReadInConfig(); err != nil && !errors.Is(err, fs.ErrNotExist) {
return nil, false
}
if v := c.Sub("nodes." + node); v != nil {
return &config{Viper: v}, true
}
return nil, false
}
9 changes: 6 additions & 3 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,11 @@ func addNodeFlags(command *cobra.Command, useFlagsOnly bool) {
)

command.PersistentPreRunE = func(cmd *cobra.Command, args []string) error {
config := config.New()
if !useFlagsOnly {
// If node or resource ID is set, we don't need to read the config file
// nor the environment variables because the CLI flags have precedence.
if !useFlagsOnly && node == "" && resourceID == "" {
config := config.New()

if cc, ok := config.CurrentConfig(); ok {
config = cc
}
Expand All @@ -131,7 +134,7 @@ func addNodeFlags(command *cobra.Command, useFlagsOnly bool) {
resourceID = config.GetString(ResourceIDKey)
}

// validate the config
// validate the parameters
var nodeSet, vmssInfoSet, resourceIDSet bool
if node != "" {
nodeSet = true
Expand Down
23 changes: 19 additions & 4 deletions cmd/utils/vmss.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ import (
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice"
"github.com/Azure/go-autorest/autorest/to"
"github.com/Azure/kubectl-aks/cmd/utils/config"
"github.com/kinvolk/inspektor-gadget/pkg/k8sutil"
"github.com/sirupsen/logrus"
log "github.com/sirupsen/logrus"
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

Expand Down Expand Up @@ -75,10 +76,24 @@ func ParseVMSSResourceID(id string, vm *VirtualMachineScaleSetVM) error {
return nil
}

// VirtualMachineScaleSetVMFromConfig returns a VirtualMachineScaleSetVM object it assumes that the config is set and valid
// VirtualMachineScaleSetVMFromConfig returns a VirtualMachineScaleSetVM object
// it assumes that the config is set and valid
func VirtualMachineScaleSetVMFromConfig() (*VirtualMachineScaleSetVM, error) {
var vm VirtualMachineScaleSetVM
if node != "" {
// Before trying to get the resource ID from the API server, verify if
// the VMSS information of that node is already in the config file.
config := config.New()
if cc, ok := config.GetNodeConfig(node); ok {
log.Debugf("Using VMSS information from config for node %s", node)

vm.SubscriptionID = cc.GetString(SubscriptionIDKey)
vm.NodeResourceGroup = cc.GetString(NodeResourceGroupKey)
vm.VMScaleSet = cc.GetString(VMSSKey)
vm.InstanceID = cc.GetString(VMSSInstanceIDKey)
return &vm, nil
}

var err error
resourceID, err = GetNodeResourceID(context.TODO(), node)
if err != nil {
Expand Down Expand Up @@ -251,8 +266,8 @@ func RunCommand(
signal.Notify(s, os.Interrupt, syscall.SIGTERM)
go func() {
<-s
logrus.Warn("The requested command hasn't finished yet, hit 'Ctrl+C' again to exit anyway.")
logrus.Warn("However, please notice the command will continue running in the node anyway, " +
log.Warn("The requested command hasn't finished yet, hit 'Ctrl+C' again to exit anyway.")
log.Warn("However, please notice the command will continue running in the node anyway, " +
"and you will be unable to see the output or run another command until it finishes.")
<-s
os.Exit(1)
Expand Down
29 changes: 17 additions & 12 deletions docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

We can use the `config` command to configure node information for `kubectl-aks` commands.
This allows ease of switching between different nodes and persisting the configuration. Nodes can be configured
either specifying the `--node` or `--resource-id` or VMSS instance information(`--subscription`, `--node-resource-group`, `--vmss`, `--instance-id`).
All three options are mutually exclusive:
either specifying the `--node` or `--id` or VMSS instance information (`--subscription`, `--node-resource-group`, `--vmss`, `--instance-id`). All three options are mutually exclusive:

```bash
$ kubectl aks config --help
Expand Down Expand Up @@ -31,7 +30,7 @@ As an example, we set a couple of nodes in the configuration (using VMSS instanc

```bash
$ kubectl aks config set-node node1 --subscription mySubID --node-resource-group myRG --vmss myVMSS --instance-id myInstanceID1
$ kubectl aks config set-node node2 --subscription mySubID --node-resource-group myRG --vmss myVMSS --instance-id myInstanceID2
$ kubectl aks config set-node node2 --id "/subscriptions/mySubID/resourceGroups/myRG/providers/Microsoft.Compute/virtualMachineScaleSets/myVMSS/virtualmachines/myInstanceID2"
$ kubectl aks show
nodes:
node1:
Expand All @@ -57,6 +56,12 @@ the `unset-node`/`unset-all`/`unset-current-node` commands.

## Importing configuration

`kubectl-aks` can also import the node information from the Kubernetes API
server or Azure API using the `config import` command. By default, if no flags
are passed, `kubectl-aks` will try to retrieve the node information from the
Kubernetes API server:

```bash
We can also import the node information using the AKS cluster credentials already available in the `kubeconfig` file:

```bash
Expand Down Expand Up @@ -87,16 +92,16 @@ nodes:
$ kubectl aks use-node aks-agentpool-12345678-vmss000000
```

Or in case Kubernetes API is not available, we can also import the node information using Azure API by specifying the cluster information:
If the Kubernetes API server is not available or we can't rely on it for some
reason (e.g. we are investigating connectivity issues between nodes and the API
server), we can use the `--subscription`, `--resource-group` and
`--cluster-name` flags to retrieve the node information from the Azure API:
```bash
$ kubectl aks config import --subscription mySubID --resource-group myRG --cluster-name myCluster
$ kubectl aks config show
kubectl aks config import --subscription mySubID --resource-group myRG --cluster-name myCluster
kubectl aks config show
```
The information is stored with node name as key and VMSS instance information as value to avoid talking to be able
to continue talking with the node, even if the API server is not working correctly.

## Precedence of configuration
Apart from the configuration file, we can also use the flags and environment variables to
Expand All @@ -109,7 +114,7 @@ pass the node information to the commands. The precedence of the configuration i
Using the flags:
```bash
$ kubectl aks check-apiserver-connectivity --node aks-agentpool-77471288-vmss000013
kubectl aks check-apiserver-connectivity --node aks-agentpool-77471288-vmss000013
```
or using the environment variables:
Expand All @@ -119,5 +124,5 @@ or using the environment variables:
- `KUBECTL_AKS_SUBSCRIPTION`, `KUBECTL_AKS_NODE_RESOURCE_GROUP`, `KUBECTL_AKS_VMSS` and `KUBECTL_AKS_INSTANCE_ID`
```bash
$ KUBECTL_AKS_NODE=aks-agentpool-77471288-vmss000013 kubectl aks check-apiserver-connectivity
```
KUBECTL_AKS_NODE=aks-agentpool-77471288-vmss000013 kubectl aks check-apiserver-connectivity
```

0 comments on commit 76393e0

Please sign in to comment.