mirror of https://github.com/kubernetes/kops.git
Setup heptio authenticator
This commit is contained in:
parent
ee8252e323
commit
5ce8f9e712
|
@ -32,3 +32,84 @@ spec:
|
|||
rbac: {}
|
||||
```
|
||||
|
||||
## Heptio Authenticator for AWS
|
||||
|
||||
If you want to turn on Heptio Authenticator for AWS, you can add this block
|
||||
to your cluster:
|
||||
|
||||
```
|
||||
authentication:
|
||||
heptio: {}
|
||||
```
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
apiVersion: kops/v1alpha2
|
||||
kind: Cluster
|
||||
metadata:
|
||||
name: cluster.example.com
|
||||
spec:
|
||||
authentication:
|
||||
heptio: {}
|
||||
authorization:
|
||||
rbac: {}
|
||||
```
|
||||
|
||||
Once the cluster is up you will need to create the heptio authenticator
|
||||
config as a config map. (This can also be done when boostrapping a cluster using addons)
|
||||
For more details on heptio authenticator please visit (heptio/authenticator)[https://github.com/heptio/authenticator]
|
||||
Example config:
|
||||
|
||||
```
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
namespace: kube-system
|
||||
name: heptio-authenticator-aws
|
||||
labels:
|
||||
k8s-app: heptio-authenticator-aws
|
||||
data:
|
||||
config.yaml: |
|
||||
# a unique-per-cluster identifier to prevent replay attacks
|
||||
# (good choices are a random token or a domain name that will be unique to your cluster)
|
||||
clusterID: my-dev-cluster.example.com
|
||||
server:
|
||||
# each mapRoles entry maps an IAM role to a username and set of groups
|
||||
# Each username and group can optionally contain template parameters:
|
||||
# 1) "{{AccountID}}" is the 12 digit AWS ID.
|
||||
# 2) "{{SessionName}}" is the role session name.
|
||||
mapRoles:
|
||||
# statically map arn:aws:iam::000000000000:role/KubernetesAdmin to a cluster admin
|
||||
- roleARN: arn:aws:iam::000000000000:role/KubernetesAdmin
|
||||
username: kubernetes-admin
|
||||
groups:
|
||||
- system:masters
|
||||
# map EC2 instances in my "KubernetesNode" role to users like
|
||||
# "aws:000000000000:instance:i-0123456789abcdef0". Only use this if you
|
||||
# trust that the role can only be assumed by EC2 instances. If an IAM user
|
||||
# can assume this role directly (with sts:AssumeRole) they can control
|
||||
# SessionName.
|
||||
- roleARN: arn:aws:iam::000000000000:role/KubernetesNode
|
||||
username: aws:{{AccountID}}:instance:{{SessionName}}
|
||||
groups:
|
||||
- system:bootstrappers
|
||||
- aws:instances
|
||||
# map federated users in my "KubernetesAdmin" role to users like
|
||||
# "admin:alice-example.com". The SessionName is an arbitrary role name
|
||||
# like an e-mail address passed by the identity provider. Note that if this
|
||||
# role is assumed directly by an IAM User (not via federation), the user
|
||||
# can control the SessionName.
|
||||
- roleARN: arn:aws:iam::000000000000:role/KubernetesAdmin
|
||||
username: admin:{{SessionName}}
|
||||
groups:
|
||||
- system:masters
|
||||
# each mapUsers entry maps an IAM role to a static username and set of groups
|
||||
mapUsers:
|
||||
# map user IAM user Alice in 000000000000 to user "alice" in "system:masters"
|
||||
- userARN: arn:aws:iam::000000000000:user/Alice
|
||||
username: alice
|
||||
groups:
|
||||
- system:masters
|
||||
```
|
|
@ -157,6 +157,103 @@ func (b *KubeAPIServerBuilder) writeAuthenticationConfig(c *fi.ModelBuilderConte
|
|||
return nil
|
||||
}
|
||||
|
||||
if b.Cluster.Spec.Authentication.Heptio != nil {
|
||||
id := "heptio-authenticator-aws"
|
||||
b.Cluster.Spec.KubeAPIServer.AuthenticationTokenWebhookConfigFile = fi.String(PathAuthnConfig)
|
||||
|
||||
{
|
||||
caCertificate, err := b.NodeupModelContext.KeyStore.FindCert(fi.CertificateId_CA)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error fetching Heptio Authentication CA certificate from keystore: %v", err)
|
||||
}
|
||||
if caCertificate == nil {
|
||||
return fmt.Errorf("Heptio Authentication CA certificate %q not found", fi.CertificateId_CA)
|
||||
}
|
||||
|
||||
cluster := kubeconfig.KubectlCluster{
|
||||
Server: "https://127.0.0.1:21362/authenticate",
|
||||
}
|
||||
context := kubeconfig.KubectlContext{
|
||||
Cluster: "heptio-authenticator-aws",
|
||||
User: "kube-apiserver",
|
||||
}
|
||||
|
||||
cluster.CertificateAuthorityData, err = caCertificate.AsBytes()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error encoding Heptio Authentication CA certificate: %v", err)
|
||||
}
|
||||
|
||||
config := kubeconfig.KubectlConfig{}
|
||||
config.Clusters = append(config.Clusters, &kubeconfig.KubectlClusterWithName{
|
||||
Name: "heptio-authenticator-aws",
|
||||
Cluster: cluster,
|
||||
})
|
||||
config.Users = append(config.Users, &kubeconfig.KubectlUserWithName{
|
||||
Name: "kube-apiserver",
|
||||
})
|
||||
config.CurrentContext = "webhook"
|
||||
config.Contexts = append(config.Contexts, &kubeconfig.KubectlContextWithName{
|
||||
Name: "webhook",
|
||||
Context: context,
|
||||
})
|
||||
|
||||
manifest, err := kops.ToRawYaml(config)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error marshalling authentication config to yaml: %v", err)
|
||||
}
|
||||
|
||||
c.AddTask(&nodetasks.File{
|
||||
Path: PathAuthnConfig,
|
||||
Contents: fi.NewBytesResource(manifest),
|
||||
Type: nodetasks.FileType_File,
|
||||
})
|
||||
}
|
||||
|
||||
{
|
||||
certificate, err := b.NodeupModelContext.KeyStore.FindCert(id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error fetching %q certificate from keystore: %v", id, err)
|
||||
}
|
||||
if certificate == nil {
|
||||
return fmt.Errorf("certificate %q not found", id)
|
||||
}
|
||||
|
||||
certificateData, err := certificate.AsBytes()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error encoding %q certificate: %v", id, err)
|
||||
}
|
||||
|
||||
c.AddTask(&nodetasks.File{
|
||||
Path: "/srv/kubernetes/heptio-authenticator-aws/cert.pem",
|
||||
Contents: fi.NewBytesResource(certificateData),
|
||||
Type: nodetasks.FileType_File,
|
||||
})
|
||||
}
|
||||
|
||||
{
|
||||
privateKey, err := b.NodeupModelContext.KeyStore.FindPrivateKey(id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error fetching %q private key from keystore: %v", id, err)
|
||||
}
|
||||
if privateKey == nil {
|
||||
return fmt.Errorf("private key %q not found", id)
|
||||
}
|
||||
|
||||
keyData, err := privateKey.AsBytes()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error encoding %q private key: %v", id, err)
|
||||
}
|
||||
|
||||
c.AddTask(&nodetasks.File{
|
||||
Path: "/srv/kubernetes/heptio-authenticator-aws/key.pem",
|
||||
Contents: fi.NewBytesResource(keyData),
|
||||
Type: nodetasks.FileType_File,
|
||||
})
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("Unrecognized authentication config %v", b.Cluster.Spec.Authentication)
|
||||
}
|
||||
|
||||
|
@ -311,7 +408,7 @@ func (b *KubeAPIServerBuilder) buildPod() (*v1.Pod, error) {
|
|||
}
|
||||
|
||||
if b.Cluster.Spec.Authentication != nil {
|
||||
if b.Cluster.Spec.Authentication.Kopeio != nil {
|
||||
if b.Cluster.Spec.Authentication.Kopeio != nil || b.Cluster.Spec.Authentication.Heptio != nil {
|
||||
addHostPathMapping(pod, container, "authn-config", PathAuthnConfig)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -230,15 +230,19 @@ type ExecContainerAction struct {
|
|||
|
||||
type AuthenticationSpec struct {
|
||||
Kopeio *KopeioAuthenticationSpec `json:"kopeio,omitempty"`
|
||||
Heptio *HeptioAuthenticationSpec `json:"heptio,omitempty"`
|
||||
}
|
||||
|
||||
func (s *AuthenticationSpec) IsEmpty() bool {
|
||||
return s.Kopeio == nil
|
||||
return s.Kopeio == nil && s.Heptio == nil
|
||||
}
|
||||
|
||||
type KopeioAuthenticationSpec struct {
|
||||
}
|
||||
|
||||
type HeptioAuthenticationSpec struct {
|
||||
}
|
||||
|
||||
type AuthorizationSpec struct {
|
||||
AlwaysAllow *AlwaysAllowAuthorizationSpec `json:"alwaysAllow,omitempty"`
|
||||
RBAC *RBACAuthorizationSpec `json:"rbac,omitempty"`
|
||||
|
|
|
@ -229,15 +229,19 @@ type ExecContainerAction struct {
|
|||
|
||||
type AuthenticationSpec struct {
|
||||
Kopeio *KopeioAuthenticationSpec `json:"kopeio,omitempty"`
|
||||
Heptio *HeptioAuthenticationSpec `json:"heptio,omitempty"`
|
||||
}
|
||||
|
||||
func (s *AuthenticationSpec) IsEmpty() bool {
|
||||
return s.Kopeio == nil
|
||||
return s.Kopeio == nil && s.Heptio == nil
|
||||
}
|
||||
|
||||
type KopeioAuthenticationSpec struct {
|
||||
}
|
||||
|
||||
type HeptioAuthenticationSpec struct {
|
||||
}
|
||||
|
||||
type AuthorizationSpec struct {
|
||||
AlwaysAllow *AlwaysAllowAuthorizationSpec `json:"alwaysAllow,omitempty"`
|
||||
RBAC *RBACAuthorizationSpec `json:"rbac,omitempty"`
|
||||
|
|
|
@ -230,15 +230,19 @@ type ExecContainerAction struct {
|
|||
|
||||
type AuthenticationSpec struct {
|
||||
Kopeio *KopeioAuthenticationSpec `json:"kopeio,omitempty"`
|
||||
Heptio *HeptioAuthenticationSpec `json:"heptio,omitempty"`
|
||||
}
|
||||
|
||||
func (s *AuthenticationSpec) IsEmpty() bool {
|
||||
return s.Kopeio == nil
|
||||
return s.Kopeio == nil && s.Heptio == nil
|
||||
}
|
||||
|
||||
type KopeioAuthenticationSpec struct {
|
||||
}
|
||||
|
||||
type HeptioAuthenticationSpec struct {
|
||||
}
|
||||
|
||||
type AuthorizationSpec struct {
|
||||
AlwaysAllow *AlwaysAllowAuthorizationSpec `json:"alwaysAllow,omitempty"`
|
||||
RBAC *RBACAuthorizationSpec `json:"rbac,omitempty"`
|
||||
|
|
|
@ -260,6 +260,25 @@ func (b *PKIModelBuilder) Build(c *fi.ModelBuilderContext) error {
|
|||
c.AddTask(t)
|
||||
}
|
||||
|
||||
if b.Cluster.Spec.Authentication != nil {
|
||||
if b.KopsModelContext.Cluster.Spec.Authentication.Heptio != nil {
|
||||
alternateNames := []string{
|
||||
"localhost",
|
||||
"127.0.0.1",
|
||||
}
|
||||
|
||||
t := &fitasks.Keypair{
|
||||
Name: fi.String("heptio-authenticator-aws"),
|
||||
Subject: "cn=heptio-authenticator-aws",
|
||||
Type: "server",
|
||||
AlternateNames: alternateNames,
|
||||
Signer: defaultCA,
|
||||
Format: format,
|
||||
}
|
||||
c.AddTask(t)
|
||||
}
|
||||
}
|
||||
|
||||
// Create auth tokens (though this is deprecated)
|
||||
for _, x := range tokens.GetKubernetesAuthTokens_Deprecated() {
|
||||
t := &fitasks.Secret{Name: fi.String(x), Lifecycle: b.Lifecycle}
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
namespace: kube-system
|
||||
name: heptio-authenticator-aws
|
||||
labels:
|
||||
k8s-app: heptio-authenticator-aws
|
||||
spec:
|
||||
updateStrategy:
|
||||
type: RollingUpdate
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
scheduler.alpha.kubernetes.io/critical-pod: ""
|
||||
labels:
|
||||
k8s-app: heptio-authenticator-aws
|
||||
spec:
|
||||
# run on the host network (don't depend on CNI)
|
||||
hostNetwork: true
|
||||
|
||||
# run on each master node
|
||||
nodeSelector:
|
||||
node-role.kubernetes.io/master: ""
|
||||
tolerations:
|
||||
- effect: NoSchedule
|
||||
key: node-role.kubernetes.io/master
|
||||
- key: CriticalAddonsOnly
|
||||
operator: Exists
|
||||
|
||||
# run `heptio-authenticator-aws server` with three volumes
|
||||
# - config (mounted from the ConfigMap at /etc/heptio-authenticator-aws/config.yaml)
|
||||
# - state (persisted TLS certificate and keys, mounted from the host)
|
||||
# - output (output kubeconfig to plug into your apiserver configuration, mounted from the host)
|
||||
containers:
|
||||
- name: heptio-authenticator-aws
|
||||
image: gcr.io/heptio-images/authenticator:v0.1.0
|
||||
args:
|
||||
- server
|
||||
- --config=/etc/heptio-authenticator-aws/config.yaml
|
||||
- --state-dir=/var/heptio-authenticator-aws
|
||||
|
||||
resources:
|
||||
requests:
|
||||
memory: 20Mi
|
||||
cpu: 10m
|
||||
limits:
|
||||
memory: 20Mi
|
||||
cpu: 100m
|
||||
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /etc/heptio-authenticator-aws/
|
||||
- name: state
|
||||
mountPath: /var/heptio-authenticator-aws/
|
||||
- name: output
|
||||
mountPath: /etc/kubernetes/heptio-authenticator-aws/
|
||||
|
||||
volumes:
|
||||
- name: config
|
||||
configMap:
|
||||
name: heptio-authenticator-aws
|
||||
- name: output
|
||||
hostPath:
|
||||
path: /srv/kubernetes/heptio-authenticator-aws/
|
||||
- name: state
|
||||
hostPath:
|
||||
path: /srv/kubernetes/heptio-authenticator-aws/
|
|
@ -723,23 +723,44 @@ func (b *BootstrapChannelBuilder) buildManifest() (*channelsapi.Addons, map[stri
|
|||
|
||||
authenticationSelector := map[string]string{"role.kubernetes.io/authentication": "1"}
|
||||
|
||||
if b.cluster.Spec.Authentication != nil && b.cluster.Spec.Authentication.Kopeio != nil {
|
||||
key := "authentication.kope.io"
|
||||
version := "1.0.20171125"
|
||||
if b.cluster.Spec.Authentication != nil {
|
||||
if b.cluster.Spec.Authentication.Kopeio != nil {
|
||||
key := "authentication.kope.io"
|
||||
version := "1.0.20171125"
|
||||
|
||||
{
|
||||
location := key + "/k8s-1.8.yaml"
|
||||
id := "k8s-1.8"
|
||||
{
|
||||
location := key + "/k8s-1.8.yaml"
|
||||
id := "k8s-1.8"
|
||||
|
||||
addons.Spec.Addons = append(addons.Spec.Addons, &channelsapi.AddonSpec{
|
||||
Name: fi.String(key),
|
||||
Version: fi.String(version),
|
||||
Selector: authenticationSelector,
|
||||
Manifest: fi.String(location),
|
||||
KubernetesVersion: ">=1.8.0",
|
||||
Id: id,
|
||||
})
|
||||
manifests[key+"-"+id] = "addons/" + location
|
||||
addons.Spec.Addons = append(addons.Spec.Addons, &channelsapi.AddonSpec{
|
||||
Name: fi.String(key),
|
||||
Version: fi.String(version),
|
||||
Selector: authenticationSelector,
|
||||
Manifest: fi.String(location),
|
||||
KubernetesVersion: ">=1.8.0",
|
||||
Id: id,
|
||||
})
|
||||
manifests[key+"-"+id] = "addons/" + location
|
||||
}
|
||||
}
|
||||
if b.cluster.Spec.Authentication.Heptio != nil {
|
||||
key := "authentication.hept.io"
|
||||
version := "0.1.0"
|
||||
|
||||
{
|
||||
location := key + "/k8s-1.10.yaml"
|
||||
id := "k8s-1.10"
|
||||
|
||||
addons.Spec.Addons = append(addons.Spec.Addons, &channelsapi.AddonSpec{
|
||||
Name: fi.String(key),
|
||||
Version: fi.String(version),
|
||||
Selector: authenticationSelector,
|
||||
Manifest: fi.String(location),
|
||||
KubernetesVersion: ">=1.10.0",
|
||||
Id: id,
|
||||
})
|
||||
manifests[key+"-"+id] = "addons/" + location
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue