1
0
mirror of https://github.com/rancher/rke.git synced 2025-07-31 22:56:19 +00:00

Enable PodSecurityPolicy support

This commit is contained in:
moelsayed 2017-12-20 03:51:07 +02:00
parent 04a137b097
commit 2011a2cf01
10 changed files with 268 additions and 3 deletions

View File

@ -39,4 +39,69 @@ subjects:
- kind: ServiceAccount
namespace: kube-system
name: rke-job-deployer`
DefaultPodSecurityPolicy = `
apiVersion: extensions/v1beta1
kind: PodSecurityPolicy
metadata:
name: default-psp
namespace: kube-system
annotations:
seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*'
spec:
privileged: true
allowPrivilegeEscalation: true
allowedCapabilities:
- '*'
volumes:
- '*'
hostNetwork: true
hostPorts:
- min: 0
max: 65535
hostIPC: true
hostPID: true
runAsUser:
rule: 'RunAsAny'
seLinux:
rule: 'RunAsAny'
supplementalGroups:
rule: 'RunAsAny'
fsGroup:
rule: 'RunAsAny'`
DefaultPodSecurityRole = `
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: default-psp-role
namespace: kube-system
rules:
- apiGroups: ['extensions']
resources: ['podsecuritypolicies']
verbs: ['use']
resourceNames:
- default-psp`
DefaultPodSecurityRoleBinding = `
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: default-psp-rolebinding
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: default-psp-role
subjects:
# Authorize all service accounts in a namespace:
- kind: Group
apiGroup: rbac.authorization.k8s.io
name: system:serviceaccounts
# Or equivalently, all authenticated users in a namespace:
- kind: Group
apiGroup: rbac.authorization.k8s.io
name: system:authenticated
`
)

35
authz/psp.go Normal file
View File

@ -0,0 +1,35 @@
package authz
import (
"github.com/rancher/rke/k8s"
"github.com/sirupsen/logrus"
)
func ApplyDefaultPodSecurityPolicy(kubeConfigPath string) error {
logrus.Infof("[authz] Applying default PodSecurityPolicy")
k8sClient, err := k8s.NewClient(kubeConfigPath)
if err != nil {
return err
}
if err := k8s.UpdatePodSecurityPolicyFromYaml(k8sClient, DefaultPodSecurityPolicy); err != nil {
return err
}
logrus.Infof("[authz] Default PodSecurityPolicy applied successfully")
return nil
}
func ApplyDefaultPodSecurityPolicyRole(kubeConfigPath string) error {
logrus.Infof("[authz] Applying default PodSecurityPolicy Role and RoleBinding")
k8sClient, err := k8s.NewClient(kubeConfigPath)
if err != nil {
return err
}
if err := k8s.UpdateRoleFromYaml(k8sClient, DefaultPodSecurityRole); err != nil {
return err
}
if err := k8s.UpdateRoleBindingFromYaml(k8sClient, DefaultPodSecurityRoleBinding); err != nil {
return err
}
logrus.Infof("[authz] Default PodSecurityPolicy Role and RoleBinding applied successfully")
return nil
}

View File

@ -1,5 +1,4 @@
---
auth:
strategy: x509
options:
@ -21,10 +20,8 @@ network:
ssh_key_path: ~/.ssh/test
ignore_docker_version: false
# Kubernetes authorization mode; currently only `rbac` is supported and enabled by default.
# Use `mode: none` to disable authorization
authorization:
mode: rbac
options:
@ -53,6 +50,7 @@ services:
kube-api:
image: rancher/k8s:v1.8.3-rancher2
service_cluster_ip_range: 10.233.0.0/18
pod_security_policy: false
extra_args:
v: 4
kube-controller:

View File

@ -140,6 +140,10 @@ func (c *Cluster) setClusterDefaults() {
if len(c.Authorization.Mode) == 0 {
c.Authorization.Mode = DefaultAuthorizationMode
}
if c.Services.KubeAPI.PodSecurityPolicy && c.Authorization.Mode != services.RBACAuthorizationMode {
logrus.Warnf("PodSecurityPolicy can't be enabled with RBAC support disabled")
c.Services.KubeAPI.PodSecurityPolicy = false
}
c.setClusterServicesDefaults()
c.setClusterNetworkDefaults()
c.setClusterImageDefaults()
@ -258,5 +262,13 @@ func (c *Cluster) ApplyAuthzResources() error {
return fmt.Errorf("Failed to apply the ClusterRoleBinding needed for node authorization: %v", err)
}
}
if c.Authorization.Mode == services.RBACAuthorizationMode && c.Services.KubeAPI.PodSecurityPolicy {
if err := authz.ApplyDefaultPodSecurityPolicy(c.LocalKubeConfigPath); err != nil {
return fmt.Errorf("Failed to apply default PodSecurityPolicy: %v", err)
}
if err := authz.ApplyDefaultPodSecurityPolicyRole(c.LocalKubeConfigPath); err != nil {
return fmt.Errorf("Failed to apply default PodSecurityPolicy ClusterRole and ClusterRoleBinding: %v", err)
}
}
return nil
}

View File

@ -260,6 +260,16 @@ func getServiceConfig(reader *bufio.Reader) (*v3.RKEConfigServices, error) {
servicesConfig.KubeAPI.ServiceClusterIPRange = serviceClusterIPRange
servicesConfig.KubeController.ServiceClusterIPRange = serviceClusterIPRange
podSecurityPolicy, err := getConfig(reader, "Enable PodSecurityPolicy", "n")
if err != nil {
return nil, err
}
if podSecurityPolicy == "y" || podSecurityPolicy == "Y" {
servicesConfig.KubeAPI.PodSecurityPolicy = true
} else {
servicesConfig.KubeAPI.PodSecurityPolicy = false
}
clusterNetworkCidr, err := getConfig(reader, "Cluster Network CIDR", cluster.DefaultClusterCIDR)
if err != nil {
return nil, err

View File

@ -32,3 +32,32 @@ func UpdateClusterRoleBindingFromYaml(k8sClient *kubernetes.Clientset, clusterRo
}
return err
}
func UpdateClusterRoleFromYaml(k8sClient *kubernetes.Clientset, clusterRoleYaml string) error {
clusterRole := rbacv1.ClusterRole{}
err := decodeYamlResource(&clusterRole, clusterRoleYaml)
if err != nil {
return err
}
for retries := 0; retries <= 5; retries++ {
if err = updateClusterRole(k8sClient, clusterRole); err != nil {
time.Sleep(time.Second * 5)
continue
}
return nil
}
return err
}
func updateClusterRole(k8sClient *kubernetes.Clientset, cr rbacv1.ClusterRole) error {
if _, err := k8sClient.RbacV1().ClusterRoles().Create(&cr); err != nil {
if !apierrors.IsAlreadyExists(err) {
return err
}
if _, err := k8sClient.RbacV1().ClusterRoles().Update(&cr); err != nil {
return err
}
}
return nil
}

View File

@ -1,6 +1,9 @@
package k8s
import (
"bytes"
yamlutil "k8s.io/apimachinery/pkg/util/yaml"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
)
@ -17,3 +20,8 @@ func NewClient(kubeConfigPath string) (*kubernetes.Clientset, error) {
}
return K8sClientSet, nil
}
func decodeYamlResource(resource interface{}, yamlManifest string) error {
decoder := yamlutil.NewYAMLToJSONDecoder(bytes.NewReader([]byte(yamlManifest)))
return decoder.Decode(&resource)
}

38
k8s/psp.go Normal file
View File

@ -0,0 +1,38 @@
package k8s
import (
"time"
"k8s.io/api/extensions/v1beta1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/client-go/kubernetes"
)
func UpdatePodSecurityPolicyFromYaml(k8sClient *kubernetes.Clientset, pspYaml string) error {
psp := v1beta1.PodSecurityPolicy{}
err := decodeYamlResource(&psp, pspYaml)
if err != nil {
return err
}
for retries := 0; retries <= 5; retries++ {
if err = updatePodSecurityPolicy(k8sClient, psp); err != nil {
time.Sleep(time.Second * 5)
continue
}
return nil
}
return err
}
func updatePodSecurityPolicy(k8sClient *kubernetes.Clientset, psp v1beta1.PodSecurityPolicy) error {
if _, err := k8sClient.ExtensionsV1beta1().PodSecurityPolicies().Create(&psp); err != nil {
if !apierrors.IsAlreadyExists(err) {
return err
}
if _, err := k8sClient.ExtensionsV1beta1().PodSecurityPolicies().Update(&psp); err != nil {
return err
}
}
return nil
}

67
k8s/role.go Normal file
View File

@ -0,0 +1,67 @@
package k8s
import (
"time"
rbacv1 "k8s.io/api/rbac/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/client-go/kubernetes"
)
func UpdateRoleBindingFromYaml(k8sClient *kubernetes.Clientset, roleBindingYaml string) error {
roleBinding := rbacv1.RoleBinding{}
err := decodeYamlResource(&roleBinding, roleBindingYaml)
if err != nil {
return err
}
for retries := 0; retries <= 5; retries++ {
if err = updateRoleBinding(k8sClient, roleBinding); err != nil {
time.Sleep(time.Second * 5)
continue
}
return nil
}
return err
}
func updateRoleBinding(k8sClient *kubernetes.Clientset, roleBinding rbacv1.RoleBinding) error {
if _, err := k8sClient.RbacV1().RoleBindings(roleBinding.Namespace).Create(&roleBinding); err != nil {
if !apierrors.IsAlreadyExists(err) {
return err
}
if _, err := k8sClient.RbacV1().RoleBindings(roleBinding.Namespace).Update(&roleBinding); err != nil {
return err
}
}
return nil
}
func UpdateRoleFromYaml(k8sClient *kubernetes.Clientset, roleYaml string) error {
role := rbacv1.Role{}
err := decodeYamlResource(&role, roleYaml)
if err != nil {
return err
}
for retries := 0; retries <= 5; retries++ {
if err = updateRole(k8sClient, role); err != nil {
time.Sleep(time.Second * 5)
continue
}
return nil
}
return err
}
func updateRole(k8sClient *kubernetes.Clientset, role rbacv1.Role) error {
if _, err := k8sClient.RbacV1().Roles(role.Namespace).Create(&role); err != nil {
if !apierrors.IsAlreadyExists(err) {
return err
}
if _, err := k8sClient.RbacV1().Roles(role.Namespace).Update(&role); err != nil {
return err
}
}
return nil
}

View File

@ -47,6 +47,9 @@ func buildKubeAPIConfig(host *hosts.Host, kubeAPIService v3.KubeAPIService, etcd
if authorizationMode == RBACAuthorizationMode {
imageCfg.Cmd = append(imageCfg.Cmd, "--authorization-mode=RBAC")
}
if kubeAPIService.PodSecurityPolicy {
imageCfg.Cmd = append(imageCfg.Cmd, "--runtime-config=extensions/v1beta1/podsecuritypolicy=true", "--admission-control=PodSecurityPolicy")
}
hostCfg := &container.HostConfig{
VolumesFrom: []string{
SidekickContainerName,