Artikel ini membawakan anda pengetahuan yang berkaitan tentang ruang nama Linux menyediakan bentuk virtualisasi yang ringan, membolehkan kami melihat sifat global sistem yang sedang berjalan dari aspek yang berbeza.
Ruang nama (ruang nama Linux) ialah ciri kernel Linux untuk pemetaan virtualisasi kontena. Setiap bekas yang kami cipta mempunyai ruang nama sendiri, dan aplikasi yang berjalan di dalamnya seolah-olah mereka berjalan dalam sistem pengendalian bebas Ruang nama memastikan bahawa bekas tidak menjejaskan satu sama lain.
Mekanisme ruang nama Linux menyediakan penyelesaian untuk pengasingan sumber. Sumber sistem seperti PID, IPC dan Rangkaian tidak lagi global, tetapi tergolong dalam Ruang Nama tertentu. Ruang nama ialah sejenis pengkapsulan dan pengasingan sumber sistem global, supaya proses dalam ruang nama yang berbeza mempunyai sumber sistem global yang bebas Menukar sumber sistem dalam ruang nama hanya akan menjejaskan proses dalam ruang nama semasa dan tidak memberi kesan kepada proses dalam ruang nama lain.
Secara tradisinya, dalam Linux dan derivatif UNIX yang lain, banyak sumber diuruskan secara global. Sebagai contoh, semua proses dalam sistem dikenal pasti secara konvensional oleh PID, yang bermaksud bahawa kernel mesti mengurus senarai global PID. Selain itu, maklumat berkaitan sistem (termasuk nama sistem dan beberapa maklumat tentang kernel) yang dikembalikan oleh semua pemanggil melalui panggilan sistem tanpa nama adalah sama. ID pengguna diurus dengan cara yang sama, iaitu, setiap pengguna dikenal pasti melalui nombor UID unik di seluruh dunia.
ID global membenarkan kernel membenarkan atau menafikan keistimewaan tertentu secara selektif. Walaupun pengguna akar dengan UID 0 dibenarkan melakukan apa-apa sahaja, ID pengguna lain adalah terhad. Sebagai contoh, pengguna dengan UID n tidak dibenarkan untuk membunuh proses kepunyaan pengguna m (m≠ n). Tetapi ini tidak menghalang pengguna daripada melihat antara satu sama lain, iaitu pengguna n dapat melihat bahawa pengguna lain m juga aktif pada komputer. Selagi pengguna hanya boleh memanipulasi proses mereka sendiri, ini tidak mengapa, kerana tiada sebab mengapa pengguna tidak dibenarkan melihat proses pengguna lain.
Tetapi dalam sesetengah kes, kesan ini mungkin tidak diingini. Jika penyedia pengehosan web bercadang untuk menyediakan pengguna dengan akses penuh kepada komputer Linux, termasuk keistimewaan root. Secara tradisinya, ini memerlukan komputer untuk setiap pengguna, yang sangat mahal. Menggunakan persekitaran virtualisasi yang disediakan oleh KVM atau VMWare adalah salah satu cara untuk menyelesaikan masalah, tetapi peruntukan sumber tidak begitu baik. Setiap pengguna komputer memerlukan kernel yang berasingan dan set aplikasi peringkat pengguna yang dipasang sepenuhnya.
Ruang nama menyediakan penyelesaian berbeza yang memerlukan lebih sedikit sumber. Dalam sistem maya, komputer fizikal boleh menjalankan berbilang teras, mungkin berbilang sistem pengendalian yang berbeza secara selari. Ruang nama hanya menggunakan satu kernel untuk beroperasi pada satu komputer fizikal, dan semua sumber global yang disebutkan di atas disarikan melalui ruang nama. Ini memungkinkan untuk meletakkan satu set proses ke dalam bekas yang diasingkan antara satu sama lain. Pengasingan membolehkan ahli bekas tidak mempunyai hubungan dengan bekas lain. Tetapi anda juga boleh mengurangkan pemisahan antara bekas dengan membenarkan mereka berkongsi jumlah maklumat tertentu. Sebagai contoh, bekas boleh disediakan untuk menggunakan set PIDnya sendiri tetapi masih berkongsi bahagian sistem fail dengan bekas lain.
Pelaksanaan ruang nama memerlukan dua bahagian: struktur ruang nama setiap subsistem, membungkus semua komponen global sebelumnya ke dalam ruang nama yang mengaitkan proses yang diberikan dengan Mekanisme setiap ruang nama; yang mana ia milik.
Sifat global subsistem sebelum ini kini dirangkumkan ke dalam ruang nama dan setiap proses dikaitkan dengan ruang nama yang dipilih. Setiap subsistem kernel sedar ruang nama mesti menyediakan struktur data yang mengumpulkan semua objek yang disediakan sebagai ruang nama. struct nsproxy digunakan untuk memasang penunjuk kepada pembalut ruang nama khusus subsistem. Dalam fail nsproxy.h terdapat:
/* * A structure to contain pointers to all per-process * namespaces - fs (mount), uts, network, sysvipc, etc. * * The pid namespace is an exception -- it's accessed using * task_active_pid_ns. The pid namespace here is the * namespace that children will use. * * 'count' is the number of tasks holding a reference. * The count for each namespace, then, will be the number * of nsproxies pointing to it, not the number of tasks. * * The nsproxy is shared by tasks which share all namespaces. * As soon as a single namespace is cloned or unshared, the * nsproxy is copied. */struct nsproxy { atomic_t count; struct uts_namespace *uts_ns; struct ipc_namespace *ipc_ns; struct mnt_namespace *mnt_ns; struct pid_namespace *pid_ns_for_children; struct net *net_ns; struct time_namespace *time_ns; struct time_namespace *time_ns_for_children; struct cgroup_namespace *cgroup_ns;};
Skop kernel semasa berikut boleh mengesan ruang nama
1. Ruang nama UTS mengandungi nama, versi dan seni bina asas bagi menjalankan jenis kernel dan maklumat lain. UTS ialah singkatan UNIX Timesharing System.
2. Semua maklumat yang berkaitan dengan komunikasi antara proses (IPC) disimpan dalam struct ipc_namespace.
3. Pandangan sistem fail yang dipasang diberikan dalam struct mnt_namespace.
4. Maklumat tentang ID proses disediakan oleh struct pid_namespace.
5. Maklumat yang disimpan oleh struct user_namespace digunakan untuk mengehadkan penggunaan sumber setiap pengguna.
6. struct net_ns mengandungi semua parameter ruang nama berkaitan rangkaian.
Apabila saya membincangkan subsistem yang sepadan, saya akan memperkenalkan kandungan setiap bekas ruang nama. Memandangkan fork boleh digunakan untuk mewujudkan ruang nama baharu semasa membuat proses baharu, bendera yang sesuai mesti disediakan untuk mengawal tingkah laku ini. Setiap ruang nama mempunyai bendera yang sepadan, yang terdapat dalam fail sched.h:
#define CLONE_NEWCGROUP 0x02000000 /* New cgroup namespace */ #define CLONE_NEWUTS 0x04000000 /* New utsname namespace */ #define CLONE_NEWIPC 0x08000000 /* New ipc namespace */ #define CLONE_NEWUSER 0x10000000 /* New user namespace */ #define CLONE_NEWPID 0x20000000 /* New pid namespace */ #define CLONE_NEWNET 0x40000000 /* New network namespace */
Fungsi pelbagai jenis ruang nama:
IPC:用于隔离进程间通讯所需的资源( System V IPC, POSIX message queues),PID命名空间和IPC命名空间可以组合起来用,同一个IPC名字空间内的进程可以彼此看见,允许进行交互,不同空间进程无法交互
Network:Network Namespace为进程提供了一个完全独立的网络协议栈的视图。包括网络设备接口,IPv4和IPv6协议栈,IP路由表,防火墙规则,sockets等等。一个Network Namespace提供了一份独立的网络环境,就跟一个独立的系统一样。
Mount:每个进程都存在于一个mount Namespace里面, mount Namespace为进程提供了一个文件层次视图。如果不设定这个flag,子进程和父进程将共享一个mount Namespace,其后子进程调用mount或umount将会影响到所有该Namespace内的进程。如果子进程在一个独立的mount Namespace里面,就可以调用mount或umount建立一份新的文件层次视图。
PID::linux通过命名空间管理进程号,同一个进程,在不同的命名空间进程号不同!进程命名空间是一个父子结构,子空间对于父空间可见。
User:用于隔离用户
UTS:用于隔离主机名
每个进程都关联到自身的命名空间视图,在任务定义的结构体task_struct中有如下定义:
struct task_struct {.../* 命名空间 */struct nsproxy *nsproxy;...}
因为使用了指针,多个进程可以共享一组子命名空间。这样,修改给定的命名空间,对所有属于该命名空间的进程都是可见的。
init_nsproxy定义了初始的全局命名空间,其中维护了指向各子系统初始的命名空间对象的指针。在kernel/nsproxy.c文件内有
struct nsproxy init_nsproxy = { .count = ATOMIC_INIT(1), .uts_ns = &init_uts_ns,#if defined(CONFIG_POSIX_MQUEUE) || defined(CONFIG_SYSVIPC) .ipc_ns = &init_ipc_ns,#endif .mnt_ns = NULL, .pid_ns_for_children = &init_pid_ns,#ifdef CONFIG_NET .net_ns = &init_net,#endif#ifdef CONFIG_CGROUPS .cgroup_ns = &init_cgroup_ns,#endif#ifdef CONFIG_TIME_NS .time_ns = &init_time_ns, .time_ns_for_children = &init_time_ns,#endif};
UTS命名空间几乎不需要特别的处理,因为它只需要简单量,没有层次组织。所有相关信息都汇集到下列结构的一个实例中。在utsname.h文件内:
struct uts_namespace { struct new_utsname name; struct user_namespace *user_ns; struct ucounts *ucounts; struct ns_common ns;} __randomize_layout;
uts_namespace所提供的属性信息本身包含在struct new_utsname中:
struct oldold_utsname { char sysname[9]; char nodename[9]; char release[9]; char version[9]; char machine[9];};#define __NEW_UTS_LEN 64struct old_utsname { char sysname[65]; char nodename[65]; char release[65]; char version[65]; char machine[65];};struct new_utsname { char sysname[__NEW_UTS_LEN + 1]; char nodename[__NEW_UTS_LEN + 1]; char release[__NEW_UTS_LEN + 1]; char version[__NEW_UTS_LEN + 1]; char machine[__NEW_UTS_LEN + 1]; char domainname[__NEW_UTS_LEN + 1];}
各个字符串分别存储了系统的名称( Linux…)、内核发布版本、机器名,等等。使用uname工具可以取得这些属性的当前值,也可以在/proc/sys/kernel/中看到
z@z-virtual-machine:~$ cat /proc/sys/kernel/ostype Linux z@z-virtual-machine:~$ cat /proc/sys/kernel/osrelease5.3.0-40-generic
初始设置保存在init_uts_ns中,在init/version.c文件内:
struct uts_namespace init_uts_ns = { .ns.count = REFCOUNT_INIT(2), .name = { .sysname = UTS_SYSNAME, .nodename = UTS_NODENAME, .release = UTS_RELEASE, .version = UTS_VERSION, .machine = UTS_MACHINE, .domainname = UTS_DOMAINNAME, }, .user_ns = &init_user_ns, .ns.inum = PROC_UTS_INIT_INO,#ifdef CONFIG_UTS_NS .ns.ops = &utsns_operations,#endif};
相关推荐:《Linux视频教程》
Atas ialah kandungan terperinci Anda mesti memahami ruang nama Linux. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!