Docker 學習筆記

安裝

docker的安裝最好須要centos內核版本在3.1及以上html

查看系統內核版本前端

uname -r

uname-r

安裝依賴java

yum install -y yum-utils device-mapper-persistent-data lvm2

添加yum源node

yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

更新yum源mysql

yum makecache fast

安裝dockerlinux

yum install docker-ce -y

配置鏡像加速

使用阿里雲的鏡像加速服務 https://cr.console.aliyun.com/cn-hangzhou/instances/mirrorsgit

在/etc/docker 目錄下建立damon.json添加下面 的信息,沒有的話新建這個文件github

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://7djn00qt.mirror.aliyuncs.com"]
}
EOF

從新加載配置,重啓dockersql

sudo systemctl daemon-reload
sudo systemctl restart docker

經常使用的操做

查找鏡像docker

docker search 關鍵字

docker search mysql

dockersearchmysql

拉取鏡像

docker pull 鏡像名

如:

dockerpullmysql

查看系統中的鏡像

docker images # 將來可能被刪除
docker image list
docker image ls

dockerimagelist

刪除鏡像

docker rm -f 鏡像id或者鏡像名:TAG

查看鏡像的元數據

docker inspect 鏡像ID或者鏡像名:TAG

運行鏡像-->容器

docker run --name 容器名 -i -t -p 主機端口:容器端口 -d -v 主機目錄:容器目錄:ro 鏡像ID或鏡像名:TAG
--name 指定容器的名字
-i 以交互的模式運行容器
-t 分配一個僞終端(能夠理解成bash命令行)
-p 端口映射,將主機的端口映射向容器內部的端口
-d 後臺運行
-v 將主機目錄(全路徑)掛載到容器的目錄中,好比可讓容器中的軟件讀取宿主機上的配置文件(默認rw讀寫,ro只讀)
-v 注意它進行的目錄級別的掛載,在使用-v啓動容器以前,確保將容器目錄中的配置文件拷貝到主機目錄下
-v 根據需求修改主機目錄配置文件,再啓動時,容器會去主機目錄下讀取配置文件
-i -t 一般都被簡寫成-it, 容器中必須運行一個進程容器纔不會自動退出,一般使用這個-it讓容器運行bash,不讓他退出
-v和-p都是能夠重複使用的

命令中的tag和鏡像id在上面的命令中都能找到

啓動時能夠經過指定容器的名字, 容器的名字是上圖中的REPOSITORY, 若是不是lasted版本的須要添加上tag

查看容器列表

docker ps # 正在運行的
docker container list # 正在運行的
docker ps -a # 能看到中止狀態Containner

dokcercontainerlist

容器中必須存在一個或者的進程容器纔不會退出,上面的COMMAND表示的容器中指定的命令,通常都是經過這個命令去啓動一個進程

中止容器

docker stop 容器ID或者容器名

重啓容器

docker restart 容器ID或者容器名

刪除容器

docker rm -f 容器id或者容器名
-f 表示強制刪除

查看日誌

docker logs 容器ID和容器名

進入正在運行的容器

docker container exec -it 指定的容器名或者容器的ID /bin/bash
# 順序別亂
# 進入正在運行的容器並開啓交互模式終端
# 這個正在運行中的容器能夠理解成它是一個簡化的linux
# /bin/bash 是固定的寫法,標準的linux的shell,表示docker做爲一個deaman在後臺運行

退出容器

exit

拷貝文件

docker cp 主機文件路徑 容器ID或者容器名:容器路徑 將主機中的文件拷貝到容器中
docker cp 容器ID或者容器名 主機文件路徑 # 將容器中的文件拷貝到主機中

這兩條命令很經常使用,由於docker容器裏面沒有vim vi命令,不能直接修改它裏面的配置文件
若是真的作配置文件的映射,別忘了將原來的Containner殺掉,而後重新啓動image產生新的Containner
從新運行時須要在命令行上添加參數表示告訴docker來宿主機讀取配置文件 參數: -v

獲取容器的元信息

docker container inspect 容器ID或容器名

Dockerfile簡介

點擊進入dockerfile的官方地址

dockerfile其實一個文件,可是這個文件中存在着一些命令,docker會讀取這個文件中的命令而後構建出命令對應的image

容器是分層的,就像下面的圖同樣

分層

When you run an image and generate a container, you add a new writable layer (the 「container layer」) on top of the underlying layers. All changes made to the running container, such as writing new files, modifying existing files, and deleting files, are written to this thin writable container layer

咱們一運行鏡像,這個鏡像就會變成一個容器, 看看上圖,能夠發現咱們手裏的容器其實自己就是分層的,(然而容器是第三方提供的咱們根本不用關心有多少層),可是咱們能在現有分層的基礎上繼續添加可寫的層, 好比咱們能夠建立新文件啊,修改現存的文件啊,或者刪除現存的一些文件,而且這些修改對docker會生效

其實上面說的分層的概念仍是有點模糊,就是說若是咱們想構建本身的鏡像的話,不用從0開始了,咱們能夠複用現有的僅可讀的鏡像,在此基礎上構建咱們的鏡像,好比舉個例子,咱們jar包的執行須要藉助java環境,那若是咱們想構建一個鏡像跑一個jar包,就得依賴現存的java 的鏡像當成基礎鏡像

docker file中的每一行都會成爲一層,因此官方推薦: dockerfile中的指令越少越好,越短越好

使用Dockerfile構建SpringBoot鏡像

  1. 將jar包上傳到linux上,並切換到jar包所在的目錄
  2. 在jar所在的目錄中建立以下的vim Dockerfile,添加以下內容
# 指定基礎鏡像,咱們的jar包依賴java8的鏡像
FROM java:8
# maintainer做者
LABEL maintainer=changwu
# 將可執行jar包複製到可執行目錄的根目錄下
ADD lawyer-lover-consumer-1.0-SNAPSHOT.jar /lawyer-lover-consumer-1.0-SNAPSHOT.jar
# 鏡像要暴露的端口,若是要使用端口,docker run -p [端口]
EXPOSE 80
# entrypoint 在鏡像運行爲容器後執行的命令
ENTRYPOINT ["java","-jar","/lawyer-lover-consumer-1.0-SNAPSHOT.jar"]

構建

docker build -t myproject:v1 .
-t 跟鏡像名和TAG
-f 跟Dockerfile的路徑
. 指當前目錄

運行

docker run --name myproject -p 9998:80 -d 鏡像名:TAG
docker run --name myproject -P -d 鏡像名:TAG

Dockerfile參數

命令 簡介
FROM 設置鏡像使用的基礎鏡像
MAINTAINER 設置鏡像的
LABEL MAINTAINER的替代者,設置鏡像的標籤
EXPOSE 暴露容器的端口
ADD 構建鏡像時,拷貝文件到容器中
COPY 構建鏡像時從宿主機拷貝文件到容器中
ENTRIPOINT 設置容器啓動後執行的命令
CMD 設置容器啓動後執行的命令
VOLUME 設置掛載卷
ENV 設置容器的環境變量
ARG 設置系統的環境變量
USER 設置運行RUN CMD ENTRYPOINT的用戶名
WORKDIR 設置RUN CMD ENTRYPOINT COPY ADD指令的工做目錄
ONBUILD 設置鏡像的ONBUILD指令
STOPSIGNAL 設置容器的退出信號量

FROM

Dockerfile中的第一個非註釋行,用來指定基礎鏡像,默認狀況下會先嚐試從本地獲取基礎鏡像,本地沒有的話就會去DockerHub中拉取,經常使用的書寫格式 以下:

這是官方推薦的基礎鏡像地址 : https://hub.docker.com/_/alpine/

FROM image
FROM image:tag
FORM image:@:digest

MAINTAINER

用來指定做者的信息,可是在將來的版本將會被棄用

LABEL

如今官方推薦的使用LABEL去描述鏡像的各類元數據,好比向下面這樣,支持同時設置多個label

# Set one or more individual labels
LABEL com.example.version="0.0.1-beta"
LABEL vendor1="ACME Incorporated"
LABEL vendor2=ZENITH\ Incorporated
LABEL com.example.release-date="2015-02-12"
LABEL com.example.version.is-production=""

注意上面的細節: 帶空格的字符串必須加引號或空格必須轉義。內部引用字符(")也必須轉義

而且官方不建議上面的書寫格式(由於每一條指令都會生成一個鏡像),而是建議咱們向下面這樣合併起來label

# Set multiple labels on one line
LABEL com.example.version="0.0.1-beta" com.example.release-date="2015-02-12"

或者這樣也行

# Set multiple labels at once, using line-continuation characters to break long lines
LABEL vendor=ACME\ Incorporated \
      com.example.is-beta= \
      com.example.is-production="" \
      com.example.version="0.0.1-beta" \
      com.example.release-date="2015-02-12"

ADD or COPY

ADD 和 COPY看起來很像,可是通常來講都會優先選擇COPY,由於它比ADD更透明, COPY僅僅支持將本地的文件複製到容器中,使用ADD支持TAR文件和URL路徑(網上文件的下載路徑), 命令不能很好的卻分 是從本地進行復制仍是經過url從遠程拉取文件

使用ADD時注意,若是是tar包的話,宿主機上的tar包拷貝到image中會被解壓, 可是過URL下載連接的製做鏡像時,tar包不會被自動解壓, 並且容器中的目錄最後須要加上/ 否則啓動不起來

ENTRIPOINT or CMD

entrypoint和cmd 都是在指定容器啓動後的命令

entrypoint兩種格式

ENTRYPOINT ["executable","param1","param2"]
ENTRYPOINT command param1 param2  (shell中執行)

ENTRYPOINT能夠指定容器啓動後執行的命令,當指定多個時,一樣也只有最後一個命令會生效,而且它不能被docker run中指定的參數所覆蓋

(不過能夠這樣進行覆蓋docker run命令的--entrypoint參數能夠覆蓋ENTRYPOINT)

cmd的三種格式

CMD ["executable","param1","param2"]  # 使用exec執行
CMD command param1 param2  # 在 /bin/sh 中執行
CMD ["param1","param2"] # 給ENTRYPOINT提供默認的參數

cmd能夠指定容器啓動時執行的命令,每一個Dockerfile中 只能有一個CMD命令,若是寫了多個CMD,只有最後一個會生效, 而且,用戶在經過docker run 啓動容器時添加的參數 會覆蓋原CMD的命令

小結:

  • 他們能夠指定容器啓動後執行的命令,而且當同時存在多個CMD或者多個ENTRYPOINT時,只有最一個會生效
  • 當Dockerfile中同時存在CMD和ENTRYPOINT時.而且CMD又不是爲了給ENTRYPOINT提供默認的參數,那麼誰在最後誰生效

VOLUME

卷, 這個參數和咱們啓動容器時使用的docker run -v 宿主機目錄:容器目錄相似這種掛載券操做, 下面命令中的掛載點實際上是容器中的目錄,宿主機中的目錄會被隨機生成

VOLUME mountpoint # 如 VOLUME /data1

舉個應用的場景,當咱們想將容器中mysql數據庫中的數據同步到宿主機的目錄下面時,咱們可使用VOLUME,這樣配置後會隨機在宿主機上建立一個目錄存放數據

#### EXPOSE

指定容器和外部進行通訊的端口以及協議, EXPOSE 能夠指個端口. 默認的協議是tcp協議

語法:

EXPOSE <port>
EXPOSE 80/tcp 9999/udp

當咱們運行鏡像時,使用-p手動指定宿主機和容器的端口映射規則, 使用-P 的話,會自動完成-p的工做, 首先會自動的分配一個宿主機的端口, 而後將宿主機的端口映射到EXPOSE的端口上

ENV

env

相似於環境變量,在Dockerfile中經過ENV定義的環境變量,以後能夠經過$variable_name 或者{variable_name}取出值使用

兩種格式:

ENV <key> <value> # 一次只能指定一對k-v
ENV <kay>=<value> # 一行指定多個k-v, 若是中間有空格經過\轉義,或者使用""標識, 並且\還能夠表示換行

ARG

做用和ENV相仿,均可以類型指定環境變量,並且能夠在docker build建立鏡像的時候,使用 --build-arg=指定參數 來指定參數

Docker 網絡模型

docker容許經過外部訪問容器或者容器互聯的方式提供網絡服務, 安裝docker deamon時,會自動安裝一個docker網卡,叫作Docker0 (通多 ip addr 能夠查看,以下圖)

ipaddr

一個小例子

在開始Docker網絡的筆記前,我想說這個真實的小例子,若是你精通網絡方面的知識但願你在評論區指出我說的不對的地方

**在說docker以前,我想說一個現實的例子: 咱們學校想舉辦一場ACM區域賽,學校給了兩個機房,每一個機房都有一百多臺電腦,老師的意思是將咱們的CLP平臺運行在內網中,在內網中舉行此次比賽,因而個人同窗開始籌劃組建一個局域網,要組建一個內網,咱們手裏面有什麼設備呢? 斐訊的路由器,還有機房的交換機. **

其實說是搭建一個局域網感受是有點花哨了,咱們的最終目的是啥呢? 其實就是讓全部的同窗都鏈接一個路由器實現電腦機房的互聯(就是能夠經過ip相互訪問到),可是路由器上有兩種接口,lanip和wanip,若是本地的機器之間想互聯的話,就使用lan口, wan口是用來鏈接外網使用的, 路由器上面lan口就4個,兩個機房中兩百個機器怎麼互聯呢? 還好咱們有交換機

**常見的內網網段: 10.X.X.X 100.X.X.X 192.168.X.X 172.16.X.X - 172.31.X.X **

下面是路由器控制檯配置lan口的圖片

lan口


而後你們都去鏈接路由器的無限信號,看上圖將DHCP關掉了,鏈接上路由器的網絡後不能不會被分配一個隨機的ip使用,因而咱們就得本身去手動配置本身電腦的ipv4地址,像下面這樣

配置ip

上面咱們配置了當前的局域網中當前機器的ip地址,兩個機房中的ip地址不會存在重複的狀況,而且他們都能都過ip通過交換機訪問到彼此

最後咱們找一臺虛擬機當成服務器,在上面啓動Tomcat,跑咱們的CLP,同窗們經過ip+_端口來訪問這個虛擬機上面的WebServer.就能歡快的比賽了

爲何說這個例子呢? 其實這應該就是你們說的橋接模型,整個局域網中,全部的機器想互聯就得在一個網段裏面,就像上面的子網掩碼限制了咱們的網段是192.168.1.XXX (XXX的範圍是1-254),同時處於這個網段的電腦之間是能夠互聯的,擁有本身的ip,而且路由器若是能鏈接外網,那麼局域網中的電腦就能中繼鏈接外網

說了這麼多和Docker有什麼關係呢? docker默認的網絡模型就是橋接模型, 上圖中的Docker0網卡是Docker deamon的虛擬網卡, 咱們可不能夠將docker demon想象成他是咱們虛擬機裏面的一個虛擬內網呢? 這個比喻就比如是下面這樣

華爲雲ECS == 筆記本電腦
docker deamon == VMware Workstation Pro
Containner1 == VMware中的虛擬機1
Containner2 == VMware中的虛擬機2
Containner3 == VMware中的虛擬機3

就比如咱們當初想讓VMware中的虛擬機鏈接外網同樣

**docker container 其實就是一個極簡的linux鏡像,麻雀雖小五臟俱全啊...什麼dns解析,路由表,host文件它都有, 每個docker容器模式使用橋接的網絡模型就意味着沒個容器都有本身的ip地址, 宿主機和容器之間怎麼通訊呢? 這個問題就比如你的筆記本怎麼和VMare中的虛擬機如何通訊同樣, 能夠理解成docker將物理機上的網卡虛擬化成一個交換機,進而實現彼此互聯 **

有啥不懂的歡迎關注計算機網絡大佬前端大佬: https://home.cnblogs.com/u/camwang

docker網絡中的核心概念

  • 沙盒: Docker的沙盒能夠讓docker擁有徹底獨立的容器網絡環境, 沙盒提供了端口socket,ip路由表,防火牆等內容
  • 網絡: 爲了保證容器之間的安全通訊, Docker的虛擬網絡和宿主機的網絡之間是隔離的,這裏說的網絡能夠理解成docker內部的虛擬子網,Docker中的容器之間能夠在這個虛擬子網中相互可見相互通訊
  • 端點: 容器經過這個端點實現和外網的通訊,這個端點就是可控的突破封閉的網絡環境的出入口

docker中存在四種網絡模式 Bridge,Host,None,Containner

拓展網絡模式解釋: https://www.cnblogs.com/ggjucheng/archive/2012/08/19/2646007.html

[root@139 ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
0dd04b1074d6        bridge              bridge              local
d3c5ff224f6d        host                host                local
83a97a50d16f        none                null                local

bridge 橋接模式

最直觀的看bridge就是, 宿主機和容器各有各的ip,可是能夠互聯

咱們在使用docker run命令時歷來沒有配置過添加參數配置docker的網絡模式, 那是由於docker中默認使用橋接模式網絡模式, 並且,bridge模式應該是能夠知足大部分的需求

咱們能夠是要使用bridge自定義一些網絡配置

修改主機名稱(就像咱們常改的host文件)

[root@139 ~]# docker run --name test1 -it --network bridge -h changwu  --rm busybox:latest
/ # hostname 
changwu

/ # cat /etc/hosts
127.0.0.1	localhost
::1	localhost ip6-localhost ip6-loopback
fe00::0	ip6-localnet
ff00::0	ip6-mcastprefix
ff02::1	ip6-allnodes
ff02::2	ip6-allrouters
172.17.0.3	changwu

/ # cat /etc/resolv.conf 
# Generated by NetworkManager
nameserver 100.125.1.250
nameserver 100.125.136.29
options single-request-reopen
 / # nslookup -type=A www.baidu.com
Server:		100.125.1.250
Address:	100.125.1.250:53

Non-authoritative answer:
www.baidu.com	canonical name = www.a.shifen.com
Name:	www.a.shifen.com
Address: 180.101.49.12
Name:	www.a.shifen.com
Address: 180.101.49.11

---------命令詳解------------
在busybox容器中查看這個容器的host文件,已經修改爲我在啓動參數規定的值了
也就是說,當前的容器會將changwu解析成前面的ip地址 172.17.0.3

你看這個容器和linux沒啥區別,確實是一個極簡的linux,並且它一樣有本身的dns解析配置
上面的查看resolv.conf ,100.125.1.250是外往的地址
換句話說,當前的容器訪問XXX.com域名時,先找本機host文件,找不到的話,就訪問這個100.125.1.250 去解析

------參數詳解--------
-h  主機名
-it 運行這個極簡的bash
--network 網絡模式
--rm 一旦退出容器就刪除該容器

自定義DNS地址

[root@139 ~]# docker run --name test -it --network bridge --dns 8.8.8.8 --rm busybox
/ # cat /etc/resolv.conf 
nameserver 8.8.8.8
options single-request-reopen

-------參 數解釋-------
 --dns 跟dns地址

更多命令使用 docker network --help 查看

**host 宿主機網絡模式 **

host網絡模式和bridge橋接的區別就是 host模式中,虛擬機和主機共用一塊網卡上網,這時候虛擬機和主機的之間至關因而一個機器, 容器啓動後對外暴露的提供服務的端口直接綁定到註解對應的端口上, 容器的ip地址就是個人華爲雲ECS的公網ip

[root@139 ~]# docker run --name test -it --network host --rm busybox
/ # hostname 
139.9X.92.X35

none

會造成一個全封閉的容器,沒有網絡配置,沒法和外網互聯

[root@139 ~]# docker run --name test -it --network none --rm busybox
/ # hostname
6511ba02c5e3

container

他和host模式很像, host模式會容器共享主機的ip, 這個container模式就是讓當前容器共享另外一個容器的 network namespace

[root@139 ~]# docker run --name test -it --network container:the_other_container --rm busybox

Docker 端口映射

-p (小寫)的幾種用法

  • 指定容器的端口動態的映射到宿主機的端口上
[root@139 ~]# docker run --name mysql -d -p 3306 -e MYSQL_ROOT_PASSWORD=123123  mysql
291f7337a1ac0232d84eae4b3632bd044bcc433c7a0bafaf97b638a05ddddaf8
[root@139 ~]# docker port mysql 
3306/tcp -> 0.0.0.0:32770
--------解釋-----------
在宿主機上找一個動態的端口,映射到 Containner的 3306端口上
  • 端口映射
[root@139 ~]# docker run --name mysql -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123123  mysql
eaa6bdb54df54419cce5866d5050fec8d1aba4d7d5b85ab41c3e41fd1887c6d0
[root@139 ~]# docker port mysql
3306/tcp -> 0.0.0.0:3306
--------解釋-----------
成功的將宿主機上的3306端口映射到 mysql Containner的3306端口上
  • 經過宿主機ip+端口, 映射到容器的指定端口上
[root@139 ~]# docker run --name mysql -d -e MYSQL_ROOT_PASSWORD=123123 -p 192.168.0.32:3306:3306 mysql
e1ef0d628415a41d6a122c78909cb63c00a788056395d64e667c496ac0c68cdc
[root@139 ~]# docker port mysql
3306/tcp -> 192.168.0.32:3306
  • 指定宿主機的ip, 將容器中的指定端口映射到動態的宿主機端口
[root@139 ~]# docker run --name mysql -d -e MYSQL_ROOT_PASSWORD=123123 -p 192.168.0.32::3306 mysql
2f125488de4dbe4b5583baa46cbedb11a6b15cd38804c23815475d39a262dff5
[root@139 ~]# docker port mysql
3306/tcp -> 192.168.0.32:32768

-P (大寫) 的用法

目的是暴露容器中的全部端口, 哪些端口呢? 就是咱們在Dockerfile中經過Export指定的端口

Docker Compose 編排SpringCloud

將項目容器化後當然很方便,可是總不能真的就挨個去啓動吧,實際上是不用的,咱們使用DockerCompose, 使用Componse咱們能夠在yml中去配置咱們的服務,使用單行命令實現啓動配置中的全部服務

下面的示例是使用Docker Compose編排我寫的 一個法律助手的項目

下載安裝

項目在github上面: https://github.com/docker/compose/releases

下載:

curl -L https://github.com/docker/compose/releases/download/1.25.0-rc3/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose

給docket-compose 可執行的權限

chmod +x /usr/local/bin/docker-compose

設置軟連接

ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose

驗證是否安裝

docker-compose version

卸載

rm /usr/local/bin/docker-compose

思路: DockerComponse的配置文件和Dickerfile中的配置文件相似的, 它的格式的 yml

首先就是安排好jar包和文件的目錄位置, 好比下圖, 四個藍色名稱的目錄中存放着不一樣功能的jar包,DockerComponse須要的配置文件 docker-componse.yml 也在這裏面

目錄

docker-componse.yml 實戰模板:

version: '2.1'
services:
  eurekaserver:
    image: eurekaserver:v1
    ports:
     - 10086:10086
  lawyer-lover-consumer:
    image: lawyer-lover-consumer:v1
    ports:
     - 8082:8082
  lawyer-lover-main:
    image: lawyer-lover-main:v1
    ports:
     - 8081:8081
  lawyer-lover-zuul:
    image: lawyer-lover-zuul:v1
    ports:
     - 10010:10010

輸入命令進行自動編排

docker-compose up -d
-----------------------
-d 表示後臺啓動

結果: 看着本身寫了這些天的項目上線了, 真的爽歪歪啊...

https://img2018.cnblogs.com/blog/1496926/201912/1496926-20191204183210799-1077750538.png

驗證結果:

驗證結果

將本地鏡像發佈到阿里雲倉庫

若是你也想一處構建, 導出運行的話, 能夠玩玩這個功能

網址: https://cr.console.aliyun.com/cn-hangzhou/repositories

  • 將鏡像推送到阿里雲
# 登陸阿里雲的docker倉庫
  docker login --username=[用戶名] registry.cn-hangzhou.aliyuncs.com
# 建立指定鏡像的tag,納入某個倉庫
  docker tag [鏡像ID] registry.cn-hangzhou.aliyuncs.com/huaan/huaan:[鏡像版本號]
# 將鏡像推送到倉庫
  docker push registry.cn-hangzhou.aliyuncs.com/huaan/huaan:[鏡像版本號
  • 拉取鏡像到本地
docker pull registry.cn-hangzhou.aliyuncs.com/coldest7/mytom:v1

dokcer run --help

docker --help

docker network --help

dokcer Containner --help

docker image --help

相關文章
相關標籤/搜索