Skip to content
Closed
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

### What works

- Creation of worker nodes on AWS, Digitalocean, Openstack, Azure, Google Cloud Platform, Nutanix, VMWare Cloud Director, VMWare Vsphere, Linode, Hetzner cloud and Kubevirt (experimental)
- Creation of worker nodes on AWS, Digitalocean, Openstack, Azure, Google Cloud Platform, Nutanix, VMWare Cloud Director, VMWare Vsphere, Linode, Hetzner cloud, Kubevirt (technology preview) and Proxmox (technology preview)
- Using Ubuntu, Flatcar or CentOS 7 distributions ([not all distributions work on all providers](/docs/operating-system.md))

### Supported Kubernetes versions
Expand Down
43 changes: 22 additions & 21 deletions docs/operating-system.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,20 @@

### Cloud provider

| | Ubuntu | CentOS | Flatcar | RHEL | SLES | Amazon Linux 2 | Rocky Linux |
|---|---|---|---|---|---|---|---|
| AWS | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Azure | ✓ | ✓ | ✓ | ✓ | x | x | ✓ |
| Digitalocean | ✓ | ✓ | x | x | x | x | ✓ |
| Equinix Metal | ✓ | ✓ | ✓ | x | x | x | ✓ |
| Google Cloud Platform | ✓ | x | x | x | x | x | x |
| Hetzner | ✓ | ✓ | x | x | x | x | ✓ |
| KubeVirt | ✓ | ✓ | ✓ | ✓ | x | x | ✓ |
| Nutanix | ✓ | ✓ | x | x | x | x | x |
| Openstack | ✓ | ✓ | ✓ | ✓ | x | x | ✓ |
| VMware Cloud Director | ✓ | x | x | x | x | x | x |
| VSphere | ✓ | ✓ | ✓ | ✓ | x | x | ✓ |
| | Ubuntu | CentOS | Flatcar | RHEL | SLES | Amazon Linux 2 | Rocky Linux |
| --- | --- | --- | --- | --- | --- | --- | --- |
| AWS | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Azure | ✓ | ✓ | ✓ | ✓ | x | x | ✓ |
| Digitalocean | ✓ | ✓ | x | x | x | x | ✓ |
| Equinix Metal | ✓ | ✓ | ✓ | x | x | x | ✓ |
| Google Cloud Platform | ✓ | x | x | x | x | x | x |
| Hetzner | ✓ | ✓ | x | x | x | x | ✓ |
| KubeVirt | ✓ | ✓ | ✓ | ✓ | x | x | ✓ |
| Nutanix | ✓ | ✓ | x | x | x | x | x |
| Openstack | ✓ | ✓ | ✓ | ✓ | x | x | ✓ |
| Proxmox | ✓ | x | x | x | x | x | x |
| VMware Cloud Director | ✓ | x | x | x | x | x | x |
| VSphere | ✓ | ✓ | ✓ | ✓ | x | x | ✓ |

## Configuring a operating system

Expand All @@ -38,11 +39,11 @@ OS specific settings can be set via `machine.spec.providerConfig.operatingSystem
Note that the table below lists the OS versions that we are validating in our automated tests.
Machine controller may work with other OS versions that are not listed in the table but support won’t be provided.

| | Versions |
|---|---|
| AmazonLinux2 | 2.x |
| CentOS | 7.4.x, 7.6.x, 7.7.x |
| RHEL | 8.x |
| Rocky Linux | 8.5 |
| SLES | SLES 15 SP3 |
| Ubuntu | 20.04 LTS, 22.04 LTS |
| | Versions |
| --- | --- |
| AmazonLinux2 | 2.x |
| CentOS | 7.4.x, 7.6.x, 7.7.x |
| RHEL | 8.x |
| Rocky Linux | 8.5 |
| SLES | SLES 15 SP3 |
| Ubuntu | 20.04 LTS, 22.04 LTS |
94 changes: 94 additions & 0 deletions docs/proxmox.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Proxmox Virtual Environment

## State of the implementation

Support for Proxmox as a provider in the machine-controller is currently just a technical demo. It
is possible to create MachineDeployments using manually created VM templates as demonstrated below.
In this example the VM template is using local storage, which is why this template can only be
cloned on the same node it is located at.

## Prerequisites

### Authentication

For authentication the following data is needed:

- `user_id` is expected to be in the form `USER@REALM!TOKENID`
- `token` is just the UUID you get when initially creating the token

See also:
* https://pve.proxmox.com/wiki/User_Management#pveum_tokens
* https://pve.proxmox.com/wiki/Proxmox_VE_API#API_Tokens

#### User Privileges

For the provider to properly function the user needs an API token with the following privileges:

* `Datastore.AllocateSpace`
* `Pool.Allocate`
* `Pool.Audit`
* `VM.Allocate`
* `VM.Audit`
* `VM.Clone`
* `VM.Config.CDROM`
* `VM.Config.CPU`
* `VM.Config.Cloudinit`
* `VM.Config.Disk`
* `VM.Config.HWType`
* `VM.Config.Memory`
* `VM.Config.Network`
* `VM.Config.Options`
* `VM.Monitor`
* `Sys.Audit`
* `Sys.Console`

### Cloud-init enabled VM Templates

Although it is possible to upload cloud-init images in Proxmox VE and create VM disks directly from
these images via CLI tools on the nodes directly, there is no API endpoint yet to provide this
functionality externally. That's why the `proxmox` provider assumes there are VM templates in place
to clone new machines from.

Proxmox recommends using either ready-to-use cloud-init images provided by many Linux distributions
(mostly designed for OpenStack) or to prepare the images yourself as you have full control over
what's in these images.

For VM templates to be available on all nodes, they need to be added to the `ha-manager`.

Example for creating a VM template:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tiny nitpick: I think a link to the qm tool would be useful. Maybe it could be easily integrated like this

Suggested change
Example for creating a VM template:
Example for creating a VM template using [qm](https://pve.proxmox.com/pve-docs/qm.1.html):

```bash
# Download the cloud-image.
wget https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-amd64.img
INSTANCE_ID=9000
# Create the VM that will be turned into the template.
qm create $INSTANCE_ID -name ubuntu-18.04-LTS
# Import the downloaded cloud-image as disk.
qm importdisk $INSTANCE_ID bionic-server-cloudimg-amd64.img local-lvm
# Set the imported Disk as SCSI drive.
qm set $INSTANCE_ID -scsihw virtio-scsi-pci -scsi0 local-lvm:vm-$INSTANCE_ID-disk-0
# Create the cloud-init drive where the user-data is read from.
qm set $INSTANCE_ID -ide2 local-lvm:cloudinit
# Boot from the imported disk.
qm set $INSTANCE_ID -boot c -bootdisk scsi0
# Set a serial console for better proxmox access.
qm set $INSTANCE_ID -serial0 socket -vga serial0
# Setup bridged network for the VM.
qm set $INSTANCE_ID -net0 virtio,bridge=vmbr0
# Enable QEMU Agent support for this VM (mandatory).
qm set $INSTANCE_ID -agent 1
# Convert VM to tempate.
qm template $INSTANCE_ID
# Make VM template available on any node, not just were it was created.
ha-manager add vm:$INSTANCE_ID -state stopped
```

### Cloud-init user-data

Proxmox currently does not support the upload of "snippets" via API, but these snippets are used for
cloud-init user-data which are required for the machine-controller to function. This provider
implementation needs to copy the generated user-data yaml file via SFTP to every proxmox node where
a VM is created or migrated to. For this to work, make sure that:

* A storage is enabled for content `snippets` (e.g. `local`)
* You have the SSH private key of a user that exists on all nodes which has write permission to the
path where snippets are stored (e.g. `/var/lib/vz/snippets`)
89 changes: 89 additions & 0 deletions examples/proxmox-machinedeployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
apiVersion: v1
kind: Secret
metadata:
# If you change the namespace/name, you must also
# adjust the rbac rules
name: machine-controller-proxmox
namespace: kube-system
type: Opaque
stringData:
token: << PM_API_TOKEN >>
sshPrivateKey: |
-----BEGIN OPENSSH PRIVATE KEY-----
...
-----END OPENSSH PRIVATE KEY-----
---
apiVersion: "cluster.k8s.io/v1alpha1"
kind: MachineDeployment
metadata:
name: proxmox-machinedeployment
namespace: kube-system
spec:
paused: false
replicas: 1
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
minReadySeconds: 0
selector:
matchLabels:
foo: bar
template:
metadata:
labels:
foo: bar
spec:
providerSpec:
value:
sshPublicKeys:
- "<< YOUR_PUBLIC_KEY >>"
cloudProvider: "proxmox"
cloudProviderSpec:
# Can also be set via the env var 'PM_API_ENDPOINT' on the machine-controller
# example: 'https://10.0.1.5/api2/json'
endpoint: '<< PM_API_ENDPOINT >>'
# Can also be set via the env var 'PM_API_USER_ID' on the machine-controller
userID: '<< PM_API_USER_ID >>'
# Can also be set via the env var 'PM_API_TOKEN' on the machine-controller
token:
secretKeyRef:
namespace: kube-system
name: machine-controller-proxmox
key: token
# Optional: Allow insecure connections to endpoint if no valid TLS certificate is
# presented. Can also be set via the env var 'PM_TLS_INSECURE' on the machine-controller
allowInsecure: true
# Optional: Connect through a proxy
# Can also be set via the env var 'PM_PROXY_URL' on the machine-controller
# proxyURL: '<< PM_PROXY_URL >>'
# SSH private key of a user that has write access to local storage on all nodes. this
# is needed to push cloud-init userdata.
ciStorageSSHPrivateKey:
secretKeyRef:
namespace: kube-system
name: machine-controller-proxmox
key: sshPrivateKey
ciStorageName: local
ciStoragePath: /var/lib/vz
# Can also be set via the env
# ID of the VM template
vmTemplateID: 9000
# Sets the CPU count for this VM
cpuSockets: 2
# Sets the CPU cores per CPU
cpuCores: 1
# Memory configuration in MiB
memoryMB: 2048
# Optional: Set up system disk size in GB. If not set, will be based on disk size in vm
# template. Cannot be smaller than the initial disk size in vm template.
diskSizeGB: 20
# Optional: Name of the disk used in the vm template.
diskName: scsi0
operatingSystem: "ubuntu"
operatingSystemSpec:
distUpgradeOnBoot: false
disableAutoUpdate: true
versions:
kubelet: 1.22.5
4 changes: 4 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ require (
github.com/BurntSushi/toml v1.1.0
github.com/Masterminds/semver/v3 v3.1.1
github.com/Masterminds/sprig/v3 v3.2.2
github.com/Telmate/proxmox-api-go v0.0.0-20220605094644-df18575a84d9
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1645
github.com/aws/aws-sdk-go-v2 v1.16.12
github.com/aws/aws-sdk-go-v2/config v1.17.3
Expand Down Expand Up @@ -61,6 +62,8 @@ require (
sigs.k8s.io/yaml v1.3.0
)

require github.com/pkg/sftp v1.13.5

require (
cloud.google.com/go v0.100.2 // indirect
cloud.google.com/go/compute v1.5.0 // indirect
Expand Down Expand Up @@ -118,6 +121,7 @@ require (
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/kr/fs v0.1.0 // indirect
github.com/kr/pretty v0.3.0 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
Expand Down
5 changes: 5 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbt
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
github.com/Telmate/proxmox-api-go v0.0.0-20220605094644-df18575a84d9 h1:iu4+7XxumrN8tWP1t2PFRMYyTGkCS6Ttg/Y7RFsg8+I=
github.com/Telmate/proxmox-api-go v0.0.0-20220605094644-df18575a84d9/go.mod h1:uHptTDYag2s4dJQWUYP4VczIeUPGGu3BNy4JGm9MSjg=
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
Expand Down Expand Up @@ -616,6 +618,7 @@ github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47e
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
Expand Down Expand Up @@ -793,6 +796,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
github.com/pkg/sftp v1.13.5 h1:a3RLUqkyjYRtBTZJZ1VRrKbN3zhuPLlUc3sphVz81go=
github.com/pkg/sftp v1.13.5/go.mod h1:wHDZ0IZX6JcBYRK1TH9bcVq8G7TLpVHYIGJRFnmPfxg=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
Expand Down
4 changes: 4 additions & 0 deletions pkg/cloudprovider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
"github.com/kubermatic/machine-controller/pkg/cloudprovider/provider/linode"
"github.com/kubermatic/machine-controller/pkg/cloudprovider/provider/nutanix"
"github.com/kubermatic/machine-controller/pkg/cloudprovider/provider/openstack"
"github.com/kubermatic/machine-controller/pkg/cloudprovider/provider/proxmox"
"github.com/kubermatic/machine-controller/pkg/cloudprovider/provider/scaleway"
vcd "github.com/kubermatic/machine-controller/pkg/cloudprovider/provider/vmwareclouddirector"
"github.com/kubermatic/machine-controller/pkg/cloudprovider/provider/vsphere"
Expand Down Expand Up @@ -105,6 +106,9 @@ var (
providerconfigtypes.CloudProviderNutanix: func(cvr *providerconfig.ConfigVarResolver) cloudprovidertypes.Provider {
return nutanix.New(cvr)
},
providerconfigtypes.CloudProviderProxmox: func(cvr *providerconfig.ConfigVarResolver) cloudprovidertypes.Provider {
return proxmox.New(cvr)
},
providerconfigtypes.CloudProviderVMwareCloudDirector: func(cvr *providerconfig.ConfigVarResolver) cloudprovidertypes.Provider {
return vcd.New(cvr)
},
Expand Down
Loading