主頁 > 作業系統 > centos安裝Docker與使用&&構建業務鏡像掛載卷harbor倉庫的高可用及網路模式和資源限制介紹

centos安裝Docker與使用&&構建業務鏡像掛載卷harbor倉庫的高可用及網路模式和資源限制介紹

2020-09-21 16:03:43 作業系統

Docker版本選擇:

    Docker之前沒有區分版本,但是2017年推出(將docker更名為)新的專案Moby,github地址:https://github.com/moby/moby,Moby專案屬于Docker專案的全新上游,Docker將是一個隸屬于的Moby的子產品,而且之后的版本之后開始區別為CE版本(社區版本)和EE(企業收費版),CE社區版本和EE企業版本都是每個季度發布一個新版本,但是EE版本提供后期安全維護1年,而CE版本是4個月

Docker安裝

下載rpm包安裝:

官方rpm包下載地址:
https : //download.docker.com/linux/centos/7/x86_64/stable/Packages/

阿里全世界下載地址:
https ://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/stable/Packages/

Centos yum源安裝:

  1. 下載docker源
rm -rf /etc/yum.repos.d/*
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
  1. 安裝
yum install docker-ce
  1. 啟動
systemctl start docker
systemctl enable docker

  

Ubuntu安裝

版本:Ubuntu 18.04.3
參考:https ://yq.aliyun.com/articles/110806

  • 阿里腳本安裝最新版
  1. 使用官方安裝腳本自動安裝(僅適用于公網環境)
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
  • 自定義版本下載
  1. 配置阿里yum源
sudo vim /etc/apt/sources.list
deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse

 

  1. 安裝必要的一些系統工具
sudo apt-get update
sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common

        2. 安裝GPG證書

curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -

        3. 寫入軟體源資訊

sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"

        4. 更新

sudo apt-get -y update

        5. 發現Docker-CE的版本:

# apt-cache madison docker-ce
docker-ce | 5:19.03.2~3-0~ubuntu-bionic | http://mirrors.aliyun.com/docker-ce/linux/ubuntu bionic/stable amd64 Packages
docker-ce | 5:19.03.1~3-0~ubuntu-bionic | http://mirrors.aliyun.com/docker-ce/linux/ubuntu bionic/stable amd64 Packages

         6. 安裝指定版本的Docker-CE:(VERSION例如上面的17.03.1?ce-0?ubuntu-xenial)

sudo apt install docker-ce-cli=5:18.09.9~3-0~ubuntu-bionic
sudo apt install docker-ce=5:18.09.9~3-0~ubuntu-bionic

         7. 驗證版本

  1. 驗證docker資訊 (以下是ubuntu安裝的資訊)
# docker info
Containers: 0
 Running: 0
 Paused: 0
 Stopped: 0
Images: 0
Server Version: 18.09.9
Storage Driver: overlay2
 Backing Filesystem: extfs
 Supports d_type: true
 Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
 Network: bridge host macvlan null overlay
 Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 894b81a4b802e4eb2a91d1ce216b8817763c29fb
runc version: 425e105d5a03fabd737a126ad93d62a9eeede87f
init version: fec3683
Security Options:
 apparmor
 seccomp
  Profile: default
Kernel Version: 4.15.0-62-generic
Operating System: Ubuntu 18.04.3 LTS
OSType: linux
Architecture: x86_64
CPUs: 2
Total Memory: 1.861GiB
Name: ubuntu
ID: 2C5Z:IASC:G3GK:325R:RDGI:GDJ4:23EE:O76B:Z2RY:HY5U:RSLC:J7OO
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
 127.0.0.0/8
Live Restore Enabled: false
Product License: Community Engine

WARNING: No swap limit support
  最后一行有個警告:警告:不支持交換限制

解決方法:

sudo vim /etc/default/grub
在GRUB_CMDLINE_LINUX=""這行加上

GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1"

 更新下grub,然后重啟

sudo update-grub
reboot

 


Docker命令

  1. 查看資訊
docker info
  1. 查看版本
docker version
  1. 查看當前容器狀態
docker ps 

        4. 搜索nginx的鏡像(第一個是默認的,也是下載最多的)

docker search nginx

 

      5.  下載nginx的鏡像

docker pull nginx

 

        6. 查看已經下載的鏡像串列,TAG版本號默認都是latest

docker images

 

     7、進入容器后,安裝基礎命令:

apt update
apt install procps
apt install iputils-ping
apt install net-tools

啟動容器

# 啟動一個在后臺運行的 docker 容器
docker run -it -d --name 'test-nginx' nginx

# -p指定埠映射,
-p 80:80

# 指定 ip 地址和傳輸協議 udp 或者 tcp:  
-p 192.168.7.108:80:80/tcp

# 也可以在創建時手動指定容器的 dns
--dns 223.6.6.6 

# 指定名稱
--name "centos3"

 

 





vi docker-enter.sh
chmod +x docker-enter.sh 

 進入容器

  1. 使用執行命令方式進入容器
docker exec -it b7a13ace208d bash

 

  1. 使用使用容器pid方式進入容器
docker inspect  -f  "{{.State.Pid}}"  02a1907e7c89
    19080 
nsenter -t 19080 -m -u -i -n -p

 

        3. 腳本方式進入容器

#!/bin/bash
docker_in(){

    NAME_ID=$1
    PID=$(docker inspect -f "{{.State.Pid}}" ${NAME_ID})
    nsenter -t ${PID} -m -u -i -n -p 

}

docker_in $1

 啟動

./docker-enter.sh centos-test

 

更多命令

以名義名:nginx為例子

  1. 洗掉docker的nginx鏡像檔案
docker rmi nginx

 

 

        2. 手動匯出docker鏡像

docker save nginx -o /root/nginx.tar.gz
docker save nginx > /root/nginx.tar.gz
  1. 手動匯入docker僅限
docker save nginx -o /root/nginx.tar.gz
docker save nginx > /root/nginx.tar.gz
  1. 停止和啟動一個容器
# d5ab2595f09a是CONTAINER ID
docker stop d5ab2595f09a
docker start d5ab2595f09a
  1. 洗掉一個已經停止的容器
docker rm d5ab2595f09a

 

  1. 強制關閉一個運行中的容器
docker kill d1ad4fa0b74c

 


docker加快加速配置:

    國內下載國外的某些有時候會很慢,因此可以更改docker組態檔添加一個加速器,可以通過加速器達到加速下載替代的目的,

獲取加速地址:

瀏覽器打開http://cr.console.aliyun.com,編碼或登錄阿里云賬號,單擊垂直的嵌套加速器,將會得到一個專屬的加速地址,而且下面有使用配置說明:

 

 

 

      1. 可以通過修改daemon組態檔/etc/docker/daemon.json來使用加速器

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["你的加速地址"]
}
EOF

      2. 重啟服務

sudo systemctl daemon-reload
sudo systemctl restart docker

使用docker info 查看

 

 

 

 

 

 

Docker命令與鏡像管理:

Docker 鏡像含有啟動容器所需要的檔案系統及所需要的內容, 因此鏡像主要用于創建并啟動 docker 容器,

Docker 鏡像含里面是一層層檔案系統,叫做 Union FS(聯合檔案系統) ,聯合檔案系統,可以將幾層目錄掛載到一起,形成一個虛擬檔案系統,虛擬檔案系統的目錄結構就像普通 linux 的目錄結構一樣, docker 通過這些檔案再加上宿主機的內核提供了一個 linux 的虛擬環境,每一層檔案系統我們叫做一層 layer,聯合檔案系統可以對每一層檔案系統設定三種權限,只讀( readonly)、讀寫( readwrite)和寫出( whiteout-able),但是 docker 鏡像中每一層檔案系統都是只讀的,構建鏡像的時候,從一個最基本的作業系統開始,每個構建的操作都相當于做一層的修改,增加了一層檔案系統,一層層往上疊加,上層的修改會覆寫底層該位置的可見性,這也很容易理解,就像上層把底層遮住了一樣,當使用鏡像的時候,我們只會看到一個完全的整體,不知道里面有幾層也不需要知道里面有幾層,結構如下:
在這里插入圖片描述

一個典型的 Linux 檔案系統由 bootfs 和 rootfs 兩部分組成, bootfs(boot filesystem) 主要包含 bootloader 和 kernel, bootloader 主要用于引導加載 kernel,

當 kernel 被加載到記憶體中后 bootfs 會被 umount 掉, rootfs (root file system) 包含的就是典型 Linux 系統中的/dev, /proc, /bin, /etc 等標準目錄和檔案, 下圖就是 docker image 中最基礎的兩層結構,不同的 linux 發行版(如 ubuntu和 CentOS ) 在 rootfs 這一層會有所區別,但是對于 docker 鏡像通常都比較小, 官方提供的 centos 基礎鏡像在 200MB 左右,一些其他版本的鏡像甚至只有幾 MB, docker 鏡像直接呼叫宿主機的內核,鏡像中只提供 rootfs,也就是只需要包括最基本的命令、工具和程式庫就可以了, 比如 alpine 鏡像,在 5M 左右,

下圖就是有兩個不同的鏡像在一個宿主機內核上實作不同的 rootfs,

在這里插入圖片描述

容器、 鏡像父鏡像:
在這里插入圖片描述

docker常用命令示例

  1. 搜索官方鏡像
# 帶指定版本號
docker search centos:7.2.1511 
# 不帶版本號默認 latest
docker search centos 
  1. 下載鏡像
docker pull 倉庫服務器:埠/專案名稱/鏡像名稱:版本號
  1. 查看本地鏡像
docker images

REPOSITORY #鏡像所屬的倉庫名稱
TAG #鏡像版本號(識別符號), 默認為 latest
IMAGE ID #鏡像唯一 ID 標示
CREATED #鏡像創建時間
VIRTUAL SIZE #鏡像的大小

  1. 鏡像匯出:可以將鏡像從本地匯出問為一個壓縮檔案,然后復制到其他服務器進行匯入使用
# 方法1
docker save centos -o /opt/centos.tar.gz
# 方法2
docker save centos > /opt/centos-1.tar.gz
  1. 查看鏡像內容:包含了鏡像的相關配置, 組態檔、分層
tar xvf centos.tar.gz
cat manifest.json
  1. 鏡像匯入:將鏡像匯入到 docker
docker load < /opt/centos.tar.gz

         洗掉鏡像

docker rmi centos
  1. 洗掉容器(-f 強制)
docker rm 容器 ID/容器名稱

 

docker命令:

  1. 命令格式
docker [OPTIONS] COMMAND
  1. 常用的COMMAND
[COMMAND]
attach      此方式進入容器的操作都是同步顯示的且 exit 后容器將被關閉
build       從Dockerfile構建一個鏡像
commit      從容器的更改中創建一個新鏡像
cp          在容器和本地檔案系統之間復制檔案/檔案夾
create      創建新容器
diff        檢查容器檔案系統上檔案或目錄的更改
events      從服務器獲取實時事件
exec        在運行的容器中運行命令
export      將容器的檔案系統匯出為tar包
history     顯示鏡像的歷史
images      列出鏡像
import      從tarball匯入內容以創建檔案系統鏡像
info        顯示整個系統的資訊
inspect     回傳Docker物件的底層資訊
kill        停止一個或多個正在運行的容器
load        從tar包或標準輸出加載鏡像
login       Log in to a Docker registry
logout      Log out from a Docker registry
logs        獲取容器的日志
pause       暫停一個或多個容器中的所有行程
port        列出容器的埠映射或特定映射
ps          列出正在運行的容器
pull        下載鏡像
push        上傳鏡像
rename      重命令一個容器
restart     重啟容器
rm          移除一個或多個容器
rmi         移除一個或多個鏡像
run         在新容器中運行命令
save        將一個或多個影像保存到tar存檔檔案(默認情況下流到STDOUT)
search      在Docker倉庫中搜索鏡像
start       啟動一個或多個處在停止狀態的容器
stats       顯示容器資源使用統計資料的實時流
stop        停止一個或多個正在運行的容器
tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
top         顯示容器的運行行程
unpause     Unpause all processes within one or more containers
update      Update configuration of one or more containers
version     查看版本
wait        阻塞直到一個或多個容器停止,然后列印它們的退出代碼

子命令幫助

docker COMMAND --help
退出容器不注銷:Ctrl + P + Q

run

在新容器中運行命令

  • 命令格式
docker run [選項] 鏡像名 [shell 命令] [引數...]

 

  • 常用選項
-p list           指定容器的埠發布到主機
-P                將所有公開的埠發布到隨機埠
--name string     為容器分配一個名稱
-d                在后臺運行容器并列印容器ID
-it               創建并進入容器
--rm              當容器退出時自動洗掉它

 例如:

  1. 啟動的容器在執行完 shell 命令就退出了
#docker run [鏡像名] [shell 命令]
docker run centos /bin/echo 'hello wold' 
  1. 從鏡像啟動一個容器:會直接進入到容器, 并隨機生成容器 ID 和名稱
docker run -it docker.io/centos bash
  1. 隨機映射埠:
    前臺啟動并隨機映射本地埠到容器的 80
docker run -P docker.io/nginx 

 

前臺啟動的會話視窗無法進行其他操作,除非退出, 但是退出后容器也會退出隨機埠映射, 其實是默認從 32768 開始

  1. 指定埠映射:

方式 1:本地埠 81 映射到容器 80 埠:

docker run -p 81:80 --name "nginx-test" nginx

方式 2:本地 IP:本地埠:容器埠

docker run -p 192.168.10.205:82:80 --name "nginx-test" docker.io/nginx

 方式 3:本地 IP:本地隨機埠:容器埠

docker run -p 192.168.10.205::80 --name "nginx-test" docker.io/nginx

方式 4:本機 ip:本地埠:容器埠/協議,默認為 tcp 協議

docker run -p 192.168.10.205:83:80/udp --name "nginx-test" docker.io/nginx

 方式 5:一次性映射多個埠+協議:

docker run -p 86:80/tcp -p 443:443/tcp -p 53:53/udp --name "nginx-test" docker.io/nginx

         5. 后臺啟動容器

docker run -d -P --name "nginx-test" docker.io/nginx
  1. 容器退出后自動洗掉
docker run -it --rm --name nginx-test docker.io/nginx
  1. 指定容器 DNS:
    Dns 服務,默認采用宿主機的 dns 地址
    一是將 dns 地址配置在宿主機
    二是將引數配置在 docker 啟動腳本里面 –dns=1.1.1.1
docker run -it --rm --dns 223.6.6.6 centos bash

 

--rm 容器退出后會洗掉容器


ps

列出正在運行的容器

  • 命令格式
docker ps [OPTIONS]
  • 常用選項
-a              顯示所有容器(默認顯示正在運行)
-f              根據提供的條件過濾輸出
-n int          顯示最后創建的n個容器(包括所有狀態)(默認值-1)
-l              顯示最新創建的容器(包括所有狀態)
--no-trunc      不截斷輸出
-q              只顯示數字id
-s              顯示總檔案大小

 例:

  1. 顯示正在運行的容器:
docker ps
  1. 顯示所有容器
docker ps -a

 


rm

移除一個或多個容器

  • 命令格式
docker rm [OPTIONS] CONTAINER [CONTAINER...]
  • 常用選項
-f        強制移除正在運行的容器(使用SIGKILL)
-l        洗掉指定鏈接
-v        洗掉與容器關聯的卷

 例:

  1. 洗掉運行中的容器:即使容正在運行當中, 也會被強制洗掉掉
docker rm -f 11445b3a84d3   # 11445b3a84d3是CONTAINER ID,通過docker ps 查詢
  1. 批量洗掉已退出容器
docker rm -f `docker ps -aq -f status=exited`
  1. 批量洗掉所有容器
docker rm -f $(docker ps -a -q)

 


logs

獲取容器的日志

  • 命令格式
docker logs [OPTIONS] CONTAINER
  • 常用選項
--details         顯示提供給日志的額外細節
-f                跟蹤日志輸出
--since string    顯示從時間戳開始的日志(如:42m表示42 分鐘)
--tail string     從日志末尾顯示的行數(默認為“all”)
-t                顯示時間戳
--until string    在時間戳前顯示日志(如:42m表示42 分鐘)

 例:

  1. 查看 Nginx 容器訪問日志
docker logs nginx-test-port3 #一次查看
docker logs -f nginx-test-port3 #持續查看

 


load

從tar存檔或STDIN加載鏡像

  • 命令格式
docker load [OPTIONS]
  • 常用選項
-i string   從tar存檔檔案中讀取,而不是從STDIN中讀取
-q          不輸出

 例:

  1. 匯入鏡像
docker load -i nginx.tar.gz

 


port

列出容器的埠映射或特定映射

  • 命令格式
docker port CONTAINER [PRIVATE_PORT[/PROTO]]
  • 例:
  1. 查看容器已經映射的埠
docker port nginx-test

 


stop

停止一個或多個正在運行的容器

  • 命令格式
docker stop [OPTIONS] CONTAINER [CONTAINER...]
  • 常用選項
-t  int   等待stop幾秒鐘后再殺死它(默認為10)

 例:

  1. 容器的關閉
docker stop f821d0cd5a99
  1. 批量關閉正在運行的容器
docker stop $(docker ps -a -q) 

 


kill

殺死一個或多個正在運行的容器

  • 命令格式
docker kill [OPTIONS] CONTAINER [CONTAINER...]
  • 常用選項
-s  string   發送到容器的信號(默認為“KILL”)

 例:

  1. 批量強制關閉正在運行的容器
docker kill $(docker ps -a -q)

 


start

啟動一個或多個停止的容器

  • 命令格式
docker start [OPTIONS] CONTAINER [CONTAINER...]
  • 常用選項
-a                      附加STDOUT/STDERR和轉發信號
--detach-keys string    覆寫用于分離容器的鍵序列
-i                      將容器的STDIN

 例:

  1. 容器的啟動
docker start f821d0cd5a99



attach

此方式進入容器的操作都是同步顯示的且 exit 后容器將被關閉

  • 命令格式
docker attach [OPTIONS] CONTAINER
  • 常用選項
--detach-keys string   覆寫用于分離容器的鍵序列
--no-stdin             不附加STDIN
--sig-proxy            代理所有接收到的行程信號(默認為true)

 例:

docker attach 63fbc2d5a3ec

 


exec

執行單次命令與進入容器,不是很推薦此方式, 雖然 exit 退出容器還在運行

  • 命令格式
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
  • 常用選項
-d                        分離模式:在后臺運行命令
--detach-keys string      覆寫用于分離容器的鍵序列
-e list                   設定環境變數
-i                        保持STDIN打開,即使沒有連接
--privileged              為該命令授予擴展特權
-t                        分配一個pseudo-TTY
-u  string                用戶名或UID(格式:< name| UID >[:<group|gid>])
-w  string                容器內的作業目錄

例:

  1. 進入容器
docker exec -it centos-test /bin/bash

 


inspect

回傳Docker物件的底層資訊

  • 命令格式
docker inspect [OPTIONS] NAME|ID ...
  • 常用選項
-f  string   使用給定的Go模板格式化輸出

例:

  1. 可以獲取到容器的 PID
# docker inspect -f "{{.State.Pid}}" centos-test3
5892

 


commit

從容器的更改中創建一個新鏡像

  • 命令格式
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
  • 常用選項
-a  string      作者
-c  list        對創建的映像應用Dockerfile指令
-m  string      提交訊息
-p              提交期間暫停容器(默認為true)

 例:

  1. 在宿主機基于容器 ID 提交為鏡像
docker commit -a "chen" -m "nginx_yum_v1" --change="EXPOSE_80_443" f5f8c13d0f9f centos-nginx:v1
  1. 提交的時候標記 tag 號:
    > 標記 tag 號,生產當中比較常用,后期可以根據 tag 標記創建不同版本的鏡像以及創建不同版本的容器,
docker commit -m "nginx image" f5f8c13d0f9f jack/centos-nginx:v1

  

Docker 鏡像與制作

Docker 鏡像有沒有內核?
從鏡像大小上面來說,一個比較小的鏡像只有十幾 MB,而內核檔案需要一百多兆, 因此鏡像里面是沒有內核的, 鏡像在被啟動為容器后將直接使用宿主機的內核, 而鏡像本身則只提供相應的 rootfs, 即系統正常運行所必須的用戶空間的檔案系統,比如/dev/, /proc, /bin, /etc 等目錄, 所以容器當中基本是沒有/boot目錄的,而/boot 當中保存的就是與內核相關的檔案和目錄,

為什么沒有內核?
由于容器啟動和運行程序中是直接使用了宿主機的內核,所以沒有直接呼叫過物理硬體, 所以也不會涉及到硬體驅動, 因此也用不上內核和驅動,另外有內核的那是虛擬機,

手動制作nginx鏡像

Docker 制作類似于虛擬機的鏡像制作,即按照公司的實際業務務求將需要安裝的軟體、相關配置等基礎環境配置完成,然后將其做成鏡像,最后再批量從鏡像批量生產實體,這樣可以極大的簡化相同環境的部署作業, Docker 的鏡像制作分為手動制作和自動制作(基于 DockerFile), 企業通常都是基于 Dockerfile 制作精細, 其中手動制作鏡像步驟具體如下:

下載鏡像并初始化系統:
基于某個基礎鏡像之上重新制作, 因此需要先有一個基礎鏡像,本次使用官方提供的 centos 鏡像為基礎:


    1. docker下載centos鏡像,并運行進入

docker pull centos
docker run -it docker.io/centos /bin/bash

 

  • 進入容器
  1. 進入容器后,更改yun源
yum install wget -y
cd /etc/yum.repos.d/
rm -rf ./*
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
  1. yum安裝nginx與常用工具
yum install –y nginx  wget pcre pcre-devel zlib zlib-devel openssl openssl-devel iproute net-tools iotop
  1. 修改nginx配置,關閉后臺運行
vim /etc/nginx/nginx.conf
    user nginx;
    worker_processes auto;
    error_log /var/log/nginx/error.log;
    pid /run/nginx.pid;
    daemon off; 

         4. 自定義 web 頁面

echo "Docker Yum Nginx" > /usr/share/nginx/html/index.html

 

  • 退出容器

          5. 提交為鏡像:在宿主機基于容器 ID 提交為鏡像

docker commit -a "xu" -m "nginx_yum_v1" --change="EXPOSE 80 4433" 75f52cfb13d2 centos-nginx:v1

 

 

帶 tag 的鏡像提交:
提交的時候標記 tag 號:
標記 tag 號,生產當中比較常用,后期可以根據 tag 標記創建不同版本的鏡像以及創建不同版本的容器,

docker commit -m "nginx image" 75f52cfb13d2  centos-nginx:v3

         6. 查看創建的鏡像

docker image ls


        7. 從自己鏡像啟動容器,因為本機用的是云主機,沒有備案和域名,所以使用4433埠映射

docker run -d -p 4433:80 --name my-centos-nginx 87e99ab0c9ab  /usr/sbin/nginx  # 87e99ab0c9ab 是IMAGE ID

8. 訪問測驗

 

 容器埠映射成功

 

Dockerfile介紹

   DockerFile 可以說是一種可以被 Docker 程式解釋的腳本, DockerFile 是由一條條的命令組成的,每條命令對應 linux 下面的一條命令, Docker 程式將這些DockerFile 指令再翻譯成真正的 linux 命令,其有自己的書寫方式和支持的命令, Docker 程式讀取 DockerFile 并根據指令生成 Docker 鏡像,相比手動制作鏡像的方式, DockerFile 更能直觀的展示鏡像是怎么產生的,有了 DockerFile,當后期有額外的需求時,只要在之前的 DockerFile 添加或者修改回應的命令即可重新生成新的 Docke 鏡像,避免了重復手動制作鏡像的麻煩,

FROM 指定基礎鏡像

定制鏡像,需要先有一個基礎鏡像,在這個基礎鏡像上進行定制,FROM 就是指定基礎鏡像,必需放在有效指令的第一行

怎么選擇合適的鏡像呢?官方有nginx、redis、mysql、httpd、tomcat等服務類的鏡像,也有作業系統類,如:centos、ubuntu、debian等,

例:

FROM centos:latest

MAINTAINER 指定維護者資訊

格式

MAINTAINER <name>

RUN 執行命令

RUN 指令是用來執行命令的,shell命令功能豐富,所以RUN 指令經常用來呼叫shell指令,

格式

RUN <command> 
# 或 
RUN ["executable", "param1", "param2"]

 

第一種不用多說,第二種方式:RUN ["/bin/bash", "-c", "echo hello world"]
Dockerfile中,每一個指令都會創建一層鏡像,RUN寫多了,創建的鏡像層數就會增多,所以一般RUN 指令的寫法為

RUN yum -y install epel-release \
      && yum -y install nginx \
      && rm -rf /usr/share/nginx/html/* \
      && echo "<h1> docker test nginx </h1>" > /usr/share/nginx/html/index.html

 

CMD 啟動容器時執行的命令

指定啟動容器時執行的命令,每個 Dockerfile 只能有一條 CMD 命令,如果指定了多條命令,只有最后一潭訓被執行,

支持三種格式

# 使用 exec 執行,推薦方式;
CMD ["executable","param1","param2"] 

# 在 /bin/sh 中執行,提供給需要互動的應用;
CMD command param1 param2 

# 提供給 ENTRYPOINT 的默認引數;
CMD ["param1","param2"] 

 

如果用戶啟動容器時候指定了運行的命令,則會覆寫掉 CMD 指定的命令,

EXPOSE 分配埠號

告訴 Docker 服務端容器暴露的埠號,供互聯系統使用,在啟動容器時需要通過 -P,Docker 主機會自動分配一個埠轉發到指定的埠

格式

EXPOSE <port> [<port>...]

ENV 環境變數

指定一個環境變數,會被后續 RUN 指令使用,并在容器運行時保持,

格式

ENV <key> <value>

例如

ENV PG_MAJOR 9.3
ENV PG_VERSION 9.3.4
RUN curl -SL http://example.com/postgres-$PG_VERSION.tar.xz | tar -xJC /usr/src/postgress && …
ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH

 

ADD 復制/解壓

該命令將復制指定的 <src> 到容器中的 <dest>, 其中<src> 可以是Dockerfile所在目錄的一個相對路徑;也可以是一個 URL;還可以是一個 tar 檔案(自動解壓為目錄)

格式

ADD <src> <dest>

COPY 復制

復制本地主機的 <src>(為 Dockerfile 所在目錄的相對路徑)到容器中的 <dest>

格式

COPY <src> <dest>

 

當使用本地目錄為源目錄時,推薦使用 COPY

ENTRYPOINT 容器啟動后執行的命令

配置容器啟動后執行的命令,并且不可被 docker run 提供的引數覆寫,

兩種格式:

ENTRYPOINT ["executable", "param1", "param2"]

# shell中執行
ENTRYPOINT command param1 param2

 

每個 Dockerfile 中只能有一個 ENTRYPOINT,當指定多個時,只有最后一個起效

VOLUME 掛載點

創建一個可以從本地主機或其他容器掛載的掛載點,一般用來存放資料庫和需要保持的資料等

格式

VOLUME ["/data"],

 

USER 指定用戶名

指定運行容器時的用戶名或 UID,后續的 RUN 也會使用指定用戶

格式

USER daemon

當服務不需要管理員權限時,可以通過該命令指定運行用戶,并且可以在之前創建所需要的用戶,

例如:

RUN groupadd -r postgres && useradd -r -g postgres postgres

 

要臨時獲取管理員權限可以使用 gosu,而不推薦 sudo,

WORKDIR 作業目錄

為后續的 RUN、CMD、ENTRYPOINT 指令配置作業目錄

格式

WORKDIR /path/to/workdir,

可以使用多個 WORKDIR 指令,后續命令如果引數是相對路徑,則會基于之前命令指定的路徑,例如

WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd

 則最終路徑為 /a/b/c,

ONBUILD

配置當所創建的鏡像作為其它新創建鏡像的基礎鏡像時,所執行的操作指令,

格式

ONBUILD [INSTRUCTION]

 例如,Dockerfile 使用如下的內容創建了鏡像 image-A,

...
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
...

如果基于 image-A 創建新的鏡像時,新的Dockerfile中使用 FROM image-A指定基礎鏡像時,會自動執行ONBUILD 指令內容,等價于在后面添加了兩條指令,

FROM image-A

#Automatically run the following
ADD . /app/src
RUN /usr/local/bin/python-build --dir /app/src

使用 ONBUILD 指令的鏡像,推薦在標簽中注明,例如 ruby:1.9-onbuild

構建鏡像

格式

docker build [選項] 路徑

   -t選項,指定鏡像的標簽資訊

docker build -t nginx:v1 /usr/local/src/

 

構建時,目錄內除了構建所需要的檔案,不要有其它檔案


DockerFile 制作yum版 nginx 鏡像:

  1. 準備目錄
mkdir -pv /opt/dockerfile/web/nginx
  1. 撰寫dockerfile檔案
vim /opt/dockerfile/web/nginx/Dockerfile
#Nginx web image

FROM centos:latest

RUN yum install epel-release -y
RUN yum install nginx -y && rm -rf /usr/share/nginx/html/*
ADD html.tar.gz /usr/share/nginx/html/
#copy 

EXPOSE 80 443 8080

CMD ["/usr/sbin/nginx","-g","daemon off;"]

 

RUN就是運行shell命令
ADD

  1. 創建網頁測驗檔案
vi /opt/dockerfile/web/nginx/index.html
<h1> docker nginx test, nginx container by dockerfile</h1>
  1. 打包網頁測驗檔案
tar czvf html.tar.gz index.html
  1. 構建鏡像,也可以把此命令寫到腳本里方便以后運行
docker build -t chenjb/centos-nginx /opt/dockerfile/web/nginx/

構建 

 

        6. 查看鏡像

docker images

  1. 啟動容器
docker run -it -d -p 80:80 --name "nginx-test" chenjb/centos-nginx 
  1. 查看行程
docker ps

  1. 測驗網頁,本機用的是云主機還得配置安全組有點麻煩,這里就直接使用命令列進行測驗了

# curl 127.0.0.1:8355
<h1> docker nginx test, nginx container by dockerfile</h1>

  

DockerFile 制作編譯版 nginx 鏡像:

下載鏡像并初始化系統:

docker pull centos
mkdir -pv /opt/dockerfile/web/nginx

 

目錄結構按照業務型別或系統型別等方式劃分,方便后期鏡像比較多的時候進行分類

撰寫 Dockerfile:

vim /opt/dockerfile/web/nginx/Dockerfile

 

生成的鏡像的時候會在執行命令的當前目錄查找 Dockerfile 檔案, 所以名稱不可寫錯, 而且 D 必須大寫
My Dockerfile
"#"為注釋,等于 shell 腳本的中#
除了注釋行之外的第一行,必須是 From xxx (xxx 是基礎鏡像)

# 第一行先定義基礎鏡像,后面的本地有效的鏡像名,如果本地沒有會從遠程倉庫下載,第一行很重要
From centos:latest

# 鏡像維護者的資訊: 
MAINTAINER han 583343636@qq.com

#自動解壓壓縮包
ADD nginx-1.16.1.tar.gz /usr/local/src/ 
#執行的命令,將編譯安裝 nginx 的步驟執行一遍
RUN rpm -ivh http://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm
RUN yum install -y vim wget tree lrzsz gcc gcc-c++ automake pcre pcre-devel zlib zlib-devel openssl openssl-devel iproute net-tools iotop

RUN cd /usr/local/src/nginx-1.16.1 && ./configure --prefix=/usr/local/nginx --with-http_sub_module && make && make install
RUN cd /usr/local/nginx/
ADD nginx.conf /usr/local/nginx/conf/nginx.conf
RUN useradd nginx -s /sbin/nologin
RUN ln -sv /usr/local/nginx/sbin/nginx /usr/sbin/nginx
RUN echo "Nginx-make version 1.16.1 test page" > /usr/local/nginx/html/index.html

# 向外開放的埠,多個埠用空格做間隔,啟動容器時候-p 需要使用此端向外映射,如: -p 8081:80,則 80 就是這里的 80
EXPOSE 80 443 

# 運行的命令,每個 Dockerfile 只能有一條,如果有多條則只有最后一條被執行
CMD ["nginx","-g","daemon off;"] 

#如果在從該鏡像啟動容器的時候也指定了命令,那么指定的命令會覆寫Dockerfile 構建的鏡像里面的 CMD 命令,即指定的命令優先級更高, Dockerfile 的優先級較低一些

準備原始碼包與組態檔:

  1. 配置nginx檔案,并關閉后臺運行添加配置 daemon   off 
cp /usr/local/nginx/conf/nginx.conf /opt/dockerfile/web/nginx
  1. nginx 原始碼包
cp /usr/local/src/nginx-1.16.1.tar.gz /opt/dockerfile/web/nginx 
  1. 執行鏡像構建
docker build –t jack/nginx-1.16.1:v1 /opt/dockerfile/web/nginx/

         4. 開始構建:可以清晰看到各個步驟執行的具體操作

構建成功了

 

         5. 查看是否生成本地鏡像,如果構建時出錯可能會導致生成名字為none的鏡像,使用命令洗掉即可

 docker images

  docker rmi -f $(docker images | grep "none" | awk '{print $3}')  #過濾出倉庫名和tag名為none的鏡像ID并強制洗掉

         6. 從鏡像啟動容器

 docker run -d -p 80:80 --name mak1e-nginx peterhx/nginx-make-1.16.1:v1  /usr/sbin/nginx

 

  1. 訪問 web 界面

 

制作 tomcat 鏡像:

基于官方提供的 centos 7.6. 基礎鏡像構建 JDK 和 tomcat 鏡像,先構建 JDK 鏡像,然后再基于 JDK 鏡像構建 tomcat 鏡像,

1、先構建 JDK 鏡像

  1. 下載基礎鏡像 Centos:
docker pull centos
  1. 執行構建 JDK 鏡像:
mkdir -pv /opt/dockerfile/{web/{nginx,tomcat,jdk,apache},system/{centos,ubuntu,redhat}}  
cd /opt/dockerfile/web/jdk/
  1. 編輯Dockerfile
# JDK Base Images
FROM centos:latest

ADD jdk-8u212-linux-x64.tar.gz /usr/local/src/
RUN ln -sv /usr/local/src/jdk1.8.0_212 /usr/local/jdk
ADD profile /etc/profile
ENV JAVA_HOME /usr/local/jdk
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/:$JRE_HOME/lib/
ENV PATH $PATH:$JAVA_HOME/bin

RUN rm -rf /etc/localtime \
      && ln -snf /usr/share/zoneinfo/Asia/Shanghai/etc/localtime \
      && echo "Asia/Shanghai" > /etc/timezone
  1. 上傳 JDK 壓縮包和 profile 檔案:
    將 JDK 壓縮包上傳到 Dockerfile 當前目錄,然后執行構建:

profile檔案內容,(最下邊宣告的環境變數,其他的一樣)

# cat profile
###########################
# System wide environment and startup programs, for login setup # Functions and aliases go in /etc/bashrc # It's NOT a good idea to change this file unless you know what you # are doing. It's much better to create a custom.sh shell script in # /etc/profile.d/ to make custom changes to your environment, as this # will prevent the need for merging in future updates. pathmunge () { case ":${PATH}:" in *:"$1":*) ;; *) if [ "$2" = "after" ] ; then PATH=$PATH:$1 else PATH=$1:$PATH fi esac } if [ -x /usr/bin/id ]; then if [ -z "$EUID" ]; then # ksh workaround EUID=`/usr/bin/id -u` UID=`/usr/bin/id -ru` fi USER="`/usr/bin/id -un`" LOGNAME=$USER MAIL="/var/spool/mail/$USER" fi # Path manipulation if [ "$EUID" = "0" ]; then pathmunge /usr/sbin pathmunge /usr/local/sbin else pathmunge /usr/local/sbin after pathmunge /usr/sbin after fi HOSTNAME=`/usr/bin/hostname 2>/dev/null` HISTSIZE=1000 if [ "$HISTCONTROL" = "ignorespace" ] ; then export HISTCONTROL=ignoreboth else export HISTCONTROL=ignoredups fi export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE HISTCONTROL # By default, we want umask to get set. This sets it for login shell # Current threshold for system reserved uid/gids is 200 # You could check uidgid reservation validity in # /usr/share/doc/setup-*/uidgid file if [ $UID -gt 199 ] && [ "`/usr/bin/id -gn`" = "`/usr/bin/id -un`" ]; then umask 002 else umask 022 fi for i in /etc/profile.d/*.sh /etc/profile.d/sh.local ; do if [ -r "$i" ]; then if [ "${-#*i}" != "$-" ]; then . "$i" else . "$i" >/dev/null fi fi done unset i unset -f pathmunge export JAVA_HOME=/usr/local/jdk export TOMCAT_HOME=/apps/tomcat export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$TOMCAT_HOME/bin:$PATH export CLASSPATH=.$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$JAVA_HOME/lib/tools.jar

執行構建

cat build-command.sh 
#!/bin/bash
docker build -t centos-jdk1.8:v1 .

 

 

 

        5. 啟動容器

docker run -it centos-jdk1.8:v1  bash

 進入容器后,要能查看到Java的環境(如果查不出來等于白做,檢查是哪個環節出錯)

 

 

2、從 JDK 鏡像構建 tomcat-8 鏡像

  1. 進入tomcat目錄:
cd /opt/dockerfile/web/tomcat
  1. 編輯Dockerfile檔案
vim Dockerfile
FROM centos-jdk:v1
RUN useradd www -u 2020

ENV TZ "Asia/Shanghai"
ENV LANG en_US.UTF-8
ENV TERM xterm
ENV TOMCAT_MAJOR_VERSION 8
ENV TOMCAT_MINOR_VERSION 8.0.49
ENV CATALINA_HOME /apps/tomcat
ENV APP_DIR ${CATALINA_HOME}/webapps

RUN mkdir /apps
ADD apache-tomcat-8.5.42.tar.gz /apps
RUN ln -sv /apps/apache-tomcat-8.5.42 /apps/tomcat
  1. 上傳 tomcat 壓縮包:apache-tomcat-8.5.42.tar.gz

  2. 通過腳本構建 tomcat 基礎鏡像

# cat build-command.sh 
#!/bin/bash
docker build -t tomcat85:v1 .

 

  1. 驗證鏡像構建完成
docker images

  1. 構建業務鏡像 app1:
mkdir -p /opt/dockerfile/app/tomcat-app1
cd /opt/dockerfile/app/tomcat-app1/
  1. 準備 Dockerfile:
vim Dockerfile
FROM tomcat85:v1
ADD run_tomcat.sh /apps/tomcat/bin/run_tomcat.sh
ADD myapp/* /apps/tomcat/webapps/myapp/
RUN chown www.www /apps/ -R
RUN chmod +x /apps/tomcat/bin/run_tomcat.sh
EXPOSE 8080 8009
CMD ["/apps/tomcat/bin/run_tomcat.sh"]
  1. 準備自定義 myapp 頁面:
mkdir myapp
echo "Docker Tomcat Web Page1" > myapp/index.html
  1. 準備容器啟動執行腳本:
 vim run_tomcat.sh
#!/bin/bash echo "10.10.10.10 tom.test.com" >> /etc/hosts echo "nameserver 223.5.5.5" > /etc/resolv.conf su - www -c "/apps/tomcat/bin/catalina.sh start" su - www -c "tail -f /etc/hosts"
  1. 運行命令或執行腳本構建Tomcat-app1鏡像
 cat build-command.sh 
#!/bin/bash
docker build -t tomcat85-app1:v1 .

 

 

  1. 查看鏡像
docker images

  1. 從鏡像啟動容器測驗:
docker run -d -p 8888:8080 tomcat85-app1:v1

 訪問測驗

 

 

制作 haproxy 鏡像:

  1. 進入目錄
mkdir -pv /opt/dockerfile/app/haproxy
cd /opt/dockerfile/app/haproxy

 

  1. 準備 Dockerfile:
vim Dockerfile
#Haproxy Base Image
FROM centos
ADD haproxy-2.0.5.tar.gz /usr/local/src/

RUN yum install gcc gcc-c++ glibc glibc-devel pcre \
                pcre-devel openssl openssl-devel systemd-devel \
                net-tools vim iotop bc zip unzip zlib-devel lrzsz \
                tree screen lsof tcpdump wget ntpdate –y \
      && cd /usr/local/src/haproxy-2.0.5 \
      && make ARCH=x86_64 TARGET=linux-glibc \
              USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 \
              USE_SYSTEMD=1 USE_CPU_AFFINITY=1 \
              PREFIX=/usr/local/haproxy \
      && make install PREFIX=/usr/local/haproxy \
      && cp haproxy /usr/sbin/ \
      && mkdir /usr/local/haproxy/run
ADD haproxy.cfg /etc/haproxy/
ADD run_haproxy.sh /usr/bin
RUN chmod +x /usr/bin/run_haproxy.sh
EXPOSE 80 9999
CMD ["/usr/bin/run_haproxy.sh"]
  1. 準備 haproxy 原始碼檔案:haproxy-2.0.5.tar.gz

  2. 準備run_haproxy.sh腳本

vim run_haproxy.sh
#!/bin/bash
haproxy -f /etc/haproxy/haproxy.cfg
tail -f /etc/hosts
  1. 準備 haproxy 組態檔:
vim haproxy.cfg
global
chroot /usr/local/haproxy
#stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin
uid 99
gid 99
daemon
nbproc 1
pidfile /usr/local/haproxy/run/haproxy.pid
log 127.0.0.1 local3 info

defaults
option http-keep-alive
option forwardfor
mode http
timeout connect 300000ms
timeout client 300000ms
timeout server 300000ms

listen stats
mode http
bind 0.0.0.0:9999
stats enable
log global
stats uri /haproxy-status
stats auth haadmin:q1w2e3r4ys

listen web_port
bind 0.0.0.0:80
mode http
log global
balance roundrobin
server web1 192.168.99.21:8888 check inter 3000 fall 2 rise 5
server web2 192.168.99.22:8889 check inter 3000 fall 2 rise 5

        6. 準備構建腳本:

docker build -t haproxy:v1 .

         7. 從鏡像啟動容器:

docker run -it -d -p 80:80 -p 9999:9999 haproxy:v1

         8. web 訪問驗證

在這里插入圖片描述

9. 訪問tomcat業務app1

在這里插入圖片描述

 

本地鏡像上傳至官方 docker 倉庫:

將自制的鏡像上傳至 docker 倉庫; https://hub.docker.com/

  1. 準備賬戶:
    登錄到 docker hub 創建官網創建賬戶, 登錄后點擊 settings 完善賬戶資訊,填寫賬戶基本資訊

     

  2. 在虛擬機使用自己的賬號登錄

docker login docker.io

 

  1. 查看認證資訊:
    #登錄成功之后會在當前目錄生成一個隱藏檔案用于保存登錄認證資訊
[root@Server1 ~]# cat /root/.docker/config.json
{
    "auths": {
        "https://index.docker.io/v1/": {
            "auth": "cGV0ZXJoeDo5NjExMjFoeC4="
        },
        "registry.cn-beijing.aliyuncs.com": {
            "auth": "NTgzMzQzNjM2QHFxLmNvbTo5NjExMjFoeA=="
        }
    },
    "HttpHeaders": {
        "User-Agent": "Docker-Client/19.03.8 (linux)"
    }
}
  1. 查看鏡像 ID
docker images
  1. 根據規定的格式給鏡像修改tag版本號 并上傳到docker倉庫中

 

 

 

docker tag a187dde48cd2 peterhx/alpine-test:alpine123
docker push peterhx/alpine-test:alpine123
  1. 上傳完成

7. 到 docker 官網驗證

 

 

8. 更換到其他 docker 服務器下載鏡像

# 登錄 
docker login docker.io
# 下載 
docker pull peterhx/alpine-test:alpine123
# 查看 
docker images
  1. 從鏡像啟動一個容器
docker run -it peterhx/alpine-test:alpine123 bash

  

docker 倉庫之分布式 Harbor

Harbor 是一個用于存盤和分發 Docker 鏡像的企業級 Registry 服務器,由vmware 開源,其通過添加一些企業必需的功能特性,例如安全、標識和管理等,擴展了開源 Docker Distribution,作為一個企業級私有 Registry 服務器,Harbor 提供了更好的性能和安全,提升用戶使用 Registry 構建和運行環境傳輸鏡像的效率, Harbor 支持安裝在多個 Registry 節點的鏡像資源復制,鏡像全部保存在私有 Registry 中, 確保資料和知識產權在公司內部網路中管控, 另外,Harbor 也提供了高級的安全特性,諸如用戶管理,訪問控制和活動審計等,

官網地址: https://vmware.github.io/harbor/cn/,
官方 github 地址:https://github.com/vmware/harbor

Harbor 功能官方介紹:

基于角色的訪問控制:用戶與 Docker 鏡像倉庫通過“專案”進行組織管理,一個用戶可以對多個鏡像倉庫在同一命名空間(project)里有不同的權限,鏡像復制:鏡像可以在多個 Registry 實體中復制(同步),尤其適合于負載均衡,高可用,混合云和多云的場景,圖形化用戶界面:用戶可以通過瀏覽器來瀏覽,檢索當前 Docker 鏡像倉庫,管理專案和命名空間,

AD/LDAP: Harbor 可以集成企業內部已有的 AD/LDAP,用于鑒權認證管理,

審計管理:所有針對鏡像倉庫的操作都可以被記錄追溯,用于審計管理,國際化:已擁有英文、中文、德文、日文和俄文的本地化版本,更多的語言將會添加進來,RESTful API - RESTful API :提供給管理員對于 Harbor 更多的操控, 使得與其它管理軟體集成變得更容易,

部署簡單:提供在線和離線兩種安裝工具, 也可以安裝到 vSphere 平臺(OVA 方式)虛擬設備,

安裝 Harbor:

下載地址:
https://github.com/goharbor/harbor/releases

安裝檔案:
https://github.com/vmware/harbor/blob/master/docs/installation_guide.md

本次使用 harbor 版本 1.2.2 離線安裝包,具體名稱為 harbor-offline-installer-v1.7.5.tgz

下載 Harbor 安裝包:

方式1:下載離線安裝包:https://github.com/goharbor/harbor/releases

cd /usr/local/src/
wget https://storage.googleapis.com/harbor-releases/release-1.7.0/harbor-offline-installer-v1.7.5.tgz

 

方式2:下載在線安裝包

cd /usr/local/src/
wget https://storage.googleapis.com/harbor-releases/release-1.7.0/harbor-online-installer-v1.7.5.tgz

 

 

配置安裝 Harbor: 

在另一臺云主機的機器(內網IP為:192.168.0.59)上安裝harbor倉庫

  1. 解壓
tar xf harbor-offline-installer-v1.7.5.tgz
ln -sv /usr/local/src/harbor /usr/local/
  1. 下載docker-compose
cd /usr/local/harbor/
 yum install python-pip epel-release -y 
pip install docker-compose

 安裝docker-compose時報錯,缺少依賴及python的開發環境,yum install -y gcc python-devel 即可

  1. 修改harbor的組態檔,最終配置如下,只修改前兩個即可,其余的根據需要修改
# vim harbor.cfg
...
hostname = 192.168.0.59
...
harbor_admin_password = harbor123
...

其它配置說明

# 寫本機ip,不要寫localho
st或127.
0.0.1 hostname = 192.168.0.59 # 訪問UI和令牌/通知服務的協議 ui_url_protocol = http # harbor DB的根用戶的密碼 db_password = root123 # 最大行程數 max_job_workers = 3 # 確定是否為注冊表的令牌生成證書 customize_crt = on # 證書路徑 ssl_cert = /data/cert/server.crt ssl_cert_key = /data/cert/server.key # 密鑰存盤的路徑 secretkey_path = /data # Admiral的url,注釋此屬性,或在Harbor獨立時將其值設定為NA admiral_url = NA # Clair的postgres資料庫的密碼 clair_db_password = root123 # 電子郵件服務器 email_identity = harbor email_server = smtp.qq.com email_server_port = 25 email_username = [email protected] email_password = 123 email_from = admin <[email protected]> email_ssl = false email_insecure = false # 啟動后從UI更改管理密碼, harbor_admin_password = root123 # 如果希望根據LDAP服務器驗證用戶的憑證,請將其設定為ldap_auth, auth_mode = db_auth ldap_url = ldaps://ldap.mydomain.com ldap_basedn = ou=people,dc=mydomain,dc=com ldap_uid = uid ldap_scope = 3 ldap_timeout = 5 # 打開或關閉自注冊功能 self_registration = on # 令牌服務創建的令牌的過期時間 token_expiration = 30 # 設定為“adminonly”,以便只有管理員用戶才能創建專案 # 默認值“everyone”允許每個人創建一個專案 project_creation_restriction = everyone # verify_remote_cert = on

     4. 準備

./prepare

 docker-compose.yml 檔案,用于配置資料目錄等配置資訊    

 

       5. 運行當前目錄下的腳本開始安裝

./install.sh

 

安裝完成,可以通過設定的連接通過瀏覽器進行訪問(默認使用的是80,加密埠是443,此主機沒有備案所以下面還需要修改一下埠)

后期修改配置:

如果 harbor 運行一段時間之后需要更改配置,則步驟如下:這里順便修改一下harbor倉庫的訪問的默認埠
1. 先停止 harbor:

cd /usr/local/harbor
docker-compose stop 

2. 編輯 harbor.cfg 進行相關配置:(修改之前一定要記得先copy一份)

vim harbor.cfg  # 主組態檔不需要修改

# 修改docker-compose.yml檔案,默認訪問的埠映射為888埠

① 這里修改了兩個埠 80改為888,443改為了4433

 

② 修改完之后還要修改一個檔案

# pwd
/usr/local/harbor/common/templates/registry
[root@Server2 registry]# ls
config.yml  config.yml.bak  root.crt
[root@Server2 registry]# vim config.yml

url后加上修改后的默認埠,保存退出

 

 ③ 修改docker的啟動檔案

#vim /usr/lib/systemd/system/docker.service  修改如下一行
ExecStart=/usr/bin/dockerd --insecure-registry=x.x.x.x:888

修改后重新加載并重啟服務

systemctl daemon-reload && systemctl restart docker.service

3. prepare

./prepare

4. 啟動 harbor 服務:

docker-compose start

 登錄測驗一下,登錄成功

 

 

常見的2個報錯資訊解答:

(1)Error response from daemon: Get https://192.168.0.59/v1/users/: dial tcp 192.168.0.59:443: getsockopt: connection refused

(2)Error response from daemon: Get https://192.168.0.59:888/v1/users/: http: server gave HTTP response to HTTPS client

報這2個錯誤的都是如下2個原因:

1、是埠錯了!

2、未在docker啟動檔案中添加--insecure-registry信任關系!

大多數這個錯誤是第2個原因,因為你沒有添加信任關系的話,docker默認使用的是https協議,所以埠不對(443),會報連接拒絕這個錯誤;

或者提示你 "服務器給HTTPS端的是HTTP回應" 這個錯誤,因為你沒添加埠信任,服務器認為這是默認的https訪問,回傳的卻是http資料!

 

解決方法:

正確的添加信任關系包括埠號:

--insecure-registry=192.168.0.59:888

一定要把主機與埠同時添加進去!

繼續

  1. 查看本地的鏡像

 2. 查看本地埠

3. web 瀏覽器訪問 Harbor 管理界面

 

 如果可以正常登錄就說明之前的配置沒毛病,下面就可上傳鏡像了

 

配置 docker 使用 harbor 倉庫上傳下載鏡像:

  1. 編輯 docker 組態檔:
    注意:如果我們配置的是 https 的話,本地 docker 就不需要有任何操作就可以訪問 harbor 了,在第一臺主機的docker啟動檔案中也添加上內網harbor倉庫的地址
vim /lib/systemd/system/docker.service

ExecStart追加

ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --insecure-registry 192.168.0.59:888
  1. 重啟 docker 服務:
systemctl daemon-reload && systemctl restart docker
  1. 驗證能否登錄 harbor:
docker login 192.168.0.59:888

 

 如果這里突然遇到密碼錯誤(確認不是忘記了密碼),可以試試重啟docker-compose

docker-compose stop
docker-compose start
  1. 從server1匯入一個小鏡像,
docker load < /root/alpine.tar.gz
  1. 驗證鏡像匯入成功(至少要有個鏡像,沒有的話按照上面匯入)
docker images
  1. 鏡像打 tag:
    > 修改 images 的名稱,不修改成指定格式無法將鏡像上傳到 harbor 倉庫,格式為: HarborIP/專案名/image 名字:版本號:

首先要新建一個專案,進入專案里,右側推送鏡像,按照指定格式進行修改才能上傳到此專案中來

  1. 查看鏡像
docker images

 

  1. 修改鏡像的tag號因為使用的埠不一樣,如果是443埠就不需要帶埠號,不過目前也還沒有配置加密證書所以還得帶著埠號才可以
docker tag alpine:latest X.X.X.X:888/alpine/alpine-test2:v4

 

  1. 將鏡像 push 到 harbor:因為默認上傳時使用加密的傳輸方式也就是https,這里因為修改了埠所以有些區別

    格式為: docker push 鏡像名:版本

docker push x.x.x.x:888/alpine/alpine-test2:v4
  1. push 完成
  2. harbor 界面驗證鏡像上傳成功

  3. 驗證鏡像資訊

 

從 harbor 下載鏡像并啟動容器:

  1. 更改 docker 組態檔:
    目前凡是需要從 harbor 鏡像服務器下載 image 的 docker 服務都要更改,不更改的話無法下載:
sudo vim /lib/systemd/system/docker.service
在ExecStart追加 ExecStart
=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --insecure-registry 192.168.0.59:888
  1. 重啟 docker:
systemctl daemon-reload
systemctl restart docker

 

       3. 查看下載命令:

 

 

  1. 執行下載:

docker pull X.X.X.X:888/alpine/alpine-test2:v4
  1. 驗證鏡像下載完成

 

  1. 啟動容器:
docker run -it x.x.x.x:888/alpine/alpine-test2:v4 sh

 

7. 成功啟動,并可以正常使用


 

實作 harbor 高可用:

Harbor 支持基于策略的 Docker 鏡像復制功能, 這類似于 MySQL 的主從同步, 其可以實作不同的資料中心、 不同的運行環境之間同步鏡像, 并提供友好的管理界面,大大簡化了實際運維中的鏡像管理作業,已經有用很多互聯網公司使用harbor 搭建內網 docker 倉庫的案例,并且還有實作了雙向復制的案列,本文將實作單向復制的部署:
1. 新部署一臺 harbor2 服務器192.168.0.36
程序見前一節

  1. 驗證從 harbor 登錄,harbor2

     

     

  • 主 harbor :192.168.0.59

復制的原理是從源harbor上推到目標harbor,所以下面的配置是要在之前創建的harbor上配置,
主harbor:192.168.0.59
從harbor:192.168.0.36

  1.  harbor:創建目標
    在這里插入圖片描述
  2. harbor:測驗連接成功后,確定

 

 

 

 

 


  1. harbor2:創建一個 alpine 專案:
    與主 harbor1 專案名稱保持一致:
    在這里插入圖片描述

  2. harbor:配置復制
    在這里插入圖片描述

  3. harbor:點擊復制,新建規則:
    在這里插入圖片描述

  4. harbor:編輯同步策略

     

     

  5. harbor:查看鏡像同步狀態

     

     

  6. harbor:查看鏡像是否同步成功

     


測驗從 harbor 鏡像下載和容器啟動:

  1. 編輯 docker 組態檔:
vim /lib/systemd/system/docker.service

ExecStart追加

ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --insecure-registry 192.168.0.36:888 --insecure-registry 192.168.0.59:888

 

其中 192.168.0.36/59 是我們部署 Harbor 的地址,即 hostname 配置項值,配置完后需要重啟 docker 服務,

 

 

  1. 重啟 docker 服務:
systemctl daemon-reload
systemctl restart docker

 

  1. 從 harbor 專案設定為公開:
    在這里插入圖片描述

     

  2. docker 客戶端下載鏡像

docker pull 192.168.0.36:888/alpine/alpine111:v10

         5. 下載完后查看鏡像

  1. docker 客戶端從鏡像啟動容器:
docker run -it 192.168.0.36:888/alpine/alpine111:v10 sh

 

 如果可以從新harbor2上拉取鏡像并運行,就說明harbor已經高可用且同步成功

至此,高可用模式的 harbor 倉庫部署完畢

 

Docker 資料管理

如果運行中的容器修如果生成了新的資料或者修改了現有的一個已經存在的檔案內容,那么新產生的資料將會被復制到讀寫層進行持久化保存,這個讀寫層也就是容器的作業目錄,此即“寫時復制(COW) copy on write”機制
在這里插入圖片描述

資料型別:

Docker 的鏡像是分層設計的,底層是只讀的,通過鏡像啟動的容器添加了一層可讀寫的檔案系統,用戶寫入的資料都保存在這一層當中,如果要將寫入的資料永久生效,需要將其提交為一個鏡像然后通過這個鏡像在啟動實體,然后就會給這個啟動的實體添加一層可讀寫的檔案系統,目前 Docker 的資料型別分為兩種, 一是資料卷, 二是資料容器,資料卷類似于掛載的一塊磁盤,資料容器是將資料保存在一個容器上
在這里插入圖片描述

  1. 查看指定 PID 的容器資訊
docker inspect f55c55544e05 

 

在這里插入圖片描述

LowerDir: image 鏡像層(鏡像本身,只讀)
UpperDir:容器的上層(讀寫)
MergedDir:容器的檔案系統,使用 Union FS(聯合檔案系統)將 lowerdir 和
WorkDir:容器在 宿主機的作業目錄

什么是資料卷(data volume):

資料卷實際上就是宿主機上的目錄或者是檔案,可以被直接 mount 到容器當中使用,

實際生成環境中,需要針對不同型別的服務、 不同型別的資料存盤要求做相應的規劃, 最終保證服務的可擴展性、 穩定性以及資料的安全性,

如下圖:
在這里插入圖片描述

左側是無狀態的 http 請求服務, 右側為有狀態,
下層為不需要存盤的服務,上層為需要存盤的部分服務

創建 APP 目錄并生成 web 頁面:

此 app 以資料卷的方式,提供給容器使用, 比如容器可以直接宿主機本地的 web_app,而需要將代碼提前添加到容器中,此方式適用于小型 web 站點,

mkdir /data/testapp –p
echo "testapp page" > /data/testapp/index.html

在宿主機或容器修改資料

  1. 給目錄下添加index檔案
mkdir /data/app
echo "docker volume Pages1" > /data/app/index.html

啟動容器并驗證資料:

啟動兩個容器, web1 容器和 web2 容器, 分別測驗能否在容器內訪問到宿主機的添加的資料,
注意使用 -v 引數, 將宿主機目錄映射到容器內部, web2 的 ro 標示在容器內對該目錄只讀,默認是可讀寫的:

docker run -d --name web1  -v /data/app/:/usr/share/nginx/html  -p 85:80 nginx
docker run -d --name web2  -v /data/app/:/usr/share/nginx/html:ro -p 86:80 nginx

2、web 界面訪問(這里使用命令列測驗)

3、洗掉容器

    洗掉容器的時候指定引數-v, 可以洗掉/var/lib/docker/containers/的容器資料目錄,但是不會洗掉資料卷的內容

docker rm -fv d044730c0f4f

 

資料卷的特點及使用:

1、資料卷是宿主機的目錄或者檔案,并且可以在多個容器之間共同使用,
2、 在宿主機對資料卷更改資料后會在所有容器里面會立即更新,
3、資料卷的資料可以持久保存,即使洗掉使用使用該容器卷的容器也不影響,
4、 在容器里面的寫入資料不會影響到鏡像本身,

檔案掛載:
檔案掛載用于很少更改檔案內容的場景, 比如 nginx 的組態檔、 tomcat 的組態檔等


資料卷使用場景:
1、 日志輸出
2、 靜態 web 頁面
3、 應用組態檔
4、 多容器間目錄或檔案共享

 

如何一次掛載多個目錄

  1. 多個目錄可以位于不同的目錄下
mkdir /data/xuecho "xu" > /data/xu/index.html
  1. 啟動容器
docker run -ti -d --name web1 -p 85:80 \
      -v /data/app/nginx.conf:/etc/nginx/nginx.conf:ro \
      -v /data/nginx/:/usr/share/nginx/html \
      nginx

          3. 驗證 web 訪問

資料卷容器:

       資料卷容器功能是可以讓資料在多個 docker 容器之間共享,即可以讓 B 容器訪問 A 容器的內容,而容器 C 也可以訪問 A 容器的內容,\

即先要創建一個后臺運行的容器作為 Server,用于卷提供, 這個卷可以為其他容器提供資料存盤服務,其他使用此卷的容器作為 client 端:

啟動一個卷容器 Server:

先啟動一個容器, 并掛載宿主機的資料目錄:
將宿主機的 catalina.sh 啟動腳本和 chen 的 web 頁面,分別掛載到卷容器 server端,然后通過 server 端共享給 client 端使用,

docker run -d --name volume-server \
      -v /data/app/nginx.conf:/etc/nginx/nginx.conf:ro \
      -v /data/nginx:/usr/share/nginx/html \
      nginx
  1. 啟動兩個端容器 Client
docker run -d --name web1 -p 85:80 \
      --volumes-from volume-server nginx

docker run -d --name web2 -p 86:80 \
      --volumes-from volume-server nginx
  1. 其實實質就是把掛載在其它容器的卷,再掛到其它容器上
docker run -d --name web3 -p 83:80 \
      --volumes-from web2 nginx
  1. 測驗訪問 web 頁面

三個容器訪問到的資料是一樣的

 

  1. 進入其它一個容器,修改網站的默認測驗頁面

docker exec -it 85466a0c2fda bash

 

5. 驗證宿主機資料

#  cat /data/nginx/index.html
3333
  1. 關閉卷容器 Server 測驗能否啟動新容器:
docker stop volume-server
docker run -d --name web6 -p 86:80 \
      --volumes-from volume-server nginx

停止了卷服務的容器,還可以從這個卷服務容器啟動新的容器

  1. 測驗洗掉源卷容器 Server 創建容器
docker rm -fv volume-server

[root@Server1 ~]# docker run -d --name web7 -p 87:80 --volumes-from volume-server nginx
docker: Error response from daemon: No such container: volume-server.

# 這里就不行了,報錯

  1. 測驗之前的容器是否正常——已經運行的容器不受任何影響
    之前已啟動的容器不受影響

重新創建容器卷 Server

docker run -d --name volume-server \
      -v /data/app/nginx.conf:/etc/nginx/nginx.conf:ro \
      -v /data/nginx:/usr/share/nginx/html \
      nginx

 

創建出 volume server 之后, 就可以創建基于 volume server 的新容器,

docker run -d --name web8 -p 88:80 \
      --volumes-from volume-server nginx

 

   在當前環境下, 即使把提供卷的容器 Server 洗掉, 已經運行的容器 Client 依然可以使用掛載的卷, 因為容器是通過掛載訪問資料的, 但是無法創建新的卷容器客戶端, 但是再把卷容器 Server 創建后即可正常創建卷容器 Client,

此方式可以用于線上共享資料目錄等環境, 因為即使資料卷容器被洗掉了,其他已經運行的容器依然可以掛載使用

   資料卷容器可以作為共享的方式為其他容器提供檔案共享,類似于 NFS 共享,可以在生產中啟動一個實體掛載本地的目錄,然后其他的容器分別掛載此容器的目錄,即可保證各容器之間的資料一致性,

 

十五:

主要介紹docker網路相關知識,docker服務安裝完成之后,至少在每個主機機會生成一個名稱為docker0的網卡
其IP地址都是172.17.0.1/16,并且會生成某種不同型別的網路,如下圖:

 

 

docker結合負載實作網站高可用:

整體規劃圖:
下圖為一個小型的網路架構圖,其中nginx使用docker運行
在這里插入圖片描述

服務器名系統ip
服務器1 centos 7.6 192.168.99.101
服務器2 centos 7.6 192.168.99.102
碼頭工人1 Ubuntu的04.04 192.168.99.22
碼頭工人2 Ubuntu的04.04 192.168.99.23

1.安裝并配置keepalived

  1. Server1安裝
yum install keepalived haproxy -y

vim /etc/keepalived/keepalived.conf
...
! Configuration File for keepalived

global_defs {
   notification_email {
           root@localhost
   }
   notification_email_from root@localhost
   smtp_server localhost
   smtp_connect_timeout 30
   router_id LVS_DEVEL1
   vrrp_skip_check_adv_addr
#vrrp_strict
   vrrp_iptables
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}
vrrp_instance MAKE_VIP_INT {
      state MASTER
      interface eth0
      virtual_router_id 1
      priority 100
      authentication {
            auth_type PASS
            auth_pass 1111
      }
      virtual_ipaddress {
            192.168.99.10 dev eth0 label eth0:1
      }
}

 

啟動

systemctl restart keepalived 
systemctl enable keepalived

 

  1. Server2安裝
yum install keepalived haproxy –y

 

配置

vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived

global_defs {
   notification_email {
           root@localhost
   }
   notification_email_from root@localhost
   smtp_server localhost
   smtp_connect_timeout 30
   router_id LVS_DEVEL2
   vrrp_skip_check_adv_addr
#vrrp_strict
   vrrp_iptables
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}
vrrp_instance MAKE_VIP_INT {
      state BACKUP
      interface eth0
      virtual_router_id 1
      priority 50
      authentication {
            auth_type PASS
            auth_pass 1111
      }
      virtual_ipaddress {
            192.168.99.10 dev eth0 label eth0:1
      }
}

啟動

systemctl restart keepalived 
systemctl enable keepalived

 

2.安裝并配置haproxy

  1. 各服務器配置內核引數
echo "net.ipv4.ip_nonlocal_bind=1" >> /etc/sysctl.conf
sysctl -p 
  1. Server1配置haproxy
vim /etc/haproxy/haproxy.cfg
global
      maxconn 100000
      uid 99
      gid 99
      daemon
      nbproc 1
      log 127.0.0.1 local0 info
defaults
      option http-keep-alive
      #option forwardfor
      maxconn 100000
      mode tcp
      timeout connect 500000ms
      timeout client 500000ms
      timeout server 500000ms

listen stats
      mode http
      bind 0.0.0.0:9999
      stats enable
      log global
      stats uri /haproxy-status
      stats auth haadmin:q1w2e3r4ys
#================================================================
frontend docker_nginx_web
      bind 0.0.0.0:80
      mode http
      default_backend docker_nginx_hosts

backend docker_nginx_hosts
      mode http
      balance roundrobin
      server 192.168.99.22 192.168.99.22:81 check inter 2000 fall 3 rise 5
      server 192.168.99.23 192.168.99.23:81 check inter 2000 fall 3 rise 5
啟動haproxy
systemctl enable haproxy
systemctl restart haproxy
  1. Server2配置haproxy
vim /etc/haproxy/haproxy.cfg
global
      maxconn 100000
      uid 99
      gid 99
      daemon
      nbproc 1
      log 127.0.0.1 local0 info
defaults
      option http-keep-alive
      #option forwardfor
      maxconn 100000
      mode tcp
      timeout connect 500000ms
      timeout client 500000ms
      timeout server 500000ms

listen stats
      mode http
      bind 0.0.0.0:9999
      stats enable
      log global
      stats uri /haproxy-status
      stats auth haadmin:q1w2e3r4ys
#================================================================
frontend docker_nginx_web
      bind 0.0.0.0:80
      mode http
      default_backend docker_nginx_hosts

backend docker_nginx_hosts
      mode http
      balance roundrobin
      server 192.168.99.22 192.168.99.22:81 check inter 2000 fall 3 rise 5
      server 192.168.99.23 192.168.99.23:81 check inter 2000 fall 3 rise 5
啟動haproxy
systemctl enable haproxy
systemctl restart haproxy

3. docker服務器啟動nginx容器并驗證

  1. dcoekr1啟動Nginx容器
    docker1:192.168.99.22
# 先下載nginx鏡像
docker pull nginx
docker run --name nginx-web1 -d -p 81:80 nginx

驗證網路訪問
在這里插入圖片描述

  1. docker2啟動nginx容器
    docker2:192.168.99.23
# 先下載nginx鏡像
docker pull nginx
docker run --name nginx-web1 -d -p 81:80 nginx 

驗證網路訪問
在這里插入圖片描述

  1. 訪問VIP
    在這里插入圖片描述

     

  2. Server1 haproxy狀態頁面:192.168.99.101:9999 / haproxy-status
    在這里插入圖片描述

  3. Server2 haproxy狀態頁面:192.168.99.102:9999 / haproxy-status
    在這里插入圖片描述

容器之間的互聯

通過容器名稱互聯:

即在同一個主機上的容器之間可以通過自定義的容器名稱相互訪問,某個業務前端靜態頁面是使用nginx,動態頁面使用的是tomcat,由于容器在啟動的時候其內部IP地址是DHCP隨機分配的,所以如果通過內部訪問的話,自定義名稱是相對比較固定的,因此比較適用于此場景,

  1. 先創建第一個容器,后續會使用到這個容器的名稱:
docker run -it -d --name app1 -p 88:80 nginx
  1. 查看當前主機檔案內容
[root@Server1 ~]# docker exec -it app1 bash
root@260fea18537b:/# 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.2    260fea18537b
  1. 創建第二個容器
docker run -it -d -p 89:80 --name app2 --link app1 nginx
  1. 查看第二個容器的主機檔案內容 
[root@Server1 ~]# docker exec -it app2 bash
root@cd11e8d1d51e:/# 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.2    app1 260fea18537b    ## 連接的對方容器的 ID 和容器名稱
172.17.0.3 cd11e8d1d51e 
  1. 檢測通信
ping app1

可能需要先安裝ping工具

apt-get update && apt install -y iputils-ping

 

通過自定義容器別名互聯:

上一步驟中,自定義的容器名稱可能后期會發生變化,那么一旦名稱發生變化,程式之間也要隨之發生變化,此類程式通過容器名稱進行服務呼叫,但是容器名稱發生變化之后再使用之前的名稱肯定是無法成功呼叫,每次都進行更改的話又比較麻煩,因此可以使用自定義別名的方式解決,即容器名稱可以隨意更容易,只要不更改別名即可,具體如下:
命令格式:

docker run -d --name 新容器名稱 \
      --link 目標容器名稱:自定義的名稱 \
      -p 本地埠:容器埠 鏡像名稱 shell命令
  1. 啟動第三個容器
docker run -it -d -p 90:80 --name app3 --link app1:web1 nginx
  1. 查看當前容器的主機
[root@Server1 ~]# docker exec -it app3 bash
root@9b99ad938dbe:/# 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.2    web1 260fea18537b app1   # 多了一個別名web1
172.17.0.4    9b99ad938dbe

 

  1. 檢查自定義別名通信
ping web1
  1. docker網路型別:


    docker的網路使用docker network ls命令看到有一種型別,下面將介紹每一種型別的具體作業方式:
    使用引數–net=網路型別指定,而不指定替代就是bridge模式,

查看當前docke的網卡資訊:

docker network list

 

網橋:可以,使用自定義IP
主機:不獲取IP直接使用物理機IP,并監聽物理機IP監聽埠
無:沒有網路

(1)主機模式:使用引數–net = host指定,
啟動的容器如果指定了使用主機模式,那么新創建的容器不會創建自己的虛擬網卡,而是直接使用托管機的網卡和IP地址,因此在容器里面查看到的IP資訊就是宿主機的資訊,

訪問容器的時候直接使用主機機IP +容器埠即可,不過容器的其他資源他們必須檔案系統,系統行程等還是和主機保持隔離,模式的網路性能最高,但是各個容器之間的埠不能相同,適用于運行容器埠比較固定的業務,

  1. 為避免埠沖突,先洗掉所有的容器:
docker rm -fv `docker ps -a -q` 

          2. 啟動一個新容器,并指定網路模式為主機

docker run -d --name app1 --net=host nginx

         3. 訪問
主機機驗證因為是主機模式,所以直接訪問主機機的IP:192.168.0.36
訪問到的是nginx的默認首頁

 

主機模式不支持埠映射,當指定埠映射的時候會提示如下警告資訊:
使用主機網路模式時,將替換已指定的埠

docker run -d --name app2 -p 81:80 --net=host nginx

 

(2)None模式:使用引數–net = none指定
在使用none模式后,Docker容器不會進行任何網路配置,其沒有網卡,沒有IP也沒有路由,因此無法與外部通信,需要手動添加網卡配置IP等,所以極少使用

命令使用方式:

docker run -it -d --name net_none -p 80:80 --net=none nginx

 

(3)容器模式:使用引數–net = container:name或ID

  使用此模式創建的容器需要指定和一個已經存在的容器共享一個網路,而不是和容納機共享網,新創建的容器不會創建自己的網卡也不會配置自己的IP,或者和一個已經存在的被指定的容器IP和埠范圍,

因此該容器的埠不能和被指定的埠沖突,除了網路之外的檔案系統,進展資訊等仍保持相互隔離,兩個容器的進展可以通過lo網卡及容器IP進行通信,

  1. 先起一個容器
docker run -it -d --name app11 -p 7070:8080 nginx
  1. 另一個容器直接使用對方的網路
docker run -it -d --name app12 --net=container:app11 tomcat85-app1:v1
  1. nginx的默認埠為80,而8080是tomcat的默認埠,所以,如果我們直接訪問托宿主機的7070,應該是訪問到tomcat的頁面才對,如圖

 

(4)bridge模式: docker的交替模式即不指定任何模式就是bridge模式,也是使用比較多的模式,此模式創建的容器會為每一個容器分配自己的網路IP等資訊,且多個容器連接到一個虛擬網橋與外界通信 在這里插入圖片描述

查看bridge模式的資訊

docker network inspect bridge

 

 

docker跨主機互聯之簡單實作:

     跨主機互聯是說A主機的容器可以訪問B主機上的容器,但是可以保證各主機之間的網路是可以相互通信的,然后各容器才可以通過主機訪問到對方的容器,實作原理是在主機做一個網路路由就可以實作A主機的容器訪問B主機的容器的目的,

復雜的網路或者大型的網路可以使用google開源的k8s進行互聯,

  修改各主機機網段: Docker的替代網段是172.17.0.x / 24,而且每個主機機都是一樣的,因此路由選擇的路由就是各個主機的網路不能一致,具體如下:

服務器A:192.168.0.36
服務器B:192.168.0.59

  1. 服務器A更改網段
vim /lib/systemd/system/docker.service

ExecStart結尾追加--bip=10.10.0.1/24,ip是你想設定的網路的網關ip

ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --bip=10.10.0.1/24
  1. 重啟docker服務
systemctl daemon-reload
systemctl restart docker
  1. 驗證一個服務器網卡
ifconfig docker0

如果你的系統是Centos,需要打開ipforward

echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p 
  1. 啟動一個容器
docker run -it -p 87:80 nginx bash
[root@781e7f053c20 /]# ifconfig eth0

 

  1. 添加靜態路由(主機上)
route add -net 10.10.0.0/24 gw 192.168.0.59

iptables -A FORWARD -s 192.168.0.0/24 -j ACCEPT
  1. 服務器B更改網段
vim /lib/systemd/system/docker.service

ExecStart結尾追加--bip=10.20.0.1/24,注意不能跟服務器A一樣

ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --bip=10.20.0.1/24
  1. 重啟docker服務
systemctl daemon-reload
systemctl restart docker
  1. 驗證網卡:  ifconfig docker0

  1. 如果你的系統是Centos,需要打開ipforward規則轉發
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p 
  1. 啟動一個容器
docker run -it -p 82:80 nginx bash
[root@781e7f053c20 /]# ifconfig eth0
  1. 添加靜態路由
route add -net 10.10.0.0/24 gw 192.168.0.36

iptables -A FORWARD -s 192.168.0.0/24 -j ACCEPT

 

容器間互相ping測驗
互連兩臺服務器分別啟動兩個容器進行測驗:10.10.0.0網段是服務器A內的容器,10.20.0.0網段是服務器B內的容器

 在另一臺容器里反ping試一下

如果可以ping通就表示沒有問題,兩個不同宿主機上的容器可以互相通信了

 

創建自定義網路:

可以基于docker命令創建自定義網路,自定義網路可以自定義IP地域和網關等資訊,

幫助

docker network create –help
  1. 創建自定義docker網路
docker network create -d bridge --subnet 10.100.0.0/24 \
      --gateway 10.100.0.1 my-net
  1. 查看網路
docker network list

 

  1. 使用自定義網路創建容器
[root@Server1 ~]# docker run -itd --net=my-net centos-nginx:v1 bash
[root@Server1 ~]# docker exec -it 25d2c84d58bd bash
[root@25d2c84d58bd /]# yum install -y net-tools &> /dev/null
[root@25d2c84d58bd /]# ifconfig eth0

 

 

  1. 創建默認網路容器

  docker run -it  centos-nginx:v1 bash

[root@ed06c2785c92 /]# ifconfig eth0
[root@ed06c2785c92 /]# ping www.baidu.com
  1. 如何與使用交替網路的容器通信:
    現在有一個docker0(10.10.0.0/24)網路一個自定義的my-net(10.100.0.0/24)網路,每個網路上分別運行了不同數量的容器,那么怎么才能讓位于不同網路的容器可以相互通信呢? 那就是修改防火墻規則條目
  2. 保存下iptbales

iptables-save > iptables.sh
  1. 修改iptables.sh   

             # vim iptables.sh

把DOCKER-ISOLATION-STAGE-2除了RETURN結尾的都注釋了

  1. 重新匯入修改后的iptables規則
iptables-restore < iptables.sh

          4. 驗證通信

先看一下其他網段的容器ip地址

 ping測驗一下

 

經過以上的配置,目前就已經實作了不通網路間的通信

 

十六、Docker資源限制

官網:https://docs.docker.com/config/containers/resource_constraints/

默認情況下, 容器沒有資源限制, 可以使用主機內核調度程式允許的盡可能多的給定資源, Docker 提供了控制容器可以限制容器使用多少記憶體或 CPU 的方法,設定 docker run 命令的運行時配置標志,
其中許多功能都要求宿主機的內核支持 Linux 功能, 要檢查支持, 可以使用docker info 命令,如果內核中禁用了某項功能, 可能會在輸出結尾處看到警告,

如下所示:

WARNING: No swap limit support

對于 Linux 主機, 如果沒有足夠的內容來執行其他重要的系統任務, 將會拋出OOM (Out of Memory Exception,記憶體溢位、 記憶體泄漏、 記憶體例外), 隨后系統會開始殺死行程以釋放記憶體, 凡是運行在宿主機的行程都有可能被 kill, 包括 Dockerd和其它的應用程式, 如果重要的系統行程被 Kill,會導致和該行程相關的服務全部宕機,

產生 OOM 例外時, Dockerd 嘗試通過調整 Docker 守護程式上的 OOM 優先級來減輕這些風險,以便它比系統上的其他行程更不可能被殺死,但是容器的 OOM優先級未調整, 這使得單個容器被殺死的可能性比 Docker 守護程式或其他系統行程被殺死的可能性更大,不推薦通過在守護程式或容器上手動設定--oomscore-adj 為極端負數,或通過在容器上設定--oom-kill-disable 來繞過這些安全措施,

OOM 優先級機制:

linux 會為每個行程算一個分數,最終他會將分數最高的行程 kill,

/proc/PID/oom_score_adj :范圍為-1000 到 1000,值越高越容易被宿主機 kill掉,如果將該值設定為-1000,則行程永遠不會被宿主機 kernel kill,

/proc/PID/oom_adj :范圍為-17 到+15,取值越高越容易被干掉,如果是-17,則表示不能被 kill,該設定引數的存在是為了和舊版本的 Linux 內核兼容,

/proc/PID/oom_score :這個值是系統綜合行程的記憶體消耗量、 CPU 時間(utime + stime)、存活時間(uptime - start time)和 oom_adj 計算出的,消耗記憶體越多分越高,存活時間越長分越低,

容器的記憶體限制:

Docker 可以強制執行硬性記憶體限制,即只允許容器使用給定的記憶體大小,
Docker 也可以執行非硬性記憶體限制,即容器可以使用盡可能多的記憶體,除非內核檢測到主機上的記憶體不夠用了,

--oom-score-adj: 宿主機 kernel 對行程使用的記憶體進行評分, 評分最高的將被宿主機內核 kill 掉, 可以指定一個容器的評分制但是不推薦手動指定,
--oom-kill-disable: 對某個容器關閉 oom 機制,


記憶體限制引數:

-m, --memory:容器可以使用的最大記憶體量,如果設定此選項,則允許的最記憶體值為 4m (4 兆位元組),
--memory-swap: 容器可以使用的交換磁區大小, 必須要在設定了物理記憶體限制的前提才能設定交換磁區的限制
--memory-swappiness: 設定容器使用交換磁區的傾向性,值越高表示越傾向于使用 swap 磁區,范圍為 0-100, 0 為能不用就不用, 100 為能用就用,
--kernel-memory: 容器可以使用的最大內核記憶體量,最小為 4m,由于內核記憶體與用戶空間記憶體隔離,因此無法與用戶空間記憶體直接交換,因此內核記憶體不足的容器可能會阻塞宿主主機資源,這會對主機和其他容器或者其他服務行程產生影響,因此不要設定內核記憶體大小,
--memory-reservation:允許指定小于--memory 的軟限制,當 Docker 檢測到主機上的爭用或記憶體不足時會激活該限制,如果使用--memory-reservation,則必須將其設定為低于--memory 才能使其優先, 因為它是軟限制,所以不能保證容器不超過限制,
--oom-kill-disable 默認情況下,發生 OOM 時, kernel 會殺死容器內行程,但是可以使用--oom-kill-disable 引數,可以禁止 oom 發生在指定的容器上,即 僅在已設定-m選項的容器上禁用 OOM,如果-m 引數未配置,產生 OOM 時,主機為了釋放記憶體還會殺死系統行程,


swap 限制:

--memory-swap:只有在設定了 --memory 后才會有意義,使用 Swap,可以讓容器將超出限制部分的記憶體置換到磁盤上, WARNING:經常將記憶體交換到磁盤的應用程式會降低性能,

不同 --memory-swap 的設定會產生不同的效果:
值為正數, 那么--memory 和--memory-swap 都必須要設定, --memory-swap 表示你能使用的記憶體和 swap 磁區大小的總和,例如: --memory=300m, --memory-swap=1g, 那么該容器能夠使用 300m 記憶體和 700m swap,即--memory 是實際物理記憶體大小值不變,而 swap 的實際大小計算方式為
(--memory-swap)-(--memory)=容器可用 swap(??memory?swap)?(??memory)=swap,

如果設定為 0:則忽略該設定,并將該值視為未設定,即未設定交換磁區,

如果等于--memory 的值,并且--memory 設定為正整數: 容器無權訪問 swap 即也沒有設定交換磁區,

如果設定為 unset:如果宿主機開啟了 swap,則實際容器的swap 值為 2x( --memory),即兩倍于物理記憶體大小,但是并不準確(在容器中使用free 命令所看到的 swap 空間并不精確, 畢竟每個容器都可以看到具體大小,但是宿主機的 swap 是有上限而且不是所有容器看到的累計大小),
如果設定為-1:如果宿主機開啟了 swap,則容器可以使用主機上 swap 的最大空間,

動態修改容器記憶體,先計算出所需要的記憶體的位元組數:如268435456(256M),只能調大不能調小

echo "268435456" > /sys/fs/cgroup/memory/docker/9fa20d824b18.../memory.limit_in_bytes

 

9fa20d824b18... 是容器ID

記憶體限制驗證:

假如一個容器未做記憶體使用限制, 則該容器可以利用到系統記憶體最大空間, 默認創建的容器沒有做記憶體資源限制,

#測驗鏡像
docker pull lorel/docker-stress-ng  

查看幫助

apt install stress-ng
stress-ng --help 

 

或者這樣也行

docker run -it --rm lorel/docker-stress-ng -help

記憶體大小硬限制

查看docker狀態

docker stats

 

  1. 啟動兩個作業行程,每個作業行程最大允許使用記憶體 256M,且宿主機不限制當前容器最大記憶體:
docker run -it --rm --name c1 lorel/docker-stress-ng \
      --vm 2 --vm-bytes 256M

 

--vm 啟動多少個行程
--vm-bytes 為每個行程分配的記憶體

  1. 宿主機限制容器最大記憶體使用:
docker run -it --rm -m 256m --name c2 lorel/docker-stress-ng \
      --vm 2 --vm-bytes 256M

 

  1. 宿主機 cgroup 驗證:
# cat /sys/fs/cgroup/memory/docker/容器 ID /memory.limit_in_bytes
268435456

 

宿主機基于 cgroup 對容器進行記憶體資源的大小限制
注:通過 echo 命令可以改記憶體限制的值,但是可以在原基礎之上增大記憶體限制,縮小記憶體限制會報錯 write error: Device or resource busy

記憶體大小軟限制:

docker run -it --rm -m 256m --memory-reservation 128m \
      --name c3 lorel/docker-stress-ng --vm 2 --vm-bytes 256M
  1. 宿主機 cgroup 驗證:
# cat /sys/fs/cgroup/memory/docker/容器 ID/memory.soft_limit_in_bytes
134217728 

 

回傳的軟限制結果

關閉 OOM 機制

docker run -it --rm -m 256m --oom-kill-disable \
      --name c4 lorel/dockerstress-ng --vm 2 --vm-bytes 256M




# cat /sys/fs/cgroup/memory/docker/容器 ID/memory.oom_control
oom_kill_disable 1
under_oom 1
oom_kill 0

 

交換磁區限制

docker run -it --rm -m 256m --memory-swap 512m \
      --name magedu-c1 centos bash

 

宿主機 cgroup 驗證:

# cat /sys/fs/cgroup/memory/docker/容器 ID/memory.memsw.limit_in_bytes
536870912 

 


容器的 CPU 限制

一個宿主機,有幾十個核心的 CPU, 但是宿主機上可以同時運行成百上千個不同的行程用以處理不同的任務, 多行程共用一個 CPU 的核心依賴計數就是為可壓縮資源, 即一個核心的 CPU 可以通過調度而運行多個行程, 但是同一個單位時間內只能有一個行程在 CPU 上運行, 那么這么多的行程怎么在 CPU 上執行和調度的呢?

實時優先級: 0 - 99

非實時優先級(nice): -20 - 19, 對應 100 - 139 的行程優先級

Linux kernel 行程的調度基于 CFS(Completely Fair Scheduler), 完全公平調度

CPU 密集型的場景:優先級越低越好, 計算密集型任務的特點是要進行大量的計算,消耗 CPU 資源,比如計算圓周率、 資料處理、 對視頻進行高清解碼等等,全靠 CPU 的運算能力,

IO 密集型的場景:優先級值高點, 涉及到網路、磁盤 IO 的任務都是 IO 密集型任務,這類任務的特點是 CPU 消耗很少,任務的大部分時間都在等待 IO 操作完成(因為 IO 的速度遠遠低于 CPU 和記憶體的速度),比如 Web 應用, 高并發,資料量大的動態網站來說,資料庫應該為 IO 密集型,

磁盤的調度演算法

# cat /sys/block/sda/queue/scheduler
noop deadline [cfq]

 

默認情況下,每個容器對主機 CPU 周期的訪問權限是不受限制的, 但是我們可以設定各種約束來限制給定容器訪問主機的 CPU 周期,大多數用戶使用的是默認的 CFS 調度方式, 在 Docker 1.13 及更高版本中, 還可以配置實時優先級,

引數:

--cpus :指定容器可以使用多少可用 CPU 資源, 例如,如果主機有兩個 CPU,并且設定了--cpus =“1.5”,那么該容器將保證最多可以訪問 1.5 個的 CPU(如果是 4 核 CPU, 那么還可以是 4 核心上每核用一點,但是總計是 1.5 核心的CPU), 這相當于設定--cpu-period =“100000”和--cpu-quota =“150000”
主要在 Docker 1.13 和更高版本中使用, 目的是替代--cpu-period--cpuquota 兩個引數,從而使配置更簡單, 最大不能超出宿主機的 CPU 總核心數(在作業系統看到的 CPU 超執行緒后的數值),

分配給容器的 CPU 超出了宿主機 CPU 總數,

# docker run -it --rm --cpus 2 centos bash
docker: Error response from daemon: Range of CPUs is from 0.01 to 1.00, as there are only 1 CPUs available.
See 'docker run --help'. 

 

--cpu-period:(CPU 調度周期)設定 CPU 的 CFS 調度程式周期,必須與--cpuquota 一起使用,默認周期為 100 微秒
--cpu-quota: 在容器上添加 CPU CFS 配額, 計算方式為 cpu-quota/cpu-period的結果值, 早期的 docker(1.12 及之前)使用此方式設定對容器的 CPU 限制值,==新版本 docker(1.13 及以上版本)通常使用--cpus 設定此值,==

--cpuset-cpus:用于指定容器運行的 CPU 編號,也就是我們所謂的綁核,
--cpuset-mem:設定使用哪個 cpu 的記憶體,僅對 非統一記憶體訪問(NUMA)架構有效,
--cpu-shares:用于設定 cfs 中調度的相對最大比例權重,cpu-share 的值越高的容器,將會分得更多的時間片(宿主機多核 CPU 總數為 100%, 假如容器 A 為1024, 容器 B 為 2048, 那么容器 B 將最大是容器 A 的可用 CPU 的兩倍 ),默認的時間片 1024,最大 262144,

測驗 CPU 限制

  1. 未限制容器 CPU
    對于一臺四核的服務器,如果不做限制, 容器會把宿主機的 CPU 全部占完,
    分配 4 核 CPU 并啟動 4 個作業執行緒
docker run -it --rm --name c10 lorel/docker-stress-ng \
      --cpu 4 --vm 4

在宿主機使用 dokcer top 命令查看容器運行狀態

docker top CONTAINER [ps OPTIONS]

容器運行狀態:

docker stats

在宿主機查看 CPU 限制引數:

# cat /sys/fs/cgroup/cpuset/docker/${容器ID}/cpuset.cpus
0-3

 

  1. 限制容器 CPU
    只給容器分配最多兩核宿主機 CPU 利用率
docker run -it --rm --name c11 \
      --cpus 2 lorel/docker-stress-ng --cpu 4 --vm 4

 

宿主機 cgroup 驗證

# cat /sys/fs/cgroup/cpu,cpuacct/docker/容器 ID/cpu.cfs_quota_us
200000

 

每核心 CPU 會按照 1000 為單位轉換成百分比進行資源劃分, 2 個核心的 CPU 就是 200000/1000=200%, 4 個核心 400000/1000=400%,以此類推

宿主機 CPU 利用率

  1. 將容器運行到指定的 CPU 上
docker run -it --rm --name c12 --cpus 1 \
      --cpuset-cpus 1,3 lorel/docker-stress-ng --cpu 2 --vm 2
# cat /sys/fs/cgroup/cpuset/docker/容器 ID /cpuset.cpus
1,3

容器運行狀態

docker stats
  1. 基于 cpu—shares 對 CPU 進行切分
    啟動兩個容器, c13 的--cpu-shares 值為 1000, c14 的--cpu-shares為 500, 觀察最終效果, --cpu-shares 值為 1000 的 c13 的 CPU 利用率基本是--cpu-shares 為 500 的 c14 的兩倍:
docker run -it --rm --name c13 --cpu-shares 10 \
      lorel/docker-stress-ng --cpu 1 --vm 2

docker run -it --rm --name c14 --cpu-shares 5 \
      lorel/docker-stress-ng --cpu 1 --vm 2

 

驗證容器運行狀態

docker stats

宿主機 cgroup 驗證

# cat /sys/fs/cgroup/cpu,cpuacct/docker/容器 ID/cpu.shares
1000
# cat /sys/fs/cgroup/cpu,cpuacct/docker/容器 ID/cpu.shares
500

 

  1. 動態修改 CPU shares 值:
    --cpu-shares 的值可以在宿主機 cgroup 動態修改, 修改完成后立即生效,其值可以調大也可以減小,
echo 2000 > /sys/fs/cgroup/cpu,cpuacct/docker/容器 ID/cpu.shares

 

驗證修改后的容器運行狀態     docker stats

十七

單機編排之Docker撰寫:

    當在主機啟動主機的容器時候,如果都是手動操作會覺得比較麻煩而且容器出錯,這個時候推薦使用docker單機編排工具docker-compose,docker-compose是docker容器的一種單機編排服務,docker- compose是一個管理多個容器的工具,可以解決容器之間的依賴關系,就像啟動一個nginx前端服務的時候會呼叫后端的tomcat,那就得先啟動tomcat,但是啟動tomcat容器還需要依賴資料庫,則那就還得先啟動資料庫,docker-compose就可以解決這樣的嵌套依賴關系,其完全可以替代docker run對容器進行創建,啟動和停止,

docker-compose專案是Docker官方的開源專案,負責實作對Docker容器放置的快速編排,docker-compose將所管理的容器分為三層,分別是工程(專案),服務以及容器

github地址https://github.com/docker/compose

基礎環境準備:


服務器1 :192.168.99.21,港口服務器2:192.168.99.22,
docker -compose 下面開始在服務器1上安裝harbor和創建nginx,tomcat,haproxy大量備用
在這里插入圖片描述

配置安裝港口:

  1. 下載Harbor離線安裝包:
cd /usr/local/src/
wget https://storage.googleapis.com/harbor-releases/release-1.7.0/harbor-offline-installer-v1.7.5.tgz
  1. 解壓
tar xf harbor-offline-installer-v1.7.5.tgz
ln -sv /usr/local/src/harbor /usr/local/

 

  1. 下載docker-compose
    Ubuntu:
apt update
apt install -y python-pip
pip install docker-compose

中心:

yum install epel-release
yum install -y python-pip
pip install --upgrade pip
pip install docker-compose
  1. 修改組態檔,最終配置如下
# vim harbor.cfg
...
hostname = 192.168.99.22
...
harbor_admin_password = root123
...

 

  1. 安裝
./install.sh
  1. 編輯docker組態檔:
    注意:如果我們配置的是https的話,本地docker就不需要任何任何操作就可以訪問Harbor了
vim /lib/systemd/system/docker.service
在ExecStart追加

ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --insecure-registry 192.168.99.21

 

其中192.168.99.21是我們部署Harbor的地址,即hostname配置項值,配置完后需要重啟docker服務,
在這里插入圖片描述

  1. 重啟docker服務:
systemctl daemon-reload
systemctl restart docker
  1. 重啟docker-compose
docker-compose restart
  1. 驗證能否登錄Harbor:
docker login 192.168.99.21

https://docs.docker.com/compose/reference/官方檔案

制作nginx鏡像

  1. 下載概述并初始化系統:
docker pull centos
mkdir -pv /opt/dockerfile/web/nginx/html

 

  1. 撰寫Dockerfile:
cd /opt/dockerfile/web/nginx
vim Dockerfile
From centos:latest

MAINTAINER han 123456@qq.com

ADD nginx-1.10.3.tar.gz /usr/local/src/

RUN rpm -ivh http://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm \
        && yum install -y vim wget tree lrzsz gcc gcc-c++ automake pcre pcre-devel zlib zlib-devel openssl openssl-devel iproute net-tools iotop \
        && cd /usr/local/src/nginx-1.10.3 \
        && ./configure --prefix=/usr/local/nginx --with-http_sub_module \
        && make \
        && make install \
        && cd /usr/local/nginx/
ADD nginx.conf /usr/local/nginx/conf/nginx.conf
RUN useradd nginx -s /sbin/nologin \
        && ln -sv /usr/local/nginx/sbin/nginx /usr/sbin/nginx \
        && echo "test nginx page" > /usr/local/nginx/html/index.html

EXPOSE 80 443

CMD ["nginx","-g","daemon off;"]

 

  1. 準備網頁
cd /opt/dockerfile/web/nginx/html
echo "test nginx" > index.html

cd /opt/dockerfile/web/nginx
vim nginx.conf

#user  nobody;
worker_processes  1;

#pid        logs/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;
    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   /usr/local/nginx/html;
            index  index.html index.htm;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}
  1. 目錄如下
# cd ..
# tree .
.
├── Dockerfile
├── html
│   └── index.html
├── nginx-1.10.3.tar.gz
└── nginx.conf

 

  1. 構建鏡像
docker build -t mynginx:v1 /opt/dockerfile/web/nginx

 

  1. 查看是否生成新鏡像
docker images
  1. 從總體啟動容器
docker run --rm -p 81:80 --name nginx-web1 \
    -v /opt/dockerfile/web/nginx/html/:/usr/local/nginx/html/ \
    -v /opt/dockerfile/web/nginx/nginx.conf:/usr/local/nginx/conf/nginx.conf \
    mynginx:v1

 

  1. 訪問網路界面
    在這里插入圖片描述
  2. 打標簽:

docker tag mynginx:v1 192.168.99.21/nginx/mynginx:v1

 

  1. 在港口管理界面創建專案(需要先創建專案再上傳高層)
    在這里插入圖片描述

  2. 將向前推到港口:

docker push 192.168.99.21/nginx/mynginx:v1

 

  1. 發布完成
    在這里插入圖片描述

制作JDK環境

  1. 執行完善JDK的方針:
mkdir -p /opt/dockerfile/web/jdk
cd /opt/dockerfile/web/jdk/

 

  1. 編輯Dockerfile
vim Dockerfile
#JDK Base Image
FROM centos:latest

ADD jdk-8u211-linux-x64.tar.gz /usr/local/src/
RUN ln -sv /usr/local/src/jdk1.8.0_211 /usr/local/jdk
ADD profile /etc/profile
ENV JAVA_HOME /usr/local/jdk
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/:$JRE_HOME/lib/
ENV PATH $PATH:$JAVA_HOME/bin

RUN rm -rf /etc/localtime \
      && ln -snf /usr/share/zoneinfo/Asia/Shanghai/etc/localtime \
      && echo "Asia/Shanghai" > /etc/timezone
  1. 準備環境變數檔案
vim profile
# /etc/profile

# System wide environment and startup programs, for login setup
# Functions and aliases go in /etc/bashrc

# It's NOT a good idea to change this file unless you know what you
# are doing. It's much better to create a custom.sh shell script in
# /etc/profile.d/ to make custom changes to your environment, as this
# will prevent the need for merging in future updates.

pathmunge () {
    case ":${PATH}:" in
        *:"$1":*)
            ;;
        *)
            if [ "$2" = "after" ] ; then
                PATH=$PATH:$1
            else
                PATH=$1:$PATH
            fi
    esac
}


if [ -x /usr/bin/id ]; then
    if [ -z "$EUID" ]; then
        # ksh workaround
        EUID=`/usr/bin/id -u`
        UID=`/usr/bin/id -ru`
    fi
    USER="`/usr/bin/id -un`"
    LOGNAME=$USER
    MAIL="/var/spool/mail/$USER"
fi

# Path manipulation
if [ "$EUID" = "0" ]; then
    pathmunge /usr/sbin
    pathmunge /usr/local/sbin
else
    pathmunge /usr/local/sbin after
    pathmunge /usr/sbin after
fi

HOSTNAME=`/usr/bin/hostname 2>/dev/null`
HISTSIZE=1000
if [ "$HISTCONTROL" = "ignorespace" ] ; then
    export HISTCONTROL=ignoreboth
else
    export HISTCONTROL=ignoredups
fi

export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE HISTCONTROL

# By default, we want umask to get set. This sets it for login shell
# Current threshold for system reserved uid/gids is 200
# You could check uidgid reservation validity in
# /usr/share/doc/setup-*/uidgid file
if [ $UID -gt 199 ] && [ "`/usr/bin/id -gn`" = "`/usr/bin/id -un`" ]; then
    umask 002
else
    umask 022
fi

for i in /etc/profile.d/*.sh /etc/profile.d/sh.local ; do
    if [ -r "$i" ]; then
        if [ "${-#*i}" != "$-" ]; then
            . "$i"
        else
            . "$i" >/dev/null
        fi
    fi
done

unset i
unset -f pathmunge

export JAVA_HOME=/usr/local/jdk
export TOMCAT_HOME=/apps/tomcat
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$TOMCAT_HOME/bin:$PATH
export CLASSPATH=.$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$JAVA_HOME/lib/tools.jar
  1. 看下目錄結構
# tree /opt/dockerfile/web/jdk
/opt/dockerfile/web/jdk
├── Dockerfile
├── jdk-8u211-linux-x64.tar.gz
└── profile
  1. 構建
cd /opt/dockerfile/web/jdk
docker build -t myjdk:v1 .
  1. 打標記
docker tag myjdk:v1 192.168.99.21/jdk/myjdk:v1

 

  1. 在港口頁面上創建jdk專案
    在這里插入圖片描述

  2. 將全面上傳到Harbor(以下有講)

docker push 192.168.99.21/jdk/myjdk:v1

 


從JDK整合重構tomcat

  1. 進入tomcat目錄:
mkdir -p /opt/dockerfile/web/tomcat
cd /opt/dockerfile/web/tomcat
  1. 編輯Dockerfile檔案
vim Dockerfile
FROM 192.168.99.21/jdk/myjdk:v1
RUN useradd www -u 2020

ENV TZ "Asia/Shanghai"
ENV LANG en_US.UTF-8
ENV TERM xterm
ENV TOMCAT_MAJOR_VERSION 8
ENV TOMCAT_MINOR_VERSION 8.0.49
ENV CATALINA_HOME /apps/tomcat
ENV APP_DIR ${CATALINA_HOME}/webapps

RUN mkdir /apps
ADD apache-tomcat-8.5.45.tar.gz /apps
RUN ln -sv /apps/apache-tomcat-8.5.45 /apps/tomcat
  1. 發布tomcat壓縮包:apache-tomcat-8.5.45.tar.gz
tree /opt/dockerfile/web/tomcat
/opt/dockerfile/web/tomcat
├── apache-tomcat-8.5.45.tar.gz
└── Dockerfile

 

  1. 通過腳本構建tomcat基礎之上
docker build -t mytomcat:v1 .

 

  1. 驗證合并重建完成
docker images
  1. 進行打上標簽
docker tag mytomcat:v1 192.168.99.21/tomcat/mytomcat:v1

 

  1. 在港口頁面上創建tomcat專案
    在這里插入圖片描述

  2. 發布

docker push 192.168.99.21/tomcat/mytomcat

 


構建tomcat-app業務運營:

  1. 準備目錄
mkdir -pv /opt/dockerfile/web/tomcat-app
cd /opt/dockerfile/web/tomcat-app
  1. 準備Dockerfile:
vim Dockerfile
FROM 192.168.99.21/tomcat/mytomcat:v1
ADD run_tomcat.sh /apps/tomcat/bin/run_tomcat.sh
ADD myapp/* /apps/tomcat/webapps/myapp/
RUN chown www.www /apps/ -R
RUN chmod +x /apps/tomcat/bin/run_tomcat.sh
EXPOSE 8080 8009
CMD ["/apps/tomcat/bin/run_tomcat.sh"]
  1. 準備自定義myapp頁面:
mkdir myapp
echo "MyTomcat Web app Page1" > myapp/index.html
  1. 準備容器啟動執行腳本run_tomcat.sh
vim run_tomcat.sh
#!/bin/bash
echo "nameserver 223.5.5.5" > /etc/resolv.conf
su - www -c "/apps/tomcat/bin/catalina.sh start"
su - www -c "tail -f /etc/hosts"
  1. 檔案目錄
# tree
.
├── Dockerfile
├── myapp
│   └── index.html
└── run_tomcat.sh

 

  1. 構建
docker build -t mytomcat-app:v1 .
  1. 查看鏡像
docker images
  1. 給Tomcat打標簽
docker tag mytomcat-app:v1 192.168.99.21/tomcat/mytomcat-app:v1
  1. 推送
docker push 192.168.99.21/tomcat/mytomcat-app:v1

 


制作haproxy補充:

  1. 進入目錄
mkdir -pv /opt/dockerfile/app/haproxy
cd /opt/dockerfile/app/haproxy

 

  1. 準備Dockerfile:
vim Dockerfile
#Haproxy Base Image
FROM centos
ADD haproxy-2.0.5.tar.gz /usr/local/src/

RUN yum -y install gcc gcc-c++ glibc glibc-devel pcre \
                pcre-devel openssl openssl-devel systemd-devel \
                net-tools vim iotop bc zip unzip zlib-devel lrzsz \
                tree screen lsof tcpdump wget ntpdate  \
      && cd /usr/local/src/haproxy-2.0.5 \
      && make ARCH=x86_64 TARGET=linux-glibc \
              USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 \
              USE_SYSTEMD=1 USE_CPU_AFFINITY=1 \
              PREFIX=/usr/local/haproxy \
      && make install PREFIX=/usr/local/haproxy \
      && cp haproxy /usr/sbin/ \
      && mkdir /usr/local/haproxy/run
ADD haproxy.cfg /etc/haproxy/
ADD run_haproxy.sh /usr/bin
RUN chmod +x /usr/bin/run_haproxy.sh
EXPOSE 80 9999
CMD ["/usr/bin/run_haproxy.sh"]
  1. 準備run_haproxy.sh腳本
vim run_haproxy.sh
#!/bin/bash
haproxy -f /etc/haproxy/haproxy.cfg
tail -f /etc/hosts
  1. 準備haproxy.cfg組態檔:
vim haproxy.cfg
global
    chroot /usr/local/haproxy
    #stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin
    uid 99
    gid 99
    daemon
    nbproc 1
    pidfile /usr/local/haproxy/run/haproxy.pid
    log 127.0.0.1 local3 info

defaults
    option http-keep-alive
    option forwardfor
    mode http
    timeout connect 300000ms
    timeout client 300000ms
    timeout server 300000ms

listen stats
    mode http
    bind 0.0.0.0:9999
    stats enable
    log global
    stats uri /haproxy-status
    stats auth haadmin:q1w2e3r4ys

listen web_port
    bind 0.0.0.0:80
    mode http
    log global
    balance roundrobin
    server web1 192.168.99.22:81 check inter 3000 fall 2 rise 5

 

調度到初步nginx服務的81埠

  1. 準備haproxy原始檔案:haproxy-2.0.5.tar.gz
# tree /opt/dockerfile/app/haproxy
/opt/dockerfile/app/haproxy
├── Dockerfile
├── haproxy-2.0.5.tar.gz
├── haproxy.cfg
└── run_haproxy.sh
  1. 準備編制腳本:
docker build -t haproxy:v1 .
  1. 給通用打標簽
docker tag haproxy:v1 192.168.99.21/haproxy/haproxy:v1

 

  1. 港口創建haproxy專案
    在這里插入圖片描述

     

  2. 推送到倉庫

docker push 192.168.99.21/haproxy/haproxy:v1

從docker compose啟動臨時容器

換成server2繼續:

  1. 安裝docker-18.09.9
    程序略

     

  2. 下載docker-compose
    Ubuntu:

apt update
apt install -y python-pip
pip install docker-compose

Centos:

yum install epel-release
yum install -y python-pip
pip install --upgrade pip
pip install docker-compose
  1. 驗證 docker-compose 版本
docker-compose -v

 

  1. 查看 docker-compose 幫助
docker-compose --help 
  1. 編輯 docker 組態檔:
vim /lib/systemd/system/docker.service

ExecStart追加

ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --insecure-registry 192.168.99.21

 

  1. 重啟 docker 服務:
systemctl daemon-reload
systemctl restart docker

 

  1. 測驗連接
docker login 192.168.99.21

在這里插入圖片描述

  1. 創建網頁存放目錄,給容器掛載用
mkdir -pv /opt/dockerfile/web/nginx/html
cd /opt/dockerfile/web/nginx/html
echo "test nginx" > index.html

 

  1. 目錄可以在任意目錄, 推薦放在有意義的位置,如:
cd /opt/
mkdir docker-compose
cd docker-compose

 

  1. 單個容器的 docker compose 檔案:
    撰寫一個 yml 格式的配置 docker-compose 檔案, 啟動一個 nginx 服務
vim docker-compose.yml
service-nginx-web:
  image: 192.168.99.21/nginx/mynginx:v1
  container_name: nginx-web1
  expose:
    - 80
    - 443
  ports:
    - "80:80"
    - "443:443"
  volumes:
    - "/opt/dockerfile/web/nginx/html/:/usr/local/nginx/html/"

 

service-nginx-web:服務名
image:鏡像名
container_name:容器名
expose:開放埠
post:宿主機映射埠
volume:資料卷掛載

  1. 啟動容器
docker-compose up -d 

不加是 d 前臺啟動
在這里插入圖片描述

  1. 啟動完成
# docker ps  | grep nginx
1e453106ca9c        192.168.99.21/nginx/mynginx:v1           "nginx -g 'daemon of…"   49 seconds ago      Up 47 seconds          443/tcp, 0.0.0.0:80->80/tcp    

 

  1. 查看容器行程
docker-compose ps

在這里插入圖片描述

  1. web 訪問測驗
    在這里插入圖片描述

啟動多個容器

docker pull 192.168.99.21/tomcat/mytomcat-app:v1

  1. 編輯組態檔
cd /opt/docker-compose/
vim docker-compose.yml
service-nginx-web:
  image: 192.168.99.21/nginx/mynginx:v1
  container_name: nginx-web1
  expose:
    - 80
    - 443
  ports:
    - "81:80"
    - "443:443"
  volumes:
    - "/opt/dockerfile/web/nginx/html/:/usr/local/nginx/html/"

service-tomcat-app1:
  image: 192.168.99.21/tomcat/mytomcat-app:v1
  container_name: tomcat-app1
  expose:
    - 8080
  ports:
    - "8080:8080"

 

  1. 重啟容器
docker-compose stop
docker-compose up -d
  1. web 訪問測驗
    在這里插入圖片描述
  2. 重啟/停止/啟動單個指定容器

docker-compose restart/stop/start service-nginx-web 

寫容器的 service 名稱,則是指定,
不指定則是所有

  1. 重啟所有容器:
docker-compose restart

 

實作Nginx反向代理Tomcat

創建nginx組態檔

  1. 創建nginx目錄
mkdir /opt/app
mkdir -p nginx/html/app{1..2}
cd /opt/app
mkdir -p nginx/conf
cd nginx/conf

 

  1. 創建nginx組態檔
vim nginx.conf
#user  nobody;
worker_processes  1;

#pid        logs/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  'remote_addr - remote_user [time_local] "request" '
    #                  'status body_bytes_sent "http_referer" '     
# '"http_user_agent" "http_x_forwarded_for"';
#        access_log logs/access.log main;
        sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on; upstream tomcat_webserver {
       server service-tomcat-app1:8080;
server service-tomcat-app2:8080;
}
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location /app1 {
root /apps/nginx/html;
index index.html index.htm;
}
location /app2 {
root /apps/nginx/html;
index index.html index.htm;
}
location /tomcat-app {
proxy_pass http://tomcat_webserver;
proxy_set_header Host host;
proxy_set_header X-Forwarded-For proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP remote_addr; } #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } }
  1. 創建網頁
echo app111111 > /opt/app/nginx/html/app1/index.html
echo app222222 > /opt/app/nginx/html/app2/index.html

 

創建haproxy組態檔

cd /opt/app
mkdir -p haproxy/conf

vim .
/haproxy/conf/haproxy.cfg
global
chroot /usr/local/haproxy uid 99 gid 99 daemon nbproc 1 pidfile /usr/local/haproxy/run/haproxy.pid log 127.0.0.1 local3 info defaults option http-keep-alive option forwardfor mode http timeout connect 300000ms timeout client 300000ms timeout server 300000ms listen stats mode http bind 0.0.0.0:9999 stats enable log global stats uri /haproxy-status stats auth admin:123 listen web_port bind 0.0.0.0:80 mode http log global balance roundrobin server web1 nginx-web1:80 check inter 3000 fall 2 rise 5

 

nginx-web1:80 這里寫的是容器內部的埠,所以nginx容器開放的什么埠就寫多少,默認80,因為沒有對宿主機映射,所以可以不會埠沖突,
nginx-web1 是容器名

準備tomcat組態檔

cd /opt/app
mkdir -p tomcat/conf

 

vim tomcat/conf/server.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<!-- Note:  A "Server" is not itself a "Container", so you may not
     define subcomponents such as "Valves" at this level.
     Documentation at /docs/config/server.html
 -->
<Server port="8005" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  <!-- Security listener. Documentation at /docs/config/listeners.html
  <Listener className="org.apache.catalina.security.SecurityListener" />
  -->
  <!--APR library loader. Documentation at /docs/apr.html -->
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <!-- Prevent memory leaks due to use of particular java/javax APIs-->
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

  <!-- Global JNDI resources
       Documentation at /docs/jndi-resources-howto.html
  -->
  <GlobalNamingResources>
    <!-- Editable user database that can also be used by
         UserDatabaseRealm to authenticate users
    -->
    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />
  </GlobalNamingResources>

  <!-- A "Service" is a collection of one or more "Connectors" that share
       a single "Container" Note:  A "Service" is not itself a "Container",
       so you may not define subcomponents such as "Valves" at this level.
       Documentation at /docs/config/service.html
   -->
  <Service name="Catalina">

    <!--The connectors can use a shared executor, you can define one or more named thread pools-->
    <!--
    <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
        maxThreads="150" minSpareThreads="4"/>
    -->


    <!-- A "Connector" represents an endpoint by which requests are received
         and responses are returned. Documentation at :
         Java HTTP Connector: /docs/config/http.html
         Java AJP  Connector: /docs/config/ajp.html
         APR (HTTP/AJP) Connector: /docs/apr.html
         Define a non-SSL/TLS HTTP/1.1 Connector on port 8080
    -->
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    <!-- A "Connector" using the shared thread pool-->
    <!--
    <Connector executor="tomcatThreadPool"
               port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    -->
    <!-- Define a SSL/TLS HTTP/1.1 Connector on port 8443
         This connector uses the NIO implementation. The default
         SSLImplementation will depend on the presence of the APR/native
         library and the useOpenSSL attribute of the
         AprLifecycleListener.
         Either JSSE or OpenSSL style configuration may be used regardless of
         the SSLImplementation selected. JSSE style configuration is used below.
    -->
    <!--
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
               maxThreads="150" SSLEnabled="true">
        <SSLHostConfig>
            <Certificate certificateKeystoreFile="conf/localhost-rsa.jks"
                         type="RSA" />
        </SSLHostConfig>
    </Connector>
    -->
    <!-- Define a SSL/TLS HTTP/1.1 Connector on port 8443 with HTTP/2
         This connector uses the APR/native implementation which always uses
         OpenSSL for TLS.
         Either JSSE or OpenSSL style configuration may be used. OpenSSL style
         configuration is used below.
    -->
    <!--
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"
               maxThreads="150" SSLEnabled="true" >
        <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
        <SSLHostConfig>
            <Certificate certificateKeyFile="conf/localhost-rsa-key.pem"
                         certificateFile="conf/localhost-rsa-cert.pem"
                         certificateChainFile="conf/localhost-rsa-chain.pem"
                         type="RSA" />
        </SSLHostConfig>
    </Connector>
    -->

    <!-- Define an AJP 1.3 Connector on port 8009 -->
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />


    <!-- An Engine represents the entry point (within Catalina) that processes
         every request.  The Engine implementation for Tomcat stand alone
         analyzes the HTTP headers included with the request, and passes them
         on to the appropriate Host (virtual host).
         Documentation at /docs/config/engine.html -->

    <!-- You should set jvmRoute to support load-balancing via AJP ie :
    <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
    -->
    <Engine name="Catalina" defaultHost="localhost">

      <!--For clustering, please take a look at documentation at:
          /docs/cluster-howto.html  (simple how to)
          /docs/config/cluster.html (reference documentation) -->
      <!--
      <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
      -->

      <!-- Use the LockOutRealm to prevent attempts to guess user passwords
           via a brute-force attack -->
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <!-- This Realm uses the UserDatabase configured in the global JNDI
             resources under the key "UserDatabase".  Any edits
             that are performed against this UserDatabase are immediately
             available for use by the Realm.  -->
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>

      <Host name="localhost"  appBase="/data/tomcat/webapps/app"
            unpackWARs="true" autoDeploy="true">

        <!-- SingleSignOn valve, share authentication between web applications
             Documentation at: /docs/config/valve.html -->
        <!--
        <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
        -->

        <!-- Access log processes all example.
             Documentation at: /docs/config/valve.html
             Note: The pattern used is equivalent to using pattern="common" -->
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t "%r" %s %b" />
      </Host>
    </Engine>
  </Service>
</Server>
  1. 準備tomcat動態頁面
cd /opt/app
mkdir -p tomcat/app1/tomcat-app
cd tomcat/app1/tomcat-app

 

注意這里:因為nginx中位置配置的配置路徑是tomcat-app,往tomcat調度的時候會帶上這個路徑,所以,掛載進去的路徑也要與之匹配,即:要能夠訪問http:// tomcat -app1:8080 / tomcat-app,才能通過nginx來調度

  1. 動態頁面示例
vim showhost.jsp
<%@page import="java.util.Enumeration"%>
<br />
host:
<%try{out.println(""+java.net.InetAddress.getLocalHost().getHostName());}catch(Exception e){}%>
<br />
remoteAddr: <%=request.getRemoteAddr()%>
<br />
remoteHost: <%=request.getRemoteHost()%>
<br />
sessionId: <%=request.getSession().getId()%>
<br />
serverName:<%=request.getServerName()%>
<br />
scheme:<%=request.getScheme()%>
<br />
<%request.getSession().setAttribute("t1","t2");%>
<%
Enumeration en = request.getHeaderNames();
while(en.hasMoreElements()){
String hd = en.nextElement().toString();
out.println(hd+" : "+request.getHeader(hd));
out.println("<br />");
}
%>

 

創建docker-compose.yml

mkdir -p /opt/app
cd /opt/app
vim docker-compose.yml
service-haproxy:
  image: 192.168.99.21/haproxy/haproxy:v1
  container_name: haproxy
  volumes:
    - ./haproxy/conf/haproxy.cfg:/etc/haproxy/haproxy.cfg
  expose:
    - 80
    - 443
    - 9999
  ports:
    - "80:80"
    - "443:443"
    - "9999:9999"
  links:
    - service-nginx-web

service-nginx-web:
  image: 192.168.99.21/nginx/mynginx:v1
  container_name: nginx-web1
  volumes:
    - ./nginx/html/app1:/apps/nginx/html/app1
    - ./nginx/html/app2:/apps/nginx/html/app2
    - ./nginx/conf/nginx.conf:/usr/local/nginx/conf/nginx.conf
  expose:
    - 80
    - 443
  links:
    - service-tomcat-app1
    - service-tomcat-app2

service-tomcat-app1:
  image: 192.168.99.21/tomcat/mytomcat-app:v1
  container_name: tomcat-app1
  volumes:
    - ./tomcat/app1:/data/tomcat/webapps/app/ROOT
    - ./tomcat/conf/server.xml:/apps/tomcat/conf/server.xml
  expose:
    - 8080

service-tomcat-app2:
  image: 192.168.99.21/tomcat/mytomcat-app:v1
  container_name: tomcat-app2
  volumes:
    - ./tomcat/app1:/data/tomcat/webapps/app/ROOT
    - ./tomcat/conf/server.xml:/apps/tomcat/conf/server.xml
  expose:
    - 8080

最終檔案目錄

cd /opt/app
# tree
.
├── docker-compose.yml
├── haproxy
│   └── conf
│       └── haproxy.cfg
│   
├── nginx
│   ├── conf
│   │   └── nginx.conf
│   └── html
│       ├── app1
│       │   └── index.html
│       └── app2
│           └── index.html
└── tomcat
    ├── app1
    │   └── tomcat-app
    │       └── showhost.jsp
    └── conf
        └── server.xml

測驗訪問

http://192.168.99.22/tomcat-app/showhost.jsp
在這里插入圖片描述

 

以上就是Docke容器大部分的使用情景及功能實作

轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/98098.html

標籤:Linux

上一篇:Linux學習筆記(七)關機、重啟及常用的網路命令

下一篇:負載均衡服務之HAProxy基礎入門

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • CA和證書

    1、在 CentOS7 中使用 gpg 創建 RSA 非對稱密鑰對 gpg --gen-key #Centos上生成公鑰/密鑰對(存放在家目錄.gnupg/) 2、將 CentOS7 匯出的公鑰,拷貝到 CentOS8 中,在 CentOS8 中使用 CentOS7 的公鑰加密一個檔案 gpg -a ......

    uj5u.com 2020-09-10 00:09:53 more
  • Kubernetes K8S之資源控制器Job和CronJob詳解

    Kubernetes的資源控制器Job和CronJob詳解與示例 ......

    uj5u.com 2020-09-10 00:10:45 more
  • VMware下安裝CentOS

    VMware下安裝CentOS 一、軟硬體準備 1 Centos鏡像準備 1.1 CentOS鏡像下載地址 下載地址 1.2 CentOS鏡像下載程序 點擊下載地址進入如下圖的網站,選擇需要下載的版本,這里選擇的是Centos8,點擊如圖所示。 決定選擇Centos8后,選擇想要的鏡像源進行下載,此 ......

    uj5u.com 2020-09-10 00:12:10 more
  • 如何使用Grep命令查找多個字串

    如何使用Grep 命令查找多個字串 大家好,我是良許! 今天向大家介紹一個非常有用的技巧,那就是使用 grep 命令查找多個字串。 簡單介紹一下,grep 命令可以理解為是一個功能強大的命令列工具,可以用它在一個或多個輸入檔案中搜索與正則運算式相匹配的文本,然后再將每個匹配的文本用標準輸出的格式 ......

    uj5u.com 2020-09-10 00:12:28 more
  • git配置http代理

    git配置http代理 經常遇到克隆 github 慢的問題,這里記錄一下幾種配置 git 代理的方法,解決 clone github 過慢。 目錄 git配置代理 git單獨配置github代理 git配置全域代理 配置終端環境變數 git配置代理 主要使用 git config 命令 git單獨 ......

    uj5u.com 2020-09-10 00:12:33 more
  • Linux npm install 裝包時提示Error EACCES permission denied解

    npm install 裝包時提示Error EACCES permission denied解決辦法 ......

    uj5u.com 2020-09-10 00:12:53 more
  • Centos 7下安裝nginx,使用yum install nginx,提示沒有可用的軟體包

    Centos 7下安裝nginx,使用yum install nginx,提示沒有可用的軟體包。 18 (flaskApi) [root@67 flaskDemo]# yum -y install nginx 19 已加載插件:fastestmirror, langpacks 20 Loading ......

    uj5u.com 2020-09-10 00:13:13 more
  • Linux查看服務器暴力破解ssh IP

    在公網的服務器上經常遇到別人爆破你服務器的22埠,用來挖礦或者干其他嘿嘿嘿的事情~ 這種情況下正確的做法是: 修改默認ssh的22埠 使用設定密鑰登錄或者白名單ip登錄 建議服務器密碼為復雜密碼 創建普通用戶登錄服務器(root權限過大) 建立堡壘機,實作統一管理服務器 統計爆破IP [root ......

    uj5u.com 2020-09-10 00:13:17 more
  • CentOS 7系統常見快捷鍵操作方式

    Linux系統中一些常見的快捷方式,可有效提高操作效率,在某些時刻也能避免操作失誤帶來的問題。 ......

    uj5u.com 2020-09-10 00:13:31 more
  • CentOS 7作業系統目錄結構介紹

    作業系統存在著大量的資料檔案資訊,相應檔案資訊會存在于系統相應目錄中,為了更好的管理資料資訊,會將系統進行一些目錄規劃,不同目錄存放不同的資源。 ......

    uj5u.com 2020-09-10 00:13:35 more
最新发布
  • vim的常用命令

    Vim的6種基本模式 1. 普通模式在普通模式中,用的編輯器命令,比如移動游標,洗掉文本等等。這也是Vim啟動后的默認模式。這正好和許多新用戶期待的操作方式相反(大多數編輯器默認模式為插入模式)。 2. 插入模式在這個模式中,大多數按鍵都會向文本緩沖中插入文本。大多數新用戶希望文本編輯器編輯程序中一 ......

    uj5u.com 2023-04-20 08:43:21 more
  • vim的常用命令

    Vim的6種基本模式 1. 普通模式在普通模式中,用的編輯器命令,比如移動游標,洗掉文本等等。這也是Vim啟動后的默認模式。這正好和許多新用戶期待的操作方式相反(大多數編輯器默認模式為插入模式)。 2. 插入模式在這個模式中,大多數按鍵都會向文本緩沖中插入文本。大多數新用戶希望文本編輯器編輯程序中一 ......

    uj5u.com 2023-04-20 08:42:36 more
  • docker學習

    ###Docker概述 真實專案部署環境可能非常復雜,傳統發布專案一個只需要一個jar包,運行環境需要單獨部署。而通過Docker可將jar包和相關環境(如jdk,redis,Hadoop...)等打包到docker鏡像里,將鏡像發布到Docker倉庫,部署時下載發布的鏡像,直接運行發布的鏡像即可。 ......

    uj5u.com 2023-04-19 09:26:53 more
  • 設定Windows主機的瀏覽器為wls2的默認瀏覽器

    這里以Chrome為例。 1. 準備作業 wsl是可以使用Windows主機上安裝的exe程式,出于安全考慮,默認情況下改功能是無法使用。要使用的話,終端需要以管理員權限啟動。 我這里以Windows Terminal為例,介紹如何默認使用管理員權限打開終端,具體操作如下圖所示: 2. 操作 wsl ......

    uj5u.com 2023-04-19 09:25:49 more
  • docker學習

    ###Docker概述 真實專案部署環境可能非常復雜,傳統發布專案一個只需要一個jar包,運行環境需要單獨部署。而通過Docker可將jar包和相關環境(如jdk,redis,Hadoop...)等打包到docker鏡像里,將鏡像發布到Docker倉庫,部署時下載發布的鏡像,直接運行發布的鏡像即可。 ......

    uj5u.com 2023-04-19 09:19:04 more
  • Linux學習筆記

    IP地址和主機名 IP地址 ifconfig可以用來查詢本機的IP地址,如果不能使用,可以通過install net-tools安裝。 Centos系統下ens33表示主網卡;inet后表示IP地址;lo表示本地回環網卡; 127.0.0.1表示代指本機;0.0.0.0可以用于代指本機,同時在放行設 ......

    uj5u.com 2023-04-18 06:52:01 more
  • 解決linux系統的kdump服務無法啟動的問題

    問題:專案麒麟系統服務器的kdump服務無法啟動,沒有相關日志無法定位問題。 1、查看服務狀態是關閉的,重啟系統也無法啟動 systemctl status kdump 2、修改grub引數,修改“crashkernel”為“512M(有的機器數值太大太小都會導致報錯,建議從128M開始試,或者加個 ......

    uj5u.com 2023-04-12 09:59:50 more
  • 解決linux系統的kdump服務無法啟動的問題

    問題:專案麒麟系統服務器的kdump服務無法啟動,沒有相關日志無法定位問題。 1、查看服務狀態是關閉的,重啟系統也無法啟動 systemctl status kdump 2、修改grub引數,修改“crashkernel”為“512M(有的機器數值太大太小都會導致報錯,建議從128M開始試,或者加個 ......

    uj5u.com 2023-04-12 09:59:01 more
  • 你是不是暴露了?

    作者:袁首京 原創文章,轉載時請保留此宣告,并給出原文連接。 如果您是計算機相關從業人員,那么應該經歷不止一次網路安全專項檢查了,你肯定是收到過資訊系統技術檢測報告,要求你加強風險監測,確保你提供的系統服務堅實可靠了。 沒檢測到問題還好,檢測到問題的話,有些處理起來還是挺麻煩的,尤其是線上正在運行的 ......

    uj5u.com 2023-04-05 16:52:56 more
  • 細節拉滿,80 張圖帶你一步一步推演 slab 記憶體池的設計與實作

    1. 前文回顧 在之前的幾篇記憶體管理系列文章中,筆者帶大家從宏觀角度完整地梳理了一遍 Linux 記憶體分配的整個鏈路,本文的主題依然是記憶體分配,這一次我們會從微觀的角度來探秘一下 Linux 內核中用于零散小記憶體塊分配的記憶體池 —— slab 分配器。 在本小節中,筆者還是按照以往的風格先帶大家簡單 ......

    uj5u.com 2023-04-05 16:44:11 more