Docker筆記(狂神說)


1、Docker 入門

狂神說教程:https://www.bilibili.com/video/BV1og4y1q7M4?share_source=copy_web

Docker概述

Docker為什么出現?

一款產品: 開發–上線 兩套環境!應用環境,應用配置!

開發 — 運維。 問題:我在我的電腦上可以允許!版本更新,導致服務不可用!對於運維來說考驗十分大?

環境配置是十分的麻煩,每一個及其都要部署環境(集群Redis、ES、Hadoop…) !費事費力。

發布一個項目( jar + (Redis MySQL JDK ES) ),項目能不能帶上環境安裝打包!

之前在服務器配置一個應用的環境 Redis MySQL JDK ES Hadoop 配置超麻煩了,不能夠跨平台。

開發環境Windows,最后發布到Linux!

傳統:開發jar,運維來做!

現在:開發打包部署上線,一套流程做完!

安卓流程:java — apk —發布(應用商店)一 張三使用apk一安裝即可用!

docker流程: java-jar(環境) — 打包項目帯上環境(鏡像) — ( Docker倉庫:商店)-----

Docker給以上的問題,提出了解決方案!

在這里插入圖片描述

Docker的思想就來自於集裝箱!

JRE – 多個應用(端口沖突) – 原來都是交叉的!
隔離:Docker核心思想!打包裝箱!每個箱子是互相隔離的。

Docker通過隔離機制,可以將服務器利用到極致!

本質:所有的技術都是因為出現了一些問題,我們需要去解決,才去學習!

Docker歷史

2010年,幾個的年輕人,就在美國成立了一家公司 dotcloud

做一些pass的雲計算服務!LXC(Linux Container容器)有關的容器技術!

Linux Container容器是一種內核虛擬化技術,可以提供輕量級的虛擬化,以便隔離進程和資源。

他們將自己的技術(容器化技術)命名就是 Docker
Docker剛剛延生的時候,沒有引起行業的注意!dotCloud,就活不下去!

開源

2013年,Docker開源!

越來越多的人發現docker的優點!火了。Docker每個月都會更新一個版本!

2014年4月9日,Docker1.0發布!

docker為什么這么火?十分的輕巧!

在容器技術出來之前,我們都是使用虛擬機技術!

虛擬機:在window中裝一個VMware,通過這個軟件我們可以虛擬出來一台或者多台電腦!笨重!

虛擬機也屬於虛擬化技術,Docker容器技術,也是一種虛擬化技術!

VMware : linux centos 原生鏡像(一個電腦!) 隔離、需要開啟多個虛擬機! 幾個G 幾分鍾
docker: 隔離,鏡像(最核心的環境 4m + jdk + mysql)十分的小巧,運行鏡像就可以了!小巧! 幾個M 秒級啟動!

聊聊Docker

Docker基於Go語言開發的!開源項目!

docker官網:https://www.docker.com/

文檔:https://docs.docker.com/ Docker的文檔是超級詳細的!

倉庫:https://hub.docker.com/

Docker能干嘛

之前的虛擬機技術

img

虛擬機技術缺點

1、 資源占用十分多

2、 冗余步驟多

3、 啟動很慢!

容器化技術

容器化技術不是模擬一個完整的操作系統

image-20200515094336846

比較Docker和虛擬機技術的不同:

  • 傳統虛擬機,虛擬出一條硬件,運行一個完整的操作系統,然后在這個系統上安裝和運行軟件
  • 容器內的應用直接運行在宿主機的內容,容器是沒有自己的內核的,也沒有虛擬我們的硬件,所以就輕便了
  • 每個容器間是互相隔離,每個容器內都有一個屬於自己的文件系統,互不影響

DevOps(開發、運維)

應用更快速的交付和部署

傳統:一對幫助文檔,安裝程序。

Docker:打包鏡像發布測試一鍵運行。

更便捷的升級和擴縮容

使用了 Docker之后,我們部署應用就和搭積木一樣
項目打包為一個鏡像,擴展服務器A!服務器B更簡單的系統運維
在容器化之后,我們的開發,測試環境都是高度一致的

更高效的計算資源利用

Docker是內核級別的虛擬化,可以在一個物理機上可以運行很多的容器實例!服務器的性能可以被壓榨到極致。

2、Docker安裝

Docker的基本組成

image-20200514195805400

鏡像(image):

docker鏡像就好比是一個目標,可以通過這個目標來創建容器服務,tomcat鏡像>run>容器(提供服務器),通過這個鏡像可以創建多個容器(最終服務運行或者項目運行就是在容器中的)。

容器(container):

Docker利用容器技術,獨立運行一個或者一組應用,通過鏡像來創建的.
啟動,停止,刪除,基本命令
目前就可以把這個容器理解為就是一個簡易的 Linux系統。

倉庫(repository):

倉庫就是存放鏡像的地方!
倉庫分為公有倉庫和私有倉庫。(很類似git)
Docker Hub是國外的。
阿里雲…都有容器服務器(配置鏡像加速!)

安裝Docker

環境准備

1.Linux要求內核3.0以上

2.CentOS 7

[root@iz2zeak7sgj6i7hrb2g862z ~]# uname -r
3.10.0-514.26.2.el7.x86_64	# 要求3.0以上
[root@iz2zeak7sgj6i7hrb2g862z ~]# cat /etc/os-release 
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"

安裝

幫助文檔:https://docs.docker.com/engine/install/
卸載與安裝

#1.卸載舊版本
yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
#2.需要的安裝包
yum install -y yum-utils

#3.設置鏡像的倉庫
yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo
#上述方法默認是從國外的,不推薦

#推薦使用國內的
yum-config-manager \
    --add-repo \
    https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    
#更新yum軟件包索引
yum makecache fast

#4.安裝docker相關的 docker-ce 社區版 而ee是企業版
yum install docker-ce docker-ce-cli containerd.io # 這里我們使用社區版即可

#5.啟動docker
systemctl start docker

#6. 使用docker version查看是否按照成功
docker version

#7. 測試
docker run hello-world


#8.查看已經下載的鏡像(從這里可以查看已有鏡像的id)
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker images
REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
hello-world           latest              bf756fb1ae65        4 months ago      13.3kB

卸載docker

#1. 卸載依賴
yum remove docker-ce docker-ce-cli containerd.io
#2. 刪除資源
rm -rf /var/lib/docker
# /var/lib/docker 是docker的默認工作路徑!

阿里雲鏡像加速

1、登錄阿里雲找到容器服務

image-20200515102112851

2、找到鏡像加速器

image-20200515102009470

3、配置使用

#1.創建一個目錄
sudo mkdir -p /etc/docker

#2.編寫配置文件
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://t2wwyxhb.mirror.aliyuncs.com"]
}
EOF

#3.重啟服務
sudo systemctl daemon-reload
sudo systemctl restart docker

回顧HelloWorld流程

image-20200515102503722

docker run 流程圖

image-20200515102637246

底層原理

Docker是怎么工作的

Docker是一個Client-Server結構的系統,Docker的守護進程運行在主機上。通過Socket從客戶端訪問!

Docker-Server接收到Docker-Client的指令,就會執行這個命令!

image-20200515102949558

為什么Docker比Vm快

1、docker有着比虛擬機更少的抽象層。由於docker不需要Hypervisor實現硬件資源虛擬化,運行在docker容器上的程序直接使用的都是實際物理機的硬件資源。因此在CPU、內存利用率上docker將會在效率上有明顯優勢。
2、docker利用的是宿主機的內核,而不需要Guest OS。

GuestOS: VM(虛擬機)里的的系統(OS)

HostOS:物理機里的系統(OS)

image-20200515104117329

因此,當新建一個 容器時,docker不需要和虛擬機一樣重新加載一個操作系統內核。仍而避免引導、加載操作系統內核返個比較費時費資源的過程,當新建一個虛擬機時,虛擬機軟件需要加載GuestOS,返個新建過程是分鍾級別的。而docker由於直接利用宿主機的操作系統,則省略了這個復雜的過程,因此新建一個docker容器只需要幾秒鍾。

3、Docker的常用命令

3.1 幫助命令

docker version    #顯示docker的版本信息。
docker info       #顯示docker的系統信息,包括鏡像和容器的數量
docker 命令 --help #幫助命令

幫助文檔的地址:https://docs.docker.com/engine/reference/commandline/build/

3.2 鏡像命令

docker images #查看所有本地主機上的鏡像 可以使用docker image ls代替

docker search #搜索鏡像

docker pull #下載鏡像 docker image pull

docker rmi #刪除鏡像 docker image rm

docker images查看所有本地的主機上的鏡像

[root@iz2zeak7sgj6i7hrb2g862z ~]# docker images
REPOSITORY            TAG                 IMAGE ID            CREATED           SIZE
hello-world           latest              bf756fb1ae65        4 months ago     13.3kB
mysql                 5.7                 b84d68d0a7db        6 days ago       448MB

# 解釋
#REPOSITORY			# 鏡像的倉庫源
#TAG				# 鏡像的標簽(版本)		---lastest 表示最新版本
#IMAGE ID			# 鏡像的id
#CREATED			# 鏡像的創建時間
#SIZE				# 鏡像的大小

# 可選項
Options:
  -a, --all         Show all images (default hides intermediate images) #列出所有鏡像
  -q, --quiet       Only show numeric IDs # 只顯示鏡像的id
  
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker images -a  #列出所有鏡像詳細信息
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker images -aq #列出所有鏡像的id
d5f28a0bb0d0
f19c56ce92a8
1b6b1fe7261e
1b6b1fe7261e

docker search 搜索鏡像

在這里插入圖片描述

[root@iz2zeak7sgj6i7hrb2g862z ~]# docker search mysql

# --filter=STARS=3000 #過濾,搜索出來的鏡像收藏STARS數量大於3000的
Options:
  -f, --filter filter   Filter output based on conditions provided
      --format string   Pretty-print search using a Go template
      --limit int       Max number of search results (default 25)
      --no-trunc        Don't truncate output
      
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker search mysql --filter=STARS=3000
NAME        DESCRIPTION         STARS            OFFICIAL        AUTOMATED
mysql       MySQL IS ...        9520             [OK]                
mariadb     MariaDB IS ...      3456             [OK]   
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker search mysql

# --filter=STARS=3000 #過濾,搜索出來的鏡像收藏STARS數量大於3000的
Options:
  -f, --filter filter   Filter output based on conditions provided
      --format string   Pretty-print search using a Go template
      --limit int       Max number of search results (default 25)
      --no-trunc        Don't truncate output
      
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker search mysql --filter=STARS=3000
NAME        DESCRIPTION         STARS            OFFICIAL        AUTOMATED
mysql       MySQL IS ...        9520             [OK]                
mariadb     MariaDB IS ...      3456             [OK]   

docker pull 下載鏡像

# 下載鏡像 docker pull 鏡像名[:tag]
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker pull tomcat:8
8: Pulling from library/tomcat #如果不寫tag,默認就是latest
90fe46dd8199: Already exists   #分層下載: docker image 的核心 聯合文件系統
35a4f1977689: Already exists 
bbc37f14aded: Already exists 
74e27dc593d4: Already exists 
93a01fbfad7f: Already exists 
1478df405869: Pull complete 
64f0dd11682b: Pull complete 
68ff4e050d11: Pull complete 
f576086003cf: Pull complete 
3b72593ce10e: Pull complete 
Digest: sha256:0c6234e7ec9d10ab32c06423ab829b32e3183ba5bf2620ee66de866df # 簽名防偽
Status: Downloaded newer image for tomcat:8
docker.io/library/tomcat:8 #真實地址

#等價於
docker pull tomcat:8
docker pull docker.io/library/tomcat:8

docker rmi 刪除鏡像

docker rmi -f 鏡像id #刪除指定id的鏡像
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker rmi -f f19c56ce92a8

docker rmi -f $(docker images -aq) #刪除全部的鏡像
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker stop $(docker ps -a -q)

3.3 容器命令

說明:我們有了鏡像才可以創建容器,Linux,下載centos鏡像來學習

鏡像下載
#docker中下載centos
docker pull centos
docker run 鏡像id #新建容器並啟動

docker ps 列出所有運行的容器 docker container list

docker rm 容器id #刪除指定容器

docker start 容器id	#啟動容器
docker restart 容器id	#重啟容器
docker stop 容器id	#停止當前正在運行的容器
docker kill 容器id	#強制停止當前容器
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker container list  #h和docker ps相同

在這里插入圖片描述

新建容器並啟動
docker run [可選參數] image | docker container run [可選參數] image 
#參書說明
--name="Name"		#容器名字 tomcat01 tomcat02 用來區分容器
-d					#后台方式運行
-it 				#使用交互方式運行,進入容器查看內容
-p					#指定容器的端口 -p 8080(宿主機):8080(容器)
		-p ip:主機端口:容器端口
		-p 主機端口:容器端口(常用)
		-p 容器端口
		容器端口
-P(大寫) 				隨機指定端口

# 測試、啟動並進入容器
[root@iz2zeak7sgj6i7hrb2g
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker run -it centos /bin/bash
[root@241b5abce65e /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@241b5abce65e /]# exit #從容器退回主機
exit

在這里插入圖片描述

列出所有運行的容器
docker ps 命令  		#列出當前正在運行的容器
  -a, --all     	 #列出當前正在運行的容器 + 帶出歷史運行過的容器
  -n=?, --last int   #列出最近創建的?個容器 ?為1則只列出最近創建的一個容器,為2則列出2個
  -q, --quiet        #只列出容器的編號

在這里插入圖片描述

在這里插入圖片描述

退出容器
exit 		#容器直接退出
ctrl +P +Q  #容器不停止退出 	---注意:這個很有用的操作
刪除容器
docker rm 容器id   				#刪除指定的容器,不能刪除正在運行的容器,如果要強制刪除 rm -rf
docker rm -f $(docker ps -aq)  	 #刪除所有的容器
docker ps -a -q|xargs docker rm  #刪除所有的容器
啟動和停止容器的操作
docker start 容器id	#啟動容器
docker restart 容器id	#重啟容器
docker stop 容器id	#停止當前正在運行的容器
docker kill 容器id	#強制停止當前容器

3. 4 常用其他命令

后台啟動命令
# 命令 docker run -d 鏡像名
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker run -d centos
a8f922c255859622ac45ce3a535b7a0e8253329be4756ed6e32265d2dd2fac6c

[root@iz2zeak7sgj6i7hrb2g862z ~]# docker ps    
CONTAINER ID      IMAGE       COMMAND    CREATED     STATUS   PORTS    NAMES
# 問題docker ps. 發現centos 停止了
# 常見的坑,docker容器使用后台運行,就必須要有要一個前台進程,docker發現沒有應用,就會自動停止
# nginx,容器啟動后,發現自己沒有提供服務,就會立刻停止,就是沒有程序了
查看日志
docker logs --help
Options:
      --details        Show extra details provided to logs 
*  -f, --follow         Follow log output
      --since string   Show logs since timestamp (e.g. 2013-01-02T13:23:37) or relative (e.g. 42m for 42 minutes)
*      --tail string    Number of lines to show from the end of the logs (default "all")
*  -t, --timestamps     Show timestamps
      --until string   Show logs before a timestamp (e.g. 2013-01-02T13:23:37) or relative (e.g. 42m for 42 minutes)
➜  ~ docker run -d centos /bin/sh -c "while true;do echo 6666;sleep 1;done" #模擬日志      
#顯示日志
-tf		#顯示日志信息(一直更新)
--tail number #需要顯示日志條數
docker logs -t --tail n 容器id #查看n行日志
docker logs -ft 容器id #跟着日志
查看容器中進程信息ps
# 命令 docker top 容器id
1

image-20200515132913888

查看鏡像的元數據
# 命令
docker inspect 容器id

#測試
➜  ~ docker inspect 55321bcae33d
[
    {
        "Id": "55321bcae33d15da8280bcac1d2bc1141d213bcc8f8e792edfd832ff61ae5066",
        "Created": "2020-05-15T05:22:05.515909071Z",
        "Path": "/bin/sh",
        "Args": [
            "-c",
            "while true;do echo 6666;sleep 1;done"
        ],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 22973,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2020-05-15T05:22:06.165904633Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        "Image": "sha256:470671670cac686c7cf0081e0b37da2e9f4f768ddc5f6a26102ccd1c6954c1ee",
        "ResolvConfPath": "/var/lib/docker/containers/55321bcae33d15da8280bcac1d2bc1141d213bcc8f8e792edfd832ff61ae5066/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/55321bcae33d15da8280bcac1d2bc1141d213bcc8f8e792edfd832ff61ae5066/hostname",
        "HostsPath": "/var/lib/docker/containers/55321bcae33d15da8280bcac1d2bc1141d213bcc8f8e792edfd832ff61ae5066/hosts",
        "LogPath": "/var/lib/docker/containers/55321bcae33d15da8280bcac1d2bc1141d213bcc8f8e792edfd832ff61ae5066/55321bcae33d15da8280bcac1d2bc1141d213bcc8f8e792edfd832ff61ae5066-json.log",
        "Name": "/bold_bell",
        "RestartCount": 0,
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "docker-default",
        "ExecIDs": null,
        "HostConfig": {
            "Binds": null,
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "default",
            "PortBindings": {},
            "RestartPolicy": {
                "Name": "no",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "CapAdd": null,
            "CapDrop": null,
            "Capabilities": null,
            "Dns": [],
            "DnsOptions": [],
            "DnsSearch": [],
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "private",
            "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,
            "DeviceRequests": null,
            "KernelMemory": 0,
            "KernelMemoryTCP": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": null,
            "OomKillDisable": false,
            "PidsLimit": null,
            "Ulimits": null,
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0,
            "MaskedPaths": [
                "/proc/asound",
                "/proc/acpi",
                "/proc/kcore",
                "/proc/keys",
                "/proc/latency_stats",
                "/proc/timer_list",
                "/proc/timer_stats",
                "/proc/sched_debug",
                "/proc/scsi",
                "/sys/firmware"
            ],
            "ReadonlyPaths": [
                "/proc/bus",
                "/proc/fs",
                "/proc/irq",
                "/proc/sys",
                "/proc/sysrq-trigger"
            ]
        },
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/1f347949ba49c4dbee70cea9ff3af39a14e602bc8fac8331c46347bf6708757a-init/diff:/var/lib/docker/overlay2/5afcd8220c51854a847a36f52775b4ed0acb16fe6cfaec3bd2e5df59863835ba/diff",
                "MergedDir": "/var/lib/docker/overlay2/1f347949ba49c4dbee70cea9ff3af39a14e602bc8fac8331c46347bf6708757a/merged",
                "UpperDir": "/var/lib/docker/overlay2/1f347949ba49c4dbee70cea9ff3af39a14e602bc8fac8331c46347bf6708757a/diff",
                "WorkDir": "/var/lib/docker/overlay2/1f347949ba49c4dbee70cea9ff3af39a14e602bc8fac8331c46347bf6708757a/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [],
        "Config": {
            "Hostname": "55321bcae33d",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/bin/sh",
                "-c",
                "while true;do echo 6666;sleep 1;done"
            ],
            "Image": "centos",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {
                "org.label-schema.build-date": "20200114",
                "org.label-schema.license": "GPLv2",
                "org.label-schema.name": "CentOS Base Image",
                "org.label-schema.schema-version": "1.0",
                "org.label-schema.vendor": "CentOS",
                "org.opencontainers.image.created": "2020-01-14 00:00:00-08:00",
                "org.opencontainers.image.licenses": "GPL-2.0-only",
                "org.opencontainers.image.title": "CentOS Base Image",
                "org.opencontainers.image.vendor": "CentOS"
            }
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "63ed0c837f35c12453bae9661859f37a08541a0749afb86e881869bf6fd9031b",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {},
            "SandboxKey": "/var/run/docker/netns/63ed0c837f35",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "b129d9a5a2cbb92722a2101244bd81a9e3d8af034e83f338c13790a1a94552a1",
            "Gateway": "172.17.0.1",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.17.0.4",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "MacAddress": "02:42:ac:11:00:04",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "ad5ada6a106f5ba3dda9ce4bc1475a4bb593bf5f7fbead72196e66515e8ac36a",
                    "EndpointID": "b129d9a5a2cbb92722a2101244bd81a9e3d8af034e83f338c13790a1a94552a1",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.4",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:04",
                    "DriverOpts": null
                }
            }
        }
    }
]
進入當前正在運行的容器
# 我們通常容器都是在后台運行,需要進入容器,修改一些配置

# 命令
docker exec -it 容器id bashshell

[root@localhost ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES
4f95779df41b   centos    "/bin/sh -c 'while t…"   10 minutes ago   Up 10 minutes             nostalgic_edison
[root@localhost ~]# docker exec -it 4f95779df41b /bin/bash
[root@4f95779df41b /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

# 方式二
dcoker attach 容器id
# 測試
[root@localhost ~]# docker attach dce7bshk8oou7
正在執行當前的代碼...

docker exec #進入容器后開啟一個新的終端
docker attach # 進入容器正在執行的終端,不會啟動新的進程

從容器內拷貝文件到主機上

docker cp 容器id:容器內路徑  目的主機路徑

# 查看當前主機目錄下
[root@localhost home]# ls
eric
[root@localhost home]# touch eric.java
[root@localhost home]# ls
eric  eric.java
[root@localhost home]# docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED              STATUS              PORTS     NAMES
2ae552528a84   centos    "/bin/bash"   About a minute ago   Up About a minute             sleepy_kowalevski

# 進入docker容器內部
[root@localhost home]# docker attach 2ae552528a84
[root@2ae552528a84 /]# cd /home
[root@2ae552528a84 home]# ls

# 在容器內部進行創建文件
[root@2ae552528a84 home]# touch test.java
[root@2ae552528a84 home]# exit
exit
[root@localhost home]# docker ps -a
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS                     PORTS     NAMES
2ae552528a84   centos    "/bin/bash"   3 minutes ago   Exited (0) 6 seconds ago             sleepy_kowalevski

# 見文件拷貝出來到主機上
[root@localhost home]# docker cp 2ae552528a84:/home/test.java /home
[root@localhost home]# ls
eric  eric.java  test.java

# 拷貝是一個手動過程,未來我們可以使用-v卷的技術,可以實現自動同步 /home /home

3.5 小結

image-20210505190814029

命令大全

  attach      Attach local standard input, output, and error streams to a running container
  #當前shell下 attach連接指定運行的鏡像
  build       Build an image from a Dockerfile # 通過Dockerfile定制鏡像
  commit      Create a new image from a container's changes #提交當前容器為新的鏡像
  cp          Copy files/folders between a container and the local filesystem #拷貝文件
  create      Create a new container #創建一個新的容器
  diff        Inspect changes to files or directories on a container's filesystem #查看docker容器的變化
  events      Get real time events from the server # 從服務獲取容器實時時間
  exec        Run a command in a running container # 在運行中的容器上運行命令
  export      Export a container's filesystem as a tar archive #導出容器文件系統作為一個tar歸檔文件[對應import]
  history     Show the history of an image # 展示一個鏡像形成歷史
  images      List images #列出系統當前的鏡像
  import      Import the contents from a tarball to create a filesystem image #從tar包中導入內容創建一個文件系統鏡像
  info        Display system-wide information # 顯示全系統信息
  inspect     Return low-level information on Docker objects #查看容器詳細信息
  kill        Kill one or more running containers # kill指定docker容器
  load        Load an image from a tar archive or STDIN #從一個tar包或標准輸入中加載一個鏡像[對應save]
  login       Log in to a Docker registry #
  logout      Log out from a Docker registry
  logs        Fetch the logs of a container
  pause       Pause all processes within one or more containers
  port        List port mappings or a specific mapping for the container
  ps          List containers
  pull        Pull an image or a repository from a registry
  push        Push an image or a repository to a registry
  rename      Rename a container
  restart     Restart one or more containers
  rm          Remove one or more containers
  rmi         Remove one or more images
  run         Run a command in a new container
  save        Save one or more images to a tar archive (streamed to STDOUT by default)
  search      Search the Docker Hub for images
  start       Start one or more stopped containers
  stats       Display a live stream of container(s) resource usage statistics
  stop        Stop one or more running containers
  tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
  top         Display the running processes of a container
  unpause     Unpause all processes within one or more containers
  update      Update configuration of one or more containers
  version     Show the Docker version information
  wait        Block until one or more containers stop, then print their exit codes

3.6作業練習(安裝)

作業一:Docker 安裝Nginx

# 1、搜索鏡像
[root@localhost home]# docker search nginx

# 2、拉取鏡像
[root@localhost home]# docker pull nginx

# 3、查看鏡像
[root@localhost home]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
nginx        latest    62d49f9bab67   3 weeks ago    133MB
centos       latest    300e315adb2f   4 months ago   209MB

# 4、啟動運行
[root@localhost home]# docker run -d --name nginx01 -p 3344:80 nginx
66f84ea1a1679cc5f062e4c7aab26f051d30df710e23e7685597257933eb7d61

# 5、查看運行情況
[root@localhost home]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                                   NAMES
66f84ea1a167   nginx     "/docker-entrypoint.…"   31 seconds ago   Up 29 seconds   0.0.0.0:3344->80/tcp, :::3344->80/tcp   nginx01

# -d 后台運行
# --name 給容器起名字
# -p 宿主機端口:容器內部端口

# 6、本機自測運行情況
[root@localhost home]# curl localhost:3344
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

# 7、進入容器,修改配置
[root@localhost home]# docker exec -it nginx01 /bin/bash
root@66f84ea1a167:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
root@66f84ea1a167:/# cd /etc/nginx
root@66f84ea1a167:/etc/nginx# ls
conf.d	fastcgi_params	koi-utf  koi-win  mime.types  modules  nginx.conf  scgi_params	uwsgi_params  win-utf
root@66f84ea1a167:/etc/nginx# 

端口暴露的概念

image-20210505195207334

思考問題:我們每次都需要改動nginx配置,都需要進入容器內部?十分的麻煩,我們要是可以在容器外部提供一個映射路徑,達到可以在容器外部修改文件名,容器內部就可以進行自動修改?-數據卷

作業二:用docker 來裝一個tomcat

# 下載 tomcat9.0
# 之前的啟動都是后台,停止了容器,容器還是可以查到, docker run -it --rm 鏡像名 一般是用來測試,用完就刪除
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker run -it --rm tomcat:9.0

--rm       Automatically remove the container when it exits 用完即刪

#下載 最新版
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker pull tomcat

#查看下載的鏡像
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker images

#以后台方式,暴露端口方式,啟動運行
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker run -d -p 8080:8080 --name tomcat01 tomcat

#測試訪問有沒有問題
curl localhost:8080

#根據容器id進入tomcat容器
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker exec -it 645596565d3f /bin/bash
root@645596565d3f:/usr/local/tomcat# 
#查看tomcat容器內部內容:
root@645596565d3f:/usr/local/tomcat# ls -l
total 152
-rw-r--r-- 1 root root 18982 May  5 20:40 BUILDING.txt
-rw-r--r-- 1 root root  5409 May  5 20:40 CONTRIBUTING.md
-rw-r--r-- 1 root root 57092 May  5 20:40 LICENSE
-rw-r--r-- 1 root root  2333 May  5 20:40 NOTICE
-rw-r--r-- 1 root root  3255 May  5 20:40 README.md
-rw-r--r-- 1 root root  6898 May  5 20:40 RELEASE-NOTES
-rw-r--r-- 1 root root 16262 May  5 20:40 RUNNING.txt
drwxr-xr-x 2 root root  4096 May 16 12:05 bin
drwxr-xr-x 1 root root  4096 May 21 11:04 conf
drwxr-xr-x 2 root root  4096 May 16 12:05 lib
drwxrwxrwx 1 root root  4096 May 21 11:04 logs
drwxr-xr-x 2 root root  4096 May 16 12:05 native-jni-lib
drwxrwxrwx 2 root root  4096 May 16 12:05 temp
drwxr-xr-x 2 root root  4096 May 16 12:05 webapps
drwxr-xr-x 7 root root  4096 May  5 20:37 webapps.dist
drwxrwxrwx 2 root root  4096 May  5 20:36 work
root@645596565d3f:/usr/local/tomcat# 
#進入webapps目錄
root@645596565d3f:/usr/local/tomcat# cd webapps
root@645596565d3f:/usr/local/tomcat/webapps# ls
root@645596565d3f:/usr/local/tomcat/webapps# 
# 發現問題:1、linux命令少了。 2.webapps目錄為空 
# 原因:阿里雲鏡像的原因,阿里雲默認是最小的鏡像,所以不必要的都剔除掉
# 保證最小可運行的環境!
# 解決方案:
# 將webapps.dist下的文件都拷貝到webapps下即可
root@645596565d3f:/usr/local/tomcat# ls 找到webapps.dist
BUILDING.txt	 LICENSE  README.md	 RUNNING.txt  conf  logs  temp     webapps.dist
CONTRIBUTING.md  NOTICE   RELEASE-NOTES  bin   lib   native-jni-lib  webapps  work

root@645596565d3f:/usr/local/tomcat# cd webapps.dist/ # 進入webapps.dist 
root@645596565d3f:/usr/local/tomcat/webapps.dist# ls # 查看內容
ROOT  docs  examples  host-manager  manager

root@645596565d3f:/usr/local/tomcat/webapps.dist# cd ..
root@645596565d3f:/usr/local/tomcat# cp -r webapps.dist/* webapps # 拷貝webapps.dist 內容給webapps
root@645596565d3f:/usr/local/tomcat# cd webapps #進入webapps
root@645596565d3f:/usr/local/tomcat/webapps# ls #查看拷貝結果
ROOT  docs  examples  host-manager  manager

這樣docker部署tomcat就可以訪問了

在這里插入圖片描述

問題:我們以后要部署項目,如果每次都要進入容器是不是十分麻煩?要是可以在容器外部提供一個映射路徑,比如webapps,我們在外部放置項目,就自動同步內部就好了!

作業三:部署elasticsearch+kibana

# es 暴露的端口很多!
# es 十分耗內存
# es 的數據一般需要放置到安全目錄!掛載
# --net somenetwork ? 網絡配置

# 啟動elasticsearch
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2

# 測試一下es是否成功啟動
➜  ~ curl localhost:9200
{
  "name" : "d73ad2f22dd3",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "atFKgANxS8CzgIyCB8PGxA",
  "version" : {
    "number" : "7.6.2",
    "build_flavor" : "default",
    "build_type" : "docker",
    "build_hash" : "ef48eb35cf30adf4db14086e8aabd07ef6fb113f",
    "build_date" : "2020-03-26T06:34:37.794943Z",
    "build_snapshot" : false,
    "lucene_version" : "8.4.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}

#測試成功就關掉elasticSearch,防止耗內存
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker stop d834ce2bd306
d834ce2bd306

[root@iz2zeak7sgj6i7hrb2g862z ~]# docker stats  # 查看docker容器使用內存情況

img

#測試成功就關掉elasticSearch,可以添加內存的限制,修改配置文件 -e 環境配置修改(看自己的容器號,這個可能也是copy別人的,所以號不一樣)
➜  ~ docker rm -f d73ad2f22dd3            # stop命令也行                               
➜  ~ docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2

img

➜  ~ curl localhost:9200
{
  "name" : "b72c9847ec48",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "yNAK0EORSvq3Wtaqe2QqAg",
  "version" : {
    "number" : "7.6.2",
    "build_flavor" : "default",
    "build_type" : "docker",
    "build_hash" : "ef48eb35cf30adf4db14086e8aabd07ef6fb113f",
    "build_date" : "2020-03-26T06:34:37.794943Z",
    "build_snapshot" : false,
    "lucene_version" : "8.4.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}

作業三:使用kibana連接es (elasticSearch)?思考網絡如何才能連接

img

Portainer 可視化面板安裝

  • portainer(先用這個)
docker run -d -p 8080:9000 \
--restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
  • Rancher(CI/CD再用)
    什么是portainer?

Docker圖形化界面管理工具!提供一個后台面板供我們操作!

# 安裝命令
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker run -d -p 8080:9000 \
> --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer

Unable to find image 'portainer/portainer:latest' locally
latest: Pulling from portainer/portainer
d1e017099d17: Pull complete 
a7dca5b5a9e8: Pull complete 
Digest: sha256:4ae7f14330b56ffc8728e63d355bc4bc7381417fa45ba0597e5dd32682901080
Status: Downloaded newer image for portainer/portainer:latest
81753869c4fd438cec0e31659cbed0d112ad22bbcfcb9605483b126ee8ff306d

測試訪問: 外網:8080 :http://123.56.247.59:8080/

img

進入之后的面板

img

4、鏡像原理之聯合文件系統

4.1 鏡像是什么

鏡像是一種輕量級、可執行的獨立軟件包,用來打包軟件運行環境和基於運行環境開發的軟件,它包含運行某個軟件所需的所有內容,包括代碼、運行時、庫、環境變量和配置文件。

所有的應用,直接打包docker鏡像,就可以直接跑起來

如何得到鏡像:

  • 從遠處倉庫下載
  • 朋友拷貝給你
  • 自己制作一個鏡像DockerFile

4.2 Docker鏡像加載原理

  1. UnionFS(聯合文件系統)

UnionFS(聯合文件系統):Union文件系統(UnionFS)是一種分層、輕量級並且高性能的文件系統,它支持對文件系統的修改作為一次提交來一層層的疊加,同時可以將不同目錄掛載到同一個虛擬文件系統下(unite several directories into a single virtual filesystem)。Union 文件系統是 Docker 鏡像的基礎。鏡像可以通過分層來進行繼承,基於基礎鏡像(沒有父鏡像),可以制作各種具體的應用鏡像。

特性:一次同時加載多個文件系統,但從外面看起來,只能看到一個文件系統,聯合加載會把各層文件系統疊加起來,這樣最終的文件系統會包含所有底層的文件和目錄。

  1. 鏡像加載原理

bootfs(boot file system)主要包含bootloader和kernel, bootloader主要是引導加載kernel, Linux剛啟動時會加載bootfs文件系統,在Docker鏡像的最底層是bootfs。這一層與我們典型的Linux/Unix系統是一樣的,包含boot加載器和內核。當boot加載完成之后整個內核就都在內存中了,此時內存的使用權已由bootfs轉交給內核,此時系統也會卸載bootfs。

rootfs (root file system),在bootfs之上。包含的就是典型 Linux 系統中的 /dev,/proc,/bin,/etc 等標准目錄和文件。rootfs就是各種不同的操作系統發行版,比如Ubuntu,Centos等等。

平時我們安裝虛擬機的centos都是好幾個G,為什么Docker這里才200M?

image-20210506121438793

對於一個精簡的OS,rootfs 可以很小,只需要包含最基本的命令,工具和程序庫就可以了,因為底層直接用Host的kernel,自己只需要提供rootfs就可以了。由此可見對於不同的linux發行版, bootfs基本是一致的,rootfs會有差別,因此不同的發行版可以公用bootfs。

虛擬機是分鍾級別的,容器是秒級別的。

4.3 分層的鏡像

我們去下載一個鏡像,注意觀察下載的日志輸出,可以看到是一層一層的在下載!

image-20210506142415950

思考:為什么要采用這種分層的結構呢?

最大的好處,我覺得莫過於是資源共享了,比如有多個鏡像都從相同的Base鏡像構建而來,那么宿主機只需要在磁盤上保留一份base鏡像,同時內存中只需要加載一份base鏡像,這樣就可以為多有的容器服務了,而且每一層都可以被共享

查看鏡像分層的方式可以通過docker image inspect 命令

[root@localhost ~]# docker image inspect redis:latest

"RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:7e718b9c0c8c2e6420fe9c4d1d551088e314fe923dce4b2caf75891d82fb227d",
                "sha256:89ce1a07a7e4574d724ea605b4877f8a73542cf6abd3c8cbbd2668d911fa5353",
                "sha256:9eef6e3cc2937e452b2325b227ca28120a70481be25404ed9aad27fa81219fd0",
                "sha256:ee748697d275b904f1d5604345d70b647a8c145b9f05aeb5ca667e1f256e43d8",
                "sha256:f1f7964d40afa49c6ef63ab11af91044e518a2539f567783ce997d3cea9ce8f6",
                "sha256:3d9fda8ff875e549d54e9d7504ce17d27423fe27dafbb92127c603dddad7fa13"
            ]
        },

理解

所有的 Docker|鏡像都起始於一個基礎鏡像層,當進行修改或增加新的內容時,就會在當前鏡像層之上,創建新的鏡像層。

舉一個簡單的例子,假如基於 Ubuntu Linux 16.04 創建一個新的鏡像,這就是新鏡像的第一層;如果在該鏡像中添加 Python包,就會在基礎鏡像層之上創建第二個鏡像層;如果繼續添加一個安全補丁,就會創建第三個鏡像層。

該鏡像當前已經包含 3 個鏡像層,如下圖所示(這只是一個用於演示的很簡單的例子)。
image-20210506144010853

在添加額外的鏡像層的同時,鏡像始終是保持當前所有鏡像的組合,理解這一點是非常重要的。下圖拒了一個簡單的例子,每個鏡像包含三個文件,而鏡像包含了來自兩個鏡像層的6個文件。

img

上圖中的鏡像層和之前的圖中略有區別,主要目的是便於展示文件

下圖中展示了一個稍微復雜的三層鏡像,在外部看來整個鏡像只有6個文件,這是因為最上層的文件7是文件5的一個更新版

image-20210506151545247

這種情況下,上層鏡像層中的文件覆蓋了底層鏡像層中的文件。這樣就使得文件的更新版本作為一個新鏡像層添加到鏡像當中。 Docker 通過存儲引擎(新版本采用快照機制)的方式來實現鏡像層堆棧,並保證多鏡像層對外展示為統一的文件系統。 Linux 上可用的存儲引擎有 AUFS、Overlay2、Device Mapper、Btrfs 以及 ZFS。顧名思義,每種存儲引擎都基於 Linux 中對應的文件系統或者塊設備技術,並且每種存儲引擎都有其獨有的性能特點。

Docker 在 Windows 上僅支持 windowsfiter一種存儲引擎,該引擎基於 NTFS 文件系統之上實現了分層和 CoW[1]。

下圖展示了與系統顯示相同的三層鏡像。所有鏡像層堆疊並合井,對外提供統一的視圖。

image-20210506152155309

特點

Docker鏡像都是只讀的,當容器啟動時,一個新的可寫層被加載到鏡像頂部!

這一層就是我們通常說的容器層,容器之下的都叫鏡像層

image-20210506153603573

4.4 commit鏡像

docker commit 提交容器成為一個新的副本# 命令和git原理類似docker commit -m="提交的描述信息" -a="作者" 容器id 目標鏡像名:[tag]

實戰測試

# 啟動一個默認的tomcat# 發現這個默認的tomcat是沒有webapps應用的,鏡像的原因:官方鏡像默認webapps下面沒有文件的!# 我自己拷貝進去了基本的文件# 將我們自己操作過后的容器通過commit提交為一個鏡像,我們以后就可以使用自己修改過的鏡像,這就是我們自己的一個修改過的鏡像[root@localhost ~]# docker commit -a="eric" -m="add webapps application" 6f4fd55369bb tomcat02:1.0sha256:a3eec2c2487fdc97ca6adeecb21d5e02e7ba7501a561256528ba7efb9021d228# 查看修改過后的鏡像

image-20210506203844240

如果你想要保存當前的狀態,就通過commit提交,獲得一個鏡像,就好比我們以前學習VM時候,快照

5. 容器數據卷

5.1 什么是容器數據卷

將應用環境打包成一個鏡像!

數據?如果數據都在容器中,那么我們容器刪除,數據就會丟失!需求:數據可以持久化

MySQL,容器刪除了,刪庫跑路!需求:MySQL的數據可以存儲在本地

容器之間可以有一個數據共享的技術!docker容器中產生的數據,同步到本地

這就是卷技術,目錄的掛載,將容器內的目錄掛載在Linux上面

image-20210506205536696

總結一句話:容器的持久化和同步操作,容器間也是可以數據共享的

5.2 使用命令來掛載

docker run -it -v 主機目錄:容器的目錄

# 測試
[root@localhost home]# docker run -it -v /home/ceshi:/home centos /bin/bash

# 容器啟動的時候我們可以通過docker inspect 容器id

image-20210506210458164

測試文件的同步

image-20210506211128888

再來測試

1.停止容器

2、宿主機上修改文件

3、啟動容器

4、容器內的數據依舊是同步的

image-20210506211801910

好處:我們以后修改只需要在本地進行修改即可,容器內部會自動進行同步!

實戰:安裝MySQL

# 獲取鏡像[root@localhost ~]# docker pull mysql:5.7# 運行容器,需要做數據掛載,安裝MySQL需要配置密碼,下面是官方命令# docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag# 啟動我們的-d 后台運行-p 端口映射-v 數據卷掛載-e 環境配置--name 容器名字[root@localhost ~]# docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=338218 --name mysql01 mysql:5.7# 在啟動成功后,我們在本地使用sqlyog來測試連接一下# sqlyog--連接到服務器3310---3310和容器內部的3306進行映射,這個時候我們就可以連接上了# 在本地測試新建一個數據庫,查看一下我們映射的路徑是否ok

5.3 具名和匿名掛載

# 匿名掛載,注意這里使用-P表示的指定隨機的端口號,沒有指定主機的位置信息-v 容器內路徑docker run -d -P --name nginx01 -v /etc/nginx nginx# 查看所有卷的情況[root@localhost ~]# docker volume lslocal     1d0b3ba7045ef37ab30b087687b36325c1941d2178961c23d511a89f38d757aa# 這里發現,這種就是匿名掛載,我們在-v只寫了容器內的路徑,沒有寫容器外的路徑# 具名掛載[root@localhost ~]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx8571cb0d59725be9ab6f9efabcfd2a9d709ff99ceee59348494f567872829a67[root@localhost ~]# docker volume lsDRIVER    VOLUME NAMElocal     1d0b3ba7045ef37ab30b087687b36325c1941d2178961c23d511a89f38d757aalocal     455e0591eae1c3969b1b8bf82da94c821a8e94c156650b328bf0720498f2dee6local     juming-nginx# 通過 -v 卷名:容器內路徑# 查看一下這個卷

image-20210506215227961

所有的docker容器內的卷,在沒有指定目錄的情況下都是在/var/lib/docker/volumes/xxx/_data

我們通過具名掛載可以方便找到我們的一個卷,大多數情況下都是使用具名掛載

# 如何確定是匿名掛載還是具名掛載,還是指定路徑掛載
-v 容器內路徑 # 匿名掛載
-v 卷名:容器內路徑 # 具名掛載
-v 宿主機路徑:容器內路徑 # 指定路徑掛載

拓展

# 通過 -v 容器內路徑:ro rw 改變讀寫權限
ro readonly # 只讀
rw readwrite # 可讀可寫

# 一旦設置了這個容器權限,容器對我們掛載出來的內容就有了限定了
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx

# ro 只要看到ro就說明這個路徑只能通過宿主機來操作,容器內部是無法進行操作的

5.4 初識DockerFile

DockerFile就是用來構建docker鏡像的構建文件,命令腳本,先體驗一下

通過這個腳本可以生成一個鏡像,鏡像是一層層的,所以腳本是一個個的命令

# 創建一個dockerfile文件,名字可以隨機,建議Dockerfile# 文件中的內容 指令(大寫) 參數FROM centosVOLUME ["volume01","volume02"]CMD echo "---end---"CMD /bin/bash# 這里的每個命令就是鏡像的一層

image-20210506222027144

image-20210506222107630

啟動一下自己寫的容器

image-20210506222438278

這個卷和外部一定有一個同步的目錄

image-20210506222628890

查看一下卷掛載的路徑

[root@localhost data]# docker inspect fca535846c94

image-20210506223145866

測試一下文件是否已經被同步出去了

這種方式未來的使用非常多,因為我們自己通常會構建自己的鏡像

假設構建鏡像的時候沒有掛載,需要自己手動掛載鏡像 -v 卷名:容器內路徑

5.5 數據卷容器

多個MySQL同步數據

image-20210506224019709

啟動3個容器,通過我們剛在自己寫的鏡像啟動*

image-20210506230229069

image-20210506231252458

docker01的數據同步到了docker02

image-20210506231106013

image-20210506231733375

# 測試 :可以刪除容器dcoker01,查看docker02和docker03時候還可以訪問這個文件

# 測試結果是依然可以訪問到

image-20210506232522977

多個MySQL實現數據共享

docker run -d -p 3310:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=338218 --name mysql01 mysql:5.7docker run -d -p 3311:3306 -e MYSQL_ROOT_PASSWORD=338218 --name mysql02 --volumes-from mysql01 mysql:5.7# 這個時候可以實現兩個容器數據同步

結論:

容器之間配置信息的傳遞,數據卷容器的生命周期這一直持續到沒有容器使用為止

但是一旦持久化到了本地,這個時候,本地的數據不會被刪除

6. DockerFile

6.1 DockerFile介紹

dockerfile是用來構建docker鏡像的文件,命令參數腳本

構建步驟:

1、編寫一個dockerfile文件

2、docker build構建為一個鏡像

3、docker run 運行鏡像

4、docker push發布鏡像(DockerHub、阿里雲鏡像倉庫)

查看一下官方是怎么做的

image-20210507154128224

image-20210507154358305

很多官方的鏡像都是基礎包,很多功能都沒有,我們通常會自己搭建自己的鏡像

官方可以制作鏡像,那我們也可以

6.2 DockerFile鏡像的構建

基礎知識:

1、每個保留關鍵字(指令)都是必須是大寫字母

2、執行從上到下順序執行

3、#表示注釋

4、每一個指令都會創建提交一個新的鏡像層,並提交

image-20210507154952005

dockerfile是面向開發的,我們以后要發布項目,做鏡像,就需要編寫dockerfile文件,這個文件十分簡單!

Docker鏡像逐漸成為了企業交付的標准,必須要掌握

步驟:開發,部署,運維…缺一不可

DockerFile:構建文件,定義了一切的步驟,源代碼

DockerImages:通過DockerFile構建生成的鏡像,最終發布和運行的產品

Docker容器:容器就是鏡像運行起來提供服務的

6.3 Docker指令

FROM  # 基礎鏡像,一切從這里開始
MAINTAINER # 鏡像是誰寫的,姓名+郵箱
RUN  # 鏡像構建的時候需要運行的命令
ADD  # 步驟:tomcat鏡像,這個tomcat壓縮包,添加內容
WORKDIR  # 鏡像的工作目錄
VOLUME  #掛載的目錄
EXPOSE  # 暴露端口配置
CMD  # 指定容器運行時的shell命令,只有最后一個生效,可被替代
ENTRYPOINT # 指定容器運行時的shell命令,可以追加命令
ONBUILD  # 當構建一個被繼承DockerFile這個還是會就會運行ONBUILD的指令,觸發指令
COPY  # 類似ADD,將我們文件拷貝到鏡像中
ENV  # 構建的時候設置環境變量

image-20210507155631163

6.4 實戰訓練

Docker Hub中99%的鏡像都是從這個基礎鏡像過來的FROM scratch,然后配置需要的軟件和配置來進行構建的

image-20210507161057482

創建一個自己的centos

# 1、編寫Dockerfile文件[root@localhost dockerfile]# cat mydockerfile-centos FROM centosMAINTAINER eric<doctor_eric@163.com>ENV MYPATH /usr/localWORKDIR $MYPATHRUN yum -y install vimRUN yum -y install net-toolsEXPOSE 80CMD echo $MYPATHCMD echo "----end----"CMD /bin/bash# 2、通過這個文件構建鏡像# 命令 docker build -f dockerfile文件路徑 -t 鏡像名:[tag]Successfully built dc4556607d09Successfully tagged mycentos:0.1# 3、測試運行

對比:之前原生的centos

image-20210507163437878

我們增加之后的鏡像

image-20210507163535804

我們可以列出本地鏡像的變更歷史:docker history 鏡像id

[root@localhost ~]# docker history dc4556607d09

image-20210507203437483

6.5 用實戰看CMD和ENTRYPOINT的區別

CMD和ENTRYPOINT的區別

通過測試可以看出:

1、CMD和ENTRYPOINT都可以執行其中的命令

2、如果在運行的時候追加命令,CMD會報錯,而ENTRYPOINT會將追加的命令拼接在其文件中的命令之后,並且會正常運行

6.6 實戰Tomcat鏡像

1、准備鏡像文件,tomcat

image-20210507212501939

2、編寫dockerfile文件,文件命名為Dockerfile,就不需要-f去指定了,build會自動尋找這個文件

FROM centos
MAINTAINER chenzhijian<952400152@qq.com>

COPY readme.txt /usr/local/readme.txt

ADD jdk-8u151-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.45.tar.gz /usr/local/

RUN yum -y install vim

ENV MYPATH /usr/local
WORKDIR $MYPATH

ENV JAVA_HOME /usr/local/jdk1.8.0_151
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.45
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.45
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin

EXPOSE 8080

CMD /usr/local/apache-tomcat-9.0.45/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.45/bin/logs/catalina.out

3、構建鏡像

[root@localhost tomcat]# docker build -t diytomcat .

4、啟動鏡像

[root@localhost tomcat]# docker run -d -p 9090:8080 --name erictomcat -v /home/eric/build/tomcat/test:/usr/local/apache-tomcat-9.0.45/webapps/test -v /home/eric/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.45/logs diytomcat

# 解釋,第一個掛載是將webapps下的test映射到本地tomcat下的test
-v /home/eric/build/tomcat/test:/usr/local/apache-tomcat-9.0.45/webapps/test

# 解釋,第二個掛載是將apache-tomcat-9.0.45下的日志映射到本地tomcat下的tomcatlogs
-v /home/eric/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.45/logs 

5、訪問測試

訪問http://192.168.58.129:9090(看自己的),可以看到成功的界面

image-20210507221203626

6、發布項目(由於做了卷掛載,我們直接在本地編寫項目就可以發布了)

在本地tomcat/test文件夾下創建WEB-INF文件夾,在WEB-INF下編寫web.xml文,在/test 下編寫index.jsp文件,再訪問http://192.168.58.129:9090/test/

<?xml version="1.0" encoding="UTF-8"?>
  <web-app xmlns="http://java.sun.com/xml/ns/javaee"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                               http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
           version="2.5">

  </web-app>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.io.*,java.util.*, javax.servlet.*" %>
<html>
<head>
<title>hello,eric</title>
</head>
<body>

<h1>顯示當前時間與日期</h1>

<%
   Date date = new Date();
   out.print( "<h2 align=\"center\">" +date.toString()+"</h2>");
%>
</body>
</html>

可以看到成功訪問的頁面

image-20210507221348837

我們以后的開發步驟:需要掌握Dockerfile的編寫,我們之后的一切都是使用docker鏡像來發布運行!

6.7 發布自己的鏡像

Docker Hub

1、地址https://hub.docker.com/

2、注冊賬號,確定這個賬號可以登錄

3、登錄服務器

# 使用docker login -u [用戶名],然后輸入密碼就可以登錄成功[root@localhost tomcat]# docker login -u ericbooneyPassword: WARNING! Your password will be stored unencrypted in /root/.docker/config.json.Configure a credential helper to remove this warning. Seehttps://docs.docker.com/engine/reference/commandline/login/#credentials-storeLogin Succeeded

4、登錄完畢后就可以提交上去鏡像,就是一步 docker push

# 這里提交出現了錯誤,因為需要在diytomcat前面加上自己docker hub的username[root@localhost tomcat]# docker push diytomcatUsing default tag: latestThe push refers to repository [docker.io/library/diytomcat]a8724fc7877e: Preparing 39a8a3af5dab: Preparing b0a26c702c9b: Preparing 7560bca74509: Preparing 2653d992f4ef: Preparing denied: requested access to the resource is denied

一定要修改diytomcat的鏡像名字為ericbooney/diytomcat,所以為了避免出現錯誤,在build的時候就要在名稱前面加上自己docker hub的用戶名

# 修改diytomcat為ericbooney/diytomcat:1.0,也盡量帶上版本號[root@localhost tomcat]# docker tag diytomcat ericbooney/diytomcat:1.0
# 再次進行提交,可以看到成功提交[root@localhost tomcat]# docker push ericbooney/diytomcat:1.0Using default tag: latestThe push refers to repository [docker.io/ericbooney/diytomcat]a8724fc7877e: Pushed 39a8a3af5dab: Pushed b0a26c702c9b: Pushing [==================================>                ]  277.3MB/406.7MB7560bca74509: Pushed 2653d992f4ef: Pushed 

阿里雲參照上面的文檔

小結

image-20210507230305076

7. Docker網絡

7.1 理解網絡

image-20210508192615122

三個網絡

問題:docker是如何處理容器網絡訪問的?

[root@localhost ~]# docker run -d -P --name tomcat01 tomcat

# 查看容器的內部網絡地址 ip addr,發現容器啟動的是否會得到一個eth0@if85 ip地址,docker分配
[root@localhost ~]# docker exec -it tomcat01 ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    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
84: eth0@if85: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

# 思考Linux能不能ping通容器內部
[root@localhost ~]# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.395 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.149 ms

# Linux可以ping通docker容器內部

原理

1、我們每啟動一個docker容器,docker就會給docker容器分配一個ip,我們只要安裝了docker,就會有一個網卡docker0橋接模式,使用的技術是evth-pair技術

再次測試ip addr,多了一對網卡

2、再啟動一個容器測試,發現又多了一對網卡

image-20210508200227586

# 我們發現這些網卡都是一對對的
# veth-pair 就是一對的虛擬設備接口,它們都是成對出現的,一段連着協議,一段彼此相連
# 正因為有這個特性veth-pair充當一個橋梁,連接各種虛擬網絡設備
# OpenStack,Docker容器之間的連接,OVS的連接,都是使用veth-pair技術

image-20210508201859735 image-20210508201859735

結論:tomcat01和tomcat02是共用的一個路由器,docker0

所有的容器在不指定網絡的情況下,都是由docker0路由的,docker會給我們的容器分配一個默認的可用ip

小結

Docker使用的是Linux橋接,宿主機中是一個Docker容器的網橋 docker0

image-20210508203719864

Docker中所有的網絡接口都是虛擬的,虛擬的轉發效率比較高(內網傳遞文件)

只要容器刪除,對應的網橋就沒了

image-20210508210544112

思考一個場景,我們編寫了一個微服務,database url=ip:,項目不重啟,數據庫ip換掉了,我們希望可以處理這個問題,可以通過名字來訪問容器?

# 如何去解決這個問題# 通過--link就可以解決問題了[root@localhost ~]# docker run -d -P --name tomcat03 --link tomcat02 tomcata8ba2a00467a9ff82520bd381973609e6a6ee64a99c1d82734d17c32693913c3[root@localhost ~]# docker exec -it tomcat03 ping tomcat02PING tomcat02 (172.17.0.3) 56(84) bytes of data.64 bytes from tomcat02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.260 ms64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.131 ms64 bytes from tomcat02 (172.17.0.3): icmp_seq=3 ttl=64 time=0.212 ms# 反向的連接可以ping通嗎,不可以[root@localhost ~]# docker exec -it tomcat02 ping tomcat03ping: tomcat03: Name or service not known

其實這個tomcat03就是本地配置了tomcat02的配置

本質探究:–link就是我們在hosts配置中增加了一個172.17.0.3 tomcat02 9f6a048802b9

我們現在 玩Docker已經不建議使用–link了!

自定義網絡!不適用於docker0!

dcoker0問題:他不支持容器名連接訪問!

7.3 自定義網絡

查看所有的docker網絡

docker network ls

image-20210508214025609

網絡模式

bridge:橋接 docker(默認,自己創建的也是使用bridge模式)

none:不配置網絡

host:和宿主機共享網絡

container:容器內網絡連通!(用的少!局限很大)

測試

# 我們直接啟動的命令 --net bridge 而這個就是我們的docker0
docker run -d -P --name tomcat01 tomcat
docker run -d -P --name tomcat01 --net bridge tomcat

# docker0特點:默認,域名不能訪問,--link可以打通連接

# 我么可以自定義一個網絡
# --driver bridge
# --subnet 192.168.0.0/16 192.168.0.2 192.168.255.255
# --gateway 192.168.0.1
[root@localhost ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
7637416b83c39b59e8af8e5b79f95f55b2cf3700017a547c3b5f2596fa637fd2

[root@localhost ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
e57926bed59d   bridge    bridge    local
b97cfa843b69   host      host      local
7637416b83c3   mynet     bridge    local
12a56a664499   none      null      local

我們自己的網絡就創建好了

image-20210508215249816

[root@localhost ~]# docker run -d -P --name tomcat-net-01 --net mynet tomcat
959374947ce0f666073cd160b0ed3f727c72f24f907754c62d377d66d48b885d
[root@localhost ~]# docker run -d -P --name tomcat-net-02 --net mynet tomcat
7b6b415d88222daf44c8542121cd7256e398fb4dd2880c74a8d4db0077245a8b
[root@localhost ~]# docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "7637416b83c39b59e8af8e5b79f95f55b2cf3700017a547c3b5f2596fa637fd2",
        "Created": "2021-05-08T21:49:56.658124832+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.0.0/16",
                    "Gateway": "192.168.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "7b6b415d88222daf44c8542121cd7256e398fb4dd2880c74a8d4db0077245a8b": {
                "Name": "tomcat-net-02",
                "EndpointID": "9c8a2979e3c1b9914fde4502298ec3aa35bd004a178d695222629fc613f482df",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            },
            "959374947ce0f666073cd160b0ed3f727c72f24f907754c62d377d66d48b885d": {
                "Name": "tomcat-net-01",
                "EndpointID": "b98aee7d07ecaea623dad5318076b32dd67bbb7a4eafa35e6d1e9605ab71f661",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

# 再次測試ping連接
[root@localhost ~]# docker exec -it tomcat-net-01 ping 192.168.0.3
PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data.
64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.177 ms
64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.130 ms
64 bytes from 192.168.0.3: icmp_seq=3 ttl=64 time=0.216 ms
64 bytes from 192.168.0.3: icmp_seq=4 ttl=64 time=0.311 ms
64 bytes from 192.168.0.3: icmp_seq=5 ttl=64 time=0.135 ms
--- 192.168.0.3 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 11ms
rtt min/avg/max/mdev = 0.130/0.193/0.311/0.068 ms

# 現在不需要使用--link也可以ping名字了!
[root@localhost ~]# docker exec -it tomcat-net-01 ping tomcat-net-02
PING tomcat-net-02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.087 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.164 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.116 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=4 ttl=64 time=0.103 ms

小結:我們自定義的網絡docker都已經幫我們維護好了對應的關系,推薦使用這個網絡

好處:

redis - 不同集群使用不同的網絡,保證集群是健康和安全的

mysql - 不同集群使用不同的網絡,保證集群是健康和安全的

網絡連通

image-20210508220421973

image-20210508220533583

# 測試打通 tomcat01 - mynet
[root@localhost ~]# docker network connect mynet tomcat01

# 連通之后將tomcat01放到了mynet網絡下

# 一個容器兩個ip地址 阿里雲服務:公網ip 私網ip

image-20210508220750892

# tomcat01 和tomcat-net-01是打通的
[root@localhost ~]# docker exec -it tomcat01 ping tomcat-net-01
PING tomcat-net-01 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.099 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.139 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=3 ttl=64 time=0.165 ms

# tomcat02 和tomcat-net-01是沒打通的
[root@localhost ~]# docker exec -it tomcat02 ping tomcat-net-01
ping: tomcat-net-01: Name or service not known

結論:如果需要跨網絡操作別人,就需要使用docker network connect進行連通

7.4 實戰:部署Redis集群

image-20210508221715222

shell腳本

# 創建網卡
docker network create redis --subnet 172.38.0.0/16

# 通過腳本創建六個redis配置
for port in $(seq 1 6); \
do \
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
cat << EOF >/mydata/redis/node-${port}/conf/redis.conf
port 6379
bind 0.0.0.0
cluster-enabled yes 
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done

# 運行6個節點
docker run -p 6371:6379 -p 16371:16379 --name redis-1 \
-v /mydata/redis/node-1/data:/data \
-v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

docker run -p 6372:6379 -p 16372:16379 --name redis-2 \
-v /mydata/redis/node-2/data:/data \
-v /mydata/redis/node-2/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.12 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

docker run -p 6373:6379 -p 16373:16379 --name redis-3 \
-v /mydata/redis/node-3/data:/data \
-v /mydata/redis/node-3/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.13 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

docker run -p 6374:6379 -p 16374:16379 --name redis-4 \
-v /mydata/redis/node-4/data:/data \
-v /mydata/redis/node-4/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.14 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

docker run -p 6375:6379 -p 16375:16379 --name redis-5 \
-v /mydata/redis/node-5/data:/data \
-v /mydata/redis/node-5/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.15 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

docker run -p 6376:6379 -p 16376:16379 --name redis-6 \
-v /mydata/redis/node-6/data:/data \
-v /mydata/redis/node-6/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.16 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

# 創建集群
/data # redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 172.38.0.15:6379 to 172.38.0.11:6379
Adding replica 172.38.0.16:6379 to 172.38.0.12:6379
Adding replica 172.38.0.14:6379 to 172.38.0.13:6379
M: ebfbbc88a83fa84c3d73fe048fc37ab82841fa0e 172.38.0.11:6379
   slots:[0-5460] (5461 slots) master
M: ed7bac9d22ce436c650f9a51c3ae7a3aa84a7537 172.38.0.12:6379
   slots:[5461-10922] (5462 slots) master
M: 2f1fdb553165c31c599f5cdbac5a42fa15901602 172.38.0.13:6379
   slots:[10923-16383] (5461 slots) master
S: d2edadd37c2b243ffa3a13ac7bb352062160f4b8 172.38.0.14:6379
   replicates 2f1fdb553165c31c599f5cdbac5a42fa15901602
S: 98bec4772bd3cdc7335111f75bc3f6b6ad2fae26 172.38.0.15:6379
   replicates ebfbbc88a83fa84c3d73fe048fc37ab82841fa0e
S: 6e8dda893836d8182af1a7cbe0ff71b32d0743ef 172.38.0.16:6379
   replicates ed7bac9d22ce436c650f9a51c3ae7a3aa84a7537
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
....
>>> Performing Cluster Check (using node 172.38.0.11:6379)
M: ebfbbc88a83fa84c3d73fe048fc37ab82841fa0e 172.38.0.11:6379
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
S: 98bec4772bd3cdc7335111f75bc3f6b6ad2fae26 172.38.0.15:6379
   slots: (0 slots) slave
   replicates ebfbbc88a83fa84c3d73fe048fc37ab82841fa0e
S: d2edadd37c2b243ffa3a13ac7bb352062160f4b8 172.38.0.14:6379
   slots: (0 slots) slave
   replicates 2f1fdb553165c31c599f5cdbac5a42fa15901602
S: 6e8dda893836d8182af1a7cbe0ff71b32d0743ef 172.38.0.16:6379
   slots: (0 slots) slave
   replicates ed7bac9d22ce436c650f9a51c3ae7a3aa84a7537
M: 2f1fdb553165c31c599f5cdbac5a42fa15901602 172.38.0.13:6379
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
M: ed7bac9d22ce436c650f9a51c3ae7a3aa84a7537 172.38.0.12:6379
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

docker搭建redis集群完成

image-20210508230802545

我們使用了docker后,所有技術都會變得更加方便

7.5 SpringBoot微服務打包Dockers鏡像

1、架構springboot項目

2、打包應用

image-20210509192427051

3、編寫dockerfile(idea中安裝docker插件比較方便)

image-20210509192508209

4、將jar包和Dockerfile文件傳輸到Linux服務器上

image-20210509192704027

5、構建鏡像eric666

image-20210509192818677

6、發布運行

image-20210509192928795

7、測試,可以看到成功打印出"hello,kungshen"

image-20210509193056390

以后我們使用了Docker之后,給別人交互的就是一個鏡像即可!

筆記參考:https://blog.csdn.net/weixin_43591980/article/details/106272050

筆記參考: https://blog.csdn.net/czj981014/article/details/116766286


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM