Skip to content

Commit bdd43c8

Browse files
authored
Merge pull request #39 from sp-yduck/node-image
updates on node images
2 parents 8a87065 + 36dce69 commit bdd43c8

File tree

10 files changed

+269
-74
lines changed

10 files changed

+269
-74
lines changed

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,18 @@ make delete-workload-cluster
6161

6262
- Supports custom cloud-config (user data). CAPPX uses ssh for bootstrapping nodes so it can applies custom cloud-config that can not be achieved by only Proxmox API.
6363

64+
### Node Images
65+
66+
CAPPX is compatible with `qcow2` image. You can build your own node image and use it for `ProxmoxMachine`.
67+
68+
CAPPX relies on a few prerequisites which have to be already installed in the used operating system images, e.g. a container runtime, kubelet, kubeadm,.. .
69+
70+
To build your custom node image, you can use [kubernetes-sigs/image-builder](https://github.com/kubernetes-sigs/image-builder) project.
71+
72+
Also there are some available out-of-box images published other communities such as [Metal3](https://github.com/metal3-io). For example https://artifactory.nordix.org/ui/native/metal3/images/. Example MD can be found [metal3-ubuntu2204-k8s127.yaml](examples/machine_deployment/metal3-ubuntu2204-k8s127.yaml).
73+
74+
If it isn't possible to pre-install those prerequisites in the image, you can always deploy and execute some custom scripts through the `ProxmoxMachine.spec.cloudInit` or `KubeadmConfig.spec.preKubeadmCommands` etc. . Example MD can be found [ubuntu2204.yaml](examples/machine_deployment/ubuntu2204.yaml).
75+
6476
## Compatibility
6577

6678
### Proxmox-VE REST API

api/v1beta1/cloudinit_types.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ type User struct {
1414
ChPasswd ChPasswd `yaml:"chpasswd,omitempty" json:"-"`
1515
Users []string `yaml:"users,omitempty" json:"-"`
1616
Password string `yaml:"password,omitempty" json:"password,omitempty"`
17-
Packages []string `yaml:"packages,omitempty" json:"-"`
17+
Packages []string `yaml:"packages,omitempty" json:"packages,omitempty"`
1818
PackageUpgrade bool `yaml:"package_upgrade,omitempty" json:"-"`
19-
WriteFiles []WriteFiles `yaml:"write_files,omitempty" json:"-"`
20-
RunCmd []string `yaml:"runcmd,omitempty" json:"-"`
19+
WriteFiles []WriteFiles `yaml:"write_files,omitempty" json:"writeFiles,omitempty"`
20+
RunCmd []string `yaml:"runcmd,omitempty" json:"runCmd,omitempty"`
2121
}
2222

2323
type GrowPart struct {
@@ -31,8 +31,8 @@ type ChPasswd struct {
3131
}
3232

3333
type WriteFiles struct {
34-
Path string `yaml:"path,omitempty" json:"-"`
35-
Owner string `yaml:"owner,omitempty" json:"-"`
36-
Permissions string `yaml:"permissions,omitempty" json:"-"`
37-
Content string `yaml:"content,omitempty" json:"-"`
34+
Path string `yaml:"path,omitempty" json:"path,omitempty"`
35+
Owner string `yaml:"owner,omitempty" json:"owner,omitempty"`
36+
Permissions string `yaml:"permissions,omitempty" json:"permissions,omitempty"`
37+
Content string `yaml:"content,omitempty" json:"content,omitempty"`
3838
}

cloud/scope/remote.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ func NewSSHClient(addr, user, password string) (*SSHClient, error) {
2828
return &SSHClient{conn, password}, nil
2929
}
3030

31-
func (conn *SSHClient) RunCommand(cmd string, stdin ...string) (string, error) {
31+
func (conn *SSHClient) RunCommand(cmd string) (string, error) {
3232
session, err := conn.NewSession()
3333
if err != nil {
3434
return "", err

cloud/services/compute/instance/cloudinit.go

Lines changed: 3 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88

99
infrav1 "github.com/sp-yduck/cluster-api-provider-proxmox/api/v1beta1"
1010
"github.com/sp-yduck/cluster-api-provider-proxmox/cloud/cloudinit"
11-
"github.com/sp-yduck/cluster-api-provider-proxmox/cloud/scope"
1211
)
1312

1413
const (
@@ -89,71 +88,10 @@ func userSnippetPath(vmName string) string {
8988
return fmt.Sprintf(userSnippetPathFormat, vmName)
9089
}
9190

92-
// DEPRECATED : cicustom should be set via API
93-
func ApplyCICustom(vmid int, vmName, storageName, ciType string, ssh scope.SSHClient) error {
94-
if !cloudinit.IsValidType(ciType) {
95-
return errors.Errorf("invalid cloud init type: %s", ciType)
96-
}
97-
cicustom := fmt.Sprintf("%s=%s:snippets/%s-%s.yml", ciType, storageName, vmName, ciType)
98-
out, err := ssh.RunCommand(fmt.Sprintf("qm set %d --cicustom '%s'", vmid, cicustom))
99-
if err != nil {
100-
return errors.Errorf("ssh command error : %s : %v", out, err)
101-
}
102-
return nil
103-
}
104-
105-
// to do : remove these cloud-config
10691
func baseUserData(vmName string) *infrav1.User {
10792
return &infrav1.User{
108-
GrowPart: infrav1.GrowPart{Mode: "auto", Devices: []string{"/"}, IgnoreGrowrootDisabled: false},
109-
HostName: vmName,
110-
ManageEtcHosts: true,
111-
ChPasswd: infrav1.ChPasswd{Expire: "False"},
112-
Users: []string{"default"},
113-
Packages: []string{"socat", "conntrack"},
114-
PackageUpgrade: true,
115-
WriteFiles: []infrav1.WriteFiles{
116-
{
117-
Path: "/etc/modules-load.d/k8s.conf",
118-
Owner: "root:root",
119-
Permissions: "0640",
120-
Content: "overlay\nbr_netfilter",
121-
},
122-
{
123-
Path: "/etc/sysctl.d/k8s.conf",
124-
Owner: "root:root",
125-
Permissions: "0640",
126-
Content: `net.bridge.bridge-nf-call-iptables = 1
127-
net.bridge.bridge-nf-call-ip6tables = 1
128-
net.ipv4.ip_forward = 1`,
129-
},
130-
},
131-
RunCmd: []string{
132-
"modprobe overlay",
133-
"modprobe br_netfilter",
134-
"sysctl --system",
135-
`mkdir -p /usr/local/bin`,
136-
`curl -L "https://github.com/containerd/containerd/releases/download/v1.7.2/containerd-1.7.2-linux-amd64.tar.gz" | tar Cxvz "/usr/local"`,
137-
`curl -L "https://raw.githubusercontent.com/containerd/containerd/main/containerd.service" -o /etc/systemd/system/containerd.service`,
138-
"mkdir -p /etc/containerd",
139-
"containerd config default > /etc/containerd/config.toml",
140-
"sed 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml -i",
141-
"systemctl daemon-reload",
142-
"systemctl enable --now containerd",
143-
"mkdir -p /usr/local/sbin",
144-
`curl -L "https://github.com/opencontainers/runc/releases/download/v1.1.7/runc.amd64" -o /usr/local/sbin/runc`,
145-
"chmod 755 /usr/local/sbin/runc",
146-
"mkdir -p /opt/cni/bin",
147-
`curl -L "https://github.com/containernetworking/plugins/releases/download/v1.3.0/cni-plugins-linux-amd64-v1.3.0.tgz" | tar -C "/opt/cni/bin" -xz`,
148-
`curl -L "https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.27.0/crictl-v1.27.0-linux-amd64.tar.gz" | tar -C "/usr/local/bin" -xz`,
149-
`curl -L --remote-name-all https://dl.k8s.io/release/v1.26.5/bin/linux/amd64/kubeadm -o /usr/local/bin/kubeadm`,
150-
`chmod +x /usr/local/bin/kubeadm`,
151-
`curl -L --remote-name-all https://dl.k8s.io/release/v1.26.5/bin/linux/amd64/kubelet -o /usr/local/bin/kubelet`,
152-
`chmod +x /usr/local/bin/kubelet`,
153-
`curl -sSL "https://raw.githubusercontent.com/kubernetes/release/v0.15.1/cmd/kubepkg/templates/latest/deb/kubelet/lib/systemd/system/kubelet.service" | sed "s:/usr/bin:/usr/local/bin:g" | tee /etc/systemd/system/kubelet.service`,
154-
`mkdir -p /etc/systemd/system/kubelet.service.d`,
155-
`curl -sSL "https://raw.githubusercontent.com/kubernetes/release/v0.15.1/cmd/kubepkg/templates/latest/deb/kubeadm/10-kubeadm.conf" | sed "s:/usr/bin:/usr/local/bin:g" | tee /etc/systemd/system/kubelet.service.d/10-kubeadm.conf`,
156-
"systemctl enable kubelet.service",
157-
},
93+
HostName: vmName,
94+
Packages: []string{"qemu-guest-agent"},
95+
RunCmd: []string{"systemctl start qemu-guest-agent"},
15896
}
15997
}

cloud/services/compute/instance/image.go

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"fmt"
66
"path"
7+
"strings"
78

89
"github.com/pkg/errors"
910
"github.com/sp-yduck/proxmox/pkg/service/node/vm"
@@ -53,7 +54,19 @@ func SetCloudImage(ctx context.Context, vmid int, storage infrav1.Storage, image
5354
return errors.Errorf("failed to download image: %s : %v", out, err)
5455
}
5556

56-
// to do: should confirm if the checksum matchies
57+
// checksum
58+
if image.Checksum != "" {
59+
cscmd, err := findValidChecksumCommand(*image.ChecksumType)
60+
if err != nil {
61+
return err
62+
}
63+
cmd := fmt.Sprintf("%s --check -", cscmd)
64+
stdin := fmt.Sprintf("%s %s", image.Checksum, rawImageFilePath)
65+
out, err = ssh.RunWithStdin(cmd, stdin)
66+
if err != nil {
67+
return errors.Errorf("failed to confirm checksum: %s : %v", out, err)
68+
}
69+
}
5770

5871
destPath := fmt.Sprintf("%s/images/%d/vm-%d-disk-0.raw", storage.Path, vmid, vmid)
5972
out, err = ssh.RunCommand(fmt.Sprintf("/usr/bin/qemu-img convert -O raw %s %s", rawImageFilePath, destPath))
@@ -62,3 +75,15 @@ func SetCloudImage(ctx context.Context, vmid int, storage infrav1.Storage, image
6275
}
6376
return nil
6477
}
78+
79+
func findValidChecksumCommand(csType string) (string, error) {
80+
csType = strings.ToLower(csType)
81+
switch csType {
82+
case "sha256", "sha256sum":
83+
return "sha256sum", nil
84+
case "md5", "md5sum":
85+
return "md5sum", nil
86+
default:
87+
return "", errors.Errorf("checksum type %s is not supported", csType)
88+
}
89+
}

config/crd/bases/infrastructure.cluster.x-k8s.io_proxmoxmachines.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,31 @@ spec:
6565
properties:
6666
user:
6767
properties:
68+
packages:
69+
items:
70+
type: string
71+
type: array
6872
password:
6973
type: string
74+
runCmd:
75+
items:
76+
type: string
77+
type: array
7078
user:
7179
type: string
80+
writeFiles:
81+
items:
82+
properties:
83+
content:
84+
type: string
85+
owner:
86+
type: string
87+
path:
88+
type: string
89+
permissions:
90+
type: string
91+
type: object
92+
type: array
7293
type: object
7394
type: object
7495
failureDomain:

config/crd/bases/infrastructure.cluster.x-k8s.io_proxmoxmachinetemplates.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,31 @@ spec:
8989
properties:
9090
user:
9191
properties:
92+
packages:
93+
items:
94+
type: string
95+
type: array
9296
password:
9397
type: string
98+
runCmd:
99+
items:
100+
type: string
101+
type: array
94102
user:
95103
type: string
104+
writeFiles:
105+
items:
106+
properties:
107+
content:
108+
type: string
109+
owner:
110+
type: string
111+
path:
112+
type: string
113+
permissions:
114+
type: string
115+
type: object
116+
type: array
96117
type: object
97118
type: object
98119
failureDomain:
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
apiVersion: cluster.x-k8s.io/v1beta1
2+
kind: MachineDeployment
3+
metadata:
4+
name: ${CLUSTER_NAME}-md-2
5+
spec:
6+
clusterName: ${CLUSTER_NAME}
7+
replicas: 1
8+
selector:
9+
matchLabels: null
10+
template:
11+
spec:
12+
bootstrap:
13+
configRef:
14+
apiVersion: bootstrap.cluster.x-k8s.io/v1beta1
15+
kind: KubeadmConfigTemplate
16+
name: ${CLUSTER_NAME}-md-2
17+
clusterName: ${CLUSTER_NAME}
18+
infrastructureRef:
19+
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
20+
kind: ProxmoxMachineTemplate
21+
name: ${CLUSTER_NAME}-md-2
22+
version: v1.27.1
23+
24+
---
25+
26+
apiVersion: bootstrap.cluster.x-k8s.io/v1beta1
27+
kind: KubeadmConfigTemplate
28+
metadata:
29+
name: ${CLUSTER_NAME}-md-2
30+
spec:
31+
template:
32+
spec: {}
33+
34+
---
35+
36+
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
37+
kind: ProxmoxMachineTemplate
38+
metadata:
39+
name: ${CLUSTER_NAME}-md-2
40+
spec:
41+
template:
42+
spec:
43+
image:
44+
url: https://artifactory.nordix.org/artifactory/metal3/images/k8s_v1.27.1/UBUNTU_22.04_NODE_IMAGE_K8S_v1.27.1.qcow2
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
apiVersion: cluster.x-k8s.io/v1beta1
2+
kind: MachineDeployment
3+
metadata:
4+
name: ${CLUSTER_NAME}-md-1
5+
spec:
6+
clusterName: ${CLUSTER_NAME}
7+
replicas: 1
8+
selector:
9+
matchLabels: null
10+
template:
11+
spec:
12+
bootstrap:
13+
configRef:
14+
apiVersion: bootstrap.cluster.x-k8s.io/v1beta1
15+
kind: KubeadmConfigTemplate
16+
name: ${CLUSTER_NAME}-md-1
17+
clusterName: ${CLUSTER_NAME}
18+
infrastructureRef:
19+
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
20+
kind: ProxmoxMachineTemplate
21+
name: ${CLUSTER_NAME}-md-1
22+
version: v1.26.5
23+
24+
---
25+
26+
apiVersion: bootstrap.cluster.x-k8s.io/v1beta1
27+
kind: KubeadmConfigTemplate
28+
metadata:
29+
name: ${CLUSTER_NAME}-md-1
30+
spec:
31+
template:
32+
spec: {}
33+
34+
---
35+
36+
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
37+
kind: ProxmoxMachineTemplate
38+
metadata:
39+
name: ${CLUSTER_NAME}-md-1
40+
spec:
41+
template:
42+
spec:
43+
image:
44+
url: https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64-disk-kvm.img
45+
checksum: 86e996f35732d26cd8b0888c46c4309d4d3b04eb6980378cf82b4d3eb2796549
46+
checksumType: sha256
47+
cloudInit:
48+
user:
49+
packages:
50+
- socat
51+
- conntrack
52+
writeFiles:
53+
- path: /etc/modules-load.d/k8s.conf
54+
owner: root:root
55+
permissions: "0640"
56+
content: overlay\nbr_netfilter
57+
- path: /etc/sysctl.d/k8s.conf
58+
owner: root:root
59+
permissions: "0640"
60+
content: |
61+
net.bridge.bridge-nf-call-iptables = 1
62+
net.bridge.bridge-nf-call-ip6tables = 1
63+
net.ipv4.ip_forward = 1
64+
runCmd:
65+
- "modprobe overlay"
66+
- "modprobe br_netfilter"
67+
- "sysctl --system"
68+
- "mkdir -p /usr/local/bin"
69+
- curl -L "https://github.com/containerd/containerd/releases/download/v1.7.2/containerd-1.7.2-linux-amd64.tar.gz" | tar Cxvz "/usr/local"
70+
- curl -L "https://raw.githubusercontent.com/containerd/containerd/main/containerd.service" -o /etc/systemd/system/containerd.service
71+
- "mkdir -p /etc/containerd"
72+
- "containerd config default > /etc/containerd/config.toml"
73+
- "sed 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml -i"
74+
- "systemctl daemon-reload"
75+
- "systemctl enable --now containerd"
76+
- "mkdir -p /usr/local/sbin"
77+
- curl -L "https://github.com/opencontainers/runc/releases/download/v1.1.7/runc.amd64" -o /usr/local/sbin/runc
78+
- "chmod 755 /usr/local/sbin/runc"
79+
- "mkdir -p /opt/cni/bin"
80+
- curl -L "https://github.com/containernetworking/plugins/releases/download/v1.3.0/cni-plugins-linux-amd64-v1.3.0.tgz" | tar -C "/opt/cni/bin" -xz
81+
- curl -L "https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.27.0/crictl-v1.27.0-linux-amd64.tar.gz" | tar -C "/usr/local/bin" -xz
82+
- curl -L --remote-name-all https://dl.k8s.io/release/v1.26.5/bin/linux/amd64/kubeadm -o /usr/local/bin/kubeadm
83+
- chmod +x /usr/local/bin/kubeadm
84+
- curl -L --remote-name-all https://dl.k8s.io/release/v1.26.5/bin/linux/amd64/kubelet -o /usr/local/bin/kubelet
85+
- chmod +x /usr/local/bin/kubelet
86+
- curl -sSL "https://raw.githubusercontent.com/kubernetes/release/v0.15.1/cmd/kubepkg/templates/latest/deb/kubelet/lib/systemd/system/kubelet.service" | sed "s:/usr/bin:/usr/local/bin:g" | tee /etc/systemd/system/kubelet.service
87+
- mkdir -p /etc/systemd/system/kubelet.service.d
88+
- curl -sSL "https://raw.githubusercontent.com/kubernetes/release/v0.15.1/cmd/kubepkg/templates/latest/deb/kubeadm/10-kubeadm.conf" | sed "s:/usr/bin:/usr/local/bin:g" | tee /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
89+
- "systemctl enable kubelet.service"

0 commit comments

Comments
 (0)