Docker 容器入門

Docker 容器入門

 
分類:  容器/虛擬化

1.1 容器簡介

1.1.1 什麼是 Linux 容器

Linux容器是與系統其餘部分隔離開的一系列進程,從另外一個鏡像運行,並由該鏡像提供支持進程所需的所有文件。容器提供的鏡像包含了應用的全部依賴項,於是在從開發到測試再到生產的整個過程當中,它都具備可移植性和一致性。php

 更加詳細地來講,請您假定您在開發一個應用。您使用的是一臺筆記本電腦,並且您的開發環境具備特定的配置。其餘開發人員身處的環境配置可能稍有不一樣。您正在開發的應用依賴於您當前的配置,還要依賴於某些特定文件。與此同時,您的企業還擁有標準化的測試和生產環境,且具備自身的配置和一系列支持文件。您但願儘量多在本地模擬這些環境,而不產生從新建立服務器環境的開銷。html

 所以,您要如何確保應用可以在這些環境中運行和經過質量檢測,而且在部署過程當中不出現使人頭疼的問題,也無需從新編寫代碼和進行故障修復?答案就是使用容器。容器能夠確保您的應用擁有必需的配置和文件,使得這些應用可以在從開發到測試、再到生產的整個流程中順利運行,而不出現任何不良問題。這樣能夠避免危機,作到皆大歡喜。java

雖然這只是簡化的示例,但在須要很高的可移植性、可配置性和隔離的狀況下,咱們能夠利用 Linux 容器經過不少方式解決難題。不管基礎架構是在企業內部仍是在雲端,或者混合使用二者,容器都能知足您的需求。node

1.1.2 容器不就是虛擬化嗎

是,但也不居然。咱們用一種簡單方式來思考一下:python

虛擬化使得許多操做系統可同時在單個系統上運行。mysql

容器則可共享同一個操做系統內核,將應用進程與系統其餘部分隔離開。linux

圖 - 普通虛擬化技術和Docker的對比nginx

這意味着什麼?首先,讓多個操做系統在單個虛擬機監控程序上運行以實現虛擬化,並不能達成和使用容器同等的輕量級效果。事實上,在僅擁有容量有限的有限資源時,您須要可以能夠進行密集部署的輕量級應用。Linux 容器可從單個操做系統運行,在全部容器中共享該操做系統,所以應用和服務可以保持輕量級,並行快速運行。git

1.1.3 容器發展簡史

 

咱們如今稱爲容器技術的概念最初出如今 2000 年,當時稱爲 FreeBSD jail,這種技術可將 FreeBSD 系統分區爲多個子系統(也稱爲 Jail)。Jail 是做爲安全環境而開發的,系統管理員可與企業內部或外部的多個用戶共享這些 Jail。github

Jail 的目的是讓進程在通過修改的 chroot 環境中建立,而不會脫離和影響整個系統 — 在 chroot 環境中,對文件系統、網絡和用戶的訪問都實現了虛擬化。儘管 Jail 在實施方面存在侷限性,但最終人們找到了脫離這種隔離環境的方法。

但這個概念很是有吸引力。

2001 年,經過 Jacques Gélinas 的 VServer 項目,隔離環境的實施進入了 Linux 領域。正如 Gélinas 所說,這項工做的目的是「在高度獨立且安全的單一環境中運行多個通用 Linux 服務器 [sic]。」 在完成了這項針對 Linux 中多個受控制用戶空間的基礎性工做後,Linux 容器開始逐漸成形並最終發展成瞭如今的模樣。

1.2 什麼是 Docker?

「Docker」 一詞指代多種事物,包括開源社區項目、開源項目使用的工具、主導支持此類項目的公司Docker Inc. 以及該公司官方支持的工具。技術產品和公司使用同一名稱,的確讓人有點困惑。

咱們來簡單說明一下:

 🎍 IT 軟件中所說的 「Docker」 ,是指容器化技術,用於支持建立和使用 Linux 容器。

🎍 開源 Docker 社區致力於改進這類技術,並免費提供給全部用戶,使之獲益。

🎍 Docker Inc. 公司憑藉 Docker 社區產品起家,它主要負責提高社區版本的安全性,並將改進後的版本與更普遍的技術社區分享。此外,它還專門對這些技術產品進行完善和安全固化,以服務於企業客戶。

藉助 Docker ,您可將容器當作重量輕、模塊化的虛擬機使用。同時,您還將得到高度的靈活性,從而實現對容器的高效建立、部署及複製,並能將其從一個環境順利遷移至另外一個環境。

1.2.1 Docker 如何工做?

Docker 技術使用 Linux 內核和內核功能(例如 Cgroups 和 namespaces)來分隔進程,以便各進程相互獨立運行。這種獨立性正是採用容器的目的所在;它能夠獨立運行多種進程、多個應用程序,更加充分地發揮基礎設施的做用,同時保持各個獨立系統的安全性。

容器工具(包括 Docker)可提供基於鏡像的部署模式。這使得它可以輕鬆跨多種環境,與其依賴程序共享應用或服務組。Docker 還可在這一容器環境中自動部署應用程序(或者合併多種流程,以構建單個應用程序)。

此外,因爲這些工具基於 Linux 容器構建,使得 Docker 既易於使用,又別具一格 —— 它可爲用戶提供史無前例的高度應用程訪問權限、快速部署以及版本控制和分發能力。

1.2.2 Docker 技術是否與傳統的 Linux 容器相同?

否。Docker 技術最初是基於 LXC 技術構建(大多數人都會將這一技術與「傳統的」 Linux 容器聯繫在一塊兒),但後來它逐漸擺脫了對這種技術的依賴。

就輕量級 虛擬化 這一功能來看,LXC 很是有用,但它沒法提供出色的開發人員或用戶體驗。除了運行容器以外,Docker 技術還具有其餘多項功能,包括簡化用於構建容器、傳輸鏡像以及控制鏡像版本的流程。

傳統的 Linux 容器使用 init 系統來管理多種進程。這意味着,全部應用程序都做爲一個總體運行。與此相反,Docker 技術鼓勵應用程序各自獨立運行其進程,並提供相應工具以實現這一功能。這種精細化運做模式自有其優點。

1.2.3 docker的目標

docker的主要目標是"Build,Ship and Run any App,Angwhere",構建,運輸,到處運行

構建:作一個docker鏡像

運輸:docker pull

運行:啓動一個容器

每個容器,他都有本身的文件系統rootfs.

1.3 安裝Docker

環境說明

# 須要兩臺幾點進行安裝
[root@docker01 ~]# cat /etc/redhat-release 
CentOS Linux release 7.2.1511 (Core) 
[root@docker01 ~]# uname  -r 
3.10.0-327.el7.x86_64
[root@docker01 ~]# hostname -I
10.0.0.100 172.16.1.100 
[root@docker02 ~]# hostname -I
10.0.0.101 172.16.1.101

兩個節點上都進行操做

wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo
sed -i 's#download.docker.com#mirrors.ustc.edu.cn/docker-ce#g' /etc/yum.repos.d/docker-ce.repo
yum install docker-ce -y

修改在docker01配置:

# 修改啓動文件,監聽遠程端口
vim /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://10.0.0.100:2375
systemctl daemon-reload
systemctl enable docker.service 
systemctl restart docker.service
# ps -ef檢查進行,是否啓動

   在docker02測試

[root@docker02 ~]# docker -H 10.0.0.100 info
Containers: 0
 Running: 0
 Paused: 0
 Stopped: 0
Images: 0
Server Version: 17.12.0-ce
Storage Driver: devicemapper
···

1.3.1 Docker基礎命令操做

查看docker相關信息

[root@docker01 ~]#  docker version  
Client:
 Version:    17.12.0-ce
 API version:    1.35
 Go version:    go1.9.2
 Git commit:    c97c6d6
 Built:    Wed Dec 27 20:10:14 2017
 OS/Arch:    linux/amd64
Server:
 Engine:
  Version:    17.12.0-ce
  API version:    1.35 (minimum version 1.12)
  Go version:    go1.9.2
  Git commit:    c97c6d6
  Built:    Wed Dec 27 20:12:46 2017
  OS/Arch:    linux/amd64
  Experimental:    false

配置docker鏡像加速

vi /etc/docker/daemon.json
{
  "registry-mirrors": ["https://registry.docker-cn.com"]
}    

1.3.2 啓動第一個容器

[root@docker01 ~]# docker run -d -p 80:80 nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
e7bb522d92ff: Pull complete 
6edc05228666: Pull complete 
cd866a17e81f: Pull complete 
Digest: sha256:285b49d42c703fdf257d1e2422765c4ba9d3e37768d6ea83d7fe2043dad6e63d
Status: Downloaded newer image for nginx:latest
8d8f81da12b5c10af6ba1a5d07f4abc041cb95b01f3d632c3d638922800b0b4d
# 容器啓動後,在瀏覽器進行訪問測試

參數說明

參數

說明

run

建立並運行一個容器

-d

放入後臺

-p

端口映射

nginx

鏡像名稱

1.3.3 Docker鏡像生命週期

 

1.4 docker鏡像相關操做

1.4.1 搜索官方倉庫鏡像

[root@docker01 ~]#  docker search centos
NAME                      DESCRIPTION                    STARS    OFFICIAL               AUTOMATED
centos                    The official build of CentOS.  3992     [OK]      
ansible/centos7-ansible   Ansible on Centos7             105                              [OK]

列表說明

參數

說明

NAME

鏡像名稱

DESCRIPTION

鏡像說明

STARS

點贊數量

OFFICIAL

是不是官方的

AUTOMATED

是不是自動構建的

1.4.2 獲取鏡像

根據鏡像名稱拉取鏡像

[root@docker01 ~]# docker pull centos
Using default tag: latest
latest: Pulling from library/centos
af4b0a2388c6: Downloading  34.65MB/73.67MB

查看當前主機鏡像列表

[root@docker01 ~]# docker image list 
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              ff426288ea90        3 weeks ago         207MB
nginx               latest              3f8a4339aadd        5 weeks ago         108MB

拉第三方鏡像方法

docker pull index.tenxcloud.com/tenxcloud/httpd

1.4.3 導出鏡像

[root@docker01 ~]# docker image list 
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              ff426288ea90        3 weeks ago         207MB
nginx               latest              3f8a4339aadd        5 weeks ago         108MB
# 導出
[root@docker01 ~]# docker image save centos > docker-centos.tar.gz

1.4.4 刪除鏡像

[root@docker01 ~]# docker image rm centos:latest
[root@docker01 ~]# docker image list 
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               latest              3f8a4339aadd        5 weeks ago         108MB

1.4.5 導入鏡像

[root@docker01 ~]# docker image load -i docker-centos.tar.gz  
e15afa4858b6: Loading layer  215.8MB/215.8MB
Loaded image: centos:latest
[root@docker01 ~]# docker image list 
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              ff426288ea90        3 weeks ago         207MB
nginx               latest              3f8a4339aadd        5 weeks ago         108MB

1.4.6 查看鏡像的詳細信息

[root@docker01 ~]# docker image inspect centos

1.5 容器的平常管理

1.5.1 容器的起/停

最簡單的運行一個容器

[root@docker01 ~]# docker run nginx

建立容器,兩步走(不經常使用)

[root@docker01 ~]# docker create centos:latest  /bin/bash
bb7f32368ecf0492adb59e20032ab2e6cf6a563a0e6751e58930ee5f7aaef204
[root@docker01 ~]# docker start stupefied_nobel
stupefied_nobel

快速啓動容器方法

[root@docker01 ~]# docker run  centos:latest  /usr/bin/sleep 20;

   容器內的第一個進程必須一直處於運行的狀態,不然這個容器,就會處於退出狀態!

查看正在運行的容器

[root@docker01 ~]# docker container ls
    或
[root@docker01 ~]# docker ps 
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
8708e93fd767        nginx               "nginx -g 'daemon of…"   6 seconds ago       Up 4 seconds        80/tcp              keen_lewin

查看你容器詳細信息/ip

[root@docker01 ~]# docker container  inspect  容器名稱/id

查看你全部容器(包括未運行的)

[root@docker01 ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS               NAMES
8708e93fd767        nginx               "nginx -g 'daemon of…"   4 minutes ago       Exited (0) 59 seconds ago                       keen_lewin
f9f3e6af7508        nginx               "nginx -g 'daemon of…"   5 minutes ago       Exited (0) 5 minutes ago                        optimistic_haibt
8d8f81da12b5        nginx               "nginx -g 'daemon of…"   3 hours ago         Exited (0) 3 hours ago                          lucid_bohr

中止容器

[root@docker01 ~]# docker stop 容器名稱/id 
或
[root@docker01 ~]# docker container  kill  容器名稱/id

1.5.2 進入容器方法

啓動時進去方法

[root@docker01 ~]# docker run -it #參數:-it 可交互終端
[root@docker01 ~]# docker run -it nginx:latest  /bin/bash
root@79241093859e:/#

退出/離開容器

1
ctrl+p & ctrl+q

啓動後進入容器的方法

啓動一個docker

[root@docker01 ~]# docker run -it centos:latest 
[root@1bf0f43c4d2f /]# ps -ef 
UID         PID   PPID  C STIME TTY          TIME CMD
root          1      0  0 15:47 pts/0    00:00:00 /bin/bash
root         13      1  0 15:47 pts/0    00:00:00 ps -ef

attach進入容器,使用pts/0 ,會讓所用經過此方法進如放入用戶看到一樣的操做。

[root@docker01 ~]# docker attach 1bf0f43c4d2f
[root@1bf0f43c4d2f /]# ps -ef 
UID         PID   PPID  C STIME TTY          TIME CMD
root          1      0  0 15:47 pts/0    00:00:00 /bin/bash
root         14      1  0 15:49 pts/0    00:00:00 ps -ef

自命名啓動一個容器 --name

[root@docker01 ~]# docker attach 1bf0f43c4d2f
[root@1bf0f43c4d2f /]# ps -ef 
UID         PID   PPID  C STIME TTY          TIME CMD
root          1      0  0 15:47 pts/0    00:00:00 /bin/bash
root         14      1  0 15:49 pts/0    00:00:00 ps -ef

exrc 進入容器方法(推薦使用)

[root@docker01 ~]# docker exec -it clsn1  /bin/bash 
[root@b20fa75b4b40 /]# 從新分配一個終端
[root@b20fa75b4b40 /]# ps -ef 
UID         PID   PPID  C STIME TTY          TIME CMD
root          1      0  0 16:11 pts/0    00:00:00 /bin/bash
root         13      0  0 16:14 pts/1    00:00:00 /bin/bash
root         26     13  0 16:14 pts/1    00:00:00 ps -ef

1.5.3 刪除全部容器

[root@docker01 ~]# docker rm -f  `docker ps -a -q`
# -f 強制刪除

1.5.4 啓動時進行端口映射

-p參數端口映射

[root@docker01 ~]# docker run -d -p 8888:80  nginx:latest 
287bec5c60263166c03e1fc5b0b8262fe76507be3dfae4ce5cd2ee2d1e8a89a9

不一樣指定映射方法

參數

說明

-p hostPort:containerPort    

端口映射  -p 8080:80

-p ip:hostPort:containerPort 

配置監聽地址 -p 10.0.0.100:8080:80

-p ip::containerPort         

隨機分配端口 -p 10.0.0.100::80

-p hostPort:containerPort:udp

指定協議 -p 8080:80:tcp

-p 81:80 –p 443:443          

指定多個

隨機映射

docker run -P (大P)# 須要鏡像支持

1.6 Docker 數據卷的管理

1.6.1 掛載時建立卷

掛載卷

[root@docker01 ~]# docker run -d -p 80:80 -v /data:/usr/share/nginx/html nginx:latest
079786c1e297b5c5031e7a841160c74e91d4ad06516505043c60dbb78a259d09

容器內站點目錄: /usr/share/nginx/html

在宿主機寫入數據,查看

[root@docker01 ~]# echo "http://www.nmtui.com" >/data/index.html
[root@docker01 ~]# curl 10.0.0.100
http://www.nmtui.com

設置共享卷,使用同一個卷啓動一個新的容器

[root@docker01 ~]# docker run -d -p 8080:80 -v /data:/usr/share/nginx/html nginx:latest 
351f0bd78d273604bd0971b186979aa0f3cbf45247274493d2490527babb4e42
[root@docker01 ~]# curl 10.0.0.100:8080
http://www.nmtui.com

查看卷列表

[root@docker01 ~]# docker volume ls
DRIVER              VOLUME NAME

1.6.2 建立卷後掛載

建立一個卷

[root@docker01 ~]# docker volume create 
f3b95f7bd17da220e63d4e70850b8d7fb3e20f8ad02043423a39fdd072b83521
[root@docker01 ~]# docker volume ls 
DRIVER              VOLUME NAME
local               f3b95f7bd17da220e63d4e70850b8d7fb3e20f8ad02043423a39fdd072b83521

指定卷名

[root@docker01 ~]# docker volume ls 
DRIVER              VOLUME NAME
local               clsn
local               f3b95f7bd17da220e63d4e70850b8d7fb3e20f8ad02043423a39fdd072b83521

查看卷路徑

[root@docker01 ~]# docker volume inspect clsn 
[
    {
        "CreatedAt": "2018-02-01T00:39:25+08:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/clsn/_data",
        "Name": "clsn",
        "Options": {},
        "Scope": "local"
    }
]

使用卷建立

[root@docker01 ~]# docker run -d -p 9000:80 -v clsn:/usr/share/nginx/html nginx:latest 
1434559cff996162da7ce71820ed8f5937fb7c02113bbc84e965845c219d3503
# 宿主機測試
[root@docker01 ~]# echo 'blog.nmtui.com' >/var/lib/docker/volumes/clsn/_data/index.html 
[root@docker01 ~]# curl 10.0.0.100:9000
blog.nmtui.com

設置卷

[root@docker01 ~]# docker run  -d  -P  --volumes-from 079786c1e297 nginx:latest 
b54b9c9930b417ab3257c6e4a8280b54fae57043c0b76b9dc60b4788e92369fb

查看使用的端口

[root@docker01 ~]# netstat -lntup 
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1400/sshd           
tcp        0      0 10.0.0.100:2375         0.0.0.0:*               LISTEN      26218/dockerd       
tcp6       0      0 :::9000                 :::*                    LISTEN      32015/docker-proxy  
tcp6       0      0 :::8080                 :::*                    LISTEN      31853/docker-proxy  
tcp6       0      0 :::80                   :::*                    LISTEN      31752/docker-proxy  
tcp6       0      0 :::22                   :::*                    LISTEN      1400/sshd           
tcp6       0      0 :::32769                :::*                    LISTEN      32300/docker-proxy  
[root@docker01 ~]# curl 10.0.0.100:32769
http://www.nmtui.com

1.6.3 手動將容器保存爲鏡像

本次是基於docker官方centos 6.8 鏡像建立

   官方鏡像列表:https://hub.docker.com/explore/

啓動一個centos6.8的鏡像

[root@docker01 ~]# docker pull  centos:6.8
[root@docker01 ~]# docker run -it -p 1022:22 centos:6.8  /bin/bash
# 在容器種安裝sshd服務,並修改系統密碼
[root@582051b2b92b ~]# yum install  openssh-server -y 
[root@582051b2b92b ~]# echo "root:123456" |chpasswd
[root@582051b2b92b ~]#  /etc/init.d/sshd start

   啓動完成後鏡像ssh鏈接測試

將容器提交爲鏡像

[root@docker01 ~]# docker commit brave_mcclintock  centos6-ssh

使用新的鏡像啓動容器

[root@docker01 ~]# docker run -d  -p 1122:22  centos6-ssh:latest  /usr/sbin/sshd -D 
5b8161fda2a9f2c39c196c67e2eb9274977e7723fe51c4f08a0190217ae93094

在容器安裝httpd服務

[root@5b8161fda2a9 /]#  yum install httpd -y

編寫啓動腳本腳本

[root@5b8161fda2a9 /]# cat  init.sh 
#!/bin/bash 
/etc/init.d/httpd start 
/usr/sbin/sshd -D
[root@5b8161fda2a9 /]# chmod +x init.sh 
# 注意執行權限

再次提交爲新的鏡像

[root@docker01 ~]# docker commit  5b8161fda2a9 centos6-httpd 
sha256:705d67a786cac040800b8485cf046fd57b1828b805c515377fc3e9cea3a481c1

啓動鏡像,作好端口映射。並在瀏覽器中測試訪問

[root@docker01 ~]# docker run -d -p 1222:22 -p 80:80  centos6-httpd /init.sh 
46fa6a06644e31701dc019fb3a8c3b6ef008d4c2c10d46662a97664f838d8c2c

1.7 Dockerfile自動構建docker鏡像

官方構建dockerffile文件參考

https://github.com/CentOS/CentOS-Dockerfiles

1.7.1 Dockerfile指令集

dockerfile主要組成部分:

     基礎鏡像信息 FROM centos:6.8

     製做鏡像操做指令RUN yum insatll openssh-server -y

     容器啓動時執行指令 CMD ["/bin/bash"]

dockerfile經常使用指令:

     FROM 這個鏡像的媽媽是誰?(指定基礎鏡像)

     MAINTAINER 告訴別人,誰負責養它?(指定維護者信息,能夠沒有)

     RUN 你想讓它幹啥(在命令前面加上RUN便可)

     ADD 給它點創業資金(COPY文件,會自動解壓)

     WORKDIR 我是cd,今天剛化了妝(設置當前工做目錄)

     VOLUME 給它一個存放行李的地方(設置卷,掛載主機目錄)

     EXPOSE 它要打開的門是啥(指定對外的端口)

     CMD 奔跑吧,兄弟!(指定容器啓動後的要乾的事情)

dockerfile其餘指令: 

    COPY 複製文件

    ENV  環境變量

    ENTRYPOINT  容器啓動後執行的命令

1.7.2 建立一個Dockerfile

建立第一個Dockerfile文件

# 建立目錄
[root@docker01 base]# cd /opt/base
# 建立Dcokerfile文件,注意大小寫
[root@docker01 base]# vim Dockerfile
FROM centos:6.8
RUN yum install openssh-server -y 
RUN echo "root:123456" |chpasswd
RUN /etc/init.d/sshd start 
CMD ["/usr/sbin/sshd","-D"]

構建docker鏡像

[root@docker01 base]# docker image build  -t centos6.8-ssh . 
-t 爲鏡像標籤打標籤  . 表示當前路徑

使用自構建的鏡像啓動

[root@docker01 base]# docker run  -d -p 2022:22 centos6.8-ssh-b 
dc3027d3c15dac881e8e2aeff80724216f3ac725f142daa66484f7cb5d074e7a

1.7.3 使用Dcokerfile安裝kodexplorer

Dockerfile文件內容

FROM centos:6.8
RUN yum install wget unzip php php-gd php-mbstring -y && yum clean all
# 設置工做目錄,以後的操做都在這個目錄中
WORKDIR /var/www/html/
RUN wget -c http://static.kodcloud.com/update/download/kodexplorer4.25.zip
RUN unzip kodexplorer4.25.zip && rm -f kodexplorer4.25.zip
RUN chown -R apache.apache .
CMD ["/usr/sbin/apachectl","-D","FOREGROUND"]

   更多的Dockerfile能夠參考官方方法。

1.8 Docker中的鏡像分層

參考文檔:http://www.maiziedu.com/wiki/cloud/dockerimage/

Docker 支持經過擴展示有鏡像,建立新的鏡像。實際上,Docker Hub 中 99% 的鏡像都是經過在 base 鏡像中安裝和配置須要的軟件構建出來的。

 

   從上圖能夠看到,新鏡像是從 base 鏡像一層一層疊加生成的。每安裝一個軟件,就在現有鏡像的基礎上增長一層。

1.8.1 Docker 鏡像爲何分層

鏡像分層最大的一個好處就是共享資源。

好比說有多個鏡像都從相同的 base 鏡像構建而來,那麼 Docker Host 只需在磁盤上保存一份 base 鏡像;同時內存中也只需加載一份 base 鏡像,就能夠爲全部容器服務了。並且鏡像的每一層均可以被共享。

若是多個容器共享一份基礎鏡像,當某個容器修改了基礎鏡像的內容,好比 /etc 下的文件,這時其餘容器的 /etc 是不會被修改的,修改只會被限制在單個容器內。這就是容器 Copy-on-Write 特性。

1.8.2 可寫的容器層

當容器啓動時,一個新的可寫層被加載到鏡像的頂部。這一層一般被稱做「容器層」,「容器層」之下的都叫「鏡像層」。

 

全部對容器的改動 - 不管添加、刪除、仍是修改文件都只會發生在容器層中。只有容器層是可寫的,容器層下面的全部鏡像層都是隻讀的

1.8.3 容器層的細節說明

鏡像層數量可能會不少,全部鏡像層會聯合在一塊兒組成一個統一的文件系統。若是不一樣層中有一個相同路徑的文件,好比 /a,上層的 /a 會覆蓋下層的 /a,也就是說用戶只能訪問到上層中的文件 /a。在容器層中,用戶看到的是一個疊加以後的文件系統。

文件操做的

文件操做

說明

添加文件

在容器中建立文件時,新文件被添加到容器層中。

讀取文件

在容器中讀取某個文件時,Docker 會從上往下依次在各鏡像層中查找此文件。一旦找到,當即將其複製到容器層,而後打開並讀入內存。

修改文件

在容器中修改已存在的文件時,Docker 會從上往下依次在各鏡像層中查找此文件。一旦找到,當即將其複製到容器層,而後修改之。

刪除文件

在容器中刪除文件時,Docker 也是從上往下依次在鏡像層中查找此文件。找到後,會在容器層中記錄下此刪除操做。(只是記錄刪除操做)

只有當須要修改時才複製一份數據,這種特性被稱做 Copy-on-Write。可見,容器層保存的是鏡像變化的部分,不會對鏡像自己進行任何修改。

這樣就解釋了咱們前面提出的問題:容器層記錄對鏡像的修改,全部鏡像層都是隻讀的,不會被容器修改,因此鏡像能夠被多個容器共享。

1.9 使用docker運行zabbix-server

1.9.1 容器間的互聯

在運行zabbix以前務必要了解容器間互聯的方法

# 建立一個nginx容器
docker run -d -p 80:80 nginx
# 建立容器,作link,並進入容器中
docker run -it --link quirky_brown:web01 centos-ssh /bin/bash
# 在容器中訪問nginx容器能夠ping通
ping web01    

命令執行過程

# 啓動apache容器
[root@docker01 ~]# docker run -d httpd:2.4  
3f1f7fc554720424327286bd2b04aeab1b084a3fb011a785b0deab6a34e56955
^[[A[root@docker01 docker ps -a
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS               NAMES
3f1f7fc55472        httpd:2.4           "httpd-foreground"   6 seconds ago       Up 5 seconds        80/tcp              determined_clarke
# 拉取一個busybox 鏡像
[root@docker01 ~]# docker pull busybox 
# 啓動容器
[root@docker01 ~]# docker run -it  --link determined_clarke:web busybox:latest   /bin/sh 
/ # 
# 使用新的容器訪問最初的web容器
/ # ping web 
PING web (172.17.0.2): 56 data bytes
64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.058 ms
^C
--- web ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.058/0.058/0.058 ms

1.9.2 啓動zabbix容器

一、啓動一個mysql的容器

docker run --name mysql-server -t \
      -e MYSQL_DATABASE="zabbix" \
      -e MYSQL_USER="zabbix" \
      -e MYSQL_PASSWORD="zabbix_pwd" \
      -e MYSQL_ROOT_PASSWORD="root_pwd" \
      -d mysql:5.7 \
      --character-set-server=utf8 --collation-server=utf8_bin

二、啓動java-gateway容器監控java服務

docker run --name zabbix-java-gateway -t \
      -d zabbix/zabbix-java-gateway:latest

三、啓動zabbix-mysql容器使用link鏈接mysql與java-gateway。

docker run --name zabbix-server-mysql -t \
      -e DB_SERVER_HOST="mysql-server" \
      -e MYSQL_DATABASE="zabbix" \
      -e MYSQL_USER="zabbix" \
      -e MYSQL_PASSWORD="zabbix_pwd" \
      -e MYSQL_ROOT_PASSWORD="root_pwd" \
      -e ZBX_JAVAGATEWAY="zabbix-java-gateway" \
      --link mysql-server:mysql \
      --link zabbix-java-gateway:zabbix-java-gateway \
      -p 10051:10051 \
      -d zabbix/zabbix-server-mysql:latest

四、啓動zabbix web顯示,使用link鏈接zabbix-mysql與mysql。

docker run --name zabbix-web-nginx-mysql -t \
      -e DB_SERVER_HOST="mysql-server" \
      -e MYSQL_DATABASE="zabbix" \
      -e MYSQL_USER="zabbix" \
      -e MYSQL_PASSWORD="zabbix_pwd" \
      -e MYSQL_ROOT_PASSWORD="root_pwd" \
      --link mysql-server:mysql \
      --link zabbix-server-mysql:zabbix-server \
      -p 80:80 \
      -d zabbix/zabbix-web-nginx-mysql:latest

1.9.3 關於zabbix API

關於zabbix API能夠參考官方文檔:https://www.zabbix.com/documentation/3.4/zh/manual/api

一、獲取token方法

# 獲取token
[root@docker02 ~]# curl -s -X POST -H 'Content-Type:application/json' -d '
{
"jsonrpc": "2.0",
"method": "user.login",
"params": {
"user": "Admin",
"password": "zabbix"
},
"id": 1
}' http://10.0.0.100/api_jsonrpc.php
{"jsonrpc":"2.0","result":"d3be707f9e866ec5d0d1c242292cbebd","id":1}

1.10 docker 倉庫(registry)

1.10.1 建立一個普通倉庫

一、建立倉庫

docker run -d -p 5000:5000 --restart=always --name registry -v /opt/myregistry:/var/lib/registry  registry 

二、修改配置文件,使之支持http

[root@docker01 ~]# cat  /etc/docker/daemon.json 
{
  "registry-mirrors": ["https://registry.docker-cn.com"],
  "insecure-registries": ["10.0.0.100:5000"]
}

重啓docker讓修改生效

[root@docker01 ~]# systemctl restart  docker.service

三、修改鏡像標籤

[root@docker01 ~]# docker tag  busybox:latest  10.0.0.100:5000/clsn/busybox:1.0
[root@docker01 ~]# docker images
REPOSITORY                      TAG                 IMAGE ID            CREATED             SIZE
centos6-ssh                     latest              3c2b1e57a0f5        18 hours ago        393MB
httpd                           2.4                 2e202f453940        6 days ago          179MB
10.0.0.100:5000/clsn/busybox    1.0                 5b0d59026729        8 days ago          1.15MB

四、將新打標籤的鏡像上傳鏡像到倉庫

[root@docker01 ~]# docker push   10.0.0.100:5000/clsn/busybox

1.10.2 帶basic認證的倉庫

一、安裝加密工具

[root@docker01 clsn]# yum install httpd-tools  -y

二、設置認證密碼

mkdir /opt/registry-var/auth/ -p
htpasswd  -Bbn clsn 123456  > /opt/registry-var/auth/htpasswd

三、啓動容器,在啓動時傳入認證參數

docker run -d -p 5000:5000 -v /opt/registry-var/auth/:/auth/ -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd registry

四、使用驗證用戶測試

# 登錄用戶
[root@docker01 ~]# docker login 10.0.0.100:5000 
Username: clsn  
Password: 123456
Login Succeeded
# 推送鏡像到倉庫
[root@docker01 ~]# docker push 10.0.0.100:5000/clsn/busybox 
The push refers to repository [10.0.0.100:5000/clsn/busybox]
4febd3792a1f: Pushed 
1.0: digest: sha256:4cee1979ba0bf7db9fc5d28fb7b798ca69ae95a47c5fecf46327720df4ff352d size: 527
#認證文件的保存位置
[root@docker01 ~]# cat .docker/config.json 
{
    "auths": {
        "10.0.0.100:5000": {
            "auth": "Y2xzbjoxMjM0NTY="
        },
        "https://index.docker.io/v1/": {
            "auth": "Y2xzbjpIenNAMTk5Ng=="
        }
    },
    "HttpHeaders": {
        "User-Agent": "Docker-Client/17.12.0-ce (linux)"
    }
}

   至此,一個簡單的docker鏡像倉庫搭建完成

1.11 docker-compose編排工具

1.11.1 安裝docker-compose

安裝docker-compose

# 下載pip軟件
yum install -y python2-pip
# 下載 docker-compose
pip install docker-compose

國內開啓pip 下載加速:http://mirrors.aliyun.com/help/pypi

mkdir ~/.pip/
cat > ~/.pip/pip.conf <<'EOF'
[global]
index-url = https://mirrors.aliyun.com/pypi/simple/
[install]
trusted-host=mirrors.aliyun.com
EOF

1.11.2 編排啓動鏡像

一、建立文件目錄

[root@docker01 ~]# mkdir /opt/my_wordpress/
[root@docker01 ~]# cd /opt/my_wordpress/

二、編寫編排文件

[root@docker01 my_wordpress]# vim docker-compose.yml
version: '3'
services:
   db:
     image: mysql:5.7
     volumes:
       - /data/db_data:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: somewordpress
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: wordpress
   wordpress:
     depends_on:
       - db
     image: wordpress:latest
     volumes:
       - /data/web_data:/var/www/html
     ports: 
       - "8000:80"
     restart: always
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD: wordpress

三、啓動

[root@docker01 my_wordpress]# docker-compose up
  #啓動方法:docker-compose up
  #後臺啓動方法:docker-compose up -d

四、瀏覽器上訪問http://10.0.0.100:8000

   進行wordpress的安裝便可

1.11.3 haproxy代理後端docker容器

一、修改編排腳本

[root@docker01 my_wordpress]# cat docker-compose.yml 
version: '3'
services:
   db:
     image: mysql:5.7
     volumes:
       - /data/db_data:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: somewordpress
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: wordpress
   wordpress:
     depends_on:
       - db
     image: wordpress:latest
     volumes:
       - /data/web_data:/var/www/html
     ports: 
       - "80"
     restart: always
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD: wordpress

二、同時啓動兩臺wordpress

[root@docker01 my_wordpress]# docker-compose scale wordpress=2 
WARNING: The scale command is deprecated. Use the up command with the --scale flag instead.
Starting mywordpress_wordpress_1 ... done
Creating mywordpress_wordpress_2 ... done

三、安裝haproxy

[root@docker01 ~]# yum install haproxy -y

四、修改haproxy配置文件

   關於配置文件的詳細說明,參考:http://www.javashuo.com/article/p-kdyqbwmz-t.html

[root@docker01 ~]#cp /etc/haproxy/haproxy.cfg{,.bak}
[root@docker01 ~]# vim /etc/haproxy/haproxy.cfg
global
    log         127.0.0.1 local2
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon
    stats socket /var/lib/haproxy/stats level admin  #支持命令行控制
defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    option forwardfor       except 127.0.0.0/8
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 3000
listen stats
    mode http
    bind 0.0.0.0:8888
    stats enable
    stats uri     /haproxy-status 
    stats auth    admin:123456
frontend frontend_www_example_com
    bind 10.0.0.100:8000
    mode http
    option httplog
    log global
    default_backend backend_www_example_com
backend backend_www_example_com
    option forwardfor header X-REAL-IP
    option httpchk HEAD / HTTP/1.0
    balance roundrobin
    server web-node1  10.0.0.100:32768 check inter 2000 rise 30 fall 15
    server web-node2  10.0.0.100:32769 check inter 2000 rise 30 fall 15

五、啓動haproxy

systemctl start haproxy
systemctl enable haproxy

六、使用瀏覽器訪問hapeoxy監聽的8000端口能夠看到負載的狀況

七、使用瀏覽器訪問 http://10.0.0.100:8888/haproxy-status

   能夠看到後端節點的監控情況,

 

1.11.4 安裝socat 直接操做socket控制haproxy

一、安裝軟件

yum install socat.x86_64 -y

二、查看幫助

[root@docker01 web_data]# echo "help"|socat stdio /var/lib/haproxy/stats

三、下線後端節點

echo "disable server backend_www_example_com/web-node2"|socat stdio /var/lib/haproxy/stats

四、上線後端節點

echo "enable server backend_www_example_com/web-node3"|socat stdio /var/lib/haproxy/stats

五、編寫php測試頁,放到/data/web_data下,在瀏覽器中訪問能夠查看當前的節點

[root@docker01 web_data]# vim check.php
<html>
    <head>
        <title>PHP測試</title>
    </head>
    <body>
        <?php  echo '<p>Hello World </p>'; ?>
        <?php  echo "訪問的服務器地址是:"."<fontcolor=red>".$_SERVER['SERVER_ADDR']."</font>"."<br>";
        echo"訪問的服務器域名是:"."<fontcolor=red>".$_SERVER['SERVER_NAME']."</font>"."<br>";
        ?>
    </body>
</html>

1.12 重啓docker服務,容器所有退出的解決辦法

1.12.1 在啓動是指定自動重啓

docker run  --restart=always

1.12.2 修改docker默認配置文件

# 添加上下面這行
"live-restore": true

docker server配置文件/etc/docker/daemon.json參考

[root@docker02 ~]# cat  /etc/docker/daemon.json 
{
  "registry-mirrors": ["https://registry.docker-cn.com"],
  "graph": "/opt/mydocker", # 修改數據的存放目錄到/opt/mydocker/,原/var/lib/docker/
  "insecure-registries": ["10.0.0.100:5000"],
  "live-restore": true
}

重啓生效,只對在此以後啓動的容器生效

[root@docker01 ~]# systemctl restart  docker.service

1.13 Docker網絡類型

 

1.13.1 docker的網絡類型

類型

說明

None

不爲容器配置任何網絡功能,沒有網絡 --net=none

Container

與另外一個運行中的容器共享Network Namespace,--net=container:containerID

Host

與主機共享Network Namespace,--net=host

Bridge

Docker設計的NAT網絡模型(默認類型)

Bridge默認docker網絡隔離基於網絡命名空間,在物理機上建立docker容器時會爲每個docker容器分配網絡命名空間,而且把容器IP橋接到物理機的虛擬網橋上。

1.13.2 不爲容器配置網絡功能

此模式下建立容器是不會爲容器配置任何網絡參數的,如:容器網卡、IP、通訊路由等,所有須要本身去配置。

[root@docker01 ~]# docker run  -it --network none busybox:latest  /bin/sh 
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 
    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

1.13.3 與其餘容器共享網絡配置(Container)

此模式和host模式很相似,只是此模式建立容器共享的是其餘容器的IP和端口而不是物理機,此模式容器自身是不會配置網絡和端口,建立此模式容器進去後,你會發現裏邊的IP是你所指定的那個容器IP而且端口也是共享的,並且其它仍是互相隔離的,如進程等。

[root@docker01 ~]# docker run  -it --network container:mywordpress_db_1  busybox:latest  /bin/sh 
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 
    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
105: eth0@if106: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:12:00:03 brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.3/16 brd 172.18.255.255 scope global eth0
       valid_lft forever preferred_lft forever

1.13.4 使用宿主機網絡

此模式建立的容器沒有本身獨立的網絡命名空間,是和物理機共享一個Network Namespace,而且共享物理機的全部端口與IP,而且這個模式認爲是不安全的。

[root@docker01 ~]# docker run  -it --network host  busybox:latest  /bin/sh

1.13.5 查看網絡列表

[root@docker01 ~]# docker network list 
NETWORK ID          NAME                  DRIVER              SCOPE
b15e8a720d3b        bridge                bridge              local
345d65b4c2a0        host                  host                local
bc5e2a32bb55        mywordpress_default   bridge              local
ebf76eea91bb        none                  null                local

1.13.6 用PIPEWORK爲docker容器配置獨立IP

參考文檔:http://blog.csdn.net/design321/article/details/48264825

官方網站:https://github.com/jpetazzo/pipework

宿主環境:centos7.2

1、安裝pipework

wget https://github.com/jpetazzo/pipework/archive/master.zip
unzip master.zip 
cp pipework-master/pipework  /usr/local/bin/
chmod +x /usr/local/bin/pipework

2、配置橋接網卡

安裝橋接工具

yum install bridge-utils.x86_64 -y

修改網卡配置,實現橋接

# 修改eth0配置,讓br0實現橋接
[root@docker01 ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0 
TYPE=Ethernet
BOOTPROTO=static
NAME=eth0
DEVICE=eth0
ONBOOT=yes
BRIDGE=br0
[root@docker01 ~]# cat /etc/sysconfig/network-scripts/ifcfg-br0 
TYPE=Bridge
BOOTPROTO=static
NAME=br0
DEVICE=br0
ONBOOT=yes
IPADDR=10.0.0.100
NETMASK=255.255.255.0
GATEWAY=10.0.0.254
DNS1=223.5.5.5
# 重啓網絡
[root@docker01 ~]# /etc/init.d/network restart

3、運行一個容器鏡像測試:

pipework br0 $(docker run -d -it -p 6880:80 --name  httpd_pw httpd) 10.0.0.220/24@10.0.0.254

在其餘主機上測試端口及連通性

[root@docker01 ~]# curl 10.0.0.220
<html><body><h1>It works!</h1></body></html>
[root@docker01 ~]# ping 10.0.0.220 -c 1
PING 10.0.0.220 (10.0.0.220) 56(84) bytes of data.
64 bytes from 10.0.0.220: icmp_seq=1 ttl=64 time=0.043 ms

4、再運行一個容器,設置網路類型爲none

pipework br0 $(docker run -d -it --net=none --name test httpd:2.4) 10.0.0.221/24@10.0.0.254

   進行訪問測試

[root@docker01 ~]# curl 10.0.0.221
<html><body><h1>It works!</h1></body></html>

5、重啓容器後須要再次指定:

pipework br0 testduliip  172.16.146.113/24@172.16.146.1
pipework br0 testduliip01  172.16.146.112/24@172.16.146.1

Dcoker跨主機通訊之overlay能夠參考:

http://www.cnblogs.com/CloudMan6/p/7270551.html

1.13.7 Docker跨主機通訊之macvlan

建立網絡

[root@docker01 ~]# docker network  create --driver macvlan  --subnet 10.1.0.0/24 --gateway 10.1.0.254 -o parent=eth0  macvlan_1
33a1f41dcc074f91b5bd45e7dfedabfb2b8ec82db16542f05213839a119b62ca

設置網卡爲混雜模式

ip link set eth0 promisc on

建立使用macvlan網絡容器

[root@docker02 ~]# docker run  -it --network macvlan_1  --ip=10.1.0.222 busybox /bin/sh

1.14 docker企業級鏡像倉庫harbor

容器管理

[root@docker01 harbor]# pwd
/opt/harbor
[root@docker01 harbor]# docker-compose stop

一、安裝docker、docker-compose

下載 harbor

cd /opt && https://storage.googleapis.com/harbor-releases/harbor-offline-installer-v1.3.0.tgz
tar xf harbor-offline-installer-v1.3.0.tgz

二、修改主機及web界面密碼

[root@docker01 harbor]# vim harbor.cfg 
    ···
    hostname = 10.0.0.100
    harbor_admin_password = Harbor12345
    ···

三、執行安裝腳本

[root@docker01 harbor]# ./install.sh

瀏覽器訪問 http://10.0.0.11

 

添加一個項目

 

四、鏡像推送到倉庫的指定項目

[root@docker02 ~]# docker  tag centos:6.8  10.0.0.100/clsn/centos6.8:1.0
[root@docker02 ~]#  
[root@docker02 ~]# docker images 
REPOSITORY                  TAG                 IMAGE ID            CREATED             SIZE
busybox                     latest              5b0d59026729        8 days ago          1.15MB
10.0.0.100/clsn/centos6.8   1.0                 6704d778b3ba        2 months ago        195MB
centos                      6.8                 6704d778b3ba        2 months ago        195MB
[root@docker02 ~]# docker login 10.0.0.100
Username: admin
Password: 
Login Succeeded

五、推送鏡像

[root@docker02 ~]# docker push 10.0.0.100/clsn/centos6.8 
The push refers to repository [10.0.0.100/clsn/centos6.8]
e00c9229b481: Pushing  13.53MB/194.5MB

六、在web界面裏查看

 

1.14.1 使用容器的建議

1. 不要以拆分方式進行應用程序發佈

2. 不要建立大型鏡像

3. 不要在單個容器中運行多個進程

4. 不要再鏡像內保存憑證,不要依賴IP地址

5. 以非root用戶運行進程

6. 不要使用「最新」標籤

7. 不要利用運行中的容器建立鏡像

8. 不要使用單層鏡像

9. 不要將數據存放在容器內

1.14.2 關於Docker容器的監控

容器的基本信息

包括容器的數量、ID、名稱、鏡像、啓動命令、端口等信息

容器的運行狀態

統計各狀態的容器的數量,包括運行中、暫停、中止及異常退出

容器的用量信息

統計容器的CPU使用率、內存使用量、塊設備I/O使用量、網絡使用狀況等資源的使用狀況

1.15 參考文獻

 [1] https://www.redhat.com/zh/topics/containers/whats-a-linux-container

 [2] https://www.redhat.com/zh/topics/containers/what-is-docker

[3] http://blog.51cto.com/dihaifeng/1713512

 [4] http://www.javashuo.com/article/p-vykldpic-bh.html

 [5] http://www.javashuo.com/article/p-hywrsgpp-bd.html

相關文章
相關標籤/搜索