https://github.com/docker/distribution
daocloud
數人雲
時速雲
http://jpetazzo.github.io/2014/06/23/docker-ssh-considered-evil/ 容器為什么不用ssh去連接
https://github.com/jpetazzo/nsenter 同上
https://segmentfault.com/a/1190000002931564 Docker 環境 Storage Pool 用完解決方案:resize-device-mapper
http://www.oschina.net/news/57894/daocloud
http://blog.csdn.net/qinyushuang/article/details/43342553 Docker學習筆記(3)-- 如何使用Dockerfile構建鏡像
http://geek.csdn.net/news/detail/35121 docker鏡像
http://www.csdn.net/article/2014-11-18/2822693 鏡像與容器分析
http://www.blogjava.net/yongboy/archive/2013/12/12/407498.html Docker學習筆記之一,搭建一個JAVA Tomcat運行環境
DOCKER_STORAGE_OPTIONS=-s devicemapper --storage-opt dm.datadev=/home/dock-data --storage-opt dm.metadatadev=/home/dock-meta
為了解決報錯,要設置以上變量
結果卻明白了字符設備與塊設備的區別,以上創建的是一個普通文件,也就是一個字符設備,
[root@docker1 ~]# docker run busybox /bin/echo Hello Docker
Usage of loopback devices is strongly discouraged for production use. Either use `--storage-opt dm.thinpooldev` or use `--storage-optl dm.no_warn_on_loop_devices=true` to suppress this warning.
The warning message occurs because your Docker storage configuration is using a "loopback device" -- a virtual block device such as /dev/loop0 that is actualled backed by a file on your filesystem. This was never meant as anything more than a quick hack to get Docker up and running quickly as a proof of concept.
You don't want to suppress the warning; you want to fix your storage configuration such that the warning is no longer issued. The easiest way to do this is to assign some local disk space for use by Docker's devicemapper storage driver and use that.
If you're using LVM and have some free space available on your volume group, this is relatively easy. For example, to give docker 100G of space, first create a data and metadata volume:
# lvcreate -n docker-data -L 100G /dev/my-vg
# lvcreate -n docker-metadata -L1G /dev/my-vg
And then configure Docker to use this space by editing /etc/sysconfig/docker-storage to look like:
DOCKER_STORAGE_OPTIONS=-s devicemapper --storage-opt dm.datadev=/dev/my-vg/docker-data --storage-opt dm.metadatadev=/dev/my-vg/docker-metadata
If you're not using LVM or don't have free space available on your VG, you could expose some other block device (e.g., a spare disk or partition) to Docker in a similar fashion.
DOCKER_STORAGE_OPTIONS=-s devicemapper --storage-opt dm.datadev=/home/dock-data --storage-opt dm.metadatadev=/home/dock-meta
[root@kvm1 docker]# touch dock-data
[root@kvm1 docker]# touch dock-meta
[root@kvm1 docker]# systemctl start docker
[root@kvm1 docker]# systemctl status docker -l
docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled)
Active: inactive (dead) since Thu 2016-06-16 21:09:37 CST; 7s ago
Docs: http://docs.docker.com
Process: 9190 ExecStart=/bin/sh -c /usr/bin/docker-current daemon $OPTIONS $DOCKER_STORAGE_OPTIONS $DOCKER_NETWORK_OPTIONS $ADD_REGISTRY $BLOCK_REGISTRY $INSECURE_REGISTRY 2>&1 | /usr/bin/forward-journald -tag docker (code=exited, status=0/SUCCESS)
Main PID: 9190 (code=exited, status=0/SUCCESS)
Jun 16 21:09:36 kvm1.zf.com systemd[1]: Starting Docker Application Container Engine...
Jun 16 21:09:36 kvm1.zf.com forward-journal[9194]: Forwarding stdin to journald using Priority Informational and tag docker
Jun 16 21:09:37 kvm1.zf.com forward-journal[9194]: time="2016-06-16T21:09:37.023360992+08:00" level=error msg="Error getblockdevicesize: inappropriate ioctl for device"
Jun 16 21:09:37 kvm1.zf.com forward-journal[9194]: time="2016-06-16T21:09:37.023710458+08:00" level=fatal msg="Error starting daemon: error initializing graphdriver: Can't get data size Can't get block size"
Jun 16 21:09:37 kvm1.zf.com systemd[1]: Started Docker Application Container Engine.
Jun 16 21:08:12 kvm1.zf.com forward-journal[9050]: Forwarding stdin to journald using Priority Informational and tag docker
Jun 16 21:08:12 kvm1.zf.com forward-journal[9050]: time="2016-06-16T21:08:12.586347689+08:00" level=fatal msg="Error starting daemon: error initializing graphdriver: open /home/docker/dock-data: is a directory"
構建鏡像
構建鏡像的兩種方法: 使用docker commit 命令 使用docker build命令和Dockerfile文件 Dockerfile更搶到、靈活,推薦使用。 一般來說不是真的“創建”新鏡像,而是基於一個已有的基礎鏡像,比如Ubuntu、Fedora等,構建新的鏡像而已。從零構建一個全新的鏡像可參考這篇文章
https://docs.docker.com/engine/userguide/eng-image/baseimages/ 從頭構建鏡像--create a base image
運行,修改,保存鏡像,然后上傳到私服上,就可以作為公共鏡像來被下載使用了。
1261 docker run -it centos bash
1263 docker ps -l
1264 docker commit 949 centos-man
1265 docker images
鏡像地址
echo “DOCKER_OPTS=\”\$DOCKER_OPTS –registry-mirror=http://your-id.m.daocloud.io -d\”” >> /etc/default/docker
sudo sed -i 's|other_args="|other_args="--registry-mirror=http://a984be05.m.daocloud.io |g' /etc/sysconfig/docker
sudo sed -i "s|OPTIONS='|OPTIONS='--registry-mirror=http://a984be05.m.daocloud.io |g" /etc/sysconfig/docker
sudo sed -i 'N;s|\[Service\]\n|\[Service\]\nEnvironmentFile=-/etc/sysconfig/docker\n|g' /usr/lib/systemd/system/docker.service
sudo sed -i 's|fd://|fd:// $other_args |g' /usr/lib/systemd/system/docker.service
sudo systemctl daemon-reload
sudo service docker restart
搭建私服
http://lishaofengstar.blog.163.com/blog/static/131972852201411585441354/
這篇博客討論了如何部署一個帶 SSL 加密、HTTP 驗證並有防火牆防護的私有 Docker Registry 。Docker Registry是一個存儲和分享 Docker 鏡像的服務。本文中我們使用的操作系統是 Ubuntu,任何支持 Upstart 的系統都可以。我們用 Nginx 作為 Docker Registry 的前端代理服務器,同時也用 Nginx 完成 SSL 加密和基本的 HTTP 驗證。我們用 Gunicorn 運行 Docker Registry 並用 Upstart 管理 Gunicorn。我們還用 Redis 實現一個 LRU(Least Recently Used,近期最少使用算法) 緩存機制來減少 Docker Registry 和硬盤之間的數據存取。
https://github.com/docker/distribution/blob/master/docs/deploying.md$ docker pull samalba/docker-registry $ docker run -d -p 5000:5000 samalba/docker-registry # 我們先pull下來一個簡單的鏡像(或者自己做一個也可以) $ docker pull busybox $ docker tag busybox localhost:5000/busybox $ docker push localhost:5000/busybox
https://segmentfault.com/a/1190000000801162
docker-registry既然也是軟件應用,自然最簡單的方法就是使用官方提供的已經部署好的鏡像registry。官方文檔中也給出了建議,直接運行sudo docker run -p 5000:5000 registry
命 令。這樣確實能啟動一個registry服務器,但是所有上傳的鏡像其實都是由docker容器管理,放在了/var/lib/docker/....某 個目錄下。而且一旦刪除容器,鏡像也會被刪除。因此,我們需要想辦法告訴docker容器鏡像應該存放在哪里。registry鏡像中啟動后鏡像默認位置 是/tmp/registry
,因此直接映射這個位置即可,比如到本機的/opt/data/registry
目錄下。
[root@kvm2 mnt]# docker run -d -p 5000:5000 -v /root/my_registry:/tmp/registry registry
先做一個私服,順便就啟動了。通過下面的docker ps可以看到。 [root@kvm2 mnt]# docker run -d -p 5000:5000 --restart=always --name registry registry:2 Unable to find image 'registry:2' locally Trying to pull repository docker.io/library/registry ... 2: Pulling from library/registry 17bd2058e0c6: Pull complete 3f0d3d140ce1: Pull complete 47339bdfc690: Pull complete 03a7f8ec3d4f: Pull complete d2501a6dc689: Pull complete 9ca18bbd0cd5: Pull complete dd0dda9b2298: Pull complete 79ec4549598b: Pull complete 5d322e774cf2: Pull complete Digest: sha256:c5455f3918e5235e641bb6d8dc8ff0780df197d5df12c589bf0c283e25fc0650 Status: Downloaded newer image for docker.io/registry:2 cf3554af4427c2700fbc2ffecf02332cf4087dd07c8da53ebf0dd54db9d2323a Usage of loopback devices is strongly discouraged for production use. Either use `--storage-opt dm.thinpooldev` or use `--storage-opt dm.no_warn_on_loop_devices=true` to suppress this warning. [root@kvm2 mnt]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES cf3554af4427 registry:2 "/bin/registry serve " 10 seconds ago Up 8 seconds 0.0.0.0:5000->5000/tcp registry 查看鏡像,多了個registry:2 [root@kvm2 mnt]# docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE centos-man latest 44cc4eec11d1 About an hour ago 282.4 MB docker.io/registry 2 5d322e774cf2 7 days ago 171.5 MB docker.io/httpd latest 6bce6ad2c6a9 9 days ago 198.5 MB docker.io/centos latest a65193109361 2 weeks ago 196.7 MB 將本地的centos-man打標為man
為需要push到私有registry的image打tag [root@kvm2 mnt]# docker tag centos-man localhost:5000/man [root@kvm2 mnt]# docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE localhost:5000/man latest 44cc4eec11d1 About an hour ago 282.4 MB centos-man latest 44cc4eec11d1 About an hour ago 282.4 MB docker.io/registry 2 5d322e774cf2 7 days ago 171.5 MB docker.io/httpd latest 6bce6ad2c6a9 9 days ago 198.5 MB docker.io/centos latest a65193109361 2 weeks ago 196.7 MB 然后將本地的man推送到私服里 [root@kvm2 mnt]# docker push localhost:5000/man The push refers to a repository [localhost:5000/man] (len: 1) 44cc4eec11d1: Pushed a65193109361: Pushed df0fc3863fbc: Pushed latest: digest: sha256:9b95cacf2aa3a4fb25ed897dd7233cd135708d527cde54d86119e221a7f8201f size: 4621
docker1上命令順序
存儲
制作本地其他分區存儲或VG,而不使用loop設備
[root@localhost ~]# vi /usr/lib/docker-storage-setup/docker-storage-setup
[root@localhost ~]# docker-storage-setup
鏡像
sed -i "s|OPTIONS='|OPTIONS='--registry-mirror=http://a984be05.m.daocloud.io |g" /etc/sysconfig/docker
systemctl restart docker
私服
docker run -d -p 5000:5000 --restart=always --name registry registry:2
docker pull httpd
31 docker run -p 8076:80 -d -it httpd
35 docker exec eb7 ls /usr/local/apache2/htdocs
37 docker cp index.html eb7:/usr/local/apache2/htdocs
38 docker commit eb7 httpd-gai
39 docker images
40 docker ps
41 docker tag httpd-gai localhost:5000/gai
42 docker ps
43 docker images
44 docker push localhost:5000/gai
docker2上命令順序
制作本地其他分區存儲或VG,而不使用loop設備
[root@localhost ~]# vi /usr/lib/docker-storage-setup/docker-storage-setup
[root@localhost ~]# docker-storage-setup
以下是在另外一個機器上拉取pull剛才在上面主機上發布push的鏡像 先修改下面這個文件,去掉注釋,加入ip,因為使用的是https [root@my graph]# vi /etc/sysconfig/docker INSECURE_REGISTRY='--insecure-registry 192.168.1.22:5000' 然后再拉取,運行,修改文件,瀏覽器測試訪問, [root@my graph]# docker pull 192.168.1.22:5000/man
698 docker run -d -p 7965:80 192.168.10.112:5000/gai
699 docker ps
700 ip addr
701 docker ps
702 vi index.html
703 docker cp index.html 8d0:/usr/local/apache2/htdocs
看json格式文件用cat json |python -mjson.tool
[root@kvm2 1544084fad81e27c28a8c12c08b2439451fd1e745e38c1dcecd862d240c4235e]# pwd
/var/lib/docker/graph/1544084fad81e27c28a8c12c08b2439451fd1e745e38c1dcecd862d240c4235e
[root@kvm2 1544084fad81e27c28a8c12c08b2439451fd1e745e38c1dcecd862d240c4235e]# cat json |python -mjson.tool { "container_config": { "AttachStderr": false, "AttachStdin": false, "AttachStdout": false, "Cmd": [ "/bin/sh -c #(nop) MAINTAINER The CentOS Project <cloud-ops@centos.org>" ], "Domainname": "", "Entrypoint": null, "Env": null, "Hostname": "", "Image": "", "Labels": null, "OnBuild": null, "OpenStdin": false, "StdinOnce": false, "Tty": false, "User": "", "Volumes": null, "WorkingDir": "" }, "created": "2015-09-07T19:05:48.678585881Z", "layer_id": "sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4" } [root@kvm2 1544084fad81e27c28a8c12c08b2439451fd1e745e38c1dcecd862d240c4235e]# cat json {"container_config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":["/bin/sh -c #(nop) MAINTAINER The CentOS Project \u003ccloud-ops@centos.org\u003e"],"Image":"","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"created":"2015-09-07T19:05:48.678585881Z","layer_id":"sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4"}[root@kvm2 1544084fad81e27c28a8c12c08b2439451fd1e745e38c1dcecd862d240c4235e]#
[root@kvm2 graph]# docker images -tree flag provided but not defined: -tree See '/usr/bin/docker-current images --help'. [root@kvm2 graph]# ll
total 0
drwx------ 2 root root 93 Jun 17 14:30 1544084fad81e27c28a8c12c08b2439451fd1e745e38c1dcecd862d240c4235e
drwx------ 2 root root 93 Jun 17 15:00 a3d54b467fad81f4b33c161c8a227c66cb45733ba5bbfdd971942083e6c666c7
drwx------ 2 root root 93 Jun 17 15:00 a65193109361c1c55a0baa79c2167ec417b977f284b3358f4d50b81e22f84ec5
drwx------ 2 root root 93 Jun 17 15:00 df0fc3863fbc60ba8576521b1ecb89133e66941ceef9b57716ccda2454c9e6fc
drwx------ 2 root root 6 Jun 17 15:00 _tmp
總共4層,一層依賴於一層 [root@kvm2 graph]# docker images -a REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE docker.io/centos latest a65193109361 2 weeks ago 196.7 MB <none> <none> a3d54b467fad 2 weeks ago 196.7 MB <none> <none> df0fc3863fbc 2 weeks ago 196.7 MB <none> <none> 1544084fad81 9 months ago 0 B
最后,當從一個鏡像啟動容器時,Docker會在該鏡像的最頂層加載一個讀寫文件系統。我們想在Docker中運行的程序就是在這個讀寫層中執行的。
從上面我們可以知道容器的writable 層是保存在以容器ID為名的長ID目錄里的,而ID+init后綴目錄是保存容器的初始信息的。
構建鏡像中很重要的一環就是如何共享和發布鏡像。可以將鏡像推送到Docker Hub或者用戶自己的私有Registry中。為了完成這項工作,需要在Docker Hub上創建一個賬號
[root@kvm2 docker]# docker-storage-setup ERROR: Docker has been previously configured for use with devicemapper graph driver. Not creating a new thin pool as existing docker metadata will fail to work with it. Manual cleanup is required before this will succeed. INFO: Docker state can be reset by stopping docker and by removing /var/lib/docker directory. This will destroy existing docker images and containers and all the docker metadata. [root@kvm2 docker]# docker images [root@kvm2 lib]# systemctl stop docker [root@kvm2 lib]# rm -rf /var/lib/docker/ [root@kvm2 lib]# docker-storage-setup Rounding up size to full physical extent 956.00 MiB Volume group "centos" has insufficient free space (16 extents): 239 required. [root@kvm2 lib]# vgdisplayr --- Volume group --- VG Name centos System ID Format lvm2 Metadata Areas 1 Metadata Sequence No 4 VG Access read/write VG Status resizable MAX LV 0 Cur LV 3 Open LV 3 Max PV 0 Cur PV 1 Act PV 1 VG Size 931.02 GiB PE Size 4.00 MiB Total PE 238341 Alloc PE / Size 238325 / 930.96 GiB Free PE / Size 16 / 64.00 MiB VG UUID njw2Ue-6opd-mjxl-7wVW-reJE-wAMf-54yF4t
所以先要留出一些分區空間,才能使用上面的命令,因為docker-storage-setup這個命令要使用塊設備。
[root@localhost ~]# lvremove -v /dev/docker/docker-data
Using logical volume(s) on command line.
Do you really want to remove active logical volume docker-data? [y/n]: y
Removing docker-docker--data (253:2)
Archiving volume group "docker" metadata (seqno 2).
Releasing logical volume "docker-data"
Creating volume group backup "/etc/lvm/backup/docker" (seqno 3).
Logical volume "docker-data" successfully removed
如果不修改/usr/lib/docker-storage-setup/docker-storage-setup這個文件的DEVS和VG行,就會出現下面的報錯。
[root@localhost ~]# docker-storage-setup
Rounding up size to full physical extent 52.00 MiB
Volume group "centos" has insufficient free space (11 extents): 13 required.
一定修改/usr/lib/docker-storage-setup/docker-storage-setup這個文件,修改/etc/sysconfig/docker-storage-setup這個文件會報各種問題
# cat <<EOF > /etc/sysconfig/docker-storage-setup DEVS=/dev/vdb VG=docker-vg EOF
下面的是給定的VG容量不夠的輸出。
[root@localhost ~]# docker-storage-setup
Rounding up size to full physical extent 52.00 MiB
Logical volume "docker-poolmeta" created.
INFO: DATA_SIZE=40%FREE is smaller than MIN_DATA_SIZE=2G. Will create data volume of size specified by MIN_DATA_SIZE.
Logical volume "docker-pool" created.
WARNING: Converting logical volume docker/docker-pool and docker/docker-poolmeta to pool's data and metadata volumes.
THIS WILL DESTROY CONTENT OF LOGICAL VOLUME (filesystem etc.)
Converted docker/docker-pool to thin pool.
Logical volume "docker-pool" changed.
[root@localhost ~]# vi /usr/lib/docker-storage-setup/docker-storage-setup
[root@localhost ~]# docker-storage-setup
Rounding up size to full physical extent 24.00 MiB
Logical volume "docker-poolmeta" created.
Logical volume "docker-pool" created.
WARNING: Converting logical volume docker/docker-pool and docker/docker-poolmeta to pool's data and metadata volumes.
THIS WILL DESTROY CONTENT OF LOGICAL VOLUME (filesystem etc.)
Converted docker/docker-pool to thin pool.
Logical volume "docker-pool" changed.
上面啟動好后,fdisk -l 會發現下面的幾個卷,而在/var/lib/docker/devicemapper/下面已沒有devicemapper子目錄,證明沒有用/dev/loop0和/dev/loop1兩個回環設備。
Disk /dev/mapper/docker-docker--pool_tmeta: 25 MB, 25165824 bytes, 49152 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk /dev/mapper/docker-docker--pool_tdata: 8577 MB, 8577351680 bytes, 16752640 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk /dev/mapper/docker-docker--pool: 8577 MB, 8577351680 bytes, 16752640 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 524288 bytes / 524288 bytes
Disk /dev/mapper/docker-253:0-34783213-a931702e612b6d6e2c6cb63d93f9ae19a5c309e6eb18443e32bf52f01ebabb21: 107.4 GB, 107374182400 bytes, 209715200 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 524288 bytes / 524288 bytes
[root@localhost lvm]# docker-storage-setup
ERROR: Found LVM2_member signature on device /dev/vdb at offset 0x218. Wipe signatures using wipefs or use WIPE_SIGNATURES=true and retry.
[root@localhost lvm]# vi /etc/sysconfig/docker-storage-setup
[root@localhost lvm]# docker-storage-setup
INFO: Wipe Signatures is set to true. Any signatures on /dev/vdb will be wiped.
wipefs: error: /dev/vdb: probing initialization failed: Device or resource busy
ERROR: Failed to wipe signatures on device /dev/vdb
[root@localhost ~]# docker-storage-setup
Checking that no-one is using this disk right now ...
OK
Disk /dev/vdb: 104025 cylinders, 16 heads, 63 sectors/track
sfdisk: /dev/vdb: unrecognized partition table type
Old situation:
sfdisk: No partitions found
New situation:
Units: sectors of 512 bytes, counting from 0
Device Boot Start End #sectors Id System
/dev/vdb1 2048 104857599 104855552 8e Linux LVM
/dev/vdb2 0 - 0 0 Empty
/dev/vdb3 0 - 0 0 Empty
/dev/vdb4 0 - 0 0 Empty
Warning: partition 1 does not start at a cylinder boundary
Warning: partition 1 does not end at a cylinder boundary
Warning: no primary partition is marked bootable (active)
This does not matter for LILO, but the DOS MBR will not boot this disk.
Successfully wrote the new partition table
Re-reading the partition table ...
If you created or changed a DOS partition, /dev/foo7, say, then use dd(1)
to zero the first 512 bytes: dd if=/dev/zero of=/dev/foo7 bs=512 count=1
(See fdisk(8).)
Physical volume "/dev/vdb1" successfully created
Volume group "docker1" successfully created
ERROR: Old mode of passing data and metadata logical volumes to docker is not supported. Exiting.
aufs: AUFS (AnotherUnionFS) 是一種Union FS,簡單來說就是支持將不同目錄掛載到同一個虛擬文件系統下的文件系統。Aufs driver是Docker最早支持的driver,但是aufs只是Linux內核的一個補丁集,而且不太可能會被加入到Linux內核中。但是由於aufs是唯一一個可以實現容器間共享可執行代碼和運行庫的storage driver,所以當你跑成千上百個擁有相同程序代碼或者運行庫的時候,aufs是個相當不錯的選擇。 device mapper: Device mapper是Linux 2.6內核中提供的一種從邏輯設備到物理設備的映射框架機制,在該機制下,用戶可以很方便的根據自己的需要制定實現存儲資源的管理策略。 Device mapper driver會創建一個100G的簡單文件包含你的鏡像和容器。每一個容器被限制在10G大小的卷內, 可以調整。 你可以在啟動Docker daemon時用參數-s 指定driver:docker -d -s devicemapper。 Btrfs: Btufs driver 在Docker build時可以很高效。但是跟device mapper一樣不支持設備間共享存儲。
在沒有aufs支持的Linux發行版本上(CentOS、openSUSE等),安裝Docker可能就使用了device mapper driver。
查看你的Linux發行版有沒有aufs支持:lsmod | grep aufs
最后,當從一個鏡像啟動容器時,Docker會在該鏡像的最頂層加載一個讀寫文件系統。我們想在Docker中運行的程序就是在這個讀寫層中執行的。
從上面我們可以知道容器的writable 層是保存在以容器ID為名的長ID目錄里的,而ID+init后綴目錄是保存容器的初始信息的。
構建鏡像中很重要的一環就是如何共享和發布鏡像。可以將鏡像推送到Docker Hub或者用戶自己的私有Registry中。為了完成這項工作,需要在Docker Hub上創建一個賬號
docker run -d -p 50001:22 ubuntu/ruby:v2 /usr/sbin/sshd -D 一般容器不開sshd
容器與主機互傳文件兩種方法:cp與-v
docker run -d -p 7965:80 192.168.10.112:5000/gai 將主機的目錄掛在容器的/mnt下
#docker run -d -p 5000:5000 -v /root/my_registry:/tmp/registry registry docker run -d -p 7965:80 -v /home/zf/:/mnt 192.168.10.112:5000/gai ./ent.sh 8d0
[root@my jj]# docker run -v /tmp/vol1 --name="vol2" -it 45b
[root@my jj]# docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3176547d7062 45b "bash" 12 seconds ago Exited (0) 5 seconds ago vol2
[root@my jj]# docker start 317
317
[root@my jj]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3176547d7062 45b "bash" 28 seconds ago Up 2 seconds vol2
c949de9826f5 192.168.1.22:5000/httpd-b "httpd-foreground" 24 hours ago Up 51 minutes 0.0.0.0:7975->80/tcp jovial_engelbart
30b3bd502c74 192.168.1.22:5000/httpd-a "httpd-foreground" 24 hours ago Up 51 minutes 0.0.0.0:7965->80/tcp ecstatic_kare
[root@my ~]# ./aa.sh 317
Last login: Tue Jun 21 07:45:04 UTC 2016
[root@3176547d7062 ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/docker-253:0-67459471-3176547d70627f3a125f734ea145163eceaa367e45ad31534eef86be91d6ae60 100G 306M 100G 1% /
tmpfs 493M 0 493M 0% /dev
tmpfs 493M 0 493M 0% /sys/fs/cgroup
tmpfs 493M 0 493M 0% /run/secrets
/dev/mapper/centos-root 48G 2.7G 45G 6% /tmp/vol1
shm 64M 0 64M 0% /dev/shm
與容器交互數據的不同方式 有-v方式本機目錄與容器目錄之間共享數據,查看對比如下 docker run -v /home/ff:/mnt/ -it 45b [root@my ff]# cp /root/RanZhi.3.3.zbox_64.tar.gz ./ [root@my ff]# /root/aa.sh b7d Last login: Tue Jun 21 08:00:31 UTC 2016 [root@b7d745dac2c4 ~]# cd /mnt/ [root@b7d745dac2c4 mnt]# ls RanZhi.3.3.zbox_64.tar.gz foef passwd [root@my ff]# cp /root/aa.sh ./ [root@my ff]# docker exec b7d ls /mnt RanZhi.3.3.zbox_64.tar.gz aa.sh foef passwd 有-v方式 docker run -v /tmp/vol1 --name="vol2" -it 45b 容器里面的路徑是/tmp/vol1 [root@my ~]# docker inspect -f '{{.State.StartedAt}}' 317 2016-06-21T07:43:44.775004038Z docker inspect -f '{{.Mounts}}' 317 獲取volume在主機中的路徑 touch /var/lib/docker/volumes/81557ef21a02e117585e41dba692a70eed5a9d7d96195679edc397e6dfecd835/_data/eif 所以只需要往_data這個目錄里復制文件即可
數據卷共享,容器之間共享卷。 docker run -it --volumes-from 317 45b 這樣會將上面容器317中的/tmp/vol1掛到新容器之中,因為新容器與317容器使用同一個卷,就是
/var/lib/docker/volumes/81557ef21a02e117585e41dba692a70eed5a9d7d96195679edc397e6dfecd835/_data
容器啟動時沒有-v選項,就用docker cp 來處理 [root@my ff]# docker cp /root/RanZhi.3.3.zbox_64.tar.gz c94:/usr/local/apache2/htdocs/ [root@my ff]# docker exec c94 ls /usr/local/apache2/htdocs RanZhi.3.3.zbox_64.tar.gz anaconda-ks.cfg world.sql
交互腳本 主要利用nsenter.
util-linux包中含有nsenter.
[root@my ~]# ./aa.sh 30b
nsenter: failed to execute su: No such file or directory
如果出現上面的報錯,只需要將腳本里的su改為/bin/su.原因是容器中的PATH 路徑問題,使用/bin/su 即可。
#!/bin/sh if [ -e $(dirname "$0")/nsenter ]; then # with boot2docker, nsenter is not in the PATH but it is in the same folder NSENTER=$(dirname "$0")/nsenter else NSENTER=nsenter fi if [ -z "$1" ]; then echo "Usage: `basename "$0"` CONTAINER [COMMAND [ARG]...]" echo "" echo "Enters the Docker CONTAINER and executes the specified COMMAND." echo "If COMMAND is not specified, runs an interactive shell in CONTAINER." else PID=$(docker inspect --format "{{.State.Pid}}" "$1") if [ -z "$PID" ]; then exit 1 fi shift OPTS="--target $PID --mount --uts --ipc --net --pid --" if [ -z "$1" ]; then # No command given. # Use su to clear all host environment variables except for TERM, # initialize the environment variables HOME, SHELL, USER, LOGNAME, PATH, # and start a login shell. "$NSENTER" $OPTS su - root else # Use env to clear all host environment variables. "$NSENTER" $OPTS env --ignore-environment -- "$@" fi fi
c/s本地與遠程訪問
vi /etc/sysconfig/docker
要使遠程可以訪問就加入-H 0.0.0.0:5555監聽端口,否則就只能本地訪問。
要本地與遠程同時可以訪問就加入-H 0.0.0.0:5555和-H unix:///var/run/docker.sock。
OPTIONS='-H 0.0.0.0:5555 --registry-mirror=http://a984be05.m.daocloud.io --registry-mirror=http://a984be05.m.daocloud.io --selinux-enabled'
docker -H 192.168.1.22:5555 images
docker -H 192.168.1.22:5555 ps
默認情況下,Docker守護進程會生成一個socket(/var/run/docker.sock)文件來進行本地進程通信,而不會監聽任何端口,因此只能在本地使用docker客戶端或者使用Docker API進行操作。 如果想在其他主機上操作Docker主機,就需要讓Docker守護進程監聽一個端口,這樣才能實現遠程通信。 修改Docker服務啟動配置文件,添加一個未被占用的端口號,重啟docker守護進程。 # vim /etc/sysconfig/docker OPTIONS='-H 0.0.0.0:5555' # systemctl restart docker 此時發現docker守護進程已經在監聽5555端口,在另一台主機上可以通過該端口訪問Docker進程了。 # docker -H IP:5555 images 但是我們卻發現在本地操作docker卻出現問題。 # docker images FATA[0000] Cannot connect to the Docker daemon. Is 'docker -d' running on this host? 這是因為Docker進程只開啟了遠程訪問,本地套接字訪問未開啟。我們修改/etc/sysconfig/docker,然后重啟即可。 # vim /etc/sysconfig/docker OPTIONS='-H unix:///var/run/docker.sock -H 0.0.0.0:5555' # systemctl restart docker 現在本地和遠程均可訪問docker進程了。