Skip to content

Commit

Permalink
Create controller CA ConfigMap in the controller deployement Namespace
Browse files Browse the repository at this point in the history
Stop using the fixed "kube-system" Namespace for the CA ConfigMap.
Also update the deployment YAML and docs/securing-control-plane.md
about the descriptions about CA ConfigMap and TLS Secret Namespace.

Fixes: antrea-io#876
  • Loading branch information
jianjuns committed Jun 27, 2020
1 parent aafd76e commit 2ba4d41
Show file tree
Hide file tree
Showing 14 changed files with 114 additions and 65 deletions.
10 changes: 6 additions & 4 deletions build/yamls/antrea-eks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -428,17 +428,19 @@ data:
#enablePrometheusMetrics: false
# Indicates whether to use auto-generated self-signed TLS certificate.
# If false, A secret named "kube-system/antrea-controller-tls" must be provided with the following keys:
# If false, A Secret named "antrea-controller-tls" must be provided with the following keys:
# ca.crt: <CA certificate>
# tls.crt: <TLS certificate>
# tls.key: <TLS private key>
# And the Secret must be mounted to directory "/var/run/antrea/antrea-controller-tls" of the
# antrea-controller container.
#selfSignedCert: true
kind: ConfigMap
metadata:
annotations: {}
labels:
app: antrea
name: antrea-config-2k49hdb86m
name: antrea-config-mhkht6fm48
namespace: kube-system
---
apiVersion: v1
Expand Down Expand Up @@ -543,7 +545,7 @@ spec:
key: node-role.kubernetes.io/master
volumes:
- configMap:
name: antrea-config-2k49hdb86m
name: antrea-config-mhkht6fm48
name: antrea-config
- name: antrea-controller-tls
secret:
Expand Down Expand Up @@ -757,7 +759,7 @@ spec:
operator: Exists
volumes:
- configMap:
name: antrea-config-2k49hdb86m
name: antrea-config-mhkht6fm48
name: antrea-config
- hostPath:
path: /etc/cni/net.d
Expand Down
10 changes: 6 additions & 4 deletions build/yamls/antrea-gke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -428,17 +428,19 @@ data:
#enablePrometheusMetrics: false
# Indicates whether to use auto-generated self-signed TLS certificate.
# If false, A secret named "kube-system/antrea-controller-tls" must be provided with the following keys:
# If false, A Secret named "antrea-controller-tls" must be provided with the following keys:
# ca.crt: <CA certificate>
# tls.crt: <TLS certificate>
# tls.key: <TLS private key>
# And the Secret must be mounted to directory "/var/run/antrea/antrea-controller-tls" of the
# antrea-controller container.
#selfSignedCert: true
kind: ConfigMap
metadata:
annotations: {}
labels:
app: antrea
name: antrea-config-cfhgb2tt48
name: antrea-config-hdtk4g848f
namespace: kube-system
---
apiVersion: v1
Expand Down Expand Up @@ -543,7 +545,7 @@ spec:
key: node-role.kubernetes.io/master
volumes:
- configMap:
name: antrea-config-cfhgb2tt48
name: antrea-config-hdtk4g848f
name: antrea-config
- name: antrea-controller-tls
secret:
Expand Down Expand Up @@ -755,7 +757,7 @@ spec:
operator: Exists
volumes:
- configMap:
name: antrea-config-cfhgb2tt48
name: antrea-config-hdtk4g848f
name: antrea-config
- hostPath:
path: /etc/cni/net.d
Expand Down
10 changes: 6 additions & 4 deletions build/yamls/antrea-ipsec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -428,17 +428,19 @@ data:
#enablePrometheusMetrics: false
# Indicates whether to use auto-generated self-signed TLS certificate.
# If false, A secret named "kube-system/antrea-controller-tls" must be provided with the following keys:
# If false, A Secret named "antrea-controller-tls" must be provided with the following keys:
# ca.crt: <CA certificate>
# tls.crt: <TLS certificate>
# tls.key: <TLS private key>
# And the Secret must be mounted to directory "/var/run/antrea/antrea-controller-tls" of the
# antrea-controller container.
#selfSignedCert: true
kind: ConfigMap
metadata:
annotations: {}
labels:
app: antrea
name: antrea-config-57kg4gbmk6
name: antrea-config-249dk76d72
namespace: kube-system
---
apiVersion: v1
Expand Down Expand Up @@ -552,7 +554,7 @@ spec:
key: node-role.kubernetes.io/master
volumes:
- configMap:
name: antrea-config-57kg4gbmk6
name: antrea-config-249dk76d72
name: antrea-config
- name: antrea-controller-tls
secret:
Expand Down Expand Up @@ -799,7 +801,7 @@ spec:
operator: Exists
volumes:
- configMap:
name: antrea-config-57kg4gbmk6
name: antrea-config-249dk76d72
name: antrea-config
- hostPath:
path: /etc/cni/net.d
Expand Down
10 changes: 6 additions & 4 deletions build/yamls/antrea.yml
Original file line number Diff line number Diff line change
Expand Up @@ -428,17 +428,19 @@ data:
#enablePrometheusMetrics: false
# Indicates whether to use auto-generated self-signed TLS certificate.
# If false, A secret named "kube-system/antrea-controller-tls" must be provided with the following keys:
# If false, A Secret named "antrea-controller-tls" must be provided with the following keys:
# ca.crt: <CA certificate>
# tls.crt: <TLS certificate>
# tls.key: <TLS private key>
# And the Secret must be mounted to directory "/var/run/antrea/antrea-controller-tls" of the
# antrea-controller container.
#selfSignedCert: true
kind: ConfigMap
metadata:
annotations: {}
labels:
app: antrea
name: antrea-config-cd7tt4t2f8
name: antrea-config-km7ch8dckd
namespace: kube-system
---
apiVersion: v1
Expand Down Expand Up @@ -543,7 +545,7 @@ spec:
key: node-role.kubernetes.io/master
volumes:
- configMap:
name: antrea-config-cd7tt4t2f8
name: antrea-config-km7ch8dckd
name: antrea-config
- name: antrea-controller-tls
secret:
Expand Down Expand Up @@ -755,7 +757,7 @@ spec:
operator: Exists
volumes:
- configMap:
name: antrea-config-cd7tt4t2f8
name: antrea-config-km7ch8dckd
name: antrea-config
- hostPath:
path: /etc/cni/net.d
Expand Down
4 changes: 3 additions & 1 deletion build/yamls/base/conf/antrea-controller.conf
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@
#enablePrometheusMetrics: false

# Indicates whether to use auto-generated self-signed TLS certificate.
# If false, A secret named "kube-system/antrea-controller-tls" must be provided with the following keys:
# If false, A Secret named "antrea-controller-tls" must be provided with the following keys:
# ca.crt: <CA certificate>
# tls.crt: <TLS certificate>
# tls.key: <TLS private key>
# And the Secret must be mounted to directory "/var/run/antrea/antrea-controller-tls" of the
# antrea-controller container.
#selfSignedCert: true
4 changes: 3 additions & 1 deletion cmd/antrea-controller/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,12 @@ type ControllerConfig struct {
// Defaults to false.
EnablePrometheusMetrics bool `yaml:"enablePrometheusMetrics,omitempty"`
// Indicates whether to use auto-generated self-signed TLS certificate.
// If false, A secret named "kube-system/antrea-controller-tls" must be provided with the following keys:
// If false, A Secret named "antrea-controller-tls" must be provided with the following keys:
// ca.crt: <CA certificate>
// tls.crt: <TLS certificate>
// tls.key: <TLS private key>
// Defaults to true.
// And the Secret must be mounted to directory "/var/run/antrea/antrea-controller-tls" of the
// antrea-controller container.
SelfSignedCert bool `yaml:"selfSignedCert,omitempty"`
}
4 changes: 3 additions & 1 deletion docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,13 @@ clientConnection:
#apiPort: 10349

# Indicates whether to use auto-generated self-signed TLS certificate.
# If false, A secret named "kube-system/antrea-controller-tls" must be provided with the following keys:
# If false, A Secret named "antrea-controller-tls" must be provided with the following keys:
# ca.crt: <CA certificate>
# tls.crt: <TLS certificate>
# tls.key: <TLS private key>
#selfSignedCert: true
# And the Secret must be mounted to directory "/var/run/antrea/antrea-controller-tls" of the
# antrea-controller container.
```

## CNI configuration
Expand Down
19 changes: 11 additions & 8 deletions docs/securing-control-plane.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,23 @@ for client authentication.
By default, antrea-controller generates a self-signed certificate. You can
override the behavior by [providing your own certificates](#providing-your-own-certificates).
Either way, the antrea-controller will distribute the CA certificate as a
ConfigMap named `antrea-ca` in the `kube-system` Namespace and inject it into
the APIServices resources created by Antrea in order to allow its clients (i.e.
antrea-agent, kube-apiserver) to perform authentication.
ConfigMap named `antrea-ca` in the Antrea deployment Namespace and inject it
into the APIServices resources created by Antrea in order to allow its clients
(i.e. antrea-agent, kube-apiserver) to perform authentication.

Typically, clients that wish to access the antrea-controller API can
authenticate the server by validating against the CA certificate published in
the `kube-system/antrea-ca` ConfigMap.
the `antrea-ca` ConfigMap.

## Providing your own certificates

Since Antrea v0.7.0, you can provide your own certificates to Antrea. To do so,
you must set the `selfSignedCert` field of `antrea-controller.conf` to `false`,
so that the antrea-controller will read the certificate key pair from the
`kube-system/antrea-controller-tls` Secret.
`antrea-controller-tls` Secret. The example manifests and descriptions below
assume Antrea is deployed in the `kube-system` Namespace. If you deploy Antrea
in a different Namepace, please update the Namespace name in the manifests
accordingly.

```yaml
apiVersion: v1
Expand Down Expand Up @@ -77,8 +80,8 @@ DNS names:
**Note: It assumes you are using `cluster.local` as the cluster domain, you
should replace it with the actual one of your Kubernetes cluster.**

You can then create the `kube-system/antrea-controller-tls` Secret with the
certificate key pair and the CA certificate in the following form:
You can then create the `antrea-controller-tls` Secret with the certificate key
pair and the CA certificate in the following form:
```yaml
apiVersion: v1
kind: Secret
Expand Down Expand Up @@ -147,7 +150,7 @@ to the antrea-controller Pod if the Pod starts before the Secret is created.**
## Certificate rotation

Antrea v0.7.0 and higher supports certificate rotation. It can be achieved by
simply updating the `kube-system/antrea-controller-tls` Secret. The
simply updating the `antrea-controller-tls` Secret. The
antrea-controller will react to the change, updating its serving certificate and
re-distributing the latest CA certificate (if applicable).

Expand Down
7 changes: 6 additions & 1 deletion pkg/agent/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,12 @@ func NewAntreaClientProvider(config config.ClientConnectionConfiguration, kubeCl
// The key "ca.crt" may not exist at the beginning, no need to fail as the CA provider will watch the ConfigMap
// and notify antreaClientProvider of any update. The consumers of antreaClientProvider are supposed to always
// call GetAntreaClient() to get a client and not cache it.
antreaCAProvider, _ := dynamiccertificates.NewDynamicCAFromConfigMapController("antrea-ca", cert.CAConfigMapNamespace, cert.CAConfigMapName, cert.CAConfigMapKey, kubeClient)
antreaCAProvider, _ := dynamiccertificates.NewDynamicCAFromConfigMapController(
"antrea-ca",
cert.GetCAConfigMapNamespace(),
cert.CAConfigMapName,
cert.CAConfigMapKey,
kubeClient)
antreaClientProvider := &antreaClientProvider{
config: config,
caContentProvider: antreaCAProvider,
Expand Down
30 changes: 23 additions & 7 deletions pkg/apiserver/certificate/cacert_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,23 @@ import (
"k8s.io/client-go/util/workqueue"
"k8s.io/klog"
"k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset"

"github.com/vmware-tanzu/antrea/pkg/util/env"
)

const (
// The namespace and name of the ConfigMap that will hold the CA certificate
// that signs the TLS certificate of antrea-controller.
CAConfigMapNamespace = "kube-system"
CAConfigMapName = "antrea-ca"
CAConfigMapKey = "ca.crt"
// Name of the ConfigMap that will hold the CA certificate that signs the TLS
// certificate of antrea-controller.
CAConfigMapName = "antrea-ca"
CAConfigMapKey = "ca.crt"

defaultCAConfigMapNamespace = "kube-system"
)

var (
// Use the Antrea Pod Namespace for the CA cert ConfigMap.
caConfigMapNamespace = GetCAConfigMapNamespace()

// apiServiceNames contains all the APIServices backed by antrea-controller.
apiServiceNames = []string{
"v1beta1.networking.antrea.tanzu.vmware.com",
Expand All @@ -59,6 +65,16 @@ type CACertController struct {

var _ dynamiccertificates.Listener = &CACertController{}

func GetCAConfigMapNamespace() string {
namespace := env.GetPodNamespace()
if namespace != "" {
return namespace
}

klog.Warningf("Failed to get Pod Namespace from environment. Using \"%s\" as the CA ConfigMap Namespace", defaultCAConfigMapNamespace)
return defaultCAConfigMapNamespace
}

func newCACertController(caContentProvider dynamiccertificates.CAContentProvider,
client kubernetes.Interface,
aggregatorClient clientset.Interface,
Expand Down Expand Up @@ -116,7 +132,7 @@ func (c *CACertController) syncAPIServices(caCert []byte) error {
// syncConfigMap updates the ConfigMap that holds the CA bundle, which will be read by API clients, e.g. antrea-agent.
func (c *CACertController) syncConfigMap(caCert []byte) error {
klog.Info("Syncing CA certificate with ConfigMap")
caConfigMap, err := c.client.CoreV1().ConfigMaps(CAConfigMapNamespace).Get(context.TODO(), CAConfigMapName, v1.GetOptions{})
caConfigMap, err := c.client.CoreV1().ConfigMaps(caConfigMapNamespace).Get(context.TODO(), CAConfigMapName, v1.GetOptions{})
if err != nil {
return fmt.Errorf("error getting ConfigMap %s: %v", CAConfigMapName, err)
}
Expand All @@ -126,7 +142,7 @@ func (c *CACertController) syncConfigMap(caCert []byte) error {
caConfigMap.Data = map[string]string{
CAConfigMapKey: string(caCert),
}
if _, err := c.client.CoreV1().ConfigMaps(CAConfigMapNamespace).Update(context.TODO(), caConfigMap, v1.UpdateOptions{}); err != nil {
if _, err := c.client.CoreV1().ConfigMaps(caConfigMapNamespace).Update(context.TODO(), caConfigMap, v1.UpdateOptions{}); err != nil {
return fmt.Errorf("error updating ConfigMap %s: %v", CAConfigMapName, err)
}
return nil
Expand Down
9 changes: 3 additions & 6 deletions pkg/apiserver/certificate/certificate.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,15 @@ var (
// certReadyTimeout is the timeout we will wait for the TLS Secret being ready. Declaring it as a variable for testing.
certReadyTimeout = 2 * time.Minute
// The DNS names that the TLS certificate will be signed with.
// TODO: Although antrea-agent and kube-aggregator only verify the server name "antrea.kube-system.svc",
// We should add the whole FQDN "antrea.kube-system.svc.<Cluster Domain>" as an alternate DNS name when
// TODO: Although antrea-agent and kube-aggregator only verify the server name "antrea.<Namespace>.svc",
// We should add the whole FQDN "antrea.<Namespace>.svc.<Cluster Domain>" as an alternate DNS name when
// other clients need to access it directly with that name.
AntreaServerNames = []string{
"antrea.kube-system.svc",
}
)

const (
// The namespace and name of the Secret that holds user-provided TLS certificate.
TLSSecretNamespace = "kube-system"
TLSSecretName = "antrea-controller-tls"
// The names of the files that should contain the CA certificate and the TLS key pair.
CACertFile = "ca.crt"
TLSCertFile = "tls.crt"
Expand Down Expand Up @@ -87,7 +84,7 @@ func ApplyServerCert(selfSignedCert bool, client kubernetes.Interface, aggregato
}
return true, nil
}); err != nil {
return nil, fmt.Errorf("error reading TLS certificate and/or key. Please make sure the Secret '%s' is present and has '%s', '%s', and '%s' when selfSignedCert is set to false", TLSSecretName, CACertFile, TLSCertFile, TLSKeyFile)
return nil, fmt.Errorf("error reading TLS certificate and/or key. Please make sure the TLS CA (%s), cert (%s), and key (%s) files are present in \"%s\", when selfSignedCert is set to false", CACertFile, TLSCertFile, TLSKeyFile, certDir)
}
// Since 1.17.0 (https://github.com/kubernetes/kubernetes/commit/3f5fbfbfac281f40c11de2f57d58cc332affc37b),
// apiserver reloads certificate cert and key file from disk every minute, allowing serving tls config to be updated.
Expand Down
Loading

0 comments on commit 2ba4d41

Please sign in to comment.