1. 程式人生 > 其它 >Docker的介紹及簡單使用

Docker的介紹及簡單使用

一、docker版本管理

1.版本管理

  • Docker 引擎主要有兩個版本:企業版(EE)和社群版(CE)

  • 每個季度(1-3,4-6,7-9,10-12),企業版和社群版都會發佈一個穩定版本(Stable)。社群版本會提供 4 個月的支援,而企業版本會提供 12 個月的支援

  • 每個月社群版還會通過 Edge 方式釋出月度版

  • 從 2017 年第一季度開始,Docker 版本號遵循 YY.MM-xx 格式,類似於 Ubuntu 等專案。例如,2018 年 6 月第一次釋出的社群版本為 18.06.0-ce

二、安裝

1.配置宿主機網絡卡轉發

## 若未配置,需要執行如下
$ cat <<EOF >  /etc/sysctl.d/docker.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward=1
EOF
$ sysctl -p /etc/sysctl.d/docker.conf

2.Yum安裝配置docker

## 下載阿里源repo檔案
$ curl -o /etc/yum.repos.d/Centos-7.repo http://mirrors.aliyun.com/repo/Centos-7.repo
$ curl -o /etc/yum.repos.d/docker-ce.repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

$ yum clean all && yum makecache

## yum安裝
$ yum install docker-ce-20.10.6 -y

## 檢視源中可用版本
$ yum list docker-ce --showduplicates | sort -r

## 安裝舊版本
##yum install -y docker-ce-18.09.9

## 配置源加速
## https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
mkdir -p /etc/docker
vi /etc/docker/daemon.json
{
  "registry-mirrors" : [
    "https://8xpk5wnt.mirror.aliyuncs.com"
  ]
}

## 設定開機自啟
systemctl enable docker  
systemctl daemon-reload

## 啟動docker
systemctl start docker 

## 檢視docker資訊
docker info

## docker-client
which docker

## docker daemon
ps aux |grep docker

## containerd
ps aux|grep containerd
systemctl status containerd

三、docker的使用

3.1 檢視映象列表

$ docker images

3.2 如何獲取映象

(1) 從遠端倉庫拉取
$ docker pull nginx:alpine
$ docker images

(2) 使用tag命令
$ docker tag nginx:alpine 172.21.51.143:5000/nginx:alpine
$ docker images


(3) 本地構建
$ docker build . -t my-nginx:ubuntu -f Dockerfile

3.3 如何通過映象啟動容器

$ docker run --name my-nginx-alpine -d nginx:alpine

3.4 如何知道容器內部運行了什麼程式?

# 進入容器內部,分配一個tty終端
$ docker exec -ti my-nginx-alpine /bin/sh
# ps aux

3.5 docker構建映象

(1) 建立Dockerfile

# 告訴docker使用哪個基礎映象作為模板,後續命令都以這個映象為基礎 
FROM ubuntu

# RUN命令會在上面指定的映象裡執行命令 
RUN apt-get update && apt install -y nginx

#告訴docker,啟動容器時執行如下命令
CMD ["/usr/sbin/nginx", "-g","daemon off;"]

(2) 構建本地映象

$ docker build . -t my-nginx:ubuntu -f Dockerfile

3.6 如何訪問容器內服務

# 進入容器內部
$ docker exec -ti my-nginx-alpine /bin/sh
# ps aux|grep nginx
# curl localhost:80

3.7 宿主機中如何訪問容器服務

# 刪掉舊服務,重新啟動
$ docker rm -f my-nginx-alpine
$ docker run --name my-nginx-alpine -d -p 8080:80 nginx:alpine
$ curl 172.21.51.143:8080

3.8 docker client如何與daemon通訊

# /var/run/docker.sock
$ docker run --name portainer -d -p 9001:9000 -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer

3.9 匯出映象到檔案中

$ docker save -o nginx-alpine.tar nginx:alpine

3.10 從檔案中載入映象

$ docker load -i nginx-alpine.tar

3.11 刪除映象

docker rmi nginx:alpine

3.12 檢視容器列表

## 檢視執行狀態的容器列表
$ docker ps

## 檢視全部狀態的容器列表
$ docker ps -a

3.13 啟動容器

## 後臺啟動
$ docker run --name nginx -d nginx:alpine

## 對映埠,把容器的埠對映到宿主機中,-p <host_port>:<container_port>
$ docker run --name nginx -d -p 8080:80 nginx:alpine

## 資源限制,最大可用記憶體500M
$ docker run --memory=500m nginx:alpine

3.14 容器資料持久化

## 掛載主機目錄
$ docker run --name nginx -d  -v /opt:/opt  nginx:alpine
$ docker run --name mysql -e MYSQL_ROOT_PASSWORD=123456  -d -v /opt/mysql/:/var/lib/mysql mysql:5.7

3.15 進入容器或者執行容器內的命令

$ docker exec -ti <container_id_or_name> /bin/sh
$ docker exec <container_id_or_name> hostname

3.16 主機與容器之間拷貝資料

## 主機拷貝到容器
$ echo '123'>/tmp/test.txt
$ docker cp /tmp/test.txt nginx:/tmp
$ docker exec -ti nginx cat /tmp/test.txt
123

## 容器拷貝到主機
$ docker cp nginx:/tmp/test.txt ./

3.17 檢視容器日誌

## 檢視全部日誌
$ docker logs nginx

## 實時檢視最新日誌
$ docker logs -f nginx

## 從最新的100條開始檢視
$ docker logs --tail=100 -f nginx

3.18 停止或者刪除容器

## 停止執行中的容器
$ docker stop nginx

## 啟動退出容器
$ docker start nginx

## 刪除非執行中狀態的容器
$ docker rm nginx

## 刪除執行中的容器
$ docker rm -f nginx

3.19 檢視容器或者映象的明細

## 檢視容器詳細資訊,包括容器IP地址等
$ docker inspect nginx

## 檢視映象的明細資訊
$ docker inspect nginx:alpine

四、部署docker registery

4.1 部署映象倉庫

https://docs.docker.com/registry/

## 使用docker映象啟動映象倉庫服務
$ docker run -d -p 5000:5000 --restart always --name registry registry:2

## 預設倉庫不帶認證,若需要認證,參考https://docs.docker.com/registry/deploying/#restricting-access

4.2 推送本地映象到映象倉庫中

$ docker tag nginx:alpine localhost:5000/nginx:alpine
$ docker push localhost:5000/nginx:alpine

## 檢視倉庫內元資料
$ curl -X GET http://172.21.51.143:5000/v2/_catalog
$ curl -X GET http://172.21.51.143:5000/v2/nginx/tags/list

## 映象倉庫給外部訪問,不能通過localhost,嘗試使用內網地址172.21.51.143:5000/nginx:alpine
$ docker tag nginx:alpine 172.21.51.143:5000/nginx:alpine
$ docker push 172.21.51.143:5000/nginx:alpine
The push refers to repository [172.21.51.143:5000/nginx]
Get https://172.21.51.143:5000/v2/: http: server gave HTTP response to HTTPS client
## docker預設不允許向http的倉庫地址推送,如何做成https的,參考:https://docs.docker.com/registry/deploying/#run-an-externally-accessible-registry
## 我們沒有可信證書機構頒發的證書和域名,自簽名證書需要在每個節點中拷貝證書檔案,比較麻煩,因此我們通過配置daemon的方式,來跳過證書的驗證:
$ cat /etc/docker/daemon.json
{
    "registry-mirrors": [
    "https://8xpk5wnt.mirror.aliyuncs.com"
    ],
    "insecure-registries": [
        "172.21.51.143:5000"
    ]
}
$ systemctl restart docker
$ docker push 172.21.51.143:5000/nginx:alpine
$ docker images	# IMAGE ID相同,等於起別名或者加快捷方式
REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
172.21.51.143:5000/nginx   alpine              377c0837328f        4 weeks ago         
nginx                    alpine              377c0837328f        4 weeks ago         
localhost:5000/nginx     alpine              377c0837328f        4 weeks ago         
registry                 2                   708bc6af7e5e        2 months ago       
  1. 掛載已有的資料,重新建立映象倉庫容器
## 解壓離線映象檔案
$ tar zxf registry.tar.gz -C /opt

## 刪除當前映象倉庫容器
$ docker rm -f registry
## 使用docker映象啟動映象倉庫服務
$ docker run -d -p 5000:5000 --restart always -v /opt/registry:/var/lib/registry --name registry registry:2

五、Dockerfile使用

$ docker build . -t ImageName:ImageTag -f Dockerfile

Dockerfile是一堆指令,在docker build的時候,按照該指令進行操作,最終生成我們期望的映象

  • FROM 指定基礎映象,必須為第一個命令

    格式:
    	FROM <image>
    	FROM <image>:<tag>
    示例:
    	FROM mysql:5.7
    注意:
    	tag是可選的,如果不使用tag時,會使用latest版本的基礎映象
    
  • MAINTAINER 映象維護者的資訊

    格式:
    	MAINTAINER <name>
    示例:
    	MAINTAINER Yongxin Li
        MAINTAINER [email protected]
        MAINTAINER Yongxin Li <[email protected]>
    
  • COPY|ADD 新增本地檔案到映象中

    格式:
    	COPY <src>... <dest>
    示例:
        ADD hom* /mydir/          # 新增所有以"hom"開頭的檔案
        ADD test relativeDir/     # 新增 "test" 到 `WORKDIR`/relativeDir/
        ADD test /absoluteDir/    # 新增 "test" 到 /absoluteDir/
    
  • WORKDIR 工作目錄

    格式:
    	WORKDIR /path/to/workdir
    示例:
        WORKDIR /a  (這時工作目錄為/a)
    注意:
    	通過WORKDIR設定工作目錄後,Dockerfile中其後的命令RUN、CMD、ENTRYPOINT、ADD、COPY等命令都會在該目錄下執行
    
  • RUN 構建映象過程中執行命令

    格式:
    	RUN <command>
    示例:
        RUN yum install nginx
        RUN pip install django
        RUN mkdir test && rm -rf /var/lib/unusedfiles
    注意:
    	RUN指令建立的中間映象會被快取,並會在下次構建中使用。如果不想使用這些快取映象,可以在構建時指定--no-cache引數,如:docker build --no-cache
    
  • CMD 構建容器後呼叫,也就是在容器啟動時才進行呼叫

    格式:
        CMD ["executable","param1","param2"] (執行可執行檔案,優先)
        CMD ["param1","param2"] (設定了ENTRYPOINT,則直接呼叫ENTRYPOINT新增引數)
        CMD command param1 param2 (執行shell內部命令)
    示例:
        CMD ["/usr/bin/wc","--help"]
        CMD ping www.baidu.com
    注意:
    	CMD不同於RUN,CMD用於指定在容器啟動時所要執行的命令,而RUN用於指定映象構建時所要執行的命令。
    
  • ENTRYPOINT 設定容器初始化命令,使其可執行化

    格式:
        ENTRYPOINT ["executable", "param1", "param2"] (可執行檔案, 優先)
        ENTRYPOINT command param1 param2 (shell內部命令)
    示例:
        ENTRYPOINT ["/usr/bin/wc","--help"]
    注意:
    	ENTRYPOINT與CMD非常類似,不同的是通過docker run執行的命令不會覆蓋ENTRYPOINT,而docker run命令中指定的任何引數,都會被當做引數再次傳遞給ENTRYPOINT。Dockerfile中只允許有一個ENTRYPOINT命令,多指定時會覆蓋前面的設定,而只執行最後的ENTRYPOINT指令
    
  • ENV

    格式:
        ENV <key> <value>
        ENV <key>=<value>
    示例:
        ENV myName John
        ENV myCat=fluffy
    
  • EXPOSE

    格式:
        EXPOSE <port> [<port>...]
    示例:
        EXPOSE 80 443
        EXPOSE 8080
        EXPOSE 11211/tcp 11211/udp
    注意:
        EXPOSE並不會讓容器的埠訪問到主機。要使其可訪問,需要在docker run執行容器時通過-p來發布這些埠,或通過-P引數來發布EXPOSE匯出的所有埠
    
    

六、Docker網路

docker容器是一塊具有隔離性的虛擬系統,容器內可以有自己獨立的網路空間,

  • 多個容器之間是如何實現通訊的呢?
  • 容器和宿主機之間又是如何實現的通訊呢?
  • 使用-p引數是怎麼實現的埠對映?

** 網路模式 **

我們在使用docker run建立Docker容器時,可以用--net選項指定容器的網路模式,Docker有以下4種網路模式:

  • bridge模式,使用--net=bridge指定,預設設定

  • host模式,使用--net=host指定,容器內部網路空間共享宿主機的空間,效果類似直接在宿主機上啟動一個程序,埠資訊和宿主機共用

  • container模式,使用--net=container:NAME_or_ID指定

    指定容器與特定容器共享網路名稱空間

  • none模式,使用--net=none指定

    網路模式為空,即僅保留網路名稱空間,但是不做任何網路相關的配置(網絡卡、IP、路由等)