containerhtml
代碼app,構建,運行,分享(推送)imagenode
mkdir img1 cd img1 [root@cu-tmp-201 img1]# ls app.py Dockerfile requirements.txt -------------------------------------------------------- vi Dockerfile # Use an official Python runtime as a parent image FROM python:2.7-slim # Set the working directory to /app WORKDIR /app # Copy the current directory contents into the container at /app COPY . /app # Install any needed packages specified in requirements.txt RUN pip install --trusted-host pypi.python.org -r requirements.txt # Make port 80 available to the world outside this container EXPOSE 80 # Define environment variable ENV NAME World # Run app.py when the container launches CMD ["python", "app.py"] ------------------------------------------------------- vi requirements.txt Flask Redis ------------------------------------------------------- vi app.py from flask import Flask from redis import Redis, RedisError import os import socket # Connect to Redis redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2) app = Flask(__name__) @app.route("/") def hello(): try: visits = redis.incr("counter") except RedisError: visits = "<i>cannot connect to Redis, counter disabled</i>" html = "<h3>Hello {name}!</h3>" \ "<b>Hostname:</b> {hostname}<br/>" \ "<b>Visits:</b> {visits}" return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits) if __name__ == "__main__": app.run(host='0.0.0.0', port=80) ========================================== docker build -t=img1 . docker build -t=img1:v0.01 . docker build -t createyuan/my-first:a1 . 運行在前臺 docker run -p 4000:80 img1 運行在後臺 docker run -d -p 4000:80 img1 [root@cu-tmp-201 img1]# docker build -t=img1 . Sending build context to Docker daemon 5.12kB Step 1/7 : FROM python:2.7-slim 2.7-slim: Pulling from library/python 743f2d6c1f65: Pull complete 9bfbedfce8de: Pull complete 7f4da2474cef: Pull complete ffc893575679: Pull complete Digest: sha256:686bc67cbebf4c4fb0d96d55650d8704d00ccb6b9c6bdd0bee5fad48b827a6cb Status: Downloaded newer image for python:2.7-slim ---> eb40dcfcbc42 Step 2/7 : WORKDIR /app ---> Running in bb3e3e32cc1f Removing intermediate container bb3e3e32cc1f ---> bed29d83d8aa Step 3/7 : COPY . /app ---> d189b5eac250 Step 4/7 : RUN pip install --trusted-host pypi.python.org -r requirements.txt ---> Running in 5e9d4ad3a252 DEPRECATION: Python 2.7 will reach the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 won't be maintained after that date. A future version of pip will drop support for Python 2.7. Collecting Flask (from -r requirements.txt (line 1)) Downloading https://files.pythonhosted.org/packages/9a/74/670ae9737d14114753b8c8fdf2e8bd212a05d3b361ab15b44937dfd40985/Flask-1.0.3-py2.py3-none-any.whl (92kB) Collecting Redis (from -r requirements.txt (line 2)) Downloading https://files.pythonhosted.org/packages/ac/a7/cff10cc5f1180834a3ed564d148fb4329c989cbb1f2e196fc9a10fa07072/redis-3.2.1-py2.py3-none-any.whl (65kB) Collecting itsdangerous>=0.24 (from Flask->-r requirements.txt (line 1)) Downloading https://files.pythonhosted.org/packages/76/ae/44b03b253d6fade317f32c24d100b3b35c2239807046a4c953c7b89fa49e/itsdangerous-1.1.0-py2.py3-none-any.whl Collecting Jinja2>=2.10 (from Flask->-r requirements.txt (line 1)) Downloading https://files.pythonhosted.org/packages/1d/e7/fd8b501e7a6dfe492a433deb7b9d833d39ca74916fa8bc63dd1a4947a671/Jinja2-2.10.1-py2.py3-none-any.whl (124kB) Collecting Werkzeug>=0.14 (from Flask->-r requirements.txt (line 1)) Downloading https://files.pythonhosted.org/packages/9f/57/92a497e38161ce40606c27a86759c6b92dd34fcdb33f64171ec559257c02/Werkzeug-0.15.4-py2.py3-none-any.whl (327kB) Collecting click>=5.1 (from Flask->-r requirements.txt (line 1)) Downloading https://files.pythonhosted.org/packages/fa/37/45185cb5abbc30d7257104c434fe0b07e5a195a6847506c074527aa599ec/Click-7.0-py2.py3-none-any.whl (81kB) Collecting MarkupSafe>=0.23 (from Jinja2>=2.10->Flask->-r requirements.txt (line 1)) Downloading https://files.pythonhosted.org/packages/fb/40/f3adb7cf24a8012813c5edb20329eb22d5d8e2a0ecf73d21d6b85865da11/MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_x86_64.whl Installing collected packages: itsdangerous, MarkupSafe, Jinja2, Werkzeug, click, Flask, Redis Successfully installed Flask-1.0.3 Jinja2-2.10.1 MarkupSafe-1.1.1 Redis-3.2.1 Werkzeug-0.15.4 click-7.0 itsdangerous-1.1.0 Removing intermediate container 5e9d4ad3a252 ---> 69c2d8844363 Step 5/7 : EXPOSE 80 ---> Running in 24367df46ae6 Removing intermediate container 24367df46ae6 ---> f3c8ef356dbc Step 6/7 : ENV NAME World ---> Running in 2a234b7f8f21 Removing intermediate container 2a234b7f8f21 ---> 9619ded601a9 Step 7/7 : CMD ["python", "app.py"] ---> Running in 03cbc7a6be80 Removing intermediate container 03cbc7a6be80 ---> 5ff25ce7dd38 Successfully built 5ff25ce7dd38 Successfully tagged img1:latest [root@cu-tmp-201 img1]# docker run -p 4000:80 img1 * Serving Flask app "app" (lazy loading) * Environment: production WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Debug mode: off * Running on http://0.0.0.0:80/ (Press CTRL+C to quit) 192.168.4.171 - - [19/May/2019 07:18:25] "GET / HTTP/1.1" 200 - 192.168.4.171 - - [19/May/2019 07:18:25] "GET /favicon.ico HTTP/1.1" 404 - 用瀏覽器或命令行來訪問 [root@cu-tmp-201 ~]# curl http://localhost:4000 <h3>Hello World!</h3><b>Hostname:</b> ddafad51e416<br/><b>Visits:</b> <i>cannot connect to Redis, counter disabled</i> ctrl+c以後,再次鏈接就報錯 [root@cu-tmp-201 ~]# curl http://localhost:4000 curl: (7) Failed connect to localhost:4000; Connection refused 運行在後臺 [root@cu-tmp-201 img1]# docker run -d -p 4000:80 img1 22cfe0d0d33bad99c403a785c5972cda33a9f422ca341568ce7320d79892ebef [root@cu-tmp-201 img1]# docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 22cfe0d0d33b img1 "python app.py" 4 seconds ago Up 2 seconds 0.0.0.0:4000->80/tcp condescending_haibt [root@cu-tmp-201 img1]# docker container stop 22cfe0d0d33b 22cfe0d0d33b docker tag img1 createyuan/my-first:devapp docker push createyuan/my-first:devapp 而後在任意機器上運行 docker run -d -p 4000:80 username/repository:tag docker run -d -p 4000:80 createyuan/my-first:devapp [root@cu-tmp-201 img1]# docker push createyuan/my-first:devapp The push refers to repository [docker.io/createyuan/my-first] 6611f8494790: Pushed f8b091cbf2de: Pushed d570601a4e8e: Pushed 0ec0d723449a: Mounted from library/python 5c78e81a8fd9: Mounted from library/python 7b6b548a54d0: Mounted from library/python 6270adb5794c: Pushed devapp: digest: sha256:85d48d62c2507a38bd5f2b63e069dac76ccf8fbea00c78f025b881d202cb0f5d size: 1788
scale applicationpython
serviceslinux
single-host modegit
分佈式應用更上一層 server與service什麼關係 scale application 在一個分佈式應用中,不一樣的應用片(軟件片)叫作服務 一個服務只運行一個鏡像 Scaling a service changes the number of container instances running that piece of software, assigning more computing resources to the service in the process. 伸縮一個服務改變了軟件片運行容器實例的數量,在進程中給服務分配更多的計算資源 Luckily it’s very easy to define, run, and scale services with the Docker platform -- just write a docker-compose.yml file. 幸運的是它很是簡單來定義,運行,伸縮服務,用docker平臺,只需編寫compose.yml文件。 A single container running in a service is called a task. ---------------------------------------- vi docker-compose.yml version: "3" services: web: # replace username/repo:tag with your name and image details image: createyuan/my-first:devapp deploy: replicas: 3 resources: limits: cpus: "0.1" memory: 50M restart_policy: condition: on-failure ports: - "4000:80" networks: - webnet networks: webnet: ---------------------------------------- docker swarm init docker stack deploy -c docker-compose.yml services-dist docker service ls [root@cu-tmp-201 img1]# docker swarm init Swarm initialized: current node (bbc6waopcxs6pof5dr8zo568j) is now a manager. To add a worker to this swarm, run the following command: docker swarm join --token SWMTKN-1-3g4ucshflo3wz2hs9lrhuzcyl05gwyb1wocs86sc57p9k52f9k-664wc65rkdb2xat7utn21h5on 192.168.7.201:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions. [root@cu-tmp-201 img1]# docker stack deploy -c docker-compose.yml services-dist Creating network services-dist_webnet Creating service services-dist_web [root@cu-tmp-201 img1]# docker service ls ID NAME MODE REPLICAS IMAGE PORTS t7lnmbq9ktud services-dist_web replicated 3/3 createyuan/my-first:devapp *:4000->80/tcp 這兩個是等效的 [root@cu-tmp-201 img1]# docker stack services services-dist ID NAME MODE REPLICAS IMAGE PORTS t7lnmbq9ktud services-dist_web replicated 3/3 createyuan/my-first:devapp *:4000->80/tcp [root@cu-tmp-201 img1]# docker service ps t7lnmbq9ktud ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS zyabpseko53b services-dist_web.1 createyuan/my-first:devapp cu-tmp-201 Running Running 6 minutes ago kgjp4l2bvz31 services-dist_web.2 createyuan/my-first:devapp cu-tmp-201 Running Running 6 minutes ago re5a39l2fkdx services-dist_web.3 createyuan/my-first:devapp cu-tmp-201 Running Running 6 minutes ago [root@cu-tmp-201 img1]# docker service ps services-dist_web ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS zyabpseko53b services-dist_web.1 createyuan/my-first:devapp cu-tmp-201 Running Running 6 minutes ago kgjp4l2bvz31 services-dist_web.2 createyuan/my-first:devapp cu-tmp-201 Running Running 6 minutes ago re5a39l2fkdx services-dist_web.3 createyuan/my-first:devapp cu-tmp-201 Running Running 6 minutes ago [root@cu-tmp-201 img1]# docker stack ps services-dist ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS zyabpseko53b services-dist_web.1 createyuan/my-first:devapp cu-tmp-201 Running Running 12 minutes ago kgjp4l2bvz31 services-dist_web.2 createyuan/my-first:devapp cu-tmp-201 Running Running 12 minutes ago re5a39l2fkdx services-dist_web.3 createyuan/my-first:devapp cu-tmp-201 Running Running 12 minutes ago curl -4 http://localhost:4000 能夠看到id在變化,每次都不同,在這三個當中輪流切換 也能夠在瀏覽器中不停地刷新 vi docker-compose.yml 修改數量爲2,保存,而後從新運行部署,就變成2個了,這樣就達到的伸縮,擴大或縮小 docker stack deploy -c docker-compose.yml services-dist docker container ls -q [root@cu-tmp-201 img1]# docker stack deploy -c docker-compose.yml services-dist Updating service services-dist_web (id: t7lnmbq9ktudyc47z9nv0q6u5) image createyuan/my-first:devapp could not be accessed on a registry to record its digest. Each node will access createyuan/my-first:devapp independently, possibly leading to different nodes running different versions of the image. [root@cu-tmp-201 img1]# docker container ls -q 351caa4550f3 f109c78a62ab ======================================= docker stack rm services-dist docker swarm leave --force [root@cu-tmp-201 img1]# docker stack rm services-dist Removing service services-dist_web Removing network services-dist_webnet [root@cu-tmp-201 img1]# docker swarm leave --force Node left the swarm.
swarm modegithub
一個服務多個容器,單機上 a single-host mode 多機,多容器,多個服務 swarm mode Swarm managers 使用一些策略來運行容器, 如空節點,用容器填充最少利用的機器 或global,簡單說就是均分 在compose文件中指示manager來使用這些策略 https://docs.docker.com/engine/reference/commandline/service_ls/ The mode filter matches on the mode (either replicated or global) of a service. The following filter matches only global services. docker service ls --filter mode=global ingress n. 進入;入口;准許進入;入境
docker network create --help
--ingress Create swarm routing-mesh network
the app is deployed on a swarm cluster! You can access your app from the IP address of either 201 or 202. ========================================== base=https://github.com/docker/machine/releases/download/v0.16.0 && curl -L $base/docker-machine-$(uname -s)-$(uname -m) >/tmp/docker-machine && install /tmp/docker-machine /usr/local/bin/docker-machine ========================================== docker swarm init docker swarm join 在另一臺機器上運行下面的命令(由上面命令的輸出結果而知) docker swarm join --token SWMTKN-1-0jj8wwym73oy4p99akpnqym51no7qff94ldv8zh392bs60gkhm-9x3p3dai7lity5c6iiu9lusrq 192.168.7.201:2377 docker node ls [root@cu-tmp-201 img1]# docker stack deploy -c docker-compose.yml services-dist Updating service services-dist_web (id: p8d20li46xa8pva4akdixlt6k) image createyuan/my-first:devapp could not be accessed on a registry to record its digest. Each node will access createyuan/my-first:devapp independently, possibly leading to different nodes running different versions of the image. 致使所有運行在一個節點 [root@cu-tmp-201 img1]# docker stack deploy --with-registry-auth -c docker-compose.yml services-dist Updating service services-dist_web (id: p8d20li46xa8pva4akdixlt6k) 這樣就行了,加--with-registry-auth這個flag 或者 [root@cu-tmp-201 img1]# docker service update services-dist_web --with-registry-auth [root@cu-tmp-202 img2]# docker stack ps services-dist ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS mt1ma16gemko services-dist_web.1 createyuan/my-first:devapp cu-tmp-202 Running Running 15 minutes ago i2bo9odkuo1c services-dist_web.2 createyuan/my-first:devapp cu-tmp-201 Running Running 21 minutes ago j03od8elgw1o services-dist_web.3 createyuan/my-first:devapp cu-tmp-202 Running Running 15 minutes ago jwz23z137ewq services-dist_web.4 createyuan/my-first:devapp cu-tmp-201 Running Running 21 minutes ago
stack,其實從part3(即container部分),就開始使用stack了,添加多個服務到stack,依次爲visualizer,redisweb
version: "3" services: web: # replace username/repo:tag with your name and image details image: createyuan/my-first:devapp deploy: replicas: 6 restart_policy: condition: on-failure resources: limits: cpus: "0.1" memory: 50M ports: - "80:80" networks: - webnet visualizer: image: dockersamples/visualizer:stable ports: - "8080:8080" volumes: - "/var/run/docker.sock:/var/run/docker.sock" deploy: placement: constraints: [node.role == manager] networks: - webnet networks: webnet: docker-compose.yml這個文件中,不能有tab,而是用空格代替 [root@cu-tmp-202 img2]# docker stack deploy --with-registry-auth -c docker-compose.yml services-dist yaml: line 19: found character that cannot start any token 修改以後,再次運行 [root@cu-tmp-202 img2]# docker stack deploy --with-registry-auth -c docker-compose.yml services-dist Creating service services-dist_visualizer Updating service services-dist_web (id: 93clo7n0xvg9op3i19qfej2xb) [root@cu-tmp-202 img2]# docker stack ls NAME SERVICES ORCHESTRATOR services-dist 2 Swarm [root@cu-tmp-202 img2]# docker stack ps services-dist [root@cu-tmp-202 img2]# docker stack services services-dist ID NAME MODE REPLICAS IMAGE PORTS 93clo7n0xvg9 services-dist_web replicated 6/6 createyuan/my-first:devapp *:80->80/tcp mr26lixzk4wp services-dist_visualizer replicated 0/1 dockersamples/visualizer:stable *:8080->8080/tcp 可能要過一會,由於要下載visualizer image 也可獨立部署visualizer https://hub.docker.com/r/dockersamples/visualizer/ [root@cu-tmp-202 log]# docker stack services services-dist ID NAME MODE REPLICAS IMAGE PORTS 93clo7n0xvg9 services-dist_web replicated 6/6 createyuan/my-first:devapp *:80->80/tcp mr26lixzk4wp services-dist_visualizer replicated 1/1 dockersamples/visualizer:stable *:8080->8080/tcp 瀏覽器地址欄訪問正常 http://192.168.7.202:8080/ 再次加入新的服務redis redis: image: redis ports: - "6379:6379" volumes: - "/home/docker/data:/data" deploy: placement: constraints: [node.role == manager] command: redis-server --appendonly yes networks: - webnet /home/docker/data 這是在host上建的目錄,能夠任意。 [root@cu-tmp-202 img2]# docker stack deploy --with-registry-auth -c docker-compose.yml services-dist Creating service services-dist_redis Updating service services-dist_web (id: 93clo7n0xvg9op3i19qfej2xb) Updating service services-dist_visualizer (id: mr26lixzk4wpdmq5fu5ns6efa) [root@cu-tmp-202 data]# docker stack services services-dist ID NAME MODE REPLICAS IMAGE PORTS 93clo7n0xvg9 services-dist_web replicated 2/2 createyuan/my-first:devapp *:80->80/tcp bv19yhv26y23 services-dist_redis replicated 1/1 redis:latest *:6379->6379/tcp mr26lixzk4wp services-dist_visualizer replicated 1/1 dockersamples/visualizer:stable *:8080->8080/tcp 完畢,以前也一直存在這個問題,但沒有解決,此次解決了 但存在一個問題,是有兩個web,但始終只訪問一個,不輪詢。執行下面這個語句就能夠了 [root@cu-tmp-202 data]# docker service update --with-registry-auth services-dist_web services-dist_web overall progress: 2 out of 2 tasks 1/2: running [==================================================>] 2/2: running [==================================================>] verify: Service converged [root@cu-tmp-202 data]#