Docker 是一個開源的應用容器引擎,基於 Go 語言 並聽從Apache2.0協議開源。html
Docker 可讓開發者打包他們的應用以及依賴包到一個輕量級、可移植的容器中,而後發佈到任何流行的 Linux 機器上,也能夠實現虛擬化。python
容器是徹底使用沙箱機制,相互之間不會有任何接口(相似 iPhone 的 app),更重要的是容器性能開銷極低。linux
Docker 從 17.03 版本以後分爲 CE(Community Edition: 社區版) 和 EE(Enterprise Edition: 企業版),咱們用社區版就能夠了。nginx
Docker 使用客戶端-服務器 (C/S) 架構模式,使用遠程API來管理和建立Docker容器。git
Docker 容器經過 Docker 鏡像來建立。web
容器與鏡像的關係相似於面向對象編程中的對象與類:
鏡像---->類
容器---->對象docker
下載安裝包:apache
[root@jin-10 ~]# curl https://download.docker.com/linux/centos/docker-ce.repo -o /etc/yum.repos.d/docker.repo
安裝:編程
yum install -y docker-ce
安裝後可查看Docker的版本信息:json
[root@jin-10 ~]# docker --version Docker version 19.03.1, build 74b1e89
鑑於國內網絡問題,後續拉取 Docker 鏡像十分緩慢,咱們能夠經過配置來解決。此處以阿里云爲例:
複製這個地址,而後編輯文件/etc/docker/daemon.json,寫入以下內容:
{ "registry-mirrors": ["https://qrel1k8y.mirror.aliyuncs.com"] }
配置完後,需重啓docker服務使其生效。
啓動Docker服務:
[root@jin-10 ~]# systemctl start docker [root@jin-10 ~]# ps aux|grep docker root 1838 3.0 6.5 569176 65524 ? Ssl 09:10 0:09 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock root 1995 0.0 0.1 112724 996 pts/0 S+ 09:15 0:00 grep --color=auto docker
測試運行 hello-world:
因爲本地沒有hello-world這個鏡像,因此會下載一個hello-world的鏡像,並在容器內運行。
[root@jin-10 ~]# docker run hello-world Unable to find image 'hello-world:latest' locally latest: Pulling from library/hello-world 1b930d010525: Pull complete Digest: sha256:451ce787d12369c5df2a32c85e5a03d52cbcef6eb3586dd03075f3034f10adcd Status: Downloaded newer image for hello-world:latest Hello from Docker! This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (amd64) 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash Share images, automate workflows, and more with a free Docker ID: https://hub.docker.com/ For more examples and ideas, visit: https://docs.docker.com/get-started/
Docker-ce的刪除命令:
systemctl remove docker-ce rm -rf /var/lib/docker
下面仍是以運行Hello World爲例:
[root@jin-10 ~]# docker run centos /bin/echo 'Hello World!' Unable to find image 'centos:latest' locally latest: Pulling from library/centos d8d02d457314: Pull complete Digest: sha256:307835c385f656ec2e2fec602cf093224173c51119bbebd602c53c3653a3d6eb Status: Downloaded newer image for centos:latest Hello World!
交互式的方式運行容器:
[root@jin-10 ~]# docker run -i -t centos /bin/bash [root@ab1c701e7fe3 /]# ls anaconda-post.log dev home lib64 mnt proc run srv tmp var bin etc lib media opt root sbin sys usr [root@ab1c701e7fe3 /]# cat /proc/version Linux version 3.10.0-957.27.2.el7.x86_64 (mockbuild@kbuilder.bsys.centos.org) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC) ) #1 SMP Mon Jul 29 17:46:05 UTC 2019 [root@ab1c701e7fe3 /]# pwd /
後臺方式啓動容器:
[root@jin-10 ~]# docker run -d centos /bin/bash -c "while true; do echo hello world; sleep 1; done" 5830d6e57f238d97de8048630bec6c74b897d95723d326fbed5a36de4fab9397
能夠看到,咱們輸入以上的命令後,並無輸出hello world內容,而是返回了一串字符編碼。這個字符編碼叫作容器ID,對每一個容器來講都是惟一的,咱們能夠經過容器ID來查看對應的容器發生了什麼。 docker ps 命令能夠查看是否有容器在運行:
[root@jin-10 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5830d6e57f23 centos "/bin/bash -c 'while…" 13 seconds ago Up 11 seconds great_taussig
docker logs(後面接容器ID或容器name)命令,能夠查看容器內的標準輸出:
[root@jin-10 ~]# docker logs 5830d6e57f23 hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world
能夠看到,其實以前輸入的命令,實際上是在後臺一直運行。 docker stop(容器ID或容器name)命令能夠中止正在運行的容器:
[root@jin-10 ~]# docker stop 5830d6e57f23 5830d6e57f23 [root@jin-10 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
咱們在docker容器中運行一個 Python Flask 應用來運行一個web應用。
[root@jin-10 ~]# docker pull training/webapp Using default tag: latest latest: Pulling from training/webapp [DEPRECATION NOTICE] registry v2 schema1 support will be removed in an upcoming release. Please contact admins of the docker.io registry NOW to avoid future disruption. e190868d63f8: Pull complete 909cd34c6fd7: Pull complete 0b9bfabab7c1: Pull complete a3ed95caeb02: Pull complete 10bbbc0fc0ff: Pull complete fca59b508e9f: Pull complete e7ae2541b15b: Pull complete 9dd97ef58ce9: Pull complete a4c1b0cb7af7: Pull complete Digest: sha256:06e9c1983bd6d5db5fba376ccd63bfa529e8d02f23d5079b8f74a616308fb11d Status: Downloaded newer image for training/webapp:latest docker.io/training/webapp:latest [root@jin-10 ~]# docker run -d -P training/webapp python app.py b8ed64647e26a3273c718b6a7ebec808f615d486dbb8cb62df73de037fcd847c
[root@jin-10 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b8ed64647e26 training/webapp "python app.py" About a minute ago Up 57 seconds 0.0.0.0:32768->5000/tcp admiring_ride
能夠看到,此處多了端口(PORTS)信息:0.0.0.0:32768->5000/tcp
Docker 開放了 5000 端口(默認 Python Flask 端口)映射到主機端口 32768 上。
咱們能夠經過瀏覽器訪問WEB應用:
咱們也能夠經過 -p 參數來設置不同的端口:
[root@jin-10 ~]# docker run -d -p 5000:5000 training/webapp python app.py 30dbbec04fcdd58f82cb642e913f26457ac985428be4d498729ceb4beb821e96 [root@jin-10 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 30dbbec04fcd training/webapp "python app.py" 8 seconds ago Up 5 seconds 0.0.0.0:5000->5000/tcp naughty_golick b8ed64647e26 training/webapp "python app.py" 7 minutes ago Up 7 minutes 0.0.0.0:32768->5000/tcp admiring_ride
咱們可使用 docker port 查看指定 (ID 或者名字)容器的某個肯定端口映射到宿主機的端口號,以上面爲例:
[root@jin-10 ~]# docker port b8ed64647e26 5000/tcp -> 0.0.0.0:32768 [root@jin-10 ~]# docker port admiring_ride 5000/tcp -> 0.0.0.0:32768
docker logs [ID或者名字] 能夠查看容器內部的標準輸出:
[root@jin-10 ~]# docker logs admiring_ride * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit) 192.168.154.1 - - [26/Aug/2019 02:20:54] "GET / HTTP/1.1" 200 - 192.168.154.1 - - [26/Aug/2019 02:20:54] "GET /favicon.ico HTTP/1.1" 404 -
此處咱們還可使用參數-f讓 docker logs 像使用 tail -f 同樣來輸出容器內部的標準輸出。
docker top(容器ID或容器name) 來查看容器內部運行的進程。
[root@jin-10 ~]# docker top admiring_ride UID PID PPID C STIME TTY TIME CMD root 4120 4103 0 10:14 ? 00:00:00 python app.py
docker inspect 命令能夠查看 Docker 的底層信息。它會返回一個 JSON 文件記錄着 Docker 容器的配置和狀態信息。
[root@jin-10 ~]# docker stop admiring_ride admiring_ride
已經中止的容器,咱們可使用命令 docker start 來啓動。
[root@jin-10 ~]# docker start admiring_ride admiring_ride
docker ps -l 查詢最後一次建立的容器:
[root@jin-10 ~]# docker ps -l CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 30dbbec04fcd training/webapp "python app.py" 13 minutes ago Up 13 minutes 0.0.0.0:5000->5000/tcp naughty_golick
刪除容器時,容器必須是中止狀態,不然會報錯:
[root@jin-10 ~]# docker rm admiring_ride Error response from daemon: You cannot remove a running container b8ed64647e26a3273c718b6a7ebec808f615d486dbb8cb62df73de037fcd847c. Stop the container before attempting removal or force remove [root@jin-10 ~]# docker stop admiring_ride admiring_ride [root@jin-10 ~]# docker rm admiring_ride admiring_ride
當運行容器時,使用的鏡像若是在本地中不存在,docker 就會自動從 docker 鏡像倉庫中下載,默認是從 Docker Hub 公共鏡像源下載。
docker images 列出本地主機上的鏡像:
[root@jin-10 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE centos latest 67fa590cfc1c 5 days ago 202MB hello-world latest fce289e99eb9 7 months ago 1.84kB training/webapp latest 6fae60ef3446 4 years ago
當咱們在本地主機上使用一個不存在的鏡像時 Docker 就會自動下載這個鏡像。若是咱們想預先下載這個鏡像,咱們可使用 docker pull 命令來下載它。
[root@jin-10 ~]# docker pull nginx Using default tag: latest latest: Pulling from library/nginx 1ab2bdfe9778: Pull complete a17e64cfe253: Pull complete e1288088c7a8: Pull complete Digest: sha256:53ddb41e46de3d63376579acf46f9a41a8d7de33645db47a486de9769201fec9 Status: Downloaded newer image for nginx:latest docker.io/library/nginx:latest
[root@jin-10 ~]# docker search httpd NAME DESCRIPTION STARS OFFICIAL AUTOMATED httpd The Apache HTTP Server Project 2614 [OK] centos/httpd 24 [OK] centos/httpd-24-centos7 Platform for running Apache httpd 2.4 or bui… 22 armhf/httpd The Apache HTTP Server Project 8 arm32v7/httpd The Apache HTTP Server Project 8 salim1983hoop/httpd24 Dockerfile running apache config 2 [OK] lead4good/httpd-fpm httpd server which connects via fcgi proxy h… 1 [OK] rgielen/httpd-image-simple Docker image for simple Apache httpd based o… 1 [OK] manageiq/httpd_configmap_generator Httpd Configmap Generator 0 [OK]
[root@jin-10 ~]# docker pull nginx Using default tag: latest latest: Pulling from library/nginx 1ab2bdfe9778: Pull complete a17e64cfe253: Pull complete e1288088c7a8: Pull complete Digest: sha256:53ddb41e46de3d63376579acf46f9a41a8d7de33645db47a486de9769201fec9 Status: Downloaded newer image for nginx:latest docker.io/library/nginx:latest
當咱們從docker鏡像倉庫中下載的鏡像不能知足咱們的需求時,咱們能夠經過如下兩種方式對鏡像進行更改:
[root@jin-10 ~]# docker run -i -t centos /bin/bash [root@101530c1659a /]# yum install -y net-tools ...... Installed: net-tools.x86_64 0:2.0-0.24.20131004git.el7 Complete! [root@101530c1659a /]# exit exit
咱們能夠經過命令 docker commit來提交容器副本:
[root@jin-10 ~]# docker commit -m="yum install net-tools" -a="jin" 101530c1659a centos:v2 sha256:e487a99a4de9733ed613d1f79fdadc683e3e1a91fcf0f1e10e6d106d6222bd76
參數說明以下:
命令 docker build,能夠從零開始來建立一個新的鏡像。須要建立一個 Dockerfile 文件,其中包含一組指令來告訴 Docker 如何構建咱們的鏡像。 咱們建立Dockerfile文件,並寫入如下內容:
FROM centos:6.7 MAINTAINER jin "jin@linux.com" RUN /bin/echo 'root:123456' |chpasswd RUN /useradd jin RUN /bin/echo 'jin:123456' |chpasswd RUN /bin/echo -e "LANG=\"en_US.UTF-8\"" >/etc/default/local EXPOSE 22 EXPOSE 80 CMD /usr/sbin/sshd -D
每個指令都會在鏡像上建立一個新的層,每個指令的前綴都必須是大寫的。
咱們使用 Dockerfile 文件,經過 docker build 命令來構建一個鏡像:
[root@jin-10 ~]# docker build -t jin/centos:6.7 . Sending build context to Docker daemon 37.38kB Step 1/9 : FROM centos:6.7 ---> 9f1de3c6ad53 Step 2/9 : MAINTAINER jin "jin@linux.com" ---> Using cache ---> 99d82b0eea4c Step 3/9 : RUN /bin/echo 'root:123456' |chpasswd ---> Using cache ---> ff3f33d1c001 Step 4/9 : RUN useradd jin ---> Running in 48c0cd93c3f5 Removing intermediate container 48c0cd93c3f5 ---> 2688337e172c Step 5/9 : RUN /bin/echo 'jin:123456' |chpasswd ---> Running in e7d7347850e9 Removing intermediate container e7d7347850e9 ---> 49bb06cc1843 Step 6/9 : RUN /bin/echo -e "LANG=\"en_US.UTF-8\"" >/etc/default/local ---> Running in c1ebc1a1b667 Removing intermediate container c1ebc1a1b667 ---> ee04f076fdc7 Step 7/9 : EXPOSE 22 ---> Running in c3e15517f0ec Removing intermediate container c3e15517f0ec ---> 3c3b68f5b66a Step 8/9 : EXPOSE 80 ---> Running in 46d8161a9bb1 Removing intermediate container 46d8161a9bb1 ---> 6487bc54a2b1 Step 9/9 : CMD /usr/sbin/sshd -D ---> Running in 3c4e2504f1a6 Removing intermediate container 3c4e2504f1a6 ---> 449e188f0215 Successfully built 449e188f0215 Successfully tagged jin/centos:6.7
其中,參數-t表示指定要建立的目標鏡像名, .表示Dockerfile 文件所在目錄,能夠指定Dockerfile 的絕對路徑。
[root@jin-10 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE jin/centos 6.7 449e188f0215 About a minute ago 191MB centos v2 e487a99a4de9 2 hours ago 314MB centos latest 67fa590cfc1c 5 days ago 202MB nginx latest 5a3221f0137b 10 days ago 126MB centos 6.7 9f1de3c6ad53 5 months ago 191MB hello-world latest fce289e99eb9 7 months ago 1.84kB training/webapp latest 6fae60ef3446 4 years ago 349MB
能夠看到,ID449e188f0215的鏡像就是咱們剛纔用Dockerfile建立的。
咱們用新的鏡像來建立容器:
[root@jin-10 ~]# docker run -i -t jin/centos:6.7 /bin/bash [root@b855cf5e62db /]# id jin uid=500(jin) gid=500(jin) groups=500(jin)
docker tag 命令,能夠爲鏡像添加一個新的標籤:
[root@jin-10 ~]# docker tag 449e188f0215 jin/centos:test [root@jin-10 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE jin/centos 6.7 449e188f0215 7 minutes ago 191MB jin/centos test 449e188f0215 7 minutes ago 191MB centos v2 e487a99a4de9 2 hours ago 314MB centos latest 67fa590cfc1c 5 days ago 202MB nginx latest 5a3221f0137b 10 days ago 126MB centos 6.7 9f1de3c6ad53 5 months ago 191MB hello-world latest fce289e99eb9 7 months ago 1.84kB training/webapp latest 6fae60ef3446 4 years ago 349MB
前面咱們實現了經過網絡端口來訪問運行在 docker 容器內的服務。下面咱們來實現經過端口鏈接到一個 docker 容器。
咱們建立一個 python 應用的容器:
[root@jin-10 ~]# docker run -d -P training/webapp python app.py d88408cc7cacfbeaaf26233135420c562db002c89e46637196c1f1ef6eff283e [root@jin-10 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d88408cc7cac training/webapp "python app.py" 6 seconds ago Up 4 seconds 0.0.0.0:32771->5000/tcp sad_kirch
咱們使用 -P 參數建立一個容器,使用 docker ps 能夠看到容器端口 5000 綁定主機端口 32771。
咱們也可使用 -p 標識來指定容器端口綁定到主機端口。
兩種方式的區別是:
[root@jin-10 ~]# docker run -d -p 5000:5000 training/webapp python app.py 30397628db6988d54e3304b24e7359949cca4b9cfbb3f4d69d4ebc11bb30bfcd [root@jin-10 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 30397628db69 training/webapp "python app.py" 10 seconds ago Up 1 second 0.0.0.0:5000->5000/tcp reverent_gould d88408cc7cac training/webapp "python app.py" 5 minutes ago Up 5 minutes 0.0.0.0:32771->5000/tcp sad_kirch
咱們能夠指定容器綁定的網絡地址,好比綁定 127.0.0.1:
[root@jin-10 ~]# docker run -d -p 127.0.0.1:5001:5000 training/webapp python app.py fc17fccfc477905897540347c0a99dcebfd97acd9831b87035bcd170c72b349d [root@jin-10 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES fc17fccfc477 training/webapp "python app.py" 14 seconds ago Up 6 seconds 127.0.0.1:5001->5000/tcp dreamy_greider 30397628db69 training/webapp "python app.py" About a minute ago Up About a minute 0.0.0.0:5000->5000/tcp reverent_gould d88408cc7cac training/webapp "python app.py" 7 minutes ago Up 7 minutes 0.0.0.0:32771->5000/tcp sad_kirch
上面的例子中,默認都是綁定 tcp 端口,若是要綁定 UDP 端口,能夠在端口後面加上 /udp:
[root@jin-10 ~]# docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py a66ee68f9308940a38edf98f4b309c8995f7359e7a390e8c69a6825e4df317fb [root@jin-10 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a66ee68f9308 training/webapp "python app.py" 15 seconds ago Up 5 seconds 5000/tcp, 127.0.0.1:5000->5000/udp kind_shtern fc17fccfc477 training/webapp "python app.py" 16 minutes ago Up 16 minutes 127.0.0.1:5001->5000/tcp dreamy_greider 30397628db69 training/webapp "python app.py" 18 minutes ago Up 18 minutes 0.0.0.0:5000->5000/tcp reverent_gould d88408cc7cac training/webapp "python app.py" 23 minutes ago Up 23 minutes 0.0.0.0:32771->5000/tcp sad_kirch
docker port 命令可讓咱們快捷地查看端口的綁定狀況:
[root@jin-10 ~]# docker port kind_shtern 5000/udp -> 127.0.0.1:5000
端口映射並非惟一把 docker 鏈接到另外一個容器的方法。
docker 有一個鏈接系統容許將多個容器鏈接在一塊兒,共享鏈接信息。
docker 鏈接會建立一個父子關係,其中父容器能夠看到子容器的信息。
當咱們建立一個容器的時候,docker 會自動對它進行命名。另外,咱們也可使用 --name 標識來命名容器:
[root@jin-10 ~]# docker run -d -P --name jin training/webapp python app.py cdcb18044fecdf8098470b5461345e9f842e3607f55f2ffe4fea9a81f772bb38 [root@jin-10 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES cdcb18044fec training/webapp "python app.py" 11 seconds ago Up 3 seconds 0.0.0.0:32772->5000/tcp jin a66ee68f9308 training/webapp "python app.py" 5 minutes ago Up 4 minutes 5000/tcp, 127.0.0.1:5000->5000/udp kind_shtern fc17fccfc477 training/webapp "python app.py" 21 minutes ago Up 21 minutes 127.0.0.1:5001->5000/tcp dreamy_greider 30397628db69 training/webapp "python app.py" 23 minutes ago Up 23 minutes 0.0.0.0:5000->5000/tcp reverent_gould d88408cc7cac training/webapp "python app.py" 28 minutes ago Up 28 minutes 0.0.0.0:32771->5000/tcp sad_kirch
附:Docker命令大全:https://www.runoob.com/docker/docker-command-manual.html