Docker倉(cāng)庫(kù)管理鏡像 -- 公共倉(cāng)庫(kù)【Docker Hub】和私人倉(cāng)庫(kù)【Registry】和【harbor】

鏡像倉(cāng)庫(kù)管理

docker倉(cāng)庫(kù),用來(lái)管理鏡像。主要分為公共倉(cāng)庫(kù)和私人倉(cāng)庫(kù)。下面介紹了公共倉(cāng)庫(kù)Docker Hub、私人倉(cāng)庫(kù)Registry和harbor。

DockerHUb倉(cāng)庫(kù)管理

什么是DockerHUb

保存和分發(fā)鏡像的最直接方法就是使用 Docker Hub。

    Docker Hub 是 Docker 公司維護(hù)的公共 Registry。用戶(hù)可以將自己的鏡像保存到 Docker Hub 免費(fèi)的 repository 中,如果不希望別人訪問(wèn)自己的鏡像,也可以購(gòu)買(mǎi)私有 repository。
賬號(hào)注冊(cè)和登陸

一般,你需要先在docker中心創(chuàng)建一個(gè)賬戶(hù)(如果您尚未有)。你可以直接在Docker Hub創(chuàng)建你的賬戶(hù)。

file

如果有已有賬號(hào)可以點(diǎn)擊sign in 進(jìn)行登錄,登陸后是這個(gè)樣子

file
Docker客戶(hù)端登錄

使用docker login登錄dockerhub

    這將提示您輸入用戶(hù)名,這個(gè)用戶(hù)名將成為你的公共存儲(chǔ)庫(kù)的命名空間名稱(chēng)。如果你的名字可用,docker會(huì)提示您輸入一個(gè)密碼和你的郵箱,然后會(huì)自動(dòng)登錄到Docker Hub,你現(xiàn)在可以提交和推送鏡像到Docker Hub的你的存儲(chǔ)庫(kù)。
docker login
file

出現(xiàn) Login Succeeded就說(shuō)明我們登錄成功

注:你的身份驗(yàn)證憑證將被存儲(chǔ)在你本地目錄的.dockercfg文件中

管理鏡像

通過(guò)docker images可以看到我們所有的鏡像列表

docker images
刪除鏡像

我們現(xiàn)在的learn-docker-storage有三個(gè)版本,現(xiàn)在我們把前兩個(gè)有問(wèn)題的版本刪除,docker rmi 鏡像ID可以刪除鏡像

docker rmi learn-docker-storage:0.0.1 learn-docker-storage:0.0.2
file

這樣我們就刪除了我們沒(méi)有用的鏡像了,可以節(jié)省內(nèi)存空間

修改鏡像命名

修改鏡像的 repository 使之與 Docker Hub 賬號(hào)匹配。

    Docker Hub 為了區(qū)分不同用戶(hù)的同名鏡像,鏡像的 registry 中要包含用戶(hù)名,完整格式為:`[用戶(hù)名]/鏡像名:tag`

我們通過(guò) docker tag 命令重命名鏡像

docker tag learn-docker-storage:0.0.3 baiyp/learn-docker-storage:0.0.3
file

這樣就將我們的鏡像改名了,這個(gè)就符合我們的dockerhub的規(guī)范了

推送鏡像
推送鏡像

現(xiàn)在我們要將我們的鏡像推送到docker hub

推送鏡像的規(guī)范是docker push 注冊(cè)用戶(hù)名/鏡像名:tag,因?yàn)槲覀兩厦嬉呀?jīng)把鏡像名字改正確了,所以可以直接推送。

docker push baiyp/learn-docker-storage:0.0.3
file

這樣我們就將我們的數(shù)據(jù)推送到docker hub,我們發(fā)現(xiàn)只有最頂層的鏡像推送了,openjdk的鏡像并沒(méi)有推送,直接復(fù)用了倉(cāng)庫(kù)的,這就是分層的好處

檢查鏡像

我們可以到docker hub檢查我們的鏡像

file

可以看到我們的鏡像已經(jīng)推送過(guò)來(lái)了,點(diǎn)開(kāi)詳情可以看到我們鏡像的內(nèi)容以及tag號(hào)

file
倉(cāng)庫(kù)鏡像測(cè)試
刪除本地鏡像

可以通過(guò)docker rmi 鏡像ID刪除本地鏡像

docker rmi baiyp/learn-docker-storage:0.0.3 learn-docker-storage:0.0.3
file

再次查看本地鏡像,已經(jīng)沒(méi)有了我們的微服務(wù)的鏡像

docker images
file
從倉(cāng)庫(kù)拉取鏡像

這個(gè)時(shí)候可以從docker hub拉取鏡像

docker pull baiyp/learn-docker-storage:0.0.3
file

這個(gè)時(shí)候已經(jīng)將鏡像拉取下來(lái)了,我們可以運(yùn)行鏡像了

運(yùn)行鏡像

執(zhí)行下面的命令進(jìn)行創(chuàng)建鏡像

docker run -d \
-v /tmp/data/logs:/logs \
-p 8003:8003 \
--name learn-docker-storage \
--network=learn-docker-network \
baiyp/learn-docker-storage:0.0.3
file
訪問(wèn)測(cè)試

我們?cè)L問(wèn)下,檢查下是否可以正常運(yùn)行

 curl http://192.168.64.153:8003/storage/employe/findByID/10001 | python -m json.tool
file

到這里我們就完成dockerhub倉(cāng)庫(kù)的發(fā)布與拉取

直接運(yùn)行測(cè)試

在真實(shí)環(huán)境中,我們一般不會(huì)拉取在運(yùn)行,一般都是直接運(yùn)行,如果docker檢查鏡像不存在會(huì)自動(dòng)拉取

停止服務(wù)并刪除鏡像

 docker rm -f learn-docker-storage
 docker rmi baiyp/learn-docker-storage:0.0.3
file

我們直接運(yùn)行容器

docker run -d \
-v /tmp/data/logs:/logs \
-p 8003:8003 \
--name learn-docker-storage \
--network=learn-docker-network \
baiyp/learn-docker-storage:0.0.3
file

這一個(gè)run命令就解決了容器的拉取以及容器運(yùn)行的問(wèn)題

registry倉(cāng)庫(kù)管理

registry簡(jiǎn)介
    官方提供了Docker Hub網(wǎng)站來(lái)作為一個(gè)公開(kāi)的集中倉(cāng)庫(kù)。然而,本地訪問(wèn)Docker Hub速度往往很慢,并且很多時(shí)候我們需要一個(gè)本地的私有倉(cāng)庫(kù)只供網(wǎng)內(nèi)使用。

    Docker倉(cāng)庫(kù)實(shí)際上提供兩方面的功能,一個(gè)是鏡像管理,一個(gè)是認(rèn)證。前者主要由docker-registry項(xiàng)目來(lái)實(shí)現(xiàn),通過(guò)http服務(wù)來(lái)上傳下載;后者可以通過(guò)docker-index(閉源)項(xiàng)目或者利用現(xiàn)成認(rèn)證方案(如nginx)實(shí)現(xiàn)http請(qǐng)求管理。  

    docker registry 就是管理 docker 鏡像的服務(wù), Docker 公司維護(hù)的 registry 就是 http://hub.docker.com ,它可以讓我們方便的下載預(yù)先做好的鏡像。
安裝registry

我們可以通過(guò)獲取官方的 registry 鏡像來(lái)運(yùn)行。

    這將使用官方提供的 `registry` 鏡像來(lái)啟動(dòng)私有倉(cāng)庫(kù),默認(rèn)情況下,倉(cāng)庫(kù)會(huì)被創(chuàng)建在容器的 `/var/lib/registry` 目錄下。我們可以通過(guò) `-v` 參數(shù)將鏡像文件存放在本地的指定路徑。
docker run -d \
-p 5000:5000 \
-v /tmp/data/registry:/var/lib/registry \
--restart=always \
registry
file

這樣我們的registry已經(jīng)啟動(dòng)起來(lái)了

訪問(wèn)測(cè)試

這時(shí)我們可以通過(guò)瀏覽器訪問(wèn) http://ip:5000/v2/_catalog 查看倉(cāng)庫(kù)是否啟動(dòng)成功。

curl http://192.168.64.152:5000/v2/_catalog
file
上傳鏡像

registry 上傳鏡像的命名規(guī)范是 倉(cāng)庫(kù)IP:5000/鏡像名稱(chēng):tag

修改鏡像名稱(chēng)

將我們的鏡像改成服務(wù)規(guī)范的名字

docker tag baiyp/learn-docker-storage:0.0.3 192.168.64.153:5000/learn-docker-storage:0.0.3
file
推送鏡像

使用命令推送鏡像

docker push 192.168.64.153:5000/learn-docker-storage:0.0.3

我們發(fā)現(xiàn)推送報(bào)錯(cuò)了,這是因?yàn)閐ocker推送默認(rèn)使用的https的方式,而我們的registry只支持http的方式

file
修改Docker推送配置

對(duì)于 Linux 系統(tǒng),我們可以在 /etc/docker/daemon.jsondaemon.josn 文件不存在則新建該文件)

 vi /etc/docker/daemon.json

添加下面的配置

{ "insecure-registries": ["倉(cāng)庫(kù)IP:5000"] }

完整的配置如下

{
  "insecure-registries": ["192.168.64.153:5000"],
  "registry-mirrors": ["https://xxxxx.mirror.aliyuncs.com"]
}

執(zhí)行以下命令重啟重新加載配置并生效

systemctl daemon-reload
service docker restart
file
再次進(jìn)行推送

執(zhí)行命令再次推送

docker push 192.168.64.153:5000/learn-docker-storage:0.0.3
file

我們發(fā)現(xiàn)這次推送成功了

再次訪問(wèn)registry

訪問(wèn)測(cè)試檢查是否已經(jīng)推送

curl http://192.168.64.153:5000/v2/_catalog | python -m json.tool
file

我們發(fā)現(xiàn)我們的鏡像已經(jīng)推送到了registry,我們通過(guò)以下URL訪問(wèn)下tag列表

curl http://192.168.64.153:5000/v2/learn-docker-storage/tags/list | python -m json.tool
file
registry鏡像測(cè)試
刪除本地鏡像

可以通過(guò)docker rmi 鏡像ID刪除本地鏡像

docker rmi baiyp/learn-docker-storage:0.0.3 192.168.64.153:5000/learn-docker-storage:0.0.3
file
運(yùn)行registry中的鏡像
docker run -d \
-v /tmp/data/logs:/logs \
-p 8003:8003 \
--name learn-docker-storage \
--network=learn-docker-network \
192.168.64.153:5000/learn-docker-storage:0.0.3
file

我們發(fā)現(xiàn)自己的registry很快就拉取并且運(yùn)行起來(lái)了

訪問(wèn)微服務(wù)測(cè)試
 curl http://192.168.64.153:8003/storage/employe/findByID/10001 | python -m json.tool
file

使用Harbor管理倉(cāng)庫(kù)

什么是Harbor

harbor是一個(gè)由vm公司開(kāi)源的企業(yè)級(jí)容器鏡像倉(cāng)庫(kù),有以下功能

  • 管理用戶(hù)界面
  • 基于角色的訪問(wèn)控制
  • LDAP/AD 集成及日志審計(jì)等基本運(yùn)維操作
    harbor是構(gòu)建企業(yè)級(jí)私有docker鏡像的倉(cāng)庫(kù)的開(kāi)源解決方案,它是 Docker Registry的更高級(jí)封裝,它除了提供友好的Web UI界面,角色和用戶(hù)權(quán)限管理,用戶(hù)操作審計(jì)等功能外,它還整合了K8s的插件(Add-ons)倉(cāng) 庫(kù),即Helm通過(guò)chart方式下載,管理,安裝K8s插件,而chartmuseum 可以提供存儲(chǔ)chart數(shù)據(jù)的倉(cāng)庫(kù)。

    另外它還整合了兩個(gè)開(kāi)源的安全組件,一個(gè)是Notary,另一個(gè)是Clair,Notary類(lèi)似 于私有CA中心,而Clair則是容器安全掃描工具,它通過(guò)各大廠商提供的 CVE漏洞庫(kù)來(lái)獲取最新漏洞信息,并掃描用戶(hù)上傳的容器是否存在已知的 漏洞信息,這兩個(gè)安全功能對(duì)于企業(yè)級(jí)私有倉(cāng)庫(kù)來(lái)說(shuō)是非常具有意義的。
Harbor的三種安裝方式

這里我們使用離線安裝

  • 在線安裝:從Docker Hub下載Harbor相關(guān)鏡像,因此安裝軟件包非常小
  • 離線安裝:安裝包包含部署的相關(guān)鏡像,因此安裝包比較大
  • OVA安裝程序(第三方):當(dāng)用戶(hù)具有vCenter環(huán)境時(shí),使用此安裝程序,在部署 OVA后啟動(dòng)Harbor
為什么使用私用倉(cāng)庫(kù)

公司的項(xiàng)目一般不予許我們上傳到 Docker Hub 這類(lèi)的公共倉(cāng)庫(kù)中,所有學(xué)會(huì)創(chuàng)建一個(gè)私有倉(cāng)庫(kù)也是非常必要的

    雖然`hub.docker.com`上可以保存鏡像,但是網(wǎng)速相對(duì)較慢,在內(nèi)部環(huán)境中搭建一個(gè)私有的公共倉(cāng)庫(kù)是個(gè)更好的方案。
harbor 的基本組件
組件 功能
harbor-adminserver 配置管理中心
harbor-db 數(shù)據(jù)庫(kù)
harbor-jobservice 鏡像復(fù)制
harbor-log 日志操作
harbor-ui Web管理頁(yè)面和API
nginx 前端代理,負(fù)責(zé)前端頁(yè)面和鏡像上傳/下載轉(zhuǎn)發(fā)
redis 會(huì)話
registry 鏡像存儲(chǔ)
前置工作
下載安裝包

Harbor官方地址:https://github.com/goharbor/harbor/releases 下載最新版安裝包

file
準(zhǔn)備環(huán)境

需要安裝docker以及docker-compose的環(huán)境上面我們已提前安裝了

  • 安裝Docker環(huán)境
  • 安裝docker-compose環(huán)境
離線安裝
解壓安裝包

解壓harbor的安裝包

tar -zxf harbor-offline-installer-v2.1.4.tgz

進(jìn)入目錄 然后將harbor.yml.tmp復(fù)制一份并該命為harbor.yml

cd harbor
cp harbor.yml.tmpl harbor.yml
file

注意: 這里跟老版本不一樣,沒(méi)有了harbor.cfg文件,我們需要手動(dòng)復(fù)制harbor.yml.tmpl在做修改即可

修改harbor.yml

harbor作為私有倉(cāng)庫(kù)作用在公司內(nèi)網(wǎng),一般都是信任關(guān)系,沒(méi)多大必要做https,使用http即可!
所以 把https相關(guān)的已經(jīng)注釋掉

file

并注意配置文件的用戶(hù)名密碼配置,默認(rèn)是 用戶(hù)名是:admin,密碼是:Harbor12345,如果修改需要安裝前修改

加載本地鏡像

使用docker load命令加載本地鏡像,不用再?gòu)膁ockerhub下載了

docker load -i harbor.v2.1.4.tar.gz
file

這樣容器鏡像就被加載到了本地,我們可以通過(guò)docker images命令查看導(dǎo)入的鏡像

docker images
file
執(zhí)行安裝命令

先執(zhí)行預(yù)處理命令,會(huì)創(chuàng)建一些文件夾,初始化一些文件

./prepare
file

然后開(kāi)始真正的安裝過(guò)程

./install.sh
file

如果出現(xiàn)-Harbor has been installed and started successfully表示安裝成功,并查看docker進(jìn)程

docker ps
file

可以看到很多服務(wù)已經(jīng)起來(lái)了。

啟動(dòng)和停止harbor

在harbor的安裝目錄執(zhí)行以下命令就可以啟動(dòng)和停止了

# 啟動(dòng)
docker-compose up -d 
# 停止
docker-compose stop 
# 重新啟動(dòng)
docker-compose restart 
harbor使用
訪問(wèn)harbor

輸入 http://harborIP就可以直接訪問(wèn)了,這里訪問(wèn)我們的地址http://192.168.64.153/

file

輸入用戶(hù)名密碼就可以登錄了 ,如果沒(méi)有修改配置文件 默認(rèn)是 用戶(hù)名是:admin,密碼是:Harbor12345

file

登錄后就可以進(jìn)行操作了

Docker登錄harbor

使用docker login命令就可以登錄harbor了

docker login -u admin -p Harbor12345 192.168.64.153
file

我們發(fā)現(xiàn)登錄報(bào)錯(cuò)了,這和registry一樣,docker模式使用https方式,而我們使用的是http的方式登錄

修改Docker配置

對(duì)于 Linux 系統(tǒng),我們可以在 /etc/docker/daemon.jsondaemon.josn 文件不存在則新建該文件)

 vi /etc/docker/daemon.json

添加下面的配置

{ "insecure-registries": ["harbor地址"] }

完整的配置如下

{
   #因?yàn)槟J(rèn)端口號(hào)是80 所以不需要加端口號(hào)
  "insecure-registries": ["192.168.64.153"],
  "registry-mirrors": ["https://xxxxx.mirror.aliyuncs.com"]
}

執(zhí)行以下命令重啟重新加載配置并生效

systemctl daemon-reload
service docker restart
file
再次進(jìn)行登錄
docker login -u admin -p Harbor12345 192.168.64.153

這次我們就成功登錄了

file

到這里我們就已經(jīng)登錄成功了

修改鏡像tag

我們推送鏡像我要把我們的鏡像名稱(chēng)改成符合規(guī)范的格式

docker tag \
192.168.64.153:5000/learn-docker-storage:0.0.3 \
192.168.64.153/library/learn-docker-storage:0.0.3
file

這里有一個(gè)library路徑,是harbor默認(rèn)的項(xiàng)目名稱(chēng)

file
推送鏡像

可以通過(guò)docker push進(jìn)行推送鏡像,注意需要先登錄在進(jìn)行推送

docker push 192.168.64.153/library/learn-docker-storage:0.0.3
file

到這里我們已經(jīng)推送到了harbor,我們可以登錄library頁(yè)面查看

file
harbor 測(cè)試
刪除本地鏡像

可以通過(guò)docker rmi 鏡像ID刪除本地鏡像

docker rmi \
192.168.64.153:5000/learn-docker-storage:0.0.3 \
192.168.64.153/library/learn-docker-storage:0.0.3
file
運(yùn)行harbor 中的鏡像

執(zhí)行運(yùn)行命令

docker run -d \
-v /tmp/data/logs:/logs \
-p 8003:8003 \
--name learn-docker-storage \
--network=learn-docker-network \
192.168.64.153/library/learn-docker-storage:0.0.3
file
訪問(wèn)微服務(wù)測(cè)試
 curl http://192.168.64.153:8003/storage/employe/findByID/10001 | python -m json.tool
file
查看harbor詳情

詳情里面會(huì)顯示拉取次數(shù)

file
HarBor用戶(hù)權(quán)限說(shuō)明

HarBor用戶(hù)角色在項(xiàng)目(項(xiàng)目-成員-新加成員)中為3類(lèi):項(xiàng)目管理員、開(kāi)發(fā)人員、訪客

  • 項(xiàng)目管理員:增刪改查
  • 開(kāi)發(fā)人員:上傳和下載
  • 訪客:只允許下載
HarBor權(quán)限配置
新建用戶(hù)

點(diǎn)擊創(chuàng)建用戶(hù)可以創(chuàng)建一個(gè)用戶(hù)

file

我們創(chuàng)建一個(gè)itcast的用戶(hù)

file
用戶(hù)授權(quán)

創(chuàng)建用戶(hù)后進(jìn)入項(xiàng)目模塊添加成員

file

選擇成員后并選擇權(quán)限

file

訪客只能進(jìn)行拉取不能推送和管理

file
用戶(hù)登錄測(cè)試

我們用itcast用戶(hù)通過(guò)web端登錄測(cè)試下,我們發(fā)現(xiàn)用戶(hù)是沒(méi)有修改權(quán)限的

file
docker登錄測(cè)試

登錄docker客戶(hù)端

 docker login -u itcast -p Qwert123 192.168.64.153
file

嘗試推送鏡像

docker push 192.168.64.153/library/learn-docker-storage:0.0.3
file

我們發(fā)現(xiàn)是無(wú)法進(jìn)行推送鏡像的

拉取鏡像測(cè)試

先刪除本地的容器以及鏡像

 docker rm -f learn-docker-storage
 docker rmi 192.168.64.153/library/learn-docker-storage:0.0.3
file

嘗試?yán)〔?dòng)本地鏡像

docker run -d \
-v /tmp/data/logs:/logs \
-p 8003:8003 \
--name learn-docker-storage \
--network=learn-docker-network \
192.168.64.153/library/learn-docker-storage:0.0.3
file

微服務(wù)訪問(wèn)測(cè)試

 curl http://192.168.64.153:8003/storage/employe/findByID/10001 | python -m json.tool
file

Harbor支持Https(擴(kuò)展)

為了支持微服務(wù)推送我們需要將HarBor設(shè)置為https,可以讓HarBor在任何地方使用以及推送

生成SSL證書(shū)

前面說(shuō)了怎么搭建harbor倉(cāng)庫(kù),這里講一講harbor實(shí)現(xiàn)https訪問(wèn),因?yàn)橹恍枰獌?nèi)網(wǎng)訪問(wèn),沒(méi)必要去申請(qǐng)一個(gè)ssl證書(shū),所以我就用openssl頒發(fā)自簽名證書(shū),實(shí)現(xiàn)https訪問(wèn)。

創(chuàng)建證書(shū)目錄
mkdir -p /tmp/data/cert && cd /tmp/data/cert && ll
file
創(chuàng)建 CA 根證書(shū)
openssl req  -newkey rsa:4096 -nodes -sha256 -keyout ca.key -x509 -days 365 -out ca.crt -subj "/C=CN/L=beijing/O=itcast/CN=harbor-registry"

這里subj是主題的意思含義如下

C=國(guó)家,S=?。ㄊ校?,L=區(qū)(縣、市),O=組織機(jī)構(gòu),OU=組織單位,CN=通用名稱(chēng)
生成證書(shū)簽名

生成一個(gè)證書(shū)簽名, 設(shè)置訪問(wèn)域名為itcastharbor.com

openssl req -newkey rsa:4096 -nodes -sha256 -keyout itcastharbor.com.key -out server.csr -subj "/C=CN/L=beijing/O=itcast/CN=itcastharbor.com"
生成主機(jī)證書(shū)
openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out itcastharbor.com.crt
操作步驟如下
file
配置harbor.yml

然后進(jìn)入harbor安裝目錄修改harbor.yml,修改下面幾個(gè)選項(xiàng)

  • hostname,使用IP或域名,不要用回環(huán)地址,localhost等
  • certificate,yourdomain.com.crt的路徑/tmp/data/cert/itcastharbor.com.crt
  • private_key,yourdomainr.com.key的路徑/tmp/data/cert/itcastharbor.com.key
file
重新安裝harbor服務(wù)
停止harbor

停止運(yùn)行中的服務(wù)

 docker-compose down

運(yùn)行目錄harbor下的prepare完成https的配置

./prepare
file
重新安裝

在harbor目錄下運(yùn)行安裝命令

./install.sh
file
修改Docker推送配置

我們需要將推送的IP改成域名

vi /etc/docker/daemon.json

上文中我們對(duì)registry已經(jīng)操作了,這里需要改用harbor,需要重新配置

#因?yàn)槟J(rèn)端口號(hào)是80 所以不需要加端口號(hào)
{ "insecure-registries": ["倉(cāng)庫(kù)IP或域名"] }

完整的配置如下

{
  "insecure-registries": ["itcastharbor.com"],
  "registry-mirrors": ["https://xxxxx.mirror.aliyuncs.com"]
}

執(zhí)行以下命令重啟重新加載配置并生效

systemctl daemon-reload
service docker restart
修改本地host文件

為了讓本機(jī)能夠正常訪問(wèn)到harbor的web環(huán)境需要配置本地的hosts文件增加如下配置

192.168.64.153 itcastharbor.com

windows環(huán)境下host路徑在C:\Windows\System32\drivers\etc

域名訪問(wèn)harbor

通過(guò)域名訪問(wèn)harbor,域名就是我們剛才配置的itcastharbor.com域名訪

file

因?yàn)槲覀兊淖C書(shū)是自簽的,不是第三方認(rèn)證的,素以有安全性提示,點(diǎn)擊繼續(xù)就可以訪問(wèn)

file

到這里登錄后就可以訪問(wèn)了

file

本文由育博學(xué)谷狂野架構(gòu)師發(fā)布
如果本文對(duì)您有幫助,歡迎關(guān)注和點(diǎn)贊;如果您有任何建議也可留言評(píng)論或私信,您的支持是我堅(jiān)持創(chuàng)作的動(dòng)力
轉(zhuǎn)載請(qǐng)注明出處!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容