Docker

ssrheart發表於2024-06-26

Docker

1 docker介紹

1.1 虛擬化

在計算機中,虛擬化(英語:Virtualization)是一種資源管理技術,是將計算機的各種實體資源,如伺服器、網路、記憶體及儲存等,予以抽象、轉換後呈現出來,打破實體結構間的不可切割的障礙,使使用者可以比原本的組態更好的方式來應用這些資源。這些資源的新虛擬部份是不受現有資源的架設方式,地域或物理組態所限制。一般所指的虛擬化資源包括計算能力和資料儲存。

在實際的生產環境中,虛擬化技術主要用來解決高效能的物理硬體產能過剩和老的舊的硬體產能過低的重組重用,透明化底層物理硬體,從而最大化的利用物理硬體  對資源充分利用

虛擬化技術種類很多,例如:軟體虛擬化、硬體虛擬化、記憶體虛擬化、網路虛擬化(vip)、桌面虛擬化、服務虛擬化、虛擬機器等等。


# kvm,VMware,openstack,docker,k8s
	-kvm,vmware:虛擬化軟體
    -openstack,阿里飛天:虛擬化軟體管理web專案 -- python
    
    -docker:容器化
    -k8s:容器管理編排

image-20240620154409479

1.2 docker

Docker 是一個開源專案,誕生於 2013 年初,最初是 dotCloud 公司內部的一個業餘專案。它基於 Google 公司推出的 Go 語言實現。 加了 Linux 基金會,遵從了 Apache 2.0 協議,專案程式碼在上進行維護。

容器化技術,區分於虛擬機器,又類虛擬機器,兼具虛擬機器隔離的優點,又有速度快的優點
容器資源隔離,網路隔離
把容器當成一個虛擬機器即可

docker 容器管理 
	-docker swarm
	-k8s

Docker 的基礎是 Linux 容器(LXC)等技術

1.3 docker和其他虛擬機器比較

# docker 不需要虛擬化出作業系統這一層---》更輕量級--佔空間更小---》還能實現隔離

# 虛擬機器技術的缺點:
    1.資源佔用太多
    2.冗餘步驟多
    3.啟動很慢

# 容器化技術
1.伺服器資源利用率高
2.比較輕量化
3.打包映象測試,一鍵執行



比較Docker和虛擬機器技術不同:
​ 1.傳統虛擬機器,虛出一套硬體,執行一個完整的作業系統,然後在這個系統上安裝和執行軟體
​ 2.容器內的應用之間執行在 宿主機的內容,容器是沒有自己的核心的,也沒有虛擬我們的硬體,所以就輕便了
​ 3.每個容器間是互相隔離的,每個容器內都有屬於自己的檔案系統,互不影響
​ 4.安全性,docker的安全性更弱
​ 5.與虛擬機器相比,docker隔離性更弱,docker屬於程序之間的隔離,虛擬機器可實現系統級別隔離
​ 6.docker建立時秒級的,docker的快速迭代性,無論是開發、測試、部署都可以節約大量時間

image-20240620154509458

1.4 docker架構

# cs 架構---》客戶端服務端
	- c 端:使用者操作,輸入命令
    - s 端:接收使用者命令,執行
    - c、s通訊,使用http協議,遵循restful規範
    	-mysql:tcp---》自定義的  
        -redis:tcp---》自定義的  
        
        
  # 架構
	1 client:客戶端,輸入命令
    2 服務端:
    	containers:容器
        images:映象--》從註冊中心下來下來的
        
    3 register:註冊中心
    	-放了很多映象--》redis,nginx,mysql

image-20240620154547869

1.5 docker命令

systemctl start docker  # 啟動docker服務
 
systemctl stop docker  # 停止docker服務
 
systemctl restart docker  # 重啟docker服務

docker -v # 檢視docker版本

2 docker安裝和配置

2.1 centos安裝

windows-docker : https://www.docker.com/products/docker-desktop/

# 1 解除安裝
# yum remove docker docker-common  docker-selinux docker-engine
# rm -rf /var/lib/docker
yum update  # 更新yum倉庫

# 2 安裝
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum install docker-ce -y


# 3 檢視安裝的版本
docker --version

# 4 目前我們只裝了 docker-ce,
	-只有:c  和 s端
    -沒有docker-compose
    -沒有圖形化介面
    -跟docker-destop的區別
    
    
# 5 啟動docker
systemctl start docker

# 6 檢視docker狀態
systemctl status docker


# 7 映象--》從遠端下載下來的---》hub.docker.com -->倉庫下的
	-有非常多映象:可以搜尋,搜到以後,映象有不同版本
    -目前:訪問不到了,拉取不下來
    -配置:國內映象站:阿里雲
    -https://cr.console.aliyun.com/cn-shanghai/instances/mirrors
        
    sudo mkdir -p /etc/docker # 如果有,就不需要建立了
    vi /etc/docker/daemon.json 
    
    # 加入
    {
        "registry-mirrors": [
            "https://registry.docker-cn.com",
            "http://hub-mirror.c.163.com",
            "https://docker.mirrors.ustc.edu.cn",
            "https://dockerhub.azk8s.cn",
            "https://mirror.ccs.tencentyun.com",
            "https://registry.cn-hangzhou.aliyuncs.com",
            "https://docker.mirrors.ustc.edu.cn"
        ]
    }
    
    systemctl daemon-reload   # 重新載入docker配置
    systemctl restart docker  # 重啟docker

2.2 ubuntu安裝

# 解除安裝原有Docker(如果已安裝)
sudo apt-get remove docker docker-engine docker.io containerd runc

# 更新軟體包列表
sudo apt-get update

# 安裝Docker依賴
sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common

# 新增GPG金鑰
# 從Docker官方獲取GPG金鑰
# 官方獲取GPG金鑰出現timeout問題,可以從阿里雲源獲取GPG金鑰
# curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

# 從阿里雲源獲取GPG金鑰:
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -

# 新增Docker軟體源 新增Docker官方軟體源到APT源列表(這裡使用的是阿里雲的Docker映象源):
sudo add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"

# 注意:
# $(lsb_release -cs) 需要替換成自己的ubuntu版本
# 檢視自己的ubuntu版本,終端輸入以下命令:
lsb_release -c


# 安裝Docker CE
# 更新軟體包列表
sudo apt-get update

# 安裝Docker CE
sudo apt-get install docker-ce docker-ce-cli containerd.io

# 驗證Docker安裝
docker -v

# 配置阿里雲映象加速
https://cr.console.aliyun.com/cn-shanghai/instances/mirrors

sudo mkdir -p /etc/docker
sudo nano /etc/docker/daemon.json
{
  "registry-mirrors": ["https://dxef3ui7.mirror.aliyuncs.com"]
}
sudo systemctl daemon-reload
sudo systemctl restart docker

# 重啟docker服務
sudo systemctl restart docker


# 拉取映象
sudo docker pull mysql:5.7 # 下載mysql 5.7映象
sudo docker pull redis:latest # 下載redis最新的映象
sudo docker pull nginx:latest  # 下載 nginx最新的映象
sudo docker pull centos:centos7  # 下載 nginx最新的映象

3 docker映象操作

3.1 映象和容器

# 映象:images
	-一堆檔案---》目前咱們從register---》下載---》放在宿主機(centos 7.9機器)
    -類比:虛擬上裝系統
    	- 作業系統檔案 xx.iso--->裝在虛擬機器上
        - 映象你當成 xx.iso 作業系統檔案
        - 把iso裝在不同虛擬機器中---》啟動---》多臺有作業系統的機器
# 容器:container
	-映象執行---》執行成容器
    -類比:
    	-容器當成一個正在執行的作業系統
    -一個映象,可以執行成多個容器
    
    
    
# python物件導向
	類:映象
    物件:例項化得到多個物件,每個物件間獨立的
    
    
    
# 以後一個容器,你們當成 :一個作業系統+軟體--》正在執行  

3.2 映象操作

docker search : 搜尋

docker pull : 拉取映象

docker images : 檢視映象

docker rmi : 刪除映象

docker rmi `docker images -q` : 一次性刪除所有映象
# 0 搜尋映象
	-去網站搜:https://hub.docker.com/ 
	-使用命令列搜:docker search mysql
    
# 1 獲取映象,拉取映象---》從register下載到本地--》阿里雲映象站--》加速拉取
	docker pull mysql:5.7 # 下載mysql 5.7映象
	docker pull redis:latest # 下載redis最新的映象
    docker pull nginx:latest  # 下載 nginx最新的映象
    docker pull centos:centos7  # 下載 nginx最新的映象
    
# 2 檢視映象
	docker images
    
# 檢視所有映象的id號
	docker images -q

# 3 刪除映象
	docker rmi redis:latest
        
# 一次性刪除所有映象
	docker rmi `docker images -q`

4 容器操作

映象執行,變成容器,一個映象可以執行處多個容器,把一個容器當成一個虛擬機器

一個容器可以有作業系統、檔案、軟體、網路等

4.1 run

-id :啟動容器,不進入容器內部

-it :啟動容器,進入容器內部

--name : 指定容器名字,容器名字不能重複,如果重複就報錯,可以隨便起

centos:centos7 :基於哪個映象執行成容器

# 1 把映象執行成容器 
# 執行,如果映象沒有,會去遠端倉庫下載
docker run -id --name=centos7 centos:centos7

# 2 檢視正在執行的容器
docker ps

# 3 執行:docker run -it  centos:centos7
進入到容器內部,可以執行centos的命令,但是它是最精簡的系統,很多命令可能沒有,用的話需要安裝
退出容器,回到宿主機:exit

# 4 容器需要建立然後執行,其實直接run就可以,最後一步會把前面沒有寫的給補完
	-建立:create命令
    -執行:run

# 5 容器要執行,內部必須有個前臺程序阻塞,否則容器就會停掉

# 6 docker ps -a   #檢視所有容器,包括停止的

# 7 刪除容器
docker rm 容器名字/容器id
docker rm `docker ps -a -q` 一次性刪除所有容器

image-20240620160819916

4.2 run的引數

-i : 表示執行容器

-d : 以守護式容器在後臺執行,用這個引數建立出來的容器,命令列還在宿主機上,沒有進入到容器內部

-t : 表示容器啟動後會進入容器命令列。加入這引數後,容器建立就能登入進去。即分配一個偽終端

--name : 指定容器名字,如果不指定,會隨機一個名字

-p : 表示埠對映,前者是宿主機埠,後者是容器內的對映埠。可以使用多個-p做多個埠對映

-v : 表示目錄對映關係(前者是宿主機目錄,後者是容器的目錄),可以使用多個-v做多個目錄或檔案對映

注意:最好做目錄對映,在宿主機上做修改,然後共享到容器上

4.2.1 幾個小案例 docker exec

docker exec : 在宿主機連線容器執行命令,把結果返回給宿主機

# 1 啟動一個centos容器並且進入,名字叫mycentos,在內部裝個vim,然後退出
	1 docker run -id --name=mycentos centos:centos7
    2 在宿主機
    3 docker exec -it mycentos /bin/bash  # 新開了一個bash程序
    4 yum install vim -y
    5 exit
    
    
# 2 docker exec  命令
	在宿主機連線容器執行命令,把結果返回給宿主機
    docker exec 容器名字/id ls
    
    
# 3  進入到容器內部
	# 在容器上執行命令
	docker exec 容器名字/id  命令
    # 利用這個特性-->進入到容器內部
    docker exec -it 容器名字/id /bin/bash
    docker exec -it python sh
    # 退出,結束掉 /bin/bash
	exit

4.3 -v 目錄對映

-v : 執行容器時,跟宿主機的檔案目錄做對映

# 1 -v 參數列示執行容器時,跟宿主機的檔案目錄做對映

#2 小案例
    # 執行出一個 centos77 容器,不進入,做目錄對映
    # 把宿主機的 /root/lqz資料夾  對映到 容器內部的 /lqz資料夾  容器如果沒有資料夾會自動建立
    # -v可以寫多個,可以是檔案或資料夾

    1 cd # 回家 前提是你是root使用者
    2 mkdir heart  # 在root目錄下建立heart資料夾
    3 執行容器,做目錄對映
    docker run -id --name=centos77 -v /root/heart:/heart centos:centos7
    4 在宿主機的 /root/heart 下新建 123.txt
    vim 123.txt

    5 來到容器內部:看這個檔案在不在
    cat 123.txt

    6 他們是相互影響的:
        容器內部修改檔案---》會影響外部
        外部修改檔案---》影響內部



# 3 目錄對映好處是,後期咱們部署django專案
	1 有個django容器,做好對映,程式碼放在宿主機上即可,以後更新了程式碼,只要重啟容器,程式碼就是最新了
    2 執行mysql容器---》mysql配置檔案,資料data目錄,放在宿主機上做好對映
    	如果 mysql容器---》表資料,放到容器中---》如果刪了容器---》資料庫全沒了
    	表資料,放在宿主機上---》把容器刪除---》表資料還在----》再啟動一個容器做好對映---》資料都還在

4.4 -p 埠對映

# 1  -p引數:埠對映  容器中啟動一個mysql5.7 --》容器中的3306監聽,宿主機3306沒人監聽,做埠對映後,宿主機的3306就被docker的這個容器監聽了

# 2 小案例,執行一個mysql容器--》做埠對映
docker run -id --name=mysql5.7 -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
#  -p : 啟動mysql容器  -p 宿主機埠:容器埠
#  -e : 啟動的mysql的root密碼是123456
# 以後臺守護程序執行mysql容器,mysql的root使用者密碼是123456,宿主機和容器做了埠對映
	宿主機 3307 對映容器 3306

    
## 2.1 檢視宿主機 3307埠占用情況

    #  netstat -nlp |grep 3307 檢視本機80埠占用情況
    # 檢視宿主機 3307埠占用情況
    yum install net-tools -y
    netstat -nlp | grep 3307 # 被docker佔了

## 2.2 遠端連結宿主機的3307埠
	以後訪問宿主機3307埠就等於訪問容器的3306埠

    # win機器可以遠端連結 mysql
        -命令列連結:mysql -h 10.0.0.110 -P 3307 -uroot -p
        -Navicate: 連結,建立lqz資料庫

    # 宿主機--》進入到容器內部--》進入到mysql,檢視有沒有建立lqz這個庫
        docker exec -it mysql5.7 /bin/bash # 進入容器內部
        mysql -uroot  -p  # 進入mysql
        show databases;  # 檢視所有資料庫

4.5 其他操作

#1 啟動容器
	docker start 容器id
#2 停止容器
	docker stop 容器id

#3 mysql的容器底層的作業系統是 debian 裝軟體需要用 
    apt-get update
    apt-get install vim -y


#4 檔案複製(宿主機執行)
	# 容器的檔案copy到宿主機上(不是在容器內執行)
    docker cp 容器名稱:容器目錄 需要複製的檔案或目錄
    docker cp  0a9633190cb9:/xx.txt /root/lqz/lqz.txt
    
    # 宿主機的檔案copy到容器中
    docker cp 需要複製的檔案或目錄 容器名稱:容器目錄
    docker cp /root/lqz/xx.txt  0a9633190cb9:/xx.txt

        
# 5 檢視容器IP地址    
	docker inspect 容器名稱  # 檢視容器的詳細描述,很多
    docker inspect 容器id/名稱 --format='{{.NetworkSettings.IPAddress}}' 容器名稱(容器ID)
    
    
# 6 在多個容器之間是可以ping通的(容器和宿主機也可以)
    # python:172.17.0.3

    # mysql5.7:172.17.0.2

    # 宿主機--》ping 它倆
    # 容器--》容器
    apt-get install iputils-ping
     ping 172.17.0.2

# 7 刪除容器(刪除已停止的容器)
	docker rm 容器id  
    docker rm `docker ps -a -q`
    
   
# 8 無狀態的服務(在容器中儘量執行無狀態的服務)
    -mysql reids   有狀態,執行過程中產生資料,儲存,容器刪除,資料就沒了
    -uwsgi+django  無狀態的服務

    
# 9 補充
	1 ip地址  ip 
    	10.0.88.110
        10.0.0.111
        10.0.0.1
        10.0.11.1
    2 子網掩碼 mask
    	255.255.0.0
        
    3 閘道器 gatway
    	10.0.0.1

5 應用部署

5.1 mysql 部署

#0 dokcer 中部署mysql,以後不需要在宿主機上裝mysql
	

#1  沒有做目錄對映---》配置檔案--》表資料都在容器中---》一旦刪除--》所有都沒了
docker run -di --name=mysql -p 3308:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7


# 2 做目錄(配置檔案和資料檔案)和埠對映

# 做目錄對映:data檔案,配置檔案
# 建立資料夾
mkdir /mysql
mkdir /mysql/conf.d
mkdir /mysql/data/
vi /mysql/my.cnf
[client]
default-character-set=utf8
[mysqld]
user=mysql
character-set-server=utf8
default_authentication_plugin=mysql_native_password
secure_file_priv=/var/lib/mysql
expire_logs_days=7
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
max_connections=1000

docker run -id -v /mysql5.7/data/:/var/lib/mysql -v /mysql5.7/conf.d:/etc/mysql/conf.d -v /mysql5.7/my.cnf:/etc/mysql/my.cnf -p 3306:3306 --name mysql5.7 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7      
        
     
    
# 建立庫,建立表,插入資料

# 關閉容器,刪除容器,myslq的容器沒了,但是資料在宿主機上放著
 docker stop mysql2
 docker rm mysql2
##docker rm mysql -f  容器之間刪了

# 再執行起一個容器,做好目錄對映,資料都回來了
docker run  -di -v /mysql/data/:/var/lib/mysql -v /mysql/conf.d:/etc/mysql/conf.d -v /mysql/my.cnf:/etc/mysql/my.cnf -p 3307:3306 --name mysql2 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7 



# 補充  -e引數--》環境變數
	-不同映象提供不同引數
    -傳入後放入環境變數
    echo $MYSQL_ROOT_PASSWORD # 檢視值

5.2 redis部署

#1  拉取redis映象
docker pull redis  #最新
mkdir /root/data
vim /root/redis.conf

bind 0.0.0.0
daemonize NO
protected-mode yes
requirepass 123456



# 執行
#啟動容器時,執行的命令是什麼 redis-server /etc/redis/redis.conf

docker run -id  -p 6379:6379 --name redis -v /root/redis.conf:/etc/redis/redis.conf -v /root/data:/data redis  redis-server /etc/redis/redis.conf
       
    
# 在容器執行時,可以自己定製執行命名 舉例:docker run -id centos:centos7 ls
# 遠端連結redis操作

5.3 nginx部署

# 拉取nginx映象
docker pull nginx

# run起容器
# docker run -id --name nginx -p 80:80 nginx
    
# /usr/share/nginx/html
docker run -id --name nginx1 -p 8008:80 -v /root/html:/usr/share/nginx/html nginx
# 以後只需要修改宿主機的/root/html 路徑,看到頁面就是修改後的

6 遷移與備份

容器儲存為映象

# 容器儲存為映象步驟
# 執行一個centos容器
docker run -id --name centos centos:centos7

# 在容器中裝vim
docker exec -it centos /bin/bash
yum install vim -y

# 把容器做成映象(centos+vim)
			 (容器名字)
docker commit centos centos_vim_image

# 基於新構建的映象,執行成容器
docker run -id --name centos_vim centos_vim_image:latest

# 進入到容器中,檢視,軟體都在
docker exec -it bc83707ed025 /bin/bash


# 上傳映象步驟
# 給映象打個tag
docker tag 映象id  映象新名字(賬號名/映象名)

# 登入賬號
docker login

# 上傳
docker push 映象新名字

# 映象備份和恢復 備份成tar壓縮包
docker save -o centos_vim_image.tar centos_vim_img

# 把備份的映象load恢復
docker load -i centos_vim_image.tar

7 Dockerfile

Dockerfile是由一系列命令和引數構成的指令碼檔案

這些命令應用於基礎映象並最終建立一個新的映象

FROM 基礎映象 	      # 基於哪個基礎映象來構建

MAINTAINER heart 	 # 宣告映象的建立者

ENV key value 	     # 設定環境變數 (可以寫多條)

RUN command 	     # 是Dockerfile的核心部分(可以寫多條)

ADD source_dir/file dest_dir/file 	# 將宿主機的檔案複製到映象內,如果是一個壓縮檔案,將會在複製後自動解壓

COPY source_dir/file dest_dir/file 	# 和ADD相似,但是如果有壓縮檔案並不能解壓

WORKDIR heart 	# 設定工作目錄,執行起這個容器,來到的路徑就是這個路徑

CMD   # 啟動並執行容器執行的命令

image-20240621152453316

image-20240621152508358

案例1

vim Dockerfile

FROM centos:centos7
MAINTAINER heart
ENV name heart
ARG age 18
RUN mkdir /heart
RUN touch /heart/test.py
RUN echo 'print(1)' > /heart/test.py
RUN echo $name
RUN echo $age
WORKDIR /heart

# 基於dockerfile構建映象,不要忘了 .   基於當前路徑下的Dockerfile 構建映象
docker build -t='centos_heart_vim' . 
docker images

# 基於這個映象執行容器
docker run -id --name centos77 centos_heart_vim

# 進入到容器
docker exec -it xx /bin/bash

# 驗證vim,和資料夾,檔案是否存在

案例2

FROM centos:centos7
MAINTAINER heart
ENV name heart
RUN mkdir /heart
RUN touch /heart/test1.py
RUN echo 'input()' > /heart/test1.py
WORKDIR /heart
CMD ['python' ,'./test1.py'] # 執行容器時會預設加上 /bin/sh -c




# 基於dockerfile構建映象,不要忘了 .
docker build -t='centos_py' . 
docker images
# 基於這個映象執行容器
docker run -id --name yy centos_py python /heart/ss.py
# 進入到容器
docker exec -it xx /bin/bash
# 檢視環境變數
# python看
os.environ.get('name')
# shell看
echo $name

7.1 常用和不常用命令

# 1 所有命令
https://zhuanlan.zhihu.com/p/419175543?utm_id=0

FROM: 指定基礎映象
RUN: 構建映象過程中需要執行的命令。可以有多條。docker build
CMD:新增啟動容器時需要執行的命令。多條只有最後一條生效。可以在啟動容器時被覆蓋和修改
ENTRYPOINT:同CMD,但這個一定會被執行,不會被覆蓋修改。
LABEL:表明映象的作者。將被遺棄,被LABEL代替。
EXPOSE:設定對外暴露的埠。
ENV:設定執行命令時的環境變數,並且在構建完成後,仍然生效
ARG:設定只在構建過程中使用的環境變數,構建完成後,將消失
ADD:將本地檔案或目錄複製到映象的檔案系統中。能解壓特定格式檔案,能將URL作為要複製的檔案
COPY:將本地檔案或目錄複製到映象的檔案系統中。
VOLUME:新增資料卷
USER:指定以哪個使用者的名義執行RUN, CMD 和ENTRYPOINT等命令
WORKDIR:設定工作目錄


# 2 docker logs 容器名字/id號  檢視映象執行成容器時,錯誤日誌
	-如果容器沒起來,看日誌排查錯誤

    
# 3 CMD  ENTRYPOINT  --https://zhuanlan.zhihu.com/p/548188679
#相同點:
只能寫一條,如果寫了多條,那麼只有最後一條生效。
容器啟動時才執行,執行時機相同。
# 不同點:
ENTRYPOINT不會被執行的command覆蓋,而CMD則會被覆蓋。
如果我們在Dockerfile中同時寫了ENTRYPOINT和CMD,並且CMD指令不是一個完整的可執行命令,那麼CMD指定的內容將會作為ENTRYPOINT的引數


# 4 ARG 和 ENV 
ENV:設定執行命令時的環境變數,並且在構建完成後,仍然生效
ARG:設定只在構建過程中使用的環境變數,構建完成後,將消失

7.2 dockerfile構建一個djagno專案

# 以圖書管理系統為例---》公司使用docker流程

# 公司中,使用Docker開發的工作流程
# 1 有一個專案,pycharm開發著,開發完後
# 2 在專案路徑下新建Dockerfile,寫入
FROM python
LABEL author="heart"
WORKDIR /soft
COPY ./requirements.txt /soft/requirements.txt
RUN pip install -r requirements.txt -i https://pypi.doubanio.com/simple
CMD ["python","manage.py","runserver","0.0.0.0:8080"]
# 3 把程式碼提交到git

# 4 在上線機器上,把程式碼克隆下來
git clone https://gitee.com/heart99999/bbs.git
    
# 5 構建映象
docker build -t='bbs' . # 要在目錄中build 我這裡是在project/books中

# 6 執行容器
docker run -id --name=bbs -v /home/heart/bbs:/soft -p 8088:8080 bbs:latest
            
# 7 其它人訪問宿主機的8080埠就能看到專案了
# 8 開發人員繼續提交程式碼
# 9 運維人員pull程式碼,重啟容器,使用者就可以看到最新的了
# 重啟docker容器即可
docker restart 名字
# 如果第三方依賴變了,必須重寫構建映象,再執行容器

7.3 烏班圖構建redis(跟底層宿主機無關)

https://zhuanlan.zhihu.com/p/623811065

8 docker 私有倉庫

8.1 映象傳到官方倉庫

# 第0步:在遠端建立倉庫
# 第一步:給映象打標籤
	docker tag 086e6b3e71c0 heart99/heart_books:v1
# 第二步:登入到遠端
	docker login
    
# 第三步:提交
	docker push heart99/heart_books:v1
        
# 第四步:別人就可以下載了
	docker pull heart99/heart_books:v1

8.2 映象分層

# 每一個Dockerfile命令都會構建一層映象(本質上是每一層都會啟動一個容器,執行完命令後,將容器進行提交,透過檢視下載下來的映象,發現歷史層資訊的層ID是missing,其實是因為原本的層id只存在於構建映象的宿主機上,一旦轉移映象後,歷史層訊息中將只保留最新一層的ID


# 只要執行一個命令就會多一層
RUN yum install vim -y
RUN yum install git -y


# 檢視映象分層的命令
docker history heart99/heart_books:v1
# 好處:
構建快,分發方便,如果本地有某一層了,這一層就不需要下載了


# 補充:Dcokerfile寫命令,建議多條命令合為一條---》只會生成一層
RUN python -m pip install --upgrade pip &&\
python -m pip install --upgrade setuptools &&\
pip install -r requirements.txt

8.3 私有倉庫搭建

# 自己搭建私有倉庫
	-harbor:企業級私有倉庫---》(有圖形化介面--》跟hub.docker 很像)		https://blog.csdn.net/weixin_47085247/article/details/129237979
    
 
    
-registry:用docker搭建私有倉庫(沒有圖形化介面)
    
# 搭建步驟:(使用docker搭建docker私有倉庫

# 1 拉取映象 docker pull registry

# 2 執行容器 就是一個web服務端 從瀏覽器中訪問它
docker run -id --name=registry -p 5000:5000 registry

# 3 開啟瀏覽器 輸入地址http://10.0.0.101:5000/v2/_catalog看到{"repositories":[]} 表示私有倉庫搭建成功並且內容為空

# 4 修改daemon.json
vi /etc/docker/daemon.json
{
    "insecure-registries":["10.0.0.101:5000"]
} 

# 5 重啟docker 讓配置生效
systemctl restart docker
docker start registry

# 6 把某個映象tag成私有倉庫的映象
docker tag 映象名字/id 10.0.0.101:5000/django_books:v1
docker tag django_books:latest 10.0.0.101:5000/django_books:v1
            
# 7 提交到私有倉庫
docker push 10.0.0.101:5000/django_books:v1
        
# 8 其他人,只要配置了私有倉庫就可以直接拉取
docker pull 10.0.0.101:5000/django_books:v1
docker run -id --name=books -v /root/project/books:/soft -p 8080:8080 10.0.0.101:5000/django_books:v1

9 harbor私有倉庫搭建

https://blog.csdn.net/weixin_47085247/article/details/129237979

9.1 CentOS7安裝DockerCompose

# linux下載
curl -L https://github.com/docker/compose/releases/download/1.29.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

# 修改檔案許可權
chmod +x /usr/local/bin/docker-compose

# Base自動補全命令
curl -L https://raw.githubusercontent.com/docker/compose/1.29.1/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose
# 如果這裡出現錯誤,需要修改自己的hosts檔案:
# echo "199.232.68.133 raw.githubusercontent.com" >> /etc/hosts

9.2 Harbor安裝與部署

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

這裡我使用的是v2.4.1版本

# wget下載 (不推薦)
wget https://github.com/goharbor/harbor/releases/download/v2.4.1/harbor-offline-installer-v2.4.1.tgz

# 下載完scp到伺服器中
scp C:\Users\heart\Desktop\harbor-offline-installer-v2.4.1.tgz root@192.168.126.128:/home/harbor/

9.2.1 安裝

# 解壓下載好的包 在同目錄下會生成一個harbor資料夾
tar xvf harbor-offline-installer-v2.4.1.tgz

# 如果有證書,還需要解壓證書包
unzip 證書.zip
# 解壓後會生成一個證書檔案和金鑰檔案
# 將證書檔案和金鑰檔案全部移到harbor資料夾裡
# mv 證書 harbor
# mv 金鑰 harbor

# 進入harbor資料夾,會看到harbor.yml.tmpl檔案,重新命名它
mv harbor.yml.tmpl harbor.yml

# 開啟
vi harbor.yml

image-20240622145713215

注:證書金鑰路徑為絕對路徑,例如:

image-20240622145729964

9.2.2 執行

執行預備工具

./prepare

執行指令碼

./install.sh

一共是9個容器

docker ps #檢視容器

image-20240622145835085

9.2.3 訪問

http://192.168.126.128/ 檔案裡配置的地址 80埠

使用者名稱 : admin

密碼 : 檔案中配置的密碼

image-20240622145853815

新增域名

vi /etc/hosts

image-20240622145955075

前面是ip地址,後面是域名

9.3 Harbor使用

9.3.1 修改docker daemon.json檔案

vi /etc/docker/daemon.json
cat /etc/docker/daemon.json
{
    "insecure-registries":["#域名或者IP地址"]
}

重啟載入daemon.json配置

systemctl daemon-reload

重啟docker

systemctl restart docker

檢視docker容器個數

docker ps

發現只啟動了5個容器

回到harbor檔案

cd /home/harbor

把已經啟動的容器停下來並刪除

docker-compose down

啟動docker容器,並在後臺進行

docker-compose up -d

重新數一下docker容器個數

docker ps

如果其他主機要使用harbor,也要修改docker daemon.json檔案並重啟

9.3.2 映象上傳與拉取

映象打包

docker tag centos:latest 域名或IP地址/專案庫名/centos:版本號

# docker tag 需要打標籤的映象 域名或者ip地址/庫名/新名字
# docker tag django_books:latest 192.168.126.128/library/books:latest

映象推送到Harbor,要先登入

docker login 域名或ip地址

推送

這個地方直接寫剛才打標籤的新名字即可

docker push 192.168.126.128/library/books:latest

image-20240622150753007

拉取

直接複製

docker pull 192.168.126.128/library/books@sha256:6511a562ecca0ad2d04f8a562679396e86cb7933b29ebaed726f0c0e579932b5

image-20240622150810225

10 docker-compose

使用docker會面臨一個比較大的問題:如果一個djagno專案使用mysql、redis,不要一次性把所有服務都放到一個容器

中,每個服務一個容器,批次的管理多個容器,比較難以操作,於是有了docker-compose。

Docker Compose是一個能一次性定義和管理多個Docker容器的工具,單機容器編排【定義和管理】

Docker Compose概念

Compose中定義和啟動的每一個容器都相當於一個服務(service)

Compose中能定義和啟動多個服務,且它們之間通常具有協同關係

管理方式:

使用YAML檔案來配置我們應用程式的服務。

使用單個命令(docker-compose up),就可以建立並啟動配置檔案中配置的所有服務。

10.1 安裝

https://github.com/docker/compose/releases

#wget https://github.com/docker/compose/releases/download/v2.15.1/docker-compose-linux-x86_64 (不推薦)

# 直接 命令列中 rz 上傳
cp ./docker-compose-linux-x86_64 /usr/local/bin/docker-compose # 想在任意路徑下執行docker-compose都有相應----》需要把可執行檔案放到環境變數所在的目錄下
chmod +x /usr/local/bin/docker-compose
# 以後在任意位置敲docker-compose都可以


  r--    ---    ---
# rwx    rwx    rwx
  屬主   屬組    其他
  r:read 讀許可權 
  w:wirte 寫許可權
  x :執行許可權

 屬主   屬組  所有人
 chmod 777 檔名
 chmod +x 

    
  rwx  r-x   -wx
  111  101   011 
  chmod 753 檔名

# epel源
	-yum install centos倉庫下載
    -軟體不全
    -epel源 擴充套件源 
    	nginx
        redis
        python

10.2 常用命令

# 啟動管理容器
docker-compose up                                 # 會自動搜尋當前路徑下的 docker-compose.yml檔案
docker-compose -f 指定檔案 up
docker-compose up -d                              # 後臺執行,一般我們看日誌輸出,不用這個
docker-compose stop                               # 停止,不會刪除容器和映象
docker-compose down                               # 停止,並刪除關聯的容器
docker-compose start                              # 啟動yml檔案管理的容器
docker-compose ps                                 # 正在執行的容器
docker-compose images                             # docker-compose管理的映象
docker-compose exec yml檔案中寫的service /bin/bash  # 進入到容器內
docker-compose up -d --build 		              # 啟動容器但是重新構建映象,基於重新構建的映象啟動
docker-compose version 				              # 檢視docker版本

10.3 部署flask

10.3.1 新建flask專案

from flask import Flask
from redis import Redis
import os

app = Flask(__name__)
# redis = Redis(host=os.environ.get('REDIS_HOST', '127.0.0.1'), port=6379)
redis = Redis(host='redis', port=6379,decode_responses=True) # 容器的主機名---》flask容器和redis容器是能ping通的,可以透過ip ping 也可以透過主機名ping

@app.route('/')
def hello():
    redis.incr('hits')
    return '你好! 檢視 %s 次\n' % (redis.get('hits'))


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000, debug=True)

10.3.2 編寫Dockerfile

FROM python:3.8
WORKDIR /app
COPY . /app
RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
EXPOSE 5000
CMD [ "python", "app.py" ]

# 構建出映象---》一會統一使用 docker-compose構建

10.3.3 編寫yml檔案

version: "3"
services:
  redis: # 啟動一個redis容器
    image: redis
  web:   # 啟動web容器
    build: # 構建映象
      context: .
      dockerfile: Dockerfile
    ports: # -p 埠轉發
      - 8080:5000
    environment: # 環境變數
      REDIS_HOST: redis

10.3.4 編寫requirements.txt

flask
redis

10.3.5 一鍵啟動

docker-compose up

image-20240624190420755

image-20240624190408705

10.4 一鍵部署django專案

# 一臺伺服器:
	-python3.8 環境 djagno +uwsgi+程式碼
    -nginx軟體
    -mysql 5.7
    -redis 

# 每個都做成一個容器
	-djagno專案容器:python3.8 構建的django,專案依賴模組,uwsgi,程式碼
    -nginx容器:目錄對映,對映到宿主機,代理vue前端,編譯後的靜態檔案
    -mysql 容器:建立,創使用者,密碼,luffy庫,做目錄對映,儲存資料,跑起來
    -redis 容器,做目錄對映,儲存資料,跑起來

目錄結構

luffy
    docker_compose_files    # 放資料的資料夾(配置,目錄對映)
    luffy_api  				# 後臺專案
    	luffy_api           # 後臺專案
    	Dockerfile          # 構建映象檔案
    luffy_front  			# 前端專案 刪除node_modules和dist 重新構建
    docker-compose.yml 		# ymal檔案

image-20240624192210688

修改前端,後端的地址

前端 settings.js

const BASE_URL = 'http://192.168.126.128:8080/api/v1/'

後端 pro.py

BACKEND_URL = "http://192.168.126.128:8080/"

LUFFY_URL = "http://192.168.126.128"

編譯前端檔案

編譯完成後提交到git

cnpm install
cnpm run build

git clone https://gitee.com/heart99999/docker-compose-luffy.git

docker-compose up

10.4.1 docker_compose_files 配置檔案

docker_compose_files/nginx/default.conf

server {
  listen 80; # 監聽80埠,用於處理HTTP請求
  server_name 127.0.0.1; # 伺服器名為127.0.0.1,本地地址
  charset utf-8; # 設定字元編碼為UTF-8

  location / {
    root /var/www/html; # 設定根目錄為/var/www/html
    index index.html; # 預設首頁檔案為index.html
    try_files $uri $uri/ /index.html; # 解決單頁面應用重新整理404問題,嘗試找到檔案,如果找不到則返回index.html
  }
}

server {
  listen 8000; # 監聽8000埠,用於處理HTTP請求
  server_name 127.0.0.1; # 伺服器名為127.0.0.1,本地地址
  charset utf-8; # 設定字元編碼為UTF-8

  location / {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 設定X-Forwarded-For頭部,記錄客戶端的原始IP地址
    proxy_set_header Host $http_host; # 設定Host頭部,保留原始主機頭
    proxy_redirect off; # 關閉代理重定向
    proxy_pass http://luffy_django:8080; # 將請求轉發到http://luffy_django:8080
  }

  location /static {
    alias /home/project/luffy_api/luffy_api/static; # 將/static路徑下的請求對映到/home/project/luffy_api/luffy_api/static目錄
  }
}

docker_compose_files/redis/redis.conf

bind 0.0.0.0
# 繫結所有網路介面,使得 Redis 可以接受來自任何網路介面的連線

port 6379
# 設定 Redis 伺服器監聽的埠號為 6379

daemonize no
# 指定是否以守護程序方式執行 Redis,如果設定為 "no",Redis 將在前臺執行

pidfile /var/run/redis_6379.pid
# 指定 Redis 程序的 PID 檔案路徑

databases 16
# 設定 Redis 例項中的資料庫數量,預設是 16 個資料庫

save 900 1
# 如果 900 秒(15 分鐘)內至少有 1 個鍵發生變更,則執行一次持久化操作

save 300 10
# 如果 300 秒(5 分鐘)內至少有 10 個鍵發生變更,則執行一次持久化操作

save 60 10000
# 如果 60 秒(1 分鐘)內至少有 10000 個鍵發生變更,則執行一次持久化操作

dbfilename dump.rdb
# 指定持久化檔案的名字,預設是 "dump.rdb"

dir ./
# 指定持久化檔案的儲存路徑,"./" 表示當前目錄

docker_compose_files/mysql.env

MYSQL_ROOT_PASSWORD=heart12345
# 設定 MySQL root 使用者的密碼為 "heart12345"

MYSQL_DATABASE=luffy
# 建立一個名為 "luffy" 的資料庫

MYSQL_USER=luffy
# 建立一個名為 "luffy" 的使用者

MYSQL_PASSWORD=Luffy123?
# 設定 "luffy" 使用者的密碼為 "Luffy123?"

TZ=Asia/Shanghai
# 設定時區為亞洲/上海

10.4.2 luffy_api

luffy_api/Dockerfile

# 依賴映象名稱和id
FROM python:3.8
# 使用 Python 3.8 作為基礎映象

# 指定映象建立者資訊
LABEL name="heart"
# 新增一個標籤,標記映象建立者為 "heart"

RUN mkdir /soft
# 建立一個名為 /soft 的目錄

WORKDIR /soft
# 設定工作目錄為 /soft

COPY ./requirements.txt /soft/requirements.txt
# 將本地的 requirements.txt 檔案複製到映象的 /soft 目錄中

RUN pip install --no-cache-dir -r requirements.txt -i https://pypi.doubanio.com/simple
# 使用 Douban 的映象源安裝 requirements.txt 中列出的 Python 依賴項,不使用快取

CMD ["uwsgi","./luffy.ini"]
# 使用 uwsgi 啟動應用,使用配置檔案 luffy.ini

luffy_api/luffy.ini

[uwsgi]
chdir = /soft
# 設定工作目錄為 /soft

master = true
# 啟用主程序管理模式

wsgi-file = luffy_api/wsgi.py
# 指定 WSGI 檔案為 luffy_api/wsgi.py

http = 0.0.0.0:8080
# 監聽 0.0.0.0 地址的 8080 埠

chmod-socket = 755
# 設定 socket 檔案的許可權為 755

processes = 2
# 啟動 2 個工作程序

pidfile = /soft/luffy_api/uwsgi.pid
# 將 uWSGI 伺服器的 PID 檔案儲存到 /soft/luffy_api/uwsgi.pid

# 設定緩衝
post-buffering = 4096
# 啟用 4096 位元組的 POST 資料緩衝區

luffy_api/requirements.txt

amqp==5.2.0
asgiref==3.8.1
async-timeout==4.0.3
billiard==4.2.0
celery==5.4.0
certifi==2024.2.2
cffi==1.16.0
charset-normalizer==3.3.2
click==8.1.7
click-didyoumean==0.3.1
click-plugins==1.1.1
click-repl==0.3.0
colorama==0.4.6
cron-descriptor==1.4.3
cryptography==42.0.7
Django==3.2
django-celery-beat==2.6.0
django-celery-results==2.5.1
django-cors-headers==4.3.1
django-filter==24.2
django-redis==5.4.0
django-simpleui==2024.4.1
django-timezone-field==6.1.0
djangorestframework==3.15.1
djangorestframework-simplejwt==5.3.1
dnspython==2.6.1
eventlet==0.36.1
flower==2.0.1
gevent==24.2.1
greenlet==3.0.3
humanize==4.9.0
idna==3.7
kombu==5.3.7
loguru==0.7.2
mysqlclient==2.2.4
pillow==10.3.0
prometheus_client==0.20.0
prompt-toolkit==3.0.43
pycparser==2.22
pycryptodomex==3.20.0
PyJWT==2.8.0
pyOpenSSL==24.1.0
python-alipay-sdk==3.3.0
python-crontab==3.0.0
python-dateutil==2.9.0.post0
pytz==2024.1
redis==5.0.4
requests==2.31.0
six==1.16.0
sqlparse==0.5.0
tencentcloud-sdk-python==3.0.1145
tornado==6.4
typing_extensions==4.11.0
tzdata==2024.1
urllib3==2.2.1
vine==5.1.0
wcwidth==0.2.13
win32-setctime==1.1.0
zope.event==5.0
zope.interface==6.4
uwsgi

10.4.3 docker-compose.yml

version: "3"
# Docker Compose 檔案的版本

services:
  nginx:
    image: nginx
    # 使用官方的 Nginx 映象

    container_name: luffy_nginx
    # 設定容器名稱為 luffy_nginx

    ports:
      - "80:80"
      # 將主機的 80 埠對映到容器的 80 埠

      - "8000:8000"
      # 將主機的 8000 埠對映到容器的 8000 埠

    restart: always
    # 配置容器總是重啟

    volumes:
      - ./luffy_front/dist:/var/www/html
      # 將主機的 ./luffy_front/dist 目錄掛載到容器的 /var/www/html 目錄

      - ./docker_compose_files/nginx:/etc/nginx/conf.d
      # 將主機的 ./docker_compose_files/nginx 目錄掛載到容器的 /etc/nginx/conf.d 目錄

    depends_on:
      - django
      # 依賴於 django 服務

    networks:
      - web
      # 使用名為 web 的網路

  django:
    build:
      context: ./luffy_api
      # 構建上下文為 ./luffy_api 目錄

      dockerfile: Dockerfile
      # 使用 Dockerfile 檔案

    container_name: luffy_django
    # 設定容器名稱為 luffy_django

    # command: python manage_pro.py makemigrations && python manage_pro.py migrate && uwsgi ./luffy.ini
    # 註釋掉的命令,用於在啟動時進行資料庫遷移和啟動 uwsgi 服務

    restart: always
    # 配置容器總是重啟

    ports:
      - "8080:8080"
      # 將主機的 8080 埠對映到容器的 8080 埠

    volumes:
      - ./luffy_api:/soft
      # 將主機的 ./luffy_api 目錄掛載到容器的 /soft 目錄

    environment:
      - TZ=Asia/Shanghai
      # 設定環境變數,時區為亞洲/上海

    depends_on:
      - mysql
      - redis
      # 依賴於 mysql 和 redis 服務

    networks:
      - web
      # 使用名為 web 的網路

  redis:
    image: redis:6.0-alpine
    # 使用 Redis 6.0 Alpine 版映象

    container_name: luffy_redis
    # 設定容器名稱為 luffy_redis

    ports:
      - "6379:6379"
      # 將主機的 6379 埠對映到容器的 6379 埠

    volumes:
      - ./docker_compose_files/redis/data:/data
      # 將主機的 ./docker_compose_files/redis/data 目錄掛載到容器的 /data 目錄

      - ./docker_compose_files/redis/redis.conf:/etc/redis/redis.conf
      # 將主機的 ./docker_compose_files/redis/redis.conf 檔案掛載到容器的 /etc/redis/redis.conf

    command: redis-server /etc/redis/redis.conf
    # 使用指定的配置檔案啟動 Redis 伺服器

    networks:
      - web
      # 使用名為 web 的網路

  mysql:
    image: mysql:8.0
    # 使用 MySQL 8.0 映象

    container_name: luffy_mysql
    # 設定容器名稱為 luffy_mysql

    restart: always
    # 配置容器總是重啟

    ports:
      - "3306:3306"
      # 將主機的 3306 埠對映到容器的 3306 埠

    env_file:
      - ./docker_compose_files/mysql.env
      # 使用主機的 ./docker_compose_files/mysql.env 檔案作為環境變數

    volumes:
      - ./docker_compose_files/mysql/data:/var/lib/mysql
      # 將主機的 ./docker_compose_files/mysql/data 目錄掛載到容器的 /var/lib/mysql 目錄

      - ./docker_compose_files/mysql/logs:/var/log/mysql
      # 將主機的 ./docker_compose_files/mysql/logs 目錄掛載到容器的 /var/log/mysql 目錄

      - ./docker_compose_files/mysql/conf:/etc/mysql/conf.d
      # 將主機的 ./docker_compose_files/mysql/conf 目錄掛載到容器的 /etc/mysql/conf.d 目錄

    networks:
      - web
      # 使用名為 web 的網路

networks:
  web:
    # 定義一個名為 web 的網路

11 遠端連線linux開發

vscode連線需要pylance才會有程式碼提示

ssh 使用者名稱@ip地址

相關文章