美文网首页
[mydocker]---实现容器指定环境变量

[mydocker]---实现容器指定环境变量

作者: nicktming | 来源:发表于2019-05-12 08:41 被阅读0次

1. 准备工作

1.1 准备环境

root@nicktming:~/go/src/github.com/nicktming/mydocker# git clone https://github.com/nicktming/mydocker.git
root@nicktming:~/go/src/github.com/nicktming/mydocker# git checkout code-5.7.2
root@nicktming:~/go/src/github.com/nicktming/mydocker# git checkout -b dev-5.8

1.2 准备busybox.tar

// 前提条件
root@nicktming:/nicktming# pwd
/nicktming
root@nicktming:/nicktming# ls
busybox.tar

2. 实现

2.1 增加环境变量参数

增加环境变量参数e.

var RunCommand = cli.Command{
    Name: "run",
    Flags: []cli.Flag {
        ...
        cli.StringSliceFlag{
            Name: "e",
            Usage: "set environment",
        },
        ...
    },
    Action: func(c *cli.Context) error {
        ...
        envSlice := c.StringSlice("e")
        ...

        Run(command, tty, &cg, rootPath, volumes, containerName, imageName, envSlice)
        return nil
    },
}

2.2 修改Run方法

func Run(command string, tty bool, cg *cgroups.CroupManger, rootPath string, volumes []string, containerName, imageName string, envSlice []string)  {
    ...
    cmd := exec.Command(initCmd, "init")
    cmd.Env = append(os.Environ(), envSlice...)
    ...
}

将增加的环境变量放入到容器中.

2.3 测试

// -it 的形式没有问题
root@nicktming:~/go/src/github.com/nicktming/mydocker# go build .
root@nicktming:~/go/src/github.com/nicktming/mydocker# ./mydocker run -it -e name=nicktming busybox /bin/sh
2019/04/19 22:44:30 rootPath is empaty, set rootPath: /nicktming
2019/04/19 22:44:30 current path: /nicktming/mnt/15556850702382348471.
/ # env | grep name
name=nicktming
/ # exit
root@nicktming:~/go/src/github.com/nicktming/mydocker# 

// 后台运行
root@nicktming:~/go/src/github.com/nicktming/mydocker# ./mydocker run -d -name container01 -e name=nicktming busybox /bin/top
2019/04/19 23:03:28 rootPath is empaty, set rootPath: /nicktming
root@nicktming:~/go/src/github.com/nicktming/mydocker# ./mydocker exec container01 /bin/sh
2019/04/19 23:03:43 containerName:container01,command:/bin/sh
/ # env | grep name
/ # exit
root@nicktming:~/go/src/github.com/nicktming/mydocker# 

后台运行的容器再次进入容器的时候发现得不到环境变量. 这是因为exec本身启动的是另外一个进程, 只不过与后台的那个进程拥有相同的namespace. 具体可以参考[mydocker]---实现进入容器Namespace. 由于环境变量是继承自父进程的,所以exec命令启动的那个进程是继承自宿主机的, 因此在exec 进程内看到的环境变量其实是宿主机的环境变量.

2.4 增加exec命令获得环境变量

func Exec(containerName, command string) {
    ...
    containerEnvs := getEnvsByPid(containerInfo.Pid)
    cmd.Env = append(os.Environ(), containerEnvs...)
    ...
}

func getEnvsByPid(pid string) []string {
    path := fmt.Sprintf("/proc/%s/environ", pid)
    contentBytes, err := ioutil.ReadFile(path)
    if err != nil {
        log.Printf("Read file %s error %v", path, err)
        return nil
    }
    envs := strings.Split(string(contentBytes), "\u0000")
    return envs
}

由于进程存放环境变量的位置是/proc/<PID >/environ, 因此根据给定的PID 去读取这个文件,便可以获取环境变量。在文件的内容中,每个环境变量之间是通过\u0000分割的,因此以此为标记来获取环境变量数组。

2.5 测试后台容器

root@nicktming:~/go/src/github.com/nicktming/mydocker# go build .
root@nicktming:~/go/src/github.com/nicktming/mydocker# ./mydocker ps
ID                     NAME          PID         STATUS      COMMAND     CREATED
15556862082746239371   container01   3176        running     /bin/top    2019-04-19 23:03:28
root@nicktming:~/go/src/github.com/nicktming/mydocker# ./mydocker exec container01 /bin/sh
2019/04/19 23:17:00 containerName:container01,command:/bin/sh
/ # env | grep name
name=nicktming
/ # exit
root@nicktming:~/go/src/github.com/nicktming/mydocker# 

3. 参考

1. 自己动手写docker.(基本参考此书,加入一些自己的理解,加深对docker的理解)

4. 全部内容

mydocker.png

1. [mydocker]---环境说明
2. [mydocker]---urfave cli 理解
3. [mydocker]---Linux Namespace
4. [mydocker]---Linux Cgroup
5. [mydocker]---构造容器01-实现run命令
6. [mydocker]---构造容器02-实现资源限制01
7. [mydocker]---构造容器02-实现资源限制02
8. [mydocker]---构造容器03-实现增加管道
9. [mydocker]---通过例子理解存储驱动AUFS
10. [mydocker]---通过例子理解chroot 和 pivot_root
11. [mydocker]---一步步实现使用busybox创建容器
12. [mydocker]---一步步实现使用AUFS包装busybox
13. [mydocker]---一步步实现volume操作
14. [mydocker]---实现保存镜像
15. [mydocker]---实现容器的后台运行
16. [mydocker]---实现查看运行中容器
17. [mydocker]---实现查看容器日志
18. [mydocker]---实现进入容器Namespace
19. [mydocker]---实现停止容器
20. [mydocker]---实现删除容器
21. [mydocker]---实现容器层隔离
22. [mydocker]---实现通过容器制作镜像
23. [mydocker]---实现cp操作
24. [mydocker]---实现容器指定环境变量
25. [mydocker]---网际协议IP
26. [mydocker]---网络虚拟设备veth bridge iptables
27. [mydocker]---docker的四种网络模型与原理实现(1)
28. [mydocker]---docker的四种网络模型与原理实现(2)
29. [mydocker]---容器地址分配
30. [mydocker]---网络net/netlink api 使用解析
31. [mydocker]---网络实现
32. [mydocker]---网络实现测试

相关文章

网友评论

      本文标题:[mydocker]---实现容器指定环境变量

      本文链接:https://www.haomeiwen.com/subject/mihhgqtx.html