Skip to content
This repository was archived by the owner on Aug 12, 2025. It is now read-only.
Merged
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 Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ endif
$(GO) run -mod=vendor vendor/sigs.k8s.io/controller-tools/cmd/controller-gen/main.go all
# patch the particular image tag we will want to deploy
@echo "updating kustomize image patch file for manager resource"
sed -i'' -e 's@PATCH_ME_IMAGE@image: '"$(PATCH_IMAGE_TAG)"'@' ./config/default/manager_image_patch.yaml
sed -i'' -e 's@PATCH_ME_IMAGE@'"$(PATCH_IMAGE_TAG)"'@' ./config/default/manager_image_patch.yaml
# create the manifests
$(KUBECTL) kustomize vendor/sigs.k8s.io/cluster-api/config/default/ > $(PROVIDERYAML)
echo "---" >> $(PROVIDERYAML)
Expand Down
17 changes: 8 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ To use the cluster-api to deploy a Kubernetes cluster to Packet, you need the fo
* A Packet API key
* A Packet project ID
* The `clusterctl` binary from this repository.
* A Kubernetes cluster - the "bootstrap cluster" - that will deploy and manage the cluster on Packet.
* A Kubernetes cluster - the "bootstrap cluster" - that will deploy and manage the cluster on Packet.
* `kubectl` - not absolutely required, but hard to interact with a cluster without it

For the bootstrap cluster, any cluster is just fine for this, including [k3s](https://k3s.io), [k3d](https://github.com/rancher/k3d) and [kind](https://github.com/kubernetes-sigs/kind).
Expand All @@ -34,13 +34,15 @@ To deploy a cluster:
* `CLUSTER_NAME` - The created cluster will have this name. If not set, it will generate one for you.
* `FACILITY` - The Packet facility where you wantto deploy the cluster. If not set, it will default to `ewr1`.
* `SSH_KEY` - The path to an ssh public key to place on all of the machines. If not set, it will use whichever ssh keys are defined for your project.
* `CA_KEY` - The path to a file with the CA private key. If not set, it will generate one for you.
* `CA_CERT` - The path to a file with the CA certificate. If not set, it will generate one for you.
1. Create the config files you need via `./generate-yaml.sh`. This will generate the following files in [out/packet](./out/packet):
* `cluster.yaml`
* `machines.yaml`
* `provider-components.yaml` - note that this file _will_ contain your secrets, specifically `PACKET_API_KEY`, to be loaded into the cluster
* `provider-components.yaml` - note that this file _will_ contain your secrets, specifically `PACKET_API_KEY`, to be loaded into the cluster, and optionally your CA private key, if provided (but not if auto-generated)
* `addons.yaml` - note that this file _will_ contain your secrets, specifically `PACKET_API_KEY`, to be loaded into the cluster
1. If desired, edit the following files:
* `cluster.yaml` - to change parameters or settings, including network CIDRs, and, if desired, your own CA certificate and key
* `cluster.yaml` - to change parameters or settings, including network CIDRs
* `machines.yaml` - to change parameters or settings, including machine types and quantity
1. Run `clusterctl` with the appropriate command.

Expand Down Expand Up @@ -72,7 +74,6 @@ Run `clusterctl create cluster --help` for more options, for example to use an e

If you do not change the generated `yaml` files, it will use defaults. You can look in the `*.yaml.template` files in [cmd/clusterctl/examples/packet/](./cmd/clusterctl/examples/packet/) for details.

* CA key/certificate: leave blank, which will cause the `manager` to create one.
* service CIDR: `172.25.0.0/16`
* pod CIDR: `172.26.0.0/16`
* service domain: `cluster.local`
Expand Down Expand Up @@ -112,7 +113,7 @@ Note that, unlike `clusterctl`, this method will not take care of the following:

The components deployed via the `yaml` files are the following:

* `cluster.yaml` - contains
* `cluster.yaml` - contains
* a single `Cluster` CRD which defines the new cluster to be deployed. Includes cluster-wide definitions, including cidr definitions for services and pods.
* `machines.yaml` - contains
* one or more `Machine` CRDs, which cause the deployment of individual server instance to serve as Kubernetes master or worker nodes.
Expand Down Expand Up @@ -142,9 +143,9 @@ The Packet cluster-api provider follows the standard design for cluster-api. It
The actual machines are deployed using `kubeadm`. The deployment process uses the following process.

1. When a new `Cluster` is created:
* if the `ClusterSpec` does not include a CA key/certificate pair, create one and save it on the `Cluster` object
* if the appropriate `Secret` does not include a CA key/certificate pair, create one and save it in that `Secret`
2. When a new master `Machine` is created:
* retrieve the CA certificate and key from the `Cluster` object
* retrieve the CA certificate and key from the appropriate Kubernetes `Secret`
* launch a new server instance on Packet
* set the `cloud-init` on the instance to run `kubeadm init`, passing it the CA certificate and key
3. When a new worker `Machine` is created:
Expand Down Expand Up @@ -265,5 +266,3 @@ Important notes:
## References

* [kubeadm yaml api](https://godoc.org/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2)


22 changes: 19 additions & 3 deletions cmd/clusterctl/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,20 @@ import (
"github.com/packethost/cluster-api-provider-packet/pkg/cloud/packet"
"github.com/packethost/cluster-api-provider-packet/pkg/cloud/packet/deployer"
"github.com/packethost/cluster-api-provider-packet/pkg/cloud/packet/util"
kclient "k8s.io/client-go/kubernetes"
clientv1 "k8s.io/client-go/kubernetes/typed/core/v1"
"k8s.io/klog"
"sigs.k8s.io/cluster-api/cmd/clusterctl/cmd"
"sigs.k8s.io/cluster-api/pkg/apis/cluster/common"
"sigs.k8s.io/controller-runtime/pkg/client/config"
)

func main() {
var err error
var (
err error
kube *kclient.Clientset
secretsGetter clientv1.SecretsGetter
)

flag.Parse()

Expand All @@ -38,10 +45,19 @@ func main() {
klog.Fatalf("unable to get Packet client: %v", err)
}

cfg, _ := config.GetConfig()
if cfg != nil {
kube, _ = kclient.NewForConfig(cfg)
}
if kube != nil {
secretsGetter = kube.CoreV1()
}

// get a deployer, which is needed at various stages
deployer, err := deployer.New(deployer.Params{
Port: util.ControlPort,
Client: client,
Port: util.ControlPort,
SecretsGetter: secretsGetter,
Client: client,
})
if err != nil {
klog.Fatalf("unable to get deployer: %v", err)
Expand Down
12 changes: 10 additions & 2 deletions cmd/manager/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/packethost/cluster-api-provider-packet/pkg/cloud/packet/actuators/machine/machineconfig"
"github.com/packethost/cluster-api-provider-packet/pkg/cloud/packet/deployer"
"github.com/packethost/cluster-api-provider-packet/pkg/cloud/packet/util"
kclient "k8s.io/client-go/kubernetes"
"k8s.io/klog"
clusterapis "sigs.k8s.io/cluster-api/pkg/apis"
"sigs.k8s.io/cluster-api/pkg/apis/cluster/common"
Expand Down Expand Up @@ -67,6 +68,10 @@ func main() {
if err != nil {
klog.Fatalf(err.Error())
}
kube, err := kclient.NewForConfig(cfg)
if err != nil {
klog.Fatalf(err.Error())
}

// get a packet client
client, err := packet.GetClient()
Expand All @@ -75,8 +80,9 @@ func main() {
}
// get a deployer, which is needed at various stages
deployer, err := deployer.New(deployer.Params{
Client: client,
Port: util.ControlPort,
Client: client,
SecretsGetter: kube.CoreV1(),
Port: util.ControlPort,
})
if err != nil {
klog.Fatalf(err.Error())
Expand All @@ -85,6 +91,7 @@ func main() {
clusterInterface := cs.ClusterV1alpha1()
clusterActuator, err := cluster.NewActuator(cluster.ActuatorParams{
ClustersGetter: clusterInterface,
SecretsGetter: kube.CoreV1(),
Deployer: deployer,
})
if err != nil {
Expand All @@ -100,6 +107,7 @@ func main() {
machineActuator, err := machine.NewActuator(machine.ActuatorParams{
MachinesGetter: clusterInterface,
MachineConfigGetter: getter,
SecretsGetter: kube.CoreV1(),
Client: client,
Deployer: deployer,
})
Expand Down
14 changes: 0 additions & 14 deletions config/crds/packetprovider_v1alpha1_packetclusterproviderspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,6 @@ spec:
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources'
type: string
caKeyPair:
description: CAKeyPair is the key pair for ca certs.
properties:
cert:
description: base64 encoded cert and key
format: byte
type: string
key:
format: byte
type: string
required:
- cert
- key
type: object
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
Expand Down
2 changes: 2 additions & 0 deletions config/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
# Adds namespace to all resources.
# This must match PRECISELY what is in the constant in pkg/cloud/packet/util.CAPPNamespace
namespace: cluster-api-provider-packet-system

# Value of this field is prepended to the
# names of all resources, e.g. a deployment named
# "wordpress" becomes "alices-wordpress".
# Note that it should also match with the prefix (text before '-') of the namespace
# field above.
# This must match PRECISELY what is in the constant in pkg/cloud/packet/util.CAPPPrefix
namePrefix: cluster-api-provider-packet-

bases:
Expand Down
10 changes: 10 additions & 0 deletions config/manager/manager.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,13 @@ stringData:
apiKey: $PACKET_API_KEY
projectID: $PACKET_PROJECT_ID
type: Opaque
---
apiVersion: v1
kind: Secret
metadata:
name: ca-$CLUSTER_NAME
namespace: system
stringData:
key: $CA_KEY
certificate: $CA_CERT
type: Opaque
32 changes: 30 additions & 2 deletions generate-yaml.sh
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@ if [ -z "$PACKET_API_KEY" ]; then
exit 1
fi


mkdir -p ${OUTPUT_DIR}

SSH_KEY=${SSH_KEY:-}
Expand All @@ -141,13 +140,42 @@ else
SSH_KEY=$SSH_PUBLIC_FILE
fi

CA_KEY="${CA_KEY:-}"
CA_CERT="${CA_CERT:-}"
CA_KEY_CONTENT=
CA_CERT_CONTENT=
if [ -z "$CA_KEY" -o -z "$CA_CERT" ]; then
echo "CA key and CA certificate not provided, will generate automatically"
elif [ ! -e "$CA_KEY" ]; then
echo "CA private key file $CA_KEY does not exist" >&2
exit 1
elif [ ! -e "$CA_CERT" ]; then
echo "CA certificate file $CA_CERT does not exist" >&2
exit 1
else
CA_KEY_CONTENT=$(cat $CA_KEY | base64 | tr -d '\r\n')
CA_CERT_CONTENT=$(cat $CA_CERT | base64 | tr -d '\r\n')
fi
# to be sane about the output
if [ -z "$CA_KEY_CONTENT" ]; then
CA_KEY_CONTENT="''"
fi
if [ -z "$CA_CERT_CONTENT" ]; then
CA_CERT_CONTENT="''"
fi



# By default, linux wraps base64 output every 76 cols, so we use 'tr -d' to remove whitespaces.
# Note 'base64 -w0' doesn't work on Mac OS X, which has different flags.
SSH_PUBLIC=$(cat $SSH_KEY | base64 | tr -d '\r\n')

cat $PROVIDER_TEMPLATE_FILE \
| sed -e "s/\$CLUSTER_NAME/$CLUSTER_NAME/" \
| sed -e "s/\$PACKET_PROJECT_ID/$PACKET_PROJECT_ID/" \
| sed -e "s/\$PACKET_API_KEY/$PACKET_API_KEY/" > $PROVIDER_GENERATED_FILE
| sed -e "s/\$PACKET_API_KEY/$PACKET_API_KEY/" \
| sed -e "s/\$CA_KEY/$CA_KEY_CONTENT/" \
| sed -e "s/\$CA_CERT/$CA_CERT_CONTENT/" > $PROVIDER_GENERATED_FILE

cat $MACHINE_TEMPLATE_FILE \
| sed -e "s/\$CLUSTER_NAME/$CLUSTER_NAME/" \
Expand Down
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ require (
go.uber.org/zap v1.10.0 // indirect
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect

k8s.io/api v0.0.0-20190222213804-5cb15d344471
k8s.io/apimachinery v0.0.0-20190703205208-4cfb76a8bf76
k8s.io/client-go v10.0.0+incompatible
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,6 @@ type PacketClusterProviderSpec struct {
metav1.ObjectMeta `json:"metadata,omitempty"`

ProjectID string `json:"projectID"`

// CAKeyPair is the key pair for ca certs.
CAKeyPair KeyPair `json:"caKeyPair,omitempty"`
}

// KeyPair is how operators can supply custom keypairs for kubeadm to use.
type KeyPair struct {
// base64 encoded cert and key
Cert []byte `json:"cert"`
Key []byte `json:"key"`
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,6 @@ func TestStoragePacketClusterProviderSpec(t *testing.T) {
Name: "foo",
Namespace: "default",
},
CAKeyPair: KeyPair{
Key: []byte{10, 20, 30},
Cert: []byte{10, 20, 30},
},
}
g := gomega.NewGomegaWithT(t)

Expand Down
27 changes: 0 additions & 27 deletions pkg/apis/packetprovider/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading