diff --git a/contributors/design-proposals/bootstrap-discovery.md b/contributors/design-proposals/bootstrap-discovery.md index 11a912e25..a093bbefc 100644 --- a/contributors/design-proposals/bootstrap-discovery.md +++ b/contributors/design-proposals/bootstrap-discovery.md @@ -18,13 +18,13 @@ Similarly, mature organizations will be able to rely on a centrally managed DNS With that in mind, the proposals here will devolve into simply using DNS names that are validated with system installed root certificates. -## Cluster Location information +## Cluster location information (aka ClusterInfo) -First we define a set of information that identifies a cluster and how to talk to it. +First we define a set of information that identifies a cluster and how to talk to it. We will call this ClusterInfo in this document. While we could define a new format for communicating the set of information needed here, we'll start by using the standard [`kubeconfig`](http://kubernetes.io/docs/user-guide/kubeconfig-file/) file format. -It is expected that the `kubeconfig` file will have a single unnamed `Cluster` entry. Other information (especially authentication secrets) must be omitted. +It is expected that the `kubeconfig` file will have a single unnamed `Cluster` entry. Other information (especially authentication secrets) MUST be omitted. ### Evolving kubeconfig @@ -45,7 +45,7 @@ Additions include: **This is to be implemented in a later phase** -Any client of the cluster will want to have this information. As the configuration of the cluster changes we need the client to keep this information up to date. It is assumed that the information here won't drift so fast that clients won't be able to find *some* way to connect. +Any client of the cluster will want to have this information. As the configuration of the cluster changes we need the client to keep this information up to date. The ClusterInfo ConfigMap (defined below) is expected to be a common place to get the latest ClusterInfo for any cluster. Clients should periodically grab this and cache it. It is assumed that the information here won't drift so fast that clients won't be able to find *some* way to connect. In exceptional circumstances it is possible that this information may be out of date and a client would be unable to connect to a cluster. Consider the case where a user has kubectl set up and working well and then doesn't run kubectl for quite a while. It is possible that over this time (a) the set of servers will have migrated so that all endpoints are now invalid or (b) the root certificates will have rotated so that the user can no longer trust any endpoint. @@ -55,31 +55,35 @@ Now that we know *what* we want to get to the client, the question is how. We w ### Method: Out of Band -The simplest way to do this would be to simply put this object in a file and copy it around. This is more overhead for the user, but it is easy to implement and lets users rely on existing systems to distribute configuration. +The simplest way to obtain ClusterInfo this would be to simply put this object in a file and copy it around. This is more overhead for the user, but it is easy to implement and lets users rely on existing systems to distribute configuration. For the `kubeadm` flow, the command line might look like: ``` -kubeadm join --cluster-info-file=my-cluster.yaml +kubeadm join --discovery-file=my-cluster.yaml ``` -Note that TLS bootstrap (which establishes a way for a client to authenticate itself to the server) is a separate issue and has its own set of methods. This command line may have a TLS bootstrap token (or config file) on the command line also. +After loading the ClusterInfo from a file, the client MAY look for updated information from the server by reading the `kube-public` `cluster-info` ConfigMap defined below. However, when retrieving this ConfigMap the client MUST validate the certificate chain when talking to the API server. + +**Note:** TLS bootstrap (which establishes a way for a client to authenticate itself to the server) is a separate issue and has its own set of methods. This command line may have a TLS bootstrap token (or config file) on the command line also. For this reason, even thought the `--discovery-file` argument is in the form of a `kubeconfig`, it MUST NOT contain client credentials as defined above. ### Method: HTTPS Endpoint -If the ClusterInfo information is hosted in a trusted place via HTTPS you can just request it that way. This will use the root certificates that are installed on the system. It may or may not be appropriate based on the user's constraints. +If the ClusterInfo information is hosted in a trusted place via HTTPS you can just request it that way. This will use the root certificates that are installed on the system. It may or may not be appropriate based on the user's constraints. This method MUST use HTTPS. Also, even though the payload for this URL is the `kubeconfig` format, it MUST NOT contain client credentials. ``` -kubeadm join --cluster-info-url="https://example/mycluster.yaml" +kubeadm join --discovery-url="https://example/mycluster.yaml" ``` This is really a shorthand for someone doing something like (assuming we support stdin with `-`): ``` -curl https://example.com/mycluster.json | kubeadm join --cluster-info-file=- +curl https://example.com/mycluster.json | kubeadm join --discovery-file=- ``` -If the user requires some auth to the HTTPS server (to keep the ClusterInfo object private) that can be done in the curl command equivalent. Or we could eventually add it to `kubeadm` directly. +After loading the ClusterInfo from a URL, the client MAY look for updated information from the server by reading the `kube-public` `cluster-info` ConfigMap defined below. However, when retrieving this ConfigMap the client MUST validate the certificate chain when talking to the API server. + +**Note:** support for loading from stdin for `--discovery-file` may not be implemented immediately. ### Method: Bootstrap Token @@ -100,7 +104,7 @@ The user experience for joining a cluster would be something like: kubeadm join --token=ae23dc.faddc87f5a5ab458
``` -**Note:** This is logically a different use of the token from TLS bootstrap. We harmonize these usages and allow the same token to play double duty. +**Note:** This is logically a different use of the token used for authentication for TLS bootstrap. We harmonize these usages and allow the same token to play double duty. #### Implementation Flow @@ -130,6 +134,8 @@ The first part of the token is the `token-id`. The second part is the `token-se This new type of token is different from the current CSV token authenticator that is currently part of Kubernetes. The CSV token authenticator requires an update on disk and a restart of the API server to update/delete tokens. As we prove out this token mechanism we may wish to deprecate and eventually remove that mechanism. +The `token-id` must be 6 characters and the `token-secret` must be 16 characters. They must be lower case ASCII letters and numbers. Specifically it must match the regular expression: `[a-z0-9]{6}\.[a-z0-9]{16}`. There is no strong reasoning behind this beyond the history of how this has been implemented in alpha versions. + #### NEW: Bootstrap Token Secrets Bootstrap tokens are stored and managed via Kubernetes secrets in the `kube-system` namespace. They have type `bootstrap.kubernetes.io/token`. @@ -138,11 +144,13 @@ The following keys are on the secret data: * **token-id**. As defined above. * **token-secret**. As defined above. * **expiration**. After this time the token should be automatically deleted. This is encoded as an absolute UTC time using RFC3339. -* **usage-bootstrap-signing**. Set to `true` to indicate this token should be used for signing bootstrap configs. If omitted or some other string, it defaults to `false`. +* **usage-bootstrap-signing**. Set to `true` to indicate this token should be used for signing bootstrap configs. If this is missing from the token secret or set to any other value, the usage is not allowed. +* **usage-bootstrap-authentication**. Set to true to indicate that this token should be used for authenticating to the API server. If this is missing from the token secret or set to any other value, the usage is not allowed. The bootstrap token authenticagtor will use this token to auth as a user that is `system:bootstrap: