一.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
-
地址 注冊自己的賬號!
確定這個賬號可以登錄
在我們的服務器上提交自己的鏡像
# 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
發布到阿里雲鏡像服務上
- 登錄阿里雲
- 找到容器鏡像服務
- 創建命名空間
- 創建容器鏡像
- 點擊倉庫名稱,參考官方文檔即可
總結
八,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
文件准備齊全,一鍵啟動項目即可
實戰:自己編寫微服務上線
-
編寫項目微服務
-
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指針