Docker與PostgreSQL 11.5系列文章(三)數據持久化

  • 2019 年 11 月 21 日
  • 筆記

作者簡介

趙振平,PostgreSQL中文社區主席、電腦暢銷書作家、貴州省省管專家、太陽塔科技CTO、國家首批大數據高級職稱、騰訊最具價值專家(TVP)、電子工業出版社簽約作家、出版了技術專著《Oracle資料庫精講與疑難解析》、出版了技術專著《成功之路:Oracle 11g學習筆記》、出版了技術專著《IT架構實錄》。

背景介紹

在學習完第一篇《Docker與PostgreSQL 11.5系列文章(一)Docker的安裝》和第二篇《Docker與PostgreSQL 11.5系列文章(二)postgreSQL 11.5安裝》之後,繼續討論容器的持久化。「持久化」 簡單理解,就是容器被關閉後PostgreSQL資料庫的數據是否還存在?

容器持久化概述

容器在本質上是短暫的。它們有自己的文件系統。當容器死亡時,存儲在其文件系統中的本地數據也會消失。PostgreSQL等有狀態應用程式不能作為Docker容器運行,因為當容器崩潰、死亡或被刪除時,存儲在其資料庫中的數據將丟失。

在Docker容器中裝載持久存儲卷有兩種不同的方法。

方法1:

您可以在主機中創建一個新的持久存儲卷,並將其裝載到Docker容器中的目錄或文件夾下。Docker容器可以獨佔訪問存儲卷。存儲在卷中的數據不容易從主機上讀取、操作或損壞。卷的原理圖如下:

方法2:

您可以將主機中的本地目錄作為Docker容器內的持久存儲卷裝載,以便在主機和Docker容器之間共享數據。如果主機希望訪問或定期備份在Docker容器內運行的DB伺服器寫入文件夾的數據或資料庫,則此方法非常有用。

創建並運行容器

數據存在docker自己管理的卷(volume)裡面(路徑在/var/lib/docker/volumes下),現在大多推薦使用volume。

[root@tar1 ~]# docker run -v volnamepg:/root/data --name dockerPG11 -e POSTGRES_PASSWORD=Xzzp2008 -p 54322:5432 -d postgres:11.5  acb5bf2a4a26b525b8ef4327efcea31963bde8f8ed78ee57f4bc98d8be391f4c

volnamepg是卷的名字,卷會被自動創建。

/root/data是容器中的目錄。

卷(volume)是繞過容器的文件系統,直接將數據寫到host主機上,只是volume是被docker管理的,docker下所有的volume都在host機器上的指定目錄下/var/lib/docker/volumes。

[root@tar1 volumes]# ll /var/lib/docker/volumes  總用量 32  drwxr-xr-x. 3 root root    19 8月  23 18:27 14145904c49f663d8345ef789a9c352046a6a6d1ccd49f4d9e2dfd1a141f6707  drwxr-xr-x. 3 root root    19 8月  23 21:26 54943648b14cc92532aa20c95e8c7d70404a344eb427750aefd873b1b2003c74  drwxr-xr-x. 3 root root    19 8月  23 17:40 59aca22a107ede60abc1795edd9d7a46ff5799850a43f536a91598f74ffa7e01  drwxr-xr-x. 3 root root    19 8月  23 17:46 666f867e5062405683033d419458a85944568a007d6e82720149f48d306c4741  drwxr-xr-x. 3 root root    19 8月  23 17:26 7b3400e3155b8a3f3950f6a495883532de20270c9811de7ea0ab5e31d944a165  drwxr-xr-x. 3 root root    19 8月  23 17:42 8f56e930685166205e4d9fa5730f844aa7b0e0d1dc503e4ec4dd529023a5e17a  drwxr-xr-x. 3 root root    19 8月  23 17:43 9cc314ca59489507b54a0f9122d9ce4fc929c99a885dab2bcd8b42df516cfa27  drwxr-xr-x. 3 root root    19 8月  23 17:48 c5c58f45d54442366d2dff3d939988601a9b46c57d2a750ebeb3c087d1e27d10  drwxr-xr-x. 3 root root    19 8月  23 19:43 d07687b3480ad42bc1d66fc7f609e831d10e917dbc6f95447af69113e8448d56  -rw-------. 1 root root 65536 8月  23 21:26 metadata.db  drwxr-xr-x. 3 root root    19 8月  23 19:43 volnamepg

查看容器

[root@tar1 ~]# docker ps  CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                     NAMES  acb5bf2a4a26        postgres:11.5       "docker-entrypoint..."   9 seconds ago       Up 8 seconds        0.0.0.0:54322->5432/tcp   dockerPG11  [root@tar1 ~]#

這裡要特別注意埠映射關係,54322是對外暴漏的埠。

登錄容器資料庫

bash-4.2$ psql -U postgres -d postgres -h 127.0.0.1 -p 54322  用戶 postgres 的口令:  psql (11.5)  輸入 "help" 來獲取幫助資訊.  postgres=#

創建表並插入數據

postgres=# CREATE TABLE season (id int, name varchar(80));  CREATE TABLE                   ^  postgres=# INSERT INTO season (id,name) VALUES (1, 'March');  INSERT 0 1  postgres=# SELECT * FROM season;   id | name  ----+-------    1 | March  (1 行記錄)    postgres=# CREATE TABLE t_test (x numeric);  CREATE TABLE  postgres=# INSERT INTO t_test SELECT random()  postgres-# FROM generate_series(1, 50000000);  INSERT 0 50000000  postgres=# select * from t_test limit 5;           x  --------------------   0.0994161088019609    0.887578224763274    0.232774924486876    0.416146846953779    0.557969538029283  (5 行記錄)

重啟容器

[root@tar1 ~]# docker stop dockerPG11  dockerPG11  [root@tar1 ~]# docker start dockerPG11  dockerPG11

dockerPG11是容器的名字。

查看數據是否丟失

postgres=# quit  -bash-4.2$ psql -U postgres -d postgres -h 127.0.0.1 -p 54322  用戶 postgres 的口令:  psql (11.5)  輸入 "help" 來獲取幫助資訊.    postgres=#  SELECT * FROM season;   id | name  ----+-------    1 | March  (1 行記錄)

從上面可以看出,容器重啟以後,數據並沒有丟失,說明數據持久化成功。

查看卷的情況

列出所有的卷

[root@tar1 ~]# docker volume ls  DRIVER              VOLUME NAME  local               14145904c49f663d8345ef789a9c352046a6a6d1ccd49f4d9e2dfd1a141f6707  local               59aca22a107ede60abc1795edd9d7a46ff5799850a43f536a91598f74ffa7e01  local               666f867e5062405683033d419458a85944568a007d6e82720149f48d306c4741  local               7b3400e3155b8a3f3950f6a495883532de20270c9811de7ea0ab5e31d944a165  local               8f56e930685166205e4d9fa5730f844aa7b0e0d1dc503e4ec4dd529023a5e17a  local               9cc314ca59489507b54a0f9122d9ce4fc929c99a885dab2bcd8b42df516cfa27  local               c5c58f45d54442366d2dff3d939988601a9b46c57d2a750ebeb3c087d1e27d10  local               d07687b3480ad42bc1d66fc7f609e831d10e917dbc6f95447af69113e8448d56  local               volnamepg

volnamepg就是前面我們指定的,用於持久化的卷。

查看指定的卷的基本資訊

[root@tar1 ~]# docker volume inspect volnamepg  [      {  "Driver": "local",  "Labels": null,  "Mountpoint": "/var/lib/docker/volumes/volnamepg/_data",  "Name": "volnamepg",  "Options": {},  "Scope": "local"      }

查看卷的大小

卷的數據的默認存儲位置是/var/lib/docker/volumes/

[root@tar1 ~]# ll /var/lib/docker/volumes/  總用量 32  drwxr-xr-x. 3 root root    19 8月  23 18:27 14145904c49f663d8345ef789a9c352046a6a6d1ccd49f4d9e2dfd1a141f6707  drwxr-xr-x. 3 root root    19 8月  23 21:26 54943648b14cc92532aa20c95e8c7d70404a344eb427750aefd873b1b2003c74  drwxr-xr-x. 3 root root    19 8月  23 17:40 59aca22a107ede60abc1795edd9d7a46ff5799850a43f536a91598f74ffa7e01  drwxr-xr-x. 3 root root    19 8月  23 17:46 666f867e5062405683033d419458a85944568a007d6e82720149f48d306c4741  drwxr-xr-x. 3 root root    19 8月  23 17:26 7b3400e3155b8a3f3950f6a495883532de20270c9811de7ea0ab5e31d944a165  drwxr-xr-x. 3 root root    19 8月  23 17:42 8f56e930685166205e4d9fa5730f844aa7b0e0d1dc503e4ec4dd529023a5e17a  drwxr-xr-x. 3 root root    19 8月  23 17:43 9cc314ca59489507b54a0f9122d9ce4fc929c99a885dab2bcd8b42df516cfa27  drwxr-xr-x. 3 root root    19 8月  23 17:48 c5c58f45d54442366d2dff3d939988601a9b46c57d2a750ebeb3c087d1e27d10  drwxr-xr-x. 3 root root    19 8月  23 23:46 cf103a7ead15ff3e25f42e83703f06544cfbf018fe469d577002dff9f692bb6f  drwxr-xr-x. 3 root root    19 8月  23 19:43 d07687b3480ad42bc1d66fc7f609e831d10e917dbc6f95447af69113e8448d56  drwxr-xr-x. 3 root root    19 8月  23 22:52 fcb160da07e922021bec2f23d8b6b065fa389b83207f7e07538b5621b045966f  -rw-------. 1 root root 65536 8月  25 12:04 metadata.db  drwxr-xr-x. 3 root root    19 8月  23 19:43 volnamepg

刪除卷

如果卷不需要,可以使用下面的命令刪除卷,volnamepg就是卷的名字。

docker volume rm volnamepg

容器問題集錦

問題1:DNS解析有問題

DNS解析有問題

[root@tar1 yum.repos.d]# docker run hello-world  Unable to find image 'hello-world:latest' locally  latest: Pulling from library/hello-world

問題2:Networking will not work

[root@tar1 yum.repos.d]# docker run --name dockerPG11 -e POSTGRES_PASSWORD=Xzzp2008 -p 54322:54355 -d postgres:11.5  WARNING: IPv4 forwarding is disabled. Networking will not work.  df222cdf3efb532da55c33d63ec98d0d01f10b9927dc7d4f9704633e42669874

解決辦法:

vim /usr/lib/sysctl.d/00-system.conf

添加如下程式碼:

net.ipv4.ip_forward=1

重啟network服務

# systemctl restart network

問題3:容器ID衝突

[root@tar1 yum.repos.d]# docker run --rm --name dockerPG11 -e POSTGRES_PASSWORD=Xzzp2008 -p 54322:54355 -d postgres:11.5  docker: Error response from daemon: Conflict. The container name "/dockerPG11" is already in use by container "df222cdf3efb532da55c33d63ec98d0d01f10b9927dc7d4f9704633e42669874". You have to remove (or rename) that container to be able to reuse that name.  See 'docker run --help'.

解決辦法:

得到容器ID

docker ps –a

刪除容器

docker rm df222cdf3efb

問題4:driver failed programming external connectivity

[root@tar1 yum.repos.d]# docker run --name dockerPG11 -e POSTGRES_PASSWORD=Xzzp2008 -p 5432:54355 -d postgres:11.5  973e9066cefee0747fc51458060ec37168039a005a23b406f787e5ad9dee146a  docker: Error response from daemon: driver failed programming external connectivity on endpoint dockerPG11 (00b10c3636525f1a7c7c9ee8c30ad74c9d153be32d93fb02b01e028b05f3db55):  (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 5432 -j DNAT --to-destination 172.17.0.2:54355 ! -i docker0: iptables: No chain/target/match by that name.   (exit status 1)).

重啟docker和重啟實例

service docker restart

問題5:卷不能被刪除

[root@tar1 ~]# docker volume rm cf103a7ead15ff3e25f42e83703f06544cfbf018fe469d577002dff9f692bb6f  Error response from daemon: unable to remove volume: remove cf103a7ead15ff3e25f42e83703f06544cfbf018fe469d577002dff9f692bb6f: volume is in use - [83fd1e1408100846bc19348f6f01f5250a8881831d2383047a72fa9b26672701]  [root@tar1 ~]#

卷正在被容器使用,要先刪除容器

docker rm dockerPG11

總結

這是一系列文章的最後一部分,著重講了數據持久化,還講了PostgreSQL安裝部署,運維中遇到的一部分問題。也許將來,會在這三篇文章的基礎之上,添加一系列文章。