15-多容器復雜應用的部署

15-多容器復雜應用的部署

此節主要是通過部署一個復雜的應用場景,進而練習容器的網絡相關知識。

創建一個flask-web應用

  1. 創建一個 flask-web 文件夾

    mkdir flask-web
    

    在此文件夾內創建 app.py 文件

    cd flask-web
    touch app.py
    
  2. 編寫一個簡單的 web 程序

    import os
    import socket
    import redis
    from flask import Flaskapp = Flask(__name__)
    redis = Redis(host=os.environ.get('REDIS_HOST', '127.0.0.1'), port=6379)@app.route('/')
    def hello():redis.incr('hits')return 'hello Container World! I have been seen %s times and my hostname is %s.\n' % (redis.get('hits'), socket.gethostname())if __name__ == '__main__':app.run(host="0.0.0.0", port=5000, debug=True)
    

創建一個 redis 數據庫容器

  1. 創建容器

    docker run -d --name redis redis
    

    這里為什么沒有增加端口呢,是因為我們想內部自己訪問,不想暴露給外面,這樣也比較安全。

  2. 查看運行情況

    [vagrant@10 flask-web]$ docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
    d9916db96279        redis               "docker-entrypoint.s…"   2 minutes ago       Up 2 minutes        6379/tcp             redis
    

部署

  1. 創建自定義的 web 程序鏡像

    首先編寫Dockerfile

    FROM python:2.7
    LABEL maintaner="vincent <jeffmanword@gmail.com>"
    COPY ./app.py /app/
    WORKDIR /app
    RUN pip install flask redis
    EXPOSE 5000
    CMD ["python", "app.py"]
    

    構建鏡像

    docker build -t vincent/flask-redis .
    
  2. 創建 flask-redis 的容器

    docker run -d --link redis --name flask-redis -e REDIS_HOST=redis vincent/flask-redis
    

    -d 是后臺執行
    –link 是連接redis容器,使 flask-redis 容器可以訪問 redis 容器
    -e 設定容器的環境變量,下面講

  3. 問題解決

    上一步構建完成后,查看容器運行情況

    docker ps
    

    發現剛剛創建的flask-redis容器并沒有運行,而是停止了,說明工作不正常,那么我怎么辦?

    首先我們查看運行日志

    [vagrant@10 flask-web]$ docker logs flask-redis 
    Traceback (most recent call last):File "app.py", line 7, in <module>redis = Redis(host=os.environ.get('REDIS_HOST', '127.0.0.1'), port=6379)
    NameError: name 'Redis' is not defined
    

    發現這里有一個錯誤,這是使用redis錯誤導致的,app.py 修改如下

    import os
    import socket
    import redis
    from flask import Flaskapp = Flask(__name__)
    redis = redis.Redis(host=os.environ.get('REDIS_HOST', '127.0.0.1'), port=6379)@app.route('/')
    def hello():redis.incr('hits')return 'hello Container World! I have been seen %s times and my hostname is %s.\n' % (redis.get('hits'), socket.gethostname())if __name__ == '__main__':app.run(host="0.0.0.0", port=5000, debug=True)
    

    重新構建鏡像

    docker rm flask-redis && docker rmi vincent/flask-redis
    

    重新創建容器

    docker run -d --link redis --name flask-redis -e REDIS_HOST=redis vincent/flask-redis
    
  4. 進入 flask-redis 容器

    docker exec -it flask-redis /bin/bash
    

    查看 env

    root@99a298edd5da:/app# env
    

    我們能在返回的內容中找到這樣一條環境變量

    REDIS_HOST=redis
    

    說明剛剛創建容器的時候參數 -e的作用就在此。

  5. 測試網絡

    測試ping redis 查看是否連通

    root@99a298edd5da:/app# ping redis
    PING redis (172.17.0.4) 56(84) bytes of data.
    64 bytes from redis (172.17.0.4): icmp_seq=1 ttl=64 time=0.079 ms
    64 bytes from redis (172.17.0.4): icmp_seq=2 ttl=64 time=0.068 ms
    

    ping redis 是通的。這是因為

    redis = redis.Redis(host=os.environ.get('REDIS_HOST', '127.0.0.1'), port=6379)
    

    在這里的 REDIS_HOST 被替換成了我們設定的名字,其實這段代碼在訪問的時候其實是直接訪問的 redis,因為設定了 --link 參數,那么是可以訪問的,而不需要ip。到這里有的人會有疑問,為什么不直接在代碼中寫 redis 呢?原因是方便我們后續更改名稱,我們只需要在創建容器的時候指定名稱即可,你可以叫 redis1,redis2 都可以。

    我們在這個容器內訪問 web 服務

    root@99a298edd5da:/app# curl 127.0.0.1:5000
    hello Container World! I have been seen 1 times and my hostname is 99a298edd5da.
    

    這個web程序運行是正常的。

  6. 設定端口

    退出容器,測試訪問本地 5000 端口

    [vagrant@10 flask-web]$ curl 127.0.0.1:5000
    curl: (7) Failed connect to 127.0.0.1:5000; 拒絕連接
    

    我們無法訪問,這是因為我們只是暴露了 容器的 5000端口,但是并沒有和本地端口進行綁定。

    那我們重新創建容器

    docker stop flask-redis && docker rm flask-redis
    docker run -d -p 5000:5000 --link redis --name flask-redis -e REDIS_HOST=redis vincent/flask-redis
    

    再次測試訪問本地 5000 端口

    [vagrant@10 flask-web]$ curl 127.0.0.1:5000
    hello Container World! I have been seen 2 times and my hostname is e2ecfc2256f7.
    

總結

我們通過這個例子我們創建了兩個容器,并且相互之間有訪問設定,這很符合我們前后端開發的一個模式,一般 web程序 和 數據是分離的,這也是我們把 redis 單獨封裝在一個容器的原因。

這里我們在創建容器的時候使用了 -e 參數,我們詳細介紹一下。

創建一個帶-e參數的test4 容器

docker run -d -e PENG=vincent --name test4 busybox /bin/sh -c "while true; do sleep 3600; done"

進入容器

docker exec -it test4 /bin/sh

這里說明一下何時加 -it 參數當我們使用 exec 的時候需要加,這時我們想進入一個容器,如果我們在創建一個容器的時候,也就是run命令,那么是否加-it取決于,這個容器內的啟動命令配置,例如: 如果使用 ENTRYPOINT [“ls”] 那么我們不需要加 -it,如果什么都沒有設置,那么就需要加,一般這樣使用docker run -it test1 /bin/sh ls

執行 env

/ # env
HOSTNAME=51801dc17c67
SHLVL=1
HOME=/root
TERM=xterm
PENG=vincent
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/

我們可以看到 PENG=vincent 已經被設置在容器內了。這有什么用呢,有的時候有些程序需要讀取環境變量才能工作,這就很有用了。

最后我們再回顧一下這節部署的程序網絡模型圖

在這里插入圖片描述

我們部署的兩個容器是在同一臺linux主機內的,他們可以訪問是很簡單的,那么如果是兩臺linux呢?

在這里插入圖片描述

我們假設這兩臺linux主機是可以通信的,現在我們想把 redis 部署在一臺linux主機上,flask-web 部署在另一臺linux主機上,他們如何通信?如何配置? 大家思考一下。

答案將在下一節我們講解。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/536031.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/536031.shtml
英文地址,請注明出處:http://en.pswp.cn/news/536031.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

16-多機器通信

16-多機器通信 回顧上節課的思考題。 flask-redis 想訪問 redis&#xff0c;該如何通信&#xff1f; 創建另外一臺linux虛擬機 直接拷貝Vagrantfile文件創建一個 centos 虛擬機 我們創建一個centos7-2文件夾&#xff0c;然后創建虛擬機 vagrant up創建的過程中提示選擇網絡接…

17-Docker的數據持久化介紹

17-Docker的數據持久化介紹 回顧容器與鏡像 容器是在鏡像之上創建的一層運行時層&#xff0c;這一層是可以讀寫的&#xff0c;我們能夠在容器內添加數據&#xff0c;讀取數據。 也就是說我們在創建容器的時候&#xff0c;我們能夠在容器內創建文件&#xff0c;安裝軟件等等&a…

18-數據持久化-Data Volume

18-數據持久化-Data Volume Data Volume 使用場景。一般來講有些容器自己會產生一些數據&#xff0c;我們不想數據隨著容器的銷毀而銷毀&#xff0c;我們想保存數據&#xff0c;正常一般用在數據庫&#xff0c;比如我們想保存數據庫中的數據&#xff0c;這個時候我們就會使用 …

19-數據持久化-Bind Mounting

19-數據持久化-Bind Mounting Bind Mounting 與 Data Volume區別 Data Volume 需要在 Dockerfile 內聲明需要創建的 volume 目錄。 Bind Mounting 則不需要在 Dockerfile 聲明 volume&#xff0c;只需要在創建容器的時候&#xff0c;也就是 run 的時候聲明即可。 如: dock…

go自定義包教程

go自定義包教程 而是環境為 go version go1.11 linux/amd64linux mint 19 創建一個自定義的包 切換到src目錄下&#xff0c;創建demo目錄 cd src mkdir demo再創建smap 文件夾 cd demo mkdir smap創建包文件 cd smap touch map.gomap.go文件內容 package smapimport "…

在Linux中對硬盤進行分區、格式化和掛載

在Linux中對硬盤進行分區、格式化和掛載 我最近有一個全新的4-TB硬盤加入我的電腦。所以我需要在Linux中安裝它。為此&#xff0c;我需要執行以下操作&#xff1a; 分區格式化掛載檢查是否已安裝硬盤驅動器 分區 首先&#xff0c;在通過SATA和電源線將硬盤連接到計算機后&am…

Angular gitlab持續集成之runner配置

gitlab持續集成 安裝Runner 正常安裝 sudo wget -O /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64sudo chmod x /usr/local/bin/gitlab-runner sudo useradd --comment GitLab Runner --creat…

javascript編譯壓縮

javascript編譯 js是JavaScript 源碼文件&#xff0c; .min.js是壓縮版的js文件。 .min.js文件經過壓縮&#xff0c;相對編譯前的js文件體積較小&#xff0c;傳輸效率快。經過編碼將變量和函數原命名改為毫無意義的命名&#xff0c;以防止他人窺視和竊取 js 源代碼 在線版 g…

vscode設置中文

vscode設置中文 當我們安裝完成vscode后&#xff0c;會發現它是中文的&#xff0c;因為默認情況下&#xff0c;vscode使用的語言為英文(us)。 那很多同學是不喜歡英文的&#xff0c;不是看不懂&#xff0c;而是不方便哈。 修改語言配置文件 使用快捷鍵組合【CtrlShiftp】 在…

linux下編譯boost

linux下編譯boost 下載boot庫 官方下載地址 下載完成會解壓。 編譯 1.進入解壓后的文件夾內 cd boost_1_69_0 執行下面的語句 ./bootstrap.sh --with-librariesall --with-toolsetgcc–with-libraries 指定編譯哪些boost庫&#xff0c;all的話就是全部編譯&#xff0c;只想…

C++通過原子變量代替互斥量

C通過原子變量代替互斥量 廢話不多說&#xff0c;直接上代碼。 實現類似lock_guard功能 #include <atomic> #include <thread>class ClockGuard { public:ClockGuard(std::atomic_flag & atomic):m_lockedFlag(atomic){lock();}~ClockGuard(){unlock();}voi…

conky安裝配置

conky安裝配置 安裝conky sudo apt-get install conky-all修改配置 在主目錄下創建’.conkyrc’ 文件內容&#xff1a; # set to yes if you want Conky to be forked in the background background no cpu_avg_samples 2 net_avg_samples 2 out_to_console no # X font w…

Windows子系統安裝圖形界面

Windows子系統安裝圖形界面 有很多同學需要使用 linux 系統,但是又不想真正安裝一個 linux 系統。于是微軟大哥就把 ubuntu 系統集成到 windows 內了&#xff0c;你說 微軟 屌不屌&#xff1f; 言歸正傳。 安裝Xlaunch 因為這個是最靠譜的圖形化界面了&#xff0c;所以不解…

C++ 判斷類是否有某變量

C 判斷類是否有某變量 話不多說上代碼。 #define HAS_MEMBER(member)\template<typename T, typename... Args>struct has_member_##member\ {\private:\template<typename U> static auto Check(int) -> decltype(std::declval<U>().member(std::declv…

C++將地址轉換為字符串

C將地址轉換為字符串 有時候在做程序設計的時候&#xff0c;有可能需要做一個類似messageBus的功能&#xff0c;并且需要一個key保證唯一&#xff0c;那么如何實現這個key的唯一呢&#xff1f;大致兩種思路: 使用函數簽名&#xff0c;因為messagebus綁定的是一個函數&#xf…

Angular 8之升級和新功能摘要

Angular 8之升級和新功能摘要 Angular 8已經到來,并帶來了大量的工作流程和性能改進。就像我們之前發布的幾個版本一樣,讓我們回顧一下Angular 8的新功能,以及如何將Angular 7應用程序升級到Angular 8。 Angular 8中明顯的新功能數量有限,但確實還有一些好東西: Differen…

Linux下查看顯卡PCIE速率x16x8x4及設定

Linux下查看顯卡PCIE速率x16x8x4 由于linux軟件并不是很齊全所以查看顯卡占用PCIE的帶寬并不直觀&#xff0c;所以本文介紹如何查看。 Windows下使用GPU-Z即可查看 Linux 確定當前顯卡型號 lspci | grep NVIDIA返回 02:00.0 3D controller: NVIDIA Corporation GM107M [GeFor…

Deepin安裝最新顯卡RTX2080Ti及CUDA10.1

Deepin安裝最新顯卡RTX2080Ti及CUDA10.1 廢話不多說直接上教程。 本系統為Deepin 15.10.2&#xff0c;是基于debian 9發布的&#xff0c;不排除后續deepin升級為debian 10&#xff0c;就目前來看是和ubuntu 16.04一樣&#xff0c;使用的是debian 9&#xff0c;所以下載安裝包等…

Anaconda安裝Tensorflow環境

Anaconda安裝Tensorflow環境 Anaconda安裝 下載安裝包&#xff0c;請到這個地址下載 安裝 打開終端執行&#xff1a; bash Anaconda3-5.3.1-Linux-x86_64.sh安裝過程全部yes即可。 然后重新啟動。 驗證是否安裝成功 conda --version如果沒有報錯&#xff0c;并且輸出下面內容…

Windows下Qt Creator設置IDE菜單字體樣式

Windows下Qt Creator設置IDE菜單字體樣式 本文為解決以下問題&#xff1a; IDE的菜單字體太小IDE的菜單字體樣式&#xff0c;可以更換為微軟雅黑 創建樣式文件 在Qt Creator目錄下C:\Qt\Qt5.12.2創建 custom-style.css 文件&#xff0c;內容如下&#xff1a; QWidget { fo…