docker volumes 文件映射方式
背景
在做區塊鏈日志模塊時,如果容器運行,需要把日志文件映射到宿主機上以方便查看。下面介紹一下我的實現方式。
實現
通過docker-compose配置文件volumes參數
配置文件示例:
volumes: - /var/run/:/host/var/run/ - ./channel-artifacts:/var/hyperledger/configs - ./fabric_logs:/tmp/fabric_logs/
把容器中/tmp/fabric_logs目錄映射到宿主機當前目錄下的./fabric_logs目錄下。這兩個目錄會共享數據。
創建容器時,代碼中配置相關參數
代碼中創建容器時添加:
func (vm *DockerVM) createContainer(ctxt context.Context, client dockerClient, imageID string, containerID string, args []string, env []string, attachStdout bool) error { volumes := make(map[string]struct{}) var mounts []docker.Mount var source string var destination string var fabricCfgPath = os.Getenv("FABRIC_CFG_PATH") var configName string _, err := os.Stat(fabricCfgPath) if err == nil { configName = strings.ToLower(Peer_Prefix) config := viper.New() config.SetConfigName(configName) config.AddConfigPath(fabricCfgPath) config.ReadInConfig() config.SetEnvPrefix("CORE") config.AutomaticEnv() replacer := strings.NewReplacer(".", "_") config.SetEnvKeyReplacer(replacer) config.SetConfigType("yaml") destination = config.GetString("logging.logpath") //fmt.Println(destination) } if destination == "" { destination = "/tmp/fabric_logs/" } source = "/tmp/chaincode_logs/" + containerID volumes[destination] = struct{}{} mount := docker.Mount{ Name: "bind", Source: source, Destination: destination, Mode: "rw", RW: true, Driver: "rprivate", } mounts = append(mounts, mount) config := docker.Config{Cmd: args, Image: imageID, Env: env, Volumes: volumes, Mounts: mounts, AttachStdout: attachStdout, AttachStderr: attachStdout} hostConfig := getDockerHostConfig() hostConfig.Binds = []string{ source + ":" + destination + ":rw", } copts := docker.CreateContainerOptions{Name: containerID, Config: &config, HostConfig: hostConfig} dockerLogger.Debugf("Create container: %s", containerID) _, err = client.CreateContainer(copts) if err != nil { return err } dockerLogger.Debugf("Created container: %s", imageID) return nil }
其中volumes,Mounts, Hostconfig.Binds參數需要按照自己的映射關系去填寫。
這樣和通過:
1、docker-compose 配置文件啟動
2、或者docker -v 參數命令行啟動
達到一樣效果。
補充:docker文件夾映射的兩種方式—主機卷映射和共享文件夾映射
docker容器不保持任何數據
重要數據請使用外部卷存儲(數據持久化)
容器可以掛載真實機目錄或共享存儲為卷
主機卷的映射
[root@docker1 ~]# mkdir /var/data [root@docker1 ~]# docker run -it -v /var/data:/abc myos [root@f1fb58b85671 /]# cd /abc/ [root@f1fb58b85671 abc]# touch f1 [root@f1fb58b85671 abc]# ls f1 zhy [root@docker1 ~]# cd /var/data/ [root@docker1 data]# ls f1 [root@docker1 data]# touch zhy
使用共享存儲的映射
思路:
將一臺主機做為nfs主機, 創建相應的文件夾,並將其共享給docker的兩臺主機,兩臺docker主機將分享的文件夾映射到容器中,使得對應的容器可以共享到nfs主機的內容。可以將http等服務器的相應的頁面文件夾使用這種形式,從而實現多個容器跑一個業務。
nfs主機配置【192.168.6.77】
[root@nfs ~]# yum -y install nfs-utils [root@nfs ~]# vim /etc/exports /public *(rw) [root@nfs ~]# systemctl restart nfs-server Failed to restart nfs-serve.service: Unit not found [root@nfs ~]# mkdir /public [root@nfs ~]# cd /public/ [root@nfs public]# touch nfs.txt [root@nfs public]# ls nfs.txt
docker1主機配置
[root@docker1 ~]# vim /etc/fstab 192.168.6.77:/public /mnt/nfs nfs defaults,_netdev 0 0 [root@docker1 ~]# mkdir /mnt/nfs [root@docker1 ~]# systemctl restart nfs-server [root@docker1 ~]# mount -a [root@docker1 ~]# df -h 192.168.6.77:/public 17G 3.2G 14G 19% /mnt/nfs [root@docker1 ~]# docker run -it -v /mnt/nfs/:/zhuhaiyan 192.168.6.153:5000/myos [root@c7c376e3755a /]# cd /zhuhaiyan [root@c7c376e3755a zhuhaiyan]# ls nfs.txt
docker2主機配置
[root@docker2 ~]# vim /etc/fstab 192.168.6.77:/public /mnt/nfs nfs defaults,_netdev 0 0 [root@docker2 ~]# mkdir /mnt/nfs [root@docker2 ~]# systemctl restart nfs-server [root@docker2 ~]# mount -a [root@docker2 ~]# df -h 192.168.6.77:/public 17G 3.2G 14G 19% /mnt/nfs [root@docker2 ~]# docker run -it -v /mnt/nfs/:/zhuhaiyan 192.168.6.153:5000/myos [root@cdd805771d07 /]# cd /zhuhaiyan/ [root@cdd805771d07 zhuhaiyan]# ls nfs.txt
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。如有錯誤或未考慮完全的地方,望不吝賜教。
推薦閱讀:
- docker如何對已經啟動的容器添加目錄映射(掛載目錄)
- Dockerfile 中 VOLUME 與 docker -v 的區別說明
- 開發者必備Docker命令小結
- Docker 存儲管理的幾種方式
- docker 添加端口及獲取dockerfile的方法