mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-21 10:51:29 +00:00
kubelet: Move userns manager to its own package
To that end, we need to add one kubelet getter listPodsFromDisk(). Other than that, it is a pretty trivial move. Signed-off-by: Rodrigo Campos <rodrigoca@microsoft.com>
This commit is contained in:
parent
16d76f6813
commit
ec0410a266
@ -109,6 +109,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/kubelet/sysctl"
|
"k8s.io/kubernetes/pkg/kubelet/sysctl"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/token"
|
"k8s.io/kubernetes/pkg/kubelet/token"
|
||||||
kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
|
kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
|
||||||
|
"k8s.io/kubernetes/pkg/kubelet/userns"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/util"
|
"k8s.io/kubernetes/pkg/kubelet/util"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/util/manager"
|
"k8s.io/kubernetes/pkg/kubelet/util/manager"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/util/queue"
|
"k8s.io/kubernetes/pkg/kubelet/util/queue"
|
||||||
@ -900,7 +901,7 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration,
|
|||||||
StateDirectory: rootDirectory,
|
StateDirectory: rootDirectory,
|
||||||
})
|
})
|
||||||
klet.shutdownManager = shutdownManager
|
klet.shutdownManager = shutdownManager
|
||||||
klet.usernsManager, err = MakeUserNsManager(klet)
|
klet.usernsManager, err = userns.MakeUserNsManager(klet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -1248,7 +1249,7 @@ type Kubelet struct {
|
|||||||
shutdownManager nodeshutdown.Manager
|
shutdownManager nodeshutdown.Manager
|
||||||
|
|
||||||
// Manage user namespaces
|
// Manage user namespaces
|
||||||
usernsManager *usernsManager
|
usernsManager *userns.UsernsManager
|
||||||
|
|
||||||
// Mutex to serialize new pod admission and existing pod resizing
|
// Mutex to serialize new pod admission and existing pod resizing
|
||||||
podResizeMutex sync.Mutex
|
podResizeMutex sync.Mutex
|
||||||
|
@ -104,6 +104,11 @@ func (kl *Kubelet) GetPodDir(podUID types.UID) string {
|
|||||||
return kl.getPodDir(podUID)
|
return kl.getPodDir(podUID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListPodsFromDisk gets a list of pods that have data directories.
|
||||||
|
func (kl *Kubelet) ListPodsFromDisk() ([]types.UID, error) {
|
||||||
|
return kl.listPodsFromDisk()
|
||||||
|
}
|
||||||
|
|
||||||
// getPodDir returns the full path to the per-pod directory for the pod with
|
// getPodDir returns the full path to the per-pod directory for the pod with
|
||||||
// the given UID.
|
// the given UID.
|
||||||
func (kl *Kubelet) getPodDir(podUID types.UID) string {
|
func (kl *Kubelet) getPodDir(podUID types.UID) string {
|
||||||
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package kubelet
|
package userns
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
@ -49,11 +49,11 @@ const maxPods = 1024
|
|||||||
const mapReInitializeThreshold = 1000
|
const mapReInitializeThreshold = 1000
|
||||||
|
|
||||||
type userNsPodsManager interface {
|
type userNsPodsManager interface {
|
||||||
getPodDir(podUID types.UID) string
|
GetPodDir(podUID types.UID) string
|
||||||
listPodsFromDisk() ([]types.UID, error)
|
ListPodsFromDisk() ([]types.UID, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type usernsManager struct {
|
type UsernsManager struct {
|
||||||
used *allocator.AllocationBitmap
|
used *allocator.AllocationBitmap
|
||||||
usedBy map[types.UID]uint32 // Map pod.UID to range used
|
usedBy map[types.UID]uint32 // Map pod.UID to range used
|
||||||
removed int
|
removed int
|
||||||
@ -86,8 +86,8 @@ const mappingsFile = "userns"
|
|||||||
|
|
||||||
// writeMappingsToFile writes the specified user namespace configuration to the pod
|
// writeMappingsToFile writes the specified user namespace configuration to the pod
|
||||||
// directory.
|
// directory.
|
||||||
func (m *usernsManager) writeMappingsToFile(pod types.UID, userNs userNamespace) error {
|
func (m *UsernsManager) writeMappingsToFile(pod types.UID, userNs userNamespace) error {
|
||||||
dir := m.kl.getPodDir(pod)
|
dir := m.kl.GetPodDir(pod)
|
||||||
|
|
||||||
data, err := json.Marshal(userNs)
|
data, err := json.Marshal(userNs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -119,8 +119,8 @@ func (m *usernsManager) writeMappingsToFile(pod types.UID, userNs userNamespace)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// readMappingsFromFile reads the user namespace configuration from the pod directory.
|
// readMappingsFromFile reads the user namespace configuration from the pod directory.
|
||||||
func (m *usernsManager) readMappingsFromFile(pod types.UID) ([]byte, error) {
|
func (m *UsernsManager) readMappingsFromFile(pod types.UID) ([]byte, error) {
|
||||||
dir := m.kl.getPodDir(pod)
|
dir := m.kl.GetPodDir(pod)
|
||||||
fstore, err := utilstore.NewFileStore(dir, &utilfs.DefaultFs{})
|
fstore, err := utilstore.NewFileStore(dir, &utilfs.DefaultFs{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -128,8 +128,8 @@ func (m *usernsManager) readMappingsFromFile(pod types.UID) ([]byte, error) {
|
|||||||
return fstore.Read(mappingsFile)
|
return fstore.Read(mappingsFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
func MakeUserNsManager(kl userNsPodsManager) (*usernsManager, error) {
|
func MakeUserNsManager(kl userNsPodsManager) (*UsernsManager, error) {
|
||||||
m := usernsManager{
|
m := UsernsManager{
|
||||||
// Create a bitArray for all the UID space (2^32).
|
// Create a bitArray for all the UID space (2^32).
|
||||||
// As a by product of that, no index param to bitArray can be out of bounds (index is uint32).
|
// As a by product of that, no index param to bitArray can be out of bounds (index is uint32).
|
||||||
used: allocator.NewAllocationMap((math.MaxUint32+1)/userNsLength, "user namespaces"),
|
used: allocator.NewAllocationMap((math.MaxUint32+1)/userNsLength, "user namespaces"),
|
||||||
@ -146,7 +146,7 @@ func MakeUserNsManager(kl userNsPodsManager) (*usernsManager, error) {
|
|||||||
return &m, nil
|
return &m, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
found, err := kl.listPodsFromDisk()
|
found, err := kl.ListPodsFromDisk()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
return &m, nil
|
return &m, nil
|
||||||
@ -166,7 +166,7 @@ func MakeUserNsManager(kl userNsPodsManager) (*usernsManager, error) {
|
|||||||
|
|
||||||
// recordPodMappings registers the range used for the user namespace if the
|
// recordPodMappings registers the range used for the user namespace if the
|
||||||
// usernsConfFile exists in the pod directory.
|
// usernsConfFile exists in the pod directory.
|
||||||
func (m *usernsManager) recordPodMappings(pod types.UID) error {
|
func (m *UsernsManager) recordPodMappings(pod types.UID) error {
|
||||||
content, err := m.readMappingsFromFile(pod)
|
content, err := m.readMappingsFromFile(pod)
|
||||||
if err != nil && err != utilstore.ErrKeyNotFound {
|
if err != nil && err != utilstore.ErrKeyNotFound {
|
||||||
return err
|
return err
|
||||||
@ -182,7 +182,7 @@ func (m *usernsManager) recordPodMappings(pod types.UID) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// isSet checks if the specified index is already set.
|
// isSet checks if the specified index is already set.
|
||||||
func (m *usernsManager) isSet(v uint32) bool {
|
func (m *UsernsManager) isSet(v uint32) bool {
|
||||||
index := int(v / userNsLength)
|
index := int(v / userNsLength)
|
||||||
return m.used.Has(index)
|
return m.used.Has(index)
|
||||||
}
|
}
|
||||||
@ -190,7 +190,7 @@ func (m *usernsManager) isSet(v uint32) bool {
|
|||||||
// allocateOne finds a free user namespace and allocate it to the specified pod.
|
// allocateOne finds a free user namespace and allocate it to the specified pod.
|
||||||
// The first return value is the first ID in the user namespace, the second returns
|
// The first return value is the first ID in the user namespace, the second returns
|
||||||
// the length for the user namespace range.
|
// the length for the user namespace range.
|
||||||
func (m *usernsManager) allocateOne(pod types.UID) (firstID uint32, length uint32, err error) {
|
func (m *UsernsManager) allocateOne(pod types.UID) (firstID uint32, length uint32, err error) {
|
||||||
if m.numAllocated >= maxPods {
|
if m.numAllocated >= maxPods {
|
||||||
return 0, 0, fmt.Errorf("limit on count of pods with user namespaces exceeded (limit is %v, current pods with userns: %v)", maxPods, m.numAllocated)
|
return 0, 0, fmt.Errorf("limit on count of pods with user namespaces exceeded (limit is %v, current pods with userns: %v)", maxPods, m.numAllocated)
|
||||||
}
|
}
|
||||||
@ -217,7 +217,7 @@ func (m *usernsManager) allocateOne(pod types.UID) (firstID uint32, length uint3
|
|||||||
}
|
}
|
||||||
|
|
||||||
// record stores the user namespace [from; from+length] to the specified pod.
|
// record stores the user namespace [from; from+length] to the specified pod.
|
||||||
func (m *usernsManager) record(pod types.UID, from, length uint32) (err error) {
|
func (m *UsernsManager) record(pod types.UID, from, length uint32) (err error) {
|
||||||
if length != userNsLength {
|
if length != userNsLength {
|
||||||
return fmt.Errorf("wrong user namespace length %v", length)
|
return fmt.Errorf("wrong user namespace length %v", length)
|
||||||
}
|
}
|
||||||
@ -257,7 +257,7 @@ func (m *usernsManager) record(pod types.UID, from, length uint32) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Release releases the user namespace allocated to the specified pod.
|
// Release releases the user namespace allocated to the specified pod.
|
||||||
func (m *usernsManager) Release(podUID types.UID) {
|
func (m *UsernsManager) Release(podUID types.UID) {
|
||||||
if !utilfeature.DefaultFeatureGate.Enabled(features.UserNamespacesStatelessPodsSupport) {
|
if !utilfeature.DefaultFeatureGate.Enabled(features.UserNamespacesStatelessPodsSupport) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -268,7 +268,7 @@ func (m *usernsManager) Release(podUID types.UID) {
|
|||||||
m.releaseWithLock(podUID)
|
m.releaseWithLock(podUID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *usernsManager) releaseWithLock(pod types.UID) {
|
func (m *UsernsManager) releaseWithLock(pod types.UID) {
|
||||||
v, ok := m.usedBy[pod]
|
v, ok := m.usedBy[pod]
|
||||||
if !ok {
|
if !ok {
|
||||||
klog.V(5).InfoS("pod user namespace allocation not present", "podUID", pod)
|
klog.V(5).InfoS("pod user namespace allocation not present", "podUID", pod)
|
||||||
@ -280,7 +280,7 @@ func (m *usernsManager) releaseWithLock(pod types.UID) {
|
|||||||
m.numAllocated--
|
m.numAllocated--
|
||||||
m.removed++
|
m.removed++
|
||||||
|
|
||||||
_ = os.Remove(filepath.Join(m.kl.getPodDir(pod), mappingsFile))
|
_ = os.Remove(filepath.Join(m.kl.GetPodDir(pod), mappingsFile))
|
||||||
|
|
||||||
if m.removed%mapReInitializeThreshold == 0 {
|
if m.removed%mapReInitializeThreshold == 0 {
|
||||||
n := make(map[types.UID]uint32)
|
n := make(map[types.UID]uint32)
|
||||||
@ -293,7 +293,7 @@ func (m *usernsManager) releaseWithLock(pod types.UID) {
|
|||||||
m.used.Release(int(v / userNsLength))
|
m.used.Release(int(v / userNsLength))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *usernsManager) parseUserNsFileAndRecord(pod types.UID, content []byte) (userNs userNamespace, err error) {
|
func (m *UsernsManager) parseUserNsFileAndRecord(pod types.UID, content []byte) (userNs userNamespace, err error) {
|
||||||
if err = json.Unmarshal([]byte(content), &userNs); err != nil {
|
if err = json.Unmarshal([]byte(content), &userNs); err != nil {
|
||||||
err = fmt.Errorf("can't parse file: %w", err)
|
err = fmt.Errorf("can't parse file: %w", err)
|
||||||
return
|
return
|
||||||
@ -333,7 +333,7 @@ func (m *usernsManager) parseUserNsFileAndRecord(pod types.UID, content []byte)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *usernsManager) createUserNs(pod *v1.Pod) (userNs userNamespace, err error) {
|
func (m *UsernsManager) createUserNs(pod *v1.Pod) (userNs userNamespace, err error) {
|
||||||
firstID, length, err := m.allocateOne(pod.UID)
|
firstID, length, err := m.allocateOne(pod.UID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
@ -366,7 +366,7 @@ func (m *usernsManager) createUserNs(pod *v1.Pod) (userNs userNamespace, err err
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetOrCreateUserNamespaceMappings returns the configuration for the sandbox user namespace
|
// GetOrCreateUserNamespaceMappings returns the configuration for the sandbox user namespace
|
||||||
func (m *usernsManager) GetOrCreateUserNamespaceMappings(pod *v1.Pod) (*runtimeapi.UserNamespace, error) {
|
func (m *UsernsManager) GetOrCreateUserNamespaceMappings(pod *v1.Pod) (*runtimeapi.UserNamespace, error) {
|
||||||
if !utilfeature.DefaultFeatureGate.Enabled(features.UserNamespacesStatelessPodsSupport) {
|
if !utilfeature.DefaultFeatureGate.Enabled(features.UserNamespacesStatelessPodsSupport) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
@ -426,7 +426,7 @@ func (m *usernsManager) GetOrCreateUserNamespaceMappings(pod *v1.Pod) (*runtimea
|
|||||||
// CleanupOrphanedPodUsernsAllocations reconciliates the state of user namespace
|
// CleanupOrphanedPodUsernsAllocations reconciliates the state of user namespace
|
||||||
// allocations with the pods actually running. It frees any user namespace
|
// allocations with the pods actually running. It frees any user namespace
|
||||||
// allocation for orphaned pods.
|
// allocation for orphaned pods.
|
||||||
func (m *usernsManager) CleanupOrphanedPodUsernsAllocations(pods []*v1.Pod, runningPods []*kubecontainer.Pod) error {
|
func (m *UsernsManager) CleanupOrphanedPodUsernsAllocations(pods []*v1.Pod, runningPods []*kubecontainer.Pod) error {
|
||||||
if !utilfeature.DefaultFeatureGate.Enabled(features.UserNamespacesStatelessPodsSupport) {
|
if !utilfeature.DefaultFeatureGate.Enabled(features.UserNamespacesStatelessPodsSupport) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -443,7 +443,7 @@ func (m *usernsManager) CleanupOrphanedPodUsernsAllocations(pods []*v1.Pod, runn
|
|||||||
}
|
}
|
||||||
|
|
||||||
allFound := sets.NewString()
|
allFound := sets.NewString()
|
||||||
found, err := m.kl.listPodsFromDisk()
|
found, err := m.kl.ListPodsFromDisk()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package kubelet
|
package userns
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -31,11 +31,11 @@ import (
|
|||||||
type testUserNsPodsManager struct {
|
type testUserNsPodsManager struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *testUserNsPodsManager) getPodDir(podUID types.UID) string {
|
func (m *testUserNsPodsManager) GetPodDir(podUID types.UID) string {
|
||||||
return "/tmp/non-existant-dir.This-is-not-used-in-tests"
|
return "/tmp/non-existant-dir.This-is-not-used-in-tests"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *testUserNsPodsManager) listPodsFromDisk() ([]types.UID, error) {
|
func (m *testUserNsPodsManager) ListPodsFromDisk() ([]types.UID, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user