1. 程式人生 > 實用技巧 >php-檔案包含

php-檔案包含

Docker

Docker概述

Docker為什麼出現

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

開發----運維

環境配置是十分的麻煩,每一個機器都要部署環境(叢集Redis,ES,Hadoop。。。。)!費時費力

釋出專案jar+(Redis,MySQL,jdk,ES...),專案能不能帶上環境安裝打包!

之前在伺服器配置一個應用的環境Redis,MySQL,jdk,ES,Hadoop,配置超麻煩,不能跨平臺

Windows,最後釋出到Linux

傳統:開發jar,運維來做部署的事情

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

java--jar(環境)---打包專案帶上環境(形成映象)---(Docker倉庫:商店)--下載我們釋出的映象--直接執行

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

docker的思想就來自集裝箱

JRE--多個應用(埠衝突)--原來是交叉的

隔離:Docker的核心思想,打包裝箱!每個箱子是互相隔離。

Docker通過隔離限制,可以將伺服器利用到極致。

Docker歷史

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

做一些pass的雲端計算服務,LXC有關的容器技術!

他們將自己的技術 容器化技術 命名為Docker

Docker剛剛建立時,沒有引起行業的注意,dotCloud就活不下去

開源

開發原始碼

2013年,Docker開源

Docker越來越火,Docker每個月都或更新一個版本

2014年4月9日。Docker1.0釋出

Doker為什麼這麼火,十分輕巧

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

虛擬機器:在windows中裝一個Vmware,通過這個軟體可以虛擬出一臺或者多臺電腦!非常笨重

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

vm:linux centOS原生映象(一臺電腦) 隔離:需要開啟多個虛擬機器  幾個G 幾分鐘
docker:隔離,映象(最核心的環境 4m + jdk +mysql) 十分輕巧,執行映象即可!小巧 幾個m kb 秒級啟動

到現在,多有開發人員都必須會Docker

Docker是基於GO語言開發!開源專案

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

文件地址:https://docs.docker.com/,Docker的文件是超級詳細的

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

Docker能做什麼

  1. 之前的虛擬機器技術

  • 資源佔用十分多

  • 冗餘步驟多

  • 啟動很慢

  1. 容器化技術

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

比較Docker和虛擬機器技術的區別:

  • 傳統虛擬機器,虛擬出一條硬體,執行一個完整的作業系統,然後在這個系統上安裝和執行軟體

  • 容器內應用直接執行在宿主機的內容,容器是沒有自己的核心的,也沒有虛擬我們的硬體,所以就輕便了

  • 每個容器是互相隔離,每個容器內都有一個屬於自己的檔案系統,互不影響

  1. DevOps(開發,運維)

    應用更快速的交付和部署

    傳統:一堆文件,安裝程式

    Docker:打包映象釋出測試,一鍵執行。

    更便捷的升級和擴縮容

    使用了Docker之後,我們部署應用就和搭積木一樣

    專案打包為一個映象,擴充套件 伺服器A!伺服器B

    更簡單的系統運維

    在容器化之後,我們的開發,測試環境都是高度一致的

    更高效的計算資源的利用

    Docker是核心級別的虛擬化,可以在一個物理機上執行很多容器例項!伺服器效能可以被壓榨到極致。

Docker安裝

Docker基本組成

映象(image):

docker映象就好比是一個模板,通過這個模板來建立容器服務,tomcat映象--->run-->tomcat01容器(提供服務)

通過這個映象可以建立多個容器(最終服務執行或者專案執行就是在容器中的)

容器(containers):

Docker利用容器技術,獨立執行一個或者一組應用,通過映象來建立的

啟動,停止,刪除,基本命令

目前就可以把這個容器理解為就是一個簡易的linux系統

倉庫(repository):

倉庫就是存放映象的地方!

倉庫分為私有和共有倉庫

Docker Hub(預設是國外的)

阿里雲。。。都有容器服務(配置映象加速)

Docker安裝

環境安裝

  1. 需要一些linux的基礎

  2. CentOS7

  3. 我們使用Xshell連線遠端伺服器進行操作

環境檢視

#系統核心是3.10
[zhoudelin@localhost ~]$ uname -r
3.10.0-1127.el7.x86_64

#系統版本
[zhoudelin@localhost ~]$ 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"

安裝

幫助文件

#1.解除安裝舊的版本
$ sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine

#2.需要的安裝包
$ sudo yum install -y yum-utils

#3.設定映象的倉庫
$ sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo #國外的地址,非常慢

yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo #推薦使用阿里雲

#先更新yum軟體包索引
yum makecache fast

#4.安裝docker docker-ce社群版 ee 企業版
$ sudo yum install docker-ce docker-ce-cli containerd.io

#5.啟動docker
$ sudo systemctl start docker

#6.判斷是否成功
[zhoudelin@localhost ~]$ docker version

#7.hello-world
$ sudo docker run hello-world
結果顯示:
[zhoudelin@localhost ~]$ sudo docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
0e03bdcc26d7: Pull complete
Digest: sha256:7f0a9f93b4aa3022c3a4c147a449bf11e0941a1fd0bf4a8e6c9408b2600777c5
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/

For more examples and ideas, visit:
https://docs.docker.com/get-started/

#8.檢視一下下載的這個hello-world映象
$ sudo docker images
[zhoudelin@localhost ~]$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest bf756fb1ae65 8 months ago 13.3kB

瞭解解除安裝docker

#解除安裝依賴
$ sudo yum remove docker-ce docker-ce-cli containerd.io

#刪除目錄
$ sudo rm -rf /var/lib/docker #docker預設工作路徑:/var/lib/docker

阿里雲映象加速

回顧HelloWorld流程

底層原理

Docker是幹什麼工作的?

docker是一個Client-Server結構的系統,Docker的守護程序執行在主機上,通過socket從客戶端訪問

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

Docker為什麼比VM快

  1. Docker有著比虛擬機器更少的抽象層

  1. Docker利用的是宿主機的核心,vm更需要的是Guest OS

    所以說,新建一個容器的時候,docker不需要像虛擬機器一樣重新載入一個作業系統核心,避免引導。虛擬機器是載入Guest OS,分鐘級別,而Docker是利用宿主機的作業系統,省略了這個複雜的過程。

Docker常用命令

幫助命令

docker version      # 顯示docker版本
docker info # 顯示docker系統資訊,包括映象和容器
docker command --help # 幫助命令
systemctl start docker # 啟動docker服務

幫助文件:https://docs.docker.com/reference/

映象命令

docker images 檢視本機上的所有映象

[root@localhost ~]$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest bf756fb1ae65 8 months ago 13.3kB

#解釋
REPOSITORY 映象的倉庫源
TAG 映象的標籤
IMAGE ID 映象的id
CREATED 映象的建立時間
SIZE 映象的大小

Options: #可選項
-a, --all Show all images (default hides intermediate images)#列出所有的映象
--digests Show digests
-f, --filter filter Filter output based on conditions provided
--format string Pretty-print images using a Go template
--no-trunc Don't truncate output
-q, --quiet Only show numeric IDs #只顯示映象的ID

docker search 搜尋映象

[root@localhost ~]$ sudo docker search mysql
[sudo] root 的密碼:
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 9934 [OK]

#可選項
[root@localhost ~]$ sudo docker search --help

Usage: docker search [OPTIONS] TERM

Search the Docker Hub for images

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

#通過收藏來過濾
--filter-STARTS-3000 #搜尋出來的映象就是STARTS大於3000的

docker pull 下載映象

#下載映象  docker pull 映象名[:tag]
[root@localhost ~]$ sudo docker pull mysql
[sudo] root 的密碼:
Using default tag: latest #如果不寫tag,預設就是latest
latest: Pulling from library/mysql
bf5952930446: Pull complete #分層下載,docker images的核心 聯合檔案系統
8254623a9871: Pull complete
938e3e06dac4: Pull complete
ea28ebf28884: Pull complete
f3cef38785c2: Pull complete
894f9792565a: Pull complete
1d8a57523420: Pull complete
6c676912929f: Pull complete
3cdd8ff735c9: Pull complete
4c70cbe51682: Pull complete
e21cf0cb4dc3: Pull complete
28c36cd3abcc: Pull complete
Digest: sha256:6ded54eb1e5d048d8310321ba7b92587e9eadc83b519165b70bbe47e4046e76a #簽名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest #真實的

#兩者等價
docker pull mysql
docker.io/library/mysql:latest

docker rmi 刪除映象

[root@localhost ~]$ sudo docker rmi -f 容器id   #刪除指定內容
[root@localhost ~]$ sudo docker rmi -f 容器id 容器id 容器id   #刪除多個容器
[root@localhost ~]$ sudo 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@localhost ~]$ sudo docker run -it centos /bin/bash
[sudo] root 的密碼:
[root@a4533364bee2 /]# ls  #檢視容器內的centos,基礎版本,很多命令都是不完善的!
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

#從容器中退回主機
[root@a4533364bee2 /]# exit

列出執行中的容器

#docker ps命令
         #列出當前正在執行的容器
-a         #列出當前正在執行的容器+帶出歷史執行過的容器
-n=?         #顯示最近建立的容器
-q       #只顯示容器的編號

[root@localhost ~]$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
[root@localhost ~]$ sudo docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                       PORTS               NAMES
a4533364bee2        centos              "/bin/bash"         9 minutes ago       Exited (127) 3 minutes ago                       upbeat_keller
2a726ed3ab4b        bf756fb1ae65        "/hello"            2 hours ago         Exited (0) 2 hours ago                           blissful_maxwell

退出容器

exit   #直接容器停止並退出
Ctrl+P+Q  #容器不停止退出

刪除容器

docker rm 容器id     #刪除指定的容器,不能刪除正在執行的容器,想要強制刪除 rm -f
docker rm -f $ (docker ps -aq)     #刪除所有的容器
docker ps -q|xargs docker rm  #刪除所有的容器

啟動和停止容器操作

docker start 容器id  #啟動容器
docker restart 容器id  #重啟容器
docker stop 容器id   #
docker kill 容器id

常用其他命令

後臺啟動容器

#命令 docker run -d 映象名
[root@localhost ~]$ sudo docker run -d centos

#問題docker ps 發現centos停止了

#常見的坑,docker容器使用後臺執行,就必須有一個前臺程序,docker發現沒有前臺程序,就會自動把後臺停止
#nginx 容器啟動之後,發現自己沒有提供服務,就會立即停止,就是沒有程式了

檢視日誌

docker logs -f -t --tail 容器,沒有日誌

檢視容器中程序資訊

# 命令 docker top 容器id

映象元資料

# 命令 docker inspect 容器id
[root@localhost ~]$ sudo docker inspect b4af22c18647
[sudo] root 的密碼:
[
    {
        "Id": "b4af22c186475328b9dda30e03e8e6915a29b65430c7a3ef126a3fa7b4d847c8",
        "Created": "2020-09-08T02:02:35.268831886Z",
        "Path": "/bin/bash",
        "Args": [],
        "State": {
            "Status": "exited",
            "Running": false,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 0,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2020-09-08T02:04:58.767625388Z",
            "FinishedAt": "2020-09-08T02:04:58.778547336Z"
        },
        "Image": "sha256:0d120b6ccaa8c5e149176798b3501d4dd1885f961922497cd0abef155c869566",
        "ResolvConfPath": "/var/lib/docker/containers/b4af22c186475328b9dda30e03e8e6915a29b65430c7a3ef126a3fa7b4d847c8/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/b4af22c186475328b9dda30e03e8e6915a29b65430c7a3ef126a3fa7b4d847c8/hostname",
        "HostsPath": "/var/lib/docker/containers/b4af22c186475328b9dda30e03e8e6915a29b65430c7a3ef126a3fa7b4d847c8/hosts",
        "LogPath": "/var/lib/docker/containers/b4af22c186475328b9dda30e03e8e6915a29b65430c7a3ef126a3fa7b4d847c8/b4af22c186475328b9dda30e03e8e6915a29b65430c7a3ef126a3fa7b4d847c8-json.log",
        "Name": "/nervous_gates",
        "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/4915f4244512c71cc03733fe4d007c6565de019a9b77944122591f74efa1d337-init/diff:/var/lib/docker/overlay2/f75740f43db3aa996a6f4b57893c909b313d94f1e2f2aff368ffe5532c3078d9/diff",
                "MergedDir": "/var/lib/docker/overlay2/4915f4244512c71cc03733fe4d007c6565de019a9b77944122591f74efa1d337/merged",
                "UpperDir": "/var/lib/docker/overlay2/4915f4244512c71cc03733fe4d007c6565de019a9b77944122591f74efa1d337/diff",
                "WorkDir": "/var/lib/docker/overlay2/4915f4244512c71cc03733fe4d007c6565de019a9b77944122591f74efa1d337/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [],
        "Config": {
            "Hostname": "b4af22c18647",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": true,
            "AttachStderr": true,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "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": "1b993ccc98a55b6da5c5db799f1d8c5273d72810a3357b51ce776faa2bec96fc",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {},
            "SandboxKey": "/var/run/docker/netns/1b993ccc98a5",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "",
            "Gateway": "",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "",
            "IPPrefixLen": 0,
            "IPv6Gateway": "",
            "MacAddress": "",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "b1923d034b83452efca1c670efe2357579bdd03170647fa6f70761d46c5e9eb0",
                    "EndpointID": "",
                    "Gateway": "",
                    "IPAddress": "",
                    "IPPrefixLen": 0,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "",
                    "DriverOpts": null
                }
            }
        }
    }
]

進入當前正在執行的容器

# 我們通常容器都是使用後臺的方式執行的,需要進入容器,修改一些配置

# 命令 docker exec -it 容器id 

#方式二:docker attach 容器id

# docker exec     # 進入容器後開啟一個新的終端,可以在裡面操作(常用)
# docker attach   # 進入容器正在執行的終端,不會啟動新的程序

從容器內拷貝到主機上

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

[root@localhost ~]$ sudo docker run -it centos /bin/bash
[sudo] root 的密碼:
[root@7222c4dfd973 /]# [root@localhost ~]$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
7222c4dfd973        centos              "/bin/bash"         46 seconds ago      Up 45 seconds                           vigilant_blackburn
# 檢視當前主機目錄下的檔案
[root@localhost ~]$ cd /home
[root@localhost home]$ ls
root
[root@localhost home]$ sudo touch antia.java
[root@localhost home]$ ls
antia.java  root
[root@localhost home]$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
7222c4dfd973        centos              "/bin/bash"         2 minutes ago       Up 2 minutes                            vigilant_blackburn
# 進入容器內部
[root@localhost home]$ sudo docker attach 7222c4dfd973
[root@7222c4dfd973 /]# cd /home
# 在容器內新建一個檔案
[root@7222c4dfd973 home]# touch test.java
[root@7222c4dfd973 home]# ls
test.java
[root@7222c4dfd973 home]# exit
exit
[root@localhost home]$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
# 將檔案拷貝到主機中
[root@localhost home]$ sudo docker cp 7222c4dfd973:/home/test.java /home
[root@localhost home]$ ls
antia.java  test.java  root


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

docker命令是十分多的。

作業練習

  1. nginx安裝

    # 1. 搜尋映象  search 
    # 2. 下載映象  pull
    # 3. 執行測試
    # -d 後臺執行
    # --name 給容器命名
    # -p 宿主機埠:容器內部埠
    [root@localhost home]$ sudo docker run -d --name nginx01 -p 3344:80 nginx
    6259fe2d44a41272eebd4719ac6fd18c088baf811a692db5f665faff5106cb5b
    [root@localhost home]$ sudo docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
    6259fe2d44a4        nginx               "/docker-entrypoint.…"   17 seconds ago      Up 16 seconds       0.0.0.0:3344->80/tcp   nginx01
    [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>

思考問題:

我們每次改動nginx配置檔案,都需要進入容器內部?

十分麻煩,我要是在容器外部提供一個對映路徑,達到在容器修改檔名,容器內部就可以自動修改?-v 資料卷

  1. docker來裝一個tomcat

    # 官方的使用
    docker run -it --rm tomcat:9.0
    
    # 我們之前的啟動都是後臺,停止容器之後,容器還是可以查到   一般用來測試,用完即刪
    
    # 一般下載再啟動
    docker pull tomcat
    
    # 啟動執行
    docker run -d -p 3355:8080 --name tomcat01 tomcat
    
    # 測試訪問沒有問題
    192.168.72.129:3355
    
    # 進入容器
    docker exec -it tomcat01 /bin/bash
    
    # 發現問題
    1. linux命令少了  2. 沒有webapps    如果是的話,可能是阿里雲的原因,預設是最小映象,所有不必要的都剔除。
                                      僅保證最小啟動。

    思考問題:我們以後要部署專案,如果每一次都要進入容器是不是十分麻煩?我要是在容器外部提供一個對映的路徑,webapps,我們在外部放置專案,就自動同步到內部就好了。

    1. 部署es+kabana

      # es 暴露埠很多
      # es 耗記憶體
      # 版本配置 7.6.2
      # --net somenetwork 網路配置
      docker run -d --name elasticsearch --net somenetwork -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:tag  
      
      # 啟動 elasticsearch
      docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2
      
      # 測試es是否成功了
      curl localhost:9200
      
      # 啟動 linux就很卡          docker stats 檢視   cpu的狀態
      
      # es 是十分耗記憶體的,佔用1.XG,   伺服器不行
      
      # 檢視CPU狀態
      docker stats
      
      # 趕緊關閉,增加記憶體限制,修改配置檔案 -e 環境配置修改
      docker run -d --name elasticsearch02 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" 
      -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2
      

      使用kabana連線elasticsearch

視覺化

  • portainer(先用這個)

    docker run -d -p 8088:9000 \
    --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
  • Rancher(CI/CD再用)

什麼是portainer?

Docker圖形化介面工具!提供一個後臺面板供我們操作!

Docker映象講解

映象是什麼?

映象是一種輕量級,可執行的的獨立軟體包,用來打包軟體執行環境和基於環境執行的軟體,它包含了某個軟體所需的所有內容,包括程式碼,執行時,庫,環境變數和配置檔案。

所有的應用,直接打成docker映象,就可以直接跑起來!

如何得到映象:

  • 從遠端倉庫下載

  • 別人拷貝給你

  • 自己製作一個映象DockerFile

Docker映象載入原理

UnionFS(聯合檔案系統)

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

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

Docker分層理解

我們看到CentOS的映象大小不到200MB,平時我們安裝一個CentOS至少是幾個GB,怎麼可能才 200MB !

下面我們來解釋這個問題,Linux 作業系統由核心空間和使用者空間組成。

典型的Linux啟動到執行需要兩個FS,bootfs + rootfs,如下圖:

rootf

核心空間是 kernel,Linux 剛啟動時會載入 bootfs 檔案系統,之後 bootfs 會被解除安裝掉。使用者空間的檔案系統是 rootfs,包含我們熟悉的 /dev, /proc, /bin 等目錄。

對於 base 映象來說,底層直接用 Host 的 kernel,自己只需要提供 rootfs 就行了。

而對於一個精簡的 OS,rootfs 可以很小,只需要包括最基本的命令、工具和程式庫就可以了。相比其他 Linux 發行版,CentOS 的 rootfs 已經算臃腫的了,alpine 還不到 10MB。

我們平時安裝的 CentOS 除了 rootfs 還會選裝很多軟體、服務、圖形桌面等,需要好幾個 GB 就不足為奇了。

可以看到,新映象是從 base 映象一層一層疊加生成的。每安裝一個軟體,就在現有映象的基礎上增加一層。

問什麼 Docker 映象要採用這種分層結構呢?

最大的一個好處就是 - 共享資源。

比如:有多個映象都從相同的 base 映象構建而來,那麼 Docker Host 只需在磁碟上儲存一份 base 映象;同時記憶體中也只需載入一份 base 映象,就可以為所有容器服務了。而且映象的每一層都可以被共享,我們將在後面更深入地討論這個特性。

這時可能就有人會問了:如果多個容器共享一份基礎映象,當某個容器修改了基礎映象的內容,比如 /etc 下的檔案,這時其他容器的 /etc 是否也會被修改?

答案是不會! 修改會被限制在單個容器內。 這就是我們接下來要說的容器 Copy-on-Write 特性。

  1. 新資料會直接存放在最上面的容器層。

  2. 修改現有資料會先從映象層將資料複製到容器層,修改後的資料直接儲存在容器層中,映象層保持不變。

  3. 如果多個層中有命名相同的檔案,使用者只能看到最上面那層中的檔案。

Docker映象

Docker映象都是隻讀的,當容器啟動時,一個新的可寫層被載入到映象的頂部!

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

如何提交一個自己的映象

commit映象

docker commit 提交容器成為一個新的副本

# 命令和git差不多
docker commit -m="提交的描述資訊" -a="作者" 容器id 目標映象名:[TAG]

實戰測試


Dockerfile、Image、Container

Dockerfile Image Container 的關係.png

  • Dockerfile: 用於描述映象的生成規則。 Dockerfile中的每一條命令,都在Docker映象中以一個獨立映象層的形式存在。

  • Image: 由Dockerfile生成, 呈現層級結構, 每層映象包含:映象檔案以及映象json元資料資訊。

  • Container: Container 是Image 的動態執行結果,概括而言,就是在Docker映象之上,執行程序。