Docker 學(xué)習(xí)筆記

環(huán)境

Ubuntu16.04

安裝Docker CE

若之前安裝過老版本的docker澈蚌,先卸載

sudo apt-get remove docker docker-engine docker.io containerd runc

1.更新apt包索引

sudo apt-get update

2.安裝軟件包支持apt使用基于Https的倉庫

sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common

3.添加Docker官方的GPG key

# 官方 
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# 中科大鏡像
curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add -

驗證key

sudo apt-key fingerprint 0EBFCD88

4.添加Docker倉庫

# 官方
sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"
# 中科大 速度快一點
sudo add-apt-repository \
   "deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu \
   $(lsb_release -cs) \
   stable"

5.更新apt包索引

sudo apt-get update

6.安裝最新的Docker CE

sudo apt-get install docker-ce docker-ce-cli containerd.io

查看版本信息

查看Docker版本

docker --version

Docker version 18.09.3, build 774a1f4

查看更多Docker信息,docker version 或者 docker info廓脆,這里使用sudo进萄,否則會出現(xiàn)權(quán)限錯誤

$ sudo docker info

一般使用docker命令得加上sudo捻脖,為了避免出現(xiàn)權(quán)限錯誤 ,設(shè)置把用戶加入到docker組中 Read more.

創(chuàng)建docker用戶組中鼠,可能會提示已經(jīng)存在

sudo groupadd docker

把用戶添加到docker用戶組

sudo usermod -aG docker $USER

登出賬號

logout

然后重新登錄可婶,現(xiàn)在不加sudo也可以使用

docker info

測試

通過運行一個簡單的image來測試Docker

$ docker run hello-world

Unable to find image 'hello-world:latest' locally
docker: Error response from daemon: Get https://registry-1.docker.io/v2/library/hello-world/manifests/latest: Get https://auth.docker.io/token?scope=repository%3Alibrary%2Fhello-world%3Apull&service=registry.docker.io: net/http: request canceled (Client.Timeout exceeded while awaiting headers).
See 'docker run --help'.

錯誤解決:

打開/etc/docker/daemon.json,如果不存在創(chuàng)建文件援雇,添加內(nèi)容

{
  "registry-mirrors": [
    "http://141e5461.m.daocloud.io"
  ]
}

重啟Docker服務(wù)

sudo service docker restart

再次運行

$ docker run hello-world

查看下載的image

$ docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              fce289e99eb9        2 months ago        1.84kB

列出所有的容器矛渴,不加--all默認列出仍在運行的容器,hello-world輸出語句后就結(jié)束了熊杨,因此不加--all就看不到hello-world容器

docker container ls --all

Containers

簡單來說曙旭,Container就是包含運行環(huán)境,代碼晶府,以及構(gòu)建運行命令的容器桂躏,他和傳統(tǒng)運行程序的區(qū)別就是環(huán)境不隨宿主機的環(huán)境變化,自己擁有自己的一套運行環(huán)境川陆,環(huán)境變量剂习,可以通過端口與宿主機交流信息。下面示例構(gòu)建了一個容器:

在新建文件夾下较沪,添加三個文件

Dockerfile

# 程序運行需要的環(huán)境鳞绕,也是一個鏡像
# 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

# 需要運行的命令,這里使用pip安裝需要的模塊
# Install any needed packages specified in requirements.txt
RUN pip install --trusted-host pypi.python.org -r requirements.txt

# 暴露80端口
# Make port 80 available to the world outside this container
EXPOSE 80

# 定義環(huán)境變量
# Define environment variable
ENV NAME World

# 當(dāng)容器運行的時候執(zhí)行的命令
# Run app.py when the container launches
CMD ["python", "app.py"]

requirements.txt

Flask
Redis

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)

構(gòu)建應(yīng)用

當(dāng)前的目錄結(jié)構(gòu)

$ ls
Dockerfile      app.py          requirements.txt

--tag設(shè)置鏡像的名字尸曼,可以使用-t代替

docker build --tag=friendlyhello

查看鏡像们何,這里顯示了所有本地鏡像,包括剛構(gòu)建的以及從遠程倉庫下載的

$ docker image ls

運行應(yīng)用

$ docker run -p 4000:80 friendlyhello

-p 4000:80將宿主機的4000端口映射到容器的80端口

訪問http://宿主機IP:4000

[圖片上傳失敗...(image-41cadb-1582005529611)]

在終端按CTRL+C停止容器

在后臺運行app

$ docker run -d -p 4000:80 friendlyhello

d5d06d6b7efc6c9e8e2e730ee0139c78200951743df80afd0ce2bc604da917a1

d5d06d6b7efc6c9e8e2e730ee0139c78200951743df80afd0ce2bc604da917a1是容器ID控轿,每個運行的容器實例都有一個ID

查看運行的容器

$ youthful_mirzakhani

停止運行app

 docker container stop d5d06d6b7efc

或者

docker container stop youthful_mirzakhani

youthful_mirzakhani是實例的NAMES屬性

分享鏡像

使用官方Registry非常慢冤竹,這里只是學(xué)習(xí)一下拂封,建議使用其他Registry 阿里云容器鏡像服務(wù)的基本使用

Docker支持將鏡像上傳到一個類似GithubMaven的公共倉庫,需要在 hub.docker.com 注冊賬號

登錄Docker賬號

$ docker login

為鏡像打標(biāo)簽

格式

$ docker tag image username/repository:tag

例如

$ docker tag friendlyhello vczyh/get-started:part2
$ docker image ls

發(fā)布鏡像

$ docker push username/repository:tag

拉取鏡像并運行

$ docker run -p 4000:80 username/repository:tag

Services

在分布式應(yīng)用中鹦蠕,不同的部分被稱為服務(wù)冒签。比如,你想做一個視頻分享網(wǎng)站钟病,網(wǎng)站可能包括存儲服務(wù)萧恕,用戶上傳視頻后的轉(zhuǎn)碼服務(wù),前臺服務(wù)等肠阱。

服務(wù)實際上只是生產(chǎn)中的容器票唆,一個服務(wù)僅運行一個鏡像,但它通過編碼決定了鏡像的運行方式——使用的端口辖所,運行副本的數(shù)量惰说,便于容器擁有它所需要的容量等。拓展服務(wù)改變了運行軟件的容器實例數(shù)量缘回,從而為進程中的服務(wù)分配更多的資源吆视。

幸運的是,使用Docker平臺定義酥宴、運行和擴展服務(wù)非常容易——只需編寫一個docker-compose.yml文件啦吧。

docker-compose.yml文件是一個YAML文件,它定義Docker容器在生產(chǎn)環(huán)境中的行為拙寡。

docker-compose.yml

version: "3"
services:
  # 定義一個叫web的服務(wù)
  web:
    # 鏡像授滓,本地或者遠程
    # replace username/repo:tag with your name and image details
    # image: username/repo:tag
    image: registry.cn-hangzhou.aliyuncs.com/zhangyuheng/hello 
    deploy:
      # 包含5個副本
      replicas: 5
      resources:
        limits:
          # 每個副本最多使用10%的CPU
          cpus: "0.1"
          # 每個副本最多使用50M內(nèi)存空間
          memory: 50M
      restart_policy:
        # 如果有任何一個失敗,則立即重啟
        condition: on-failure
    ports:
      # 將主機4000端口映射到web服務(wù)的80端口
      - "4000:80"
    networks:
      # 指示web容器通過稱為webnet的負載均衡網(wǎng)絡(luò)共享80端口(在內(nèi)部肆糕,容器本身在一個臨時端口上發(fā)布到web的80端口般堆。)
      - webnet
networks:
  # 使用默認設(shè)置定義webnet網(wǎng)絡(luò)(一個負載均衡的覆蓋網(wǎng)絡(luò))。
  webnet:

運行你的負載均衡應(yīng)用

首先先運行:

$ docker swarm init

getstartedlab是app的名字:

$ docker stack deploy -c docker-compose.yml getstartedlab

Creating network getstartedlab_webnet
Creating service getstartedlab_web

現(xiàn)在單個服務(wù)堆棧在一臺主機上運行了5個已部署鏡像的實例

查看服務(wù):

$ docker service ls

也可以這樣查看服務(wù):

$ docker stack services getstartedlab 

服務(wù)中運行的單個容器稱為任務(wù)诚啃。任務(wù)被賦予惟一的id淮摔,這些id在數(shù)字上遞增,直到您在docker-comp.yml中定義的副本的數(shù)量始赎。

列出你的服務(wù)任務(wù):

$ docker service ps getstartedlab_web 

也可以通過查看容器來查看任務(wù):-q僅僅列出容器ID

$ docker container ls

瀏覽器多次訪問:http://localhost:4000

或者多次輸入:

$ curl -4 http://localhost:4000

可以看到顯示的Hostname(容器ID)每次都不一樣和橙,也驗證了輪詢方式的負載均衡

顯示一個stack的所有任務(wù):

$ docker stack ps getstartedlab

拓展應(yīng)用

可以通過改變replicas 的值來拓展應(yīng)用:

docker-compose.yml

 deploy:
      # 包含5個副本
      replicas: 7
$ docker stack deploy -c docker-compose.yml getstartedlab

Docker更新服務(wù)不需要關(guān)掉服務(wù)或者關(guān)掉任何容器

查看目前的容器和任務(wù):

$ docker stack ps getstartedlab

移除應(yīng)用

$ docker stack rm getstartedlab

移除集群

$ docker swarm leave --force

常用命令

docker stack ls                                            # List stacks or apps
docker stack deploy -c <composefile> <appname>  # Run the specified Compose file
docker service ls                 # List running services associated with an app
docker service ps <service>                  # List tasks associated with an app
docker inspect <task or container>                   # Inspect task or container
docker container ls -q                                      # List container IDs
docker stack rm <appname>                             # Tear down an application
docker swarm leave --force      # Take down a single node swarm from the manager

Swarms

安裝docker-machine

$ base=https://github.com/docker/machine/releases/download/v0.16.0 &&
  curl -L $base/docker-machine-$(uname -s)-$(uname -m) >/tmp/docker-machine &&
  sudo install /tmp/docker-machine /usr/local/bin/docker-machine

這個豈止是慢,根本就沒速度造垛,所以采用手動安裝魔招,先去https://github.com/docker/machine/releases/下載,這里下載也得翻墻==

下載好安裝:

$ sudo install docker-machine-Linux-x86_64 /usr/local/bin/docker-machine

驗證:

$ docker-machine version

docker-machine version 0.16.0, build 702c267f

創(chuàng)建虛擬機集群

安裝virtualbox驅(qū)動:

$ sudo apt install virtualbox

創(chuàng)建名為myvm1的虛擬機:

$ docker-machine create --driver virtualbox myvm1

Running pre-create checks...
Error with pre-create check: "This computer doesn't have VT-X/AMD-v enabled. Enabling it in the BIOS is mandatory"

出現(xiàn)錯誤五辽,這里使用的是VMware办斑,解決:

在這里插入圖片描述
$ docker-machine create --driver virtualbox myvm1

從github下載iso文件非常慢,采用手動下載杆逗,參考

iso文件放到默認位置:

$ cp boot2docker.iso ~/.docker/machine/cache/
$ docker-machine create --driver virtualbox myvm1

Running pre-create checks...
Creating machine...
(myvm1) Copying /home/vczyh/.docker/machine/cache/boot2docker.iso to /home/vczyh/.docker/machine/machines/myvm1/boot2docker.iso...
(myvm1) Creating VirtualBox VM...
(myvm1) Creating SSH key...
(myvm1) Starting the VM...
(myvm1) Check network to re-create if needed...
(myvm1) Found a new host-only adapter: "vboxnet0"
(myvm1) Waiting for an IP...
Waiting for machine to be running, this may take a few minutes...
Detecting operating system of created instance...
Waiting for SSH to be available...
Detecting the provisioner...
Provisioning with boot2docker...
Copying certs to the local machine directory...
Copying certs to the remote machine...
Setting Docker configuration on the remote daemon...
Checking connection to Docker...
Docker is up and running!
To see how to connect your Docker Client to the Docker Engine running on this virtual machine, run: docker-machine env myvm1

同樣乡翅,再創(chuàng)建一個名為myvm2的虛擬機:

$ docker-machine create --driver virtualbox myvm2

查看虛擬機:

$ docker-machine ls  

連接虛擬機

$ docker-machine --native-ssh ssh myvm1
docker@myvm1:~$ 

初始化swarm以及添加節(jié)點

連接myvm1后:指定myvm1swarm manager吁讨,192.168.99.100myvm1的IP

docker@myvm1:~$ docker swarm init --advertise-addr 192.168.99.100

CTRL+D退出連接,連接myvm2后:設(shè)置myvm2swarm worker

docker@myvm2:~$ docker swarm join --token SWMTKN-1

現(xiàn)在一個swarm已經(jīng)創(chuàng)建完成

swarm manager(myvm1)中查看所有節(jié)點:

docker@myvm1:~$ docker node ls

另外一種與虛擬機對話方式

$ docker-machine env myvm1

export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.100:2376"
export DOCKER_CERT_PATH="/Users/sam/.docker/machine/machines/myvm1"
export DOCKER_MACHINE_NAME="myvm1"
# Run this command to configure your shell:
# eval $(docker-machine env myvm1)

運行:

eval $(docker-machine env myvm1)

現(xiàn)在實現(xiàn)了和ssh連接myvm1相同的結(jié)果:

docker node ls

好處之一就是虛擬機可以直接使用宿主機的文件

斷開對話:

eval $(docker-machine env -u)

部署應(yīng)用到swarm

使用eval $(docker-machine env myvm1)打開與myvm1的對話

$ docker stack deploy -c docker-compose.yml getstartedlab

如果docker-compose.yml里使用的鏡像不是Docker Hub的:

docker login registry.example.com

docker stack deploy --with-registry-auth -c docker-compose.yml getstartedlab
$ docker stack ps getstartedlab 

現(xiàn)在5個實例(容器)已經(jīng)分布在倆個虛擬機中

查看myvm1的容器:其他的3個實例在myvm2

$ docker container ls

測試

宿主機運行:192.168.99.101是任意一個虛擬機的IP

curl 192.168.99.101:4000

每次訪問的Hostname不同峦朗,證實了集群的負載均衡

拓展應(yīng)用

第一種:修改docker-compose.yml

第二種:使用docker swarm join為集群添加機器

這倆種操作之后,重新執(zhí)行docker stack deploy -c docker-compose.yml getstartedlab

關(guān)閉應(yīng)用

關(guān)閉stack

docker stack rm getstartedlab

關(guān)閉swarm:

docker swarm leave  // worker
docker swarm leave --force // manager

常用命令

docker-machine create --driver virtualbox myvm1 # Create a VM (Mac, Win7, Linux)
docker-machine create -d hyperv --hyperv-virtual-switch "myswitch" myvm1 # Win10
docker-machine env myvm1                # View basic information about your node
docker-machine ssh myvm1 "docker node ls"         # List the nodes in your swarm
docker-machine ssh myvm1 "docker node inspect <node ID>"        # Inspect a node
docker-machine ssh myvm1 "docker swarm join-token -q worker"   # View join token
docker-machine ssh myvm1   # Open an SSH session with the VM; type "exit" to end
docker node ls                # View nodes in swarm (while logged on to manager)
docker-machine ssh myvm2 "docker swarm leave"  # Make the worker leave the swarm
docker-machine ssh myvm1 "docker swarm leave -f" # Make master leave, kill swarm
docker-machine ls # list VMs, asterisk shows which VM this shell is talking to
docker-machine start myvm1            # Start a VM that is currently not running
docker-machine env myvm1      # show environment variables and command for myvm1
eval $(docker-machine env myvm1)         # Mac command to connect shell to myvm1
& "C:\Program Files\Docker\Docker\Resources\bin\docker-machine.exe" env myvm1 | Invoke-Expression   # Windows command to connect shell to myvm1
docker stack deploy -c <file> <app>  # Deploy an app; command shell must be set to talk to manager (myvm1), uses local Compose file
docker-machine scp docker-compose.yml myvm1:~ # Copy file to node's home dir (only required if you use ssh to connect to manager and deploy the app)
docker-machine ssh myvm1 "docker stack deploy -c <file> <app>"   # Deploy an app using ssh (you must have first copied the Compose file to myvm1)
eval $(docker-machine env -u)     # Disconnect shell from VMs, use native docker
docker-machine stop $(docker-machine ls -q)               # Stop all running VMs
docker-machine rm $(docker-machine ls -q) # Delete all VMs and their disk images

Docker其他配置

鏡像配置

/etc/docker/daemon.json

{
  "registry-mirrors": [
    "http://141e5461.m.daocloud.io"
  ]
}
sudo service docker restart

DNS配置

Docker實例里的DNS可能出問題排龄,所以配置Docker使用的DNS

/etc/docker/daemon.json

{
  "dns": ["your_dns_address", "8.8.8.8"]
}
sudo service docker restart
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末波势,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子橄维,更是在濱河造成了極大的恐慌尺铣,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件争舞,死亡現(xiàn)場離奇詭異凛忿,居然都是意外死亡,警方通過查閱死者的電腦和手機竞川,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門店溢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人委乌,你說我怎么就攤上這事床牧。” “怎么了遭贸?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵戈咳,是天一觀的道長。 經(jīng)常有香客問我壕吹,道長著蛙,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任耳贬,我火速辦了婚禮踏堡,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘效拭。我一直安慰自己暂吉,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布缎患。 她就那樣靜靜地躺著慕的,像睡著了一般。 火紅的嫁衣襯著肌膚如雪挤渔。 梳的紋絲不亂的頭發(fā)上肮街,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天,我揣著相機與錄音判导,去河邊找鬼嫉父。 笑死沛硅,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的绕辖。 我是一名探鬼主播摇肌,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼仪际!你這毒婦竟也來了围小?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤树碱,失蹤者是張志新(化名)和其女友劉穎肯适,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體成榜,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡框舔,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了赎婚。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片刘绣。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖挣输,靈堂內(nèi)的尸體忽然破棺而出额港,到底是詐尸還是另有隱情,我是刑警寧澤歧焦,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布移斩,位于F島的核電站,受9級特大地震影響绢馍,放射性物質(zhì)發(fā)生泄漏向瓷。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一舰涌、第九天 我趴在偏房一處隱蔽的房頂上張望猖任。 院中可真熱鬧,春花似錦瓷耙、人聲如沸朱躺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽长搀。三九已至,卻和暖如春鸡典,著一層夾襖步出監(jiān)牢的瞬間源请,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留谁尸,地道東北人舅踪。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像良蛮,于是被迫代替她去往敵國和親抽碌。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,781評論 2 354