Docker

Docker

環境:Centos7.3

get the most up-to-date version of Docker
https://get.docker.com

(This script is meant for quick & easy install via:)
[root@linux-node0 ~]# curl -fsSL https://get.docker.com -o get-docker.sh
[root@linux-node0 ~]# sh get-docker.sh

[root@linux-node0 ~]# service docker start
Redirecting to /bin/systemctl start docker.service
[root@linux-node0 ~]# docker version
Client:
Version: 18.09.0
API version: 1.39
Go version: go1.10.4
Git commit: 4d60db4
Built: Wed Nov 7 00:48:22 2018
OS/Arch: linux/amd64
Experimental: false

Server: Docker Engine - Community
Engine:
Version: 18.09.0
API version: 1.39 (minimum version 1.12)
Go version: go1.10.4
Git commit: 4d60db4
Built: Wed Nov 7 00:19:08 2018
OS/Arch: linux/amd64
Experimental: false

如果是ubuntu系統,可以運行以下來更新,但是我是剛裝的docker一般不會有更新:
apt get update
it's going to get any new information from the Docker archives.
這個命令,會訪問源列表裏的每個網址,並讀取軟件列表,然後保存在本地電腦。
update後,可能需要upgrade一下。
apt get upgrade
it's going to install any new updates we have, including Docker.
這個命令,會把本地已安裝的軟件,與剛下載的軟件列表裏對應軟件進行對比,如果發現已安裝的軟件版本太低,就會提示你更新。

Create a Simple Dockerized App
[root@linux-node0 ~]# docker run -d ubuntu /bin/bash -c 'while true; do X=$[$X+1]; echo $X ; sleep 1; done'
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
32802c0cfa4d: Pull complete
da1315cffa03: Pull complete
fa83472a3562: Pull complete
f85999a86bef: Pull complete
Digest: sha256:6d0e0c26489e33f5a6f0020edface2727db9489744ecc9b4f50c7fa671f23c49
Status: Downloaded newer image for ubuntu:latest
a801ab6247561beb6094e24e98ba6b27ab4e4444cc36cbc0ddca3f8f3678d589
("run" it will look in our local image repository for an environment to run our application in, and if it doesn't exist, it will download it from Docker Hub.)
(-d, so that goes in daemon mode and runs in the background. )
(ubuntu, what environment do we want it to run in)
(但是由於我的系統是Centos,The system can't find that image called ubuntu. I don't have an image like that. So what it does, it goes on the internet, and it will download the ubuntu image for us from Docker Hub. See, it goes through. It's going to download it. It will take a little bit. But it's going to download the entire ubuntu environment. Notice it's not a ubuntu virtual machine, it's just all over the dependencies and stuff that is required inside of a container. )

[root@linux-node0 ~]# docker ps ( it's going to show us what containers are running on our system. CONTAINER ID is from the first little bit of CONTAINER ID above in red, NAMES is random name)
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a801ab624756 ubuntu "/bin/bash -c 'while猞" 5 minutes ago Up 5 minutes vibrant_hamilton

查看container日誌
[root@linux-node0 ~]# docker logs a801ab624756 或者
[root@linux-node0 ~]# docker logs vibrant_hamilton
關閉container
[root@linux-node0 ~]# docker stop a801ab624756 或者
[root@linux-node0 ~]# docker stop vibrant_hamilton
啓動container
[root@linux-node0 ~]# docker start a801ab624756 或者
[root@linux-node0 ~]# docker start vibrant_hamilton

Managing Containers and Images
顯示 images
[root@linux-node0 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest 93fd78260bd1 8 days ago 86.2MB
(it will show us all those that we've downloaded. So here you see I have the ubuntu latest image.)

[root@linux-node0 ~]# docker search php (This actually looks on Docker Hub, what I like to do is scroll to the top, because the most popular ones are always at the top)
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
php While designed for web development, the PHP 猞 4091 [OK]
phpmyadmin/phpmyadmin A web interface for MySQL and MariaDB. 662 [OK]
richarvey/nginx-php-fpm Container running Nginx + PHP-FPM capable of猞 651 [OK]
adminer Database management in a single PHP file. 188 [OK]
php-zendserver Zend Server - the integrated PHP application猞 157 [OK]

添加IMAGE
[root@linux-node0 ~]# docker pull php
( it's going to pull that image from the Docker Hub repository, and it's going to download it. )

[root@linux-node0 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest 93fd78260bd1 8 days ago 86.2MB
php latest 8473cbe51b22 12 days ago 367MB

[root@linux-node0 ~]# docker pull centos

[root@linux-node0 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest 93fd78260bd1 8 days ago 86.2MB
php latest 8473cbe51b22 12 days ago 367MB
centos latest 75835a67d134 7 weeks ago 200MB

刪除IMAGE
[root@linux-node0 ~]# docker rmi php

更新IMAGE
[root@linux-node0 ~]# docker pull centos
Using default tag: latest
latest: Pulling from library/centos
Digest: sha256:67dad89757a55bfdfabec8abd0e22f8c7c12a1856514726470228063ed86593b
Status: Image is up to date for centos:latest
(if there are any updates to the CentOS image up on Docker Hub, it will actually go, and test, and see.)

顯示所有運行中的containers
[root@linux-node0 ~]# docker ps

顯示所有的containers
[root@linux-node0 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a801ab624756 ubuntu "/bin/bash -c 'while猞" 2 hours ago Exited (137) About an hour ago vibrant_hamilton

刪除非運行的container
[root@linux-node0 ~]# docker rm vibrant_hamilton
vibrant_hamilton

刪除運行的container
[root@linux-node0 ~]# docker rm -f vibrant_hamilton

[root@linux-node0 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

Networking
After we installed docker on our local machine, we have docker0 ip address.
[root@linux-node0 ~]# ip add
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:78:37:89 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.243/24 brd 192.168.1.255 scope global dynamic ens33
valid_lft 2963sec preferred_lft 2963sec
inet 192.168.1.38/32 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe78:3789/64 scope link
valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN
link/ether 02:42:3b:56:9c:78 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:3bff:fe56:9c78/64 scope link
valid_lft forever preferred_lft forever

[root@linux-node0 ~]# docker run -d adejonge/helloworld (下載adejonge/helloworld)
Unable to find image 'adejonge/helloworld:latest' locally
latest: Pulling from adejonge/helloworld
a3ed95caeb02: Pull complete
5a5de98b2fa4: Pull complete
Digest: sha256:46d95092b73dccbcc12cdec910a3673e41cd7c4fabc7bf7413dfb12f709e2a1d
Status: Downloaded newer image for adejonge/helloworld:latest
e557547b0349077934081593c556b344773a482e53e0241cc1a38f3a1aa78b55

[root@linux-node0 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e557547b0349 adejonge/helloworld "/helloworld" 17 seconds ago Up 16 seconds gifted_ellis

[root@linux-node0 ~]# docker inspect gifted_ellis (查找CONTAINER 的ip地址)
[
{
"Id": "e557547b0349077934081593c556b344773a482e53e0241cc1a38f3a1aa78b55",
"Created": "2018-11-28T07:15:00.939324112Z",
"Path": "/helloworld",
"Args": [],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 14733,
"ExitCode": 0,
"Error": "",
"StartedAt": "2018-11-28T07:15:01.290577712Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:4fa84a96f0d641a79ad7574fd75eabee71e93095fb35af9c30e9b59e3269206d",
"ResolvConfPath": "/var/lib/docker/containers/e557547b0349077934081593c556b344773a482e53e0241cc1a38f3a1aa78b55/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/e557547b0349077934081593c556b344773a482e53e0241cc1a38f3a1aa78b55/hostname",
"HostsPath": "/var/lib/docker/containers/e557547b0349077934081593c556b344773a482e53e0241cc1a38f3a1aa78b55/hosts",
"LogPath": "/var/lib/docker/containers/e557547b0349077934081593c556b344773a482e53e0241cc1a38f3a1aa78b55/e557547b0349077934081593c556b344773a482e53e0241cc1a38f3a1aa78b55-json.log",
"Name": "/gifted_ellis",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "default",
"PortBindings": {},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": null,
"CapDrop": null,
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "shareable",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"ConsoleSize": [
0,
0
],
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": [],
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DeviceCgroupRules": null,
"DiskQuota": 0,
"KernelMemory": 0,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": false,
"PidsLimit": 0,
"Ulimits": null,
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"MaskedPaths": [
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware"
],
"ReadonlyPaths": [
"/proc/asound",
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/a6ee1a97dabd2384f7baf9f09ac29d488d3f637e0ec4da135d39bf79d8da0751-init/diff:/var/lib/docker/overlay2/6679f7b2b9942e4b13e9d3dcaab02040cf264011f444dc0f16fceae668678e5f/diff:/var/lib/docker/overlay2/31dede3ad36eab372a3e590d0dca9816a2ee04ba695c66b6d23d89cb5256d195/diff:/var/lib/docker/overlay2/41c4349ab6d857b5f084701ee9e7f15b3109530f4e9054925b7d9d9b1e79262c/diff",
"MergedDir": "/var/lib/docker/overlay2/a6ee1a97dabd2384f7baf9f09ac29d488d3f637e0ec4da135d39bf79d8da0751/merged",
"UpperDir": "/var/lib/docker/overlay2/a6ee1a97dabd2384f7baf9f09ac29d488d3f637e0ec4da135d39bf79d8da0751/diff",
"WorkDir": "/var/lib/docker/overlay2/a6ee1a97dabd2384f7baf9f09ac29d488d3f637e0ec4da135d39bf79d8da0751/work"
},
"Name": "overlay2"
},
"Mounts": [],
"Config": {
"Hostname": "e557547b0349",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"HOME=/",
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/helloworld"
],
"Image": "adejonge/helloworld",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "d247c39f4ae6f990427aa6e372ed389dc620545accf7a4279480fd42b1fdd491",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {},
"SandboxKey": "/var/run/docker/netns/d247c39f4ae6",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "5a3a11f64fe6ce7bbba84808e7700c3dac39a68ffa187099a26a3e90425e39c1",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:02",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "2659d5fe4dda5401004f0fe9b7942a9cd6e61ae42f2c278112fbc53e6ae304cc",
"EndpointID": "5a3a11f64fe6ce7bbba84808e7700c3dac39a68ffa187099a26a3e90425e39c1",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:02",
"DriverOpts": null
}
}
}
}
]

或者
[root@linux-node0 ~]# docker inspect gifted_ellis | grep IP
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"IPAMConfig": null,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
(172.17.0.2 is the IP address of eth0 inside our container called gifted_ellis.)

[root@linux-node0 ~]# ip add
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:78:37:89 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.243/24 brd 192.168.1.255 scope global dynamic ens33
valid_lft 2471sec preferred_lft 2471sec
inet 192.168.1.38/32 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe78:3789/64 scope link
valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
link/ether 02:42:3b:56:9c:78 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:3bff:fe56:9c78/64 scope link
valid_lft forever preferred_lft forever
9: veth1244b57@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP
link/ether 46:66:47:ef:cf:57 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::4466:47ff:feef:cf57/64 scope link
valid_lft forever preferred_lft forever
(There's a new ethernet port created. It's that veth1244b57@if8. You'll notice it does not have an IP address. This is just a bridge port. This ties our container to docker0 up here with the 172.17.0.1. So it ties it to that.)

[root@linux-node0 ~]# telnet 172.17.0.2 8080
Trying 172.17.0.2...
Connected to 172.17.0.2.

可以成功連接了

Advanced Networking
[root@linux-node0 ~]# docker run -d -p 8080 adejonge/helloworld (p means Publish)

[root@linux-node0 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bd91165056b9 adejonge/helloworld "/helloworld" 31 seconds ago Up 28 seconds 0.0.0.0:10000->8080/tcp lucid_ritchie

http://192.168.1.243:10000/
可以成功連接了

刪除lucid_ritchie
[root@linux-node0 ~]# docker rm -f lucid_ritchie

指定端口
[root@linux-node0 ~]# docker run -d -p 8001:8080 adejonge/helloworld
bfcdd7042250457be297a923fadbf45bf0e5c9f848dc47fcd731cc7e4d4860e7

[root@linux-node0 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bfcdd7042250 adejonge/helloworld "/helloworld" 2 minutes ago Up 2 minutes 0.0.0.0:8001->8080/tcp fervent_ardinghelli

http://192.168.1.243:8001

指定多端口
[root@linux-node0 ~]# docker run -d -p 8003:8080 -p 8004:8080 adejonge/helloworld

[root@linux-node0 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6ca8b3520d15 adejonge/helloworld "/helloworld" 26 seconds ago Up 24 seconds 0.0.0.0:8003->8080/tcp, 0.0.0.0:8004->8080/tcp hopeful_wilson

指定使用host ip地址
[root@linux-node0 ~]# docker run -d --net=host adejonge/helloworld
fca32a314dd6c90f756b04e2e89270b9e0c1c170c6e605f9b41020a52bb764c0

[root@linux-node0 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fca32a314dd6 adejonge/helloworld "/helloworld" 1 second ago agitated_mestorf

訪問本機http://192.168.1.243:8080/

Shared and Persistent Data
[root@linux-node0 ~]# docker run -d nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
a5a6f2f73cd8: Pull complete
1ba02017c4b2: Pull complete
33b176c904de: Pull complete
Digest: sha256:59f8d756e723a610d60bdcb37a4d68185a7b67bfc7ef4c616dd022458ec3db3a
Status: Downloaded newer image for nginx:latest
ea964d2cafc02da060b25f40a7a919bcfebc34d22cec95f90a60f38f433a6840

[root@linux-node0 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ea964d2cafc0 nginx "nginx -g 'daemon of猞" 10 seconds ago Up 8 seconds 80/tcp jolly_agnesi

[root@linux-node0 ~]# docker inspect jolly_agnesi | grep IP
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"IPAMConfig": null,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,

[root@linux-node0 ~]# mkdir web
[root@linux-node0 ~]# cd web
[root@linux-node0 web]# vi index.html
IT WORKED!
[root@linux-node0 web]# pwd
/root/web

(mount a local directory in a Container. I do not recommend you try to install NFS or Samba inside of a container as it spins up. That's just a nightmare. And it's so simple to mount volumes from the host, and it can even be a volume that happens to be a Samba share. So if you have a Samba share that's mounted on your host, you can take that and mount it using the -v command, and it can be a volume inside of your container. So that's the best way to deal with data when you're dealing with Docker.)
[root@linux-node0 web]# docker run -d -v /root/web:/usr/share/nginx/html nginx
fa141c51fe28bf42e90e66e322e383c9917ebf747159b900ff2885d4c8f24549
(v for volume, and (/usr/share/nginx/html)where I want it to mount inside of the container. I just happen to know that usr/share/nginx/html is where it serves webpages from inside that container.)

[root@linux-node0 web]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ea964d2cafc0 nginx "nginx -g 'daemon of猞" 8 minutes ago Up 8 minutes 80/tcp wonderful_hodgkin

[root@linux-node0 web]# docker inspect wonderful_hodgkin | grep IP
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"IPAMConfig": null,
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,

[root@linux-node0 web]# curl http://172.17.0.3
IT WORKED!

[root@linux-node0 web]# vi /root/web/index.html
IT REALLY WORKED!

[root@linux-node0 web]# curl http://172.17.0.3
IT REALLY WORKED!

Modifying Containers and Images
There's two different ways to go about modifying an image. The first way we're going to do is kind of a quick hack sort of way to do it, but it's completely legitimate, and it's the easiest way, I think, to go through and modify an image so that it's exactly what you want. And the other way you do it is basically you spin up a container, modify that container, and then create and save that container as an image itself. So to do that, we have to be able to attach to a running container, because to make modifications to a container you have to be able to connect to it.

[root@linux-node0 web]# docker run -d --name my_nginxtemp nginx

[root@linux-node0 web]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
93d62ce3f5ad nginx "nginx -g 'daemon of猞" 21 seconds ago Up 20 seconds 80/tcp my_nginxtemp

[root@linux-node0 web]# docker inspect my_nginxtemp | grep IP
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.4",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"IPAMConfig": null,
"IPAddress": "172.17.0.4",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,

[root@linux-node0 web]# docker exec -i -t my_nginxtemp bash
(-t, connect to a running instance or a running container. Then what command we want it to run inside of that terminal session)

root@93d62ce3f5ad:/#
We are inside that container, that running container called my_nginxtemp.

root@93d62ce3f5ad:/# cd /usr/share/nginx/html
root@93d62ce3f5ad:/usr/share/nginx/html# ls
50x.html index.html
root@93d62ce3f5ad:/usr/share/nginx/html# rm index.html
root@93d62ce3f5ad:/usr/share/nginx/html# cat > index.html
123456
(Control-D to save)

root@93d62ce3f5ad:/usr/share/nginx/html# exit
exit

[root@linux-node0 ~]# curl http://172.17.0.4
123456

we want to create an image from the running container
[root@linux-node0 web]# docker commit my_nginxtemp my_nginx
sha256:16089e1bbfd23f583f9f037e3c54d195f26cc33d8779fd6d4adb841dd574aed8

[root@linux-node0 web]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
my_nginx latest 16089e1bbfd2 1 second ago 109MB
nginx latest 568c4670fa80 12 hours ago 109MB
ubuntu latest 93fd78260bd1 8 days ago 86.2MB
centos latest 75835a67d134 7 weeks ago 200MB
adejonge/helloworld latest 4fa84a96f0d6 4 years ago 3.6MB

[root@linux-node0 web]# docker rm -f my_nginxtemp

[root@linux-node0 web]# docker run -d my_nginx
6af25acf46c0d2eed2df90083e8b1c01e169d847643e3faa4f45dfcb2f1e2732

[root@linux-node0 web]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6af25acf46c0 my_nginx "nginx -g 'daemon of猞" 4 seconds ago Up 3 seconds 80/tcp priceless_kowalevski

[root@linux-node0 web]# docker inspect priceless_kowalevski | grep IP
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"IPAMConfig": null,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,

[root@linux-node0 ~]# curl http://172.17.0.2
123456

Creating Images from Scratch
[root@linux-node0 ~]# mkdir my_counter
[root@linux-node0 ~]# cd my_counter
[root@linux-node0 my_counter]# pwd
/root/my_counter
[root@linux-node0 my_counter]# vi counter.sh
#!/bin/bash
while true
do
X=$[$X+1]
echo $X
sleep 1
done
[root@linux-node0 my_counter]# chmod +x counter.sh
[root@linux-node0 my_counter]# ./counter.sh
1
2
3
[root@linux-node0 my_counter]# vi Dockerfile

Base image

FROM ubuntu

#Maintainer
MAINTAINER norman.jin [email protected]

#COPY and ADD both are ok. (The difference is copy just copies it directly. So whatever we have here in our build directory, it's going to copy it to that image. If you say add, this source could be a file. It could be a TAR zipped file. So if this is a TAR.gz file, it's going to extract it and put it in the destination. And if you use the add command, this could even be a URL. So if there's a file listed somewhere, like if you're doing WordPress and you want to download the latest WordPress TAR.gz, you could put a URL in this first place and it will download it and then put it in the destination.)
COPY counter.sh /usr/local/bin/counter.sh

RUN chmod +x /usr/local/bin/counter.sh

#run /usr/local/bin/counter.sh
CMD ["/usr/local/bin/counter.sh"]

[root@linux-node0 my_counter]# ls
counter.sh Dockerfile

now we wanted to create an image from this
[root@linux-node0 my_counter]# docker build -t my_counter .
Sending build context to Docker daemon 3.072kB
Step 1/5 : FROM ubuntu
---> 93fd78260bd1
Step 2/5 : MAINTAINER norman.jin [email protected]
---> Running in 3d3fab6065f6
Removing intermediate container 3d3fab6065f6
---> b0d2929d4cbb
Step 3/5 : COPY counter.sh /usr/local/bin/counter.sh
---> 4a82bc6ebd18
Step 4/5 : RUN chmod +x /usr/local/bin/counter.sh
---> Running in 9ed8196e77f3
Removing intermediate container 9ed8196e77f3
---> f7b45ebfdff8
Step 5/5 : CMD ["/usr/local/bin/counter.sh"]
---> Running in ae106de79aec
Removing intermediate container ae106de79aec
---> 327c887e0e93
Successfully built 327c887e0e93
Successfully tagged my_counter:latest

[root@linux-node0 my_counter]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
my_counter latest 327c887e0e93 7 seconds ago 86.2MB

[root@linux-node0 my_counter]# docker run -d my_counter

[root@linux-node0 my_counter]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
95ba3dbd83d5 my_counter "/usr/local/bin/coun猞" 6 seconds ago Up 1 second wizardly_kirch

[root@linux-node0 my_counter]# docker logs wizardly_kirch
(we'll see that it's counting)

Containers Working Together
the first thing I want to do is create a container that will store the data for our other two containers to look at.
A container doesn't even have to be running in order to share its data volumes with other containers.

[root@linux-node0 my_counter]# docker create --name my_data -v /usr/share/nginx/html ubuntu

[root@linux-node0 my_counter]# docker ps (because it is not running, so can not see it here)
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

[root@linux-node0 my_counter]# docker ps –a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
746a23a94052 ubuntu "/bin/bash" 4 seconds ago Created my_data

[root@linux-node0 my_counter]# docker run -d --volumes-from my_data nginx

[root@linux-node0 my_counter]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
92593c0eccbf nginx "nginx -g 'daemon of猞" 8 seconds ago Up 5 seconds 80/tcp angry_varahamihira

[root@linux-node0 my_counter]# docker inspect angry_varahamihira | grep IP
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"IPAMConfig": null,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,

[root@linux-node0 my_counter]# curl http://172.17.0.2
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.15.7</center>
</body>
</html>
(Why is Nginx giving us an error? Well, because it's using the volume from my_data but there's currently nothing in that volume.)

[root@linux-node0 ~]# mkdir my_webcounter
[root@linux-node0 ~]# cd my_webcounter
[root@linux-node0 my_webcounter]# pwd
/root/my_webcounter
[root@linux-node0 my_webcounter]# vi webcounter.sh
#!/bin/bash
while true
do
X=$[$X+1]
echo "$X" > /usr/share/nginx/html/index.html
sleep 1
done

[root@linux-node0 my_webcounter]# vi Dockerfile

Base image

FROM ubuntu
#Maintainer
MAINTAINER norman.jin [email protected]
COPY webcounter.sh /usr/local/bin/webcounter.sh
RUN chmod +x /usr/local/bin/webcounter.sh
CMD ["/usr/local/bin/webcounter.sh"]

[root@linux-node0 my_webcounter]# ls
Dockerfile webcounter.sh

[root@linux-node0 my_webcounter]# docker build -t my_webapp .

[root@linux-node0 my_webcounter]# docker run -d --volumes-from my_data my_webapp

[root@linux-node0 my_webcounter]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f18927b3f59b my_webapp "/usr/local/bin/webc猞" 8 seconds ago Up 7 seconds distracted_babbage
92593c0eccbf nginx "nginx -g 'daemon of猞" About an hour ago Up About an hour 80/tcp angry_varahamihira

可以看到有數據了
[root@linux-node0 my_webcounter]# curl http://172.17.0.2
66
[root@linux-node0 my_webcounter]# curl http://172.17.0.2
67
[root@linux-node0 my_webcounter]# curl http://172.17.0.2
68

So it's actually working. What's happening our counter app is counting as a file.
And it's writing it directly to this data only container called my_data. And then this web server has this data only container volume mounted as well. So when it looks to serve out it's file, it's actually looking in this shared volume and it sees a file there.
So sure enough, it serves it out and they're working in concert without needing any reference to the underlying file system. Which means that we've created a completely portable pool of applications that are working together. Because these can be delivered to anybody.
They can be delivered to your computer and as long as you name it the data only container properly and you point them volumes from that data container, it doesn't matter what your operating system's file system looks like. You don't have to reference the file system at all.
You can reference this shared volume and then share your data from inside there. And while it seems like it adds a layer of complexity, what it gives us is this really awesome ability to allow our system to be completely portable. They're still independently executing.
They're sharing that input and output, but rather than sharing it off the host file system, they're sharing it from a data volume container that doesn't even have to be running. It just has to be existing and created so that the running containers, the other ones, can reference it.

GUI Tools for Docker
[root@linux-node0 ~]# docker run -d -p 9000:9000 --privileged -v /var/run/docker.sock:/var/run/docker.sock dockerui/dockerui
Unable to find image 'dockerui/dockerui:latest' locally
docker: Error response from daemon: pull access denied for dockerui/dockerui, repository does not exist or may require 'docker login'.

[root@linux-node0 ~]# docker run -d -p 9000:9000 --privileged -v /var/run/docker.sock:/var/run/docker.sock uifd/ui-for-docker
Unable to find image 'uifd/ui-for-docker:latest' locally
latest: Pulling from uifd/ui-for-docker
841194d080c8: Pull complete
Digest: sha256:fe371ff5a69549269b24073a5ab1244dd4c0b834cbadf244870572150b1cb749
Status: Downloaded newer image for uifd/ui-for-docker:latest
dbec4a21d596255a5beb14dfb9924475757469a54984bfaa0f8233de5d2199d8

[root@linux-node0 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dbec4a21d596 uifd/ui-for-docker "/ui-for-docker" About a minute ago Up About a minute 0.0.0.0:9000->9000/tcp brave_gates

[root@linux-node0 ~]# ip add
ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:78:37:89 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.243/24 brd 192.168.1.255 scope global dynamic ens33
valid_lft 2426sec preferred_lft 2426sec
inet 192.168.1.38/32 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe78:3789/64 scope link
valid_lft forever preferred_lft forever

訪問 http://192.168.1.243:9000

other GUI Tools for Docker
Kitematic: use linux containers on windows or OSX
Shipyard: Docker集中化web界面管理平臺Shipyard
Panamax: Docker Management for Humans

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章