docs/proposals: update kubelet tls bootstrap proposal

pull/6/head
George Tankersley 2016-04-12 12:27:11 -07:00
parent c553c5b575
commit ac1e82c38c
1 changed files with 99 additions and 62 deletions

View File

@ -72,55 +72,80 @@ provisioning script.
We introduce a new API object to represent PKCS#10 certificate signing We introduce a new API object to represent PKCS#10 certificate signing
requests. It will be accessible under: requests. It will be accessible under:
`/api/vX/certificaterequests/mycsr` `/apis/certificates/v1beta1/signingrequests/mycsr`
It will have the following structure: It will have the following structure:
```go ```go
// Describes a certificate signing request // Describes a certificate signing request
type CertificateSigningRequest struct { type CertificateSigningRequest struct {
api.TypeMeta `json:",inline"` api.TypeMeta `json:",inline"`
api.ObjectMeta `json:"metadata,omitempty"` api.ObjectMeta `json:"metadata,omitempty"`
// Specifies the behavior of the CSR // The certificate request itself and any additonal information.
Spec CertificateSigningRequestSpec Spec CertificateSigningRequestSpec `json:"spec,omitempty"`
// Most recently observed status of the CSR // Derived information about the request.
Status CertificateSigningRequestStatus Status CertificateSigningRequestStatus `json:"status,omitempty"`
// The current approval state of the request.
Approve CertificateSigningRequestApproval `json:"approve,omitempty"`
} }
// This information is immutable after the request is created.
type CertificateSigningRequestSpec struct { type CertificateSigningRequestSpec struct {
// Raw PKCS#10 CSR data // Raw PKCS#10 CSR data
CertificateRequest []byte CertificateRequest string `json:"request"`
// Fingerprint of the public key that signed the CSR // Any extra information the node wishes to send with the request.
Fingerprint string ExtraInfo []string `json:"extra,omitempty"`
// Subject fields from the CSR
Subject pkix.Name
// DNS SANs from the CSR
Hostnames []string
// IP SANs from the CSR
IPAddresses []string
// Extra information the node wishes to send with the request
ExtraInfo []string
} }
// This information is derived from the request by Kubernetes and cannot be
// modified by users. All information is optional since it might not be
// available in the underlying request. This is intented to aid approval
// decisions.
type CertificateSigningRequestStatus struct { type CertificateSigningRequestStatus struct {
// Indicates whether CSR has a response yet. Default is Unknown. Status // Information about the requesting user (if relevant)
// is True for approval and False for rejections. // See user.Info interface for details
Status api.ConditionStatus Username string `json:"username,omitempty"`
UID string `json:"uid,omitempty"`
Groups []string `json:"groups,omitempty"`
// If CSR was rejected, these contain the reason why (if any was supplied). // Fingerprint of the public key in request
Reason string Fingerprint string `json:"fingerprint,omitempty"`
Message string
// If CSR was approved, this contains the issued certificate. // Subject fields from the request
Certificate []byte Subject pkix.Name `json:"subject,omitempty"`
// DNS SANs from the request
Hostnames []string `json:"dns,omitempty"`
// IP SANs from the request
IPAddresses []string `json:"ip,omitempty"`
} }
type CertificateSigningRequestApproval struct {
// CSR approval state, one of Submitted, Approved, or Denied
State CertificateRequestState `json:"state"`
// brief reason for the request state
Reason string `json:"reason,omitempty"`
// human readable message with details about the request state
Message string `json:"message,omitempty"`
// If request was approved, the controller will place the issued certificate here.
Certificate []byte `json:"certificate,omitempty"`
}
type CertificateRequestState string
// These are the possible states for a certificate request.
const (
RequestSubmitted CertificateRequestState = "Submitted"
RequestApproved CertificateRequestState = "Approved"
RequestDenied CertificateRequestState = "Denied"
)
``` ```
We also introduce CertificateSigningRequestList to allow listing all the CSRs in the cluster: We also introduce CertificateSigningRequestList to allow listing all the CSRs in the cluster:
@ -141,7 +166,7 @@ type CertificateSigningRequestList struct {
When the kubelet executes it checks a location on disk for TLS assets When the kubelet executes it checks a location on disk for TLS assets
(currently `/var/run/kubernetes/kubelet.{key,crt}` by default). If it finds (currently `/var/run/kubernetes/kubelet.{key,crt}` by default). If it finds
them, it proceeds. If there are no TLS assets, the kubelet generates a keypair them, it proceeds. If there are no TLS assets, the kubelet generates a keypair
and self-signed certificate. We propose the following optional fallback behavior: and self-signed certificate. We propose the following optional behavior:
1. Generate a keypair 1. Generate a keypair
2. Generate a CSR for that keypair with CN set to the hostname (or 2. Generate a CSR for that keypair with CN set to the hostname (or
@ -152,49 +177,60 @@ and self-signed certificate. We propose the following optional fallback behavior
### Controller response ### Controller response
The apiserver must first validate the signature on the raw CSR data and reject The apiserver persists the CertificateSigningRequests and exposes the List of
requests featuring invalid CSRs. It then persists the all CSRs for an administrator to approve or reject.
CertificateSigningRequests and exposes the List of all CSRs for an
administrator to approve or reject. The apiserver should watch for updates the A new certificate controller watches for certificate requests. It must first
Status field of any CertificateSigningRequest. When a CSR is approved validate the signature on each CSR and set `CertificateRequestState=Denied` on
(signified by Status changing from Unknown to True) the apiserver should any requests with invalid signatures. For valid requests, it will set
generate and sign the certificate, then update the `CertificateRequestState=Submitted`. The controller will derive the information
CertificateSigningRequestStatus with the new data. in `CertificateSigningRequestStatus` and update that object. The controller
should watch for updates the approval state of any CertificateSigningRequest.
When a request is approved (signified by CertificateRequestState changing from
Submitted to Approved) the controller should generate and sign a certificate
based on that CSR, then update the approval subresource with the certificate
data.
### Manual CSR approval ### Manual CSR approval
An administrator using `kubectl` or another API client can query the An administrator using `kubectl` or another API client can query the
CertificateSigningRequestList and update the status of CertificateSigningRequestList and update the approval state of
CertificateSigningRequests. The default Status is Unknown, indicating that CertificateSigningRequests. The default state is empty, indicating that there
there has been no decision so far. A Status of True indicates that the admin has been no decision so far. Once a request has passed basic validation it will
has approved the request and the apiserver should issue the certificate. A be "Submitted". A state of "Approved" indicates that the admin has approved the
Status of False indicates that the admin has denied the request. An admin may request and the certificate controller should issue the certificate. A state of
also supply Reason and Message fields to explain the rejection. "Denied" indicates that the admin has denied the request. An admin may also
supply Reason and Message fields to explain the rejection.
## kube-apiserver support (CA assets) ## kube-apiserver support
So that the apiserver can handle certificate issuance on its own, it will need The apiserver will present the new endpoints mentioned above and support the
access to CA signing assets. This could be as simple as a private key and a relevant object types.
config file or as complex as a PKCS#11 client and supplementary policy system.
For now, we will add flags for a signing key, a certificate, and a basic config ## kube-controller-manager support
file.
To handle certificate issuance, the controller-manager will need access to CA
signing assets. This could be as simple as a private key and a config file or
as complex as a PKCS#11 client and supplementary policy system. For now, we
will add flags for a signing key, a certificate, and a basic policy file.
## kubectl support ## kubectl support
To support manual CSR inspection and approval, we will add support for listing, To support manual CSR inspection and approval, we will add support for listing,
inspecting, and approving/rejecting CertificateSigningRequests to kubectl. The inspecting, and approving or denying CertificateSigningRequests to kubectl. The
interface will be similar to interaction will be similar to
[salt-key](https://docs.saltstack.com/en/latest/ref/cli/salt-key.html). [salt-key](https://docs.saltstack.com/en/latest/ref/cli/salt-key.html).
Specifically, the admin will have the ability to retrieve the full list of Specifically, the admin will have the ability to retrieve the full list of
active CSRs, inspect their contents, and set their statuses to one of: pending CSRs, inspect their contents, and set their states to one of:
1. **approved** if the apiserver should issue the cert 1. **Approved** if the controller should issue the cert
2. **rejected** if the apiserver should not issue the cert 2. **Denied** if the controller should not issue the cert
The suggested commands are `kubectl get certificates`, `kubectl approve <csr>` The suggested command for listing is `kubectl get csrs`. The approve/deny
and `kubectl reject <csr>`. For the reject subcommand, the admin will also be interactions can be accomplished with normal updates, but would be more
able to supply Reason and Message fields via additional flags. conveniently accessed by direct subresource updates. We leave this for future
updates to kubectl.
## Security Considerations ## Security Considerations
@ -210,8 +246,9 @@ access to the CSR endpoint.
The node is responsible for monitoring its own certificate expiration date. The node is responsible for monitoring its own certificate expiration date.
When the certificate is close to expiration, the kubelet should begin repeating When the certificate is close to expiration, the kubelet should begin repeating
this flow until it successfully obtains a new certificate. If the expiring this flow until it successfully obtains a new certificate. If the expiring
certificate has not been revoked then it may do so using the same keypair certificate has not been revoked and the previous certificate request is still
unless the cluster policy (see "Future Work") requires fresh keys. approved, then it may do so using the same keypair unless the cluster policy
(see "Future Work") requires fresh keys.
Revocation is for the most part an unhandled problem in Go, requiring each Revocation is for the most part an unhandled problem in Go, requiring each
application to produce its own logic around a variety of parsing functions. For application to produce its own logic around a variety of parsing functions. For