【Docker學習】Docker安裝與初步實踐


參考資料:

Docker優點

在這裏插入圖片描述
在虛擬化技術成熟的今天,用戶不僅僅滿足於OS級別的虛擬化機制,它們需要的是更小、更快速的服務擴展方式,虛擬機會重新創建一個虛擬OS,所以無論是佔用空間、運行速度上都要慢得多。
相比之下Docker是將一個個服務、應用程序打包,直接用宿主底層的操作系統來進行運行,但是將資源隔離開來,實現了高效地利用。

概念描述

  • Image鏡像,相當於一個執行程序,每次都執行得到一個進程
  • Container容器,就是一個封裝好的進程,資源都是隔離開的,於Image的關係,可以看作類和對象的關係,Container就是實例化的Image
  • Registy倉庫,存放不同版本鏡像的地方,類似Github的repo

Docker安裝

以下是Ubuntu18.04的安裝過程:

1. 卸載舊版本(初次安裝不用做)

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

2. 使用Dokcer倉庫安裝

首先需要安裝一些需要的依賴包,如果確認已經都安裝過,就可以跳過。

# 更新源列表
$ sudo apt-get update
# 安裝所需依賴
$ sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common

然後添加官方庫的GPG密鑰:

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

可以查看是否添加成功,通過搜索指紋的後8位:

$ sudo apt-key fingerprint 0EBFCD88

pub   rsa4096 2017-02-22 [SCEA]
      9DC8 5822 9FC7 DD38 854A  E2D8 8D81 803C 0EBF CD88
uid           [ unknown] Docker Release (CE deb) <[email protected]>
sub   rsa4096 2017-02-22 [S]

添加Docker倉庫:

sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable"

然後更新以下源列表,再進行安裝:

# 更新源列表
$ sudo apt-get update
# 安裝docker-ce
$ sudo apt-get install docker-ce

檢查安裝是否成功:

$ sudo docker version

Client: Docker Engine - Community
 Version:           19.03.5
 API version:       1.40
 Go version:        go1.12.12
 Git commit:        633a0ea838
 Built:             Wed Nov 13 07:29:52 2019
 OS/Arch:           linux/amd64
 Experimental:      false
 ......
 ......

或者直接運行:

$ sudo docker run hello-world

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
9bb5a5d4561a: Pull complete
Digest: sha256:3e1764d0f546ceac4565547df2ac4907fe46f007ea229fd7ef2718514bcec35d
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.
......

上述信息說明,一開始沒有找到hello-world的鏡像,所以需要從默認倉庫拉取,拉取完之後,創建了一個容器,然後在裏面執行了程序,看到輸出了一個Hello from Docker的信息。此時可以看到成功安裝了Docker並且創建了第一個容器來運行。

將用戶加入Docker組

如果不使用sudo,直接執行docker命令的話,我們會看到一些錯誤信息,如下所示:

$ docker version

Client: Docker Engine - Community
 Version:           19.03.5
 API version:       1.40
 Go version:        go1.12.12
 Git commit:        633a0ea838
 Built:             Wed Nov 13 07:29:52 2019
 OS/Arch:           linux/amd64
 Experimental:      false
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.40/version: dial unix /var/run/docker.sock: connect: permission denied

因爲當前用戶沒有足夠的權限,所以需要在前面加上sudo,可是這樣就十分不方便,每次輸指令都需要sudo一下。
這是因爲,默認情況下,該docker命令只能由root用戶或docker組中的用戶運行,該用戶在Docker的安裝過程中自動創建。
解決辦法就是,將當前用戶加入docker組當中去。

$ sudo usermod -aG docker ${USER}

將指定的用戶加入用戶組中去,然後註銷重新登陸一下,就可以不使用sudo來執行docker的指令了。

Docker實踐

運行Ubuntu容器

剛剛我們已經成功創建並且運行了hello-world的應用。
現在嘗試一些別的。

search

使用search可以搜索鏡像庫中存在的鏡像列表:

$ docker search ubuntu

NAME                                                      DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
ubuntu                                                    Ubuntu is a Debian-based Linux operating sys鈥�   10271               [OK]                
dorowu/ubuntu-desktop-lxde-vnc                            Docker image to provide HTML5 VNC interface 鈥�   370                                     [OK]
rastasheep/ubuntu-sshd                                    Dockerized SSH service, built on top of offi鈥�   236                                     [OK]
consol/ubuntu-xfce-vnc                                    Ubuntu container with "headless" VNC session鈥�   199                                     [OK]
ubuntu-upstart                                            Upstart is an event-based replacement for th鈥�   102                 [OK]                
ansible/ubuntu14.04-ansible                               Ubuntu 14.04 LTS with ansible                   98                                      [OK]
neurodebian                                               NeuroDebian provides neuroscience research s鈥�   62                  [OK]                
1and1internet/ubuntu-16-nginx-php-phpmyadmin-mysql-5      ubuntu-16-nginx-php-phpmyadmin-mysql-5          50     

pull

可以選擇自己想要的版本進行拉取,這裏選用默認的:

$ docker pull ubuntu

Using default tag: latest
latest: Pulling from library/ubuntu
6b98dfc16071: Pull complete
4001a1209541: Pull complete
6319fc68c576: Pull complete
b24603670dc3: Pull complete
97f170c87c6f: Pull complete
Digest: sha256:5f4bdc3467537cbbe563e80db2c3ec95d548a9145d64453b06939c4592d67b6d
Status: Downloaded newer image for ubuntu:latest

images

通過指令查看本地鏡像列表:

$ docker images

REPOSITORY             TAG                 IMAGE ID            CREATED             SIZE
ubuntu                 latest              775349758637        6 weeks ago         64.2MB
hello-world            latest              fce289e99eb9        11 months ago       1.84kB

交互式運行Ubuntu容器

$ docker run -it ubuntu
# 進入到容器的ubuntu環境中
root@d50fe7bde791:/# 

注意到的是,雖然容器使用的版本是Ubunut16.04,但是內核還是會使用宿主機的內核(區別於虛擬化技術),所以即使查看內核,還是會顯示當前宿主機的內核信息。

root@d50fe7bde791:/# uname -a
Linux d50fe7bde791 5.0.0-37-generic #40~18.04.1-Ubuntu SMP Thu Nov 14 12:06:39 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

然後就可以在這個容器裏面執行一些基本命令來測試了。

Docker基本操作

管理Container

使用docker container 查看幫助:

$ docker container

Usage:	docker container COMMAND

Manage containers

Commands:
  attach      Attach local standard input, output, and error streams to a running container
  commit      Create a new image from a container's changes
  cp          Copy files/folders between a container and the local filesystem
  create      Create a new container
  diff        Inspect changes to files or directories on a container's filesystem
  exec        Run a command in a running container
  export      Export a container's filesystem as a tar archive
  inspect     Display detailed information on one or more containers
  kill        Kill one or more running containers
  logs        Fetch the logs of a container
  ls          List containers
  pause       Pause all processes within one or more containers
  port        List port mappings or a specific mapping for the container
  prune       Remove all stopped containers
  rename      Rename a container
  restart     Restart one or more containers
  rm          Remove one or more containers
  run         Run a command in a new container
  start       Start one or more stopped containers
  stats       Display a live stream of container(s) resource usage statistics
  stop        Stop one or more running containers
  top         Display the running processes of a container
  unpause     Unpause all processes within one or more containers
  update      Update configuration of one or more containers
  wait        Block until one or more containers stop, then print their exit codes

可以看到基本上跟進程的操作類似,主要掌握起、停、查看狀態、連接幾個基本操作;
實際上,並不需要加container命令參數,docker指令本身也能夠執行這些命令,如:

  • docker ps == docker container ls
  • docker start ${CONTAINER} == docker container start ${CONTAINER}
  • docker attach ${CONTAINER} == docker container attach ${CONTAINER}
  • 等等就不一一列舉。

下面就以剛剛運行的ubuntu容器做例子:

# 在退出了ubuntu容器之後,進程也自動停止了,所以這裏不能夠看到
$ docker ps

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
$ docker ps -a
CONTAINER ID        IMAGE                  COMMAND                  CREATED             STATUS                           PORTS               NAMES
d50fe7bde791        ubuntu                 "bash"                   24 hours ago        Exited (127) About an hour ago                       beautiful_mestorf
9c053d7c27ad        hello-world            "/hello"                 24 hours ago        Exited (0) 24 hours ago                              happy_ellis

可以看到之前創建的兩個容器,但是狀態都是停止的。

現在可以先啓動容器,通過其ID或者是名字:

# docker start beautiful_mestorf
$ docker start d50fe7bde791
d50fe7bde791
# 連接到容器
$ docker attach d50fe7bde791
root@d50fe7bde791:/# 

然後就能像剛剛那樣去終端調試它了。

對於不想要的容器,可以使用rm來刪除它(兩種命令方式,我比較喜歡簡潔一點的):

# $ docker container rm d50fe7bde791
$ docker rm d50fe7bde791

管理鏡像

使用docker image查看幫助:

$ docker image

Usage:	docker image COMMAND

Manage images

Commands:
  build       Build an image from a Dockerfile
  history     Show the history of an image
  import      Import the contents from a tarball to create a filesystem image
  inspect     Display detailed information on one or more images
  load        Load an image from a tar archive or STDIN
  ls          List images
  prune       Remove unused images
  pull        Pull an image or a repository from a registry
  push        Push an image or a repository to a registry
  rm          Remove one or more images
  save        Save one or more images to a tar archive (streamed to STDOUT by default)
  tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE

跟之前一樣有一些指令是不需要加image這個參數的:
如:

  • docker images == docker image ls
  • docker rmi ${IMAGE} == docker image rm ${IMAGE}
  • 等等

使用history可以查看對鏡像執行過什麼操作。
這裏解釋一下,因爲鏡像的組成過程中是一層一層往上套的,比如說,在ubuntu鏡像創建的容器裏,安裝一些基本的軟件如vim等,然後把這個容器構建成一個新的鏡像,這時候這個鏡像就相當於在ubuntu鏡像的基礎上運行了幾條指令。
下面進行測試,首先進入ubuntu容器,然後安裝幾個軟件(Ubuntu基本使用,這裏不展開說明),結束之後,回到自己的終端,使用docker commit ${container_id} ${image_name}創建一個新的鏡像:

$ docker commit d50fe7bde791 test
sha256:97c46372fe797e69871fff1741af09bfecb73ffda236d81e12f1d54635fe9e16
hsy@ubuntu:~$ docker images
REPOSITORY             TAG                 IMAGE ID            CREATED             SIZE
test                   latest              97c46372fe79        15 seconds ago      245MB
ubuntu                 latest              775349758637        6 weeks ago         64.2MB
hello-world            latest              fce289e99eb9        11 months ago       1.84kB

可以看到比初始的鏡像大了很多,因爲裝了幾個軟件的原因。
然後可以通過history來查看這個構建的過程:

$ docker history test
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
97c46372fe79        3 minutes ago       bash                                            181MB               
775349758637        6 weeks ago         /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B                  
<missing>           6 weeks ago         /bin/sh -c mkdir -p /run/systemd && echo 'do…   7B                  
<missing>           6 weeks ago         /bin/sh -c set -xe   && echo '#!/bin/sh' > /…   745B                
<missing>           6 weeks ago         /bin/sh -c [ -z "$(apt-get indextargets)" ]     987kB               
<missing>           6 weeks ago         /bin/sh -c #(nop) ADD file:a48a5dc1b9dbfc632…   63.2MB

可以看到第二個image的id就是ubuntu的ID,就是說明,這個鏡像是從ubuntu鏡像的基礎上執行了一些命令,套了一個新的層來構建的。

docker網絡

docker默認網關是172.17.0.1,然後創建容器的時候,會默認自動分配給172.17.0.2.。。。這樣的地址,是因爲子網的設置就是172.17.0.0/16,
通過docker network create XXX可以創建新的網橋,然後在創建容器的時候可以指定分配IP,或所使用的網絡:

$ docker run --name u1 --net mynet -it -p 8080:80 --rm ubuntu-aliyun_source:net
$ docker run --name u2 --net mynet -it --rm ubuntu-aliyun_source:net
  • --net指定所使用的網橋
  • -p指定容器端口與網橋端口的映射關係,類似NAT的變換。

MySQL與容器化

首先到Registry上拉取mysql的鏡像,拉取方式之前已經講過了。
然後啓動:

# 服務端
$ docker run -p 3306:3306 --name mysql2 -e MYSQL_ROOT_PASSWORD=root -d mysql

# 客戶端
$ docker run -it --net host mysql:5.7 "sh"
$ mysql -h127.0.0.1 -P3306 -uroot -proot

這樣可以連上服務器。

更改volume

創建叫mydb的volumn

$ docker rm $(docker ps -a -q) -f -v

$ docker volume create mydb
$ docker volume ls
DRIVER              VOLUME NAME
local               39898de78ce82ac68d13ccd7bb00aa5f58ddceacf86d88339c002ac6ffbf879f
local               mydb

將自己定義的volumn掛載到相應的目錄下,創建數據庫容器

$ docker run --name mysql2 -e MYSQL_ROOT_PASSWORD=root -v mydb:/var/lib/mysql -d mysql

使用客戶端連接:

$ docker run --name myclient --link mysql2:mysql -it mysql bash

mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.18 MySQL Community Server - GPL

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> ...

本次實驗先到這裏,之後繼續學習docker的知識。
初次學習,有很多概念都不太懂,現在先總結一下。如有錯誤,請指正,謝謝!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章