mirror of
https://github.com/rancher/rke.git
synced 2025-08-11 03:32:45 +00:00
Enable PodSecurityPolicy support
This commit is contained in:
parent
04a137b097
commit
2011a2cf01
@ -39,4 +39,69 @@ subjects:
|
|||||||
- kind: ServiceAccount
|
- kind: ServiceAccount
|
||||||
namespace: kube-system
|
namespace: kube-system
|
||||||
name: rke-job-deployer`
|
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:
|
auth:
|
||||||
strategy: x509
|
strategy: x509
|
||||||
options:
|
options:
|
||||||
@ -21,10 +20,8 @@ network:
|
|||||||
|
|
||||||
ssh_key_path: ~/.ssh/test
|
ssh_key_path: ~/.ssh/test
|
||||||
ignore_docker_version: false
|
ignore_docker_version: false
|
||||||
|
|
||||||
# Kubernetes authorization mode; currently only `rbac` is supported and enabled by default.
|
# Kubernetes authorization mode; currently only `rbac` is supported and enabled by default.
|
||||||
# Use `mode: none` to disable authorization
|
# Use `mode: none` to disable authorization
|
||||||
|
|
||||||
authorization:
|
authorization:
|
||||||
mode: rbac
|
mode: rbac
|
||||||
options:
|
options:
|
||||||
@ -53,6 +50,7 @@ services:
|
|||||||
kube-api:
|
kube-api:
|
||||||
image: rancher/k8s:v1.8.3-rancher2
|
image: rancher/k8s:v1.8.3-rancher2
|
||||||
service_cluster_ip_range: 10.233.0.0/18
|
service_cluster_ip_range: 10.233.0.0/18
|
||||||
|
pod_security_policy: false
|
||||||
extra_args:
|
extra_args:
|
||||||
v: 4
|
v: 4
|
||||||
kube-controller:
|
kube-controller:
|
||||||
|
@ -140,6 +140,10 @@ func (c *Cluster) setClusterDefaults() {
|
|||||||
if len(c.Authorization.Mode) == 0 {
|
if len(c.Authorization.Mode) == 0 {
|
||||||
c.Authorization.Mode = DefaultAuthorizationMode
|
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.setClusterServicesDefaults()
|
||||||
c.setClusterNetworkDefaults()
|
c.setClusterNetworkDefaults()
|
||||||
c.setClusterImageDefaults()
|
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)
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -260,6 +260,16 @@ func getServiceConfig(reader *bufio.Reader) (*v3.RKEConfigServices, error) {
|
|||||||
servicesConfig.KubeAPI.ServiceClusterIPRange = serviceClusterIPRange
|
servicesConfig.KubeAPI.ServiceClusterIPRange = serviceClusterIPRange
|
||||||
servicesConfig.KubeController.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)
|
clusterNetworkCidr, err := getConfig(reader, "Cluster Network CIDR", cluster.DefaultClusterCIDR)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -32,3 +32,32 @@ func UpdateClusterRoleBindingFromYaml(k8sClient *kubernetes.Clientset, clusterRo
|
|||||||
}
|
}
|
||||||
return err
|
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
|
package k8s
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
|
||||||
|
yamlutil "k8s.io/apimachinery/pkg/util/yaml"
|
||||||
"k8s.io/client-go/kubernetes"
|
"k8s.io/client-go/kubernetes"
|
||||||
"k8s.io/client-go/tools/clientcmd"
|
"k8s.io/client-go/tools/clientcmd"
|
||||||
)
|
)
|
||||||
@ -17,3 +20,8 @@ func NewClient(kubeConfigPath string) (*kubernetes.Clientset, error) {
|
|||||||
}
|
}
|
||||||
return K8sClientSet, nil
|
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 {
|
if authorizationMode == RBACAuthorizationMode {
|
||||||
imageCfg.Cmd = append(imageCfg.Cmd, "--authorization-mode=RBAC")
|
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{
|
hostCfg := &container.HostConfig{
|
||||||
VolumesFrom: []string{
|
VolumesFrom: []string{
|
||||||
SidekickContainerName,
|
SidekickContainerName,
|
||||||
|
Loading…
Reference in New Issue
Block a user