docker學習(常用命令,映象燒錄,定製映象)

chinagod發表於2024-07-13

docker常用命令

檢視Docker版本

docker version

列印測試資訊

sudo docker run hello-world

檢視映象

sudo docker images

檢視容器

sudo docker ps -a

進入容器,執行bash命令。

docker exec -it webserver bash
root@3729b97e8226:/# echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
root@3729b97e8226:/# exit
exit

不需要sudo執行docker的辦法

參考自https://www.runoob.com/note/51562

安裝完 docker 後,執行docker相關命令,出現:

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.26/images/json: dial unix /var/run/docker.sock: connect: permission denied“

原因

摘自docker 手冊上的一段話:

Manage Docker as a non-root user

The docker daemon binds to a Unix socket instead of a TCP port. By default that Unix socket is owned by the user root and other users can only access it using sudo. The docker daemon always runs as the root user.

If you dont want to use sudo when you use the docker command, create a Unix group called docker and add users to it. When the docker daemon starts, it makes the ownership of the Unix socket read/writable by the docker group

大概的意思就是:docker程序使用Unix Socket而不是TCP埠。而預設情況下,Unix socket屬於root使用者,需要root許可權才能訪問。

解決方法1

使用sudo獲取管理員許可權,執行docker命令

解決方法2

docker守護程序啟動的時候,會預設賦予名字為docker的使用者組讀寫Unix socket的許可權,因此只要建立docker使用者組,並將當前使用者加入到docker使用者組中,那麼當前使用者就有許可權訪問Unix socket了,進而也就可以執行docker相關命令

sudo groupadd docker     #新增docker使用者組
sudo gpasswd -a $USER docker     #將登陸使用者加入到docker使用者組中
newgrp docker     #更新使用者組
docker ps    #測試docker命令是否可以使用sudo正常使用

docker燒錄映象/打包系統示例(不建議使用,參見下一節)

參考自https://bbs.06climate.com/forum.php?mod=viewthread&tid=50384&fromuid=12776 (出處: 氣象家園)

建立自己的映象

#1 下載乾淨的ubuntu映象
docker search ubuntu
docker pull ubuntu #乾淨的ubuntu
docker images

#2 基於映象建立容器
docker run -i -t f49eec89601e /bin/bash #其中的-t是映象的id
docker ps -a

# (本機與容器共享檔案)的方法,加入-v引數
docker run -it -v /home/jinhuanz:/root f49eec89601e /bin/bash

#
sudo docker commit 7e2e33e3f556 jinhuan/ubuntu-meteorology:0.0.1

push映象到docker hub個人的倉庫

# should create id first

step1——找到本地映象的ID:docker images

step2——登陸Hub:docker login --username=username --password=password --email=email

step3——tag:docker tag <imageID> <namespace>/<image name>:<version tag eg latest>

step4——push映象:docker push <namespace>/<image name>

docker pull <namespace>/<image name>

即可使用。

注意! 慎用docker commit(參見https://yeasy.gitbook.io/docker_practice/image/commit)

原因如下:

第一,docker commit命令是對現有的系統目錄的檔案進行打包,如果是編譯、安裝軟體包,那麼所有的檔案(包括程式碼編譯產生的臨時物件檔案)也會一同打包進來,會導致映象極為臃腫。

第二,docker映象是分層儲存的形式儲存的,使用 docker commit 命令,會給舊的映象新增了新的一層,而原先的舊的映象內容依然存在、不會被刪除。

除當前層外,之前的每一層都是不會發生改變的,換句話說,任何修改的結果僅僅是在當前層進行標記、新增、修改,而不會改動上一層。如果使用 docker commit 製作映象,以及後期修改的話,每一次修改都會讓映象更加臃腫一次,所刪除的上一層的東西並不會丟失,會一直如影隨形的跟著這個映象,即使根本無法訪問到。這會讓映象更加臃腫。

第三,因為使用docker commit是對系統進行打包,因此也不知道這個映象是如何建立的。

就是除了製作映象的人知道執行過什麼命令、怎麼生成的映象,別人根本無從得知。而且,即使是這個製作映象的人,過一段時間後也無法記清具體的操作。這種黑箱映象的維護工作是非常痛苦的。

使用 Dockerfile 定製映象(請參考使用 Dockerfile 定製映象 | Docker — 從入門到實踐

映象的定製實際上就是定製每一層所新增的配置、檔案。如果我們可以把每一層修改、安裝、構建、操作的命令都寫入一個指令碼,用這個指令碼來構建、定製映象,那麼之前提及的無法重複的問題、映象構建透明性的問題、體積的問題就都會解決。這個指令碼就是 Dockerfile。

Dockerfile 是一個文字檔案,其內包含了一條條的 指令(Instruction),每一條指令構建一層,因此每一條指令的內容,就是描述該層應當如何構建。

主要指令

FORM 指定基礎映象

RUN 執行命令

在撰寫 Dockerfile 的時候,要經常提醒自己,這並不是在寫 Shell 指令碼,而是在定義每一層該如何構建。

層數儘量少,用&&將命令串聯起來

示例指令碼

FROM debian:stretch

RUN set -x; buildDeps='gcc libc6-dev make wget' \
    && apt-get update \
    && apt-get install -y $buildDeps \
    && wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
    && mkdir -p /usr/src/redis \
    && tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1 \
    && make -C /usr/src/redis \
    && make -C /usr/src/redis install \
    && rm -rf /var/lib/apt/lists/* \
    && rm redis.tar.gz \
    && rm -r /usr/src/redis \
    && apt-get purge -y --auto-remove $buildDepsc

編譯安裝命令放在一層,刪除多餘的庫

Dockerfile寫好後,構建映象。進入Dockerfile所在的目錄,命令格式為:docker build [選項] <上下文路徑/URL/->

docker build -t nginx:v3 .

這個 .,實際上是在指定上下文的目錄,docker build 命令會將該目錄下的內容打包交給 Docker 引擎以幫助構建映象。

一般來說,應該會將 Dockerfile 置於一個空目錄下,或者專案根目錄下。如果該目錄下沒有所需檔案,那麼應該把所需檔案複製一份過來。如果目錄下有些東西確實不希望構建時傳給 Docker 引擎,那麼可以用 .gitignore 一樣的語法寫一個 .dockerignore,該檔案是用於剔除不需要作為上下文傳遞給 Docker 引擎的。

實際上,Dokerfile的檔名不要求必須為 Dockerfile,而且並不要求必須位於上下文目錄中,詳細資訊參見https://yeasy.gitbook.io/docker_practice/image/build

相關文章