docker基礎知識

1、認識

1.什麼是docker

Docker 是一個開源項目,誕生於 2013 年初,最初是 dotCloud 公司內部的一個業餘項目。它基於 Google 公司推出的 Go 語言實現。 項目後來加入了 Linux 基金會,聽從了 Apache 2.0 協議,項目代碼在 GitHub 上進行維護。node

Docker 自開源後受到普遍的關注和討論,以致於dotCloud 公司後來都更名爲 Docker Inc。Redhat已經在其 RHEL6.5 中集中支持 Docker;Google 也在其 PaaS 產品中普遍應用。python

Docker的主要目標:mysql

經過對應用組件的封裝、分發、部署、運行等生命週期的管理,達到應用級別的一次封裝,處處運行。linux

小貼士:這裏的應用組件,能夠是WEB應用,也能夠是一套數據庫服務,甚至能夠是一個操做系統編譯器ios

2.爲何使用docker

Docker容器虛擬化的優勢:nginx

  • 環境隔離;

經過cgroups和namesapce進行實現資源隔離,實現一臺機器運行多個容器互不影響。git

  • 更快速的交付部署;

使用docker,開發人員能夠利用鏡像快速構建一套標準的研發環境;開發完成後,測試和運維人員能夠直接經過使用相同的環境來部署代碼。Docker能夠快速建立和刪除容器,實現快速迭代,大量節約開發、測試、部署的時間。而且,各個步驟都有明確的配置和操做,整個過程全程課件,使團隊裏更容易理解應用建立和工做的過程。github

  • 更高效的資源利用;

docker容器的運行不須要額外的虛擬化管理程序的支持,它是內核級的虛擬化,能夠實現更高的性能,同時對資源的額外需求很低。web

  • 更易遷移擴展;

docker容器幾乎能夠在任意的平臺上運行,包括烏力吉、虛擬機、公有云、私有云、我的電腦、服務器等,這種兼容性讓用戶能夠在不一樣平臺之間輕鬆的遷移應用。sql

  • 更簡單的更新管理。

使用Dockerfile,只須要小小的配置修改,就能夠替代以往的大量的更新工做。而且全部修改都是以增量的方式進行分發和更新,從而實現自動化和高效的容器管理。

3.虛擬化與docker

虛擬化定義:虛擬化是一種資源管理技術,是將計算機的各類實體資源,如服務器、網絡、內存及存儲等,予以抽象、轉換後呈現出來,打破實體結構間的不可切割的障礙,使用戶能夠比本來的配置更好的方式來應用這些資源。這些資源的新虛擬部分是不受現有資源的架設方式,地域或物理配置所限制。通常所指的虛擬化資源包括計算能力和數據存儲。

系統虛擬化,Hypervisor Virtualization,全虛擬化。在 Host 中經過 Hypervisor 層實現安裝多個 GuestOS,每一個 GuestOS 都有本身的內核,和主機的內核不一樣,GuestOS 之間徹底隔離。

容器虛擬化,Operating System Virtualization ,使用 Linux 內核中的 namespaces 和 cgroups 實現進程組之間的隔離。是用內核技術實現的隔離,因此它是一個共享內核的虛擬化技術。

容器虛擬化沒有 GuestOS,使用 Docker 時下載的鏡像,只是爲運行 App 提供的一個依賴的環境,是一個刪減版本的系統鏡像。通常狀況下系統虛擬化沒有容器虛擬化的運行效率高,可是系統安全性高不少。

優越性:

你在一臺機器能夠開10個虛擬機,若是用docker能夠開100個容器,就是這麼霸氣

4.docker官網註冊

註冊一個docker帳號:https://hub.docker.com/

完成註冊,我用的qq郵箱,等了10分鐘才收到。

收到後激活郵箱,進行登陸

登陸完畢

2、核心概念和安裝

1.環境介紹

​ 操做系統:CentOS7 7.6 X64

​ docker版本:18.06.1-ce

要求: 內核版本最低爲3.10

查看當前內核版本: uname –r

更改網卡配置:vim /etc/sysconfig/network-scripts/ifcfg-enp0s3ONBOOT="yes"

2.經過yum方式安裝docker

新增通常用戶,並加入到sudo組,如下命令均使用通常用戶執行

第一步:更新yum源: sudo yum update

第二步:增長docker的yum源

# sudo vim /etc/yum.repos.d/docker.repo
[dockerrepo]
name=Docker Repository
baseurl=https://yum.dockerproject.org/repo/main/centos/$releasever/ 
enabled=1
gpgcheck=1
gpgkey=https://yum.dockerproject.org/gpg

第三步:經過yum安裝docker:sudo yum install docker

第四步:啓動docker服務:sudo systemctl start docker.service

第五步:查看版本信息,經過測試用例驗證docker是否安裝成功:docker version

測試:sudo docker run hello-world

第六步:docker配置

設置docker開機啓動:sudo chkconfig docker on

docker卸載

​ 查看安裝包:sudo yum list installed | grepdocker

​ 移除安裝包:sudo yum -y remove docker.x86_64

​ 清除全部docker依賴文件:sudo rm -rf /var/lib/docker

3.Docker的核心概念

3.1 Docker核心概念之鏡像

Docker 鏡像就是一個只讀的模板。

例如:一個鏡像能夠包含一個完整的 centos操做系統環境,裏面僅安裝了 Apache 或用戶須要的其它應用程序。

鏡像能夠用來建立 Docker 容器。

建立Docker鏡像有幾種方式,多數是在一個現有鏡像基礎上建立新鏡像,由於幾乎你須要的任何東西都有了公共鏡像,包括全部主流Linux發行版,你應該不會找不到你須要的鏡像。不過,就算你想從頭構建一個鏡像,也有好幾種方法。

要建立一個鏡像,你能夠拿一個鏡像,對它進行修改來建立它的子鏡像 。

3.2 Docker核心概念之容器

Docker 利用容器來運行應用。

容器是從鏡像建立的運行實例。它能夠被啓動、開始、中止、刪除。每一個容器都是相互隔離的、保證安全的平臺。

能夠把容器看作是一個簡易版的 Linux 環境(包括root用戶權限、進程空間、用戶空間和網絡空間等)和運行在其中的應用程序。

注:鏡像是隻讀的,容器在啓動的時候建立一層可寫層做爲最上層。

3.3 Docker核心概念之倉庫

倉庫是集中存放鏡像文件的場所。

有時候會把倉庫和倉庫註冊服務器(Registry)混爲一談,並不嚴格區分。實際上,倉庫註冊服務器上每每存放着多個倉庫,每一個倉庫中又包含了多個鏡像,每一個鏡像有不一樣的標籤(tag)。Centos的6.0和7.0就是tag。

3、鏡像的經常使用操做

1.獲取鏡像

命令:

docker pull <域名>/<namespace>/<repo>:<tag>

​ 好比:sudo docker pull centos

說明:

​ 鏡像是Docker運行容器的前提。

​ 用戶可使用docker pull 命令從網絡上下載鏡像。對於鏡像來講,若是不顯式地指定tag,則默認會選擇latest標籤,即下載倉庫中最新版本的鏡像。

​ 默認是從docker官方下載的。只有docker官方的能夠不須要增長命名空間直接進行下載。

2.查看鏡像列表

命令:

docker images

說明:

​ 使用docker images命令能夠列出本地主機上已有的鏡像。

​ 信息含義:來自於哪一個倉庫、鏡像的標籤信息、鏡像的ID號(惟一)、建立時間、鏡像大小。

3.查看鏡像信息

命令:

docker inspect <image_id>

說明:

​ docker inspect命令返回的是一個JSON的格式消息,若是咱們只要其中的一項內容時,能夠經過-f參數來指定。Image_id一般可使用該鏡像ID的前若干個字符組成的可區分字符串來替代完成的ID。

sudo docker inspect -f {{.DockerVersion}} image_id
# DockerVersion前面有一個點號,查詢指定的內容

4.查找鏡像

命令:

docker search <image_name>

說明:

​ 使用docker search命令能夠搜索遠端倉庫中共享的鏡像,默認搜索Docker hub官方倉庫中的鏡像。

5.刪除鏡像

命令:

docker rmi <image>:<tag>

說明:

​ 使用docker rmi命令能夠刪除鏡像,其中image能夠爲標籤或ID。

注意:

  • 當同一個鏡像擁有多個標籤,docker rmi只是刪除該鏡像多個標籤中的指定標籤而已,而不影響鏡像文件。

  • 當有該鏡像建立的容器存在時,鏡像文件默認是沒法被刪除的。

  • 若是一個鏡像就有一個tag的話,刪除tag就刪除了鏡像的自己。

若是鏡像裏面有容器正在運行,刪除鏡像的話,會提示error,系統默認是不容許刪除的,若是強制刪除須要加入-f操做,可是docker是不建議這麼操做的,由於你刪除了鏡像其實容器並未刪除,直接致使容器找不到鏡像,這樣會比較混亂。

一個鏡像作一個tag:sudo docker tag image_id image:tag

執行刪除tag操做:sudo docker rmi image:tag

運行一個鏡像裏面的容器:$ sudo docker run centos echo 'Docker hahaha'

查看運行中的容器:sudo docker ps -a

6.建立鏡像

命令:

docker commit <options> <container_id><repository:tag>

參數說明:

​ -a , --author : 做者信息

​ -m , --meassage : 提交消息

​ -p , --pause=true : 提交時暫停容器運行

說明:

​ 基於已有的鏡像的容器的建立。

例子:以centos爲例子建立

運行centos,-ti把容器內標準綁定到終端並運行bash,這樣開跟傳統的linux操做系統沒什麼兩樣,如今咱們直接在容器內運行。這個內部系統都是極簡的只保留咱們的一些系統的運行參數,裏面不少vi命令可能都是沒有的。

$ sudo docker run -ti centos
[root@158183a8ae93 /]# echo '1111' > 1.txt
[root@158183a8ae93 /]# exit

退出容器exit。

容器建立成鏡像的方法:

​ 經過某個容器d1d6706627f1 建立對應的鏡像,有點相似git。注意,是根據容器ID建立的,可使用docker pa -a事先查看容器ID

命令:docker commit -a 'author' -m 'message' container_id image_name

sudo docker commit -a 'Sandu' -m 'create a docker version' 158183a8ae93 centos11/test

7.遷出鏡像

命令:

docker save -o <image>.tar <image>:<tag>

參數說明:

​ -o:設置存儲壓縮後的文件名稱

說明:

​ 可使用docker save命令來遷出鏡像,其中image能夠爲標籤或ID。

8.載入鏡像

命令:

docker load --input <image>.tar `

說明:

​ 使用docker load命令能夠載入鏡像,其中image能夠爲標籤或ID。這將導入鏡像及相關的元數據信息(包括標籤等),可使用docker images命令進行查看。能夠先刪除以前的鏡像而後再導入,或者在一臺新機器上部署docker環境後再導入

默認載入的鏡像沒有鏡像名稱和tag,使用下面的命令建立:sudo docker tag image_id image_name,tag自動爲latest

9.上傳鏡像

命令:

docker push <域名>/<namespace>/<repo>:<tag>

說明:

​ 可使用docker push命令上傳鏡像到倉庫,默認上傳到DockerHub官方倉庫(須要登陸)。

# 登錄到docker官網
$ sudo docker login

# 輸入帳號密碼,提示:Login Succeeded

# 而後開始上傳鏡像,注意:image_name的/前部分名稱要與官網註冊的名稱一致,不然提示:denied: requested access to the resource is denied
# 可使用tag方式複製一份鏡像並重命名的方式來上傳鏡像
# sudo docker tag image_id  xxxx/iamge_name  # xxxx要與在官網上註冊的Docker ID保持一致
$ sudo docker push image_name

4、容器的經常使用操做

1.建立容器

Docker的容器十分輕量級,用戶能夠隨時建立或刪除容器。

​ 新建容器:docker create

​ Example:docker create –it centos

說明:使用docker create命令建立的容器處於中止狀態,可使用docker start命令啓動它。

$ sudo docker create -it centos
$ sudo docker ps -a
CONTAINER ID   IMAGE     COMMAND      CREATED        STATUS          PORTS               NAMES
00e0a9ee7fe2   centos   "/bin/bash"    8 seconds ago     Created       affectionate_mahavira

新建並啓動容器:`docker run

​ Example: docker run centos /bin/echo 「Hello World」

說明: 等價於先執行docker create命令,再執行docker start命令。

docker run 背後的故事:

  • 1 檢查本地是否存在制定的鏡像,不存在就從公有倉庫下載。

  • 2 利用本地鏡像建立並啓動一個容器。

  • 3 分配一個文件系統,並在只讀的鏡像層外面掛載一層可讀寫層。

  • 4 從宿主機配置的網橋接口橋接一個虛擬接口到容器中去。

  • 5 從地址池配置一個IP地址給容器。

  • 6 執行用戶的指定的用戶程序。

  • 7 執行完畢後容器被終止。

一條簡單的命令:

docker run -i –t centos /bin/bash

  • -t : 讓docker分配一個僞終端並綁定到容器的標準輸入上。

  • -i : 讓容器的標準輸入保持打開。

在交互模式下,用戶能夠經過所建立的終端來輸入命令,exit命令退出容器。

退出後,容器自動處於終止狀態。

守護臺運行:

​ 更多的時候,須要讓Docker容器運行在後臺以守護態(daemonized)形式運行。用戶能夠經過添加-d參數來實現。

Example:

docker run -d centos /bin/bash -c "while true;do echo hello world;sleep 1;done"

補充:

​ 查看日誌: docker logs <container_id>

docker logs –f <container_id>動態的查看日誌,相似查看tomcat的日誌同樣

2.終止容器

可使用docker stop命令來終止一個運行中的容器。

docker stop <container_id>

注意:當容器中的應用終結時,容器也會自動中止。

查看終止的容器:docker ps -a

查看運行的容器:docker ps

從新啓動容器:docker start <container_id>

3.進入容器

在使用-d參數時,容器啓動後會進入後臺,用戶沒法看到容器中的信息。

docker exec <options> <container_id> <command>

Exec能夠直接在容器內部運行命令。前提是容器正在運行。

進入容器:

docker exec -i –t <container_id> bash

區別:

  • run 運行一個容器後,進入容器的話,exit退出後,容器也直接退出

  • exec 進入容器後,exit退出後,容器不退出仍在後臺運行

4.刪除容器

可使用docker rm命令刪除終止狀態的容器。

docker rm image_name|image_id

若是刪除正在運行的容器,須要中止容器而後進行刪除。

無論容器是否運行,可使用docker rm –f命令進行刪除。

5.導入和導出容器

導出容器是指導出一個已經建立的容器到一個文件,無論容器是否處於運行狀態。可使用docker export命令。

docker export <container_id>

Example:

docker export container_id > test.tar

sudo docker export 7adfb980d640 > test_contain_id.tar

導出的文件又可使用docker import命令導入,成爲鏡像。

Example:

cat test_contain_id.tar | docker import - image_name:latest

注意:不知爲啥,通常用戶沒法導入,須要使用root用戶才能夠導入成功

5、倉庫

1.Docker Hub

倉庫是集中存放鏡像的地方。

目前Docker官方倉庫維護了一個公共倉庫https://hub.docker.com,其中已經包括15000多個的鏡像。

大部分需求均可以經過在Docker Hub中直接下來鏡像來實現。

登錄:

能夠經過執行docker login命令來輸入用戶名、密碼和郵箱來完成註冊登陸。

基本操做

用戶無需登陸能夠經過 docker search命令來查找官方倉庫中的鏡像,並利用docker pull下載到本地,能夠經過docker push命令將本地鏡像推送到docker hub。

先tag一下複製一個鏡像,而後把鏡像push到服務器上。

2.建立和使用私有倉庫

使用registry鏡像建立私有倉庫

能夠經過docker官方提供的registry鏡像來搭建一套本地私有倉庫。

鏡像地址:https://hub.docker.com/_/registry/

命令:

docker run -e SEARCH_BACKEND=sqlalchemy -e SQLALCHEMY_INDEX_DATABASE=sqlite:////tmp/docker-registry.db -d --name registry -p 5000:5000 registry

命令參數:

  • -e設定環境變量

  • -d從後臺啓動的方式鏡像啓動

  • -name 啓動的容器起個名字

  • -p 暴露端口,容器內部的5000綁定到宿主機的5000端口上。

  • registry鏡像自己

  • SEARCH_BACKEND=sqlalchemy默認索引是能夠查詢的

參考地址:

https://github.com/docker/docker-registry#search-engine-options

https://hub.docker.com/_/registry/

# 1. 先配置,提早解決後續出現的問題:http: server gave HTTP response to HTTPS client 
[sandu@bogon ~]$ sudo vim /etc/doker/daemon.json # 沒有該文件的話就建立一個
{ "insecure-registries":["192.168.0.192:5000"] } # ip爲本機的ip,5000端口爲後續使用的端口
# 重啓docker服務
[sandu@bogon ~]$ sudo systemctl daemon-reload
[sandu@bogon ~]$ sudo systemctl restart docker.service
# 2. 登錄docker
[sandu@bogon ~]$ sudo docker login
# 3.拉取私有倉庫鏡像
[sandu@bogon ~]$ sudo docker run -e SEARCH_BACKEND=sqlalchemy -e SQLALCHEMY_INDEX_DATABASE=sqlite:////tmp/docker-registry.db -d --name registry -p 5000:5000 registry
[sudo] password for sandu: 
Unable to find image 'registry:latest' locally
Trying to pull repository docker.io/library/registry ... 
latest: Pulling from docker.io/library/registry
c87736221ed0: Pull complete 
1cc8e0bb44df: Pull complete 
54d33bcb37f5: Pull complete 
e8afc091c171: Pull complete 
b4541f6d3db6: Pull complete 
Digest: sha256:8004747f1e8cd820a148fb7499d71a76d45ff66bac6a29129bfdbfdc0154d146
Status: Downloaded newer image for docker.io/registry:latest
1cec256c7e63bb6b29cbeb7ae1b3b25fc53fbb86122b950eee788f553ce14619

# 查看當前運行的容器
[sandu@bogon ~]$ sudo docker ps
CONTAINER ID  IMAGE   COMMAND              CREATED           STATUS      PORTS               NAMES
630bf936586d  registry "/entrypoint.sh /e..."   9 minutes ago       Up 9 minutes  0.0.0.0:5000->5000/tcp   registry

# 查看現有鏡像
[sandu@bogon ~]$ sudo docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
docker.io/centos     latest              9f38484d220f        4 months ago        202 MB
docker.io/registry   latest              f32a97de94e1        5 months ago        25.8 MB

# 4.拉取一個公共鏡像,修改後打算上傳到私有倉庫,須要給該鏡像從新賦值一個tag
[sandu@bogon ~]$ sudo docker tag docker.io/centos 192.168.0.192:5000/sanduzxcvbnm/test2_registry
# 注意:前面的參數是打算上傳到私有倉庫的鏡像,後面那個是從新賦值的tag,最前面的是私有倉庫地址,中間的是在docker官網註冊的用戶名,後者是鏡像名

[sandu@bogon ~]$ sudo docker images
REPOSITORY                                       TAG                 IMAGE ID            CREATED             SIZE
192.168.0.192:5000/sanduzxcvbnm/test2_registry   latest              9f38484d220f        5 months ago        202 MB
docker.io/centos                                 latest              9f38484d220f        5 months ago        202 MB
docker.io/registry                               latest              f32a97de94e1        5 months ago        25.8 MB

# 5.上傳鏡像到私有倉庫
[sandu@bogon ~]$ sudo docker push 192.168.0.192:5000/sanduzxcvbnm/test2_registry

3.倉庫加速服務

加速下載官方鏡像。

推薦服務:https://dashboard.daocloud.io/

點擊加速器:https://dashboard.daocloud.io/mirror

4.倉庫管理

Registry Web UI 用於鏡像的查詢,刪除。

鏡像地址:https://hub.docker.com/r/atcol/docker-registry-ui/

# 拉取管理倉庫的web鏡像,把私有倉庫綁定到管理倉庫web並啓動
[sandu@bogon ~]$ sudo docker run -d --name registry_ui -p 8080:8080 -e REG1=http://192.168.0.192:5000/v1/ atcol/docker-registry-ui

# 問題
界面上雖然能看到本身建立的私有倉庫信息,可是界面提示:ping faild
查看日誌:docker logs -f registry_ui,報錯信息以下:
2019-08-12 03:24:00,187 [http-nio-8080-exec-5] ERROR web.RepositoryService  - Failed to ping http://192.168.0.192:5000/v1/_ping: 404 : Not Found

此問題留待之後解決,初步判斷是須要給私有倉庫添加認證信息

6、數據管理

1.數據卷

數據卷是一個可供容器使用的特殊目錄,有以下特性:

  • 數據卷能夠在容器之間共享和重用

  • 數據卷修改會當即生效

  • 數據卷的更新不會影響鏡像

  • 若是有容器使用數據卷,該卷會一直存在

準備工做:

​ 建立一個目錄,並在目錄裏面建立文件,文件內寫入內容。

[root@bogon ~]# cd /tmp/
[root@bogon tmp]# mkdir webapp
[root@bogon tmp]# cd webapp/
[root@bogon webapp]# echo '數據卷' > 1.txt
[root@bogon webapp]# cat 1.txt
數據卷
[root@bogon webapp]#

1.1在容器內建立數據卷

在使用docker run的命令時,使用 -v 標記能夠在容器內建立一個數據卷,而且能夠指定掛在一個本地已有的目錄到容器中做爲數據卷:

建立啓動app1容器並掛載數據卷,注意,此時是在tmp目錄下進行的操做

echo ${pwd} 命令標識當前目錄

[root@bogon tmp]# docker run -d --name app1 -it -v ${pwd}/webapp:/root/webapp centos bash

經過目錄跟容器內創建了一層關係,數據捲髮生變化後,容器內和容器外都會隨之發生改變。例如容器掛載一個文件,當容器掛了後,文件不會丟失。

注意:默認掛載的數據卷的權限是rw(可讀寫),若是要求ro(只讀),則須要加上對應的ro參數,命令可改成:

docker run -d --name app1 -it -v ${pwd}/webapp:/root/webapp:ro centos bash

# 建立啓動app1容器並掛載數據卷,前者/tmp/webapp是本機路徑,後者/tmp/webapp1是容器路徑
[root@bogon webapp]# docker run -d -it --name app1 -v /tmp/webapp:/tmp/webapp1 centos bash
# 進入容器找到/tmp目錄可查看到已掛載的數據卷
[root@bogon webapp]# docker exec -it app1 bash
[root@11755ef11dc1 /]# cd /tmp/
[root@11755ef11dc1 tmp]# ll
total 4
-rwx------. 1 root root 836 Mar  5 17:36 ks-script-eC059Y
drwxr-xr-x. 2 root root  32 Aug 13 06:30 webapp1
-rw-------. 1 root root   0 Mar  5 17:34 yum.log
# 數據卷目錄與容器內目錄有映射關係,因此無論是在容器內部修改數據卷仍是在外部修改數據卷,相對應的數據卷都會發生改變。
# 在容器內修改文件數據後,exit退出容器,進入本機路徑查看文件,會發現文件也發生了變化.
# 只讀權限是沒法寫入數據的

2.數據卷容器

數據卷容器用於用戶須要在容器間共享一些持續更新的數據,數據卷容器專門提供數據卷供其它容器掛載使用。

2.1 建立數據卷容器

Example:

建立數據卷容器db1

docker run -d --name db1 -v /dbdata -ti centos bash

建立容器db2與db1共享dbdata的數據

docker run -d --name db2 --volumes-from db1 -ti centos bash

# 建立數據卷容器db1
[root@bogon tmp]# docker run -d --name db1 -v /tmp/dbdata/ -it centos bash
# 建立數據卷容器db2,使用db1的數據卷
[root@bogon tmp]# docker run -d --name db2 --volumes-from db1 -it centos bash
# 在容器db1和容器db2任意一個容器修改/tmp/dbdata/的內容,在兩個容器內均生效

2.2 數據卷容器的刪除

若是刪除了掛載的容器,數據卷並不會被自動刪除,若是要刪除一個數據卷,必須在刪除最後一個還掛載它的容器時顯示使用docker rm -v 命令指定同時刪除關聯的容器。能夠利用數據卷容器對其中的數據捲進行備份、恢復,以實現數據的遷移。

2.3 數據卷容器的備份

使用下面的命令來備份dbdata數據卷容器內的數據卷:

docker run --volumes-from /tmp/dbdata -v ${PWD}:/backup --name worker centos \tar cvf /backup/backup.tar /tmp/dbdata

說明:

利用centos鏡像建立一個容器worker。

使用`--volumes-from /tmp/dbdata參數來讓worker容器掛載dbdata的數據卷。

使用${pwd}:/backup參數來掛載本地目錄到worker容器的/backup目錄。

worker啓動後,使用tar命令將/tmp/dbdata下的內容備份爲容器內的/backup/backup.tar。

2.4 數據卷容器的恢復

若是恢復數據到一個容器,能夠參照下面的操做。首先建立一個帶有數據卷的容器dbdata2:

` docker run -d -v /dbdata --name dbdata2 centos /bin/bash

而後建立另外一個新的容器,掛載dbdata2的容器,並使用tar命令解壓備份文件到掛載的容器卷中便可:

docker run --volumes-fromd bdata2 -v ${pwd}:/backup centos tar xvf /backup/backup.tar

7、網絡

1.容器對外服務

當容器內運行一些網絡應用,要讓外部訪問這些應用時,能夠經過 -P 或 -p 參數來指定端口映射。

使用 -P 映射時,Docker會隨機映射一個49000 ~49900 的端口至容器內部開放的端口:

docker run -d -P --name mysql mysql:5.6

經過docker ps能夠看到端口映射關係。

能夠經過映射在宿主機的端口來訪問對應容器內的服務。

映射到指定宿主機的端口:

# 從官網拉取並運行MySQL5.6鏡像,並設置鏡像內的MySQL鏈接密碼
docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:5.6
# -e 是環境變量的意思 運行容器內的環境變量設置mysql的密碼
# 默認使用宿主機的3306端口

映射到指定地址的指定端口,爲例:

docker run -d -p 3306:3306 --name -e MYSQL_ROOT_PASSWORD=my-secret-pw mysql mysql:5.6

若不加上-e參數,則會報錯:

error: database is uninitialized and password option is not specified You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD

[root@bogon log]# docker ps
CONTAINER ID   IMAGE   COMMAND     CREATED   STATUS       PORTS           NAMES
9f298b7aeb6e  mysql:5.6   "docker-entrypoint..."   3 seconds ago       Up 2 seconds        0.0.0.0:3306->3306/tcp   mysql
# 0.0.0.0表示任意主機均能訪問

外部訪問宿主機的3306直接映射到容器的3306鏈接到數據庫

映射到指定地址的指定端口,以127.0.0.1爲例:

docker run -d -p 127.0.0.1:3306:3306 -e MYSQL_ROOT_PASSWORD=my-secret-pw --name mysql mysql:5.6

[root@bogon log]# docker ps
CONTAINER ID   IMAGE    COMMAND    CREATED    STATUS   PORTS      NAMES
082f503397da   mysql:5.6    "docker-entrypoint..."   3 seconds ago   Up 2 seconds    127.0.0.1:3306->3306/tcp   quirky_franklin
# 127.0.0.1 表示僅本機才能訪問,沒有使用--name指定容器名則隨機生成一個

映射到指定地址的任意端口,以127.0.0.1爲例:

docker run -d -p 127.0.0.1::3306 -e MYSQL_ROOT_PASSWORD=my-secret-pw --name mysqlmysql:5.6

[root@bogon log]# docker ps
CONTAINER ID   IMAGE   COMMAND  CREATED  STATUS   PORTS    NAMES
29293afe0d7a   mysql:5.6   "docker-entrypoint..."   4 seconds ago   Up 3 seconds   127.0.0.1:32768->3306/tcp   unruffled_curran
# 宿主機沒有指定端口,則隨機使用一個端口跟容器3306端口作映射

查看映射端口配置:

docker port mysql 3306

[root@bogon log]# docker port 29293afe0d7a
3306/tcp -> 127.0.0.1:32768

2.容器間相互通訊

經過映射宿主機的端口實現容器的互聯。

使用--link參數可讓容器之間安全的進行交互。

建立一個數據庫容器:

docker run -d -e MYSQL_ROOT_PASSWORD=my-secret-pw --name mysqldb mysql:5.6

建立一個web容器並和數據庫容器創建鏈接:

docker run -d --name Webapp -p 8000:8080 --link mysqldb:MySQL tomcat

上邊的MySQL別名就相似dns解析的方式,我給這個容器起了個別名叫MySQL,我就經過這個別名就能夠找到對應的這個mysqldb容器

mysqldb容器和web容器創建互聯關係。

--link參數的格式爲--link name:alias,其中name是要鏈接的容器名稱,alias是這個鏈接的別名。

[root@bogon log]# docker run -d -e MYSQL_ROOT_PASSWORD=my-secret-pw --name mysqldb mysql:5.6
5978df27095f87193bf6dbffd5cf7c1e315b19129687c4409757b83923a70c02
[root@bogon log]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
5978df27095f        mysql:5.6           "docker-entrypoint..."   5 seconds ago       Up 4 seconds        3306/tcp            mysqldb
[root@bogon log]# docker run -d --name webapp -p 8000:8080 --link mysqldb:MySQL tomcat 
Unable to find image 'tomcat:latest' locally
Trying to pull repository docker.io/library/tomcat ... 
latest: Pulling from docker.io/library/tomcat
9cc2ad81d40d: Pull complete 
8e391ba3712a: Pull complete 
Digest: sha256:ddb9336dcd0ff66874db84880d58f6571bfa737cf6390bc38a66d1f78a857be6
Status: Downloaded newer image for docker.io/tomcat:latest
690b944739532e1ce55dfe49b5e3b24ddd5a13f8030d384c975f87631a8a5056
[root@bogon log]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                    NAMES
690b94473953        tomcat              "catalina.sh run"        3 seconds ago        Up 2 seconds        0.0.0.0:8000->8080/tcp   webapp
5978df27095f        mysql:5.6           "docker-entrypoint..."   About a minute ago   Up About a minute   3306/tcp                 mysqldb
[root@bogon log]# docker exec -it webapp bash
root@690b94473953:/usr/local/tomcat# ping MySQL
PING MySQL (172.17.0.2) 56(84) bytes of data.
64 bytes from MySQL (172.17.0.2): icmp_seq=1 ttl=64 time=0.119 ms
64 bytes from MySQL (172.17.0.2): icmp_seq=2 ttl=64 time=0.078 ms
^Z
[1]+  Stopped                 ping MySQL

可使用docker ps(PORT字段)來查看容器的鏈接。

Docker在兩個容器之間建立了安全隧道,並且不用映射它們的端口到宿主機上。在啓動mysqldb的時候並無使用-p和-P標記,從而避免的了暴露數據庫的端口到外部的網絡上。

link就是容器直接互相通訊的

Docker經過兩種方式爲容器公開鏈接信息:

1 環境變量:

使用env命令來查看。

EX:docker run --rm --name test --link dblink:dblink ubuntu env

2 更新/etc/hosts文件

查看/etc/hosts文件。

八 、Dockerfile

1. 利用Dockerfile建立鏡像

什麼是Dockerfile?

定義:Dockerfile是一個文本格式的配置文件,用戶可使用Dockerfile快速建立自定義鏡像。

基本結構:

Dockerfile由一行行的命令語句組成。而且支持以#開頭的註釋行。

通常Dockerfile分爲四個部分:基礎鏡像信息、維護者信息、鏡像操做指令和容器啓動時的指令。

Dockerfile示例:

#This is a Dockerfile

#Author:liming

#第一行必須指定基礎鏡像

FROM ubuntu

#維護者信息

MAINTAINER 394498036@qq.com

#鏡像的操做指令

RUN apt-get update

RUN apt-getinstall -y nginx

RUN echo 「\ndaemonoff:」 >> /etc/nginx/nginx.conf

#容器啓動時的指令

CMD /usr/sbin/nginx

建立命令:

docker build –t=「<鏡像名稱>」 .

注意:執行此命令要和Dockerfile在同級目錄,文件名稱必須爲Dockerfile。命令後面的」.」表示在當前目錄下執行。

2.Dockerfile指令集

1 FROM

格式爲 FROM :

第一條指令必須爲FROM指令,用於指定基礎鏡像。

2 MAINTAINER

格式爲 MAINTAINER ,指定維護者信息。

3 RUN

格式爲 RUN ,會在shell終端運行命令。

4 EXPOSE

格式爲 EXPOSE [ ...],容器須要暴露的端口號。鏡像啓動能夠經過 –P 或 -p 進行端口映射的綁定。

5 ENV

格式爲 ENV

指定一個環境變量,能夠被後續的RUN引用,而且在容器中記錄該環境變量。

6 ADD

格式爲 ADD

該命令將複製指定的 到容器中的 。其中 能夠是Dockerfile所在目錄的一個相對路徑;也能夠是url,還能夠是tar文件(自動解壓)。

7 VOLUME

格式爲 VOLUME [path]。

建立一個能夠從本地主機或其餘容器掛載點,通常用來存放須要保持的數據。

8 USER

格式爲 USER

指定運行容器時的用戶名,後續的RUN也會指定該用戶。

9 WORKDIR

格式爲 WORKDIR

指定工做空間,運行完WORKDIR後,後續執行的RUN、CMD、ENTRYPOINT都會在此目錄下執行。

10 COPY

格式爲 COPY

複製本地主機的 到容器中的 ,目標路徑不存在時,會自動建立。

當使用本地目錄爲源目錄時,推薦使用COPY。

11 CMD

推薦格式爲 CMD [「executable」,」param1」,」param2」] 。

做爲ENTRYPOINT的默認參數爲 CMD[」param1」,」param2」]。

指定容器的啓動命令,每一個Dockerfile只能有一條CMD命令,若是指定多條,只有最後一條會執行。

用戶啓動容器時指定運行命令,會覆蓋掉Dockerfile中的CMD命令。

12 ENTRYPOINT

格式爲 ENTRYPOINT [「executable」,」param1」,」param2」]。

配置容器啓動後的命令,可被docker run提供的--entrypoint參數覆蓋。

每一個Dockerfile只能有一條ENTRYPOINT命令,若是指定多條,只有最後一條會執行。

3.容器內安裝工具的方法

yum 或者apt-get

4.Dockerfile最佳實踐

1 錯誤定位

每一個Dockerfile的指令能夠生成新的一層鏡像,若是經過Dockerfile建立鏡像出錯,能夠根據出錯所在步驟的上一層啓動容器,而後手工執行出錯層的命令,以達到調試目的。

2 好的使用習慣

一、使用緩存
Dockerfile的每條指令都會將結果提交爲新的鏡像,下一個指令將會基於上一步指令的鏡像的基礎上構建,若是一個鏡像存在相同的父鏡像和指令(除了ADD),Docker將會使用鏡像而不是執行該指令,即緩存。

爲了有效地利用緩存,你須要保持你的Dockerfile一致,而且儘可能在末尾修改。我全部的Dockerfile的前五行都是這樣的:

FROM ubuntu
MAINTAINER Michael Crosby <michael@crosbymichael.com>
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
RUN apt-get update
RUN apt-get upgrade -y


更改MAINTAINER指令會使Docker強制執行RUN指令來更新apt,而不是使用緩存。

因此,咱們應該使用經常使用且不變的Dockerfile開始(譯者注:上面的例子)指令來利用緩存。

二、使用標籤
除非你正在用Docker作實驗,不然你應當經過-t選項來docker build新的鏡像以便於標記構建的鏡像。一個簡單的可讀標籤將幫助你管理每一個建立的鏡像。

docker build -t="crosbymichael/sentry" .


注意,始終經過-t標記來構建鏡像。

三、公開端口
兩個Docker的核心概念是可重複和可移植。鏡像應該能夠運行在任何主機上而且運行儘量多的次數。在Dockerfile中你有能力映射私有和公有端口,可是你永遠不要經過Dockerfile映射公有端口。經過映射公有端口到主機上,你將只能運行一個容器化應用程序實例。(譯者注:運行多個端口不就衝突啦)

#private and public mapping
EXPOSE 80:8080

#private only
EXPOSE 80


若是鏡像的使用者關心容器公有映射了哪一個公有端口,他們能夠在運行鏡像時經過-p參數設置,不然,Docker會自動爲容器分配端口。

切勿在Dockerfile映射公有端口。

四、CMD與ENTRYPOINT的語法
CMD和ENTRYPOINT指令都很是簡單,但它們都有一個隱藏的容易出錯的「功能」,若是你不知道的話可能會在這裏踩坑,這些指令支持兩種不一樣的語法。

CMD /bin/echo
#or
CMD ["/bin/echo"]


這看起來好像沒什麼問題,但仔細一看其實兩種方式差距很大。若是你使用第二個語法:CMD(或ENTRYPOINT)是一個數組,它執行的命令徹底像你指望的那樣。若是使用第一種語法,Docker會在你的命令前面加上/bin/sh -c,我記得一直都是這樣。

若是你不知道Docker修改了CMD命令,在命令前加上/bin/sh -c可能會致使一些意想不到的問題以及難以理解的功能。所以,在使用這兩個指令時你應當使用數組語法,由於數組語法會確切地執行你打算執行的命令。

使用CMD和ENTRYPOINT時,請務必使用數組語法。

五、CMD和ENTRYPOINT 結合使用更好
docker run命令中的參數都會傳遞給ENTRYPOINT指令,而不用擔憂它被覆蓋(跟CMD不一樣)。當與CMD一塊兒使用時ENTRYPOINT的表現會更好。讓咱們來研究一下個人Rethinkdb Dockerfile,看看如何使用它。

#Dockerfile for Rethinkdb 
#http://www.rethinkdb.com/

FROM ubuntu

MAINTAINER Michael Crosby <michael@crosbymichael.com>

RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
RUN apt-get update
RUN apt-get upgrade -y

RUN apt-get install -y python-software-properties
RUN add-apt-repository ppa:rethinkdb/ppa
RUN apt-get update
RUN apt-get install -y rethinkdb

#Rethinkdb process
EXPOSE 28015
#Rethinkdb admin console
EXPOSE 8080

#Create the /rethinkdb_data dir structure
RUN /usr/bin/rethinkdb create

ENTRYPOINT ["/usr/bin/rethinkdb"]

CMD ["--help"]


這是Docker化Rethinkdb的全部配置文件。在開始咱們有標準的5行來確保基礎鏡像是最新的、端口的公開等。當ENTRYPOINT指令出現時,咱們知道每次運行該鏡像,在docker run過程當中傳遞的全部參數將成爲ENTRYPOINT(/usr/bin/rethinkdb)的參數。

在Dockerfile中我還設置了一個默認CMD參數--help。這樣作是爲了docker run期間若是沒有參數的傳遞,rethinkdb將會給用戶顯示默認的幫助文檔。這是你所指望的與rethinkdb交互相同的功能。

docker run crosbymichael/rethinkdb


輸出

Running 'rethinkdb' will create a new data directory or use an existing one,
and serve as a RethinkDB cluster node.
File path options:
-d [ --directory ] path           specify directory to store data and metadata
--io-threads n                    how many simultaneous I/O operations can happen
                                at the same time

Machine name options:
-n [ --machine-name ] arg         the name for this machine (as will appear in
                                the metadata).  If not specified, it will be
                                randomly chosen from a short list of names.

Network options:
--bind {all | addr}               add the address of a local interface to listen
                                on when accepting connections; loopback
                                addresses are enabled by default
--cluster-port port               port for receiving connections from other nodes
--driver-port port                port for rethinkdb protocol client drivers
-o [ --port-offset ] offset       all ports used locally will have this value
                                added
-j [ --join ] host:port           host and port of a rethinkdb node to connect to
.................


如今,讓咱們帶上--bind all參數來運行容器。

docker run crosbymichael/rethinkdb --bind all


輸出

info: Running rethinkdb 1.7.1-0ubuntu1~precise (GCC 4.6.3)...
info: Running on Linux 3.2.0-45-virtual x86_64
info: Loading data from directory /rethinkdb_data
warn: Could not turn off filesystem caching for database file: "/rethinkdb_data/metadata" (Is the file located on a filesystem that doesn't support direct I/O (e.g. some encrypted or journaled file systems)?) This can cause performance problems.
warn: Could not turn off filesystem caching for database file: "/rethinkdb_data/auth_metadata" (Is the file located on a filesystem that doesn't support direct I/O (e.g. some encrypted or journaled file systems)?) This can cause performance problems.
info: Listening for intracluster connections on port 29015
info: Listening for client driver connections on port 28015
info: Listening for administrative HTTP connections on port 8080
info: Listening on addresses: 127.0.0.1, 172.16.42.13
info: Server ready
info: Someone asked for the nonwhitelisted file /js/handlebars.runtime-1.0.0.beta.6.js, if this should be accessible add it to the whitelist.


就這樣,一個全面的能夠訪問db和管理控制檯的Rethinkdb實例就運行起來了,你能夠用與鏡像交互同樣的方式來與其交互。雖然簡單小巧但它的功能很是強大。

CMD和ENTRYPOINT 結合在一塊兒使用更好。

我但願這篇文章能夠幫助你使用Dockerfiles以及構建鏡像。Dockerfile是Docker的重要一部分,不管你是構建或是使用鏡像,它都很是簡單並且使用方便。我打算投入更多的時間來提供一個完整的、功能強大但簡單的解決方案來使用Dockerfile構建Docker鏡像。

一、不要開機初始化
容器模型是進程而不是機器。若是你認爲你須要開機初始化,那麼你就錯了。

二、可信任構建
即便你不喜歡這個題目但它是很棒的一個功能。我把大部分 GitHub 倉庫添加到可信任構建,所以當我提交一個新鏡像以後不久,就在等待索引。另外,我沒必要再建立單獨的 Dockerfile 倉庫與他人分享,它們都在同一個地方。

請記住,這不是你嘗試新東西的試驗場。在你推送以前,請在本地先構建一下。Docker 能夠確保你在本地的構建和運行,與你推送到任何地方的構建和運行是同樣的。本地開發和測試、提交和推送、以及等待索引上的官方鏡像都是創建在可信任構建的基礎之上的。

三、不要在構建中升級版本
更新將發生在基礎鏡像裏,你不須要在你的容器內來apt-get upgrade更新。由於在隔離狀況下,若是更新時試圖修改 init 或改變容器內的設備,更新可能會常常失敗。它還可能會產生不一致的鏡像,由於你再也不有你的應用程序該如何運行以及包含在鏡像中依賴的哪一種版本的正確源文件。

若是基礎鏡像須要安全更新,那麼讓上游的知道,讓他們給你們更新,並確保你再次構建的一致性。

四、使用小型基礎鏡像
有些鏡像比其餘的更臃腫。我建議使用debian:jessie做爲你的基礎鏡像。若是你熟悉Ubuntu,你將發現一個更輕量和巧妙的自制 debian,它足夠小而且沒有包含任何不須要的包。

五、使用特定的標籤
對於你的基礎鏡像這是很是重要的。Dockerfile 中FROM應始終包含依賴的基礎鏡像的完整倉庫名和標籤。好比說FROM debian:jessie而不只僅是FROM debian。

六、常見指令組合
您的apt-get update應該與apt-get install組合。此外,你應該採起\的優點使用多行來進行安裝。

#Dockerfile for https://index.docker.io/u/crosbymichael/python/ 
FROM debian:jessie

RUN apt-get update && apt-get install -y \
git \
libxml2-dev \
python \
build-essential \
make \
gcc \
python-dev \
locales \
python-pip

RUN dpkg-reconfigure locales && \
locale-gen C.UTF-8 && \
/usr/sbin/update-locale LANG=C.UTF-8

ENV LC_ALL C.UTF-8


謹記層和緩存都是不錯的。不要懼怕過多的層,由於緩存是大救星。固然,你應當儘可能使用上游的包。

七、使用本身的基礎鏡像
我不是在談論運行 debbootstrap 來製做本身的 debian。你不是 tianon(Tianon Gravi),沒有人想要你認爲別人須要你的 500mb 的狗屎垃圾基礎鏡像。我說的是,若是你要運行 python 應用程序須要有一個python基礎鏡像。前面示例中用於構建 crosbymichael/python 的 Dockerfile 也被用於其餘不少構建 Python 應用程序的鏡像。

FROM crosbymichael/python

RUN pip install butterfly
RUN echo "root\nroot\n" | passwd root

EXPOSE 9191
ENTRYPOINT ["butterfly.server.py"]
CMD ["--port=9191", "--host=0.0.0.0"]


另外一個:

FROM crosbymichael/python

RUN pip install --upgrade youtube_dl && mkdir /download
WORKDIR /download
ENTRYPOINT ["youtube-dl"]
CMD ["--help"]


正如你看到的,這使得使用你的基礎鏡像很是小,從而使你集中精力在應用程序上。

九 、持續系統集成了解下git

1.什麼是持續集成?

持續集成(Continuous integration,簡稱CI)。

​ 根據敏捷大師Martin Fowler的定義,「持續集成是一種軟件開發實踐。在持續集成中,團隊成員頻繁集成他們的工做成果,通常每人天天至少集成一次,也能夠屢次。每次集成會通過自動構建(包括自動測試)的檢驗,以儘快發現集成錯誤。許多團隊發現這種方法能夠顯著減小集成引發的問題,並能夠加快團隊合做軟件開發的速度。

爲何要持續集成?

​ 1 快速發現錯誤:每完成一點更新,就集成到主幹,能夠快速發現錯誤,定位錯誤也比較容易。

​ 2 防止分支大幅偏離主幹:若是不是常常集成,主幹又在不斷更新,會致使之後集成的難度變大,甚至難以集成。

下面是持續集成的圖譜介紹:

​ 1 將更改提交到代碼管理倉庫

​ 2 持續集成服務器收到請求拉取變動代碼

​ 3 持續集成服務器編譯代碼

​ 4 持續集成服務器跑代碼相關測試

​ 5 持續集成服務器測試結束

​ 6 持續集成服務器對結果進行反饋Docker在持續集成中的做用:Docker提供代碼編譯、打包、測試的相關環境。

優點:

​ 1 環境能夠是是任意版本

​ 2 節省空間

​ 3 環境相對隔離

2.什麼是Git?

​ Git是一個開源的分佈式版本控制系統,能夠有效、高速的處理從很小到很是大的項目版本管理。Git 是 Linus Torvalds 爲了幫助管理 Linux 內核開發而開發的一個開放源碼的版本控制軟件。

Git經常使用命令:

1 初始化git項目

git init

2 查看當前項目狀態

git status

3 新建文件並再次查看狀態

echo 「# My Project」 > README.md

git status

4 記錄當前操做,記錄新加入的文件並再次查看狀態

git add README.md

git status

5 記錄當前更改並加以信息描述

git commit 文件名 -m ’add my first project’

6 查看提交歷史

git log

7 新建遠程倉庫

git remote add origin https://github.com/limingios/git-test.git

8 同步到遠程倉庫

git push -u origin master

9 從遠程代碼庫同步到本地

git pull origin master

10 與同步前對比變動

git diff HEAD

11 查看當前更改變動

git diff --staged

12 恢復到爲更改狀態

​ git reset README.md

13 覆蓋本地文件

​ git checkout octocat.txt

14 新建分支

​ git branch feature1

15 切換分支

​ git checkout feature1

16 刪除本地分支

​ git branch –d feature1

10、jenkins的使用

11、Github+Jenkins+Docker持續集成

相關文章
相關標籤/搜索