CentOSLinux安裝Docker容器

Docker 使用

環境說明

  • CentOS 7.3(不許確地說:要求必須是 CentOS 7 64位)
  • 不建議在 Windows 上使用

Docker 基本概念

  • 官網:https://www.docker.com/
  • 宿主機:安裝 Docker 的那臺電腦
  • Docker:一個虛擬化軟件,你能夠認爲是相似:VMware、Virtualbox
  • 鏡像:能夠認爲是相似 Windows 下的:XXXX.iso
  • 容器:容器爲鏡像的實例,能夠認爲是 Virtualbox 運行 XXXX.iso 後的效果
  • 官網的鏡像倉庫地址:https://store.docker.com/
  • 對開發來說總結一個最簡單的說法:在 Maven 未產生的年代,jar 包要隨着開發項目走到哪裏跟到哪裏。有了 Maven 寫好 pom.xml 便可。此時的 Docker 就比如如 Maven,幫你省去了開發過程當中的部署環境差別,你不再能隨便說:你的系統能夠運行,個人系統就不行。如今別人連繫統都幫你作好了。
  • 玩法理念:單進程,一個容器最好最專一去作一個事情。雖然它能夠既裝 MySQL,又裝 Nginx 等等,可是讓一個容器只作好一件事是最合適的。
  • 其餘通俗解釋:

Docker的思想來自於集裝箱,集裝箱解決了什麼問題?在一艘大船上,能夠把貨物規整的擺放起來。而且各類各樣的貨物被集裝箱標準化了,集裝箱和集裝箱之間不會互相影響。那麼我就不須要專門運送水果的船和專門運送化學品的船了。只要這些貨物在集裝箱裏封裝的好好的,那我就能夠用一艘大船把他們都運走。 docker就是相似的理念。如今都流行雲計算了,雲計算就比如大貨輪。docker就是集裝箱。 1.不一樣的應用程序可能會有不一樣的應用環境,好比.net開發的網站和php開發的網站依賴的軟件就不同,若是把他們依賴的軟件都安裝在一個服務器上就要調試好久,並且很麻煩,還會形成一些衝突。好比IIS和Apache訪問端口衝突。這個時候你就要隔離.net開發的網站和php開發的網站。常規來說,咱們能夠在服務器上建立不一樣的虛擬機在不一樣的虛擬機上放置不一樣的應用,可是虛擬機開銷比較高。docker能夠實現虛擬機隔離應用環境的功能,而且開銷比虛擬機小,小就意味着省錢了。 2.你開發軟件的時候用的是Ubuntu,可是運維管理的都是centos,運維在把你的軟件從開發環境轉移到生產環境的時候就會遇到一些Ubuntu轉centos的問題,好比:有個特殊版本的數據庫,只有Ubuntu支持,centos不支持,在轉移的過程中運維就得想辦法解決這樣的問題。這時候要是有docker你就能夠把開發環境直接封裝轉移給運維,運維直接部署你給他的docker就能夠了。並且部署速度快。 3.在服務器負載方面,若是你單獨開一個虛擬機,那麼虛擬機會佔用空閒內存的,docker部署的話,這些內存就會利用起來。 總之docker就是集裝箱原理。php

  • Docker 的優勢:
  • 持續部署與測試

Docker在開發與運維的世界中具備極大的吸引力,由於它能保持跨環境的一致性。在開發與發佈的生命週期中,不一樣的環境具備細微的不一樣,這些差別多是因爲不一樣安裝包的版本和依賴關係引發的。然而,Docker能夠經過確保從開發到產品發佈整個過程環境的一致性來解決這個問題。 Docker容器經過相關配置,保持容器內部全部的配置和依賴關係始終不變。最終,你能夠在開發到產品發佈的整個過程當中使用相同的容器來確保沒有任何差別或者人工干預。 使用Docker,你還能夠確保開發者不須要配置徹底相同的產品環境,他們能夠在他們本身的系統上經過VirtualBox創建虛擬機來運行Docker容器。Docker的魅力在於它一樣可讓你在亞馬遜EC2實例上運行相同的容器。若是你須要在一個產品發佈週期中完成一次升級,你能夠很容易地將須要變動的東西放到Docker容器中,測試它們,而且使你已經存在的容器執行相同的變動。這種靈活性就是使用Docker的一個主要好處。和標準部署與集成過程同樣,Docker可讓你構建、測試和發佈鏡像,這個鏡像能夠跨多個服務器進行部署。哪怕安裝一個新的安全補丁,整個過程也是同樣的。你能夠安裝補丁,而後測試它,而且將這個補丁發佈到產品中。html

  • 環境標準化和版本控制

Docker容器能夠在不一樣的開發與產品發佈生命週期中確保一致性,進而標準化你的環境。除此以外,Docker容器還能夠像git倉庫同樣,可讓你提交變動到Docker鏡像中並經過不一樣的版原本管理它們。設想若是你由於完成了一個組件的升級而致使你整個環境都損壞了,Docker可讓你輕鬆地回滾到這個鏡像的前一個版本。這整個過程能夠在幾分鐘內完成,若是和虛擬機的備份或者鏡像建立流程對比,那Docker算至關快的,它可讓你快速地進行復制和實現冗餘。此外,啓動Docker就和運行一個進程同樣快。java

  • 隔離性

Docker能夠確保你的應用程序與資源是分隔開的。幾個月前,Gartner發表了一篇報告,這份報告說明了運行Docker 容器進行資源隔離的效果和虛擬機(VM)管理程序同樣的好,可是管理與控制方面還須要進行完善。咱們考慮這樣一個場景,你在你的虛擬機中運行了不少應用程序,這些應用程序包括團隊協做軟件(例如Confluence)、問題追蹤軟件(例如JIRA)、集中身份管理系統(例如Crowd)等等。因爲這些軟件運行在不一樣的端口上,因此你必須使用Apache或者Nginx來作反向代理。到目前爲止,一切都很正常,可是隨着你的環境向前推動,你須要在你現有的環境中配置一個內容管理系統(例如Alfresco)。這時候有個問題發生了,這個軟件須要一個不一樣版本的Apache Tomcat,爲了知足這個需求,你只能將你現有的軟件遷移到另外一個版本的Tomcat上,或者找到適合你現有Tomcat的內容管理系統(Alfresco)版本。對於上述場景,使用Docker就不用作這些事情了。Docker可以確保每一個容器都擁有本身的資源,而且和其餘容器是隔離的。你能夠用不一樣的容器來運行使用不一樣堆棧的應用程序。除此以外,若是你想在服務器上直接刪除一些應用程序是比較困難的,由於這樣可能引起依賴關係衝突。而Docker能夠幫你確保應用程序被徹底清除,由於不一樣的應用程序運行在不一樣的容器上,若是你不在須要一款應用程序,那你能夠簡單地經過刪除容器來刪除這個應用程序,而且在你的宿主機操做系統上不會留下任何的臨時文件或者配置文件。除了上述好處,Docker還能確保每一個應用程序只使用分配給它的資源(包括CPU、內存和磁盤空間)。一個特殊的軟件將不會使用你所有的可用資源,要否則這將致使性能下降,甚至讓其餘應用程序徹底中止工做。node

  • 安全性

如上所述,Gartner也認可Docker正在快速地發展。從安全角度來看,Docker確保運行在容器中的應用程序和其餘容器中的應用程序是徹底分隔與隔離的,在通訊流量和管理上賦予你徹底的控制權。Docker容器不能窺視運行在其餘容器中的進程。從體系結構角度來看,每一個容器只使用着本身的資源(從進程到網絡堆棧)。做爲緊固安全的一種手段,Docker將宿主機操做系統上的敏感掛載點(例如/proc和/sys)做爲只讀掛載點,而且使用一種寫時複製系統來確保容器不能讀取其餘容器的數據。Docker也限制了宿主機操做系統上的一些系統調用,而且和SELinux與AppArmor一塊兒運行的很好。此外,在Docker Hub上可使用的Docker鏡像都經過數字簽名來確保其可靠性。因爲Docker容器是隔離的,而且資源是受限制的,因此即便你其中一個應用程序被黑,也不會影響運行在其它Docker容器上的應用程序。linux

  • 多雲平臺

Docker最大的好處之一就是可移植性。在過去的幾年裏,全部主流的雲計算提供商,包括亞馬遜AWS和谷歌的GCP,都將Docker融入到他們的平臺並增長了各自的支持。Docker容器能運行在亞馬遜的EC2實例、谷歌的GCP實例、Rackspace服務器或者VirtualBox這些提供主機操做系統的平臺上。舉例來講,若是運行在亞馬遜EC2實例上的Docker容器可以很容易地移植到其餘幾個平臺上,好比說VirtualBox,而且達到相似的一致性和功能性,那這將容許你從基礎設施層中抽象出來。除了AWS和GCP,Docker在其餘不一樣的IaaS提供商也運行的很是好,例如微軟的Azure、OpenStack和能夠被具備不一樣配置的管理者所使用的Chef、Puppet、Ansible等。git

Docker 安裝和基本配置

  • 主要有兩個版本:

Docker Enterprise Edition (Docker EE) is designed for enterprise development and IT teams who build, ship, and run business critical applications in production at scale. Docker EE is integrated, certified, and supported to provide enterprises with the most secure container platform in the industry to modernize all applications. For more information about Docker EE, including purchasing options, see Docker Enterprise Edition. Docker Community Edition (Docker CE) is ideal for developers and small teams looking to get started with Docker and experimenting with container-based apps. Docker CE is available on many platforms, from desktop to cloud to server. Docker CE is available for macOS and Windows and provides a native experience to help you focus on learning Docker. You can build and share containers and automate the development pipeline all from a single environment. Docker CE has both stable and edge channels. Stable builds are released once per quarter and are supported for 4 months. Edge builds are released once per month, and are supported for that month only. If you subscribe to the Edge channel on Linux distributions, you should also subscribe to the Stable channel.github

  • 官網總的安裝手冊:https://docs.docker.com/install/web

  • 官網 CentOS 安裝手冊:https://docs.docker.com/install/linux/docker-ce/centos/正則表達式

  • 目前也支持 Windows,特別是 Windows 10,直接官網一個安裝包便可搞定。redis

  • Windows 10 的 Docker 安裝說明:https://store.docker.com/editions/community/docker-ce-desktop-windows

  • 我這裏選擇 Docker CE 版本:

  • CentOS 安裝過程:

    • sudo yum install -y yum-utils device-mapper-persistent-data lvm2
    • 添加 repo(可能網絡會很慢,有時候會報:Timeout,因此要多試幾回)
    • sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
    • sudo yum makecache fast
    • sudo yum install -y docker-ce,大小:19M,速度很慢。
  • 查看配置文件位置:systemctl show --property=FragmentPath docker

  • 啓動 Docker:systemctl start docker.service

  • 中止 Docker:systemctl stop docker.service

  • 查看狀態:systemctl status docker.service

  • 運行 hello world 鏡像:sudo docker run hello-world

    • 由於是第一次使用,因此沒這個鏡像,須要一個下載過程,因此須要幾分鐘,可能還會報:Timeout。
    • 鏡像自動下載好後會輸出這樣一段內容,表示已經正常安裝並可用了:
    Unable to find image 'hello-world:latest' locally latest: Pulling from library/hello-world 78445dd45222: Pull complete Digest: sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7 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. 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://cloud.docker.com/ For more examples and ideas, visit: https://docs.docker.com/engine/userguide/

鏡像加速

{
  "registry-mirrors": ["https://ldhc17y9.mirror.aliyuncs.com"] }
  • sudo systemctl daemon-reload
  • sudo systemctl restart docker
  • 在之後的生活中若是要常用阿里雲作爲本身倉庫,那你還須要作:
    • 在 namespace管理 中建立屬於你本身的 namespace:https://cr.console.aliyun.com/#/namespace/index
    • 建立鏡像倉庫:https://cr.console.aliyun.com/#/imageList
      • 建立好倉庫後,點擊:管理 進入查看倉庫的更多詳細信息,這裏面有不少有用的信息,包括一個詳細的操做指南,這份指南等下會用到。
      • 好比我本身建立一個 redis-to-cluster 倉庫,地址是阿里雲給咱們的:registry.cn-shenzhen.aliyuncs.com/youmeek/redis-to-cluster
      • 那我登陸這個鏡像地址的方式:
docker login registry.cn-shenzhen.aliyuncs.com
會讓我輸入
Username:阿里雲郵箱
password:上文提到的--Registry登陸密碼
docker login

docker tag [ImageId] registry.cn-shenzhen.aliyuncs.com/youmeek/redis-to-cluster:[鏡像版本號]

docker push registry.cn-shenzhen.aliyuncs.com/youmeek/redis-to-cluster:[鏡像版本號]

Docker 命令,最終部署 Spring Boot 項目

  • 建議:初期使用的時候儘可能用容器 ID / 鏡像 ID。若是使用 Tag/Name 在東西多的狀況下很容易混亂 還不如就用記不住可是確定惟一的容器 ID / 鏡像 ID

重要的基本概念

  • 能夠表明一個完整的鏡像名有兩種方式:
    • REPOSITORY(倉庫):TAG(標籤)
      • 其中 TAG 表面上不是必須有的,本質是 docker 幫你用 latest 來代替了。latest 這裏最好翻譯爲默認,而不是最新。
    • IMAGE ID(鏡像ID)
      • 這是一個 Docker 隨機給你生成 數字+字母 的字符串

部署一個 Spring Boot 的 Java Web 項目爲例

  • 宿主機環境說明:
    • IP 地址:http://192.168.137.128
    • 中止了防火牆:systemctl stop firewalld.service ; systemctl stop iptables.service
    • 中止防火牆後重啓 Docker 服務:systemctl restart docker.service
    • JDK(jdk-8u121-linux-x64.tar.gz)、jar 應用(spring-boot-my-demo.jar),存放宿主機位置:/opt/setups
    • Spring Boot 的 jar 應用中配置文件給的端口是:8080,常規狀況下的訪問路徑:http://127.0.0.1:8080/youmeek
  • 下載鏡像:docker pull centos:6.8,個人 IMAGE_ID 爲:0cd976dc0a98
  • 運行鏡像,實例化爲一個容器:docker run -i -t -v /opt/setups:/opt 0cd976dc0a98 /bin/bash
    • -v:表示須要將本地宿主機的目錄掛載到容器中對應的一個目錄上,格式:-v <宿主機目錄>:<容器目錄>,因此此時對容器此目錄的操做,也是等同於對宿主機的目錄的操做
  • 在容器裏安裝 Oracle JDK 八、配置 JDK 環境變量這裏很少說,具體看:JDK 安裝
  • 把容器中 /opt 目錄下的 spring-boot-my-demo.jar 拷貝到容器的 root 目錄下:cp /opt/spring-boot-my-demo.jar /root
  • 再容器裏新建腳本:vi /root/spring-boot-run.sh,腳本內容以下:
#!/bin/bash source /etc/profile java -jar /root/spring-boot-my-demo.jar
  • 在容器中對新建腳本增長執行權限:chmod u+x /root/spring-boot-run.sh
  • 咱們啓動另一個終端
  • 查看咱們剛剛運行的容器相關信息:docker ps -a
    • 咱們看到了咱們剛剛運行的容器 ID(CONTAINER ID)爲:a5d544d9b6f9,這個下面要用到
  • 基於剛剛運行的容器建立新鏡像:docker commit a5d544d9b6f9 youmeek/springboot:0.1
    • 查看如今的鏡像庫:docker images,會發現多了一個 youmeek/springboot 新鏡像,鏡像 ID 爲:7024f230fef9
  • 運行新鏡像,實例化爲一個容器,並啓動容器中剛剛寫的腳本:docker run -d -p 38080:8080 --name=springBootJar --hostname=springBootJar 7024f230fef9 /root/spring-boot-run.sh
    • -d:表示以「守護模式」執行 spring-boot-run.sh 腳本,此時 jar 中的 log 日誌不會出如今輸出終端上。
    • -p:表示宿主機與容器的端口映射,此時將容器內部的 8080 端口映射爲宿主機的 38080 端口,這樣就向外界暴露了 38080 端口,可經過 Docker 網橋來訪問容器內部的 8080 端口了。
    • --name:表示給新實例容器取的名稱,用一個有意義的名稱命名便可
  • 查看其實運行的容器:docker ps -a,能夠知道咱們的新容器 ID:fd21ac056343,名稱爲:springBootJar
  • 查看這個容器的 jar 應用的 log 輸出:docker logs -f fd21ac056343,能夠看到 jar 啓動後的 log 輸出內容
  • 經過瀏覽器訪問容器中的應用:http://192.168.137.128:38080/youmeek/,能夠看到 jar 應用的首頁能夠訪問

Docker 基本命令

版本信息

  • docker version,查看docker版本
  • docker info,顯示docker系統的信息

鏡像倉庫

  • docker pull:從倉庫下載鏡像到本地
    • docker pull centos:latest:獲取 CentOS 默認版本鏡像
    • docker pull centos:7.3.1611:獲取 CentOS 7 鏡像,下載大小 70M 左右,下面的操做基於此鏡像
    • docker pull centos:6.8:獲取 CentOS 6 鏡像
    • docker pull registry.cn-hangzhou.aliyuncs.com/chainone/centos7-jdk8:獲取別人作好的阿里雲鏡像
  • docker push:將一個鏡像 push 到 registry 倉庫中
    • docker push myapache:v1
  • docker search:從 registry 倉庫搜索鏡像
    • docker search -s 3 centos,參數 -s 數字:表示篩選出收藏數(stars值)大於等於 3 的鏡像
  • docker login:登陸到一個鏡像倉庫。默認登陸的是官網的倉庫:https://hub.docker.com

本地鏡像管理

  • docker stats:查看當前啓動的容器各自佔用的系統資源
    • bin docker stats --no-stream kafkadocker_kafka_1 kafkadocker_zookeeper_1:查看指定容器的佔用資源狀況
    • 更加高級的監控方式有一個軟件叫作:ctop(推薦使用):https://github.com/bcicen/ctop
CONTAINER ID        NAME                      CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
4532a9ee27b8        cloud-cadvisor            1.49%               53.28MiB / 3.702GiB   1.41%               13.5MB / 646MB      265MB / 0B          19
3895d5d50a5e        kafkadocker_kafka_1       1.45%               1.24GiB / 3.702GiB    33.51%              145MB / 186MB       499MB / 724MB       128
1d1a6a7c48d8        kafkadocker_zookeeper_1   0.11%               70.85MiB / 3.702GiB   1.87%               55.8MB / 33.7MB     209MB / 1.22MB      23
  • docker images:顯示本地全部的鏡像列表
    • 關注 REPOSITORY(名稱),TAG(標籤),IMAGE ID(鏡像ID)三列
  • docker images centos:查看具體鏡像狀況
  • docker rmi:刪除鏡像,通常刪除鏡像前要先刪除容器,否則若是鏡像有被容器調用會報錯
    • docker rmi 容器ID:刪除具體某一個鏡像
    • docker rmi 倉庫:Tag:刪除具體某一個鏡像
    • docker rmi $(docker images -q),刪除全部鏡像
    • docker rmi -f $(docker images -q),強制刪除全部鏡像
    • docker rmi $(docker images | grep "vmware" | awk '{print $3}'),批量刪除帶有 vmware 名稱的鏡像
  • docker tag:爲鏡像打上標籤
    • docker tag -f ubuntu:14.04 ubuntu:latest,-f 意思是強制覆蓋
    • 同一個IMAGE ID可能會有多個TAG(可能還在不一樣的倉庫),首先你要根據這些 image names 來刪除標籤,當刪除最後一個tag的時候就會自動刪除鏡像;
    • docker rmi 倉庫:Tag,取消標籤(若是是鏡像的最後一個標籤,則會刪除這個鏡像)
  • docker build:使用 Dockerfile 建立鏡像(推薦)
    • docker build . --rm -t runoob/ubuntu:v1,參數 -t,表示:-tag,打標籤
    • 屢次 docker build 過程當中是有依賴一個緩存的過程的,通常 build 過程都有好幾個 step,Docker 很是聰明,會本身判斷那些沒有被修改過程的 step 採用緩存。若是想要避免使用緩存,可使用這樣命令 --no-cache:docker build --no-cache . --rm -t runoob/ubuntu:v1
  • docker history:顯示生成一個鏡像的歷史命令,能夠看出這個鏡像的構建過程,包括:每一層鏡像的 ID、指令
  • docker save:將一個鏡像保存爲一個 tar 包,帶 layers 和 tag 信息(導出一個鏡像)
    • docker save 鏡像ID -o /opt/test.tar
  • docker load:從一個 tar 包建立一個鏡像(導入一個鏡像)
    • docker load -i /opt/test.tar

容器生命週期管理

  • docker run,運行鏡像
    • docker run -v /java_logs/:/opt/ -d -p 8080:80 --name=myDockerNameIsGitNavi --hostname=myDockerNameIsGitNavi -i -t 鏡像ID /bin/bash
      • -i -t 分別表示保證容器中的 STDIN 開啓,並分配一個僞 tty 終端進行交互,這兩個是合着用。
      • --name 是給容器起了一個名字(若是沒有主動給名字,docker 會自動給你生成一個)容器的名稱規則:大小寫字母、數字、下劃線、圓點、中橫線,用正則表達式來表達就是:[a-zA-Z0-9_*-]
      • -d 容器運行在後臺。
      • -p 8080:80 表示端口映射,將宿主機的8080端口轉發到容器內的80端口。(若是是 -P 參數,則表示隨機映射應該端口,通常用在測試的時候)
      • -v /java_logs/:/opt/ 表示目錄掛載,/java_logs/ 是宿主機的目錄,/opt/ 是容器目錄
    • docker run --rm --name=myDockerNameIsGitNavi --hostname=myDockerNameIsGitNavi -i -t centos /bin/bash,--rm,表示退出即刪除容器,通常用在作實驗測試的時候
    • docker run --restart=always -i -t centos /bin/bash,--restart=always 表示中止後會自動重啓
    • docker run --restart=on-failure:5 -i -t centos /bin/bash,--restart=on-failure:5 表示中止後會自動重啓,最多重啓 5 次
  • docker exec:對守護式的容器裏面執行命令,方便對正在運行的容器進行維護、監控、管理
    • docker exec -i -t 容器ID /bin/bash,進入正在運行的 docker 容器,並啓動終端交互
    • docker exec -d 容器ID touch /opt/test.txt,已守護式的方式進入 docker 容器,並建立一個文件
  • docker stop 容器ID,中止容器
    • docker stop $(docker ps -a -q),中止全部容器
    • docker stop $(docker ps -a -q) ; docker rm $(docker ps -a -q),中止全部容器,並刪除全部容器
    • docker kill $(docker ps -q) ; docker rm $(docker ps -a -q),中止全部容器,並刪除全部容器
  • docker start 容器ID,從新啓動已經中止的容器(從新啓動,docker run 參數仍是保留以前的)
  • docker restart 容器ID,重啓容器
  • docker rm,刪除容器
    • docker rm 容器ID,刪除指定容器(該容器必須是中止的)
    • docker rm -f 容器ID,刪除指定容器(該容器若是正在運行能夠這樣刪除)
    • docker rm $(docker ps -a -q),刪除全部容器
    • docker rm -f $(docker ps -a -q),強制刪除全部容器
    • docker ps -a | grep 'weeks ago' | awk '{print $1}' | xargs docker rm 刪除老的(一週前建立)容器
    • docker kill $(docker ps -q) ; docker rm $(docker ps -a -q) ; docker rmi $(docker images -q -a) 中止全部容器,刪除全部容器,刪除全部鏡像
  • docker commit,把容器打成鏡像
    • docker commit 容器ID gitnavi/docker-nodejs-test:0.1
      • gitnavi 是你註冊的 https://store.docker.com/ 的名字,若是你沒有的話,那須要先註冊
      • docker-nodejs-test 是你爲該鏡像起的名字
      • 0.1 是鏡像的版本號,默認是 latest 版本
    • docker commit -m="這是一個描述信息" --author="GitNavi" 容器ID gitnavi/docker-nodejs-test:0.1
      • 在提交鏡像時指定更多的數據(包括標籤)來詳細描述所作的修改
  • docker diff 容器ID:顯示容器文件系統的先後變化
  • --link 同一個宿主機下的不一樣容器的鏈接:
    • docker run -it 鏡像ID --link redis-name:myredis /bin/bash
      • redis-name 是容器名稱
      • myredis 是容器別名,其餘容器鏈接它能夠用這個別名來寫入到本身的配置文件中
  • 容器與宿主機之間文件的拷貝
    • docker cp /www/runoob 96f7f14e99ab:/www/ 將主機 /www/runoob 目錄拷貝到容器 96f7f14e99ab 的 /www 目錄下
    • docker cp /www/runoob 96f7f14e99ab:/www 將主機 /www/runoob 目錄拷貝到容器 96f7f14e99ab 中,目錄重命名爲 www。
    • docker cp 96f7f14e99ab:/www /tmp/ 將容器96f7f14e99ab的/www目錄拷貝到主機的/tmp目錄中。

docker 網絡模式

  • 查看也有網絡:docker network ls
  • 建立網絡:docker network create --subnet=172.19.0.0/16 net-redis-to-cluster
  • 已有容器鏈接到某個網絡(一個容器能夠同時連上多個網絡):docker network connect net-redis-to-cluster my-redis-container
  • 若是是內網提供服務的,能夠直接建立一個網絡,其服務使用該網絡。而後另一個須要調用該服務的,而且是對外網提供服務的可使用 host 模式
  • --network XXXXXX 常見幾種模式
    • bridge 默認模式,在 docker0 的網橋上建立新網絡棧,確保獨立的網絡環境,實現網絡隔離:docker run -it 鏡像ID --network=bridge /bin/bash
    • none 不適用網卡,不會有 IP,沒法聯網:docker run -it 鏡像ID --network=none /bin/bash
    • host 使用宿主機網絡 IP、端口聯網(在容器裏面輸入:ip a,看到的結果和在宿主機看到的同樣):docker run -it 鏡像ID --network=host /bin/bash
    • 自定義-使用本身命名的網絡棧,可是須要手動配置網卡、IP 信息:docker run -it 鏡像ID --network=自定義名稱 /bin/bash

容器管理操做

  • docker ps:列出當前全部 正在運行 的容器
    • docker ps -a:列出全部的容器(包含歷史,即運行過的容器)
    • docker ps -l:列出最近一次啓動的container
    • docker ps -q:列出最近一次運行的container ID
    • docker ps -a -l:列出最後一次運行的容器
    • docker ps -n x:顯示最後 x 個容器,無論是正在運行或是已經中止的
  • docker top 容器ID:顯示容器的進程信息
  • docker events:獲得 docker 服務器的實時的事件
  • docker logs -f 容器ID:查看容器日誌(若是一些容器不斷重啓,或是自動中止,能夠這樣看下)
    • docker logs 容器ID,獲取守護式容器的日誌
    • docker logs -f 容器ID,不斷監控容器日誌,相似 tail -f
    • docker logs -ft 容器ID,在 -f 的基礎上又增長 -t 表示爲每條日誌加上時間戳,方便調試
    • docker logs --tail 10 容器ID,獲取日誌最後 10 行
    • docker logs --tail 0 -f 容器ID,跟蹤某個容器的最新日誌而沒必要讀取日誌文件
    • docker logs -f -t --since="2018-05-26" --tail=200 容器ID 根據某個時間讀取日誌
    • docker logs -f -t --since="2018-05-26T11:13:40" --tail=200 容器ID 根據某個時間讀取日誌
    • docker logs -f -t --since="2018-05-25T11:13:40" --until "2018-05-26T11:13:40" --tail=200 容器ID 根據某個時間讀取日誌
    • docker logs --since 10m 容器ID 查看最近 10 分鐘的日誌
      • -f : 表示查看實時日誌
      • -t : 顯示時間戳
      • -since : 顯示某個開始時間的全部日誌
      • -tail=200 : 查看最後的 200 條日誌
  • docker wait,阻塞到一個容器,直到容器中止運行
  • docker export,將容器整個文件系統導出爲一個tar包,不帶layers、tag等信息
  • docker port,顯示容器的端口映射
  • docker inspect 容器ID:查看容器的全面信息,用 JSON 格式輸出
  • docker inspect network名稱:查看 network 信息,用 JSON 格式輸出,包含使用該網絡的容器有哪些
  • docker system df:相似於 Linux 上的 df 命令,用於查看 Docker 的磁盤使用狀況
    • Images 鏡像
    • Containers 容器
    • Local Volumes 數據卷
TYPE                TOTAL               ACTIVE              SIZE                RECLAIMABLE
Images              6                   6                   1.049GB             0B (0%)
Containers          7                   4                   10.25kB             0B (0%)
Local Volumes       13                  5                   38.49GB             1.365MB (0%)
Build Cache                                                 0B                  0B
獲取容器中的 IP:docker inspect -f {{.NetworkSettings.IPAddress}} 容器ID
獲取容器中的 IP:docker inspect -f {{.Volumes}} 容器ID
查看容器的掛載狀況:docker inspect 容器ID | grep Mounts -A 10
  • 下面爲一個 docker inspect 後的結果示例:
[
    {
        "Id": "e1dff77b99d9c8489e0a0ce68a19ec5ffe18cc5d8b8ec17086f7f7bea29aa09b", "Created": "2018-01-18T03:47:16.138180181Z", "Path": "docker-entrypoint.sh", "Args": [ "--auth" ], "State": { "Status": "running", "Running": true, "Paused": false, "Restarting": false, "OOMKilled": false, "Dead": false, "Pid": 19952, "ExitCode": 0, "Error": "", "StartedAt": "2018-01-18T03:47:16.348568927Z", "FinishedAt": "0001-01-01T00:00:00Z" }, "Image": "sha256:42aa46cfbd7a0d1101311defac39872b447b32295b40f9c99104ede5d02e9677", "ResolvConfPath": "/var/lib/docker/containers/e1dff77b99d9c8489e0a0ce68a19ec5ffe18cc5d8b8ec17086f7f7bea29aa09b/resolv.conf", "HostnamePath": "/var/lib/docker/containers/e1dff77b99d9c8489e0a0ce68a19ec5ffe18cc5d8b8ec17086f7f7bea29aa09b/hostname", "HostsPath": "/var/lib/docker/containers/e1dff77b99d9c8489e0a0ce68a19ec5ffe18cc5d8b8ec17086f7f7bea29aa09b/hosts", "LogPath": "/var/lib/docker/containers/e1dff77b99d9c8489e0a0ce68a19ec5ffe18cc5d8b8ec17086f7f7bea29aa09b/e1dff77b99d9c8489e0a0ce68a19ec5ffe18cc5d8b8ec17086f7f7bea29aa09b-json.log", "Name": "/cas-mongo", "RestartCount": 0, "Driver": "overlay", "Platform": "linux", "MountLabel": "", "ProcessLabel": "", "AppArmorProfile": "", "ExecIDs": null, "HostConfig": { "Binds": [ "/data/mongo/db:/data/db" ], "ContainerIDFile": "", "LogConfig": { "Type": "json-file", "Config": {} }, "NetworkMode": "default", "PortBindings": { "27017/tcp": [ { "HostIp": "", "HostPort": "27017" } ] }, "RestartPolicy": { "Name": "always", "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 }, "GraphDriver": { "Data": { "LowerDir": "/var/lib/docker/overlay/0ab08b1f9c8f5f70cdcac2b01d9ee31de9e5a4955003567573635e8837931249/root", "MergedDir": "/var/lib/docker/overlay/4d6bb0d57f3f1b1dcf98c70b4bee4abf8dc110c7efa685ee5d84fe6f58c07b63/merged", "UpperDir": "/var/lib/docker/overlay/4d6bb0d57f3f1b1dcf98c70b4bee4abf8dc110c7efa685ee5d84fe6f58c07b63/upper", "WorkDir": "/var/lib/docker/overlay/4d6bb0d57f3f1b1dcf98c70b4bee4abf8dc110c7efa685ee5d84fe6f58c07b63/work" }, "Name": "overlay" }, "Mounts": [ { "Type": "volume", "Name": "6cd9721ff6a2768cd20e4a0678b176fa81a5de1c7d21fe6212b50c6854196db2", "Source": "/var/lib/docker/volumes/6cd9721ff6a2768cd20e4a0678b176fa81a5de1c7d21fe6212b50c6854196db2/_data", "Destination": "/data/configdb", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" }, { "Type": "bind", "Source": "/data/mongo/db", "Destination": "/data/db", "Mode": "", "RW": true, "Propagation": "rprivate" } ], "Config": { "Hostname": "e1dff77b99d9", "Domainname": "", "User": "", "AttachStdin": false, "AttachStdout": false, "AttachStderr": false, "ExposedPorts": { "27017/tcp": {} }, "Tty": false, "OpenStdin": false, "StdinOnce": false, "Env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "GOSU_VERSION=1.7", "GPG_KEYS=0C49F3730359A14518585931BC711F9BA15703C6", "MONGO_PACKAGE=mongodb-org", "MONGO_REPO=repo.mongodb.org", "MONGO_MAJOR=3.4", "MONGO_VERSION=3.4.10" ], "Cmd": [ "--auth" ], "Image": "mongo:3.4", "Volumes": { "/data/configdb": {}, "/data/db": {} }, "WorkingDir": "", "Entrypoint": [ "docker-entrypoint.sh" ], "OnBuild": null, "Labels": {} }, "NetworkSettings": { "Bridge": "", "SandboxID": "7eabf418238f4d9f5fd5163fd4d173bbaea7764687a5cf40a9757d42b90ab2f9", "HairpinMode": false, "Link LocalIPv6Address": "", "LinkLocalIPv6PrefixLen": 0, "Ports": { "27017/tcp": [ { "HostIp": "0.0.0.0", "HostPort": "27017" } ] }, "SandboxKey": "/var/run/docker/netns/7eabf418238f", "SecondaryIPAddresses": null, "SecondaryIPv6Addresses": null, "EndpointID": "11c8d10a4be63b4ed710add6c440adf9d090b71918d4aaa837c46258e5425b80", "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": "ada97659acda146fc57e15a099e430a6e97de87f6d043b91d4c3582f6ab52d47", "EndpointID": "11c8d10a4be63b4ed710add6c440adf9d090b71918d4aaa837c46258e5425b80", "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 } } } } ]

Docker 容器產生的 log 位置

  • Docker 運行一段時間,若是你的容器有大量的輸出信息,則這個 log 文件會很是大,因此要考慮清理。
  • log 位置:/var/lib/docker/containers/容器ID值/容器ID值-json.log
  • 能夠考慮在停到容器的時候備份這個文件到其餘位置,而後:echo > 容器ID值-json.log
  • 固然,官網也提供了自動化的方案:https://docs.docker.com/config/containers/logging/json-file/
    • 修改 Docker 是配置文件:vim /etc/docker/daemon.json,(若是沒有這個文件,本身新增)增長以下內容:
{
  "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "5" } }
  • 若是你已經有該文件文件萊使用國內源,那修改方案應該是這樣的:
{
	"registry-mirrors": ["https://ldhc17y9.mirror.aliyuncs.com"], "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "5" } }

刪除 Docker 鏡像中爲 none 的鏡像

  • Dockerfile 代碼更新頻繁,天然 docker build 構建同名鏡像也頻繁的很,產生了衆多名爲 none 的無用鏡像
docker rmi $(docker images -f "dangling=true" -q)

Docker daemon.json 可配置參數

Docker remote api 遠程操做配置(保證在內網環境)

  • 假設要被遠程操做的服務器 IP:192.168.1.22
  • 修改其配置文件:vim /lib/systemd/system/docker.service
  • 修改默認值爲:ExecStart=/usr/bin/dockerd
  • 改成:ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2376
    • 若是還須要連本身的 harbor 這類,完整配置:ExecStart=/usr/bin/dockerd --insecure-registry harbor.youmeek.com -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2376
  • systemctl daemon-reload
  • systemctl reload docker
  • systemctl restart docker
  • 驗證:
    • 在其餘服務器上運行:docker -H 192.168.1.22:2376 images
    • 能拿到和它自己看到的同樣的數據表示能夠了

Dockerfile 解釋

  • 該文件名就叫 Dockerfile,注意大小寫,沒有後綴,不然會報錯。
  • 主要由下面幾個部分組成:
    • 基礎鏡像信息
    • 維護者/建立者信息
    • 鏡像操做指令
    • 容器啓動時執行執行
  • 註釋符號:# 這是一段註釋說明
  • 經常使用指令關鍵字:
    • FROM,基礎鏡像信息
    • MAINTAINER,維護者/建立者信息
    • ADD,添加文件。若是添加的文件是相似 tar.gz 壓縮包,會自動解壓。
      • 特別注意的是:ADD 文件到鏡像的地址若是是目錄,則須要最後保留斜槓,好比:ADD test.tar.gz /opt/shell/。不是斜槓結尾會認爲是文件。
      • 添加文件格式:ADD test.sh /opt/shell/test.sh
      • 添加壓縮包並解壓格式:ADD test.tar.gz /opt/shell/,該壓縮包會自動解壓在 /opt/shell 目錄下
    • COPY,相似 ADD,只是 COPY 只是複製文件,不會作相似解壓壓縮包這種行爲。
      • COPY /opt/conf/ /etc/ 把宿主機的 /opt/conf 下文件複製到鏡像的 /etc 目錄下。
    • WORKDIR,設置工做目錄,能夠理解爲相似 cd 命令,表示如今在某個目錄路徑,而後下面的 CMD、ENTRYPOINT 操做都是基於此目錄
    • VOLUME,目錄掛載
    • EXPOSE,暴露端口
    • USER,指定該鏡像以什麼用戶去運行,也能夠用這個來指定:docker run -u root。不指定默認是 root
    • ENV,定義環境變量,該變量能夠在後續的任何 RUN 指令中使用,使用方式:$HOME_DIR。在 docker run 的時候能夠該方式來覆蓋變量值 docker run -e 「HOME_DIR=/opt」
    • RUN,執行命令並建立新的鏡像層,RUN 常常用於安裝軟件包
    • CMD,執行命令,而且一個 Dockerfile 只能有一條 CMD,有多條的狀況下最後一條有效。在一種場景下 CMD 命令無效:docker run 的時候也指定了相同命令,則 docker run 命令優先級最高
    • ENTRYPOINT,配置容器啓動時運行的命令,不會被 docker run 指令覆蓋,而且 docker run 的指令能夠做爲參數傳遞到 ENTRYPOINT 中。要覆蓋 ENTRYPOINT 命令也是有辦法的:docker run --entrypoint 方式。Dockerfile 同時有 CMD 和 ENTRYPOINT 的時候,CMD 的指令是做爲參數傳遞給 ENTRYPOINT 使用。
      • 特別注意:RUN、CMD 和 ENTRYPOINT 這三個 Dockerfile 指令看上去很相似,很容易混淆。
      • 最佳實戰:來源
        • 使用 RUN 指令安裝應用和軟件包,構建鏡像。
        • 若是 Docker 鏡像的用途是運行應用程序或服務,好比運行一個 MySQL,應該優先使用 Exec 格式的 ENTRYPOINT 指令。CMD 可爲 ENTRYPOINT 提供額外的默認參數,同時可利用 docker run 命令行替換默認參數。
        • 若是想爲容器設置默認的啓動命令,可以使用 CMD 指令。用戶可在 docker run 命令行中替換此默認命令。

Dockerfile 部署 Spring Boot 應用

  • jar 名稱:skb-user-0.0.1-SNAPSHOT.jar
  • 打算用的宿主機端口:9096
  • Dockerfile 文件和 jar 文件存放在宿主機目錄:/opt/zch
  • Dockerfile 內容以下:
FROM java:8-jre
MAINTAINER gitnavi <gitnavi@qq.com> ENV TZ=Asia/Shanghai RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone ADD skb-user-0.0.1-SNAPSHOT.jar /usr/local/skb/user/ CMD ["java", "-Xmx500m", "-jar", "/usr/local/skb/user/skb-user-0.0.1-SNAPSHOT.jar", "--spring.profiles.active=test"] EXPOSE 9096
  • 開始構建:
    • cd /opt/zch
    • docker build . --tag="skb/user:v1.0.1"
      • 由於 build 過程當中會有多層鏡像 step 過程,因此若是 build 過程當中失敗,那解決辦法的思路是找到 step 失敗的上一層,成功的 step 中鏡像 ID。而後 docker run 該鏡像 ID,手工操做,看報什麼錯誤,而後就比較清晰得了解錯誤狀況了。
    • docker run -d -p 9096:9096 -v /usr/local/logs/:/opt/ --name=skbUser --hostname=skbUser skb/user:v1.0.1
    • 查看啓動後容器列表:docker ps
    • jar 應用的日誌是輸出在容器的 /opt 目錄下,由於咱們上面用了掛載,所在在咱們宿主機的 /usr/local/logs 目錄下能夠看到輸出的日誌
  • 防火牆開放端口:
    • firewall-cmd --zone=public --add-port=9096/tcp --permanent
    • firewall-cmd --reload
  • 解釋:
# 是爲了解決容器的時區和宿主機不一致問題
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

Dockerfile 部署 Tomcat 應用

  • 編寫 Dockerfile
FROM tomcat:8.0.46-jre8
MAINTAINER GitNavi <gitnavi@qq.com>

ENV JAVA_OPTS="-Xms2g -Xmx2g -XX:MetaspaceSize=128M -XX:MaxMetaspaceSize=312M"
ENV CATALINA_HOME /usr/local/tomcat

ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

RUN rm -rf /usr/local/tomcat/webapps/*

ADD qiyeweixin.war /usr/local/tomcat/webapps/

EXPOSE 8080

CMD ["catalina.sh", "run"]
  • 打包鏡像:docker build -t harbor.gitnavi.com/demo/qiyeweixin:1.2.2 ./
  • 運行:docker run -d -p 8888:8080 --name=qiyeweixin --hostname=qiyeweixin -v /data/docker/logs/qiyeweixin:/data/logs/qiyeweixin harbor.gitnavi.com/demo/qiyeweixin:1.2.2
  • 帶 JVM 參數運行:docker run -d -p 8888:8080 -e JAVA_OPTS='-Xms7g -Xmx7g -XX:MetaspaceSize=128M -XX:MaxMetaspaceSize=512M' --name=qiyeweixin --hostname=qiyeweixin -v /data/docker/logs/qiyeweixin:/data/logs/qiyeweixin harbor.gitnavi.com/demo/qiyeweixin:1.2.2
    • 雖然 Dockerfile 已經有 JVM 參數,而且也是有效的。可是若是 docker run 的時候又帶了 JVM 參數,則會以 docker run 的參數爲準
  • 測試 JVM 是否有效方法,在代碼裏面書寫,該值要接近 xmx 值:
long maxMemory = Runtime.getRuntime().maxMemory();
logger.warn("-------------maxMemory=" + ((double) maxMemory / (1024 * 1024)));

Docker Compose

  • Docker Compose 主要用於定義和運行多個 Docker 容器的工具,這樣能夠快速運行一套分佈式系統
    • 容器之間是有依賴關係,好比我一個 Java web 系統依賴 DB 容器、Redis 容器,必須這些依賴容器先運行起來。
  • 一個文件:docker-compose.yml
  • 一個命令:docker-compose up
    • 指定文件:docker-compose -f zookeeper.yml -p zk_test up -d
  • 官網安裝說明:https://docs.docker.com/compose/install/#install-compose
  • 安裝方法:
sudo curl -L https://github.com/docker/compose/releases/download/1.18.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose

sudo chmod +x /usr/local/bin/docker-compose
  • 檢查是否安裝成功:docker-compose --version,輸出:docker-compose version 1.18.0, build 8dd22a9
  • 經常使用命令:
    • 運行:docker-compose up -d
    • 中止運行:docker-compose down
    • 查看容器:docker-compose ps
    • 刪除中止的服務容器:docker-compose rm

Docker Swarm

  • Docker Swarm 是一個 Docker 集羣管理工具

Harbor 鏡像私有倉庫

相關文章
相關標籤/搜索