一文搞懂 AWS Docker 基礎(chǔ) 下篇 實(shí)戰(zhàn)
時(shí)間:2023-07-27 18:36:02 | 來源:網(wǎng)站運(yùn)營
時(shí)間:2023-07-27 18:36:02 來源:網(wǎng)站運(yùn)營
一文搞懂 AWS Docker 基礎(chǔ) 下篇 實(shí)戰(zhàn):本文承接《一文搞懂 AWS Docker 基礎(chǔ) 上篇 理論》,實(shí)戰(zhàn)測試運(yùn)行 docker。
讀完也許就會(huì)發(fā)現(xiàn)使用 docker 也沒那么難。
Win10 下 WSL2 和 Docker Desktop 的詳細(xì)配置請(qǐng)參考《AWS CDK 利用 asset 編譯 Docker 鏡像并部署到 ECS Fargate (Python)》一文。
目錄
- 環(huán)境(配置)
- 實(shí)戰(zhàn)步驟
- 運(yùn)行一個(gè) httpd 網(wǎng)站
- 登錄 Docker 倉庫
- pull httpd 鏡像
- 生成容器(運(yùn)行鏡像)
2. 容器與本地文件交換
3. 編譯鏡像
4. 運(yùn)行容器作為 mysql 客戶端
環(huán)境(配置)
- AWS 中國或 Global 帳號(hào),可在官網(wǎng)申請(qǐng),一年內(nèi)使用指定資源免費(fèi)
- Win10 + terminal(WSL 2 Ubuntu20)
- Docker desktop 3.3.3
實(shí)戰(zhàn)步驟
1. 運(yùn)行一個(gè) httpd 網(wǎng)站
傳統(tǒng)上,如果我們要在本機(jī)上運(yùn)行一個(gè)測試網(wǎng)站(httpd),先需要下載 httpd 軟件,然后雙擊安裝進(jìn)行配置。
有了 WSL2 之后,我們可以直接用 httpd 鏡像,在本機(jī)上運(yùn)行一個(gè) docker 網(wǎng)站,十分方便。(沒有 WSL2 之前也可以用 Docker desktop 運(yùn)行容器,但是只能用 powershell 或者 CMD 與 docker 互交)
登錄 Docker 倉庫
第一次使用 docker 時(shí),需要先登錄 docker 公共倉庫才能 pull 鏡像。帳號(hào)可以在 docker 官網(wǎng)免費(fèi)注冊。
https://www.docker.com/用如下命令登錄
docker login
圖 1
pull httpd 鏡像
生成網(wǎng)站容器前,我們先從 docker 公共倉庫 pull httpd 鏡像。
docker 公共倉庫中有各大廠商提供的官方鏡像,也有個(gè)人制作的鏡像(比如,我自己打包的 tansong0091/httpd-ssh)。
docker 公共倉庫地址如下,我們在這里也可以搜索鏡像及版本說明
https://hub.docker.com/repositories圖 26
我們用如下命令 pull 鏡像
#pull最新的httpd鏡像docker pull httpd#相當(dāng)于運(yùn)行docker pull httpd:latest#pull指定版本的鏡像docker pull httpd:2.4
我們直接拉一個(gè)最新版本的 httpd 鏡像
圖 2
pull 完成后,用下列命令查看鏡像
docker images|grep httpd
圖 27
也可以在 docker desktop 中看到新鏡像
圖 6
生成容器(運(yùn)行鏡像)
下面我們先運(yùn)行一個(gè)最簡單的容器,執(zhí)行以下命令
docker run -d -p 80:80 httpd
說明:
- run: 運(yùn)行一個(gè)容器
- d: 后臺(tái)運(yùn)行這個(gè)容器
- p (本地端口:容器內(nèi)端口): 端口映射,把容器里的 80 端口映射到本地 80 端口,這樣我們就可以從瀏覽器中訪問容器里網(wǎng)站
- httpd: 鏡像名稱(不加版本號(hào),相當(dāng)于 httpd:latest)
圖 3
用下列命令查看正在運(yùn)行的容器
docker ps
圖 4
說明:
現(xiàn)在只有一個(gè)容器在運(yùn)行,由 httpd 鏡像生成,端口映射 80:80
在 docker desktop 中也可以看到新的容器正在運(yùn)行
圖 7
這時(shí)我們在網(wǎng)站中打開“http://localhost”,可以看到httpd的網(wǎng)站測試頁面已經(jīng)打開了
圖 5
可以看到用 docker 在本地運(yùn)行一個(gè)網(wǎng)站非常簡單,pull 一個(gè)鏡像,生成容器,然后網(wǎng)站就可以訪問了。
但此時(shí)運(yùn)行的 httpd 容器和我們的系統(tǒng)是分隔開的,如何把我們自己的內(nèi)容部署到這個(gè)容器中?
我們介紹兩種方法。
2. 容器與本地文件交換
cp
我們可以用 docker cp 命令把文件復(fù)制到運(yùn)行的容器上,或把文件從運(yùn)行的容器里復(fù)制到本地
#從本地復(fù)制到容器中docker cp LOCAL_FILE CONTAINER_NAME:/PATH/FILENAME#從容器中復(fù)制到本地docker cp CONTAINER_NAME:/PATH/FILENAME LOCAL_FILE
我們在本地建一個(gè)文件 test.html,內(nèi)容如下
<p>this is a docker test for readCrapforAWS</p>
然后運(yùn)行如下命令,把這個(gè)文件復(fù)制到 httpd 容器中
docker cp test.html b4c33aa008f8:/usr/local/apache2/htdocs/test.html
說明:b4c33aa008f8 是 CONTAINER ID,這里也可以用容器的 name
圖 9
訪問http://localhost/test.html,可以看到新網(wǎng)頁部署成功,本地文件成功復(fù)制到容器中
圖 10
exec
在上面的步驟中,我們把本地文件復(fù)制到了容器的/usr/local/apache2/htdocs 目錄下。
但是如果我不知道里面的文件夾結(jié)構(gòu),或者我想直接修改 httpd 容器里的配置文件,這時(shí)該怎么辦?
我們可以用 exec 的命令進(jìn)入容器內(nèi)部進(jìn)行查看修改。
運(yùn)行下列命令進(jìn)行容器內(nèi)部
docker exec -it b4c33aa008f8 bash
說明:
- i 運(yùn)行交互模式
- t 開啟一個(gè) pseudo-TTY
- bash 運(yùn)行容器的 bash,與鏡像本身有關(guān)。一般是 bash 或者 sh
- b4c33aa008f8 是容器的 ID,可用 docker ps 查看
這時(shí)可以看到,我們已經(jīng)進(jìn)入容器的內(nèi)部了。現(xiàn)在我們可以在編輯 httpd.conf 文件修改參數(shù)了。
圖 11
如需退出容器,輸入 exit
圖 12
說明:
- httpd 鏡像本身沒有提供 vim 編輯器,所以需要手工安裝
#可以直接連接internetapt-get updateapt-get install vim#需要代理連接internetapt-get -o Acquire::http::proxy="http://YOUR_PROXY_SERVER:PORT" updateapt-get -o Acquire::http::proxy="http://YOUR_PROXY_SERVER:PORT" install vim
- 在 httpd 容器內(nèi)部修改 httpd.conf 文件后,需要重啟容器生效時(shí),可以用如下命令
docker restart b4c33aa008f8
圖 13
volume
除了用 cp 命令把部署文件復(fù)制到容器內(nèi)部,我們還可以把本地文件夾映射到容器中,這樣本地文件夾的內(nèi)容直接在容器中可見。
運(yùn)行以下命令,先把容器中的/usr/local/apache2/conf 文件夾復(fù)制到本地
docker cp b4c33aa008f8:/usr/local/apache2/conf ./
圖 14
然后運(yùn)行下列兩條命令,停止容器并刪除
docker stop b4c33aa008f8docker rm b4c33aa008f8
圖 15
然后我們在本地再創(chuàng)建兩個(gè)文件夾
mkdir htdocsmkdir logs
運(yùn)行以下命令重新建一個(gè)容器
docker run -d -p 80:80 / --name tshttpd / --restart=always / -v /home/tans/Docker/conf:/usr/local/apache2/conf / -v /home/tans/Docker/logs:/usr/local/apache2/logs / -v /home/tans/Docker/htdocs:/usr/local/apache2/htdocs / httpd:latest
說明:
- name: 指定容器 name,之后我們可以用這個(gè) name 進(jìn)行重啟容器等操作
- restart: 在 docker 服務(wù)重啟后,自動(dòng)運(yùn)行容器(重啟服務(wù)器后,容器自動(dòng)啟動(dòng))
- v: 把本地文件夾“/home/tans/Docker/conf”映射到容器中“/usr/local/apache2/conf”(原容器中這個(gè)路徑下的內(nèi)容會(huì)被本地文件夾覆蓋掉)
現(xiàn)在我們重新建了一個(gè)容器,并把三個(gè)本地文件夾映射到了容器內(nèi)部
圖 16
我們把剛才建的 test.html 文件,移動(dòng)到剛才建的本地 htdocs 目錄
mv test.html htdocs/
然后我們進(jìn)入容器(現(xiàn)在我們可以用容器名稱進(jìn)入容器了)
docker exec -it tshttpd bash
圖 17
說明:
進(jìn)入容器的 htdocs 目錄,可以看到我們在本地文件夾 htdocs 中的文件 test.html
現(xiàn)在有了卷映射,我們無需再把部署文件復(fù)制到容器內(nèi)部,只需要把部署文件復(fù)制到映射目錄,容器中就可以看到這些文件了。
注意:在使用 volume 時(shí),如果在容器內(nèi)訪問映射進(jìn)來的文件提示沒有權(quán)限時(shí),我們需要把本地文件的屬主 UID 數(shù)字改成容器內(nèi)用戶的 UID 數(shù)字3. 編譯鏡像
有時(shí)在公共倉庫中下載的鏡像并不能滿足我們的需要,這時(shí)我們可以自行編譯鏡像,安裝我們需要的軟件。
我們以“AWS ECS Fargate 容器調(diào)試”一文中的 Dockerfile 為例,講述如何自己編譯鏡像。
這個(gè)鏡像把 openssh 加入 httpd 鏡像中,使得我們可以用 ssh 命令遠(yuǎn)程登入容器內(nèi)部,這個(gè)功能對(duì)無服器模式的 docker 環(huán)境調(diào)試非常有用,比如 ECS Fargate。
Dockerfile
編譯鏡像,主要就是編輯 Dockerfile 這個(gè)文件,在這文件中指定基礎(chǔ)鏡像,安裝軟件及暴露端口等。
復(fù)制 httpd-ssh 文件夾如下(資源下載中可下載)
tans@GDSVGQQ2E:~/Docker$ tree httpd-ssh/httpd-ssh/├── Dockerfile├── conf│ ├── htaccess│ ├── httpd.conf│ └── sshd_config├── entrypoint.sh├── runscript└── test.html
Dockerfile 文件內(nèi)容如下
#1FROM httpd:2.4#2COPY ./test.html/ /usr/local/apache2/htdocs/dist/test.htmlCOPY entrypoint.sh /entrypoint.shCOPY conf/httpd.conf /usr/local/apache2/conf/#3RUN apt-get -o Acquire::http::proxy="http://YOUR_PROXY_SERVIER:PORT/" update / && apt-get -o Acquire::http::proxy="http://YOUR_PROXY_SERVIER:PORT/" install -y vim procps openssh-server / && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime / && echo "Asia/Shanghai" > /etc/timezone / && mkdir -p /var/run/sshd / # SSH login fix. Otherwise user is kicked off after login && sed -i 's@session/s*required/s*pam_loginuid.so@session optional pam_loginuid.so@g' /etc/pam.d/sshdCOPY conf/sshd_config /etc/ssh/sshd_config#4EXPOSE 80 22#5ENTRYPOINT ["/entrypoint.sh"]
說明:
- #1 FROM: 本鏡像以 httpd:2.4 鏡像為基礎(chǔ),如果本地不存在 httpd:2.4 鏡像,docker 會(huì)自動(dòng)連接到公共倉庫中下載
- #2 COPY: 把本地文件復(fù)制到鏡像中
- #3 RUN: 用來在鏡像中執(zhí)行命令。比如,apt-get update/install 用來安裝軟件包,這里安裝了 openssh 包和 vim procps
- #4 EXPOSE: 暴露端口,這里暴露了 80 和 22 兩個(gè)端口
- #5 ENTRYPOINT: 指定容器啟動(dòng)后運(yùn)行的腳本
我們可以在鏡像里安裝任意軟件,比如我們可以安裝一套 php,apache,mysql 在一個(gè)鏡像文件中。
需要注意的是,鏡像一般以簡化的 linux 系統(tǒng)(比如 Alpine linux)為主,所以一般需要自己解決軟件的依賴包。
我們再來看一下 entrypoint.sh 文件的內(nèi)容
#!/bin/shHOST=`hostname`echo "export HOSTNAME=$HOST" >>/usr/local/apache2/bin/envvars#1/usr/local/apache2/bin/apachectl start#2# Create a folder to store user's SSH keys if it does not exist.USER_SSH_KEYS_FOLDER=~/.ssh[ ! -d "$USER_SSH_KEYS_FOLDER" ] && mkdir -p $USER_SSH_KEYS_FOLDER && chmod 700 $USER_SSH_KEYS_FOLDER && echo $SSH_PUBLIC_KEY > ${USER_SSH_KEYS_FOLDER}/authorized_keysunset SSH_PUBLIC_KEY# Start the SSH daemon.#3/usr/sbin/sshd -D
說明:
- #1 后臺(tái)啟動(dòng) httpd 進(jìn)程
- #2 用環(huán)境變量引入 SSH Public key,然后對(duì) SSH Key 進(jìn)行配置保存
- #3 前臺(tái)運(yùn)行 ssh 進(jìn)程
如果我們希望容器啟動(dòng)之后一直運(yùn)行,那么 entrypoint.sh 最后一條命令必須是前臺(tái)命令(前臺(tái)命令是指運(yùn)行后,命令在前臺(tái)顯示不會(huì)退出)。
否則容器啟動(dòng)后,運(yùn)行完 entrypoint.sh 中所有命令之后便會(huì)退出停止。
生成鏡像
運(yùn)行下面的命令編譯新鏡像
docker build --tag tshttpd-ssh .
圖 18
編譯完成
圖 19
用下列命令查看當(dāng)前的鏡像
docker images
圖 20
運(yùn)行并測試
下面我們用新鏡像重新創(chuàng)建容器
docker stop tshttpddocker rm tshttpddocker run -d -p 80:80 / -p 10022:22 / --name tshttpd / --restart=always / -e SSH_PUBLIC_KEY="ssh-rsa AAAAB3 ... wNIt5dFd9wQ85X8sYcZ4M0TEq8i9BDOmEH7QZiXjCf6nYIzATG3GNyflAPWkA70BHEDtIo7x1TsCsjumqwl1qXvuZLxx/sunx/Sew==" / -v /home/tans/Docker/conf:/usr/local/apache2/conf / -v /home/tans/Docker/logs:/usr/local/apache2/logs / -v /home/tans/Docker/htdocs:/usr/local/apache2/htdocs / tshttpd-ssh:latest
說明:
- e: 定義了一個(gè)環(huán)境變量“SSH_PUBLIC_KEY”,用來遠(yuǎn)程 ssh 登錄容器
- p 10022:22 把容器中的端口 22 映射到本地 10022 端口
圖 21
現(xiàn)在我們用 ssh 登錄測試一下
sudo ssh -i id_rsa_ts localhost -p22
登錄成功,可以看到容器內(nèi)正在跑的 httpd 進(jìn)程和 sshd 進(jìn)程
圖 22
接下來我們可以把這個(gè)新鏡像打 tag 后推私人或公共倉庫,以供后繼使用。
4. 運(yùn)行容器作為 mysql 客戶端
除了運(yùn)行容器做為網(wǎng)站服務(wù)器,我們還可以利用用完即刪除的容器做為各種工具客戶端。
比如,我想測試一下到遠(yuǎn)程 mysql 的數(shù)據(jù)庫用戶連接是否正常。
一般這種情況,我們需要要在本機(jī)上安裝一個(gè)對(duì)應(yīng)版本的 mysql 客戶端軟件。
但有了 docker 就不需要這么做了。我們可以 pull 一個(gè) mysql 鏡像,然后啟用一個(gè)臨時(shí)的容器做為客戶端。
比如我想遠(yuǎn)程連接一個(gè) mysql8 數(shù)據(jù)庫,但我又不想在本機(jī)上裝 mysql 客戶端。
那么可以直接運(yùn)行以下命令連接 mysql
docker run --rm -it mysql:8.0.19 mysql -hYOUR_MYSQL_SERVER_IP -PYOUR_MYSQL_PORT -uroot -pYOUR_MYSQL_PWD
如果本機(jī)沒有 mysql:8.0.19 的鏡像,則 docker 會(huì)自動(dòng) pull 后登錄
圖 23
如果已經(jīng)存在 mysql:8.0.19 的鏡像,則會(huì)直接登錄
圖 24
exit 退出 mysql 后,這個(gè)臨時(shí)的 mysql 容器會(huì)自動(dòng)刪除(--rm)
如果連鏡像也不需要了,可以用下列命令刪除鏡像
docker rmi mysql:8.0.19
圖 25
總結(jié)
docker 使用起來沒有那么難,簡單來說就兩步
- pull 鏡像
- 生成容器
熟練之后,我們可以
- 自己編譯鏡像
- 用 docker-compose 定義多個(gè)容器的應(yīng)用,控制啟動(dòng)順序等
- 使用其它容器編排工具幫我們管理容器,比如 k8s
Dockderfile 還有許多其它命令,環(huán)境變量可以設(shè)置,可以參考 Docker 官網(wǎng)文檔繼續(xù)學(xué)習(xí)。
引申
上面說過容器啟動(dòng)后運(yùn)行 entrypoint.sh 腳本的最后一條命令必須是前臺(tái)命令,否則容器會(huì)退出。
當(dāng)最后一條命令不是前臺(tái)命令時(shí),執(zhí)行完全部命令就會(huì)自動(dòng)退出。我們可以利用這個(gè)特性,把容器當(dāng)成執(zhí)行一次性任務(wù)的實(shí)例。
比如我們需要定期從本地復(fù)制數(shù)據(jù)到 AWS 云上某數(shù)據(jù)庫。
我們可以把復(fù)雜的相關(guān)操作做成一個(gè)鏡像,然后利用 AWS Cron 定時(shí)啟動(dòng)容器。
容器啟動(dòng)后運(yùn)行命令復(fù)制數(shù)據(jù),復(fù)制完成后就會(huì)自動(dòng)退出容器并刪除。
資源下載
httpd-ssh 文件夾可以下列鏈接下載
https://github.com/tansong0091/realCrapForAWS/tree/main/CDK_DOCKERIMAGE后記
看完這篇文章,動(dòng)手實(shí)踐一下,再看看 Docker 官網(wǎng)的文檔,基本上使用 Docker 就問題不大了。
對(duì) Docker 使用有了感覺,使用其它容器編排工具就簡單多了,因?yàn)椴徽摼幣殴ぞ叩拿钍鞘裁?,下層總是在運(yùn)行容器。
喜歡請(qǐng)點(diǎn)贊,禁止轉(zhuǎn)載,轉(zhuǎn)發(fā)請(qǐng)標(biāo)明出處
關(guān)注 B 站 UP 主“我是手拉面” 觀看更多視頻
關(guān)注GZH“全是 AWS 干貨”查看更多內(nèi)容
關(guān)鍵詞:基礎(chǔ),實(shí)戰(zhàn)