從入門到實踐 —— Docker

Docker 介紹

參考:爲什麼需要Docker?

Docker 是一個開源的應用容器引擎,基於 Go 語言並遵從 Apache2.0 協議開源。

主要應用場景如下:

  1. 環境隔離

    容器間環境相互獨立,互不影響。類似於虛擬機,但相比於更輕量。Docker 各個容器共享一個操作系統內核,而每一個虛擬機都有一套完整的操作系統。

  2. 整體部署

    可以將一整套環境構建爲鏡像,進行整體部署,避免線上線下開發環境帶來的各種問題,同時也極大地提高了部署效率,不再需要重複配置開發環境。

Docker 架構

Docker 的三個重要概念:

  1. 鏡像(Image)

    相當於一個操作系統模板,比如官方鏡像 mysql 就包含了一套完整的操作系統。

  2. 容器(Container)

    容器是鏡像運行的實體,好比於 Java 中對象是類的實例。容器可以被創建、啓動、暫停和停止等。

  3. 倉庫(Repository)

    保存鏡像的倉庫,好比於 Maven 倉庫用來保存依賴的 Jar 包。

Docker 使用客戶端-服務器 (C/S) 架構模式,使用遠程 API 來管理和創建 Docker 容器。

  1. Docker_Client

    通過命令行與 Docker daemon(守護進程)通信。

  2. Docker_Host

    用於執行 Docker daemon 的主機。

  3. Registry

    Docker 倉庫,一個 Registry 可以包含多個 Repository 倉庫。

Docker 安裝

CentOS

卸載舊版本(如果存在)

yum remove docker docker-common docker-selinux docker-engine

安裝依賴軟件包

yum install -y yum-utils device-mapper-persistent-data lvm2

設置 yum 源

yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

安裝 Docker

yum install -y docker-ce docker-ce-cli containerd.io

可能由於版本原因提示 requires containerd.io >= 1.2.2-3,先手動安裝新版 containerd.io:

wget https://download.docker.com/linux/centos/7/x86_64/edge/Packages/containerd.io-1.2.6-3.3.el7.x86_64.rpm
yum -y install containerd.io-1.2.6-3.3.el7.x86_64.rpm

然後重新執行 Docker 安裝命令即可。

啓動並加入開機啓動

systemctl start docker && systemctl enable docker

驗證

docker version

鏡像加速

運行 bash 命令;

curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f1361db2.m.daocloud.io

然後重啓 docker 服務;

systemctl daemon-reload && systemctl restart docker

遠程訪問

修改 docker 服務腳本:

vi /lib/systemd/system/docker.service

ExecStart=/usr/bin/dockerd這一行的後面添加:

 -H tcp://0.0.0.0:2375

然後重啓 docker 服務:

systemctl daemon-reload && systemctl restart docker

驗證操作結果:

curl http://localhost:2375/version

遠程訪問(TLS)

上述開放遠程訪問存在極大的安全隱患,沒有認證授權,可採用 TLS 認證完善;

#創建 Docker TLS 證書
#!/bin/bash

#相關配置信息
SERVER="106.13.180.17"
PASSWORD="123456"
COUNTRY="CN"
STATE="湖北省"
CITY="武漢市"
ORGANIZATION="公司名稱"
ORGANIZATIONAL_UNIT="Dev"
EMAIL="[email protected]"

###開始生成文件###
echo "開始生成文件"

#切換到生產密鑰的目錄
cd /etc/docker   
#生成ca私鑰(使用aes256加密)
openssl genrsa -aes256 -passout pass:$PASSWORD  -out ca-key.pem 2048
#生成ca證書,填寫配置信息
openssl req -new -x509 -passin "pass:$PASSWORD" -days 3650 -key ca-key.pem -sha256 -out ca.pem -subj "/C=$COUNTRY/ST=$STATE/L=$CITY/O=$ORGANIZATION/OU=$ORGANIZATIONAL_UNIT/CN=$SERVER/emailAddress=$EMAIL"

echo "subjectAltName = IP:$SERVER" >> extfile.cnf
echo "extendedKeyUsage = serverAuth" >> extfile.cnf
#生成server證書私鑰文件
openssl genrsa -out server-key.pem 2048
#生成server證書請求文件
openssl req -subj "/CN=$SERVER" -new -key server-key.pem -out server.csr
#使用CA證書及CA密鑰以及上面的server證書請求文件進行簽發,生成server自簽證書
openssl x509 -req -days 3650 -in server.csr -CA ca.pem -CAkey ca-key.pem -passin "pass:$PASSWORD" -CAcreateserial -out server-cert.pem -extfile extfile.cnf

#生成client證書RSA私鑰文件
openssl genrsa -out key.pem 2048
#生成client證書請求文件
openssl req -subj '/CN=client' -new -key key.pem -out client.csr

echo "extendedKeyUsage=clientAuth" > extfile.cnf
#生成client自簽證書(根據上面的client私鑰文件、client證書請求文件生成)
openssl x509 -req -days 3650 -in client.csr -CA ca.pem -CAkey ca-key.pem  -passin "pass:$PASSWORD" -CAcreateserial -out cert.pem -extfile extfile.cnf

#更改密鑰權限
chmod 0400 ca-key.pem key.pem server-key.pem
#更改密鑰權限
chmod 0444 ca.pem server-cert.pem cert.pem
#刪除無用文件
rm client.csr server.csr

echo "生成文件完成"
###生成結束###

同時修改 docker 服務腳本:

vi /lib/systemd/system/docker.service

修改ExecStart=/usr/bin/dockerd這一行爲:

ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock \
         --tlsverify \
         --tlscacert=/etc/docker/ca.pem \
         --tlscert=/etc/docker/server-cert.pem \
         --tlskey=/etc/docker/server-key.pem \
         -H tcp://0.0.0.0:2376

重啓 docker;

systemctl daemon-reload && systemctl restart docker

連接驗證;

docker --tlsverify --tlscacert=/etc/docker/ca.pem   --tlscert=/etc/docker/cert.pem --tlskey=/etc/docker/key.pem -H tcp://106.13.180.17:2376 version

注意服務 IP 填寫自己對應的主機 IP。

Hello World

docker run hello-world

運行 hello-world 鏡像,先在本地主機查找,不存在則從鏡像倉庫中拉取。

[root@localhost ~]# docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
1b930d010525: Pull complete 
Digest: sha256:9572f7cdcee8591948c2963463447a53466950b3fc15a247fcad1917ca215a2f
Status: Downloaded newer image for hello-world:latest

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

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

常用命令

參考:Docker 命令大全

docker run ubuntu:15.10 /bin/echo "Hello world"

運行一個 ubuntu 容器,版本號爲 15.10,並執行 /bin/echo “hello world”。

docker exec -it centos /bin/bash

進入一個 name 爲 centos 的容器,並且跳轉到該容器 bash 終端。

可選項

  1. -i

    交互式操作,通常和 -t 組合使用;

  2. -t

    在新容器內指定一個僞終端;

  3. -d

    後臺運行;

  4. -e

    設置環境變量;

  5. -p

    端口映射,主機端口:容器端口

容器

  1. ps

    獲取容器列表;

  2. run

    指定鏡像運行一個容器;

  3. start/stop/restart

    啓動、停止或重啓一個容器;

  4. rm

    刪除容器;

  5. exec

    在容器內執行命令;

  6. logs

    獲取容器內的日誌;

鏡像

  1. images

    獲取本地鏡像列表;

  2. rmi

    刪除本地鏡像;

部分 <none>:<none> 的鏡像沒有任何引用,可以通過 docker rmi $(docker images -f “dangling=true” -q) 清除。

實踐

時間同步

通常宿主機和 docker 容器機器時間不一致,可採取外部掛載解決;

-v /etc/localtime:/etc/localtime:ro

MySQL 安裝

安裝

創建一個 mysql 容器,映射本機端口 3306 至容器,並初始化密碼爲 123456;

docker run -d --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql

數據持久化

每次重新創建 mysql 容器相關數據會被初始化,可以通過 -v 指定掛載路徑;

docker run -d --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -v /docker/mysql/data:/var/lib/mysql mysql

添加遠程用戶

進入 mysql 容器 bash 終端交互;

docker exec -it mysql /bin/bash

連接 mysql 服務;

mysql -uroot -p123456

執行下面 SQL;

create user 'caojiantao'@'%' identified with mysql_native_password by '123456';
grant all privileges on *.* to 'caojiantao'@'%' with grant option;
flush privileges;

SpringBoot 部署(Idea)

Docker 連接

如果 docker 遠程連接採用 TLS 連接,那麼首先將服務器的ca.pemcert.pemkey.pem三個文件下載到本地D:\docker目錄,然後如圖設置 docker 連接;

Dockerfile

新建 Dockerfile 文件,用來構建鏡像,放在項目的根目錄;

FROM java:8
ADD "/target/docker-0.0.1-SNAPSHOT.jar" "app.jar"
EXPOSE 8080
ENTRYPOINT [ "java", "-jar", "app.jar" ]

鏡像部署

增加鏡像部署配置,注意最底部 Maven 命令,clean package -DskipTests,用來生成構建鏡像需要的 jar 包;

外部掛載

通常需要掛載“項目配置”、“靜態資源”和“服務日誌”幾個目錄,通過 idea 也能很方便的操作,通過上圖中的Bind mounts設置;

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