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:
parent
04a137b097
commit
2011a2cf01
@ -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
35
authz/psp.go
Normal 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
|
||||
}
|
@ -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:
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
38
k8s/psp.go
Normal 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
67
k8s/role.go
Normal 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
|
||||
}
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user