docker--筆記(四)

Docker 持久化數據的方案:
基於本地文件系統的Volume: 能夠在執行Docker create 或 Docker run 時,經過-v參數將主機的目錄做爲容器的數據卷。這部分功能即是基於本地文件系統的volume管理html

基於plugin的volume,支持第三方的存儲方案,好比NAS,aws
volume類型:
受管理的data Volume,由docker後臺自動建立
綁定掛載的Volume,具體掛載位置能夠由用戶指定。
數據持久化:
方法一:Data Volume
以mysql爲例:
>> sudo docker run -d --name mysql1 -e MYSQL_ROOT_PASSWORD=root mysql:5.7
>> sudo docker run -d --name mysql1 -e
mysql #去掉密碼
>> sudo docker volume ls
>> sudo docker volume inspect + VOLUMENAME
>> sudo docker run -d -v mysql:/var/lib/mysql --name mysql1 -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql # -v 給volume name重命名
>> sudo docker exec -it mysql1 /bin/bash
# mysql -uroot -p
# show databases;
# create database docker;
>> sudo docker stop mysql1
>> sudo docker rm mysql1
>> sudo docker volume ls
>> sudo docker run -d -v mysql:/var/lib/mysql --name mysql2 -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql
>> sudo docker exec -it mysql2 /bin/bash
# mysql -uroot -p
# show databases; # 發現docker這個數據庫還在
方法二:Bind Mouting
docker run -v 本地目錄:容器目錄
>> sudo docker run -d -p 80:80 -v $(pwd):/usr/share/nginx/html --name web wgw/nginxt
>> sudo docker exec -it web /bin/bash
# ls
# cd /usr/share/nginx/html
# touch test.txt
# exit
>> ls # 發現當期目錄也有了test.txt,說明當前目錄和容器中的/usr/share/nginx/html是同步的
實戰:
Dokcer + bind mount
>> sudo docker build -t wgw/flask-skeleton .
>> sudo docker run -d -p 80:5000 -v $(pwd):/skeleton --name falsk wgw/flask-skeleton
# 實時修改本地的home.html ,查看網頁顯示變化node

實戰--部署一個wordpress:
>> sudo docker run -d --name mysql -v mysql-data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=wordpress mysql
>> sudo docker run -d -e WORDPRESS_DB_HOST=mysql:3306 -e WORDPRESS_DB_PASSWORD=root --link mysql -p 8888:80 wordpress python


Docker compose究竟是什麼?
Docker Compose "批處理"
Docker Compose 是一個工具
這個工具能夠經過一個yml文件定義多容器的docker應用
經過一條命令就能夠根據yml文件的定義去建立或者管理多個容器
安裝docker compose:
https://docs.docker.com/compose/install/
docker-compose.yml:
三大概念:
services:
一個service表明一個container,這個container能夠從dockerhub的image來建立,
或者能夠從本地的Dockerfile build出來的image建立
service的啓動相似docker run,咱們能夠給其指定network和volume,因此能夠給service指定network和volume的引用
networks:mysql


volumes:
>> docker-compose up # 將咱們yml文件中定義的容器所有運行起來
>> docker-compose -f docker-compose.yml up -d
>> docker-compose ps
>> docker-compose images
>> docker-compose exec +yml文件中定義的service bash
>> docker-compose down # 中止並刪除
水平擴展與負載均衡:
>> docker-compose up -d
>> docker-compose ps
>> docker-compose up --scale web=3 # 啓動3個web容器
容器編排:Swarm mode
問題引入:
怎麼去管理這麼多容器?
怎麼能方便的橫向擴展?
若是容器down了,怎麼能自動恢復?
如何去更新容器而不影響業務?
如何去監控追蹤這些容器?
怎麼去調度容器的建立?
怎麼保護隱私數據?
swarm是一種集羣的架構:
service和replicas
建立一個3節點的swarm集羣:
三種方法:
方法一:
vagrant + virtuabox
>> sudo docker swarm init --advertise-addr=192.168.50.2 # swarm
# 拷貝docker swarm join ... 到其餘節點上node2,node3
>> sudo docker node ls #顯示當前swarm的節點
方法二:
docker machine + virtualbox
~ docker-machine create node1
~ docker-machine create node2
~ docker-machine create node2
方法三:
play with docker https://labs.play-with-docker.com/nginx

service建立維護和水平擴展:
# node1
>> sudo docker service create --name demo busybox sh -c "while true;do sleep 3600;done"
>> sudo docker service ls # 其中replicated代表能夠水平擴展
ID NAME MODE REPLICAS IMAGE PORTS
8c41wr8l7u4r demo replicated 1/1 busybox:latest
>> sudo docker service demo ps
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE
xowievbqgav8 demo.1 busybox:latest wgw2 Running Running 3 minutes ago
>> sudo docker service scale demo=5 # 水平擴展爲5個
>> sudo docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
8c41wr8l7u4r demo replicated 5/5 busybox:latest
>> sudo docker service ps demo # 發現這5個service分佈在不一樣的節點上
# 在node2或node3上強制刪除一個service
>> sudo docker ps
>> sudo docker rm -f "19d46aefc5ab"
# node1
>> sudo docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
8c41wr8l7u4r demo replicated 4/5 busybox:latest
>> sudo docker service ls # 再執行一遍,發現有變回了5個,說明scale不只保證了水平擴展,並且保證了必定數目的擴展是有效的,
# 從而保證了系統的有效與穩定
ID NAME MODE REPLICAS IMAGE PORTS
8c41wr8l7u4r demo replicated 5/5 busybox:latest
>> sudo service rm demo # 刪除service,看到很快的刪除,其實真正刪除是要必定的過程
實戰————在swarm集羣中經過service部署wordpress:
>> sudo docker network create -d overlay demo # 實現多機通訊
>> sudo docker network ls
# 建立mysql的服務
# sudo docker service create --name mysql-server --network demo --env MYSQL_ROOT_PASSWORD=root123 --env MYSQL_DATABASE=wordpress --mount(docker中是-v) type=volume,source(存儲的本地址)=mysql-data,destination(容器中的位置)=/var/lib/mysql mysql:5.7
>>sudo docker service create --name mysql-server --network demo --env MYSQL_ROOT_PASSWORD=root123Abc? --env MYSQL_DATABASE=wordpress --mount type=volume,source=mysql-data,destination=/var/lib/mysql mysql:5.7
>> sudo docker service ls
>> sudo docker service ps mysql # 查看mysql服務運行在哪一個節點上
# 建立wordpress service
>> sudo docker service create --name wordpress --network demo -p 80:80 --env WORDPRESS_DB_PASSWORD=root123Abc? --env WORDPRESS_DB_HOST=mysql-server wordpress
集羣服務間通訊之RoutingMesh:
DNS服務發現:
以wordpress多機部署爲例:
咱們的mysql和wordpress分別位於不一樣的節點上,他們之間經過service name 進行通訊,由於swarm有一個內置的DNS服務發現的功能,咱們經過service建立一個service時,若是他識別到了一個overlay的網絡上面,咱們就會爲鏈接到這個overlay網絡上面的全部的service添加一條DNS記錄,咱們經過DNS記錄就能知道他的ip地址,而後咱們就能夠訪問這個服務了,可是,service中的DNS記錄中的service name 對應的ip並非實際的ip,而是有一個虛擬IP叫作vip,由於咱們的service的ip是不穩定的(好比因爲x當掉了,service從新分配時分配到了另外一個節點),而service name - vip與真實ip的對應關係是用lvs來解決的
>> sudo docker service create --name whoami -p 8000:8000 --network demo
-d jwilder/whoami
>> sudo docker service create --name client -d --network demo busybox sh -c "while true;do sleep 3600; done"
>> sudo docker exec -it 38e sh # client
~ ping whoami # 能夠ping通,可是他Ping的是10.0.0.35這個ip,並非whoami的真實ip
問題:
若是將whoami橫向擴展成2個,ping的時候他的ip會不會變?
>> sudo docker service scale whoami=2
>> sudo docker service ps whoami
>> sudo docker exec -it 38e sh # client
~ ping whoami # 能夠ping通,可是他的ip並無發生變化,他真正ping的是一個vip--虛擬ip
~ nslookup whoami # sudo yum install bind-utils,沒有的話能夠安裝,用來查詢dns
Server: 127.0.0.11 # DNS服務器地址
Address: 127.0.0.11:53
Name: whoami
Address: 10.0.0.35
~ nslookup tasks.whoamigit

Routing Mesh 的兩種體現:
Internal --Container和Container之間的訪問經過overlay網絡(經過VIP虛擬IP)
Ingress --若是服務有綁定接口,則此服務能夠經過任意swarm節點的響應接口訪問github

RoutingMesh之Ingress負載均衡:
Ingress Network:
1.外部訪問的負載均衡
2.服務端口被暴露到各個swarm節點
3.內部經過IPVS進行負載均衡
當咱們去任何一臺swarm節點上去訪問端口服務的時候,他會把咱們的服務經過本地的本節點的ipvs把個人這個服務load balance 到真正具備service的swarm節點上,再把response返回給咱們
>> sudo iptables -nL -t nat # 能夠看到咱們本地的一些轉發規則
Chain DOCKER-INGRESS (2 references)
target prot opt source destination
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:8000 to:172.18.0.2:8000
RETURN all -- 0.0.0.0/0 0.0.0.0/0
>> ip a
...
docker_gwbridge: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:c4:2e:14:07 brd ff:ff:ff:ff:ff:ff
inet 172.18.0.1/16 brd 172.18.255.255 scope global docker_gwbridge
valid_lft forever preferred_lft forever
inet6 fe80::42:c4ff:fe2e:1407/64 scope link
valid_lft forever preferred_lft forever
...
>> brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.0242cdeade99 no
docker_gwbridge 8000.0242c42e1407 no veth403a876
veth76ab65a
>>sudo docker network inspect docker_gwbridge
"Containers": {
"38e4791dc1df72c9511527f08ce234498ae609cd1a085f5e8363555994627f89": {
"Name": "gateway_d485c6e2abcb",
"EndpointID": "72861c680ba4ded23a008d40e6fa107aa015b9a3.0.76a369f734aefd824cbde",
"MacAddress": "02:42:ac:12:00:03",
"IPv4Address": "172.18.0.3/16",
"IPv6Address": ""
},
"ingress-sbox": {
"Name": "gateway_ingress-sbox",
"EndpointID": "266905d9d33abea66e0df42ae28c68781aef72e9afcca2122a44688b0af9f59f",
"MacAddress": "02:42:ac:12:00:02",
"IPv4Address": "172.18.0.2/16",
"IPv6Address": ""
}
},
>>sudo ls /var/run/docker/netns
1-guy2oiuzz0 1-ll8amb5yay d485c6e2abcb ingress_sbox lb_guy2oiuzz
>> sudo yum install ipvsadm # 這是一個LVS管理的工具
>>nsenter --net=/var/run/docker/netns/ingress_sbox # 進入到ingress_sbox
# ip a # 看到ip變成了172.18.0.2,咱們已經不是在本地的network namespace了
# iptables -nL -t mangle # 能夠看到他去往8000端口的他給作了一個mark set,其實就是作了一個負載均衡
target prot opt source destination
MARK tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:8000 MARK set 0x10a
# ipvsadm -l
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
FWM 266 rr
-> 10.255.0.10:0 Masq 1 0 0 # 這個就是咱們的whoami 的service containal的地址
-> 10.255.0.11:0 Masq 1 0 0
# web

說明:
Ingress Network的數據包走向詳情:
127.0.0.1:8000 ===> {HOST1:docker_gwbridge ===> Ingress-sbox[iptables MANGLE table PREROUTING MARK:Published-PORT->ingress-sbox] -> <fw-mark-id>][IPVS Match<fw-mark-id>->Masq{RR across container-IPs}](他實際上是一個network namespace)===>Ingress Network[ingress-overlay-bridge]}==
vxlan tunner with vni ===>{HOST2:Ingress Network[ingress-overlay-bridge]===>[container-sbox] and [Ingress-sbox]====>default_gwbridge==>Ingress-sbox[iptables MANGLE table PREROUTING MARK:Published-PORT->ingress-sbox]}
DockerStack部署wordpress:
# 建立一個名字爲wordpress的stack
>> sudo docker stack deploy wordpress --compose-file=docker-compose.yml
>> sudo docker stack ls
NAME SERVICES ORCHESTRATOR
wordpress 2 Swarm
>> sudo docker stack ps wordpress
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
p5hoplu3al3e wordpress_mysql.zg3vus7jnzjl3vl3uealg580h mysql:5.7 wgw2 Running Running about a minute ago
bdxdyuovmgil wordpress_web.1 wordpress:latest wgw6 Running Preparing about a minute ago
qv2p70q0e0xa wordpress_web.2 wordpress:latest wgw2 Running Preparing about a minute ago
tync4d3u4sld wordpress_web.3 wordpress:latest wgw3 Running Running about a minute ago
>> sudo docker stack services wordpress
ID NAME MODE REPLICAS IMAGE PORTS
aw6py2ckn4k8 wordpress_web replicated 1/3 wordpress:latest *:8080->80/tcp
u4ksl9mmtbax wordpress_mysql global 1/1 mysql:5.7
>> sudo docker stack rm wordpresssql

實戰部署投票應用:
>> sudo docker stack deploy example --compose-file=docker-compose.yml
>> sudo docker stack ls
>> sudo docker stack services exampledocker

# 離開節點
>> sudo docker swarm leave
# manager離開節點
>> sudo docker swarm leave --force

DockerSecret的管理和使用:
Docker Secrets Managment:
什麼是secret?
1.用戶名密碼
2.SSH KEY
3.TLS認證
4.任何不想讓別人看到的數據
Secrets Managment:
1.存在swarm manager節點Raft database裏
2.secret能夠assign給一個service,這個service就能看到這個sercret
3.在container內部secret看起來像文件,可是其實是在內存中
方法一:經過文件建立
>> sudo vim password
# admin123
>> sudo docker secret create my-password(名字) password(上面建立的文件) # 建立完以後刪除password文件
>> sudo rm -rf password
>> sudo docker secret ls # 就能夠看到咱們這個節點上有哪些secret
方法二:經過標準輸入
>> echo "admin123" | docker secret create my-password2 -
# 刪除secret
>> sudo docker secret rm my-password2


service如何去使用secret?

>> sudo docker service create --name client --secret my-password busybox sh -c "while true;do sleep 3600;done" # 這樣的話咱們的service就能夠看到my-password
>> sudo docker service ls
>> sudo docker service ps client
>> sudo docker ps
>> sudo docker exec -it 04c7f7bb13a9 sh
# cd /run/secrets/
# ls
~my-password
# cat my-password # 就能夠看到咱們的密碼原文
~admin123


>> sudo docker service create --name db --secret my-password -e MYSQL_ROOT_PASSWORD_FILE=/run/secrets/my-password mysql:5.7
>> sudo docker exec -it 6dc34 sh
# ls /run/secrets
~my-password
# cat my-password
# mysql -uroot -p

Dockersecret 在Stack中的使用:
https://github.com/phantom0925/dockerstack-wordpress/blob/master/wordpress/docker-compose.yml

Service更新:
如何在service正在運行中進行更新:
>> sudo docker network ls
>> sudo docker service create --name web --publish 8080:5000 --network demo xiaopeng163/python-flask-demo:1.0
# 要更新又要不中斷
# 第一步:scale
manager節點
>> sudo docker service scale web=2
>> sudo docker service ps web
>> curl 127.0.0.1:8080
node2節點
>> sh -c "while true;do curl 127.0.0.1:8080&&sleep 1;done"

manager節點 >> sudo docker service update --image xiaopeng163/python-flask-demo:2.0 web

相關文章
相關標籤/搜索