目錄
- Docker前言
- 在 CentOS 系統上安裝 Docker
- Docker鏡像
- Docker 容器
- Docker網絡
- Dockerfile構建鏡像
- 1、FROM:指定基礎環境
- 2、MAINTAINER:指定維護者信息
- 3、RUN:構建鏡像時執行命令
- 4、CMD:設置Docker鏡像啟動時默認執行的命令
- 5、ENTRYPOINT:設置Docker鏡像啟動命令
- 6、WORKDIR:指定Docker容器的工作目錄
- 7、EXPOSE:指定默認端口號
- 8、ADD:將宿主主機中的內容或者互聯網下載的內容放置於鏡像中
- 9、COPY:將宿主主機中的內容復制到鏡像中
- 10、VOLUME:指定容器需要掛載的目錄
- 11、ENV:指定該鏡像啟動容器中的環境變量
- 12、ARG:設置構建鏡像臨時參數
- 13、ONBUILD:構建觸發器
- 14、案例:使用Nginx代理Django
- Docker-compose容器編排工具
- Harbor私有倉庫
Docker前言
1、Docker簡介
傳統運維可能會遇到的問題:
1、機器很多但是版本各異:使用自動化運維工具(Ansible)來避免不同型號,不同版本導致的服務器之間的命令的不同。但是自動化運維工具也伴隨這這些問題:當系統不支持時,自動化運維工具無法解決;當大規模應用需要部署時,無法解決穩定運行的問題。
2、這時候就考慮到以下功能的實現:將編寫好了的軟件進行打包,如果需要運行的時候,直接運行安裝包即可實現服務穩定運行。如果出現服務運行宕機等不穩定現象時,將自動重啟直至服務穩定運行。實現這一功能的軟件有兩個,打包的軟件叫作:Docker;實現自動化部署和運行的軟件叫作:kubernetes。
3、打包的過程叫作虛擬化,虛擬化的發展史:
● 20世紀90年代的時候,Linux操作系統中為了解決多進程之間的相互隔離的問題,創建出了一個systemd的虛擬化
● 21世紀初,提出了操作系統軟件虛擬化。
● 21世紀10年代初,Google的一個科學家發布了一篇關於軟件虛擬化的論文。
● 2013年,有一個dotCloud公司,開發出了一款叫作Docker的虛擬化軟件。
● 2014年,Google公司推出了一款容器管理軟件:kubernetes
4、至此,容器化可以落地並且實現規模化。
# 在Docker中,有三個核心概念,分別是:鏡像、容器以及倉庫。
1.鏡像:在Docker中,部署的所有的應用都必須打包成一個鏡像。也就是說鏡像就是我們將軟件打包之后的安裝包。
2.容器:容器是鏡像運行之后的一個實例。實質上,容器就是一個進程。容器可以被創建、啟動、停止、刪除、暫停等。
3.倉庫:倉庫是用來存放鏡像的地方。當我們構建好自己的鏡像之后,需要存放在倉庫中,當我們需要啟動一個鏡像時,可以在倉庫中下載下來。
# Docker 是一個開源項目,誕生於 2013 年初,最初是 dotCloud 公司內部的一個業余項目。它基於 Google公司推出的 Go 語言實現。 項目后來加入了 Linux 基金會,遵從了 Apache 2.0 協議,項目代碼在 GitHub 上進行維護。Docker 自開源后受到廣泛的關注和討論,以至於 dotCloud 公司后來都改名為 Docker Inc。Redhat已經在其 RHEL6.5 中集中支持 Docker;Google 也在其 PaaS 產品中廣泛應用。Docker 項目的目標是實現輕量級的操作系統虛擬化解決方案。 Docker 的基礎是 Linux 容器(LXC)等技術。在 LXC 的基礎上 Docker進行了進一步的封裝,讓用戶不需要去關心容器的管理,使得操作更為簡便。用戶操作 Docker 的容器就像操作一個快速輕量級的虛擬機一樣簡單。Docker 可以讓開發者打包他們的應用以及依賴包到一個輕量級、可移植的容器中,然后發布到任何流行的 Linux 機器上,也可以實現虛擬化。容器是完全使用沙箱機制,相互之間不會有任何接口(類似 iPhone 的 app),更重要的是容器性能開銷極低。
2、為什么要用Docker
2.1 Docker 容器虛擬化的好處
在雲時代,開發者創建的應用必須要能很方便地在網絡上傳播,也就是說應用必須脫離底層物理硬件的限制;同時必須滿足“任何時間任何地點”可獲取可使用的特點。因此,開發者們需要一種新型的創建分布式應用程序的方式,快速分發部署,而這正是 Docker 所能夠提供的最大優勢。Docker 提供了一種更為聰明的方式,通過容器來打包應用、解耦應用和運行平台。這意味着遷移的時候,只需要在新的服務器上啟動需要的容器就可以了,無論新舊服務器是否是同一類別的平台。這無疑幫助我們節約了大量的寶貴時間,並降低部署過程出現問題的風險。
2.2 Docker 在開發和運維中的優勢
對於開發和運維人員來說,最夢寐以求的效果可能就是一次創建和配置,之后可以在任意地方、任意時間讓應用正常運行,而 Docker 恰恰可以實現這一中級目標。具體來說,在開發和運維過程中,Docker 具有以下幾個方面的優勢:
1.更快的交付和部署:使用 Docker,開發人員可以使用鏡像來快速構建一套標准的開發環境;開發完之后,測試和運維人員可以直接使用完全相同的環境來部署代碼。只要是開發測試過的代碼,就可以確保在生產環境無縫運行。Docker 可以快速創建和刪除容器,實現快速迭代,節約開發、測試及部署的時間。
2.更高效的利用資源:運行 Docker 容器不需要額外的虛擬化管理程序的支持,Docker 是內核級的虛擬化,可以實現更高的性能,同時對資源的額外需求很低,與傳統的虛擬機方式相比,Docker 的性能要提高 1 ~ 2 個數量級。
3.更輕松的遷移和擴展:Docker 容器幾乎可以在任意的平台上運行,包括物理機、虛擬機、公有雲、私有雲、個人電腦等等,同時支持主流的操作系統發行版本。這種兼容性能讓用戶可以在不同的平台之間輕松的遷移應用。
4.更輕松的管理和更新:使用 Dockerfile,只需要小小的配置修改,就可以替代以往大量的更新工作。所有的修改都以增量的方式被分發和更新,從而實現自動化並且高效的容器管理。
2.3 Docker 與虛擬機的比較
Docker可以說是一個依賴於Linux虛擬化的容器軟件。它是由dotClound公司使用Golang語言在2013年初開發的。后來加入了Linux基金會,遵循Apache 2.0協議同時將源代碼開源至GitHub上。
# 容器中的數據無法永久保存,但是虛擬機中的數據可以永久保存。
在 CentOS 系統上安裝 Docker
Docker 目前支持 CentOS 7 及以后版本。系統的要求跟 Ubuntu 情況類似,64 位操作系統,內核至少是 3.10
以上。
1.1 更換系統 yum 源
# 查看系統內核版本
[root@mysql01 ~]# uname -a
Linux mysql01 3.10.0-1160.el7.x86_64 #1 SMP Mon Oct 19 16:18:59 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
# 備份原來 yum 源
[root@mysql01 ~]# cp /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak
# 更換 yum 源
[root@mysql01 ~]# curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
# 刷新 yum 源緩存
[root@mysql01 ~]# yum makecache
1.2 更新系統
[root@mysql01 ~]# yum update -y --exclud=kernel*
1.3 安裝所需的基礎軟件
[root@mysql01 ~]# yum install -y yum-utils device-mapper-persistent-data lvm
# 知識補充:
yum-utils:yum的管理工具包,安裝yum-utils之后才能運行yum-config-manager命令。
device-mapper-persistent-data: Linux2.6 內核中支持邏輯卷管理的通用設備映射機制,它為實現用於存儲資源管理的塊設備驅動提供了一個高度模塊化的內核架構。
lvm:邏輯盤卷管理(Logical Volume Manager)的簡稱,它是一種磁盤管理工具,最主要的功能就是可以隨時在線調整分區的大小,解決了安裝Linux系統時需要評估分區大小的煩惱。從linux內核2.6.9開始,device-mapper模塊就已經包含在內,只需加載即可。
[root@mysql01 ~]# modprobe dm_mod && lsmod | grep dm_mod # 加載lvm並查看
dm_mod 124501 5 dm_log,dm_mirror
1.4 安裝 yum 源
[root@mysql01 ~]# yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
Loaded plugins: fastestmirror
adding repo from: https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
grabbing file https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo to /etc/yum.repos.d/docker-ce.repo
repo saved to /etc/yum.repos.d/docker-ce.repo
1.5 更新並安裝 Docker-CE
[root@mysql01 ~]# yum makecache fast
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: mirrors.aliyun.com
* extras: mirrors.aliyun.com
* updates: mirrors.aliyun.com
...
Metadata Cache Created
[root@mysql01 ~]# yum install docker-ce-19.03.12 -y
已加載插件:fastestmirror
Loading mirror speeds from cached hostfile
* base: mirrors.aliyun.com
* extras: mirrors.aliyun.com
* updates: mirrors.aliyun.com
...
Complete!
1.6 測試啟動
[root@mysql01 ~]# systemctl start docker # 啟動
[root@mysql01 ~]# systemctl status docker # 查看狀態
Docker鏡像
在Docker中,部署的所有的應用都必須打包成一個鏡像。也就是說鏡像就是我們將軟件打包之后的安裝包。
# docker鏡像的來源,分別是:
1.官方的鏡像倉庫(https://hub.docker.com/),優勢:
○ 官方的倉庫比較小
○ 官方的倉庫比較安全
○ 官方倉庫的鏡像免費,可以拿來自己修改
2.第三方鏡像倉庫(https://cr.console.aliyun.com/cn-shanghai/instances)
○ 服務商提供的倉庫穩定,一般用來作為公司內部的鏡像倉庫
3.自建鏡像倉庫(https://goharbor.io/)
1.1 獲取Docker鏡像
語法格式:
docker pull [倉庫URL]/[名稱空間]/倉庫名稱:版本號
# 解釋
默認的倉庫:URL
默認的名稱空間:library
默認的版本號:latest
# 案例:查詢默認的倉庫名稱
[root@kubernetes ~]# docker info
Registry: https://index.docker.io/v1/
# 案例:在阿里雲上下載docker鏡像
[root@kubernetes ~]# docker pull registry.cn-hangzhou.aliyuncs.com/k8stes/kube-proxy:v1.18.8
1.2 查看本機下載的鏡像
語法格式:docker images 或者 docker image ls
[root@mysql01 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest f2f70adc5d89 7 hours ago 142MB
registry.cn-hangzhou.aliyuncs.com/k8stes/kube-proxy v1.18.8 0fb7201f92d0 19 months ago 117MB
1.3 搜索鏡像
語法格式:docker search [鏡像名稱]
[root@kubernetes ~]# docker search nginx
# 解釋:
● NAME:鏡像名稱
● DESCRIPTION:簡介
● STARS:收藏(點贊)的個數
● OFFICIAL:是否是官方構建的鏡像
● AUTOMATED:是否是自構建的鏡像
1.3.1 參數 --limit : 指定每次搜索顯示的行數
[root@kubernetes ~]# docker search nginx --limit=2
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
nginx Official build of Nginx. 16478 [OK]
bitnami/nginx Bitnami nginx Docker Image 120 [OK]
1.3.2 參數:-f : 過濾
[root@kubernetes ~]# docker search nginx --limit=2 -f is-official=true
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
nginx Official build of Nginx. 16478 [OK]
1.3.3 參數--no-trunc:不截斷輸出
[root@kubernetes ~]# docker search nginx --no-trunc
1.4 為鏡像添加tag
語法格式:docker tag [原名稱] 新名稱
[root@mysql01 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest f2f70adc5d89 7 hours ago 142MB
registry.cn-hangzhou.aliyuncs.com/k8stes/kube-proxy v1.18.8 0fb7201f92d0 19 months ago 117MB
[root@kubernetes ~]# docker tag 605c77e624dd registry.cn-hangzhou.aliyuncs.com/k8stes/nginx:latest
1.5 上傳鏡像到倉庫
# 登錄倉庫
語法格式:docker login [倉庫的URL]
默認登錄的是官方倉庫URL
[root@kubernetes ~]# docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: alvinos
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
# 上傳至倉庫
格式:docker push [鏡像名稱]
[root@kubernetes ~]# docker push registry.cn-hangzhou.aliyuncs.com/k8stes/nginx:latest
The push refers to repository [registry.cn-hangzhou.aliyuncs.com/k8stes/nginx]
d874fd2bc83b: Pushed
32ce5f6a5106: Pushed
f1db227348d0: Pushed
b8d6e692a25e: Pushed
e379e8aedd4d: Pushed
2edcec3590a4: Pushed
latest: digest: sha256:c4c20a2fa2aaa7ede3 size: 1570
1.6 查看鏡像詳情
# 查詢鏡像更多的詳細信息。
語法格式:docker inspect [可選參數-f] 鏡像ID
[root@kubernetes ~]# docker inspect 605c77e624dd
[root@kubernetes ~]# docker inspect -f '{{ .DockerVersion }}' 605c77e624dd
20.10.7
[root@kubernetes ~]# docker inspect -f '{{ .ContainerConfig.Hostname }}' 605c77e624dd
ca3e48389f71
1.7 鏡像的歷史
語法格式:docker history 鏡像ID
[root@kubernetes ~]# docker history 605c77e624dd
1.8 刪除和清理鏡像
# 刪除鏡像
語法格式:docker rmi 鏡像名稱
# 注意:如果鏡像有多個TAG,docker rmi刪除的就是tag;如果沒有了tag,才會刪除docker鏡像。
[root@kubernetes ~]# docker rmi test:v2
Untagged: test:v2
# 清理鏡像
將當前電腦中,所有的未被使用過的鏡像全部刪除。
[root@kubernetes ~]# docker image prune -a
Docker 容器
容器是鏡像運行之后的一個實例。實質上,容器就是一個進程。容器可以被創建、啟動、停止、刪除、暫停等。
1、創建容器
語法:docker run [參數] [鏡像] [啟動語法格式]
# 注意:容器內必須至少有一個進程運行在前台才能讓容器保持運行,如果容器內沒有進程運行在前台的話,容器就是空的,系統機制會直接回收資源。
# 案例:創建一個CentOS容器。
[root@kubernetes ~]# docker run centos bash
# 案例:啟動一個nginx容器
[root@kubernetes ~]# docker run -d --name nginx-test -P -v /root/nginx-test:/usr/share/nginx/html -e Name=Nginx-test nginx
1.1 參數
參數 | 參數解析 | 案例 |
---|---|---|
-d | 以守護進程方式運行 | # 指定一個宿主主機的端口,來代理容器內部的端口。 [root@kubernetes ~]# docker run -d -p 30080:80 nginx |
-p | 指定映射端口 | |
-P | 隨機映射端口 | # 隨機分配一個宿主主機的端口,用來代理容器的端口 [root@kubernetes ~]# docker run -d -P nginx |
-v | 設置掛載文件到主機上 | Docker容器是無法永久保存數據的,一旦容器被刪除,則里面的數據就會全部刪掉。將docker容器內部的數據保存在宿主主機中。 [root@kubernetes ~]# docker run -d -P -v /root/teszt/:/usr/share/nginx/html/ nginx |
--rm | 當容器關閉時自動刪除 | # 容器生命周期一旦結束,立即刪除容器 [root@kubernetes ~]# docker run --rm -d centos sleep 11 |
--name | 為啟動的容器設置名字; 將容器的名稱解析至容器DNS上 | [root@kubernetes ~]# docker run -d --name test nginx |
-i | 保持標准輸入打開 | [root@kubernetes teszt]# docker run -i -t centos bash |
-t | 分配一個偽終端 | [root@kubernetes teszt]# docker run -i -t centos bash |
-e | 設置容器中的環境變量 | [root@kubernetes teszt]# docker run -e Name=test-centos centos printenv |
-h | 指定容器內的主機名 | |
--network | 指定使用哪個網絡 | |
--link | 鏈接到另一個容器 |
2、查看容器
查詢操作系統中,運行過的容器。
語法格式:docker ps [可選參數-a] # -a : 查看所有的容器
[root@kubernetes ~]# docker ps
[root@kubernetes ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9b119a6b1032 centos "bash" 2 minutes ago Exited (0) 2 minutes ago angry_dhawan
# 解釋
● CONTAINER ID : 容器ID
● IMAGE:鏡像語法格式
● COMMAND:運行的語法格式
● CREATED:創建的時間
● STATUS:啟動狀態
○ UP:正常啟動
○ DOWN:正常關閉
○ Exited:啟動失敗
● PORTS:啟動的端口
● NAMES:容器的名稱
3、查看docker容器的日志
語法格式:docker log 容器ID或容器名稱
參數:
○ -f : 實時打印日志
[root@kubernetes ~]# docker logs 346ac4822d4c
[root@kubernetes ~]# docker logs 346ac4822d4c -f
4、開啟/停止容器
語法格式:
● 開啟:docker start 容器ID或容器名稱
● 停止:docker stop 容器ID或容器名稱
[root@kubernetes ~]# docker start exciting_meninsky
[root@kubernetes ~]# docker stop exciting_meninsky
5、 查看容器詳細信息
語法格式:docker inspect 容器ID或容器名稱
[root@kubernetes ~]# docker inspect jovial_cori
6、刪除容器
將容器在宿主主機中刪除
語法:docker rm 容器名稱 [可選參數-f] # -f: 強制刪除
[root@kubernetes ~]# docker rm -f exciting_meninsky
exciting_meninsky
7、保存容器和鏡像
保存鏡像有三種方式:保存容器為鏡像、導出容器為鏡像、導出鏡像為鏡像。
7.1 保存容器為鏡像
# 保存容器為鏡像:將正在運行的容器保存為鏡像。
語法:docker commit [可選參數] 容器名稱 鏡像名稱
參數:
-a : 指定作者
-c :修改的列表
-m :提交信息
-p :暫停容器
[root@kubernetes ~]# docker commit jovial_cori test:v1
sha256:e9a3491205940b0f390461086bffb7bf08da497b327ce0d67c0462cfc89f452f
[root@kubernetes ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test v1 e9a349120594 5 seconds ago 141MB
7.2 導出容器為鏡像
導出容器為鏡像:將正在運行的容器,導出為一個鏡像壓縮包。
語法格式:
導出:docker export -o [容器包名] [容器名] # 或 docker export [容器名] > [容器包名]
導入:docker import [容器包名] [鏡像名]
[root@kubernetes teszt]# docker export -o nginx.tar jovial_cori
[root@kubernetes teszt]# ll
總用量 140660
-rw------- 1 root root 144025600 3月 18 11:00 nginx.tar
[root@kubernetes teszt]# docker import -m '測試導出' ./nginx.tar test:v2
sha256:ac7290ff39286ffbc88a23b520d634851f017c71bad4ab53985f95bd1f73e750
[root@kubernetes teszt]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test v2 ac7290ff3928 6 seconds ago 140MB
7.3 導出鏡像
導出鏡像:將宿主主機中的鏡像導出為鏡像壓縮包。
語法格式:
導出鏡像:docker save -o [鏡像包名] [鏡像名]
導入鏡像:docker load -i
[root@kubernetes teszt]# docker save -o centos.tar centos:latest
[root@kubernetes teszt]# docker load -i centos.tar
Loaded image: centos:latest
[root@kubernetes teszt]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 8becc16f3db7 4 months ago 204MB
8、進入容器
8.1 attach
attach 是最早 docker 官方推出的進入容器的命令了,它主要是建立一個進程管道,連接上容器中的PID為1的進程。
不過使用該命令有一個問題。當多個窗口同時使用該命令進入該容器時,所有的窗口都會同步顯示。如果有一個窗口阻塞了,那么其他窗口也無法再進行操作,當所有窗口退出時,即所有的進程都結束的話,容器結束,會被系統回收。
[root@mysql01 ~]# docker attach clever_ride
8.2 exec
繼attach 之后,exec 是官方推出的有一個新的進入容器的命令,這個命令相當於在容器中執行一個命令。主要是用來在宿主主機中執行容器內的命令,是目前企業最常用的方式。
[root@mysql01 ~]# docker exec -it clever_ride /bin/bash # /bin/bash是給個bash進程窗口可以執行命令
8.3 nsenter
需要配合 docker inspect 來使用,主要是是新建一個進程管道,並且在容器中新建一個bash進程。
[root@mysql01 ~]# nsenter --target $(docker inspect -f '{{ .State.Pid }}' vigorous_jackson ) --mount --uts --ipc --net --pid
9、容器復制文件
9.1 復制容器內文件到宿主主機
語法格式:docker cp 容器名稱:文件路徑 宿主主機路徑
[root@mysql01 ~]# docker cp 437617cd0270:/root/test.txt /opt
[root@mysql01 opt]# ll /opt
9.2 復制宿主主機文件到容器內
語法格式:docker cp 宿主主機路徑 容器名稱:文件路徑
[root@mysql01 opt]# docker cp /opt/test.txt 437617cd0270:/root/test1.txt
[root@mysql01 opt]# docker exec 437617cd0270 ls /root/
10、練習:要求使用容器部署Django
# 要求使用容器部署Django
1.安裝依賴軟件
[root@mysql01 opt]# yum install python3 libxml* gcc* pcre-devel openssl-devel python3-devel python-devel-y
2.安裝Django:pip3
[root@mysql01 opt]# pip3 install django -i http://pypi.douban.com/simple --trusted-host=pypi.douban.com
3.創建項目生成代碼:django-admin startproject / startapp
[root@mysql01 ~]# cd /opt/
[root@mysql01 opt]# django-admin startproject djangotest
[root@mysql01 opt]# cd /opt/djangotest/
[root@mysql01 djangotest]# django-admin startapp application
4.修改配置文件
[root@mysql01 djangotest]# vim /opt/djangotest/djangotest/settings.py
ALLOWED_HOSTS = ['*'] # 加入一個※號表示通用
DATABASES = {} # 把原來的內容清空
5.安裝uwsgi
[root@mysql01 djangotest]# pip3 install uwsgi http://pypi.douban.com/simple --trusted-host=pypi.douban.com
7.修改ini配置文件
[root@mysql01 djangotest]# vim /opt/djangotest/myweb.ini
[uwsgi]
# 端口號
socket = :8080
# 指定項目的目錄
chdir = /opt/djangotest
# wsgi文件路徑
wsgi-file = djangotest/wsgi.py
# 模塊wsgi路徑
module = djangotest.wsgi
# 是否開啟master進程
master = true
# 工作進程的最大數目
processes = 4
# 結束后是否清理文件
vacuum = true
8.啟動uwsgi
[root@mysql01 djangotest]# uwsgi --ini myweb.ini
5.指定啟動端口
[root@mysql01 djangotest]# python3 /opt/djangotest/manage.py runserver 0.0.0.0:8081
10.啟動docker
[root@mysql01 ~]# systemctl enable --now docker
11.啟動容器
[root@mysql01 ~]# docker run -dit -v /opt/djangotest/:/opt -p 8081:8081 python:3
12.進入容器
[root@mysql01 ~]# docker ps
[root@mysql01 ~]# docker exec -it eloquent_chaum bash
12.在容器內安裝Django
root@6010a5a4b1b1:/# cd /opt
root@6010a5a4b1b1:/opt# pip3 install django==2.2.2 -i https://pypi.tuna.tsinghua.edu.cn/simple/
root@6010a5a4b1b1:/opt# python manage.py runserver 0.0.0.0:8081
13.瀏覽器訪問
192.168.15.51:8081
Docker網絡
Docker本身的技術依賴於Linux內核虛擬化,對Linux內核的特性有很強的依賴。要學習Docker網絡首先要了解linux內核。
在Docker之中,存在多個容器使用同一個端口的情況,怎么解決?例如多個nginx都使用80端口,是怎么實現的呢?
1、Linux網絡基礎
為了支持網絡協議的多實例,Linux在網絡協議棧中引入了網絡名稱空間(Network Namespace),這些獨立的協議棧被隔離到不同的命名空間中去,處於不同的命名空間中的網絡協議棧完全隔離,彼此之間無法進行網絡通信。
通這種對網絡協議資源的隔離,就能夠在一個宿主主機上虛擬出來多個不同的網絡環境,Docker正是利用了這種網絡名稱空間的特性,實現了不同容器之間的網絡隔離。
Linux的網絡協議棧是十分復雜的,為了支持獨立的協議棧,Linux把所有的全局變量都修改為網絡協議棧的私有變量。最好的辦法就是讓這些全局變量成為一個 Net Namespace 變量的成員,然后為了協議棧的函數調用加入一個Namespace 參數。這就是 Linux 網絡名稱空間的核心。所以的網絡設備都只能屬於一個網絡名稱空間。當然,通常的物理網絡設備只能關聯到 root 這個命名空間中。虛擬網絡設備則可以被創建並關聯到一個給定的命名空間中,而且可以在這些名稱空間之間移動。
1.2 實現Linux命名空間之間網絡轉發
1.2.1 創建一個命名空間
[root@kubernetes ~]# ip netns add test01
[root@kubernetes ~]# ip netns list
test01
1.2.2 Linux中不同命名空間之間網絡互通的實現方式
在Linux操作系統中,實現不同網絡名稱空間之間網絡互通的方式如下:
1.Veth設備對:建立一個Veth設備對時,會創建兩個Veth設備網卡,將其中一個Veth設備網卡放到需要鏈接的網絡名稱空間內,即可實現兩個名稱空間之間的網絡互通。
2. Iptables:通過Iptables進行網絡轉發,來實現網絡互通。
3. 網橋:所有的網絡全部走網橋,通過網橋進行網絡轉發。
設備 | 作用 |
---|---|
network namespace | 主要提供了關於網絡資源的隔離,包括網絡設備、IPv4 和 IPv6 協議棧、IP 路 由表、防火牆、/proc/net 目錄、/sys/class/net 目錄、端口(socket)等。 |
veth pair | 兩個虛擬網卡組成的數據通道。在 Docker 中,用於連接 Docker 容器和 Linux Bridge。一端在容器中作為 eth0 網卡,另一端在 Linux Bridge 中作為網橋的 一個端口。 |
iptables | 主要為容器提供 NAT 以及容器網絡安全。 |
linux Bridge | 功能相當於物理交換機,為連在其上的設備(容器)轉發數據幀。如 docker0 網橋。 |
1.3 Veth設備對
為了解決不同網絡名稱空間之間的網絡互通,我們可以使用Veth設備對來實現。由於要連接的兩個網絡命名空間,所以 Veth 設備是成對出現的,很像一對以太網卡,並且中間有一根直連的網線。既然是一對網卡,那么我們將其中一端稱為另一端的peer。在 Veth 設備的一端發送數據時,它會將數據直接發送到另一端,並觸發另一端的接收操作。
# 創建Veth設備對:生成了兩個 veth 設備, 互為對方的 peer。
[root@kubernetes ~]# ip link add veth type veth peer name veth001
# 將veth設備對綁定到命名空間
[root@kubernetes ~]# ip link set veth001 netns test01
# 將 Veth 分配 IP:注意不能與現有IP網段一致
[root@kubernetes ~]# ip a
[root@kubernetes ~]# ip netns exec test01 ip addr add 172.18.0.111/20 dev veth001
[root@kubernetes ~]# ip addr add 172.18.0.112/20 dev veth
# 刷新宿主主機的veth設備 IP
[root@kubernetes ~]# ip link set dev veth down
[root@kubernetes ~]# ip link set dev veth up
# 刷新容器的veth設備 IP
[root@kubernetes ~]# ip netns exec test01 ip link set dev veth001 down
[root@kubernetes ~]# ip netns exec test01 ip link set dev veth001 up
# 測試連接:ping通即OK
[root@kubernetes ~]# ping 172.18.0.111
[root@kubernetes ~]# ping 172.18.0.112
1.4 Iptables
Iptables:基於系統安全框架,繞過網絡名稱空間實現網絡互通。網絡命名空間屬於是用戶級別,而Iptables屬於是系統層級。
我們知道, Linux 絡協議樵非常高效,同時比較復雜 如果我們希望在數據的處理過程中對關心的數據進行一些操作該怎么做呢? Linux 提供了一套機制來為用戶實現自定義的數據包處理過程。
在 Linux 網絡協議棋中有一組回調函數掛接點,通過這些掛接點掛接的鈎子函數可以在 Linux 網絡棋處理數據包的過程中對數據包進行 些操作,例如過濾、修改、丟棄等 整個掛接點技術叫作 Netfilter lptablesNetfilter 負責在內核中執行各種掛接的規則,運行在內核模式中:而 lptables 是在用戶模式下運行的進程,負責協助維護內核中 Netfilter 的各種規則表 通過 者的配合來實現整個 Linux 網絡協議戰中靈活的數據包處理機制。
Iptables詳情參考博客:https://www.cnblogs.com/90s-blog/p/15736429.html
2、Docker網絡
Docker使用了Linux橋接的方式,在宿主主機上虛擬出來一個Docker容器網橋,Docker啟動一個容器時,會根據網段分配給容器一個IP地址,稱之為:Contabiner IP,同時Docker網橋是每個容器默認的網關,因為在同一個宿主主機內的容器都接入同一個網橋,這樣容器之間就可以實現互聯互通了。
2.1 Docker網橋
Linux 可以支持多個不同的網絡,它們之間能夠相互通信,就需要一個網橋。 網橋是二層的虛擬網絡設備,它是把若干個網絡接口“連接”起來,從而報文能夠互相轉發。網橋能夠解析收發的報文,讀取目標 MAC 地址的信息,和自己記錄的 MAC 表結合,來決定報文的轉發目標網口。
網橋設備 brO 綁定了 eth0、 eth1 。對於網絡協議械的上層來說,只看得到 brO 。因為橋接是在數據鏈路層實現的 ,上層不需要關心橋接的細節,於是協議枝上層需要發送的報文被送到 brO ,網橋設備的處理代碼判斷報文該被轉發到 ethO 還是 ethl ,或者兩者皆轉發。反過來,從 ethO 或從 ethl 接收到的報文被提交給網橋的處理代碼,在這里會判斷報文應該被轉發、丟棄還是提交到協議枝上層。 而有時 ethl 也可能會作為報文的源地址或目的地址 直接參與報文的發送與接收,從而繞過網橋。
網橋相當於交換機,所有的網絡之間要想互聯互通,就必須跟網橋關聯,然后由網橋進行網絡轉發。在Docker中,網橋一般有四種模式:分別是:HOST模式、Contaniner模式、None模式和Bridge模式。
# MAC 地址: 類似於身份證號碼,用於標識唯一的一台計算機。以太網協議:規定了計算機必須有一塊網卡,並且網卡上面需要有一串固定12位的16進制數字。前六位是產商編號,后六位是流水線號。上述的數字也稱為計算機的mac地址。
2.2 Docker 網絡模式
Docker 使用 Linux 橋接的方式,在宿主機虛擬一個 Docker 容器網橋(docker0),Docker 啟動一個容器時會根據 Docker 網橋的網段分配給容器一個 IP 地址,稱為 Container-IP,同時 Docker 網橋是每個容器的默認網關。因為在同一宿主機內的容器都接入同一個網橋,這樣容器之間就能夠通過容器的 Container-IP 直接通信。
Docker 網橋是宿主機虛擬出來的,並不是真實存在的網絡設備,外部網絡是無法尋址到的,這也意味着外部網絡無法通過直接 Container-IP 訪問到容器。如果容器希望外部訪問能夠訪問到,可以通過映射容器端口到宿主主機(端口映射),即 docker run 創建容器時候通過 -p 或 -P 參數來啟用,訪問容器的時候就通過[宿主機 IP]:[容器端口]訪問容器。
Docker網絡模型 | 配置 | 說明 |
---|---|---|
host模式 | –-network=host | 容器和宿主機共享Network namespace |
containe模式 | --network=container:ID | 容器和另外一個容器共享 Network namespace。 kubernetes 中的 pod 就是多個容器共享一個 Network namespace。 |
none 模式 | --network=none | 容器有獨立的 Network namespace,但並沒有對其進行任何網 絡設置,如分配 veth pair 和網橋連接,配置 IP 等。 |
bridge 模式 | --network=bridge | 當 Docker 進程啟動時,會在主機上創建一個名為 docker0 的虛 擬網橋,此主機上啟動的 Docker 容器會連接到這個虛擬網橋上。 虛擬網橋的工作方式和物理交換機類似,這樣主機上的所有容器 就通過交換機連在了一個二層網絡中。(默認為該模式) |
2.2.1 HOST 模式
如果啟動容器的時候使用 host 模式,那么這個容器將不會獲得一個獨立的 Network Namespace,而是和主機共用一個 Network Namespace。容器將不會虛擬出自己的網卡,配置自己的 IP 等,而是使用宿主機的 IP和端口。但是,容器的其他方面,如文件系統、進程列表等還是和宿主機隔離的。
使用 host 模式的容器可以直接使用宿主機的 IP 地址與外界通信,容器內部的服務端口也可以使用宿主機的端口,不需要進行 NAT,host 最大的優勢就是網絡性能比較好,但是 docker host 上已經使用的端口就不能再用了,網絡的隔離性不好。
[root@kubernetes ~]# docker run -d --network host nginx
[root@kubernetes ~]# docker ps
[root@kubernetes ~]# curl 127.0.0.1:80
2.2.2 Containe 模式
這個模式指定新創建的容器和已經存在的一個容器共享一個 Network Namespace,而不是和宿主機共享。新創建的容器不會創建自己的網卡,配置自己的 IP,而是和一個指定的容器共享 IP、端口范圍等。同樣,兩個容器除了網絡方面,其他的如文件系統、進程列表等還是隔離的。兩個容器的進程可以通過 lo 網卡設備通信。
[root@kubernetes ~]# docker run --name test -it centos bash
[root@kubernetes ~]# docker run -it --network "container:test" centos bash
[root@mysql01 djangotest]# docker exec eloquent_galileo ip a
[root@mysql01 djangotest]# docker exec test ip a
2.2.3 none 模式
使用 none 模式,Docker 容器擁有自己的 Network Namespace,但是,並不為 Docker 容器進行任何網絡配置。也就是說,這個 Docker 容器沒有網卡、IP、路由等信息。需要我們自己為 Docker 容器添加網卡、配置IP 等。
這種網絡模式下容器只有 lo 回環網絡,沒有其他網卡。none 模式可以在容器創建時通過--network=none來指定。這種類型的網絡沒有辦法聯網,封閉的網絡能很好的保證容器的安全性。一般這種模式只會用在機密或者絕密數據。
[root@kubernetes ~]# docker run -it --network none centos bash
2.2.4 bridge 模式
當 Docker 進程啟動時,會在主機上創建一個名為 docker0 的虛擬網橋,此主機上啟動的 Docker 容器會連接到這個虛擬網橋上。虛擬網橋的工作方式和物理交換機類似,這樣主機上的所有容器就通過交換機連在了一個二層網絡中。
從 docker0 子網中分配一個 IP 給容器使用,並設置 docker0 的 IP 地址為容器的默認網關。在主機上創建一對虛擬網卡 veth pair 設備,Docker 將 veth pair 設備的一端放在新創建的容器中,並命名為 eth0(容器的網卡),另一端放在主機中,以 vethxxx 這樣類似的名字命名,並將這個網絡設備加入到 docker0 網橋中。可以通過 brctl show 命令查看。
bridge 模式是 docker 的默認網絡模式,不寫--net 參數,就是 bridge 模式。使用 docker run -p 時,docker實際是在 iptables 做了 DNAT 規則,實現端口轉發功能。可以使用 iptables -t nat
[root@kubernetes ~]# docker network create test
[root@kubernetes ~]# docker run -d --network test nginx
[root@kubernetes ~]# docker run -it --network test centos
2.3 Docker網絡(network)
2.3.1 創建docker 網絡
[root@kubernetes ~]# docker network create chenyang1
87d1a7fae878ebb1cd26dab85b81f126eccec18d8d8dcc160ab96c0afa5e6a51
2.3.2 查看網橋
[root@kubernetes ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
87d1a7fae878 chenyang1 bridge local
- NETWORK ID : 網橋的ID
- NAME :網橋的名稱
- DRIVER :網橋的類型
- SCOPE :網橋的所在地
2.3.3 鏈接網橋
已經創建過的容器鏈接網橋。
[root@kubernetes ~]# docker network connect chenyang1 9bc930694812
2.3.4 斷開鏈接網橋
[root@kubernetes ~]# docker network disconnect chenyang1 9bc930694812
2.3.5 刪除網橋
[root@kubernetes ~]# docker network rm chenyang2
2.3.6 清理網橋
將所有未被使用到的網橋全部刪除
[root@kubernetes ~]# docker network prune
3、練習:要求在docker中實現用nginx代理django
3.1 生成代碼
# 安裝:python3.6 python3-devel nginx
[root@mysql01 djangotest]# yum install python3.6 python3-devel nginx
# 安裝django和uwsgi
[root@mysql01 djangotest]# pip3 install django==2.2.2 -i https://pypi.tuna.tsinghua.edu.cn/simple/
[root@mysql01 djangotest]# pip3 install uwsgi -i https://pypi.tuna.tsinghua.edu.cn/simple/
# 創建目錄生成代碼
[root@mysql01 djangotest]# cd /opt
[root@mysql01 djangotest]# mkdir linux
[root@mysql01 djangotest]# cd linux
[root@mysql01 djangotest]# django-admin startproject test
[root@mysql01 djangotest]# cd test
[root@mysql01 djangotest]# django-admin startapp application
# 修改配置文件settings.py和myweb.ini
[root@mysql01 djangotest]# vim /opt/djangotest/djangotest/settings.py
ALLOWED_HOSTS = ['*']
DATABASES = {}
[root@mysql01 djangotest]# vim /opt/djangotest/myweb.ini
[uwsgi]
# 端口號
socket = :8080
# 指定項目的目錄
chdir = /opt/djangotest
# wsgi文件路徑
wsgi-file = djangotest/wsgi.py
# 模塊wsgi路徑
module = djangotest.wsgi
# 是否開啟master進程
master = true
# 工作進程的最大數目
processes = 4
# 結束后是否清理文件
vacuum = true
3.2 部署django
# 開啟docker
[root@mysql01 djangotest]# systemctl enable --now docker
# 創建docker網絡
[root@mysql01 djangotest]# docker network create chenyang3
# 創建容器
[root@mysql01 djangotest]# docker run -it -d --name djangotest -v /opt/djangotest/djangotest/:/opt --network chenyang3 python:3.6 bash
# 進入容器
[root@mysql01 djangotest]# docker exec -it djangotest bash
# 切換目錄
root@883b7923c861:/# cd /opt/
# 安裝django
root@883b7923c861:/opt# pip install django==2.2.2 -i https://pypi.tuna.tsinghua.edu.cn/simple/
# 啟動
root@883b7923c861:/opt# python manage.py runserver 0.0.0.0:8080
3.3 部署Nginx
# 創建目錄
[root@mysql01 djangotest]# mkdir /opt/djangotest/nginx
[root@mysql01 djangotest]# cd nginx/
# 編輯配置文件
[root@mysql01 nginx]# vim default.conf
server {
server_name _;
listen 80;
location / {
proxy_pass http://djangotest:8080;
}
}
[root@kubernetes nginx]# docker run -d -P --name nginx1 -v /root/django/nginx/:/etc/nginx/conf.d --network chenyang3 nginx
3.4 測試結果
# 查看隨機端口號
[root@mysql01 nginx]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a7b070217d24 nginx "/docker-entrypoint.…" 6 seconds ago Up 4 seconds 0.0.0.0:49153->80/tcp, :::49153->80/tcp nginx01
94288f90aaab python:3.6 "bash" 4 minutes ago Up 4 minutes djangotest
# 瀏覽器訪問:192.168.15.52:49153 出現django
Dockerfile構建鏡像
Dockerfile主要用在Docker中,構建鏡像。
Dockerfile是由一行一行指令組成的,支持以#開頭的行為注釋的行。
一般而言,Dockerfile主體內容分為兩個部分:基礎鏡像信息(必須)、其他指令。
在構建鏡像之前,必須基於Docker一個基礎環境(基礎鏡像)。
構建鏡像語法:Docker build -t 鏡像名字:版本 鏡像路徑
1、FROM:指定基礎環境
FROM指令必須是Dockerfile中的第一個指令,而且FROM指令有且只有一個,主要用來指定一個構建鏡像的基礎環境。
[root@kubernetes linux]# vim Dockerfile
FROM python:3.6
2、MAINTAINER:指定維護者信息
指定維護者信息。沒有實際作用,主要是用來指定構建該鏡像的作者信息。
[root@kubernetes linux]# cat Dockerfile
FROM python:3.6
MAINTAINER shanhe shanhe@123.com xxxxxxx
3、RUN:構建鏡像時執行命令
構建鏡像時執行命令。
[root@kubernetes linux]# cat Dockerfile
FROM python:3.6
MAINTAINER shanhe shanhe@123.com xxxxxxx
RUN pip install django==2.2.2 -i https://pypi.tuna.tsinghua.edu.cn/simple/
4、CMD:設置Docker鏡像啟動時默認執行的命令
設置Docker鏡像啟動時默認執行的命令。
[root@kubernetes linux]# cat Dockerfile
FROM python:3.6
MAINTAINER shanhe shanhe@123.com xxxxxxx
RUN pip install django==2.2.2 -i https://pypi.tuna.tsinghua.edu.cn/simple/
CMD python manage.py runserver 0.0.0.0:8080
5、ENTRYPOINT:設置Docker鏡像啟動命令
設置Docker鏡像啟動命令,如果設置了ENTRYPOINT,則CMD將會變成它的參數。
[root@kubernetes linux]# cat Dockerfile
FROM python:3.6
MAINTAINER shanhe shanhe@123.com xxxxxxx
RUN pip install django==2.2.2 -i https://pypi.tuna.tsinghua.edu.cn/simple/
ADD ./ /opt/
VOLUME /tmp
WORKDIR /opt
EXPOSE 8080
ENTRYPOINT ["python"]
CMD ["manage.py", "runserver", "0.0.0.0:8080"]
6、WORKDIR:指定Docker容器的工作目錄
指定Docker容器的工作目錄。也就是說docker容器啟動時,默認執行命令的目錄。
[root@kubernetes linux]# cat Dockerfile
FROM python:3.6
MAINTAINER shanhe shanhe@123.com xxxxxxx
RUN pip install django==2.2.2 -i https://pypi.tuna.tsinghua.edu.cn/simple/
WORKDIR /opt
CMD python manage.py runserver 0.0.0.0:8080
[root@kubernetes linux]# docker run -d -v /root/django/linux/:/opt -p 8081:8080 django:v3
7、EXPOSE:指定默認端口號
expost是Dockerfile中指定默認端口號。
[root@kubernetes linux]# cat Dockerfile
FROM python:3.6
MAINTAINER shanhe shanhe@123.com xxxxxxx
RUN pip install django==2.2.2 -i https://pypi.tuna.tsinghua.edu.cn/simple/
WORKDIR /opt
EXPOSE 8080 8081 8082 8083/udp
CMD python manage.py runserver 0.0.0.0:8080
8、ADD:將宿主主機中的內容或者互聯網下載的內容放置於鏡像中
將宿主主機中的內容或者互聯網下載的內容放置於鏡像中。支持自動解壓tar類型的壓縮包。
[root@kubernetes linux]# cat Dockerfile
FROM python:3.6
MAINTAINER shanhe shanhe@123.com xxxxxxx
RUN pip install django==2.2.2 -i https://pypi.tuna.tsinghua.edu.cn/simple/
ADD ./ /opt/
ADD http://106.13.81.75/Navicat15.exe /tmp/
WORKDIR /opt
EXPOSE 8080 8081 8082 8083/udp
CMD python manage.py runserver 0.0.0.0:8080
9、COPY:將宿主主機中的內容復制到鏡像中
將宿主主機中的內容復制到鏡像中。不支持互聯網下載,也不支持自動解壓。
[root@kubernetes linux]# cat Dockerfile
FROM python:3.6
MAINTAINER shanhe shanhe@123.com xxxxxxx
RUN pip install django==2.2.2 -i https://pypi.tuna.tsinghua.edu.cn/simple/
COPY etcd-v3.4.14-linux-amd64.tar.gz /tmp/
WORKDIR /opt
EXPOSE 8080
CMD python manage.py runserver 0.0.0.0:8080
10、VOLUME:指定容器需要掛載的目錄
指定容器需要掛載的目錄(注意:如果我們啟動容器時,使用了-v參數則直接掛載,如果沒有使用-v,則會使用volume指定默認的掛載)
[root@kubernetes linux]# cat Dockerfile
FROM python:3.6
MAINTAINER shanhe shanhe@123.com xxxxxxx
RUN pip install django==2.2.2 -i https://pypi.tuna.tsinghua.edu.cn/simple/
ADD ./ /opt/
VOLUME /tmp
WORKDIR /opt
EXPOSE 8080
CMD python manage.py runserver 0.0.0.0:8080
11、ENV:指定該鏡像啟動容器中的環境變量
指定該鏡像啟動容器中的環境變量。
[root@kubernetes linux]# cat Dockerfile
FROM python:3.6
MAINTAINER shanhe shanhe@123.com xxxxxxx
RUN pip install django==2.2.2 -i https://pypi.tuna.tsinghua.edu.cn/simple/
ADD ./ /opt/
VOLUME /tmp
ENV DJANGO_VERSION=123456
WORKDIR /opt
EXPOSE 8080
ENTRYPOINT ["python"]
CMD ["manage.py", "runserver", "0.0.0.0:8080"]
12、ARG:設置構建鏡像臨時參數
設置構建鏡像臨時參數。
[root@kubernetes django]# cat Dockerfile
FROM python:3.6
ARG package=django
RUN pip install $package
[root@kubernetes django]# docker build --build-arg=package=pymysql -t django:v17 .
13、ONBUILD:構建觸發器
Docker構建觸發器。主要是當該鏡像作為基礎鏡像時觸發。
[root@kubernetes django]# cat Dockerfile
FROM django:v19
ARG package=django
RUN pip install $package
ONBUILD RUN rm -rf /opt
14、案例:使用Nginx代理Django
14.1 宿主主機生成代碼
# 安裝依賴軟件
[root@kubernetes ~]# yum install python3.6 python3-dev
# 安裝django和uwsgi
[root@kubernetes ~]# pip3 install django==2.2.2 -i https://pypi.tuna.tsinghua.edu.cn/simple/
[root@kubernetes ~]# pip3 install uwsgi -i https://pypi.tuna.tsinghua.edu.cn/simple/
# 創建目錄生成代碼
[root@kubernetes ~]# mkdir -p /opt/linux
[root@kubernetes ~]# cd /opt/linux
[root@kubernetes linux]# django-admin startproject djangotest
[root@kubernetes linux]# cd djangotest
[root@kubernetes djangotest]# django-admin startapp application
# 修改配置
[root@kubernetes djangotest]# vim /opt/linux/djangotest/settings.py
ALLOWED_HOSTS = ['*']
DATABASES = {}
14.2 部署Django
# 1.創建Dockerfile文件
[root@kubernetes opt]# vim Dockerfile
FROM python:3.6
MAINTAINER shanhe shanhe@123.com xxxxxxx
RUN pip install uwsgi -i https://pypi.tuna.tsinghua.edu.cn/simple/
RUN pip install django==2.2.2 -i https://pypi.tuna.tsinghua.edu.cn/simple/
RUN mkdir /opt/linux
ADD ./linux /opt/linux/
EXPOSE 8000
WORKDIR /opt/linux
CMD uwsgi --ini myweb.ini
# 2.配置myweb.ini文件
[root@kubernetes opt]# vim /opt/linux/myweb.ini
[uwsgi]
# 端口號
socket = :8000
# 指定項目的目錄
chdir = /opt/linux
# wsgi文件路徑
wsgi-file = djangotest/wsgi.py
# 模塊wsgi路徑
module = djangotest.wsgi
# 是否開啟master進程
master = true
# 工作進程的最大數目
processes = 4
# 結束后是否清理文件
vacuum = true
# 3.構建鏡像到當前目錄
[root@kubernetes opt]# docker build -t django:v1 .
# 4.啟動鏡像
[root@kubernetes opt]# docker run -d --name djangotest django:v1
14.3 部署Nginx
# 1.創建nginx目錄
[root@kubernetes django]# mkdir -p /opt/linux/nginx
# 2.編輯配置文件
[root@kubernetes django]# cd /opt/linux/nginx
[root@kubernetes nginx]# vim /opt/linux/nginxdefault.conf
server {
listen 80;
server_name py.test.com;
location / {
include uwsgi_params;
uwsgi_pass djangotest:8000;
uwsgi_read_timeout 2;
uwsgi_param UWSGI_SCRIPT djangotest.wsgi;
uwsgi_param UWSGI_CHDIR /opt/linux;
index index.html index.htm;
client_max_body_size 35m;
}
}
# 3.創建Dockerfile
[root@kubernetes django]# vim Dockerfile
FROM nginx
ADD default.conf /etc/nginx/conf.d/
EXPOSE 80 443
CMD nginx -g 'daemon off;'
# 4.構建鏡像到當前目錄
[root@kubernetes django]# docker build -t nginx:v1 .
# 5.創建網橋
[root@kubernetes django]# docker network create bridge1
# 6.綁定容器
[root@kubernetes django]# docker network connect bridge1 djangotest1
# 7.創建容器
[root@kubernetes django]# docker run -d -p 8082:80 --name nginxtest1 --network bridge1 nginx:v1
14.4 測試結果
瀏覽器訪問192.168.15.51:8082
Docker-compose容器編排工具
在K8S出現之前,市場上有很多個容器編排工具。docker-compose就是其中之一,但是docker-compose只支持單機容器編排。
docker-compose是Docker官方開源的又一個項目,主要負責對Docker容器集群進行快速編排。
在docker-compose中有兩個重要的概念:
● service:一個應用的容器,實際上可以包含若干個運行相同鏡像的容器。
● project:由一組相關聯的應用容器組成的一個完整的業務單元。
由此,docker-compose恰好滿足用戶通過一個命令,啟動整個業務單元中所有的容器的這樣一個功能。
而且,docker-compose是通過Python編寫的,是想上調用了Docker服務提供的API,來對容器進行管理。因此,只要所操作的平台支持Docker,就可以利用docker-compose來進行管理。
1、安裝Docker-compose
安裝docker-compose非常的簡單,從GitHub上面直接下載下來給個執行權限就能用。
[root@mysql01 ~]# echo "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)"
https://github.com/docker/compose/releases/download/1.29.2/docker-compose-Linux-x86_64
[root@mysql01 ~]# sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-Linux-x86_64" -o /usr/local/bin/docker-compose
[root@mysql01 ~]# sudo chmod +x /usr/local/bin/docker-compose
[root@mysql01 ~]# dockre-compose # 查看有數據則安裝完成
2、增加docker-compose的命令行補全
[root@mysql01 ~]# curl -L https://raw.githubusercontent.com/docker/compose/1.29.2/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose
3、docker-compose的使用
docker-compose管理容器是通過配置清單的方式進行管理。配置清單的名稱必須如下選擇一個:
docker-compose.yml, docker-compose.yaml(推薦), compose.yml, compose.yaml。
3.1 image:指定鏡像
[root@kubernetes ~]# mkdir harbor
[root@kubernetes ~]# cd harbor
[root@kubernetes harbor]# vim docker-compose.yaml
# 指定docker-compose配置清單的版本
version: "3"
services:
mydjango: # 自己具體應用
image: django:v24
[root@kubernetes harbor]# docker-compose up -d
3.2 build:構建鏡像
根據指定路徑的dockerfile構建鏡像並啟動。
# 指定docker-compose配置清單的版本
version: "3"
services:
mydjango:
build: ./
# 指定docker-compose配置清單的版本
version: "3"
services:
mydjango:
build:
context: ./
dockerfile: docker-file
3.3 command:指定容器啟動的默認命令
# 指定docker-compose配置清單的版本
version: "3"
services:
mydjango:
build:
context: ./
dockerfile: docker-file
command: python manage.py runserver 0.0.0.0:80
3.4 container_name:指定容器名稱
# 指定docker-compose配置清單的版本
version: "3"
services:
mydjango:
build:
context: ./
dockerfile: docker-file
command: python manage.py runserver 0.0.0.0:80
container_name: test
3.5 depens_on:解決容器啟動順序
# django + Nginx時,Nginx通常必須在Django容器之后啟動。
version: "3"
services:
mydjango:
build:
context: ./
dockerfile: docker-file
command: python manage.py runserver 0.0.0.0:80
container_name: django
mynginx:
image: nginx:v3
depends_on:
- mydjango
3.6 ports:指定容器端口
version: "3"
services:
mydjango:
build:
context: ./
dockerfile: docker-file
container_name: django
mynginx:
image: nginx:v3
ports:
- "8090:80"
depends_on:
- mydjango
3.6 volumes:掛載目錄
version: "3"
services:
mydjango:
build:
context: ./
dockerfile: docker-file
container_name: django
mynginx:
image: nginx:v3
ports:
- "8090:80"
volumes:
- /opt:/opt
depends_on:
- mydjango
4、docker-compose常用命令
關於docker-compose操作容器的命令。
4.1 up:創建容器並啟動
[root@kubernetes django]# docker-compose up -d
4.2 down:停止容器
[root@kubernetes django]# docker-compose down
4.3 ps:容器列表
[root@kubernetes django]# docker-compose ps
Name Command State Ports
---------------------------------------------------------------------------------------------------------
django uwsgi --ini myweb.ini Up 8000/tcp
django_mynginx_1 /docker-entrypoint.sh /bin ... Up 443/tcp, 0.0.0.0:8090->80/tcp,:::8090->80/tcp
4.4 exec:進入容器
[root@kubernetes django]# docker-compose exec mynginx bash
4.5 restart:重啟容器
[root@kubernetes django]# docker-compose restart
4.6 rm:刪除容器
# 先停止后刪除
[root@kubernetes django]# docker-compose stop mydjango
Stopping django ... done
[root@kubernetes django]# docker-compose rm -f mydjango
Going to remove django
Removing django ... done
4.7 top:查看容器內部的進程
[root@kubernetes django]# docker-compose top mynginx
5、docker的可視化平台
5.1 啟動
# step1 加上域名解析
[root@kubernetes linux]# vim /etc/sysconfig/network-scripts/ifcfg-ens33
DNS1=114.114.114.114
DNS2=192.168.15.61
# step2 兩種啟動方法:
# 方法1:用命令行啟動
[root@docker01 harbor]# docker run -d -p 8000:8000 -p 9443:9443 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:2.11.1
# 方法2:用docker-compose.yaml啟動
[root@docker01 harbor]# vim docker-compose.yaml
version: "3"
services:
portainer:
image: portainer/portainer-ce:2.11.1
volumes:
- /opt/portainer_data:/data
- /var/run/docker.sock:/var/run/docker.sock
container_name: portainer
ports:
- 8000:8000
- 9443:9443
# 啟動
[root@kubernetes linux]# docker-compose up -d
5.2 查看
# 瀏覽器訪問:https://192.168.15.61:9443
# 設置密碼
# 進入docker可視化平台
Harbor私有倉庫
Harbor是有VMware公司中國團隊為企業用戶設計的私有倉庫開源項目,它包含了權限管理、審計、管理界面、自我注冊等企業必須的功能。同時針對中國用戶的特點,設計了鏡像復制和中文支持等功能。提供了更好的性能和安全,提升用戶使用私有倉庫構建和運行環境的傳輸效率。
1、下載harbor
# 下載harbor安裝包
wget https://github.com/goharbor/harbor/releases/download/v2.4.2/harbor-offline-installer-v2.4.2.tgz
# 解壓
tar -xf harbor-offline-installer-v2.4.2.tgz
# 創建證書目錄
mkdir /root/harbor/harbor/cert
cd /root/harbor/harbor/cert
2、安裝
2.1 生成CA簽名
openssl genrsa -out ca.key 4096
2.2 生成CA證書
注意修改 IP !!
openssl req -x509 -new -nodes -sha512 -days 3650 \
-subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=192.168.15.61" \
-key ca.key \
-out ca.crt
2.3 生成服務器證書
注意修改 IP !!
openssl genrsa -out 192.168.15.61.key 4096
# 注意:192.168.15.61為本機IP,注意修改!
2.4 生成證書簽名
注意修改 IP !!
openssl req -sha512 -new \
-subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=192.168.15.61" \
-key 192.168.15.61.key \
-out 192.168.15.61.csr
# 注意:192.168.15.61為本機IP,注意修改!
2.5 生成x509 v3拓展文件
注意修改 IP !!
cat > v3.ext <<-EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = IP:192.168.15.61
EOF
2.6 通過v3.ext文件生成證書
注意修改 IP !!
openssl x509 -req -sha512 -days 3650 \
-extfile v3.ext \
-CA ca.crt -CAkey ca.key -CAcreateserial \
-in 192.168.15.61.csr \
-out 192.168.15.61.crt
2.7 將證書提供給Docker
# 創建目錄
mkdir -p /data/cert/
openssl x509 -inform PEM -in 192.168.15.61.crt -out 192.168.15.61.cert
# 復制證書給docker
mkdir -pv /etc/docker/certs.d/192.168.15.61/
cp 192.168.15.61.cert /etc/docker/certs.d/192.168.15.61/
cp 192.168.15.61.key /etc/docker/certs.d/192.168.15.61/
cp ca.crt /etc/docker/certs.d/192.168.15.61/
2.8 修改Harbor的配置文件
cd /root/harbor/harbor
cp harbor.yml.tmpl harbor.yml
vim harbor.yml # 只需要修改下面三處,其他不修改
hostname: 192.168.15.61
certificate: /data/cert/192.168.15.61.crt
private_key: /data/cert/192.168.15.61.key
2.9 生成Harbor的配置文件
cp /root/harbor/harbor/cert/{192.168.15.61.crt,192.168.15.61.key} /data/cert/
bash /root/harbor/harbor/prepare
2.10 安裝Harbor
bash /root/harbor/harbor/install.sh
2.11 瀏覽器訪問
# 訪問https://192.168.15.61
# 初始賬號admin; 初始密碼Harbor12345
3、測試Docker登錄Harbor
3.1 docker登錄
[root@kubernetes harbor]# docker login 192.168.15.61
Username: admin
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
3.2 瀏覽器登錄harbor創建空間os
3.3 docker上傳鏡像
[root@kubernetes harbor]# docker tag 5d0da3dc9764 192.168.15.61/os/centos:8
[root@kubernetes harbor]# docker push 192.168.15.61/os/centos:8
The push refers to repository [106.13.81.75/os/centos]
74ddd0ec08fa: Pushed
8: digest: sha256:a1801b843b1bfaf77c501e7a6d3f709401a1e0c83863037fa3aab063a7fdb9dc size: 529