Basic RBAC functionality. (Based from work done by @jwfang (#1351))
* Add a flag "authorization_method", when set to "RBAC" enables role based access control. * Add required cluster roles and bindings for kube-dns * Patch tiller deployment to use a service account with proper credentials. * Add a flag to regenerate kubernetes certs on the nodes.
This commit is contained in:
parent
00e5fc8aa4
commit
c8a2fe321b
19 changed files with 156 additions and 14 deletions
|
@ -67,6 +67,10 @@ following default cluster paramters:
|
||||||
OpenStack (default is unset)
|
OpenStack (default is unset)
|
||||||
* *kube_hostpath_dynamic_provisioner* - Required for use of PetSets type in
|
* *kube_hostpath_dynamic_provisioner* - Required for use of PetSets type in
|
||||||
Kubernetes
|
Kubernetes
|
||||||
|
* *authorization_mode* - Set this to "RBAC" (upper-case, no quotes)
|
||||||
|
[to enable Role Based Access Control](https://kubernetes.io/docs/admin/authorization/rbac/)
|
||||||
|
* *rotate_kubernetes_certs* - Set this to true to regenerate kubernetes Node certificates. *Warning: Will overwrite old certs.*
|
||||||
|
|
||||||
|
|
||||||
Note, if cloud providers have any use of the ``10.233.0.0/16``, like instances'
|
Note, if cloud providers have any use of the ``10.233.0.0/16``, like instances'
|
||||||
private addresses, make sure to pick another values for ``kube_service_addresses``
|
private addresses, make sure to pick another values for ``kube_service_addresses``
|
||||||
|
@ -116,3 +120,4 @@ The possible vars are:
|
||||||
|
|
||||||
Kargo sets up two Kubernetes accounts by default: ``root`` and ``kube``. Their
|
Kargo sets up two Kubernetes accounts by default: ``root`` and ``kube``. Their
|
||||||
passwords default to changeme. You can set this by changing ``kube_api_pwd``.
|
passwords default to changeme. You can set this by changing ``kube_api_pwd``.
|
||||||
|
|
||||||
|
|
|
@ -40,3 +40,11 @@ netchecker_server_memory_requests: 64M
|
||||||
# SSL
|
# SSL
|
||||||
etcd_cert_dir: "/etc/ssl/etcd/ssl"
|
etcd_cert_dir: "/etc/ssl/etcd/ssl"
|
||||||
canal_cert_dir: "/etc/canal/certs"
|
canal_cert_dir: "/etc/canal/certs"
|
||||||
|
|
||||||
|
# RBAC
|
||||||
|
rbac_resources:
|
||||||
|
- clusterrole,
|
||||||
|
- clusterrolebinding,
|
||||||
|
- sa
|
||||||
|
|
||||||
|
rbac_enabled: "{{ authorization_mode == 'RBAC' }}"
|
|
@ -13,12 +13,15 @@
|
||||||
src: "{{item.file}}"
|
src: "{{item.file}}"
|
||||||
dest: "{{kube_config_dir}}/{{item.file}}"
|
dest: "{{kube_config_dir}}/{{item.file}}"
|
||||||
with_items:
|
with_items:
|
||||||
- {name: kube-dns, file: kubedns-serviceaccount.yml, type: serviceaccount}
|
- {name: kubedns, file: kubedns-sa.yml, type: sa}
|
||||||
- {name: kubedns, file: kubedns-deploy.yml, type: deployment}
|
- {name: kubedns, file: kubedns-deploy.yml, type: deployment}
|
||||||
- {name: kubedns, file: kubedns-svc.yml, type: svc}
|
- {name: kubedns, file: kubedns-svc.yml, type: svc}
|
||||||
|
- {name: kubedns-autoscaler, file: kubedns-autoscaler-sa.yml, type: sa}
|
||||||
|
- {name: kubedns-autoscaler, file: kubedns-autoscaler-clusterrole.yml, type: clusterrole}
|
||||||
|
- {name: kubedns-autoscaler, file: kubedns-autoscaler-clusterrolebinding.yml, type: clusterrolebinding}
|
||||||
- {name: kubedns-autoscaler, file: kubedns-autoscaler.yml, type: deployment}
|
- {name: kubedns-autoscaler, file: kubedns-autoscaler.yml, type: deployment}
|
||||||
register: manifests
|
register: manifests
|
||||||
when: dns_mode != 'none' and inventory_hostname == groups['kube-master'][0]
|
when: dns_mode != 'none' and inventory_hostname == groups['kube-master'][0] and (item.type not in rbac_resources or rbac_enabled)
|
||||||
tags: dnsmasq
|
tags: dnsmasq
|
||||||
|
|
||||||
- name: Kubernetes Apps | Start Resources
|
- name: Kubernetes Apps | Start Resources
|
||||||
|
@ -30,6 +33,7 @@
|
||||||
filename: "{{kube_config_dir}}/{{item.item.file}}"
|
filename: "{{kube_config_dir}}/{{item.item.file}}"
|
||||||
state: "{{item.changed | ternary('latest','present') }}"
|
state: "{{item.changed | ternary('latest','present') }}"
|
||||||
with_items: "{{ manifests.results }}"
|
with_items: "{{ manifests.results }}"
|
||||||
|
failed_when: manifests|failed and "Error from server (AlreadyExists)" not in manifests.msg
|
||||||
when: dns_mode != 'none' and inventory_hostname == groups['kube-master'][0]
|
when: dns_mode != 'none' and inventory_hostname == groups['kube-master'][0]
|
||||||
tags: dnsmasq
|
tags: dnsmasq
|
||||||
|
|
||||||
|
@ -37,3 +41,4 @@
|
||||||
include: tasks/netchecker.yml
|
include: tasks/netchecker.yml
|
||||||
when: deploy_netchecker
|
when: deploy_netchecker
|
||||||
tags: netchecker
|
tags: netchecker
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
# Copyright 2016 The Kubernetes Authors. All rights reserved
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
kind: ClusterRole
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||||
|
metadata:
|
||||||
|
name: cluster-proportional-autoscaler
|
||||||
|
namespace: kube-system
|
||||||
|
rules:
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["nodes"]
|
||||||
|
verbs: ["list"]
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["replicationcontrollers/scale"]
|
||||||
|
verbs: ["get", "update"]
|
||||||
|
- apiGroups: ["extensions"]
|
||||||
|
resources: ["deployments/scale", "replicasets/scale"]
|
||||||
|
verbs: ["get", "update"]
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["configmaps"]
|
||||||
|
verbs: ["get", "create"]
|
|
@ -0,0 +1,27 @@
|
||||||
|
# Copyright 2016 The Kubernetes Authors. All rights reserved
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
kind: ClusterRoleBinding
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||||
|
metadata:
|
||||||
|
name: cluster-proportional-autoscaler
|
||||||
|
namespace: kube-system
|
||||||
|
subjects:
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: cluster-proportional-autoscaler
|
||||||
|
namespace: kube-system
|
||||||
|
roleRef:
|
||||||
|
kind: ClusterRole
|
||||||
|
name: cluster-proportional-autoscaler
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
|
@ -0,0 +1,19 @@
|
||||||
|
# Copyright 2016 The Kubernetes Authors. All rights reserved
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
kind: ServiceAccount
|
||||||
|
apiVersion: v1
|
||||||
|
metadata:
|
||||||
|
name: cluster-proportional-autoscaler
|
||||||
|
namespace: kube-system
|
|
@ -46,4 +46,5 @@ spec:
|
||||||
- --default-params={"linear":{"nodesPerReplica":{{ kubedns_nodes_per_replica }},"min":{{ kubedns_min_replicas }}}}
|
- --default-params={"linear":{"nodesPerReplica":{{ kubedns_nodes_per_replica }},"min":{{ kubedns_min_replicas }}}}
|
||||||
- --logtostderr=true
|
- --logtostderr=true
|
||||||
- --v=2
|
- --v=2
|
||||||
|
serviceAccountName: cluster-proportional-autoscaler
|
||||||
|
serviceAccount: cluster-proportional-autoscaler
|
||||||
|
|
|
@ -114,4 +114,6 @@ spec:
|
||||||
- containerPort: 8080
|
- containerPort: 8080
|
||||||
protocol: TCP
|
protocol: TCP
|
||||||
dnsPolicy: Default # Don't use cluster DNS.
|
dnsPolicy: Default # Don't use cluster DNS.
|
||||||
serviceAccountName: kube-dns
|
{% if authorization_mode is defined and authorization_mode == "RBAC" %}
|
||||||
|
serviceAccount: kube-dns
|
||||||
|
{% endif %}
|
||||||
|
|
|
@ -2,3 +2,5 @@ helm_enabled: false
|
||||||
|
|
||||||
# specify a dir and attach it to helm for HELM_HOME.
|
# specify a dir and attach it to helm for HELM_HOME.
|
||||||
helm_home_dir: "/root/.helm"
|
helm_home_dir: "/root/.helm"
|
||||||
|
|
||||||
|
rbac_enabled: "{{ authorization_mode == 'RBAC' }}"
|
|
@ -10,10 +10,28 @@
|
||||||
mode: 0755
|
mode: 0755
|
||||||
register: helm_container
|
register: helm_container
|
||||||
|
|
||||||
|
- name: Helm | Configure tiller service account for RBAC
|
||||||
|
command: kubectl create serviceaccount tiller --namespace=kube-system
|
||||||
|
ignore_errors: yes
|
||||||
|
when: rbac_enabled
|
||||||
|
|
||||||
|
- name: Helm | Configure tiller rolebindings for RBAC
|
||||||
|
command: kubectl create clusterrolebinding tiller --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
|
||||||
|
ignore_errors: yes
|
||||||
|
when: rbac_enabled
|
||||||
|
|
||||||
- name: Helm | Install/upgrade helm
|
- name: Helm | Install/upgrade helm
|
||||||
command: "{{ bin_dir }}/helm init --upgrade --tiller-image={{ tiller_image_repo }}:{{ tiller_image_tag }}"
|
command: "{{ bin_dir }}/helm init --upgrade --tiller-image={{ tiller_image_repo }}:{{ tiller_image_tag }}"
|
||||||
when: helm_container.changed
|
when: helm_container.changed
|
||||||
|
|
||||||
|
- name: Helm | Patch tiller deployment for RBAC
|
||||||
|
shell: >
|
||||||
|
kubectl --namespace=kube-system get deployment tiller-deploy -o json | \
|
||||||
|
python -c 'import sys,json;a=json.load(sys.stdin);a["spec"]["template"]["spec"]["serviceAccount"]="tiller";json.dump(a,sys.stdout)' | \
|
||||||
|
kubectl apply -f -
|
||||||
|
when: rbac_enabled
|
||||||
|
|
||||||
- name: Helm | Set up bash completion
|
- name: Helm | Set up bash completion
|
||||||
shell: "umask 022 && {{ bin_dir }}/helm completion bash >/etc/bash_completion.d/helm.sh"
|
shell: "umask 022 && {{ bin_dir }}/helm completion bash >/etc/bash_completion.d/helm.sh"
|
||||||
when: ( helm_container.changed and not ansible_os_family in ["CoreOS", "Container Linux by CoreOS"] )
|
when: ( helm_container.changed and not ansible_os_family in ["CoreOS", "Container Linux by CoreOS"] )
|
||||||
|
|
||||||
|
|
|
@ -65,3 +65,5 @@ apiserver_custom_flags: []
|
||||||
controller_mgr_custom_flags: []
|
controller_mgr_custom_flags: []
|
||||||
|
|
||||||
scheduler_custom_flags: []
|
scheduler_custom_flags: []
|
||||||
|
|
||||||
|
authorization_mode: RBAC
|
|
@ -81,6 +81,9 @@ spec:
|
||||||
{% if kube_api_anonymous_auth is defined and kube_version | version_compare('v1.5', '>=') %}
|
{% if kube_api_anonymous_auth is defined and kube_version | version_compare('v1.5', '>=') %}
|
||||||
- --anonymous-auth={{ kube_api_anonymous_auth }}
|
- --anonymous-auth={{ kube_api_anonymous_auth }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if authorization_mode %}
|
||||||
|
- --authorization-mode={{ authorization_mode }}
|
||||||
|
{% endif %}
|
||||||
{% if apiserver_custom_flags is string %}
|
{% if apiserver_custom_flags is string %}
|
||||||
- {{ apiserver_custom_flags }}
|
- {{ apiserver_custom_flags }}
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|
|
@ -35,6 +35,9 @@ spec:
|
||||||
- --node-monitor-period={{ kube_controller_node_monitor_period }}
|
- --node-monitor-period={{ kube_controller_node_monitor_period }}
|
||||||
- --pod-eviction-timeout={{ kube_controller_pod_eviction_timeout }}
|
- --pod-eviction-timeout={{ kube_controller_pod_eviction_timeout }}
|
||||||
- --v={{ kube_log_level }}
|
- --v={{ kube_log_level }}
|
||||||
|
{% if authorization_mode is defined and authorization_mode == "RBAC" %}
|
||||||
|
- --use-service-account-credentials
|
||||||
|
{% endif %}
|
||||||
{% if cloud_provider is defined and cloud_provider in ["openstack", "azure", "vsphere"] %}
|
{% if cloud_provider is defined and cloud_provider in ["openstack", "azure", "vsphere"] %}
|
||||||
- --cloud-provider={{cloud_provider}}
|
- --cloud-provider={{cloud_provider}}
|
||||||
- --cloud-config={{ kube_config_dir }}/cloud_config
|
- --cloud-config={{ kube_config_dir }}/cloud_config
|
||||||
|
|
|
@ -1,4 +1,9 @@
|
||||||
---
|
---
|
||||||
|
- name: restart kubelet if secrets changed
|
||||||
|
command: /bin/true
|
||||||
|
when: secret_changed|d(False)
|
||||||
|
notify: restart kubelet
|
||||||
|
|
||||||
- name: restart kubelet
|
- name: restart kubelet
|
||||||
command: /bin/true
|
command: /bin/true
|
||||||
notify:
|
notify:
|
||||||
|
|
|
@ -4,3 +4,7 @@
|
||||||
args:
|
args:
|
||||||
creates: "/var/lib/cni"
|
creates: "/var/lib/cni"
|
||||||
failed_when: false
|
failed_when: false
|
||||||
|
|
||||||
|
- name: "Pre-upgrade | Make sure to restart kubelet if certificates changed"
|
||||||
|
command: /bin/true
|
||||||
|
notify: restart kubelet if secrets changed
|
|
@ -44,6 +44,9 @@ spec:
|
||||||
- mountPath: "{{ kube_config_dir }}/ssl"
|
- mountPath: "{{ kube_config_dir }}/ssl"
|
||||||
name: etc-kube-ssl
|
name: etc-kube-ssl
|
||||||
readOnly: true
|
readOnly: true
|
||||||
|
- mountPath: {{kube_config_dir}}/kube-proxy-kubeconfig.yaml
|
||||||
|
name: "kubeconfig"
|
||||||
|
readOnly: true
|
||||||
- mountPath: "{{ kube_config_dir }}/kube-proxy-kubeconfig.yaml"
|
- mountPath: "{{ kube_config_dir }}/kube-proxy-kubeconfig.yaml"
|
||||||
name: kubeconfig
|
name: kubeconfig
|
||||||
readOnly: true
|
readOnly: true
|
||||||
|
@ -63,7 +66,10 @@ spec:
|
||||||
path: "{{ kube_config_dir }}/ssl"
|
path: "{{ kube_config_dir }}/ssl"
|
||||||
- name: kubeconfig
|
- name: kubeconfig
|
||||||
hostPath:
|
hostPath:
|
||||||
path: "{{ kube_config_dir }}/kube-proxy-kubeconfig.yaml"
|
path: "{{kube_config_dir}}/kube-proxy-kubeconfig.yaml"
|
||||||
|
- name: "etc-kube-ssl"
|
||||||
|
hostPath:
|
||||||
|
path: "{{kube_config_dir}}/ssl"
|
||||||
- name: var-run-dbus
|
- name: var-run-dbus
|
||||||
hostPath:
|
hostPath:
|
||||||
path: /var/run/dbus
|
path: /var/run/dbus
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
---
|
---
|
||||||
kube_cert_group: kube-cert
|
kube_cert_group: kube-cert
|
||||||
|
|
||||||
|
rotate_kubernetes_certs: false # set this to true to regenerate certificates
|
||||||
|
|
|
@ -10,8 +10,8 @@
|
||||||
|
|
||||||
- name: "Check_certs | Set default value for 'sync_certs', 'gen_certs', and 'secret_changed' to false"
|
- name: "Check_certs | Set default value for 'sync_certs', 'gen_certs', and 'secret_changed' to false"
|
||||||
set_fact:
|
set_fact:
|
||||||
sync_certs: false
|
sync_certs: true
|
||||||
gen_certs: false
|
gen_certs: true
|
||||||
secret_changed: false
|
secret_changed: false
|
||||||
|
|
||||||
- name: "Check certs | check if a cert already exists on node"
|
- name: "Check certs | check if a cert already exists on node"
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
- name: "Check_certs | Set 'gen_certs' to true"
|
- name: "Check_certs | Set 'gen_certs' to true"
|
||||||
set_fact:
|
set_fact:
|
||||||
gen_certs: true
|
gen_certs: true
|
||||||
when: "not item in kubecert_master.files|map(attribute='path') | list"
|
when: "rotate_kubernetes_certs or item not in (kubecert_master.files|map(attribute='path')|list)"
|
||||||
run_once: true
|
run_once: true
|
||||||
with_items: >-
|
with_items: >-
|
||||||
['{{ kube_cert_dir }}/ca.pem',
|
['{{ kube_cert_dir }}/ca.pem',
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
{% set existing_certs = kubecert_master.files|map(attribute='path')|list|sort %}
|
{% set existing_certs = kubecert_master.files|map(attribute='path')|list|sort %}
|
||||||
{% for host in groups['k8s-cluster'] -%}
|
{% for host in groups['k8s-cluster'] -%}
|
||||||
{% set host_cert = "%s/node-%s-key.pem"|format(kube_cert_dir, host) %}
|
{% set host_cert = "%s/node-%s-key.pem"|format(kube_cert_dir, host) %}
|
||||||
{% if host_cert in existing_certs -%}
|
{% if host_cert in existing_certs and not rotate_kubernetes_certs -%}
|
||||||
"{{ host }}": False,
|
"{{ host }}": False,
|
||||||
{% else -%}
|
{% else -%}
|
||||||
"{{ host }}": True,
|
"{{ host }}": True,
|
||||||
|
@ -62,5 +62,5 @@
|
||||||
(kubecert_node.results[1].stat.checksum|default('') != kubecert_master.files|selectattr("path", "equalto", kubecert_node.results[1].stat.path)|map(attribute="checksum")|first|default('')) -%}
|
(kubecert_node.results[1].stat.checksum|default('') != kubecert_master.files|selectattr("path", "equalto", kubecert_node.results[1].stat.path)|map(attribute="checksum")|first|default('')) -%}
|
||||||
{%- set _ = certs.update({'sync': True}) -%}
|
{%- set _ = certs.update({'sync': True}) -%}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{{ certs.sync }}
|
{{ rotate_kubernetes_certs or certs.sync }}
|
||||||
|
|
||||||
|
|
|
@ -136,7 +136,6 @@
|
||||||
- name: Gen_certs | Unpack certs on masters
|
- name: Gen_certs | Unpack certs on masters
|
||||||
shell: "base64 -d < {{ cert_tempfile.stdout }} | tar xz -C {{ kube_cert_dir }}"
|
shell: "base64 -d < {{ cert_tempfile.stdout }} | tar xz -C {{ kube_cert_dir }}"
|
||||||
no_log: true
|
no_log: true
|
||||||
changed_when: false
|
|
||||||
check_mode: no
|
check_mode: no
|
||||||
when: inventory_hostname in groups['kube-master'] and sync_certs|default(false) and
|
when: inventory_hostname in groups['kube-master'] and sync_certs|default(false) and
|
||||||
inventory_hostname != groups['kube-master'][0]
|
inventory_hostname != groups['kube-master'][0]
|
||||||
|
@ -154,7 +153,6 @@
|
||||||
args:
|
args:
|
||||||
executable: /bin/bash
|
executable: /bin/bash
|
||||||
no_log: true
|
no_log: true
|
||||||
changed_when: false
|
|
||||||
check_mode: no
|
check_mode: no
|
||||||
when: inventory_hostname in groups['kube-node'] and
|
when: inventory_hostname in groups['kube-node'] and
|
||||||
sync_certs|default(false) and
|
sync_certs|default(false) and
|
||||||
|
|
Loading…
Reference in a new issue