Docker操作篇
Docker操作篇
本筆記以個人思維為導向講述docker的操作,以實驗用到什么聊什么為敘述指導,不包含太多關于原理性內容,并且自身為運維,故整篇文章還是偏重于運維角度的,距通用文檔水平相去尚遠,更算不得一篇原理性筆記,只是操作。綜上這篇筆記還是比較合適對容器已經有一定概念的運維同學來一起學習使用。
并且本筆記不包含docker compose與docker swarm的內容,推薦在掌握了docker基礎后使用kubernetes,故此不再過多的涉及docker的編排方面。
本文實驗環境:
? 基于 Centos7.9(通篇以linux為基本講述,mac os及windows不涉及)
? docker版本:docker-ce-20.10.7
? 每節點 2核心2G內存40G磁盤
節點概況:
| 192.168.1.101 | node01 | docker測試 |
| 192.168.1.102 | node02 | docker測試 |
| 192.168.1.110 | harbor | harbor |
修改記錄:
| v.00 | 2021.6 | systemctl529_Yu |
注:
? 一定請看好每條命令前的主機名,本筆記以主機名區分不同主機操作
一、容器的概念及簡史
容器,顧名思義,即為承載其他“物體”的器具,如生活中的鍋碗瓢盆,他們都是物理世界中真實可觸碰的載具,我們這里提到的容器,是軟件層級的邏輯容器。
關于容器技術的發展,最早被認為是容器的技術,出現在1979年,Unix版本7在開發過程中引入Chroot Jail以及Chroot系統調用。Chroot jail被用于“Change Root”,它被認為是最早的容器化技術之一。(相信應該有不少人在單用戶模式下使用過chroot /sysroot)
后來在21世紀初期出現了眾多的容器相關的技術,比如Linux-Vserver,比如Cgroups LXC等等
而我們今天討論的docker,第一個開源版本出現于2013年,但現今為止,類似docker的這種容器引擎,存在有眾多的發行版本,截止目前,docker仍然是容器引擎的主流
docker公司原本叫做dotCloud,做PaaS項目,然而經營并不好,13年他們開源了docker,竟突然獲得巨大成功,所以公司也就改名叫做docker Inc了,docker公司的CTO Solomon Hykes,是docker的靈魂人物,也正是他提出了現在注明的:“Build Once,Run Anywhere”,一次構建,到處運行。
探討一個問題,我們已經有了相當成熟的Iaas虛擬化架構,為何又需要paas,我個人認為主要還是來源于效率的需求,傳統虛擬化總是無法繞過“客戶機操作系統”,即便是一個經過了精心裁剪的系統,其也無法擺脫一個獨立的客戶機系統內核及基本運行環境等的資源占用,而容器技術一大區別就是其不再需要額外的虛擬化出一套完整的系統,其內核直接共用宿主機系統,只需要封裝一個基本的軟件所需運行環境和項目代碼即可了,這就使其足夠的輕量化,減輕了一些資源的浪費,并且因為一個一個簡潔的鏡像和運行時,docker變得要比傳統軟件部署一定方面上更易于管理,再加上容器一旦配合上一些編排技術,那么其快速的擴縮容能力和通用部署能力也非傳統虛擬化可比。當然了,目前來看,任何技術都并非完美的,虛擬化亦有其自身目前難以被替代的優勢,比如其真正的資源隔離,對物理機的資源集群整合等。而且其實目前大部分的容器集群,真正的利用環境亦是運行在虛擬機之上的,真正具備物理機直接運行容器的企業,還是相對較大型的體量,總體較少,所以容器目前對于中小企業來看,仍然是前瞻意義大于實際意義的。
容器的優勢和劣勢在哪里?簡單來說,容器的主要劣勢還是存在于隔離性上面,優勢就較多了,比如資源消耗小,啟動速度快,跨平臺能力強,擴展快,對微服務支持好,對自動化架構配合好等
二、Docker的實現
1、docker的實現技術
1.1 虛擬結構的不同
常見的傳統虛擬化:
? 以下是一個 2 型虛擬化的基本結構圖:
傳統的虛擬化通常有兩種,1型虛擬化(如xen esxi)或者2型虛擬化(kvm workstation),不論是1型還是2型,都無法離開“Guest OS”,這也就會帶來一定的資源額外消耗,
容器的虛擬化
容器也是一種虛擬化技術,只是它并非是“平臺虛擬化”,而是“操作系統虛擬化”,也就是說,其虛擬的內容已經不再是傳統虛擬化的硬件資源,而是應用運行環境
? 以下是容器的基本結構圖:
可以看到,容器是直接運行在宿主機系統之上的,不再需要一個額外的操作系統來作為應用運行環境,故這種形式,也可以將一個容器看作是一個“進程”
1.2 容器用哪些內核技術實現
既然容器直接跑在宿主機中,那么資源的隔離和限制怎么來實現,到目前,解決方案已經直接集成在了系統內核中
docker通過系統內核中的 namespace實現資源隔離,通過cGroups實現資源限制,那么一個容器需要隔離出哪些基本資源?
namespace資源隔離
| Mount(文件系統,掛載點…) | 2.4.19 |
| Pid (進程ID) | 2.6.24 |
| IPC (信號量,消息隊列,共享內存…) | 2.6.19 |
| Net (網絡設備,網絡協議棧,端口…) | 2.6.29 |
| UTS (主機名,域名…) | 2.6.19 |
| User(操作進程的用戶及用戶組) | 3.8 |
namespace隔離的系統調用參數及基本解釋
mount CLONE_NEWNS 每個容器的文件系統是獨立的
pid CLONE_NEWPID 每個容器內部有獨立的進程樹
IPC CLONE_NEWIPC 每個容器依舊使用linux內核中進程交互的方法,實現進程間通信
Net CLONE_NEWNET 每個容器之間的網絡默認隔離
UTS CLONE_NEWUTS 每個namesapce有自己獨立的主機名或者域名
User CLONE_NEWUSER 每個容器都有獨立的root,獨立的用戶
cGroups
cgroups(Control Groups) 是 linux內核提供的一種機制,這種機制可以根據需求把一系列系統任務及其子任務整合(或分隔)到按資源劃分等級的不同組內,從而為系統資源管理提供一個統一的框架。簡單說,cgroups可以限制、記錄任務組所使用的物理資源。本質上來說,cgroups 是內核附加在程序上的一系列鉤子(hook),通過程序運行時對資源的調度觸發相應的鉤子以達到資源追蹤和限制的目的。
實現 cgroups 的主要目的是為不同用戶層面的資源管理提供一個統一化的接口。從單個任務的資源控制到操作系統層面的虛擬化,cgroups 提供了四大功能:
資源限制:cgroups 可以對任務是要的資源總額進行限制,比如設定任務運行時使用的內存上限,一旦超出就發OOM。
優先級分配:通過分配的 CPU 時間片數量和磁盤 IO 帶寬,實際上就等同于控制了任務運行的優先級。
資源統計:cgoups 可以統計系統的資源使用量,比如 CPU 使用時長、內存用量等。這個功能非常適合當前云端產品按使用量計費的方式。
? 任務控制:cgroups 可以對任務執行掛起、恢復等操作。
2、Docker的實現語言
docker引擎是基于Google公司的Go語言來編寫實現,Golang號稱21世紀C語言,當前非常熱門,目前來看,Go語言的前景也確實夠好。
Go(又稱Golang)是Google開發的一種靜態強類型、編譯型、并發型,并具有垃圾回收功能的編程語言。
docker部署時,可以直接安裝二進制軟件包,如果想要源碼編譯,也就需要一個Go的編譯環境。
三、安裝Docker
關于系統環境的基本初始化就不再贅述了,仍然是關掉防火墻,Selinux這一套
另外可能唯一和之前不同的是,需要開一下路由轉發
# echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf # sysctl -p我們安裝的docker,是docker-ce(社區版),企業版是docker-ee
1、配置Yum源
因為這里使用的是Centos(Rpm包管理),故需要配置的是yum源
首先配置基礎源,可以是系統默認的,也可以自己手動新增國內源,然后配置docker源
# 配置清華源 [root@node01 yum.repos.d]# pwd /etc/yum.repos.d # 注意,國內源中缺少一些包,不要刪除掉系統自帶的repo文件,只新增即可 [root@node01 yum.repos.d]# vim tuna.os.repo [tuna_centos] name=tuna.centos.os.yum baseurl=https://mirrors.tuna.tsinghua.edu.cn/centos/7.9.2009/os/x86_64/ enabled=1 gpgcheck=0# epel源 [root@node01 yum.repos.d]# vim tuna.epel.repo [tuna.epel] name=tuna.epel baseurl=https://mirrors.tuna.tsinghua.edu.cn/epel/7/x86_64/ enabled=1 gpgcheck=0# 配置docker源 [root@node01 yum.repos.d]# vim tuna.docker.repo [docker-ce-stable] name=Docker CE Stable - $basearch baseurl=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/$releasever/$basearch/stable enabled=1 gpgcheck=1 gpgkey=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/gpg 或者 [root@node01 yum.repos.d]# wget https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo [root@node01 yum.repos.d]# sed -i 's+download.docker.com+mirrors.tuna.tsinghua.edu.cn/docker-ce+' /etc/yum.repos.d/docker-ce.repo# 緩存 [root@node01 yum.repos.d]# yum clean all [root@node01 yum.repos.d]# yum makecache# 查看最新的docekr版本 [root@node01 yum.repos.d]# yum list docker-ce 已加載插件:fastestmirror Loading mirror speeds from cached hostfile 可安裝的軟件包 docker-ce.x86_64 3:20.10.7-3.el7 docker-ce-stable列出源中所有軟件包版本可以執行
[root@node01 yum.repos.d]# yum list docker-ce --show-duplicates
2、更新系統軟件包
也可以只更新kernel相關包
[root@node01 yum.repos.d]# yum update3、安裝docker
[root@node01 ~]# yum -y install docker-ce[root@node01 ~]# docker -v Docker version 20.10.7, build f0df3504、配置并啟動docker
# 啟動并設置開機自啟 [root@node01 ~]# systemctl start docker [root@node01 ~]# systemctl enable docker # 配置docker [root@node01 ~]# vim /etc/docker/daemon.json {"data-root": "/docker","bip": "172.1.1.1/16","storage-driver": "overlay2" }[root@node01 ~]# systemctl daemon-reloaddaemon.json配置項簡析:
首先需要一個 {},然后每行配置的間隔需要使用 , 號,最后一行可以不加 ,號
“exec-root”:“/docker” exec-root配置的是docker工作目錄
“registry-mirrors”: [“https://xxxxxxxxxxxxxx.mirror.aliyuncs.com”] registry-mirrors是配置的鏡像加速,如果有多個,可以[“1”,‘’2“]繼續寫
“insecure-registries”: [“域名/IP:port”] insecure-registries配置的是私有非ssl鏡像倉庫地址,如果有多個,可以[“1”,“2”]繼續寫
“storage-driver”: “overlay2” storage-driver存儲驅動程序
\“bip”: “172.1.1.1/16” bip docker網絡
“live-restore”: true live-restore傳遞一個SIGHUP信號給daemon進程來重載配置
docker-daemon.json各配置詳解 {“api-cors-header”:"", ——————在引擎API中設置CORS標頭“authorization-plugins”:[], ——————要加載的授權插件“bridge”:"", ————將容器附加到網橋“cgroup-parent”:"", ——————為所有容器設置父cgroup“cluster-store”:"", ——————分布式存儲后端的URL“cluster-store-opts”:{}, ————————設置集群存儲選項(默認map [])“cluster-advertise”:"", ————————要通告的地址或接口名稱“debug”: true, ————————啟用調試模式,啟用后,可以看到很多的啟動信息。默認false“default-gateway”:"", ——————容器默認網關IPv4地址“default-gateway-v6”:"", ——————容器默認網關IPv6地址“default-runtime”:“runc”, ————————容器的默認OCI運行時(默認為“ runc”)“default-ulimits”:{}, ——————容器的默認ulimit(默認[])“dns”: [“192.168.1.1”], ——————設定容器DNS的地址,在容器的 /etc/resolv.conf文件中可查看?!癲ns-opts”: [], ————————容器 /etc/resolv.conf 文件,其他設置“dns-search”: [], ————————設定容器的搜索域,當設定搜索域為 .example.com 時,在搜索一個名為 host 的 主機時,DNS不僅搜索host,還會搜索host.example.com 。 注意:如果不設置, Docker 會默認用主機上的 /etc/resolv.conf 來配置容器。“exec-opts”: [], ————————運行時執行選項“exec-root”:"", ————————執行狀態文件的根目錄(默認為’/var/run/docker‘)“fixed-cidr”:"", ————————固定IP的IPv4子網“fixed-cidr-v6”:"", ————————固定IP的IPv6子網“data-root”:"/var/lib/docker", ————-Docker運行時使用的根路徑,默認/var/lib/docker“group”: “”, ——————UNIX套接字的組(默認為“docker”)“hosts”: [], ——————設置容器hosts“icc”: false, ——————啟用容器間通信(默認為true)“ip”:“0.0.0.0”, ————————綁定容器端口時的默認IP(默認0.0.0.0)“iptables”: false, ———————啟用iptables規則添加(默認為true)“ipv6”: false, ——————啟用IPv6網絡“ip-forward”: false, ————————默認true, 啟用 net.ipv4.ip_forward ,進入容器后使用 sysctl -a | grepnet.ipv4.ip_forward 查看“ip-masq”:false, ——————啟用IP偽裝(默認為true)“labels”:[“nodeName=node-121”], ————————docker主機的標簽,很實用的功能,例如定義:–label nodeName=host-121“live-restore”: true, ——————在容器仍在運行時啟用docker的實時還原“log-driver”:"", ——————容器日志的默認驅動程序(默認為“ json-file”)“log-level”:"", ——————設置日志記錄級別(“調試”,“信息”,“警告”,“錯誤”,“致命”)(默認為“信息”)“max-concurrent-downloads”:3, ——————設置每個請求的最大并發下載量(默認為3)“max-concurrent-uploads”:5, ——————設置每次推送的最大同時上傳數(默認為5)“mtu”: 0, ——————設置容器網絡MTU“oom-score-adjust”:-500, ——————設置守護程序的oom_score_adj(默認值為-500)“pidfile”: “”, ——————Docker守護進程的PID文件“raw-logs”: false, ——————全時間戳機制“selinux-enabled”: false, ——————默認 false,啟用selinux支持“storage-driver”:"", ——————要使用的存儲驅動程序“swarm-default-advertise-addr”:"", ——————設置默認地址或群集廣告地址的接口“tls”: true, ————————默認 false, 啟動TLS認證開關“tlscacert”: “”, ——————默認 ~/.docker/ca.pem,通過CA認證過的的certificate文件路徑“tlscert”: “”, ————————默認 ~/.docker/cert.pem ,TLS的certificate文件路徑“tlskey”: “”, ————————默認~/.docker/key.pem,TLS的key文件路徑“tlsverify”: true, ————————默認false,使用TLS并做后臺進程與客戶端通訊的驗證“userland-proxy”:false, ——————使用userland代理進行環回流量(默認為true)“userns-remap”:"", ————————用戶名稱空間的用戶/組設置“bip”:“192.168.88.0/22”, ——————————指定網橋IP“registry-mirrors”: [“https://192.498.89.232:89”], ————————設置鏡像加速“insecure-registries”: [“120.123.122.123:12312”], ———————設置私有倉庫地址可以設為http“storage-opts”: [“overlay2.override_kernel_check=true”,“overlay2.size=15G”], ————————存儲驅動程序選項“log-opts”: {“max-file”: “3”,“max-size”: “10m”,}, ————————容器默認日志驅動程序選項“iptables”: false ————————啟用iptables規則添加(默認為true) }5、docker基本信息查看
# 執行docker info 可以查看基本的docker信息 [root@node01 docker]# docker info Client:Context: defaultDebug Mode: falsePlugins:app: Docker App (Docker Inc., v0.9.1-beta3)buildx: Build with BuildKit (Docker Inc., v0.5.1-docker)scan: Docker Scan (Docker Inc., v0.8.0)Server:Containers: 0Running: 0Paused: 0Stopped: 0Images: 0Server Version: 20.10.7 Storage Driver: overlay2 Backing Filesystem: xfsSupports d_type: trueNative Overlay Diff: trueuserxattr: falseLogging Driver: json-fileCgroup Driver: cgroupfsCgroup Version: 1Plugins:Volume: localNetwork: bridge host ipvlan macvlan null overlayLog: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslogSwarm: inactiveRuntimes: io.containerd.runc.v2 io.containerd.runtime.v1.linux runcDefault Runtime: runcInit Binary: docker-initcontainerd version: d71fcd7d8303cbf684402823e425e9dd2e99285drunc version: b9ee9c6314599f1b4a7f497e1f1f856fe433d3b7init version: de40ad0Security Options:seccompProfile: defaultKernel Version: 3.10.0-1160.11.1.el7.x86_64Operating System: CentOS Linux 7 (Core)OSType: linuxArchitecture: x86_64CPUs: 2Total Memory: 1.933GiBName: node01ID: WIDC:DX4D:7IW7:H5OR:EK4Y:F4YX:ABUI:IKE7:DVIN:K5W3:KE76:6YAODocker Root Dir: /dockerDebug Mode: falseRegistry: https://index.docker.io/v1/Labels:Experimental: falseInsecure Registries:127.0.0.0/8Registry Mirrors:https://xxxxxx.mirror.aliyuncs.com/Live Restore Enabled: false如果執行 docker info時,發現了以下兩條警告
WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled
這意味著你的防火墻沒有關閉,如果不想關,就增加下配置,以要求iptables不對bridge的數據進行處理
# vim /etc/sysctl.conf # 追加 net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1# sysctl -p net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 16、docker鏡像加速
提前做一下docker鏡像加速的配置,因為后面運行docker需要先拉取docker鏡像,但是docker hub是在國外的,對我們而言,很慢,所以先配置下加速
這里以阿里云鏡像加速為例,首先記得注冊好阿里云賬號
配置下加速地址
[root@node01 ~]# vim /etc/docker/daemon.json {### 追加以下一行"registry-mirrors": ["https://xxxxxxxxxxxx.mirror.aliyuncs.com"] }[root@node01 ~]# systemctl daemon-reload [root@node01 ~]# systemctl restart docker四、Docker的使用
docker對鏡像或者容器的操作,使用ID或者名稱均可
1、docker 鏡像
docker鏡像,就是打包好的應用以及應用環境(代碼,運行時,庫,環境變量,配置文件等)
1.1 查看本地鏡像
# docker images 查看鏡像列表 [root@node01 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE1.2 搜索鏡像
搜索鏡像可以在命令行搜索,也可以去比如docker hub等鏡像倉庫搜索
[root@node01 ~]# docker search centos NAME DESCRIPTION STARS OFFICIAL AUTOMATED centos The official build of CentOS. 6594 [OK] ansible/centos7-ansible Ansible on Centos7 134 [OK] consol/centos-xfce-vnc Centos container with "headless" VNC session… 129 [OK] jdeathe/centos-ssh OpenSSH / Supervisor / EPEL/IUS/SCL Repos - … 118 [OK] ......docker 官方鏡像倉庫:https://registry.hub.docker.com/
1.3 拉取鏡像
拉取鏡像時,如果不指定版本,那么拉取的就是 latest 最新版本,指定版本 # docker pull centos:TAG
[root@node01 ~]# docker pull centos Using default tag: latest latest: Pulling from library/centos 7a0437f04f83: Downloading 39.37MB/75.18MB[root@node01 ~]# docker pull centos:7.9.2009 7.9.2009: Pulling from library/centos 2d473b07cdd5: Downloading 22.57MB/76.1MB# 查看下本地鏡像 [root@node01 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE centos latest 300e315adb2f 6 months ago 209MB centos 7.9.2009 8652b9f0cb4c 7 months ago 204MB1.4 刪除鏡像
[root@node01 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE centos latest 300e315adb2f 6 months ago 209MB centos 7.9.2009 8652b9f0cb4c 7 months ago 204MB[root@node01 ~]# docker rmi centos:latest Untagged: centos:latest Untagged: centos@sha256:5528e8b1b1719d34604c87e11dcd1c0a20bedf46e83b5632cdeac91b8c04efc1 Deleted: sha256:300e315adb2f96afe5f0b2780b87f28ae95231fe3bdd1e16b9ba606307728f55 Deleted: sha256:2653d992f4ef2bfd27f94db643815aa567240c37732cae1405ad1c1309ee9859[root@node01 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE centos 7.9.2009 8652b9f0cb4c 7 months ago 204MB1.5 導入導出鏡像
# 導出 [root@node01 ~]# docker save centos:7.9.2009 -o /tmp/centos.7.9.2009 [root@node01 ~]# du -sh /tmp/centos.7.9.2009 202M /tmp/centos.7.9.2009# 導入 先刪除本地的centos:7.9.2009鏡像 [root@node01 ~]# docker rmi centos:7.9.2009 Untagged: centos:7.9.2009 Untagged: centos@sha256:0f4ec88e21daf75124b8a9e5ca03c37a5e937e0e108a255d890492430789b60e Deleted: sha256:8652b9f0cb4c0599575e5a003f5906876e10c1ceb2ab9fe1786712dac14a50cf Deleted: sha256:174f5685490326fc0a1c0f5570b8663732189b327007e47ff13d2ca59673db02 [root@node01 ~]# docker load < /tmp/centos.7.9.2009 174f56854903: Loading layer 211.7MB/211.7MB Loaded image: centos:7.9.2009 [root@node01 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE centos 7.9.2009 8652b9f0cb4c 7 months ago 204MB如果導入鏡像后,查看時,發現鏡像名為 ,這種可以使用 docker tag 來命名
# docker tag [鏡像ID] 鏡像名:TAG2、docker容器 (運行時)
也就是在運行的容器,運行起來的鏡像;其與鏡像的區別:鏡像是靜態的定義,容器是鏡像運行時的實體
關于容器生命周期
- 執行docker run時,檢查本地是否有該名稱的鏡像,如果沒有,從倉庫檢索并拉取
- 使用本地鏡像啟動容器
- 分配一個文件系統,并在只讀的鏡像層上掛載一個可寫層(容器層)
- 從宿主機配置的網橋接口中橋接一個虛擬接口到容器
- 從地址池中分配IP給容器
- 執行CMD指令
- 執行完畢后容器生命結束,容器停止
2.1 運行容器
docker run [選項 參數] 鏡像 CMD
# 當本地沒有你要運行的鏡像時,會自動拉取
[root@node01 ~]# docker pull centos:latest[root@node01 ~]# docker run centos2.2 查看運行的容器
# 查看運行中的容器 [root@node01 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 剛運行的容器并沒有存在,這是因為我們運行時沒有指定CMD運行內容,有些鏡像比如這種系統鏡像,是需要手動指定運行內容的# 查看所有的容器(包含未運行的) [root@node01 ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 36a3d9354ba4 centos "/bin/bash" 37 seconds ago Exited (0) 36 seconds ago confident_visvesvaraya2.3 運行時添加選項
常用選項
-d: 后臺運行容器,并返回容器ID;
-i: 以交互模式運行容器,通常與 -t 同時使用;
-P: 隨機端口映射,容器內部端口隨機映射到主機的端口
-p: 指定端口映射,格式為:主機(宿主)端口:容器端口
-t: 為容器重新分配一個偽輸入終端,通常與 -i 同時使用;
–name=“容器名”: 為容器指定一個名稱;
**-m **:設置容器使用內存最大值;
–net=“bridge”: 指定容器的網絡連接類型,支持 bridge/host/none/container: 四種類型;
–expose=[]: 開放一個端口或一組端口;
–volume , -v: 綁定一個卷
-e: 傳遞環境變量 環境變量key:環境變量value
# 運行bash程序 [root@node01 ~]# docker run -itd centos:latest /bin/bash 3b1157fa7e1b34b1c288de81da35cd8e310ff14ec4ea8d16d64cb4d60da96c09[root@node01 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3b1157fa7e1b centos:latest "/bin/bash" 2 seconds ago Up 1 second sharp_shaw2.4 查看容器運行輸出(日志)
[root@node01 ~]# docker run -itd --name="centos_v1" centos:latest /bin/bash -c "while true;do echo hello docker;sleep 10;done" efcd72ea15a7e1ca8c17245d0ed41c7e331d646a488e3c8ef5a3d8fd7490dc3c[root@node01 ~]# docker logs centos_v1 hello docker hello docker2.5 操作容器
[root@node01 ~]# docker exec -it centos_v1 /bin/bash [root@efcd72ea15a7 /]# psPID TTY TIME CMD22 pts/1 00:00:00 bash36 pts/1 00:00:00 ps# 退出時執行 exit [root@efcd72ea15a7 /]# exit exit2.6 查看容器相關信息
[root@node01 ~]# docker inspect centos_v1 [{"Id": "efcd72ea15a7e1ca8c17245d0ed41c7e331d646a488e3c8ef5a3d8fd7490dc3c","Created": "2021-06-13T09:51:13.330140921Z","Path": "/bin/bash","Args": ["-c","while true;do echo hello docker;sleep 10;done"],"State": {"Status": "running","Running": true,"Paused": false,"Restarting": false,"OOMKilled": false,"Dead": false,"Pid": 26148,"ExitCode": 0,"Error": "","StartedAt": "2021-06-13T09:51:14.040711318Z","FinishedAt": "0001-01-01T00:00:00Z"},"Image": "sha256:300e315adb2f96afe5f0b2780b87f28ae95231fe3bdd1e16b9ba606307728f55","ResolvConfPath": "/docker/containers/efcd72ea15a7e1ca8c17245d0ed41c7e331d646a488e3c8ef5a3d8fd7490dc3c/resolv.conf","HostnamePath": "/docker/containers/efcd72ea15a7e1ca8c17245d0ed41c7e331d646a488e3c8ef5a3d8fd7490dc3c/hostname","HostsPath": "/docker/containers/efcd72ea15a7e1ca8c17245d0ed41c7e331d646a488e3c8ef5a3d8fd7490dc3c/hosts","LogPath": "/docker/containers/efcd72ea15a7e1ca8c17245d0ed41c7e331d646a488e3c8ef5a3d8fd7490dc3c/efcd72ea15a7e1ca8c17245d0ed41c7e331d646a488e3c8ef5a3d8fd7490dc3c-json.log","Name": "/centos_v1","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,"CgroupnsMode": "host","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": "/docker/overlay2/119adbf51607bfc6fdfc8f30081b9263dc961d09400f1695527eb6b728b2209b-init/diff:/docker/overlay2/2386f591a659192e7d79caae80c3eb520db3d1120fbcd7970d9d6eb8fab10507/diff","MergedDir": "/docker/overlay2/119adbf51607bfc6fdfc8f30081b9263dc961d09400f1695527eb6b728b2209b/merged","UpperDir": "/docker/overlay2/119adbf51607bfc6fdfc8f30081b9263dc961d09400f1695527eb6b728b2209b/diff","WorkDir": "/docker/overlay2/119adbf51607bfc6fdfc8f30081b9263dc961d09400f1695527eb6b728b2209b/work"},"Name": "overlay2"},"Mounts": [],"Config": {"Hostname": "efcd72ea15a7","Domainname": "","User": "","AttachStdin": false,"AttachStdout": false,"AttachStderr": false,"Tty": true,"OpenStdin": true,"StdinOnce": false,"Env": ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd": ["/bin/bash","-c","while true;do echo hello docker;sleep 10;done"],"Image": "centos:latest","Volumes": null,"WorkingDir": "","Entrypoint": null,"OnBuild": null,"Labels": {"org.label-schema.build-date": "20201204","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": "0f3c7ccaebc706fb06f611ce07ce5c9a68c9ace1784a03af672f28bd3cc611d1","HairpinMode": false,"LinkLocalIPv6Address": "","LinkLocalIPv6PrefixLen": 0,"Ports": {},"SandboxKey": "/var/run/docker/netns/0f3c7ccaebc7","SecondaryIPAddresses": null,"SecondaryIPv6Addresses": null,"EndpointID": "ee962448e879bc5b001e3d77c04d0fa05c94aa6c9120e8e42b0705fab44c898f","Gateway": "172.1.1.1","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"IPAddress": "172.1.0.2","IPPrefixLen": 16,"IPv6Gateway": "","MacAddress": "02:42:ac:01:00:02","Networks": {"bridge": {"IPAMConfig": null,"Links": null,"Aliases": null,"NetworkID": "659b6c5dab2c8a0fd5058534fc195828865fc12d6e0388d47bf2a12118890998","EndpointID": "ee962448e879bc5b001e3d77c04d0fa05c94aa6c9120e8e42b0705fab44c898f","Gateway": "172.1.1.1","IPAddress": "172.1.0.2","IPPrefixLen": 16,"IPv6Gateway": "","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"MacAddress": "02:42:ac:01:00:02","DriverOpts": null}}}} ]2.7 提交容器為新鏡像
假設我們運行了一個容器,并完成了修改,想要將其保存為一個鏡像,在沒有聊到dockerfile前,可以使用commit來實現
[root@node01 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES efcd72ea15a7 centos:latest "/bin/bash -c 'while…" 6 minutes ago Up 6 minutes centos_v1 3b1157fa7e1b centos:latest "/bin/bash" 10 minutes ago Up 10 minutes sharp_shaw[root@node01 ~]# docker commit efcd72ea15a7 centos_while:v1 sha256:d11182ec9f08c11e57151f5005e6200432faf9da5563114fd9a6b7c7c0859af8[root@node01 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE centos_while v1 d11182ec9f08 5 seconds ago 209MB2.8 停止容器
[root@node01 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES efcd72ea15a7 centos:latest "/bin/bash -c 'while…" 9 minutes ago Up 9 minutes centos_v1 3b1157fa7e1b centos:latest "/bin/bash" 13 minutes ago Up 13 minutes sharp_shaw[root@node01 ~]# docker stop efcd72ea15a7 efcd72ea15a7[root@node01 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3b1157fa7e1b centos:latest "/bin/bash" 13 minutes ago Up 13 minutes sharp_shaw2.9 啟動容器
[root@node01 ~]# docker start efcd72ea15a7 efcd72ea15a7[root@node01 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES efcd72ea15a7 centos:latest "/bin/bash -c 'while…" 10 minutes ago Up 22 seconds centos_v1 3b1157fa7e1b centos:latest "/bin/bash" 14 minutes ago Up 14 minutes sharp_shaw2.10 刪除容器
先停后刪
[root@node01 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES efcd72ea15a7 centos:latest "/bin/bash -c 'while…" 10 minutes ago Up 22 seconds centos_v1 3b1157fa7e1b centos:latest "/bin/bash" 14 minutes ago Up 14 minutes sharp_shaw[root@node01 ~]# docker stop efcd efcd[root@node01 ~]# docker rm efcd efcd[root@node01 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3b1157fa7e1b centos:latest "/bin/bash" 15 minutes ago Up 15 minutes sharp_shaw2.11 更新運行參數
如果容器已經運行起來,不便于重新運行一個新容器的情況下更新參數,可以使用docker update,但不是每一個參數都可以更新
# 查看下哪些參數可以被更新 [root@node01 ~]# docker update --helpUsage: docker update [OPTIONS] CONTAINER [CONTAINER...]Update configuration of one or more containersOptions:--blkio-weight uint16 Block IO (relative weight), between 10 and 1000,or 0 to disable (default 0)--cpu-period int Limit CPU CFS (Completely Fair Scheduler) period--cpu-quota int Limit CPU CFS (Completely Fair Scheduler) quota--cpu-rt-period int Limit the CPU real-time period in microseconds--cpu-rt-runtime int Limit the CPU real-time runtime in microseconds-c, --cpu-shares int CPU shares (relative weight)--cpus decimal Number of CPUs--cpuset-cpus string CPUs in which to allow execution (0-3, 0,1)--cpuset-mems string MEMs in which to allow execution (0-3, 0,1)--kernel-memory bytes Kernel memory limit-m, --memory bytes Memory limit--memory-reservation bytes Memory soft limit--memory-swap bytes Swap limit equal to memory plus swap: '-1' toenable unlimited swap--pids-limit int Tune container pids limit (set -1 for unlimited)--restart string Restart policy to apply when a container exits# 簡單的解釋 --blkio-weight 阻塞IO (相對權重),介于10到1000之間,0表示禁用(默認禁止) --cpu-period 限制CPU CFS(完全公平的調度程序)期限 --cpu-quota 限制CPU CFS(完全公平的調度程序)配額 --cpu-rt-period API 1.25+,將CPU實時時間限制為微秒 --cpu-rt-runtime API 1.25+,將CPU實時運行時間限制為微秒 --cpu-shares, -c CPU份額(相對權重) --cpus API 1.29+,CPU數量 --cpuset-cpus 允許執行的CPU(0-3,0,1) --cpuset-mem 允許執行的MEM(0-3,0,1) --kernel-memory 內核內存限制 --memory-swap 交換限制等于內存加交換,“-1”以啟用無限交換 --memory-reservatio 內存軟限制 --memory, -m 內存限制 --pids-limit API 1.40+,調節容器pids限制(-1表示無限制) --restart 容器退出時重新啟動策略以應用 # 更新下容器使其內存最高為 256M [root@node01 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3b1157fa7e1b centos:latest "/bin/bash" 2 hours ago Up 2 hours sharp_shaw[root@node01 ~]# docker update -m 256M --memory-swap -1 3b11 # --momory-swap -1是因為docker 默認沒有啟用memory-swap交換內存,直接設置了內存問題會出問題,也就是說宿主 swap 支持使用多少則容器即可使用多少,將memory-swap 設置值為 -1,表示容器程序使用內存受限,而 swap 空間使用不受限制[root@node01 ~]# docker inspect 3b11|grep -Ei "\"memory\"""Memory": 268435456, # 已經生效3、docker 鏡像倉庫
存放鏡像文件的倉庫,我們這里不演示公共倉庫,如果想要使用公共倉庫,直接打開公共倉庫的頁面,都會有配置提示,我們本文只演示本地倉庫
docker使用Registry(注冊中心)來保存鏡像,常見的registry有公有私有兩種,私有最常見的封裝方案是 harbor
綜上,這里先顯示 harbor鏡像倉庫的搭建(作為私有倉庫),然后再來演示倉庫的登入登出等
harbor倉庫直接運行于docker中,采用docker-compose部署,故部署也是極為簡單
harbor的組件:
1、Proxy:反向代理工具
2、Registry:負責存儲docker鏡像,處理上傳/下載命令。對用戶進行訪問控制,它指向一個token服務,強制用戶的每次docker pull/push請求都要攜帶一個合法的token,registry會通過公鑰對token進行解密驗證。
3、Core service:Harbor的核心功能:
- UI:圖形界面
- Webhook:及時獲取registry上image狀態變化情況,在registry上配置 webhook,把狀態變化傳遞給UI模塊。
- Token服務:復雜根據用戶權限給每個docker push/p/ull命令簽發token。Docker客戶端向registry服務發起的請求,如果不包含token,會被重定向到這里,獲得token后再重新向registry進行請求。
4、Database:提供數據庫服務,存儲用戶權限,審計日志,docker image分組信息等數據
5、Log collector:為了幫助監控harbor運行,復責收集其他組件的log,供日后進行分析
3.1 下載Harbor
harbor主機采用 192.168.1.110來安裝,關于基礎環境初始化及yum源此處不再演示,參照上文即可
瀏覽器訪問:https://github.com/goharbor/harbor/releases 進行下載
# 創建一些目錄,用于后續使用 [root@harbor ~]# mkdir /data/app -p [root@harbor ~]# mkdir /data/docker [root@harbor ~]# mkdir /data/harbor# 安裝一下docker [root@harbor ~]# yum -y install docker-ce# 配置docker [root@harbor ~]# mkdir /etc/docker [root@harbor ~]# vim /etc/docker/daemon.json {"data-root": "/data/docker","bip": "172.1.1.1/16","storage-driver": "overlay2","registry-mirrors": ["https://xxxxxxxxxxxxxxxx.mirror.aliyuncs.com"] }[root@harbor ~]# systemctl start docker [root@harbor ~]# systemctl enable docker# 下載harbor [root@harbor /]# cd /data/app/ [root@harbor app]# wget https://github.com/goharbor/harbor/releases/download/v2.2.2/harbor-offline-installer-v2.2.2.tgz3.2 安裝docker-compose
harbor使用docker-compose部署,關于docker-compose的使用,后面再聊,現在先來安裝下(可以直接下載,也可以使用 # pip install docker-compose -i http://mirrors.aliyun.com/pypi/simple/
–trusted-host mirrors.aliyun.com)
docker-compose下載地址:https://github.com/docker/compose/releases/
# 下載 [root@node01 app]# wget https://github.com/docker/compose/releases/download/1.29.2/docker-compose-Linux-x86_64# 給予執行權限 [root@harbor app]# cp docker-compose-Linux-x86_64 /usr/bin/docker-compose [root@harbor app]# chmod 744 /usr/bin/docker-compose3.3 安裝harbor
[root@harbor app]# tar xf harbor-offline-installer-v2.2.2.tgz [root@harbor app]# cd harbor harbor/ harbor-offline-installer-v2.2.2.tgz [root@harbor app]# cd harbor [root@harbor harbor]# ls common.sh harbor.v2.2.2.tar.gz harbor.yml.tmpl install.sh LICENSE prepare # 修改配置文件 [root@harbor harbor]# cp -a harbor.yml.tmpl harbor.yml [root@harbor harbor]# vim harbor.yml hostname: harbor.local.top # 本地IP或者域名,這里使用域名,但我們沒有DNS,故此等下做下hosts解析 harbor_admin_password: 123456 # harbor管理員密碼 database:password: 123456 # 數據庫密碼 data_volume: /data/harbor # 存儲目錄 # 注釋掉https # https related config #https: # # https port for harbor, default is 443 # port: 443 # # The path of cert and key files for nginx # certificate: /your/certificate/path # private_key: /your/private/key/path # 做一下hosts解析,所有節點都要做,包括node1 node2 [root@harbor harbor]# echo "192.168.1.101 node01" >> /etc/hosts [root@harbor harbor]# echo "192.168.1.102 node02" >> /etc/hosts [root@harbor harbor]# echo "192.168.1.110 harbor" >> /etc/hosts [root@harbor harbor]# echo "192.168.1.110 harbor.local.top" >> /etc/hosts# 安裝 [root@harbor harbor]# ./install.sh [Step 0]: checking if docker is installed ... Note: docker version: 20.10.7 # 成功讀取docker版本 [Step 1]: checking docker-compose is installed ... Note: docker-compose version: 1.29.2 # 成功讀取docker-compose版本 ...... [Step 5]: starting Harbor ... Creating network "harbor_harbor" with the default driver Creating harbor-log ... done Creating registry ... done Creating harbor-portal ... done Creating harbor-db ... done Creating registryctl ... done Creating redis ... done Creating harbor-core ... done Creating nginx ... done Creating harbor-jobservice ... done ? ----Harbor has been installed and started successfully.----# 查看啟動了哪些容器 [root@harbor harbor]# docker-compose ps # 注意docker-compose命令,只能于docker-compose項目目錄下執行Name Command State Ports ------------------------------------------------------------------------------------------- harbor-core /harbor/entrypoint.sh Up (healthy) harbor-db /docker-entrypoint.sh Up (healthy) harbor-jobservice /harbor/entrypoint.sh Up (healthy) harbor-log /bin/sh -c /usr/local/bin/ Up (healthy) 127.0.0.1:1514->10514/tcp... harbor-portal nginx -g daemon off; Up (healthy) nginx nginx -g daemon off; Up (healthy) 0.0.0.0:80->8080/tcp,:::80->8080/tcp redis redis-server Up (healthy)/etc/redis.conf registry /home/harbor/entrypoint.sh Up (healthy) registryctl /home/harbor/start.sh Up (healthy)[root@harbor harbor]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES be460fb4cb9b goharbor/harbor-jobservice:v2.2.2 "/harbor/entrypoint.…" About a minute ago Up About a minute (healthy) harbor-jobservice 9de4a1ca6be0 goharbor/nginx-photon:v2.2.2 "nginx -g 'daemon of…" About a minute ago Up About a minute (healthy) 0.0.0.0:80->8080/tcp, :::80->8080/tcp nginx 91ce9201ea03 goharbor/harbor-core:v2.2.2 "/harbor/entrypoint.…" 2 minutes ago Up About a minute (healthy) harbor-core abe2e68cee15 goharbor/redis-photon:v2.2.2 "redis-server /etc/r…" 2 minutes ago Up 2 minutes (healthy) redis 96fdb49b29d9 goharbor/harbor-registryctl:v2.2.2 "/home/harbor/start.…" 2 minutes ago Up About a minute (healthy) registryctl d978e8fc6d75 goharbor/harbor-portal:v2.2.2 "nginx -g 'daemon of…" 2 minutes ago Up 2 minutes (healthy) harbor-portal 55c2bbadcc3e goharbor/registry-photon:v2.2.2 "/home/harbor/entryp…" 2 minutes ago Up 2 minutes (healthy) registry 0bb8c40cea5c goharbor/harbor-db:v2.2.2 "/docker-entrypoint.…" 2 minutes ago Up 2 minutes (healthy) harbor-db fd34d2af91e8 goharbor/harbor-log:v2.2.2 "/bin/sh -c /usr/loc…" 2 minutes ago Up 2 minutes (healthy) 127.0.0.1:1514->10514/tcp3.4 harbor基本使用
因為都是圖形化的,所以不多贅述,只說下怎么創建倉庫
harbor的訪問,使用瀏覽器輸入harbor節點的IP:port或者域名即可
創建一個私有倉庫(私有項目)
3.5 登錄私有倉庫并推送鏡像
# node1節點先確認做一下hosts解析 [root@node01 ~]# echo "192.168.1.101 node01" >> /etc/hosts [root@node01 ~]# echo "192.168.1.102 node02" >> /etc/hosts [root@node01 ~]# echo "192.168.1.110 harbor" >> /etc/hosts [root@node01 ~]# echo "192.168.1.110 harbor.local.top" >> /etc/hosts# 登錄私有倉庫 因為我們這里沒有使用https進行通信,所以還需要給docker配置下http不安全通信 [root@node01 ~]# vim /etc/docker/daemon.json {# 追加"insecure-registries": ["harbor.local.top"] }[root@node01 ~]# systemctl daemon-reload [root@node01 ~]# systemctl restart docker# 登錄私有倉庫 [root@node01 ~]# docker login harbor.local.top Username: admin Password: WARNING! Your password will be stored unencrypted in /root/.docker/config.json. Configure a credential helper to remove this warning. See # 這句警告是說你的密碼會不安全的存儲在/root/.docker/config.json中。配置憑據助手可以去掉這個警告 https://docs.docker.com/engine/reference/commandline/login/#credentials-storeLogin Succeeded# 推送鏡像到私有倉庫 在推送前,需要先給本地的鏡像打標簽,以符合harbor中的項目路徑 [root@node01 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE centos_while v1 d11182ec9f08 3 hours ago 209MB ......[root@node01 ~]# docker tag centos_while:v1 harbor.local.top/images/centos_while:v1推送 [root@node01 ~]# docker push harbor.local.top/images/centos_while:v1 The push refers to repository [harbor.local.top/images/centos_while] 6ecc5281cd8d: Pushed 2653d992f4ef: Pushing 85.67MB/209.3MB3.6 登出倉庫
[root@node01 ~]# docker logout harbor.local.top Removing login credentials for harbor.local.top4、運行一個應用容器
接下來我們來實際運行一個應用容器
以nginx為例
4.1 規劃好應用容器的配置
運行容器前,除非是不重要的測試環境,否則一定要考慮好該容器的 端口 存儲 等等信息后再運行
如果是官方鏡像,那么這個容器有哪些參數可以被配置,都會寫的很清晰,比如前往dockerhub網站,閱讀容器的文檔
此處,我以nginx容器為例
打開 https://registry.hub.docker.com/_/nginx
如上,可以看到官方會給出很多運行參數的示例
此處規劃的參數如下: -p 8001:80 # -p 映射端口,8001為宿主機端口,80為容器內端口 -v /data/docker/nginx/html:/usr/share/nginx/html # -v 掛載卷,/data/docker/nginx/html是宿主機目錄,/usr/share/nginx/html是容器內目錄,這個掛載用于實現html目錄的掛載 --name 8001 # 設置容器名 -v /data/docker/nginx/nginx.conf:/etc/nginx/nginx.conf:ro # -v不僅可以掛載目錄,也可以掛載單個文件,這里就是掛載的配置文件,ro是只讀,默認是rw --restart=always # 重啟策略為任何狀態自動重啟既然做好了規劃,那么下面就把規劃的內容準備好
# 創建掛載卷的宿主機目錄 [root@node01 ~]# mkdir /data/docker/nginx/html -p # 準備html目錄下的index.html測試文件 [root@node01 ~]# echo "nginx docker test" >> /data/docker/nginx/html/index.html # 準備要被掛載進去的nginx.conf配置文件 [root@node01 ~]# vim /data/docker/nginx/nginx.conf user nginx; worker_processes auto; error_log /var/log/nginx/error.log notice; pid /var/run/nginx.pid; events {worker_connections 1024; } http {include /etc/nginx/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 /var/log/nginx/access.log main;sendfile on;#tcp_nopush on;keepalive_timeout 65;gzip on;include /etc/nginx/conf.d/*.conf; }4.2 運行nginx容器
# 拉取鏡像 [root@node01 ~]# docker pull nginx# 運行 [root@node01 ~]# docker run -d --name="nginx_8001" -v /data/docker/nginx/html:/usr/share/nginx/html -v /data/docker/nginx/nginx.conf:/etc/nginx/nginx.conf -p 8001:80 --restart=always nginx:latest c410430dc13d7d27a2ed7b41ee8f40ddedac54a2afe0d753d044d6718836643a# 查看啟動后的狀態 [root@node01 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c410430dc13d nginx:latest "/docker-entrypoint.…" 19 seconds ago Up 18 seconds 0.0.0.0:8001->80/tcp, :::8001->80/tcp nginx_8001# 查看宿主機端口 [root@node01 ~]# ss -naltp|grep 8001 LISTEN 0 128 *:8001 *:* users:(("docker-proxy",pid=93384,fd=4)) LISTEN 0 128 [::]:8001 [::]:* users:(("docker-proxy",pid=93389,fd=4))測試訪問
[root@harbor harbor]# curl node01:8001 nginx docker test測試自動重啟策略
[root@node01 ~]# systemctl restart docker [root@node01 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c410430dc13d nginx:latest "/docker-entrypoint.…" 2 minutes ago Up 1 second 0.0.0.0:8001->80/tcp, :::8001->80/tcp nginx_80014.4 容器的數據卷
這里簡單介紹下數據卷的掛載
在上面我們采用-V參數,掛載了數據存儲目錄到容器內,實際上這就是數據卷,數據卷主要解決的是數據持久化到宿主機且宿主機與容器間數據同步
掛載數據卷做持久化在絕大多數時候都是是必要的,畢竟容器可以被隨意刪除,一旦容器崩潰或者被刪除掉,數據就丟失了。
另外多提一句,一般情況下,不建議在容器里運行有狀態服務,比如mysql redis等,主要也是數據丟失的風險
5、docker的網絡模式
docker本地共有四種網絡模型,分別為 bridge,host,none,container
# 查看docker 網絡 [root@node01 ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 95ab2996b951 bridge bridge local ff9ddd83a44a host host local 3ab59d75c16c none null local# 查看容器使用的網絡模式 [root@node01 ~]# docker inspect c410# 創建一個網絡# 以創建一個新的briage網絡 bridge_test1 為例 [root@node01 ~]# docker network create -d bridge --subnet "10.1.1.1/24" --gateway="10.1.1.254" briage_test1 2bdd140c3dfb69e0942d93a8416628d4c0cdd77b1e2437ff446e1b658aaaf0bb[root@node01 ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 2bdd140c3dfb briage_test1 bridge local 新創建的網絡 95ab2996b951 bridge bridge local ff9ddd83a44a host host local 3ab59d75c16c none null local# 刪除一個網絡 [root@node01 ~]# docker network rm briage_test1 briage_test1 [root@node01 ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 95ab2996b951 bridge bridge local ff9ddd83a44a host host local 3ab59d75c16c none null local5.1 Bridge橋接網絡
默認情況下,docker即使用bridge橋接網絡,這個橋接和我們日常理解的橋接不同,它更像是我們在虛擬機中使用的NAT網絡。
當宿主機存在多塊網卡時,可以通過brctl命令將指定的物理網卡橋接到docker0上
當Docker進程啟動時,會在主機上創建一個名為docker0的虛擬網橋,此主機上啟動的Docker容器會連接到這個虛擬網橋上。虛擬網橋的工作方式和物理交換機類似,這樣主機上的所有容器就通過交換機連在了一個二層網絡中。
[root@node01 ~]# ifconfig docker0 docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 172.1.1.1 netmask 255.255.0.0 broadcast 172.1.255.255inet6 fe80::42:4aff:fece:f9d1 prefixlen 64 scopeid 0x20<link>ether 02:42:4a:ce:f9:d1 txqueuelen 0 (Ethernet)RX packets 12 bytes 1100 (1.0 KiB)RX errors 0 dropped 0 overruns 0 frame 0TX packets 17 bytes 1267 (1.2 KiB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0[root@node01 ~]# route -n | grep docker0 172.1.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0從docker0子網中分配一個IP給容器使用,并設置docker的IP地址為容器的默認網關,在主機上創建一對虛擬網卡veth pair設備,docker將veth pair設備的一端放在容器中,并以eth0命名,一端放在宿主機中,以vethxxx命名,并且將這個網絡加入到docker0網橋中,可以通過 # brctl show 命令查看(沒有brctl安裝下 # yum install bridge-utils -y)
# 起個容器 [root@node01 ~]# docker run -itd --name="centos_test1" centos:7.9.2009 /bin/bash 55124e99e88f2da9f61a927eb301ef43e043eb9eb862579d894ce8903a31e2e8 [root@node01 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 55124e99e88f centos:7.9.2009 "/bin/bash" 6 seconds ago Up 6 seconds centos_test1# 查看容器內網卡名 [root@node01 ~]# docker exec -it 5512 /bin/bash [root@55124e99e88f /]# yum -y install net-tools [root@55124e99e88f /]# ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 172.1.0.2 netmask 255.255.0.0 broadcast 172.1.255.255ether 02:42:ac:01:00:02 txqueuelen 0 (Ethernet)RX packets 3877 bytes 16524721 (15.7 MiB)RX errors 0 dropped 0 overruns 0 frame 0TX packets 3223 bytes 178107 (173.9 KiB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 ......# 查看宿主機內網卡名 [root@node01 ~]# ip a 17: veth48645da@if16: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group defaultlink/ether 0a:45:b9:c9:ea:2c brd ff:ff:ff:ff:ff:ff link-netnsid 0inet6 fe80::845:b9ff:fec9:ea2c/64 scope linkvalid_lft forever preferred_lft forever ......# 網橋控制器查看 [root@node01 ~]# brctl show bridge name bridge id STP enabled interfaces docker0 8000.02424acef9d1 no veth48645dabridge模式是docker的默認網絡模式,不寫–net參數,就是bridge模式。使用docker run -p時,docker實際是在iptables做了DNAT規則,實現端口轉發功能??梢允褂?# iptables -t nat -vnL查看。
5.2 Host宿主機共享網絡
如果啟動容器的時候使用host模式,那么這個容器將不會獲得一個獨立的Network Namespace,而是和宿主機共用一個Network Namespace。容器將不會虛擬出自己的網卡,配置自己的IP等,而是使用宿主機的IP和端口。但是,容器的其他方面,如文件系統、進程列表等還是和宿主機隔離的。
使用host模式的容器可以直接使用宿主機的IP地址與外界通信,容器內部的服務端口也可以使用宿主機的端口,不需要進行NAT,host最大的優勢就是網絡性能比較好,但是docker host上已經使用的端口就不能再用了,網絡的隔離性不好。
啟動容器時使用host網絡
–net=host 參數
以nginx鏡像為例,nginx鏡像默認使用80端口,我們來驗證下
# 查看下宿主機80端口沒有沖突 [root@node01 ~]# ss -naltp|grep 80# 使用 --net=host 來指定使用host網絡模式 [root@node01 ~]# docker run -d --net=host --name="nginx_host_test1" nginx:latest b908023b773f1a5163cc8cf91864c3684f546e937159396fdaa0e9a81d39b29b [root@node01 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b908023b773f nginx:latest "/docker-entrypoint.…" 5 seconds ago Up 4 seconds nginx_host_test1# 再來查看下宿主機中的端口 [root@node01 ~]# ss -naltp|grep 80 LISTEN 0 128 *:80 *:* users:(("nginx",pid=107305,fd=7),("nginx",pid=107304,fd=7),("nginx",pid=107262,fd=7)) LISTEN 0 128 [::]:80 [::]:* users:(("nginx",pid=107305,fd=8),("nginx",pid=107304,fd=8),("nginx",pid=107262,fd=8)) 可以看到,80端口直接出現在了宿主機中# 直接訪問下 [root@node01 ~]# curl localhost:80 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style>body {width: 35em;margin: 0 auto;font-family: Tahoma, Verdana, Arial, sans-serif;} </style> </head> <body> <h1>Welcome to nginx!</h1> ......5.3 None無外部網絡
用none模式,Docker容器擁有自己的Network Namespace,但是,并不為Docker容器進行任何網絡配置。也就是說,這個Docker容器沒有網卡、IP、路由等信息。需要我們自己為Docker容器添加網卡、配置IP等。
這種網絡模式下容器只有lo回環網絡,沒有其他網卡。none模式可以在容器創建時通過–network=none來指定。這種類型的網絡沒有辦法聯網,封閉的網絡能很好的保證容器的安全性。
通過 --net=none參數指定
# 運行時指定--net=none [root@node01 ~]# docker run -itd --net=none --name="centos7.9_none_test1" centos:7.9.2009 /bin/bash e81b1e6ca20d9d3469dcfe4876e7828099167ba5731a7fcb60c5d0b0d686293a [root@node01 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e81b1e6ca20d centos:7.9.2009 "/bin/bash" 4 seconds ago Up 2 seconds centos7.9_none_test1# 查看下網絡設備 [root@node01 ~]# docker exec -it e81b /bin/bash [root@e81b1e6ca20d /]# cat /proc/net/dev Inter-| Receive | Transmitface |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressedlo: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 可以看到,只有一個lo網絡5.4 container容器共享(依附)網絡
這個模式指定新創建的容器和已經存在的一個容器共享一個 Network Namespace,而不是和宿主機共享。新創建的容器不會創建自己的網卡,配置自己的 IP,而是和一個指定的容器共享 IP、端口范圍等。同樣,兩個容器除了網絡方面,其他的如文件系統、進程列表等還是隔離的。兩個容器的進程可以通過 lo 網卡設備通信。
–net=container:被依附的容器名
# 先啟動一個新的容器,命名為 centos_container_test1 [root@node01 ~]# docker run -itd --name centos_container_test1 centos:7.9.2009 /bin/bash 49595449fb50b82625af2c08745e2597853af450a98973b477020bf442f61c9c# 在啟動一個容器,啟動時指定網絡為container并依附到 centos_container_test1 [root@node01 ~]# docker run -itd --name centos_container_test2 --net=container:centos_container_test1 centos:7.9.2009 /bin/bash ca27254e32512c5c5ec095f590d5c627c91ff08a3c8a00e4bf0628479ba549c9# 查看網絡是否相同 [root@node01 ~]# docker exec -it centos_container_test1 /bin/bash [root@49595449fb50 /]# yum -y install net-tools [root@49595449fb50 /]# ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 172.1.0.3 netmask 255.255.0.0 broadcast 172.1.255.255ether 02:42:ac:01:00:03 txqueuelen 0 (Ethernet)RX packets 4075 bytes 16535781 (15.7 MiB)RX errors 0 dropped 0 overruns 0 frame 0TX packets 3213 bytes 177825 (173.6 KiB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 ...... [root@node01 ~]# docker exec -it centos_container_test2 /bin/bash [root@49595449fb50 /]# yum -y install net-tools [root@49595449fb50 /]# ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 172.1.0.3 netmask 255.255.0.0 broadcast 172.1.255.255ether 02:42:ac:01:00:03 txqueuelen 0 (Ethernet)RX packets 6926 bytes 33005634 (31.4 MiB)RX errors 0 dropped 0 overruns 0 frame 0TX packets 5632 bytes 312908 (305.5 KiB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 ......附:批量停止及刪除容器
前面實驗開啟了非常多的容器,怎么一次全停止并刪除
# 停 [root@node01 ~]# docker stop $(docker ps -q) ca27254e3251 49595449fb50 e81b1e6ca20d b908023b773f 55124e99e88f c410430dc13d# 刪 [root@node01 ~]# docker rm $(docker ps -aq) ca27254e3251 49595449fb50 e81b1e6ca20d b908023b773f 55124e99e88f c410430dc13d 3b1157fa7e1b 36a3d9354ba4 [root@node01 ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES五、DockerFile 構建鏡像
構建鏡像除了前面提到的docker commit,還有dockerfile。實際真正使用的也是dockerfile
Dockerfile把構建鏡像的步驟都寫出來,然后按順序執行實現自動構建鏡像,就像ansible的playbook類似,也類似于使用pom去構建maven項目…
dockerfile的組成模塊
| FROM | 基礎鏡像信息 |
| MAINTAINER | 維護者信息 |
| RUN COPY ADD USER WORKDIR VOLUME EXPOSE… | 容器操作 |
| CMD ENTRYPOINT | 啟動操作 |
1、dockerfile關鍵字(指令)
1.1 FROM
指定以哪個鏡像為基礎鏡像
# 比如以centos為基礎鏡像 FROM centos:7.9.20091.2 MAINTAINER
指定鏡像維護者信息
# 比如指定維護者及郵件 MAINTAINER "systemctl529_yu" "systemctlxxxxxx@163.com"1.3 RUN
用于在構建鏡像中執行命令,比如安裝一些軟件、配置一些基礎環境,可使用\來換行或者用 && 連續執行,盡量減少多行RUN*(一個RUN一層)*
# 兩種語法: 1. shell格式 RUN yum -y install nginx && echo "test web" >> /usr/share/nginx/html/index.html RUN echo "hello docker" \/usr/share/nginx/html/index.html2. exec格式 RUN ["命令", "參數1", "參數2"] RUN ["yum","-y","install","nginx"]1.4 COPY
將主機的文件復制到鏡像內,如果目的位置不存在,Docker會自動創建所有需要的目錄結構,但是它只是單純的復制,并不會去做文件提取和解壓工作。
需要復制的目錄一定要放在Dockerfile文件的同級目錄下
# 拷貝配置文件到容器中 COPY nginx.conf /etc/nginx1.5 ADD
將主機的文件復制到鏡像中,跟COPY一樣,限制條件和使用方式都一樣,也是需要在dockerfile的同級目錄中。
ADD會對壓縮文件(tar, gzip, bzip2, etc)做提取和解壓操作
# 拷貝html.tar到容器中 ADD HTML.tar /usr/share/nginx/html1.6 EXPOSE
暴露鏡像的端口供主機做映射,啟動鏡像時,使用-P參數來將鏡像端口與宿主機的隨機端口做映射。(可指定多個)
docker run時,還需 -p 參數指定內外端口
EXPOSE 指令是聲明運行時容器提供服務端口,這只是一個聲明,在運行時并不會因為這個聲明應用就會開啟這個端口的服務。在 Dockerfile 中寫入這樣的聲明有兩個好處,一個是幫助鏡像使用者理解這個鏡像服務的守護端口,以方便配置映射;另一個用處則是在運行時使用隨機端口映射時,也就是 docker run -P時,會自動隨機映射 EXPOSE 的端口
EXPOSE 80 81 82 ...1.7 ENV
ENV指令用于指定一個環境變量
當使用生成的鏡像運行容器時,使用 ENV 設置的環境變量將持久存在于容器內,如果僅僅要在構建過程中使用變量,可以 RUN MY_NAME=“systemctl529_yu”,或者用ARG MY_NAME="systemctl529_yu"
# ENV <key> <value> 或者 ENV <key>=<value> ENV JAVA_HOME /usr/local/openjdk/bin ENV MY_NAME="systemctl529_yu" MY_JOB="OPS"1.8 WORKDIR
在構建鏡像時,指定鏡像的工作目錄,之后的命令都是基于此工作目錄,如果不存在,則會創建目錄
WORKDIR /usr/share/nginx/html RUN echo 'hello docker' > text.txt # 這樣就會在容器的/usr/share/nginx/html/text.txt文件寫入 “hello docker”1.9 ONBUILD
為他人做嫁衣,做基礎鏡像使用
ONBUILD 是一個特殊的指令,它后面跟的是其它指令,比如 RUN, COPY 等,而這些指令,在當前鏡像構建時并不會被執行。只有當以當前鏡像為基礎鏡像,去構建下一級鏡像的時候才會被執行。
Dockerfile 中的其它指令都是為了定制當前鏡像而準備的,唯有 ONBUILD 是為了幫助別人定制自己而準備的。比如我們需要一個java鏡像跑jar包,每次都創建一個jre環境太麻煩,所以就可以先創建個基礎鏡像,然后每次放不同jar進去做新的鏡像
語法格式為 :ONBUILD <其它指令>
# 創建基礎鏡像image1 FROM openjdk RUN mkdir /APP ONBUILD COPY xxxxx.jar /APP WORKDIR /APP CMD java -jar xxxxx.jar# 基于基礎鏡像1創建鏡像image2 FROM image1 # 似的,沒看錯,就這一行,其會調用image1中的ONBUILD1.10 USER
指定該鏡像以哪個用戶去執行(比如以hadoop用戶執行hadoop)
如果設置了容器以XXXXX用戶去運行,那么RUN,CMD和ENTRYPOINT都會以這個用戶去運行
鏡像構建完成后,通過docker run運行容器時,可以通過-u參數來覆蓋所指定的用戶
1.11 VOLUME
用來向基于鏡像創建的容器添加卷。比如你可以將mongodb鏡像中存儲數據的data文件指定為宿主機的某個文件。(容器內部建議不要存儲任何數據),如果只指定掛載點,docker宿主機映射的目錄會自動生成。
# VOLUME 宿主機目錄 容器內目錄 或者 # VOLUME 容器目錄VOLUME /data/nginx/html /usr/share/nginx/html1.12 CMD
容器啟動時需要執行的命令
CMD不同于RUN,CMD用于指定在容器啟動時所要執行的命令,而RUN用于指定鏡像構建時所要執行的命令
每個Dockerfile只能有一條CMD命令。如果指定了多條命令,只有最后一條會被執行,同時CMD可以被docker run 時指定的運行命令覆蓋
# 兩種語法 1. exec寫法 CMD ["命令","參數1","參數2"]CMD ["/bin/bash"]2. shell寫法 CMD 命令 參數1 參數2CMD /bin/bash1.13 ENTRYPOINT
用法和功能與CMD一致
ENTRYPOINT指定的命令不會被docker run覆蓋,但會把docker run后的命令當做 ENTRYPOINT指定命令的參數,如果dockerfile中同時有CMD和ENTRYPOINT,那么CMD也會被ENTRYPOINT當做執行命令的參數
# 兩種語法 1. exec寫法 ENTRYPOINT ["命令","參數1","參數2"]ENTRYPOINT ["/bin/bash"]2. shell寫法 ENTRYPOINT 命令 參數1 參數2ENTRYPOINT /bin/bash2 實際寫幾個
build創建鏡像時,需要在命令后寫一個 . 這個 . 代表當前目錄上下文(當前目錄及當前目錄下的子目錄)
2.1 寫個nginx的先
[root@node01 ~]# mkdir /data/dockerfile -p [root@node01 ~]# cd /data/docker [root@node01 docker]# mkdir nginx_dockerfile [root@node01 docker]# cd nginx_dockerfile/ [root@node01 nginx_dockerfile]## 以centos為基礎鏡像,寫一個nginx的容器 [root@node01 nginx_dockerfile]# vim nginx_dockerfile FROM centos:latest MAINTAINER "systemctl529_yu" "xxxxxxx.163.com" RUN yum -y install nginx COPY index.html /usr/share/nginx/html COPY nginx.conf /etc/nginx EXPOSE 80 CMD nginx -g "daemon off;"# 準備好dockerfile中定義的文件 [root@node01 nginx_dockerfile]# echo "dockerfile_nginx_test1" >> index.html [root@node01 nginx_dockerfile]# vim nginx.conf user nginx; worker_processes auto; error_log /var/log/nginx/error.log notice; pid /var/run/nginx.pid; events {worker_connections 1024; } http {include /etc/nginx/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 /var/log/nginx/access.log main;sendfile on;#tcp_nopush on;keepalive_timeout 65;gzip on;include /etc/nginx/conf.d/*.conf;server {listen 80 default_server;server_name _;root /usr/share/nginx/html;# Load configuration files for the default server block.include /etc/nginx/default.d/*.conf;location / {}error_page 404 /404.html;location = /404.html {}error_page 500 502 503 504 /50x.html;location = /50x.html {}}}# build構建鏡像 [root@node01 nginx_dockerfile]# docker build -f nginx_dockerfile -t nginx_dockerfile:test1 . Sending build context to Docker daemon 4.608kB Step 1/7 : FROM centos:latest---> 300e315adb2f Step 2/7 : MAINTAINER "systemctl529_yu" "xxxxxxx.163.com"---> Running in 00ba4060520f Removing intermediate container 00ba4060520f---> 1b3338ca9f72 Step 3/7 : RUN yum -y install nginx ...... Step 4/7 : COPY index.html /usr/share/nginx/html---> 97379c724a8d Step 5/7 : COPY nginx.conf /etc/nginx---> 23b118c3271d Step 6/7 : EXPOSE 80---> Running in 4b14485d0bcd Removing intermediate container 4b14485d0bcd---> f88b7595fefa Step 7/7 : CMD nginx -g "daemon off;"---> Running in 1df3be4f8e69 Removing intermediate container 1df3be4f8e69---> 3a7c2ca9c867 Successfully built 3a7c2ca9c867 Successfully tagged nginx_dockerfile:test1[root@node01 nginx_dockerfile]# docker images | grep nginx_dockerfile nginx_dockerfile test1 3a7c2ca9c867 About a minute ago 313MB# 運行個容器試試 [root@node01 nginx_dockerfile]# docker run -d --name="nginx_dockerfile_test1_8001" -p 8001:80 nginx_dockerfile:test1 9c483dccd5e657006d46b60dc04422eb138b8050552b2358c1889a345392a477[root@node01 nginx_dockerfile]# curl localhost:8001 dockerfile_nginx_test12.2 寫個tomcat的
[root@node01 docker]# mkdir /data/docker/tomcat_dockerfile [root@node01 docker]# cd /data/docker/tomcat_dockerfile/[root@node01 tomcat_dockerfile]# vim tomcat_dockerfile # 這里沒有war包演示,所以就用tomcat默認頁面了,實際使用,可以使用 RUN rm -rf /usr/local/tomcat/webapps/*刪除掉自帶的項目,然后CPOY進WAR包 FROM adoptopenjdk/openjdk8:ubi MAINTAINER "systemctl529_yu" "xxxxxxx.163.com" ADD apache-tomcat-9.0.14.tar.gz /usr/local EXPOSE 8080 CMD /usr/local/apache-tomcat-9.0.14/bin/catalina.sh run# 下載好tomcat到當前目錄 [root@node01 tomcat_dockerfile]# ls apache-tomcat-9.0.14.tar.gz tomcat_dockerfile# build構建 [root@node01 tomcat_dockerfile]# docker build -f tomcat_dockerfile -t tomcat_dockerfile:test1 .至于jar包的,更簡單,比如
FROM adoptopenjdk/openjdk8:ubi RUN mkdir /opt/app COPY xxxxxxx.jar /opt/app CMD ["java", "-jar", "/opt/app/xxxxxxx.jar"]總結
- 上一篇: 如何让自己在云服务器上部署的进程一直运行
- 下一篇: Python爬虫——爬取IEEE论文