關於國內Docker映象,可以參考:Docker容器學習梳理--基礎知識(2) 的Docker映象使用。
如果我們需要在Docker環境下部署tomcat、redis、mysql、nginx、php等應用服務環境,有下面三種方法:
1)根據系統映象建立Docker容器,這時容器就相當於是一個虛擬機器,進入容器內部署應用環境。 然後將這種應用容器提交為新的映象,最後基於這種新的應用映象建立容器,建立時做好埠對映,就可以在外部訪問這些應用了。 2)直接通過docker pull拉取別人提交好的tomcat、nginx等應用程式映象,然後基於這些映象去建立容器。 3)通過dockerfile製作自己的應用程式映象。 根據系統映象部署應用容器,簡單做法如下: 1)啟動centos系統映象的容器my_container 2)在my_container容器裡部署例如nginx、php、mysql、php的服務 3)將部署完對應服務的容器my_container提交為新的映象 4)然後根據新映象去建立容器 5)這個新映象可以打包,匯入到別的Docker伺服器上使用
啟動容器時,記得要做好埠對映和目錄對映。埠對映是為了實現在外部能成功訪問到容器裡的應用服務。目錄對映是為了實現宿主機和容器的資料共享,這樣要對容器做修改時,直接在宿主機的對映目錄下做修改就行。修改資料的操作最好不要在容器內進行;原則上來說一個應用啟動一個容器,最好別在一個容器內啟動多個應用。
下面列舉幾個通過應用服務映象部署環境的例子:
Docker宿主機內網ip:192.168.1.23
Docker宿主機外網ip:103.110.186.23
Docker部分命令解釋:
-i:表示以“互動模式”執行容器 -t:表示容器啟動後會進入其命令列。加入這兩個引數後,容器建立就能登入進去。即分配一個偽終端。 --name :表示建立的容器名為my-nginx -v:表示目錄對映關係(前者是宿主機目錄,後者是對映到宿主機上的目錄),可以使用多個-v做多個目錄或檔案對映。 注意:最好做目錄對映,在宿主機上做修改,然後共享到容器上。 -d:在run後面加上-d引數,則會建立一個守護式容器在後臺執行(這樣建立容器後不會自動登入容器,如果只加-i -t兩個引數,建立後就會自動進去容器)。docker attch登入容器時如果卡著,按ctrl+c。 -p:表示埠對映,前者是宿主機埠,後者是容器內的對映埠。可以使用多個-p做多個埠對映
如果建立容器時報如下錯:
docker: Error response from daemon: failed to create endpoint mosredis on network bridge: iptables failed: iptables --wait -t filter -A DOCKER ! -i docker0 -o docker0 -p tcp -d 172.17.0.6 -j ACCEPT: iptables: No chain/target/match by that name. (exit status 1). 解決辦法: 一般來說,重啟docker服務,即可解決這個問題。 [root@localhost ~]# systemctl restart docker [root@localhost ~]# ---------------------------------- 如果重啟docker服務解決不了,那麼如下操作: [root@localhost ~]# pkill docker [root@localhost ~]# iptables -t nat -F [root@localhost ~]# ifconfig docker0 down [root@localhost ~]# brctl delbr docker0
一、redis容器環境部署
拉取redis映象(這裡拉取的是官方映象。也可以自己製作redis映象) [root@localhost ~]# docker pull redis [root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/redis latest e4a35914679d 2 weeks ago 182.9 MB 用下面的命令啟動Redis容器,記得要帶上“-d”引數.在run後面加上-d引數,則會建立一個守護式容器在後臺執行。 [root@localhost ~]# docker run --name myredis -d docker.io/redis 7a273a550005b8494be9d48970a6cc4efbaddd8a152261310a07237d43c9eb16 [root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7a273a550005 docker.io/redis "docker-entrypoint.sh" 3 seconds ago Up 2 seconds 6379/tcp myredis 連線容器的redis 1)第一種方式:找出容器的ip [root@localhost ~]# docker inspect --format='{{.NetworkSettings.IPAddress}}' 7a273a550005 172.17.0.2 然後連線容器的redis [root@localhost ~]# redis-cli -h 172.17.0.2 -p 6379 redis 172.17.0.2:6379> ping //驗證下redis服務是否已經連線上 PONG redis 172.17.0.2:6379> 2)第二種方式: [root@localhost ~]# docker run --name myredis -d docker.io/redis 5e260566925e9d6a31b47a47124feb10f3dcfce131c6aa67647881da7874502b [root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5e260566925e docker.io/redis "docker-entrypoint.sh" 13 minutes ago Up 13 minutes 6379/tcp myredis 下面的命令表示新建一個容器(命名為myredis2),將redis-cli執行在裡面。然後使用--link將這個容器和之前的redis容器(myredis)連線起來,並將其別名命名為redisdb。 Docker會在redis容器中的/etc/hosts路徑下為"redisdb"建立一個入口,並指向redis容器的IP地址. 這樣在這兩個容器裡就可以使用“redisdb”來作為提供redis容器的機器名,也就可以利用這個別名來連線容器redis。 [root@localhost ~]# docker run --rm -it --name myredis2 --link myredis:redisdb docker.io/redis /bin/bash root@4d4b25678b84:/data# redis-cli -h redisdb -p 6379 redisdb:6379> ping PONG redisdb:6379> ----------------------------------------------------- 當然,這樣也可以如上面先查容器ip進行連線 [root@localhost ~]# docker inspect --format='{{.NetworkSettings.IPAddress}}' 5e260566925e 172.17.0.2 [root@localhost ~]# redis-cli -h 172.17.0.2 -p 6379 redis 172.17.0.2:6379> 3)第三種方式:通過埠對映,外部連線redis容器應用的方法 建立Redis容器例項,這裡使用了Docker的埠對映機制,從而就可以使用Host伺服器的IP訪問這些redis例項. 如下建立三個redis容器例項 [root@localhost ~]# docker run -d --name node1 -p 7001:6379 docker.io/redis e4b8ca12d9e76441efe2074ab1109757a33a45aff71d1a553140d48d88133372 [root@localhost ~]# docker run -d --name node2 -p 7002:6379 docker.io/redis a8ee6f48f431651a0342fba289604046cd5b142f53a7eb43f655dde397a06a6f [root@localhost ~]# docker run -d --name node3 -p 7003:6379 docker.io/redis 2b61bf6765a8c254df9dd41d3ece6b12f4dd768976e6e22f327516063fc2e634 [root@localhost ~]# [root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2b61bf6765a8 docker.io/redis "docker-entrypoint.sh" 48 seconds ago Up 47 seconds 0.0.0.0:7003->6379/tcp node3 a8ee6f48f431 docker.io/redis "docker-entrypoint.sh" 55 seconds ago Up 55 seconds 0.0.0.0:7002->6379/tcp node2 e4b8ca12d9e7 docker.io/redis "docker-entrypoint.sh" About a minute ago Up About a minute 0.0.0.0:7001->6379/tcp node1 在容器之間建立連線 可以建立應用程式容器,使用--link引數來建立一個連線redis容器,使用別名,將會在redis容器和redis例項容器中建立一個安全的通訊隧道 ------------node1操作------------ [root@localhost ~]# docker run --link node1:db -i -t docker.io/redis /bin/bash root@8fd8d9db3cc1:/data# 現在可以測試連線,首先要先檢視下web應用程式容器的環境變數,可以用我們的ip和埠來連線redis容器 root@8fd8d9db3cc1:/data# env | grep DB_ DB_PORT_6379_TCP_PORT=6379 DB_NAME=/nauseous_heisenberg/db DB_PORT=tcp://172.17.0.2:6379 DB_PORT_6379_TCP=tcp://172.17.0.2:6379 DB_ENV_GOSU_VERSION=1.7 DB_ENV_REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-3.2.8.tar.gz DB_ENV_REDIS_VERSION=3.2.8 DB_PORT_6379_TCP_ADDR=172.17.0.2 DB_PORT_6379_TCP_PROTO=tcp DB_ENV_REDIS_DOWNLOAD_SHA1=6780d1abb66f33a97aad0edbe020403d0a15b67f 可以看到上面命令結果中有一個DB為字首的環境變數列表,DB來自指定別名連線對應的應用容器,這裡就可以使用DB_PORT_6379_TCP_ADDR變數連線到Redis容器。 root@8fd8d9db3cc1:/data# redis-cli -h $DB_PORT_6379_TCP_ADDR 172.17.0.2:6379> ping PONG 172.17.0.2:6379> set node1 redis-node1 OK 172.17.0.2:6379> get node1 "redis-node1" 172.17.0.2:6379> ------------node2操作------------ [root@localhost ~]# docker run --link node2:db2 -i -t docker.io/redis /bin/bash root@8eb2ccc2aff3:/data# env | grep DB2_ DB2_PORT_6379_TCP_PROTO=tcp DB2_ENV_REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-3.2.8.tar.gz DB2_PORT_6379_TCP_ADDR=172.17.0.3 DB2_ENV_GOSU_VERSION=1.7 DB2_PORT=tcp://172.17.0.3:6379 DB2_PORT_6379_TCP_PORT=6379 DB2_ENV_REDIS_VERSION=3.2.8 DB2_ENV_REDIS_DOWNLOAD_SHA1=6780d1abb66f33a97aad0edbe020403d0a15b67f DB2_PORT_6379_TCP=tcp://172.17.0.3:6379 DB2_NAME=/furious_kare/db2 root@8eb2ccc2aff3:/data# redis-cli -h $DB2_PORT_6379_TCP_ADDR 172.17.0.3:6379> ping PONG 172.17.0.3:6379> set node2 redis-node2 OK 172.17.0.3:6379> get node2 "redis-node2" 172.17.0.3:6379> ------------node3操作------------ [root@localhost ~]# docker run --link node3:db3 -i -t docker.io/redis /bin/bash root@d60d074ca66b:/data# env|grep DB3_ DB3_PORT_6379_TCP_ADDR=172.17.0.4 DB3_PORT_6379_TCP_PORT=6379 DB3_PORT_6379_TCP_PROTO=tcp DB3_ENV_REDIS_DOWNLOAD_SHA1=6780d1abb66f33a97aad0edbe020403d0a15b67f DB3_NAME=/amazing_kalam/db3 DB3_PORT=tcp://172.17.0.4:6379 DB3_ENV_REDIS_VERSION=3.2.8 DB3_ENV_GOSU_VERSION=1.7 DB3_ENV_REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-3.2.8.tar.gz DB3_PORT_6379_TCP=tcp://172.17.0.4:6379 root@d60d074ca66b:/data# redis-cli -h $DB3_PORT_6379_TCP_ADDR 172.17.0.4:6379> ping PONG 172.17.0.4:6379> set node3 redis-node3 OK 172.17.0.4:6379> get node3 "redis-node3" 172.17.0.4:6379> 這樣就可以在docker宿主機或其他伺服器上通過宿主機的ip地址以及對映的埠進行連線 [root@localhost ~]# redis-cli -h 192.168.1.23 -p 7001 redis 192.168.1.23:7001> get node1 "redis-node1" redis 192.168.1.23:7001> [root@localhost ~]# redis-cli -h 192.168.1.23 -p 7002 redis 192.168.1.23:7002> get node2 "redis-node2" redis 192.168.1.23:7002> [root@localhost ~]# redis-cli -h 192.168.1.23 -p 7003 redis 192.168.1.23:7003> get node3 "redis-node3" redis 192.168.1.23:7003>
注意一個細節:
建立應用容器的時候,一般會做埠對映,這樣是為了讓外部能夠訪問這些容器裡的應用。可以通過-P或-p引數來指定埠對映
1)當使用-p標記時,可以指定埠對映,即容器埠對映到宿主機的對應埠。可以用多個-p指定多個埠對映關係。如下: [root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/redis latest e4a35914679d 2 weeks ago 182.9 MB [root@localhost ~]# docker run --name myredis -p 63799:6379 -d docker.io/redis f5d5ff51ace01c5f26fcd65a6ca4853f8556a333c812576123ed71fd3d405737 [root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f5d5ff51ace0 docker.io/redis "docker-entrypoint.sh" 6 seconds ago Up 5 seconds 0.0.0.0:63799->6379/tcp myredis [root@localhost ~]# docker run --rm -it --name myredis2 --link myredis:redisdb docker.io/redis /bin/bash root@16b660ff9f65:/data# redis-cli -h redisdb -p 6379 redisdb:6379> ping PONG redisdb:6379> set test linux OK redisdb:6379> 在別的機器上通過訪問本機的63799埠連線這個容器的redis [root@linux-node2 ~]# redis-cli -h 192.168.1.23 -p 63799 192.168.1.23:63799> get test "linux" 192.168.1.23:63799> 2)當使用-P標記時,Docker 會隨機對映一個 49000~49900 的埠到內部容器開放的網路埠。如下: [root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/redis latest e4a35914679d 2 weeks ago 182.9 MB [root@localhost ~]# docker run --name myredis -P -d docker.io/redis 805d0e21e531885aad61d3e82395210b50621f1991ec4b7f9a0e25c815cc0272 [root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 805d0e21e531 docker.io/redis "docker-entrypoint.sh" 4 seconds ago Up 3 seconds 0.0.0.0:32768->6379/tcp myredis 從上面的結果中可以看出,本地主機的32768埠被對映到了redis容器的6379埠上,也就是說訪問本機的32768埠即可訪問容器內redis埠。 測試看下,登陸redis容器,隨意寫個資料 [root@localhost ~]# docker run --rm -it --name myredis2 --link myredis:redisdb docker.io/redis /bin/bash root@be44d955d6f4:/data# redis-cli -h redisdb -p 6379 redisdb:6379> set wangshibo huanqiu OK redisdb:6379> 在別的機器上通過上面對映的埠32768連線這個容器的redis [root@linux-node2 ~]# redis-cli -h 192.168.1.23 -p 32768 192.168.1.23:32768> get wangshibo "huanqiu"
二、nginx容器環境部署(下面是自己製作的應用映象)
[root@linux-node2 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE centos latest 67591570dd29 3 months ago 191.8 MB 為了防止centos7映象容器裡出現:Failed to get D-Bus connection: Operation not permitted 這個bug錯誤,需要在啟動容器的時候新增--privileged引數 並且後面登入容器執行的命令是/sbin/init,如下: [root@linux-node2 ~]# docker run --privileged -t -i centos /sbin/init 上面命令執行後,會一直卡著。這個不要緊,再開啟一個終端視窗,檢視並登入容器: [root@linux-node2 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES eaf66f1e43ab centos "/sbin/init" 16 seconds ago Up 15 seconds hungry_khorana [root@linux-node2 ~]# docker exec -it eaf66f1e43ab /bin/bash [root@eaf66f1e43ab /]# 接著在容器裡安裝nginx [root@eaf66f1e43ab /]# yum install -y wget lsof vim 新增CentOS 7 Nginx yum資源庫,然後安裝nginx [root@eaf66f1e43ab /]# rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm [root@eaf66f1e43ab /]# yum install -y nginx [root@eaf66f1e43ab conf.d]# pwd /etc/nginx/conf.d [root@eaf66f1e43ab conf.d]# cat test.conf server { listen 8080; server_name localhost; location / { root /var/www/html; index index.html; } } [root@eaf66f1e43ab conf.d]# mkdir -p /var/www/html [root@eaf66f1e43ab conf.d]# cat /var/www/html/test.html this is nginx page of docker!! [root@eaf66f1e43ab conf.d]# systemctl start nginx.service 將這個容器提交為新的映象 [root@linux-node2 ~]# docker stop eaf66f1e43ab [root@linux-node2 ~]# docker commit eaf66f1e43ab my-nginx [root@linux-node2 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE my-nginx latest 8dacda904e00 45 minutes ago 314.4 MB 將上面提交的映象打包 [root@linux-node2 ~]# docker save my-nginx > /root/my-nginx.tar.gz 然後將這個映象包上傳到別的機器上,比如上傳到192.168.1.23機器上的/root下。 在192.168.1.23機器上匯入新映象 [root@localhost ~]# docker load < /root/my-nginx.tar.gz [root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE my-nginx latest 8dacda904e00 50 minutes ago 314.4 MB 啟動nginx容器 [root@localhost ~]# docker run -t -i --privileged --name nginx -v /var/www/html:/var/www/html -p 8899:8080 my-nginx /sbin/init 上面命令執行後會卡著,在另一個埠視窗: [root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3b5cbea50052 my-nginx "/sbin/init" 36 seconds ago Up 35 seconds 0.0.0.0:8899->8080/tcp nginx [root@localhost ~]# docker exec -t -i 3b5cbea50052 /bin/bash [root@3b5cbea50052 /]# [root@3b5cbea50052 /]# systemctl start nginx.service [root@3b5cbea50052 /]# ps -ef|grep nginx root 117 1 0 16:47 ? 00:00:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf nginx 118 117 0 16:47 ? 00:00:00 nginx: worker process root 120 88 0 16:47 ? 00:00:00 grep --color=auto nginx [root@3b5cbea50052 /]# cat /etc/nginx/conf.d/test.conf server { listen 8080; server_name localhost; location / { root /var/www/html; index index.html; } } [root@3b5cbea50052 /]# cat /etc/nginx/conf.d/test.conf server { listen 8080; server_name localhost; location / { root /var/www/html; index index.html; } } [root@localhost ~]# cat /var/www/html/index.html this is page of Docker-nginx-test!!! Docker宿主機的iptables防火牆設定好對映埠8899
測試訪問
----------------------------------------------------------------------------
根據nginx應用映象直接建立:
[root@localhost ~]# docker pull nginx [root@localhost ~]# docker images docker.io/nginx latest 5e69fe4b3c31 4 days ago 182.5 MB [root@localhost ~]# docker run -ti -d --name my-nginx -p 9988:80 docker.io/nginx /bin/bash 55ae1f2b1eca6638e11865171f322a55cfa277a0aec06526428a1887229b022e [root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 55ae1f2b1eca docker.io/nginx "/bin/bash" 3 seconds ago Up 3 seconds 443/tcp, 0.0.0.0:9988->80/tcp my-nginx [root@localhost ~]# docker exec -ti my-nginx /bin/bash root@55ae1f2b1eca:/# find / -name nginx /etc/default/nginx /etc/init.d/nginx /etc/logrotate.d/nginx /etc/nginx /usr/lib/x86_64-linux-gnu/perl5/5.20/auto/nginx /usr/lib/nginx /usr/sbin/nginx /usr/share/doc/nginx /usr/share/lintian/overrides/nginx /usr/share/nginx /var/cache/nginx /var/log/nginx root@55ae1f2b1eca:/# mkdir -p /var/web/www root@55ae1f2b1eca:/# exit exit [root@localhost ~]# docker cp my-nginx:/etc/nginx /var/ [root@localhost ~]# mkdir -p /var/web/www [root@localhost ~]# cd /var/web/www/ [root@localhost www]# echo "12313123" > index.html [root@localhost ~]# docker stop my-nginx my-nginx [root@localhost ~]# docker rm my-nginx my-nginx [root@localhost ~]# docker run -ti -d --name my-nginx -v /var/nginx:/etc/nginx -v /var/web/www:/var/web/www -p 8899:80 docker.io/nginx /bin/bash af8a4594d643197d204200cd1e3b6a3d000cae71ef92826c0e40edfa87026a2a [root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES af8a4594d643 docker.io/nginx "/bin/bash" 52 seconds ago Up 50 seconds 443/tcp, 0.0.0.0:8899->80/tcp my-nginx [root@localhost ~]# vim /etc/sysconfig/iptables ....... -A INPUT -p tcp -m state --state NEW -m tcp --dport 8899 -j ACCEPT [root@localhost ~]# systemctl restart iptables.service [root@localhost ~]# docker exec -ti my-nginx /etc/init.d/nginx start 然後就可以通過訪問http://宿主機ip:8899,進而訪問到nginx容器應用了。 接著測試下 [root@localhost ~]# mv /var/nginx/conf.d/default.conf /var/nginx/conf.d/default.conf.bak [root@localhost ~]# cat /var/nginx/conf.d/test.conf server { listen 80; server_name localhost; location / { root /var/web/www; index index.html; } } [root@localhost ~]# echo "12312313" > /var/www/html/test.html 接著重啟容器的nginx應用 [root@localhost ~]# docker exec -t -i my-nginx /etc/init.d/nginx restart 測試訪問(192.168.1.23是宿主機ip) [root@localhost ~]# curl http://192.168.1.23:8899/ 12313123
可以使用Nginx+Docker實現負載均衡
1)在本機部署兩個nginx的docker容器,埠對應關係分別是8088:80、8089:80 2)在本機在安裝nginx,然後在nginx配置檔案中使用upstream將訪問請求負載到本機的8088和8089埠上, 這樣也就是將訪問請求負載到兩個容器上了 此方案的原理是將宿主機的埠和docker容器的埠做一個對映(即訪問宿主機的某埠會對映到docker容器對應的埠), 然後在宿主機通過配置Nginx,即可達到訪問宿主機的某埠,按規則分配到指定的服務地址,即完成了負載均衡。
三、tomcat容器環境部署
[root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/centos latest 67591570dd29 3 months ago 191.8 MB [root@localhost ~]# docker run -it --name=container1 docker.io/centos [root@9df6dc740f01 /]# java -version //容器裡安裝java 上傳宿主機的tomcat到容器裡 [root@localhost ~]# cd /usr/local/src/ [root@localhost src]# ls apache-tomcat-7.0.57.tar.gz [root@localhost src]# docker cp apache-tomcat-7.0.57.tar.gz 9df6dc740f01:/usr/local/src/ 登陸容器,安裝tomcat [root@9df6dc740f01 /]# cd /usr/local/src/ [root@9df6dc740f01 src]# ls apache-tomcat-7.0.57.tar.gz [root@9df6dc740f01 src]# tar -zvxf apache-tomcat-7.0.57.tar.gz [root@9df6dc740f01 src]# mv apache-tomcat-7.0.57 /usr/local/tomcat7 將此容器提交為新的映象 [root@localhost ~]# docker commit container1 tomcat7 sha256:2ec9e2eb978a4af266608fdfd70320bff0886b245a9a2d249cdefdfe70760acb [root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE tomcat7 latest 2ec9e2eb978a 3 minutes ago 562.3 MB [root@localhost ~]# docker stop container1 container1 [root@localhost ~]# docker rm container1 container1 利用新提交的映象啟動tomcat容器 [root@localhost ~]# docker run -t -i -d --name=tomcat -p 8888:8080 tomcat7 /bin/bash 25f20fa6d54a1b2e2454a4d0a3966854e2fe4d81c54c366a1b07da47695f5418 [root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 25f20fa6d54a tomcat7 "/bin/bash" 3 seconds ago Up 2 seconds 0.0.0.0:8888->8080/tcp tomcat 登陸容器,啟動tomcat程式 [root@localhost ~]# docker attach tomcat [root@25f20fa6d54a ~]# /usr/local/tomcat7/bin/startup.sh Using CATALINA_BASE: /usr/local/tomcat7 Using CATALINA_HOME: /usr/local/tomcat7 Using CATALINA_TMPDIR: /usr/local/tomcat7/temp Using JRE_HOME: /usr Using CLASSPATH: /usr/local/tomcat7/bin/bootstrap.jar:/usr/local/tomcat7/bin/tomcat-juli.jar Tomcat started. [root@25f20fa6d54a ~]# ps -ef|grep tomcat root 62 1 92 07:52 ? 00:00:03 java -Djava.util.logging.config.file=/usr/local/tomcat7/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed.dirs=/usr/local/tomcat7/endorsed -classpath /usr/local/tomcat7/bin/bootstrap.jar:/usr/local/tomcat7/bin/tomcat-juli.jar -Dcatalina.base=/usr/local/tomcat7 -Dcatalina.home=/usr/local/tomcat7 -Djava.io.tmpdir=/usr/local/tomcat7/temp org.apache.catalina.startup.Bootstrap start root 84 1 0 07:52 ? 00:00:00 grep --color=auto tomcat
宿主機防火牆開通8888埠,然後就可以在外部容器的tomcat了(通過宿主機的8888埠進行對映)
[root@localhost ~]# vim /etc/sysconfig/iptables ....... -A INPUT -p tcp -m state --state NEW -m tcp --dport 8888 -j ACCEPT [root@localhost ~]# systemctl restart iptables.service
-------------------------------------------------------------------------------------------- 在部署應用容器的時候,最好將容器的配置檔案及資料目錄跟宿主機目錄做個對映關係!最好不要在容器內修改資料。 這樣就可以通過宿主機的共享檔案及共享目錄去控制對應容器的資料了。 先啟動tomcat容器,將tomcat的配置檔案和資料目錄跟宿主機做個對映。 [root@localhost ~]# docker cp tomcat:/usr/local/tomcat7/webapps /mnt/ [root@localhost ~]# docker cp tomcat:/usr/local/tomcat7/conf /mnt/ [root@localhost ~]# ls /mnt/conf/ catalina.policy catalina.properties context.xml logging.properties server.xml tomcat-users.xml web.xml [root@localhost ~]# ls /mnt/webapps/ docs examples host-manager manager ROOT 然後關閉和刪除這個tomcat容器,重啟啟動,啟動時做目錄對映關係 [root@localhost ~]# docker stop tomcat tomcat [root@localhost ~]# docker rm tomcat tomcat [root@localhost ~]# docker run -t -i -d --name=tomcat -v /mnt/webapps:/usr/local/tomcat7/webapps -v /mnt/conf:/usr/local/tomcat7/conf -p 8888:8080 tomcat7 /bin/bash 63799add4a628b1b690eb9e538001e6872b12e8e03e39b4e7275f7bf49c2645f [root@localhost ~]# docker attach tomcat [root@63799add4a62 /]# /usr/local/tomcat7/bin/startup.sh Using CATALINA_BASE: /usr/local/tomcat7 Using CATALINA_HOME: /usr/local/tomcat7 Using CATALINA_TMPDIR: /usr/local/tomcat7/temp Using JRE_HOME: /usr Using CLASSPATH: /usr/local/tomcat7/bin/bootstrap.jar:/usr/local/tomcat7/bin/tomcat-juli.jar Tomcat started. ......................溫馨提示一下..................... 上面在建立容器時啟動的程式是/bin/bash,容器建立成功後,需要啟動建立裡其他的程式,比如上面的tomcat程式。 那麼除了上面直接登入容器內啟動tomcat程式外,還可以在宿主機上通過docker exec啟動(前提是容器在啟動狀態中) docker exec 命令使用者在執行狀態中的容器內再次啟動新的程式。命令格式:docker exec [OPTIONS] CONTAINER COMMAND [ARG...] [root@localhost ~]# docker exec tomcat /usr/local/tomcat7/bin/startup.sh //如果啟動中出現卡的情況,就ctrl+c,不影響啟動結果 Tomcat started. [root@linux-node2 ~]# docker attach my_tomcat [root@f268eefdc283 /]# ps -ef|grep tomcat root 30 0 1 10:13 ? 00:00:06 java -Djava.util.logging.config.file=/usr/local/tomcat7/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed.dirs=/usr/local/tomcat7/endorsed -classpath /usr/local/tomcat7/bin/bootstrap.jar:/usr/local/tomcat7/bin/tomcat-juli.jar -Dcatalina.base=/usr/local/tomcat7 -Dcatalina.home=/usr/local/tomcat7 -Djava.io.tmpdir=/usr/local/tomcat7/temp org.apache.catalina.startup.Bootstrap start root 76 1 0 10:23 ? 00:00:00 grep --color=auto tomcat -------------------------------------------------------------------------------------------- 如上在本機制作了tomcat7的映象,可以將這個映象上傳到別的機器上進行tomcat容器部署 [root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE tomcat7 latest 2ec9e2eb978a 39 minutes ago 562.3 MB [root@localhost ~]# docker save tomcat7 > /opt/tomcat7.tar.gz [root@localhost ~]# rsync -e "ssh -p22" -avpgolr /opt/tomcat7.tar.gz 192.168.1.17:/opt/ 然後在192.168.1.17機器上部署tomcat容器 [root@linux-node2 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE tomcat7 latest 2ec9e2eb978a 58 minutes ago 562.3 MB [root@linux-node2 ~]# docker run -t -i -d --name=my_tomcat tomcat7 /bin/bash 8657fa536c4a6308801d96b585671a22d08795bd891b0b2b20d86b843cde0040 [root@linux-node2 ~]# docker attach my_tomcat [root@8657fa536c4a /]# /usr/local/tomcat7/bin/startup.sh Using CATALINA_BASE: /usr/local/tomcat7 Using CATALINA_HOME: /usr/local/tomcat7 Using CATALINA_TMPDIR: /usr/local/tomcat7/temp Using JRE_HOME: /usr Using CLASSPATH: /usr/local/tomcat7/bin/bootstrap.jar:/usr/local/tomcat7/bin/tomcat-juli.jar Tomcat started. --------------------------------------------------------------------------------------------
四、Mysql容器環境部署
[root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/centos latest 67591570dd29 3 months ago 191.8 MB 啟動容器,進入容器內編譯安裝mysql [root@localhost ~]# docker run -t -i docker.io/centos /bin/bash [root@2ccd29e52286 /]# rpm -qa | grep mysql //確保沒有自帶安裝mysql,有的話就解除安裝 [root@2ccd29e52286 /]# yum -y install make gcc-c++ cmake bison-devel ncurses-devel [root@2ccd29e52286 /]# groupadd mysql [root@2ccd29e52286 /]# useradd -g mysql mysql -M -s /sbin/nologin [root@2ccd29e52286 /]# cd /usr/local/src [root@2ccd29e52286 src]# wget -c http://ftp.ntu.edu.tw/MySQL/Downloads/MySQL-5.6/mysql-5.6.34.tar.gz [root@2ccd29e52286 src]# tar -zxvf mysql-5.6.34.tar.gz [root@2ccd29e52286 src]# cd mysql-5.6.34/ [root@2ccd29e52286 mysql-5.6.34]# cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_DATADIR=/data/mysql/data -DSYSCONFDIR=/etc -DWITH_MYISAM_STORAGE_ENGINE=1 -DWITH_INNOBASE_STORAGE_ENGINE=1 -DWITH_MEMORY_STORAGE_ENGINE=1 -DWITH_READLINE=1 -DMYSQL_UNIX_ADDR=/var/lib/mysql/mysql.sock -DMYSQL_TCP_PORT=3306 -DENABLED_LOCAL_INFILE=1 -DWITH_PARTITION_STORAGE_ENGINE=1 -DEXTRA_CHARSETS=all -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci [root@2ccd29e52286 mysql-5.6.34]# make && make install [root@2ccd29e52286 mysql-5.6.34]# mkdir -p /data/mysql/data [root@2ccd29e52286 mysql-5.6.34]# chown -R mysql:mysql /usr/local/mysql [root@2ccd29e52286 mysql-5.6.34]# chown -R mysql:mysql /data/mysql/data 初始化mysql [root@2ccd29e52286 mysql-5.6.34]# cd /usr/local/mysql [root@2ccd29e52286 mysql]# ./scripts/mysql_install_db --basedir=/usr/local/mysql --datadir=/data/mysql/data --user=mysql ------------------------------------------------------------------------------------------- 如果報錯:FATAL ERROR: please install the following Perl modules before executing ./scripts/mysql_install_db: Data::Dumper 解決辦法: [root@2ccd29e52286 mysql]# yum install -y perl-Module-Install.noarch ------------------------------------------------------------------------------------------ 啟動mysql,並設定密碼 [root@2ccd29e52286 mysql]# cp support-files/mysql.server /etc/init.d/mysql [root@2ccd29e52286 mysql]# /etc/init.d/mysql start [root@2ccd29e52286 mysql]# mysql -uroot ..... 修改root密碼,執行命令如下 mysql> SET PASSWORD = PASSWORD('123456'); 若要設定root使用者可以遠端訪問,執行 mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'password' WITH GRANT OPTION; 使授權立即生效 mysql> FLUSH PRIVILEGES; 提交為新映象 [root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2ccd29e52286 docker.io/centos "/bin/bash" 3 hours ago Up 3 hours modest_bose [root@localhost ~]# docker commit 2ccd29e52286 mysql sha256:3b965b11e7a01b9422c8d82a8352c60c83545698309d9511b4df6371bcfcd6a1 [root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE mysql latest 3b965b11e7a0 6 minutes ago 4.511 GB docker.io/centos latest 67591570dd29 3 months ago 191.8 MB 根據新提交的映象,啟動mysql容器 [root@localhost ~]# docker stop 2ccd29e52286 2ccd29e52286 [root@localhost ~]# docker rm 2ccd29e52286 //當然這個之前啟動的容器也可以不刪除,忽略就行。 2ccd29e52286 [root@localhost ~]# docker run -t -i -d --name=my_mysql -p 33061:3306 mysql /bin/bash a02f56c3e7313733bcd58414d5dcd5501f8504352206ee321e9e2aeab15d6269 [root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a02f56c3e731 mysql "/bin/bash" 7 seconds ago Up 6 seconds 0.0.0.0:33061->3306/tcp my_mysql 啟動容器的mysql服務方法(也可以在上面建立容器的時候直接啟動,即將/bin/bash命令換成mysql啟動命令): 1)直接在宿主機上通過docker exec命令啟動 [root@localhost ~]# docker exec my_mysql /etc/init.d/mysql start //如果啟動後出現卡的情況,就ctrl+c,不影響啟動結果 Starting MySQL SUCCESS! 2)登陸容器內啟動 [root@localhost ~]# docker attach my_mysql [root@a02f56c3e731 /]# /etc/init.d/mysql start Starting MySQL SUCCESS! 檢視容器啟動的程式 [root@localhost ~]# docker top my_mysql UID PID PPID C STIME TTY TIME CMD root 7340 28948 0 14:21 pts/1 00:00:00 /bin/bash root 8595 7340 0 14:28 pts/1 00:00:00 /bin/sh /usr/local/mysql//bin/mysqld_safe --datadir=/data/mysql/data --pid-file=/data/mysql/data/mysql.pid mysql 9376 8595 0 14:28 pts/1 00:00:00 /usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql/ --datadir=/data/mysql/data --plugin-dir=/usr/local/mysql//lib/plugin --user=mysql --log-error=/data/mysql/data/mysql-error.log --pid-file=/data/mysql/data/mysql.pid --socket=/usr/local/mysql/var/mysql.sock --port=3306 登陸容器檢視 [root@a02f56c3e731 /]# netstat -tunlp //首先yum安裝net-tools Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN - 在容器內的mysql裡寫入一些資料 [root@a02f56c3e731 /]# /usr/local/mysql/bin/mysql -p123456 Warning: Using a password on the command line interface can be insecure. ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (111) [root@a02f56c3e731 /]# ln -s /usr/local/mysql/var/mysql.sock /var/lib/mysql/mysql.sock ln: failed to create symbolic link '/var/lib/mysql/mysql.sock': File exists [root@a02f56c3e731 /]# rm -f /var/lib/mysql/mysql.sock [root@a02f56c3e731 /]# ln -s /usr/local/mysql/var/mysql.sock /var/lib/mysql/mysql.sock [root@a02f56c3e731 /]# /usr/local/mysql/bin/mysql -p123456 ....... mysql> create database wangshibo; Query OK, 1 row affected (0.00 sec) mysql> use wangshibo; Database changed mysql> create table hehe( -> id int(3), -> name varchar(10) -> ); Query OK, 0 rows affected (0.03 sec) mysql> insert into hehe values(1,"wanglei"); Query OK, 1 row affected (0.01 sec) mysql> insert into hehe values(2,"zhaomin"); Query OK, 1 row affected (0.01 sec) 檢視容器ip,可以登陸容器內ifconfig檢視(首先要yum安裝net-tools) [root@a02f56c3e731 /]# ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.17.0.2 netmask 255.255.0.0 broadcast 0.0.0.0 inet6 fe80::42:acff:fe11:2 prefixlen 64 scopeid 0x20<link> ether 02:42:ac:11:00:02 txqueuelen 0 (Ethernet) RX packets 117 bytes 319373 (311.8 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 102 bytes 7042 (6.8 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 0 (Local Loopback) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 或者在宿主機使用docker inspect命令檢視容器ip [root@localhost ~]# docker inspect my_mysql|grep IPAddress "SecondaryIPAddresses": null, "IPAddress": "172.17.0.2", "IPAddress": "172.17.0.2", 在宿主機本地連線容器的mysql [root@localhost ~]# mysql -u root -h 172.17.0.2 -p123456 ERROR 1130 (HY000): Host '172.17.0.1' is not allowed to connect to this MySQL server 出現錯誤的原因: 容器的網路ip是根據宿主機的虛擬橋接網路卡docker0自動分配的,而docker0的ip預設是172.17.0.1. 容器的mysql內需要給這個ip授權。 [root@localhost ~]# ifconfig docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.17.0.1 netmask 255.255.0.0 broadcast 0.0.0.0 .......... 登陸容器內的mysql,進行授權 [root@a02f56c3e731 /]# /usr/local/mysql/bin/mysql -p123456 ....... mysql> select host,user,password from mysql.user; +--------------+------+-------------------------------------------+ | host | user | password | +--------------+------+-------------------------------------------+ | localhost | root | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 | | 2ccd29e52286 | root | | | 127.0.0.1 | root | | | ::1 | root | | | localhost | | | | 2ccd29e52286 | | | +--------------+------+-------------------------------------------+ 6 rows in set (0.00 sec) mysql> grant all privileges on *.* to root@'%' identified by "123456"; Query OK, 0 rows affected (0.00 sec) mysql> flush privileges; Query OK, 0 rows affected (0.00 sec) mysql> select host,user,password from mysql.user; +--------------+------+-------------------------------------------+ | host | user | password | +--------------+------+-------------------------------------------+ | localhost | root | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 | | 2ccd29e52286 | root | | | 127.0.0.1 | root | | | ::1 | root | | | localhost | | | | 2ccd29e52286 | | | | % | root | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 | +--------------+------+-------------------------------------------+ 8 rows in set (0.00 sec) 再次在宿主機本機嘗試連線容器的mysql,發現可以正常連線! [root@localhost ~]# mysql -u root -h 172.17.0.2 -p123456 ....... MySQL [(none)]> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | test | | wangshibo | +--------------------+ 5 rows in set (0.01 sec) MySQL [(none)]> select * from wangshibo.hehe; +------+---------+ | id | name | +------+---------+ | 1 | wanglei | | 2 | zhaomin | +------+---------+ 2 rows in set (0.00 sec) --------------------------------------------------------------------------------------------------- 也可以再建立一個容器,使用--link進行容器連結。 這裡需要特別注意一下"--link=my_mysql:mydb"(中間可以使用=,也可以空格隔開),這個引數是告訴容器需要使用my_mysql容器,並將其別名命名為mydb,這樣在這兩個容器裡就可以使用mydb來作為提供mysql資料庫服務的機器名。 [root@localhost ~]# docker run --rm -it --name mymysql2 --link my_mysql:mydb docker.io/centos /bin/bash [root@f1534ad473f4 /]# cat /etc/hosts 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters 172.17.0.2 mydb 33d784ee3121 my_mysql 172.17.0.4 f1534ad473f4 [root@f1534ad473f4 /]# mysql -u root -h mydb -p123456 ...... MySQL [(none)]> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | test | | wangshibo | +--------------------+ 5 rows in set (0.00 sec) MySQL [(none)]> select * from wangshibo.hehe; +------+---------+ | id | name | +------+---------+ | 1 | wanglei | | 2 | zhaomin | +------+---------+ 2 rows in set (0.00 sec) ------------------------------------------------------------------------------------------------ 在外部連線my_mysql容器內的mysql,就需要通過對映到宿主機的33061埠了(首先在宿主機的iptables裡開放33061埠的訪問) [root@localhost ~]# vim /etc/sysconfig/iptables ...... -A INPUT -p tcp -m state --state NEW -m tcp --dport 33061 -j ACCEPT [root@localhost ~]# systemctl restart iptables.service 這樣在遠端,就可以使用宿主機的對映埠33061訪問容器mysql (使用-P指定埠進行mysql的連線) [root@huanqiu_web1 ~]# mysql -uroot -h103.10.86.23 -P33061 -p123456 ....... mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | test | | wangshibo | +--------------------+ 5 rows in set (0.00 sec) mysql> select * from wangshibo.hehe; +------+---------+ | id | name | +------+---------+ | 1 | wanglei | | 2 | zhaomin | +------+---------+ 2 rows in set (0.00 sec) mysql>
----------------------------------------------------------------------------------------
上面容器內使用的是編譯安裝mysql,也可以yum安裝:
[root@localhost ~]# docker run -t -i --privileged -i --name=wang docker.io/centos /sbin/init //容器啟動後,會一直在卡著的狀態中,先不用管,開啟另一個終端視窗執行下面命令登陸容器 [root@localhost ~]# docker exec -it wang /bin/bash [root@e9efd323782a /]# yum install -y wget net-tools [root@e9efd323782a /]# wget http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm [root@e9efd323782a /]# rpm -ivh mysql-community-release-el7-5.noarch.rpm [root@e9efd323782a /]# yum install mysql-community-server [root@e9efd323782a /]# systemctl start mysqld [root@e9efd323782a /]# lsof -i:3306 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME mysqld 453 mysql 10u IPv6 32200473 0t0 TCP *:mysql (LISTEN)
其他應用容器的部署與上面操作類似~