Docker 學習筆記

環(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)限錯誤 ,設置把用戶加入到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服務

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

# 當容器運行的時候執(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)建應用

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

$ ls
Dockerfile      app.py          requirements.txt

--tag設置鏡像的名字,可以使用-t代替

docker build --tag=friendlyhello

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

$ docker image ls

運行應用

$ 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非常慢,這里只是學習一下,建議使用其他Registry 阿里云容器鏡像服務的基本使用

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

登錄Docker賬號

$ docker login

為鏡像打標簽

格式

$ 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

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

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

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

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

docker-compose.yml

version: "3"
services:
  # 定義一個叫web的服務
  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服務的80端口
      - "4000:80"
    networks:
      # 指示web容器通過稱為webnet的負載均衡網(wǎng)絡共享80端口(在內(nèi)部,容器本身在一個臨時端口上發(fā)布到web的80端口。)
      - webnet
networks:
  # 使用默認設置定義webnet網(wǎng)絡(一個負載均衡的覆蓋網(wǎng)絡)。
  webnet:

運行你的負載均衡應用

首先先運行:

$ docker swarm init

getstartedlab是app的名字:

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

Creating network getstartedlab_webnet
Creating service getstartedlab_web

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

查看服務:

$ docker service ls

也可以這樣查看服務:

$ docker stack services getstartedlab 

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

列出你的服務任務:

$ docker service ps getstartedlab_web 

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

$ docker container ls

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

或者多次輸入:

$ curl -4 http://localhost:4000

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

顯示一個stack的所有任務:

$ docker stack ps getstartedlab

拓展應用

可以通過改變replicas 的值來拓展應用:

docker-compose.yml

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

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

查看目前的容器和任務:

$ docker stack ps getstartedlab

移除應用

$ 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后:設置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)

部署應用到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不同,證實了集群的負載均衡

拓展應用

第一種:修改docker-compose.yml

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

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

關(guān)閉應用

關(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)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容