zl程序教程

您现在的位置是:首页 >  工具

当前栏目

构建Melis系统开发的Docker镜像

2023-09-11 14:15:47 时间

我们没有必要从头开始构建一个docker镜像完善开发系统,而是在一个相对完善的docker镜像的基础上加以扩展,达到我们的目的。

从doker hub获取原始镜像

执行

sudo docker pull gcc

下载后查看当前系统的docker镜像列表:

进入docker:

首先我们看一下系统当前是没有活动的docker容器的: 

此时,我们创建一个,并且将主机的home目录映射为容器的/data/目录

sudo docker run -it -v ~/:/data  gcc /bin/bash

start up command also can be:

sudo docker run -it -v ~/:/data  $docker_image_id /bin/bash

a record entry installed after each running session

the CONTAINER ID and NAMES item are dynamic allocated each running session.

 below two commands are used to manange the running session.

sudo docker stop 94ad6ab47180
sudo docker start 94ad6ab47180

if you wnat to inteactive with the docker,you can add -i option after above command

sudo docker start 94ad6ab4718 -i

同一个内核:

在docker中获取到的内核信息和在HOST主机中获取到的内核信息相同,说明docker用的是主机的内核。

构建melis系统:

我们一步一步来,首先我们把系统放在HOST共享目录中,通过容器去编译, 

a deep usage about docker please refer:

基于Docker环境的YOLCAT语意分割模型实验环境搭建_papaofdoudou的博客-CSDN博客_yolcat

other options on docker:

sudo docker exec 866a9a9a3221 ps -ef

above command just get the pid from the view of docker inside,but how to get the realy pid from the host? you can get use below commands:

sudo docker container top 866a9a9a3221

we can view the heriarchy of process by command;

pstree -p -H 308334 #308334 is a.out PID

sudo docker top serene_wu

see the log from the view of host

docker exec -d serene_wu sleep 2000
sudo docker logs serene_wu|more

docker related process

related is dockerd, containerd, containerd-shim

namespace of containerd-shim(305281)─┬─bash(305302)───a.out(308334)

containerd is in the same namespace with hosts init, and a.out in docker is in the same name space with the docker bash.

how to get the current namespace of process?

how to create  a namespace in helloworld?

#define _GNU_SOURCE
#include <fcntl.h>
#include <sched.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
 
#define STACK_SIZE	(1024 * 1024)	
 
int idle(void *args)
{
	printf("I'm child process, and my pid is: %d\n", getpid());
	for (;;) {
		sleep(1);
	}
 
	return 0;
}
 
pid_t clone_wrapper(int (*func)(void *), int flag, void *args)
{
	char *stack, *stack_top;
	
	stack = (char *)malloc(STACK_SIZE);
	if (stack == NULL) {
		printf("alloc stack for child failed!\n");
		return -1;
	}
	stack_top = stack + STACK_SIZE;  /* Assume stack grows downward */
 
	return clone(func, stack_top, flag , args);
}
 
char *get_pid_ns(int pid)
{
	char bytes[32];
	
	sprintf(bytes, "/proc/%d/ns/pid", pid);
	return strdup(bytes);
}
 
int main(void)
{
	pid_t childs[2];
	char *ns_file;
	int fd;
 
	printf("I'm parent, and my pid is: %d\n", getpid());
 
	childs[0] = clone_wrapper(idle, CLONE_NEWPID, NULL);
	if (childs[0] == -1) {
		printf("error: create child thread failed!\n");
		return -1;
	}
	printf("first child's pid is: %d\n", childs[0]);
 
	ns_file = get_pid_ns(childs[0]);
	printf("%s line %d, nsfile %s.\n", __func__, __LINE__, ns_file);
	if (!ns_file) {
		printf("get child pid ns failed!\n");
		return -1;
	}
 
	fd = open(ns_file, O_RDONLY);
	if (fd == -1) {
		printf("open child pid ns failed!\n");
		return -1;
	}
 
	if (setns(fd, 0) == -1) {
		printf("set ns failed!\n");
		return -1;
	}
 
	printf("I'm parent, and my pid is: %d\n", getpid());
 
	childs[1] = clone_wrapper(idle, 0, NULL);
	if (childs[1] == -1) {
		printf("error: create child thread failed!\n");
		return -1;
	}
	printf("second child's pid is: %d\n", childs[1]);
 
	sleep(3);
 
	kill(childs[0], SIGTERM);
	kill(childs[1], SIGTERM);
 
	waitpid(childs[0], NULL, 0);
	waitpid(childs[1], NULL, 0);
 
	return 0;
}

reference

理解Docker容器的进程管理 - ilinux_one - 博客园


结束!