What is the namespace of linux
About the linux namespace, Official documents Here's what it says:
A namespace wraps a global system resource in an abstraction that
makes it appear to the processes within the namespace that they
have their own isolated instance of the global resource. Changes
to the global resource are visible to other processes that are
members of the namespace, but are invisible to other processes.
One use of namespaces is to implement containers.
The following is a simple translation:
namespace is an abstraction of system resources: it can make the process look like it has independent resources
You can use namespace technology to implement containers
Summary: namespace can isolate the resources used by the process and can be used as a container
What namespace s are there?
Or reference: https://man7.org/linux/man-pages/man7/namespaces.7.html , list two tables:
name | View location | Supported versions | explain |
---|---|---|---|
cgroup | /proc/[pid]/ns/cgroup | since Linux 4.6 | Control the resources used by the process, (e.g. limit maximum memory usage) |
IPC | /proc/[pid]/ns/ipc | since Linux 3.0 | Isolate interprocess communication |
Mount | /proc/[pid]/ns/mnt | since Linux 3.8 | Make each process seem to have its own file system, A bit like chroot() |
Network | /proc/[pid]/ns/net | since Linux 3.0 | Processes can have independent cyberspace |
PID | /proc/[pid]/ns/cgroup | since Linux 3.8 | Isolation pid |
USER | /proc/[pid]/ns/cgroup | since Linux 3.8 | Isolate users |
UTS(UNIX Time-Sharing) | /proc/[pid]/ns/cgroup | since Linux 3.0 | Isolate nodename, hostname |
In addition to those listed above, Official documents It also gives: pid_for_children, time, etc. students who are interested can learn by themselves
Give an example to illustrate the role of namespace
There are many namespaces listed above. In fact, there are some system calls or commands about the namespace. Give a few examples to intuitively feel it and learn what the use of the namespace is?
This is mainly demonstrated by the command: unshare. The man document of unshare makes it very clear:
unshare - run program with some namespaces unshared from parent
In fact, you can guess from the name, UN share, which probably means not sharing, that is, monopolizing and isolating
Here are some examples:
Isolation PID
$ unshare --fork --pid --mount-proc /bin/bash $ ps -ef UID PID PPID C STIME TTY TIME CMD root 1 0 0 20:22 pts/0 00:00:00 /bin/bash root 19 1 0 20:22 pts/0 00:00:00 ps -ef $
It is found that the PID of bash process in the current namespace is 1, and there is no other process information, indicating that the PID of the current namespace and the operating system has been isolated
This has the advantage that if you want to do any experiment, you can easily view the process through PID namespace without being disturbed by other processes
Quarantine hostname
$ hostname # Check the host name first myvm $ unshare --fork --uts /bin/bash # Isolate uts namespace $ hostname # Check the hostname and find that it inherits the hostname of the system myvm $ hostname -b test # Modify the hostname in the current namespace $ hostname test # Check again and find that the hostname in the current namespace has been modified # $ exit # At this time, use exit to exit the current namespace or open another shell to check the hostname of the system and find that it is still the original myvm # exit $ hostname myvm
An example of UTS namespace written in C language (from man clone)
#define _GNU_SOURCE #include <sys/wait.h> #include <sys/utsname.h> #include <sched.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \ } while (0) /* Start function for cloned child */ static int childFunc(void *arg) { struct utsname uts; /* Change hostname in UTS namespace of child */ if (sethostname(arg, strlen(arg)) == -1) errExit("sethostname"); /* Retrieve and display hostname */ if (uname(&uts) == -1) errExit("uname"); printf("uts.nodename in child: %s\n", uts.nodename); /* Keep the namespace open for a while, by sleeping. This allows some experimentation--for example, another process might join the namespace. */ sleep(200); return 0; /* Child terminates now */ } #define STACK_SIZE (1024 * 1024) /* Stack size for cloned child */ int main(int argc, char *argv[]) { char *stack; /* Start of stack buffer */ char *stackTop; /* End of stack buffer */ pid_t pid; struct utsname uts; if (argc < 2) { fprintf(stderr, "Usage: %s <child-hostname>\n", argv[0]); exit(EXIT_SUCCESS); } /* Allocate stack for child */ stack = malloc(STACK_SIZE); if (stack == NULL) errExit("malloc"); stackTop = stack + STACK_SIZE; /* Assume stack grows downward */ /* Create child that has its own UTS namespace; child commences execution in childFunc() */ // Note the third parameter pid = clone(childFunc, stackTop, CLONE_NEWUTS | SIGCHLD, argv[1]); if (pid == -1) errExit("clone"); printf("clone() returned %ld\n", (long) pid); /* Parent falls through to here */ sleep(1); /* Give child time to change its hostname */ /* Display hostname in parent's UTS namespace. This will be different from hostname in child's UTS namespace. */ if (uname(&uts) == -1) errExit("uname"); printf("uts.nodename in parent: %s\n", uts.nodename); if (waitpid(pid, NULL, 0) == -1) /* Wait for child */ errExit("waitpid"); printf("child has terminated\n"); exit(EXIT_SUCCESS); }
Run verification:
$ gcc main.c $ ./a.out xx clone() returned 22122 uts.nodename in child: xx # Indicates that the hostname has been quarantined uts.nodename in parent: myvm ^C $
Examples of UTS namespace written in go language
main.go:
package main import ( "log" "os" "os/exec" "syscall" ) func main() { cmd := exec.Command("sh") cmd.SysProcAttr = &syscall.SysProcAttr{ Cloneflags: syscall.CLONE_NEWUTS, // In fact, it is the flags parameter of the clone() system call } cmd.Stdin = os.Stdin cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { log.Fatal(err) } }
Run verification:
$ go run main.go # After running this sentence, UTS namespace has taken effect $ hostname myvm $ hostname -b xx $ hostname xx $ exit exit $ hostname myvm $
summary
namespace is one of the core technologies to implement container. The bottom layer needs to call clone system functions
reference resources
- https://man7.org/linux/man-pages/man7/namespaces.7.html
- https://blog.csdn.net/qq_34939308/article/details/114115443
(end)