Docker入門到精通


一.Docker入門

1. Docker 為什么會出現

在這里插入圖片描述

在這里插入圖片描述

2. Docker的歷史

在這里插入圖片描述

3. Docker最新超詳細版教程通俗易懂

在這里插入圖片描述

 

4. 虛擬化技術和容器化技術對比

4.1. 虛擬化技術的缺點

 

  • 資源占用十分多

冗余步驟多

啟動很慢

在這里插入圖片描述

2.2. 容器化技術

    比較Docker和虛擬化技術的不同
        傳統虛擬機, 虛擬出一條硬件,運行一個完整的操作系統,然后在這個系統上安裝和運行軟件
        容器內的應用直接運行在宿主機的內部,容器是沒有自己的內核的,也沒有虛擬硬件,所以輕便
        每個容器間是相互隔離的,每個容器內都有一個屬於自己的文件系統,互不影響
    應用更快速的交互和部署
        傳統:一堆幫助文檔,安裝程序
        Docker: 打包鏡像發布測試,一鍵運行
    更便捷的升級和擴縮容
    更簡的系統運維
    更高效的計算資源利用

4.3. DevOps

 

 


3. 名詞解釋

    鏡像(image)
        Docker鏡像就好比是一個模板,可以通過這個模板來創建容器服務,tomcat鏡像 ===> run ===> tomcat01容器, 通過這個鏡像可以創建多個容器(最終服務運行或者項目運行就是在容器中的)
    容器(container)
        Docker利用容器技術,獨立運行一個或者一組應用, 通過鏡像來創建的
        啟動,停止,刪除,基本命令!
        就目前可以把這個容器理解為一個建議的linux系統
    倉庫(repository)
        存放鏡像的地方
        Docker Hub(默認是國外的)
        阿里雲,,,都有容器服務(配置鏡像加速!)

4. 阿里雲鏡像加速

    登錄阿里雲服務器,找到容器鏡像服務
    設置Registry登錄密碼
    找到鏡像加速器
    配置使用
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://pi9dpp60.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
4.2 安裝docker
卸載舊版本

較舊的 Docker 版本稱為 docker 或 docker-engine 。如果已安裝這些程序,請卸載它們以及相關的依賴項。

$ sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
安裝 Docker Engine-Community
使用 Docker 倉庫進行安裝

在新主機上首次安裝 Docker Engine-Community 之前,需要設置 Docker 倉庫。之后,您可以從倉庫安裝和更新 Docker。

設置倉庫

安裝所需的軟件包。yum-utils 提供了 yum-config-manager ,並且 device mapper 存儲驅動程序需要 device-mapper-persistent-data 和 lvm2。

$ sudo yum install -y yum-utils \
  device-mapper-persistent-data \
  lvm2

使用以下命令來設置穩定的倉庫。
使用官方源地址(比較慢)

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

可以選擇國內的一些源地址:
阿里雲

$ sudo yum-config-manager \
    --add-repo \
    http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
清華大學源

$ sudo yum-config-manager \
    --add-repo \
    https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo

 
安裝 Docker Engine-Community

安裝最新版本的 Docker Engine-Community 和 containerd,或者轉到下一步安裝特定版本:

$ sudo yum install docker-ce docker-ce-cli containerd.io

Docker 安裝完默認未啟動。並且已經創建好 docker 用戶組,但該用戶組下沒有用戶。

要安裝特定版本的 Docker Engine-Community,請在存儲庫中列出可用版本,然后選擇並安裝:

1、列出並排序您存儲庫中可用的版本。此示例按版本號(從高到低)對結果進行排序。

$ yum list docker-ce --showduplicates | sort -r

docker-ce.x86_64  3:18.09.1-3.el7                     docker-ce-stable
docker-ce.x86_64  3:18.09.0-3.el7                     docker-ce-stable
docker-ce.x86_64  18.06.1.ce-3.el7                    docker-ce-stable
docker-ce.x86_64  18.06.0.ce-3.el7                    docker-ce-stable

2、通過其完整的軟件包名稱安裝特定版本,該軟件包名稱是軟件包名稱(docker-ce)加上版本字符串(第二列),從第一個冒號(:)一直到第一個連字符,並用連字符(-)分隔。例如:docker-ce-18.09.1。

$ sudo yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io

啟動 Docker。

$ sudo systemctl start docker

通過運行 hello-world 映像來驗證是否正確安裝了 Docker Engine-Community 。

$ sudo docker run hello-world

5. 底層原理

  • HelloWorld鏡像

  • 底層原理

    Docker Engine是一個客戶端-服務器應用程序,具有以下主要組件:

        一個服務器,它是一種長期運行的程序,稱為守護進程(dockerd命令)
        一個REST API,它指定程序可以用來與守護進程對話並指示它做什么的接口。

    Docker是一個Client Server結構的系統,Docker守護進程運行在主機上,然后通過Socket連接從客戶 端訪問,守護進程從客戶端接受命令並管理運行在主機上的容器。容器,是一個運行時環境就是我們所說的集裝箱。

     

     

     為什么Docker比Vm快

        docker有着比虛擬機更少的抽象層。由於docker不需要Hypervisor實現硬件資源虛擬化,*運行在docker容器上的程序直接使用的都是實際物理機的硬件資源*。因此在CPU、內存利用率上docker將會在效率上有明顯優勢。**
        docker利用的是宿主機的內核,而不需要Guest OS。因此,當新建一個 容器時,docker不需要和虛擬機一樣重新加載一個操作系統內核。仍而避免引尋、加載操作系統內核返個比較費時費資源的過程,當新建一個虛擬機時,虛擬機軟件需要加載GuestOS,返個新建過程是分鍾級別的。而docker由於直接利用宿主機的操作系統,則省略了返個過程,因此新建一個docker容器只需要幾秒鍾。

     

     

    二,Docker基本命令

    1. Docker的常用命令

  •  

    幫助命令 

docker version  # docker版本信息
docker info     # 系統級別的信息,包括鏡像和容器的數量
docker 命令 --help

鏡像命令

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

[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              bf756fb1ae65        7 months ago        13.3kB
 
# 解釋
REPOSITORY      # 鏡像的倉庫
TAG             # 鏡像的標簽
IMAGE ID        # 鏡像的ID
CREATED         # 鏡像的創建時間
SIZE            # 鏡像的大小
 
# 可選項
--all , -a      # 列出所有鏡像
--quiet , -q    # 只顯示鏡像的id

docker search 查找鏡像

    NAME                              DESCRIPTION                                     STARS               OFFICIAL         AUTOMATED
    mysql                             MySQL is a widely used, open-source relation…   9822                [OK]                
    mariadb                           MariaDB is a community-developed fork of MyS…   3586                [OK]                
    mysql/mysql-server                Optimized MySQL Server Docker images. Create…   719                                     [OK]
     
    # 可選項
    --filter=STARS=3000     # 搜素出來的鏡像就是STARS大於3000的
     
    [root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker search mysql --filter=STARS=3000
    NAME                DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
    mysql               MySQL is a widely used, open-source relation…   9822                [OK]                
    mariadb             MariaDB is a community-developed fork of MyS…   3586                [OK]     

docker pull 下拉鏡像

    # 下載鏡像,docker pull 鏡像名[:tag]
    [root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker pull mysql
    Using default tag: latest           # 如果不寫tag,默認就是latest
    latest: Pulling from library/mysql
    bf5952930446: Pull complete         # 分層下載,dockerimages的核心,聯合文件系統
    8254623a9871: Pull complete
    938e3e06dac4: Pull complete
    ea28ebf28884: Pull complete
    f3cef38785c2: Pull complete
    894f9792565a: Pull complete
    1d8a57523420: Pull complete
    6c676912929f: Pull complete
    ff39fdb566b4: Pull complete
    fff872988aba: Pull complete
    4d34e365ae68: Pull complete
    7886ee20621e: Pull complete
    Digest: sha256:c358e72e100ab493a0304bda35e6f239db2ec8c9bb836d8a427ac34307d074ed     # 簽名
    Status: Downloaded newer image for mysql:latest
    docker.io/library/mysql:latest      # 真實地址
     
    # 等價於
    docker pull mysql
    docker pull docker.io/library/mysql:latest
     
    # 指定版本下載
    [root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker pull mysql:5.7
    5.7: Pulling from library/mysql
    bf5952930446: Already exists
    8254623a9871: Already exists
    938e3e06dac4: Already exists
    ea28ebf28884: Already exists
    f3cef38785c2: Already exists
    894f9792565a: Already exists
    1d8a57523420: Already exists
    5f09bf1d31c1: Pull complete
    1b6ff254abe7: Pull complete
    74310a0bf42d: Pull complete
    d398726627fd: Pull complete
    Digest: sha256:da58f943b94721d46e87d5de208dc07302a8b13e638cd1d24285d222376d6d84
    Status: Downloaded newer image for mysql:5.7
    docker.io/library/mysql:5.7
     
    # 查看本地鏡像
    [root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker images
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    mysql               5.7                 718a6da099d8        6 days ago          448MB
    mysql               latest              0d64f46acfd1        6 days ago          544MB
    hello-world         latest              bf756fb1ae65        7 months ago        13.3kB

docker rmi 刪除鏡像

    [root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker rmi -f IMAGE ID                        # 刪除指定鏡像
    [root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker rmi -f IMAGE ID1 IMAGE ID2 IMAGE ID3   # 刪除多個鏡像
    [root@iZ2zeg4ytp0whqtmxbsqiiZ ~]#  docker rmi -f $(docker images -aq)           # 刪除所有鏡像

容器命令

說明: 我們有了鏡像才可創建容器,linux,下載一個centos鏡像來測試學習

docker pull centos

新建容器並啟動

    docker run [可選參數] image
     
    # 參數說明
    --name=“Name”   容器名字    tomcat01    tomcat02    用來區分容器
    -d      后台方式運行
    -it     使用交互方式運行,進入容器查看內容
    -p      指定容器的端口     -p 8080:8080
        -p  ip:主機端口:容器端口
        -p  主機端口:容器端口(常用)
        -p  容器端口
        容器端口
    -p      隨機指定端口
     
     
    # 測試,啟動並進入容器
    [root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker run -it centos /bin/bash
    [root@74e82b7980e7 /]# ls   # 查看容器內的centos,基礎版本,很多命令是不完善的
    bin  etc   lib    lost+found  mnt  proc  run   srv  tmp  var
    dev  home  lib64  media       opt  root  sbin  sys  usr
     
    # 從容器中退回主機
    [root@77969f5dcbf9 /]# exit
    exit
    [root@iZ2zeg4ytp0whqtmxbsqiiZ /]# ls
    bin   dev  fanfan  lib    lost+found  mnt  proc  run   srv  tmp  var
    boot  etc  home    lib64  media       opt  root  sbin  sys  usr

列出所有的運行的容器

    # docker ps 命令
            # 列出當前正在運行的容器
    -a      # 列出正在運行的容器包括歷史容器
    -n=?    # 顯示最近創建的容器
    -q      # 只顯示當前容器的編號
     
    [root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker ps
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    [root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker ps -a
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
    77969f5dcbf9        centos              "/bin/bash"         5 minutes ago       Exited (0) 5 minutes ago                       xenodochial_bose
    74e82b7980e7        centos              "/bin/bash"         16 minutes ago      Exited (0) 6 minutes ago                       silly_cori
    a57250395804        bf756fb1ae65        "/hello"            7 hours ago         Exited (0) 7 hours ago                         elated_nash
    392d674f4f18        bf756fb1ae65        "/hello"            8 hours ago         Exited (0) 8 hours ago                         distracted_mcnulty
    571d1bc0e8e8        bf756fb1ae65        "/hello"            23 hours ago        Exited (0) 23 hours ago                        magical_burnell
     
    [root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker ps -qa
    77969f5dcbf9
    74e82b7980e7
    a57250395804
    392d674f4f18
    571d1bc0e8e8

退出容器

    exit            # 直接退出容器並關閉
    Ctrl + P + Q    # 容器不關閉退出

刪除容器

    docker rm -f 容器id                       # 刪除指定容器
    docker rm -f $(docker ps -aq)       # 刪除所有容器
    docker ps -a -q|xargs docker rm -f  # 刪除所有的容器

啟動和停止容器的操作

    docker start 容器id           # 啟動容器
    docker restart 容器id         # 重啟容器
    docker stop 容器id            # 停止當前正在運行的容器
    docker kill 容器id            # 強制停止當前的容器

常用的其他命令

后台啟動容器

    # 命令 docker run -d 鏡像名
    [root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker run -d centos
     
    # 問題 docker ps, 發現centos停止了
     
    # 常見的坑, docker 容器使用后台運行, 就必須要有一個前台進程,docker發現沒有應用,就會自動停止
    # nginx, 容器啟動后,發現自己沒有提供服務,就會立即停止,就是沒有程序了

查看日志

    docker logs -tf --tail number 容器id
     
    [root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker logs -tf --tail 1 8d1621e09bff
    2020-08-11T10:53:15.987702897Z [root@8d1621e09bff /]# exit      # 日志輸出
     
    # 自己編寫一段shell腳本
    [root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker run -d centos /bin/sh -c "while true;do echo xiaofan;sleep 1;done"
    a0d580a21251da97bc050763cf2d5692a455c228fa2a711c3609872008e654c2
     
    [root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
    a0d580a21251        centos              "/bin/sh -c 'while t…"   3 seconds ago       Up 1 second                             lucid_black
     
    # 顯示日志
    -tf                 # 顯示日志
    --tail number       # 顯示日志條數
    [root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker logs -tf --tail 10 a0d580a21251

查看容器中進程信息ps

    # 命令 docker top 容器id
    [root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker top df358bc06b17
    UID                 PID                 PPID                C                   STIME               TTY     
    root                28498               28482               0                   19:38               ?      

查看鏡像的元數據

    # 命令
    docker inspect 容器id
     
    [root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker inspect df358bc06b17
    [
        {
            "Id": "df358bc06b17ef44f215d35d9f46336b28981853069a3739edfc6bd400f99bf3",
            "Created": "2020-08-11T11:38:34.935048603Z",
            "Path": "/bin/bash",
            "Args": [],
            "State": {
                "Status": "running",
                "Running": true,
                "Paused": false,
                "Restarting": false,
                "OOMKilled": false,
                "Dead": false,
                "Pid": 28498,
                "ExitCode": 0,
                "Error": "",
                "StartedAt": "2020-08-11T11:38:35.216616071Z",
                "FinishedAt": "0001-01-01T00:00:00Z"
            },
            "Image": "sha256:0d120b6ccaa8c5e149176798b3501d4dd1885f961922497cd0abef155c869566",
            "ResolvConfPath": "/var/lib/docker/containers/df358bc06b17ef44f215d35d9f46336b28981853069a3739edfc6bd400f99bf3/resolv.conf",
            "HostnamePath": "/var/lib/docker/containers/df358bc06b17ef44f215d35d9f46336b28981853069a3739edfc6bd400f99bf3/hostname",
            "HostsPath": "/var/lib/docker/containers/df358bc06b17ef44f215d35d9f46336b28981853069a3739edfc6bd400f99bf3/hosts",
            "LogPath": "/var/lib/docker/containers/df358bc06b17ef44f215d35d9f46336b28981853069a3739edfc6bd400f99bf3/df358bc06b17ef44f215d35d9f46336b28981853069a3739edfc6bd400f99bf3-json.log",
            "Name": "/hungry_heisenberg",
            "RestartCount": 0,
            "Driver": "overlay2",
            "Platform": "linux",
            "MountLabel": "",
            "ProcessLabel": "",
            "AppArmorProfile": "",
            "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/5af8a2aadbdba9e1e066331ff4bce56398617710a22ef906f9ce4d58bde2d360-init/diff:/var/lib/docker/overlay2/62926d498bd9d1a6684bb2f9920fb77a2f88896098e66ef93c4b74fcb19f29b6/diff",
                    "MergedDir": "/var/lib/docker/overlay2/5af8a2aadbdba9e1e066331ff4bce56398617710a22ef906f9ce4d58bde2d360/merged",
                    "UpperDir": "/var/lib/docker/overlay2/5af8a2aadbdba9e1e066331ff4bce56398617710a22ef906f9ce4d58bde2d360/diff",
                    "WorkDir": "/var/lib/docker/overlay2/5af8a2aadbdba9e1e066331ff4bce56398617710a22ef906f9ce4d58bde2d360/work"
                },
                "Name": "overlay2"
            },
            "Mounts": [],
            "Config": {
                "Hostname": "df358bc06b17",
                "Domainname": "",
                "User": "",
                "AttachStdin": true,
                "AttachStdout": true,
                "AttachStderr": true,
                "Tty": true,
                "OpenStdin": true,
                "StdinOnce": true,
                "Env": [
                    "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
                ],
                "Cmd": [
                    "/bin/bash"
                ],
                "Image": "centos",
                "Volumes": null,
                "WorkingDir": "",
                "Entrypoint": null,
                "OnBuild": null,
                "Labels": {
                    "org.label-schema.build-date": "20200809",
                    "org.label-schema.license": "GPLv2",
                    "org.label-schema.name": "CentOS Base Image",
                    "org.label-schema.schema-version": "1.0",
                    "org.label-schema.vendor": "CentOS"
                }
            },
            "NetworkSettings": {
                "Bridge": "",
                "SandboxID": "4822f9ac2058e8415ebefbfa73f05424fe20cc8280a5720ad3708fa6e80cdb08",
                "HairpinMode": false,
                "LinkLocalIPv6Address": "",
                "LinkLocalIPv6PrefixLen": 0,
                "Ports": {},
                "SandboxKey": "/var/run/docker/netns/4822f9ac2058",
                "SecondaryIPAddresses": null,
                "SecondaryIPv6Addresses": null,
                "EndpointID": "5fd269c0a28227241e40cd30658e3ffe8ad6cc3e6514917c867d89d36a31d605",
                "Gateway": "172.17.0.1",
                "GlobalIPv6Address": "",
                "GlobalIPv6PrefixLen": 0,
                "IPAddress": "172.17.0.2",
                "IPPrefixLen": 16,
                "IPv6Gateway": "",
                "MacAddress": "02:42:ac:11:00:02",
                "Networks": {
                    "bridge": {
                        "IPAMConfig": null,
                        "Links": null,
                        "Aliases": null,
                        "NetworkID": "30d6017888627cb565618b1639fecf8fc97e1ae4df5a9fd5ddb046d8fb02b565",
                        "EndpointID": "5fd269c0a28227241e40cd30658e3ffe8ad6cc3e6514917c867d89d36a31d605",
                        "Gateway": "172.17.0.1",
                        "IPAddress": "172.17.0.2",
                        "IPPrefixLen": 16,
                        "IPv6Gateway": "",
                        "GlobalIPv6Address": "",
                        "GlobalIPv6PrefixLen": 0,
                        "MacAddress": "02:42:ac:11:00:02",
                        "DriverOpts": null
                    }
                }
            }
        }
    ]
    [root@iZ2zeg4ytp0whqtmxbsqiiZ /]#
     

進入當前正在運行的容器

    # 我們通常容器使用后台方式運行的, 需要進入容器,修改一些配置
     
    # 命令
    docker exec -it 容器id /bin/bash
     
    # 測試
    [root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker exec -it df358bc06b17 /bin/bash
    [root@df358bc06b17 /]# ls       
    bin  etc   lib    lost+found  mnt  proc  run   srv  tmp  var
    dev  home  lib64  media       opt  root  sbin  sys  usr
    [root@df358bc06b17 /]# ps -ef
    UID        PID  PPID  C STIME TTY          TIME CMD
    root         1     0  0 Aug11 pts/0    00:00:00 /bin/bash
    root        29     0  0 01:06 pts/1    00:00:00 /bin/bash
    root        43    29  0 01:06 pts/1    00:00:00 ps -ef
     
    # 方式二
    docker attach 容器id
     
    # docker exec       # 進入容器后開啟一個新的終端,可以在里面操作
    # docker attach     # 進入容器正在執行的終端,不會啟動新的進程

從容器中拷貝文件到主機

    docker cp 容器id:容器內路徑    目的地主機路徑
     
    [root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker cp 7af535f807e0:/home/Test.java /home

三,Docker部署軟件實戰
1.Docker部署軟件實戰
Docker安裝Nginx

    # 1. 搜索鏡像 search 建議去docker hub搜索,可以看到幫助文檔
    # 2. 下載鏡像 pull
    # 3. 運行測試
    [root@iZ2zeg4ytp0whqtmxbsqiiZ home]# docker images
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    centos              latest              0d120b6ccaa8        32 hours ago        215MB
    nginx               latest              08393e824c32        7 days ago          132MB
     
    # -d 后台運行
    # -name 給容器命名
    # -p 宿主機端口:容器內部端口
    [root@iZ2zeg4ytp0whqtmxbsqiiZ home]# docker run -d --name nginx01 -p 3344:80 nginx  # 后台方式啟動啟動鏡像
    fe9dc33a83294b1b240b1ebb0db9cb16bda880737db2c8a5c0a512fc819850e0
    [root@iZ2zeg4ytp0whqtmxbsqiiZ home]# docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
    fe9dc33a8329        nginx               "/docker-entrypoint.…"   4 seconds ago       Up 4 seconds        0.0.0.0:3344->80/tcp   nginx01
    [root@iZ2zeg4ytp0whqtmxbsqiiZ home]# curl localhost:3344    # 本地訪問測試
     
    # 進入容器
    [root@iZ2zeg4ytp0whqtmxbsqiiZ home]# docker exec -it nginx01 /bin/bash
    root@fe9dc33a8329:/# whereis nginx
    nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
    root@fe9dc33a8329:/# cd /etc/nginx/
    root@fe9dc33a8329:/etc/nginx# ls
    conf.d      koi-utf  mime.types  nginx.conf   uwsgi_params
    fastcgi_params  koi-win  modules     scgi_params  win-utf

端口暴露概念

在這里插入圖片描述

2. Docker安裝Tomcat

# 官方的使用
docker run -it --rm tomcat:9.0
 
# 我們之前的啟動都是后台的,停止了容器之后, 容器還是可以查到,docker run -it --rm 一般用來測試,用完就刪
 
# 下載再啟動
docker pull tomcat
 
# 啟動運行
docker run -d -p 3344:8080 --name tomcat01 tomcat
 
# 測試訪問沒有問題
 
# 進入容器
docker exec -it tomcat01 /bin/bash
 
# 發現問題:1.linux命令少了, 2. webapps下內容為空,阿里雲凈吸納過默認是最小的鏡像,所有不必要的都剔除了,保證最小可運行環境即可

3. Docker部署es + kibana

    # es 暴露的端口很多
    # es 十分的耗內存
    # es 的數據一般需要放置到安全目錄! 掛載
    # --net somenetwork 網絡配置
     
    # 啟動elasticsearch
    docker run -d --name elasticsearch --net somenetwork -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2
     
    [root@iZ2zeg4ytp0whqtmxbsqiiZ home]# docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2
    a920894a940b354d3c867079efada13d96cf9138712c76c8dea58fabd9c7e96f
     
    # 啟動了linux就卡主了,docker stats 查看cpu狀態
     
    # 測試一下es成功了
    [root@iZ2zeg4ytp0whqtmxbsqiiZ home]# curl localhost:9200
    {
      "name" : "a920894a940b",
      "cluster_name" : "docker-cluster",
      "cluster_uuid" : "bxE1TJMEThKgwmk7Aa3fHQ",
      "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"
    }
     
     
    # 增加內存限制,修改配置文件 -e 環境配置修改
    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

可視化

    portainer(先用這個)

    docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
     
    # 測試
    [root@iZ2zeg4ytp0whqtmxbsqiiZ home]# curl localhost:8088
    <!DOCTYPE html
    ><html lang="en" ng-app="portainer">
     
    # 外網訪問 http://ip:8088
     

 

 

 



    Rancher(CI/CD再用)

四.Docker原理

 

    特點

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

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

    commit鏡像

    docker commit 提交容器成為一個新的版本
     
    # 命令和git 原理類似
    docker commit -m="提交的描述信息" -a="作者" 容器id 目標鏡像名:[TAG]
     
    docker commit -a="xiaofan" -m="add webapps app" d798a5946c1f tomcat007:1.0
     

實戰測試

    # 1. 啟動一個默認的tomcat
    # 2. 發現這個默認的tomcat是沒有webapps應用, 鏡像的原因,官方鏡像默認webapps下面是沒有內容的
    # 3. 我自己拷貝進去了基本的文件
    # 4. 將我們操作過的容器通過commit提價為一個鏡鏡像!我們以后就使用我們自己制作的鏡像了

五,容器數據卷
1. 容器數據卷
1.1. docker的理解回顧

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

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

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

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

這就是卷技術,目錄的掛載,將我們容器內的目錄掛載到linux目錄上面!

**總結: **容器的持久化和同步操作!容器間數據也是可以共享的!
1.2. 使用數據卷

    方式一:直接使用命令來掛載 -v

    docker run -it -v 主機目錄:容器目錄
     
    [root@iZ2zeg4ytp0whqtmxbsqiiZ home]# docker run -it -v /home/ceshi:/home centos /bin/bash

 

 

 

 

 

 

再來測試(測試通過)

    停止容器

    主機上修改文件

    啟動容器

    容器內的數據依舊是同步的!

1.3. 實戰:安裝MySQL

思考:MySQL的數據持久化的問題!

    # 獲取鏡像
    [root@iZ2zeg4ytp0whqtmxbsqiiZ home]# 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@iZ2zeg4ytp0whqtmxbsqiiZ home]# docker run -d -p 3344:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
    9552bf4eb2b69a2ccd344b5ba5965da4d97b19f2e1a78626ac1f2f8d276fc2ba
     
    # 啟動成功之后,我們在本地使用navicat鏈接測試一下
    # navicat鏈接到服務器的3344 --- 3344 和 容器的3306映射,這個時候我們就可以連接上mysql嘍!
     
    # 在本地測試創建一個數據庫,查看下我們的路徑是否ok!

 

 

 


1.4. 匿名和具名掛載
# 匿名掛載
-v 容器內路徑
docker run -d -P --name nginx01 -v /etc/nginx nginx     # -P 隨機指定端口
 
# 查看所有volume的情況
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker volume ls
DRIVER              VOLUME NAME
local               561b81a03506f31d45ada3f9fb7bd8d7c9b5e0f826c877221a17e45d4c80e096
local               36083fb6ca083005094cbd49572a0bffeec6daadfbc5ce772909bb00be760882
 
# 這里發現,這種情況就是匿名掛載,我們在-v 后面只寫了容器內的路徑,沒有寫容器外的路徑!
 
# 具名掛載
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
26da1ec7d4994c76e80134d24d82403a254a4e1d84ec65d5f286000105c3da17
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                   NAMES
26da1ec7d499        nginx               "/docker-entrypoint.…"   3 seconds ago       Up 2 seconds        0.0.0.0:32769->80/tcp   nginx02
486de1da03cb        nginx               "/docker-entrypoint.…"   3 minutes ago       Up 3 minutes        0.0.0.0:32768->80/tcp   nginx01
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker volume ls
DRIVER              VOLUME NAME
local               561b81a03506f31d45ada3f9fb7bd8d7c9b5e0f826c877221a17e45d4c80e096
local               36083fb6ca083005094cbd49572a0bffeec6daadfbc5ce772909bb00be760882
local               juming-nginx
 
# 通過-v 卷名:容器內的路徑
# 查看一下這個卷
# docker volume inspect juming-nginx
 
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker volume inspect juming-nginx
[
  {
      "CreatedAt": "2020-08-12T18:15:21+08:00",
      "Driver": "local",
      "Labels": null,
      "Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",
      "Name": "juming-nginx",
      "Options": null,
      "Scope": "local"
  }
]

所有docker容器內的卷,沒有指定目錄的情況下都是在/var/lib/docker/volumes/xxxxx/_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就說明這個路徑只能通過宿主機來操作,容器內容無法操作

六,DockerFile
初始DockerFile

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

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

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

 

 

 # 啟動自己的容器

 

 

 

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

在這里插入圖片描述

docker inspect 容器id

 

 

 

測試一下剛才的文件是否同步到主機上了!

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

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

數據卷容器

多個mysql同步數據!

在這里插入圖片描述

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

 

 

 

 多個mysql實現數據共享

    [root@iZ2zeg4ytp0whqtmxbsqiiZ home]# docker run -d -p 3344:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
     
    [root@iZ2zeg4ytp0whqtmxbsqiiZ home]# docker run -d -p 3344:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7

結論

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

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

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

構建步驟

1. 編寫一個dockerFile文件

2.docker build 構建成為一個鏡像

3. docker run 運行鏡像

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

查看嬰喜愛官方是怎么做的?

 

 

 

 

 

 

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

官方既然可以制作鏡像,能我們一樣可以!
DockerFile的構建過程

基礎知識:

    每個保留關鍵字(指令)都是必須大寫字母
    執行從上到下順序執行
    # 表示注釋
    每個指令都會創建提交一個新的鏡像層,並提交!


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

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

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

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

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

Docker容器:容器就是鏡像運行起來提供服務器
DockerFile指令說明

 

 

 

 

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

創建一個自己的centos

    # 1. 編寫Dockerfile的文件
    [root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# cat mydockerfile-centos
    FROM centos
    MAINTAINER xiaofan<594042358@qq.com>
     
    ENV MYPATH /usr/local
    WORKDIR $MYPATH     # 鏡像的工作目錄
     
    RUN yum -y install vim
    RUN yum -y install net-tools
     
    EXPOSE 80
     
    CMD echo $MYPATH
    CMD echo "---end---"
    CMD /bin/bash
    # 2. 通過這個文件構建鏡像
    # 命令 docker build -f dockerfile文件路徑 -t 鏡像名:[tag] .
     
    [root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# docker build -f mydockerfile-centos -t mycentos:0.1 .
     
    Successfully built d2d9f0ea8cb2
    Successfully tagged mycentos:0.1

 

 

 我們可以列出本地進行的變更歷史

 

 

     CMD 和ENTRYPOINT區別

    CMD         # 指定這個容器啟動的時候要運行的命令,只有最后一個會生效可被替代
    ENTRYPOINT      # 指定這個容器啟動的時候要運行的命令, 可以追加命令

測試CMD

    # 1. 編寫dockerfile文件
    [root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# vim dockerfile-cmd-test
    FROM centos
    CMD ["ls", "-a"]
     
    # 2. 構建鏡像
    [root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# docker build -f dockerfile-cmd-test -t cmdtest .
     
    # 3. run運行, 發現我們的ls -a 命令生效
    [root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# docker run ebe6a52bb125
    .
    ..
    .dockerenv
    bin
    dev
    etc
    home
    lib
    lib64
     
    # 想追加一個命令 -l 變成 ls -al
    [root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# docker run ebe6a52bb125 -l
    docker: Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"-l\": executable file not found in $PATH": unknown.
    [root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# docker run ebe6a52bb125 ls -l
     
    # cmd的情況下 -l替換了CMD["ls", "-a"]命令, -l不是命令,所以報錯了

測試ENTRYPOINT

    # 1. 編寫dockerfile文件
    [root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# vim dockerfile-entrypoint-test
    FROM centos
    ENTRYPOINT ["ls", "-a"]
     
    # 2. 構建文件
    [root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# docker build -f dockerfile-entrypoint-test -t entrypoint-test .
     
    # 3. run運行 發現我們的ls -a 命令同樣生效
    [root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# docker run entrypoint-test
    .
    ..
    .dockerenv
    bin
    dev
    etc
    home
    lib
     
    # 4. 我們的追加命令, 是直接拼接到ENTRYPOINT命令的后面的!
    [root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# docker run entrypoint-test -l
    total 56
    drwxr-xr-x  1 root root 4096 Aug 13 07:52 .
    drwxr-xr-x  1 root root 4096 Aug 13 07:52 ..
    -rwxr-xr-x  1 root root    0 Aug 13 07:52 .dockerenv
    lrwxrwxrwx  1 root root    7 May 11  2019 bin -> usr/bin
    drwxr-xr-x  5 root root  340 Aug 13 07:52 dev
    drwxr-xr-x  1 root root 4096 Aug 13 07:52 etc
    drwxr-xr-x  2 root root 4096 May 11  2019 home
    lrwxrwxrwx  1 root root    7 May 11  2019 lib -> usr/lib
    lrwxrwxrwx  1 root root    9 May 11  2019 lib64 -> usr/lib64
    drwx------  2 root root 4096 Aug  9 21:40 lost+found
     

 
七,Dockerfile制作tomcat鏡像
Dockerfile制作tomcat鏡像

    准備鏡像文件 tomcat壓縮包,jdk的壓縮包!

 

 

     編寫Dockerfile文件,官方命名Dockerfile, build會自動尋找這個文件,就不需要-f指定了!

    [root@iZ2zeg4ytp0whqtmxbsqiiZ tomcat]# cat Dockerfile
    FROM centos
    MAINTAINER xiaofan<594042358@qq.com>
     
    COPY readme.txt /usr/local/readme.txt
     
    ADD jdk-8u73-linux-x64.tar.gz /usr/local/
    ADD apache-tomcat-9.0.37.tar.gz /usr/local/
     
    RUN yum -y install vim
     
    ENV MYPATH /usr/local
    WORKDIR $MYPATH
     
    ENV JAVA_HOME /usr/local/jdk1.8.0_73
    ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
    ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.37
    ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.37
    ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
     
    EXPOSE 8080
     
    CMD /usr/local/apache-tomcat-9.0.37/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.37/bin/logs/catalina.out
     

    構建鏡像

# docker build -t diytomcat .

    啟動鏡像

#  docker run -d -p 3344:8080 --name xiaofantomcat1 -v /home/xiaofan/build/tomcat/test:/usr/local/apache-tomcat-9.0.37/webapps/test -v /home/xiaofan/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.37/logs diytomcat

    訪問測試

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

在本地編寫web.xml和index.jsp進行測試

 

 

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

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>hello. xiaofan</title>
    </head>
    <body>
    Hello World!<br/>
    <%
    System.out.println("-----my test web logs------");
    %>
    </body>
    </html>

發現:項目部署成功, 可以直接訪問ok!

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

 

 

 

發布自己的鏡像到Docker Hub

Docker Hub

  1. 地址 注冊自己的賬號!

 

 

 

 確定這個賬號可以登錄

 

 

     在我們的服務器上提交自己的鏡像

    # push到我們的服務器上
    [root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker push diytomcat
    The push refers to repository [docker.io/library/diytomcat]
    2eaca873a720: Preparing
    1b38cc4085a8: Preparing
    088ebb58d264: Preparing
    c06785a2723d: Preparing
    291f6e44771a: Preparing
    denied: requested access to the resource is denied  # 拒絕
     
    # push鏡像的問題?
    The push refers to repository [docker.io/1314520007/diytomcat]
    An image does not exist locally with the tag: 1314520007/diytomcat
     
    # 解決,增加一個tag
    docker tag diytomcat 1314520007/tomcat:1.0

 

 

 

發布到阿里雲鏡像服務上

  1. 登錄阿里雲
  2. 找到容器鏡像服務
  3. 創建命名空間

在這里插入圖片描述

  1. 創建容器鏡像

在這里插入圖片描述

  1. 點擊倉庫名稱,參考官方文檔即可

在這里插入圖片描述

總結

 

 

 

 

 

 

八,Docker網絡

1. Docker網絡

鏈接Docker0

測試

 

 

 三個網絡

    # 問題: docker是如何處理容器網絡訪問的?
     
    # [root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker run -d -P --name tomcat01 tomcat
     
    # 查看容器內部的網絡地址 ip addr
    [root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker exec -it tomcat01 ip addr, 發現容器啟動的時候得到一個eth0@if115 ip地址,docker分配的!
    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
    114: eth0@if115: <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@iZ2zeg4ytp0whqtmxbsqiiZ ~]# 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.077 ms
    64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.069 ms
    64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.075 ms
     
    # linux 可以 ping 通docker容器內部!

    原理

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

再次測試 ip addr

 

 

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

 

 

 

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

我們測試一下tomcat01和tomcat02之間是否可以ping通!

 

 

 結論:容器與容器之間是可以相互ping通的!

繪制一個網絡模型圖

 

 

 



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

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

    小結

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

 

 

 



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

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

 

 

 -- link

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

    [root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker exec -it tomcat02 ping tomcat01
    ping: tomcat01: Name or service not known
     
    # 如何可以解決呢?
    # 通過--link既可以解決網絡連通問題
    [root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker run -d -P  --name tomcat03 --link tomcat02 tomcat
    3a2bcaba804c5980d94d168457c436fbd139820be2ee77246888f1744e6bb473
    [root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker ps
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                     NAMES
    3a2bcaba804c        tomcat              "catalina.sh run"   4 seconds ago       Up 3 seconds        0.0.0.0:32772->8080/tcp   tomcat03
    f22ed47ed1be        tomcat              "catalina.sh run"   57 minutes ago      Up 57 minutes       0.0.0.0:32771->8080/tcp   tomcat02
    9d97f93401a0        tomcat              "catalina.sh run"   About an hour ago   Up About an hour    0.0.0.0:32770->8080/tcp   tomcat01
    [root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker exec -it tomcat03 ping tomcat02
    PING 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.129 ms
    64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.100 ms
    64 bytes from tomcat02 (172.17.0.3): icmp_seq=3 ttl=64 time=0.110 ms
    64 bytes from tomcat02 (172.17.0.3): icmp_seq=4 ttl=64 time=0.107 ms
     
    # 反向可以ping通嗎?
    [root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker exec -it tomcat02 ping tomcat03
    ping: tomcat03: Name or service not known
     

探究:inspect!

 

 

 

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

    [root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker exec -it tomcat03 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  tomcat02 f22ed47ed1be
    172.17.0.4  3a2bcaba804c

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

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

自定義網絡!不使用Docker0!

Docker0的問題:它不支持容器名鏈接訪問!
自定義網絡

    查看所有的docker網絡



網絡模式

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

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 可以支持255*255個網絡 192.168.0.2 ~ 192.168.255.254
# --gateway 192.168.0.1
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
26a5afdf4805d7ee0a660b82244929a4226470d99a179355558dca35a2b983ec
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
30d601788862        bridge              bridge              local
226019b14d91        host                host                local
26a5afdf4805        mynet               bridge              local
7496c014f74b        none                null                local

我們自己創建的網絡就ok了!

 

 

 在自己創建的網絡里面啟動兩個容器

    [root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker run -d -P --name tomcat-net-01 --net mynet tomcat
    0e85ebe6279fd23379d39b27b5f47c1e18f23ba7838637802973bf6449e22f5c
    [root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker run -d -P --name tomcat-net-02 --net mynet tomcat
    c6e462809ccdcebb51a4078b1ac8fdec33f1112e9e416406b606d0c9fb6f21b5
    [root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker network inspect mynet
    [
        {
            "Name": "mynet",
            "Id": "26a5afdf4805d7ee0a660b82244929a4226470d99a179355558dca35a2b983ec",
            "Created": "2020-08-14T11:12:40.553433163+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": {
                "0e85ebe6279fd23379d39b27b5f47c1e18f23ba7838637802973bf6449e22f5c": {
                    "Name": "tomcat-net-01",
                    "EndpointID": "576ce5c0f5860a5aab5e487a805da9d72f41a409c460f983c0bd341dd75d83ac",
                    "MacAddress": "02:42:c0:a8:00:02",
                    "IPv4Address": "192.168.0.2/16",
                    "IPv6Address": ""
                },
                "c6e462809ccdcebb51a4078b1ac8fdec33f1112e9e416406b606d0c9fb6f21b5": {
                    "Name": "tomcat-net-02",
                    "EndpointID": "81ecbc4fe26e49855fe374f2d7c00d517b11107cc91a174d383ff6be37d25a30",
                    "MacAddress": "02:42:c0:a8:00:03",
                    "IPv4Address": "192.168.0.3/16",
                    "IPv6Address": ""
                }
            },
            "Options": {},
            "Labels": {}
        }
    ]
     
    # 再次拼連接
    [root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# 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.113 ms
    64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.093 ms
    ^C
    --- 192.168.0.3 ping statistics ---
    2 packets transmitted, 2 received, 0% packet loss, time 999ms
    rtt min/avg/max/mdev = 0.093/0.103/0.113/0.010 ms
    # 現在不使用 --link也可以ping名字了!
    [root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# 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.068 ms
    64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.096 ms
    64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.094 ms
     

我們自定義的網絡docker都已經幫我們維護好了對應的關系,推薦我們平時這樣使用網絡

好處:

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

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

 

 

 測試打通tomcat01 和mynet


    [root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker network connect  mynet tomcat01
     
    # 連通之后就是講tomcat01 放到了mynet網路下
    # 一個容器兩個ip地址:
    # 阿里雲服務器,公網ip,私網ip

 

 

 

 

 

 # 連通ok
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# 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.100 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.085 ms
^C
--- tomcat-net-01 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 0.085/0.092/0.100/0.012 ms
# 依舊無法連通,沒有connect
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker exec -it tomcat02 ping tomcat-net-01
ping: tomcat-net-01: Name or service not known
 

結論:假設要跨網絡 操作別人,就要使用docker network connect連通.....!

實戰:部署redis

 

 

 # 創建網卡
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
# 創建結點1
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
 
#創建結點2
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
#創建結點3
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
#創建結點4
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
#創建結點5
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
#創建結點6
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
 
# 創建集群
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker exec -it redis-1 /bin/sh
/data # ls
appendonly.aof  nodes.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: 541b7d237b641ac2ffc94d17c6ab96b18b26a638 172.38.0.11:6379
   slots:[0-5460] (5461 slots) master
M: a89c1f1245b264e4a402a3cf99766bcb6138dbca 172.38.0.12:6379
   slots:[5461-10922] (5462 slots) master
M: 259e804d6df74e67a72e4206d7db691a300c775e 172.38.0.13:6379
   slots:[10923-16383] (5461 slots) master
S: 9b19170eea3ea1b92c58ad18c0b5522633a9e271 172.38.0.14:6379
   replicates 259e804d6df74e67a72e4206d7db691a300c775e
S: 061a9d38f22910aaf0ba1dbd21bf1d8f57bcb7d5 172.38.0.15:6379
   replicates 541b7d237b641ac2ffc94d17c6ab96b18b26a638
S: 7a16b9bbb0615ec95fc978fa62fc054df60536f0 172.38.0.16:6379
   replicates a89c1f1245b264e4a402a3cf99766bcb6138dbca
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: 541b7d237b641ac2ffc94d17c6ab96b18b26a638 172.38.0.11:6379
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: a89c1f1245b264e4a402a3cf99766bcb6138dbca 172.38.0.12:6379
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: 7a16b9bbb0615ec95fc978fa62fc054df60536f0 172.38.0.16:6379
   slots: (0 slots) slave
   replicates a89c1f1245b264e4a402a3cf99766bcb6138dbca
S: 061a9d38f22910aaf0ba1dbd21bf1d8f57bcb7d5 172.38.0.15:6379
   slots: (0 slots) slave
   replicates 541b7d237b641ac2ffc94d17c6ab96b18b26a638
M: 259e804d6df74e67a72e4206d7db691a300c775e 172.38.0.13:6379
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: 9b19170eea3ea1b92c58ad18c0b5522633a9e271 172.38.0.14:6379
   slots: (0 slots) slave
   replicates 259e804d6df74e67a72e4206d7db691a300c775e
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
 
 SpringBoot微服務打包Docker鏡像

    構建springboot項目

? IDEA2020 Ultimate版本激活方案 親測有效

    打包應用
    編寫Dockerfile

    FROM java:8
     
    COPY *.jar /app.jar
     
    CMD ["--server.port=8080"]
     
    EXPOSE 8080
     
    ENTRYPOINT ["java", "-jar", "/app.jar"]

    構建鏡像

    發布運行!

    # 把打好的jar包和Dockerfile上傳到linux
    [root@iZ2zeg4ytp0whqtmxbsqiiZ idea]# ll
    total 16140
    -rw-r--r-- 1 root root 16519871 Aug 14 17:38 demo-0.0.1-SNAPSHOT.jar
    -rw-r--r-- 1 root root      122 Aug 14 17:38 Dockerfile
     
    # 構建鏡像,不要忘了最后有一個點
    [root@iZ2zeg4ytp0whqtmxbsqiiZ idea]# docker build -t xiaofan666 .
    Sending build context to Docker daemon  16.52MB
    Step 1/5 : FROM java:8
    8: Pulling from library/java
    5040bd298390: Pull complete
    fce5728aad85: Pull complete
    76610ec20bf5: Pull complete
    60170fec2151: Pull complete
    e98f73de8f0d: Pull complete
    11f7af24ed9c: Pull complete
    49e2d6393f32: Pull complete
    bb9cdec9c7f3: Pull complete
    Digest: sha256:c1ff613e8ba25833d2e1940da0940c3824f03f802c449f3d1815a66b7f8c0e9d
    Status: Downloaded newer image for java:8
     ---> d23bdf5b1b1b
    Step 2/5 : COPY *.jar /app.jar
     ---> d4de8837ebf9
    Step 3/5 : CMD ["--server.port=8080"]
     ---> Running in e3abc66303f0
    Removing intermediate container e3abc66303f0
     ---> 131bb3917fea
    Step 4/5 : EXPOSE 8080
     ---> Running in fa2f25977db7
    Removing intermediate container fa2f25977db7
     ---> d98147377951
    Step 5/5 : ENTRYPOINT ["java", "-jar", "/app.jar"]
     ---> Running in e1885e23773b
    Removing intermediate container e1885e23773b
     ---> afb6b5f28a32
    Successfully built afb6b5f28a32
    Successfully tagged xiaofan666:latest
     
    # 查看鏡像
    [root@iZ2zeg4ytp0whqtmxbsqiiZ idea]# docker images
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    xiaofan666          latest              afb6b5f28a32        14 seconds ago      660MB
    tomcat              latest              2ae23eb477aa        8 days ago          647MB
    redis               5.0.9-alpine3.11    3661c84ee9d0        3 months ago        29.8MB
    java                8                   d23bdf5b1b1b        3 years ago         643MB
     
    # 運行容器
    [root@iZ2zeg4ytp0whqtmxbsqiiZ idea]# docker run -d -P --name xiaofan-springboot-web xiaofan666
    fd9a353a80bfd61f6930c16cd92204532bfd734e003f3f9983b5128a27b0375e
    # 查看運行起來的容器端口(因為我們啟動的時候沒有指定)
    [root@iZ2zeg4ytp0whqtmxbsqiiZ idea]# docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                     NAMES
    fd9a353a80bf        xiaofan666          "java -jar /app.jar …"   9 seconds ago       Up 8 seconds        0.0.0.0:32779->8080/tcp   xiaofan-springboot-web
    # 本地訪問1
    [root@iZ2zeg4ytp0whqtmxbsqiiZ idea]# curl localhost:32779
    {"timestamp":"2020-08-14T09:42:57.371+00:00","status":404,"error":"Not Found","message":"","path":"/"}
    # 本地訪問2
    [root@iZ2zeg4ytp0whqtmxbsqiiZ idea]# [root@iZ2zeg4ytp0whqtmxbsqiiZ idea]# curl localhost:32779/hello
    hello, xiaofan
    # 遠程訪問(開啟阿里雲上的安全組哦)

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

Docker

Dockerfile build run 手動操作,單個容器!

微服務,100個微服務,依賴關系。

Docker Compose 來輕松高效的管理容器,定義運行多個容器。

    官方介紹

    定義運行多個容器
    YAML file配置文件
    single command。命令有哪些?

Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration. To learn more about all the features of Compose, see the list of features.

    所有的環境都可以使用compose。

Compose works in all environments: production, staging, development, testing, as well as CI workflows. You can learn more about each case in Common Use Cases.

三步驟:

Using Compose is basically a three-step process:

    Define your app’s environment with a Dockerfile so it can be reproduced anywhere.
        Dockerfile保證我們的項目再任何地方可以運行
    Define the services that make up your app in docker-compose.yml so they can be run together in an isolated environment.
        services 什么是服務。
    Run docker-compose up and Compose starts and runs your entire app.
        啟動項目

作用:批量容器編排

    我自己的理解

Compose是Docker官方的開源項目,需要安裝!

Dockerfile讓程序在任何地方運行。web服務、redis、mysql、nginx... 多個容器。 run

Compose

    version: '2.0'
    services:
      web:
        build: .
        ports:
        - "5000:5000"
        volumes:
        - .:/code
        - logvolume01:/var/log
        links:
        - redis
      redis:
        image: redis
    volumes:
      logvolume01: {}

docker-compose up 100個服務

Compose:重要概念

    服務services, 容器、應用(web、redis、mysql...)
    項目project。 一組關聯的容器

安裝

    下載

    # 官網提供 (沒有下載成功)
    curl -L "https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
     
    # 國內地址
    curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

    授權

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

 

 

 

體驗(沒有測試通過)

地址:https://docs.docker.com/compose/gettingstarted/

python應用。 計數器。redis!

    應用app.py

    Dockerfile 應用打包為鏡像

        FROM python:3.6-alpine
        ADD . /code
        WORKDIR /code
        RUN pip install -r requirements.txt
        CMD ["python", "app.py"]
        # 官網的用來flask框架,我們這里不用它
        # 這告訴Docker
        # 從python3.7開始構建鏡像
        # 將當前目錄添加到/code印像中的路徑中
        # 將工作目錄設置為/code
        # 安裝Python依賴項
        # 將容器的默認命令設置為python app.py

    Docker-compose yaml文件(定義整個服務,需要的環境 web、redis) 完整的上線服務!

        version: '3.8'
        services:
          web:
            build: .
            ports:
              - "5000:5000"
            volumes:
              - .:/code
          redis:
            image: "redis:alpine"
         

    啟動compose 項目 (docker-compose up)

流程:

    創建網絡
    執行Docker-compose.yaml
    啟動服務

yaml規則

docker-compose.yaml 核心!

https://docs.docker.com/compose/compose-file/#compose-file-structure-and-examples
開源項目:博客

https://docs.docker.com/compose/wordpress/

下載程序、安裝數據庫、配置....

compose應用 => 一鍵啟動

    下載項目(docker-compse.yaml)
    如果需要文件。Dockerfile
    文件准備齊全,一鍵啟動項目即可

 

 

 

 

實戰:自己編寫微服務上線

  1. 編寫項目微服務

  2. Dockerfile構建鏡像

FROM java:8
 
COPY *.jar /app.jar
 
CMD ["--server.port=8080"]
 
EXPOSE 8080
 
ENTRYPOINT ["java", "-jar", "/app.jar"]

    docker-compose.yml編排項目

        version '3.8'
        services:
          xiaofanapp:
            build: .
            image: xiaofanapp
            depends_on:
              - redis
            ports:
              - "8080:8080"
         
          redis:
            image: "library/redis:alpine"

    丟到服務器運行 docker-compose up

    docker-compose down         # 關閉容器
    docker-compose up --build   # 重新構建

 

 

 

 

 

 

總結:

工程、服務、容器

項目 compose: 三層

  • 工程 Project
  • 服務
  • 容器 運行實例! docker k8s 容器

十,Docker Swarm

Docker Swarm

集群

購買服務器

登錄阿里雲賬號,進入控制台,創建實例

4台服務器2G

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

到此,我們的服務器購買成功!

四台機器安裝docker

和我們單機安裝一樣

技巧: xshell直接同步操作,省時間!

Swarm集群搭建

工作機制

 

 

 docker swarm init --help
 
ip addr # 獲取自己的ip(用內網的不要流量)
 
[root@iZ2ze58v8acnlxsnjoulk5Z ~]# docker swarm init --advertise-addr 172.16.250.97
Swarm initialized: current node (otdyxbk2ffbogdqq1kigysj1d) is now a manager.
To add a worker to this swarm, run the following command:
    docker swarm join --token SWMTKN-1-3vovnwb5pkkno2i3u2a42yrxc1dk51zxvto5hrm4asgn37syfn-0xkrprkuyyhrx7cidg381pdir 172.16.250.97:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

初始化結點docker swarm init

docker swarm join 加入一個結點!

    # 獲取令牌
    docker swarm join-token manager
    docker swarm join-token worker

    [root@iZ2ze58v8acnlxsnjoulk6Z ~]# docker swarm join --token SWMTKN-1-3vovnwb5pkkno2i3u2a42yrxc1dk51zxvto5hrm4asgn37syfn-0xkrprkuyyhrx7cidg381pdir 172.16.250.97:2377
    This node joined a swarm as a worker.
     

把后面的結點都搭建進去

 

 

 100台!

    生成主節點init
    加入(管理者,worker)

Raft協議

雙主雙從:假設一個結點掛了!其他結點是否可以用!

Raft協議:保證大多數結點存活才可以使用,只要>1, 集群至少大於3台!

實驗:

1、將docker1機器停止。宕機!雙主,另外一個結點也不能使用了!

 

 

 

 可以將其他結點離開docker swarm leave

 

 

     worker就是工作的,管理結點操作! 3台結點設置為了管理結點。
    Docker swarm集群增加節點

十分簡單:集群,可用! 3個主節點。 > 1台管理結點存活!

Raft協議:保證大多數結點存活,才可以使用,高可用!
體會

彈性、擴縮容!集群!

以后告別 docker run!

docker-compose up!啟動一個項目。單機!

集群: swarm docker-service

k8s service

容器 => 服務!

容器 => 服務! => 副本!

redis => 10個副本!(同時開啟10個redis容器)

體驗:創建服務、動態擴容服務、動態更新服務

 

 

 

灰度發布(金絲雀發布)

編程浪子的博客

 

 

 docker run 容器啟動! 不具有擴縮容器
docker service 服務! 具有擴縮容器,滾動更新!

查看服務

 

 

 動態擴縮容

    [root@iZ2ze58v8acnlxsnjoulk5Z ~]# docker service update --replicas 3 my-nginx
    1/3: running   [==================================================>]
    1/3: running   [==================================================>]
    2/3: running   [==================================================>]
    3/3: running   [==================================================>]
    verify: Service converged
     
     
    [root@iZ2ze58v8acnlxsnjoulk5Z ~]# docker service scale my-nginx=5
    my-nginx scaled to 5
    overall progress: 3 out of 5 tasks
    overall progress: 3 out of 5 tasks
    overall progress: 3 out of 5 tasks
    overall progress: 5 out of 5 tasks
    1/5: running   [==================================================>]
    2/5: running   [==================================================>]
    3/5: running   [==================================================>]
    4/5: running   [==================================================>]
    5/5: running   [==================================================>]
    verify: Service converged
     
     
    [root@iZ2ze58v8acnlxsnjoulk5Z ~]# docker service scale my-nginx=1
    my-nginx scaled to 1
    overall progress: 1 out of 1 tasks
    1/1: running   [==================================================>]
    verify: Service converged
     

移出!docker service rm

docker swarm其實並不難

只要會搭建集群、會啟動服務、動態管理容器就可以了!
概念的總結

swarm

集群的管理和編號,docker可以初始化一個swarm集群,其他結點可以加入。(管理,工作者)

Node

就是一個docker結點,多個結點就組成了一個網絡集群(管理、工作者)

Service

任務,可以在管理結點或者工作結點來運行。核心,用戶訪問。

Task

容器內的命令、細節任務!

 

 

 

service

 

 

 

命令 -> 管理 -> api -> 調度 -> 工作結點(創建Task容器維護創建!)

服務副本和全局服務

 

 

 

調整service以什么方式運行

    --mode string                        
    Service mode (replicated or global) (default "replicated")
     
    docker service create --mode replicated --name mytom tomcat:7 默認的
    docker service create --mode global  --name haha alpine ping www.baidu.com

拓展: 網絡模式 "PublishMode":"ingress"

Swarm:

Overlay:

ingress:特殊的Overlay網絡!負載均衡的功能!ipvs vip!

    [root@iZ2ze58v8acnlxsnjoulk5Z ~]# docker network ls
    NETWORK ID          NAME                DRIVER              SCOPE
    74cecd37149f        bridge              bridge              local
    168d35c86dd5        docker_gwbridge     bridge              local
    2b8f4eb9c2e5        host                host                local
    dmddfc14n7r3        ingress             overlay             swarm
    8e0f5f648e69        none                null                local
     
     
    [root@iZ2ze58v8acnlxsnjoulk5Z ~]# docker network inspect ingress
    [
        {
            "Name": "ingress",
            "Id": "dmddfc14n7r3vms5vgw0k5eay",
            "Created": "2020-08-17T10:29:07.002315919+08:00",
            "Scope": "swarm",
            "Driver": "overlay",
            "EnableIPv6": false,
            "IPAM": {
                "Driver": "default",
                "Options": null,
                "Config": [
                    {
                        "Subnet": "10.0.0.0/24",
                        "Gateway": "10.0.0.1"
                    }
                ]
            },
            "Internal": false,
            "Attachable": false,
            "Ingress": true,
            "ConfigFrom": {
                "Network": ""
            },
            "ConfigOnly": false,
            "Containers": {
                "ingress-sbox": {
                    "Name": "ingress-endpoint",
                    "EndpointID": "9d6ec47ec8309eb209f4ff714fbe728abe9d88f9f1cc7e96e9da5ebd95adb1c4",
                    "MacAddress": "02:42:0a:00:00:02",
                    "IPv4Address": "10.0.0.2/24",
                    "IPv6Address": ""
                }
            },
            "Options": {
                "com.docker.network.driver.overlay.vxlanid_list": "4096"
            },
            "Labels": {},
            "Peers": [
                {
                    "Name": "cea454a89163",
                    "IP": "172.16.250.96"
                },
                {
                    "Name": "899a05b64e09",
                    "IP": "172.16.250.99"
                },
                {
                    "Name": "81d65a0e8c03",
                    "IP": "172.16.250.97"
                },
                {
                    "Name": "36b31096f7e2",
                    "IP": "172.16.250.98"
                }
            ]
        }
    ]
     

其他命令學習方式

    Docker Stack

    docker-compose 單機部署項目
    docker stack 集群部署
    # 單機
    docker-compose up -d wordpress.yaml
    # 集群
    docker stack deploy wordpress.yaml

    Docker Secret

    安全!配置密碼!證書!
     
    [root@iZ2ze58v8acnlxsnjoulk5Z ~]# docker secret --help
     
    Usage:  docker secret COMMAND
     
    Manage Docker secrets
     
    Commands:
      create      Create a secret from a file or STDIN as content
      inspect     Display detailed information on one or more secrets
      ls          List secrets
      rm          Remove one or more secrets

    Docker Config

    配置!
    [root@iZ2ze58v8acnlxsnjoulk5Z ~]# docker config --help
     
    Usage:  docker config COMMAND
     
    Manage Docker configs
     
    Commands:
      create      Create a config from a file or STDIN
      inspect     Display detailed information on one or more configs
      ls          List configs
      rm          Remove one or more configs
     

拓展到k8s

雲原生時代

Go語言!必須掌握! Java Go!

並發語言!

B語言,C語言的創始人。Unix創始人VB

go指針


免責聲明!

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



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