前端工程師眼中的Docker
- 2020 年 3 月 18 日
- 筆記
筆者最近在整理 Node.js 操作各資料庫的方法,卻不料遇到一個很棘手的問題:很多資料庫,都需要同時下載 Server 端和 Client 端,並進行相應的配置,著實是麻煩。那有沒有方法可以省去這些步驟呢?
答案肯定是有的,這就是今天要介紹的主題 —— Docker。
Docker 概述
那 Docker 是什麼呢?
通俗地講,當我們部署程式碼到生產伺服器時,第一次都需要先進行環境配置,比如你有 100 台機器,你就要手動配置 100 台伺服器的環境,這樣難保不會出錯。 Docker 則將軟體服務製作成標準化的模板,也就是鏡像,從而實現快捷部署。每次部署新機器,只需要拉取相關鏡像,即可一鍵完成。
Docker 官方提供了很多標準鏡像,涵蓋 MySQL、MongoDB、Node.js 等常見開源軟體。此外,開發者也可以在已有鏡像的基礎上,打造屬於自己的訂製化鏡像。
接下來以 MySQL 為例,快速入坑 Docker。
鏡像和鏡像庫
那麼如何獲取鏡像呢?
Docker 鏡像一般存儲在 鏡像庫 ( registry ) 中。 Docker Hub 和 Docker Cloud 是公共鏡像庫,任何人均可使用。 Docker 默認使用 Docker Hub 。同時,用戶也可以部署自己的私有鏡像庫。
拉取鏡像
首先,從鏡像庫中拉取 MySql 8.0 版本的鏡像:
$ docker pull mysql:8.0
鏡像列表
讀取鏡像列表,驗證 MySQL 鏡像是否拉取成功:
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE mysql 8.0 c8ad2be69a22 3 days ago 465MB
可以看到 MySQL 已經在鏡像列表中,版本號為 8.0 。
容器
容器 是通過 鏡像 創建的可執行環境,同個鏡像可以實例化多個容器。
創建容器
現在,讓我們使用 MySQL 鏡像創建容器:
$ docker run --name first-mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:8.0
命令有點長,且聽我細細講述。
docker run
命令用於創建並執行新容器:--name
,用於指定容器名,在此我們將新容器命名為 first-mysql
;-e
,即 --environment
,指定環境變數,MYSQL_ROOT_PASSWORD
環境變數用於配置資料庫 root 用戶的密碼;-d
,讓容器在後台運行;最後指定鏡像名和版本號,這裡用的是 mysql:8.0
。
容器列表
docker ps
命令用於讀取正在運行的容器列表:
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a68be49896f8 mysql:8.0 "docker-entrypoint.s…" 6 seconds ago Up 5 seconds 3306/tcp, 33060/tcp first-mysql
docker ps -a
命令用於讀取所有容器列表,包括停止的容器:
$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a68be49896f8 mysql:8.0 "docker-entrypoint.s…" About a minute ago Up About a minute 3306/tcp, 33060/tcp first-mysql c344ce31b67e mongo:3.6 "docker-entrypoint.s…" 3 months ago Exited (255) 3 months ago 0.0.0.0:27017->27017/tcp docker-service_mongo_1
列表中一共有兩個容器,從 STATUS 列可以獲知容器的狀態。first-mysql ,處於運行的狀態;docker-service_mongo_1 處於退出狀態。
停止容器
使用 docker stop
命令停止容器。
$ docker stop a68be49896f8
a68be49896f8
是 first-mysql 的 容器 ID。
查看容器列表,發現 first-mysql 容器此時已處於退出狀態:
$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a68be49896f8 mysql:8.0 "docker-entrypoint.s…" 20 minutes ago Exited (0) 3 seconds ago first-mysql
開啟容器
使用 docker start
開啟已被停止的容器,這裡,我們開啟剛剛被停止的 first-mysql。
$ docker start a68be49896f8
查看容器列表,此時 first-mysql 容器已經是運行中狀態。
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a68be49896f8 mysql:8.0 "docker-entrypoint.s…" 25 minutes ago Up 6 seconds 3306/tcp, 33060/tcp first-mysql
在容器內執行命令
掌握了鏡像和容器的基本操作後,接下來,讓我們來看看如何操作 MySQL。我們拉取的 MySQL 鏡像,已經內置了客戶端程式 mysql 命令,可以直接連接並操作 MySQL 。那麼,如何在容器內執行命令呢?
這就要用到 docker exec
命令了:
$ docker exec -it first-mysql bash
這個命令在容器 first-mysql 內執行 bash
命令,啟動一個互動式 Shell 。注意到,命令行參數 -it
表示提供互動式的終端。
執行完上述命令,不出意外,便進入容器 Shell 環境:
root@a68be49896f8:/#
在 Shell 中,執行 mysql 命令即可連接資料庫:
root@a68be49896f8:/# mysql -u root -p Enter password: Welcome to the MySQL monitor. Commands end with ; or g. Your MySQL connection id is 9 Server version: 8.0.19 MySQL Community Server - GPL Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or 'h' for help. Type 'c' to clear the current input statement. mysql>
-u
,即用戶名,此處是 root
;-p
,表示密碼,即一開始我們創建容器時指定的密碼。在容器內成功連接資料庫後,就可以愉快地進行各種數據操作了。
容器埠映射
如果我們要在實際中應用 Docker 技術,僅在容器內操作顯然是不夠的。試想一下,當我們需要在本機連接容器內的 MySQL,又該如何操作呢?有辦法將容器的埠映射出來嗎?
先看一下我們的 MySQL 容器都有哪些埠:
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES eff3e64f65bb mysql:8.0 "docker-entrypoint.s…" 6 minutes ago Up 6 minutes 3306/tcp, 33060/tcp first-mysql
可以看到,MySQL 容器暴露了兩個埠,分別是 3306
和 33060
,其中 3306
用於連接資料庫。但遺憾的是,這兩個埠目前還無法被外部訪問,除非將它們映射出來。
創建容器時,可以指定 -p
參數,將本地指定埠映射到容器內:
$ docker run --name first-mysql -e MYSQL_ROOT_PASSWORD=123456 -d -p 3306:3306 mysql:8.0
這個命令在本機開啟 3306
埠,並映射到容器的 3306
埠。
現在,我們再來看下容器發生了什麼變化:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e1c17ca83541 mysql:8.0 "docker-entrypoint.s…" 8 seconds ago Up 6 seconds 0.0.0.0:3306->3306/tcp, 33060/tcp first-mysql
PORTS
列顯示 0.0.0.0:3306->3306/tcp
, 這表示本地 3306
埠映射到容器 3306
埠。0.0.0.0
代表全網可連接。
下載 MySQL 客戶端,連接容器內的 MySQL 伺服器。這裡筆者用的是 Homebrew 下載的 mysql-client。由於本機埠配置了全網可連,所以我們的 host
設定為 127.0.0.1
即可,埠指定 3306
。執行如下命令連接 MySQL:
$ /usr/local/Cellar/mysql-client/8.0.18/bin/mysql -u root -h 127.0.0.1 -P 3306 -p Enter password: Welcome to the MySQL monitor. Commands end with ; or g. Your MySQL connection id is 8 Server version: 8.0.19 MySQL Community Server - GPL Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or 'h' for help. Type 'c' to clear the current input statement. mysql>
成功連接了!
小結
- Docker 將軟體服務製作成模板,稱為 鏡像 ;
- 鏡像 存儲在 鏡像庫 中, Docker Hub 和 Docker Cloud 是公共鏡像庫;
- 通過 鏡像 可快速創建可執行環境,這就是 容器 ;
附錄
更多 Node.js 技術文章,請查看:Node.js小冊 ,轉至 原文 可獲得最佳閱讀體驗。
訂閱更新,獲取更多學習資料,請關注我們的 微信公眾號 。