iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 3
0

開講前先閒聊一下~

第一次使用Markdown,天呀,好好用喔!!

可惜我在用notejoy還沒支援Markdown(許願池已經有人提了,相信未來會有,必竟畢竟evernote已經支援了)
最近notejoy出web clipper beta,抓文、圖、code都蠻準的,可惜表格還是不行
notejoy web clipper for chrome
https://chrome.google.com/webstore/detail/notejoy-web-clipper/hdpnapnmccppiagahpoclpjdoimjjkic
notejoy新增的功能
https://notejoy.com/releases

本篇主要參考

用30天來介紹和使用Docker

https://ithelp.ithome.com.tw/users/20103456/ironman/1320

Docker —— 從入門到實踐

https://philipzheng.gitbooks.io/docker_practice/content/install/ubuntu.html

如果你的VM只是要跑Docker,可以用Docker Machine呦,也是有ssh的

安裝Docker Machine

1.先查版本,內含最新版的安裝指令 https://github.com/docker/machine/releases

基本上就是下載編譯好的docker-machine執行檔,權限設成可執行,放到/usr/local/bin

$ curl -L https://github.com/docker/machine/releases/download/v0.15.0/docker-machine-Linux-x86_64 >/tmp/docker-machine &&
    chmod +x /tmp/docker-machine &&
    sudo cp /tmp/docker-machine /usr/local/bin/docker-machine

2.用Docker Machine來建vm(支援VMWare Fusion、Virtual Box)

官方文件:https://docs.docker.com/machine/overview/

# 預設image用frapposelli/boot2docker
$ docker-machine create --driver=vmwarefusion vm1 # 假設你的mac有裝vm
可以設定資源
--vmwarefusion-cpu-count=2
--vmwarefusion-disk-size=20000 # 單位MB
--vmwarefusion-memory-size=2000 # 單位MB

# virtualbox有更多參數喔,"目前"官方是建議virtualbox 5+
# 預設image用boot2docker/boot2docker
$ docker-machine create --driver=virtualbox vbox-test
--virtualbox-boot2docker-url file://$HOME/Downloads/rc.iso # 如果有下載image可指定
--virtualbox-share-folder 共用的folder
--virtualbox-hostonly-cidr=192.168.99

# 部分執行畫面
# 建憑證
Creating CA: /home/user/.docker/machine/certs/ca.pem
Creating client certificate: /home/user/.docker/machine/certs/cert.pem
Latest release for github.com/boot2docker/boot2docker is v18.06.1-ce
(vbox-test) Downloading /home/user/.docker/machine/cache/boot2docker.iso from https://github.com/boot2docker/boot2docker/releases/download/v18.06.1-ce/boot2docker.iso
Creating machine...
(vbox-test) Copying /home/user/.docker/machine/cache/boot2docker.iso to /home/user/.docker/machine/machines/vbox-test/boot2docker.iso...
(vbox-test) Creating VirtualBox VM...
(vbox-test) Creating SSH key...
(vbox-test) Starting the VM...
(vbox-test) Check network to re-create if needed...
(vbox-test) Waiting for an IP...
  • Boot2Docker
    輕量的linux版本,用來跑docker containers,port 2376(是在iana上有註冊的)
    service name: docker-s (s代表用ssl加密)
    支援:(VirtualBox, Parallels, VMware, XenServer)

不負責任猜:
更新image吧? 如果有大大看不下去想更正,歡迎用留言喔,也避免我誤導他人

docker-machine upgrade 

把現有的virtualbox的vm轉成docker-machine的image?

docker-machine create -d virtualbox --virtualbox-import-boot2docker-vm boot2docker-vm b2d

3.使用docker-machine

$ docker-machine ls  # 用docker-mainchin建的vm清單
NAME    ACTIVE DRIVER   STATE  URL            SWARM DOCKER    ERRORS
vbox-test -    virtualbox Running tcp://192.168.99.100:2376     v18.06.1-ce  

$ docker-machine ssh vbox-test # 連到vbox-test,ssh自動設好了,跟vagrant一樣方便呢

$ docker run hello-world # 測試docker,叫一下來聽聽
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
d1725b59e92d: Pull complete 

# 刪掉vm
$ docker-machine rm <machine-name>

# 全刪(這個最重要!!!要怎麼在code裡面把字放大呢呢呢???)
$ docker-machine rm -f $(docker-machine ls -q)

# 備註
~/.docker/machine/machines/ # 不要手動去刪這個目錄裡的檔案

===========docker machine就先介紹到這邊啦============

Dockerfile

學習時可用docker run,但如果要配合docker compose、或者你想build image,就建議寫Dockerfile啦
分享1個學習的小技巧
到docker hub,查詢你想玩的image
就會有一堆公開的images,裡面可能有Dockerfile可參考
也有各種docker run的方式
例如:以Ubuntu來說,查gitlab,找一個Dockerfile是FROM ubuntu的
https://hub.docker.com/r/sameersbn/gitlab/~/dockerfile/
這樣就能學到別人怎麼從ubuntu中,安裝gitlab的過程

FROM ubuntu:latest
MAINTAINER user@gmail.com # 大德寶號
WORKDIR ~/workspace # 工作目錄
VOLUME ["~/Downloads:/storage"]
RUN apt-get update && apt-get install -y wget # -y很重要,就是都回答yes啦~
RUN cd /
ADD xxx.tar.gz / # copy 本目錄下的檔案到 /
# 設定環境變數
ENV XX_HOME=/xxx # 這個就像 ~/.bash_profile,告訴你的container啥咪bin檔放哪邊
ENV PATH=$PATH:/xxx/bin
CMD ["~/xxx.sh", "run"]
EXPOSR 8080 # 對外8080

Dockerfile 也能拿來建 image,放到 docker hub 普渡it人
$ docker build -t myBuildImage . # 嗯…暫時用不到build image

docker compose 一次跑多個container

一樣到官網看最新版的安裝指令

https://github.com/docker/compose/releases (記得自己去看latest版本)
https://oomusou.io/docker/dockerfile-dockercompose/

  • 安裝docker-compose
# 這是ubuntu的指令,建議可到官網看指令最新
$ curl -L https://github.com/docker/compose/releases/download/1.22.0/docker-compose-Linux-x86_64 -o /usr/local/bin/docker-compose
# 重點是,如果官網的指令不能裝成功,「-Linux-x86_64」自己打就好囉
# 不然直接下載也行,反正只是binary檔
chmod +x /usr/local/bin/docker-compose
  • 撰寫docker-compose.yml

參考官方文件,目前到docker-compose的compose file到version 3囉,https://docs.docker.com/compose/compose-file/
Compose file format 版本 會對應到 Docker Engine release 版本
基本上 Docker Engine 版本愈新愈好(向下支援)
https://docs.docker.com/compose/compose-file/#compose-and-docker-compatibility-matrix

  • 範例1
version: '3'
services:
  db:
     image: mysql
     environment:
        MYSQL_ROOT_PASSWORD: 123456
  admin:
     image: adminer
     ports:
       - 8080:8080
  • 範例2
version: "3.3"
services:
  wordpress:
    image: wordpress
    ports:
      - "8080:80"
    networks:
      - overlay # 指定相同的network,才能相連
    deploy:
      mode: replicated
# 多重影分身之術,運行2個container(如果你砍掉1個就會再跑1個)
      replicas: 2
# 預設的,Docker為service分配虛擬IP,Client不用知道後面有多少replicas
      endpoint_mode: vip 
  mysql:
    image: mysql
    volumes:
       - db-data:/var/lib/mysql/data
    networks:
       - overlay
# https://docs.docker.com/compose/compose-file/#deploy

    deploy:
      mode: replicated
      replicas: 2
# DNS round-robin,方便用 service name 反查 IP,常用於Load Balancer
      endpoint_mode: dnsrr 
volumes:
  db-data:
networks:
  overlay:

在跟yaml同目錄下,所以以下操作應該都是指這個yaml檔裡的container吧

$ docker-compose up -d
$ docker-compose ps # 看container執行狀態
$ docker-compose logs
$ docker-compose start
$ docker-compose stop
$ docker-compose rm -f # 要先stop,才能remove,-f == --force

==========docker machine就先介紹到這邊啦==========

這個重像蠻重要der

其實應該獨立一篇比較方便大家找

建一個local端的Registry(private docker registry)

如果在公司內部,我們開發環境包成一個image,這些image不方便放docker hub
這時候就需要自架 private docker registry

詳細請參考官網文件
https://docs.docker.com/registry/deploying/#run-a-local-registry

很多時候,我們Build出來的image不想push到Docker Hub,

  • 我們要建一個private的Docker Registry
$ docker run -d -p 5000:5000 -v /home/user1/storage:/var/lib/registry --name registry registry:2
  • 參數說明如下:
    -d:執行的 docker container 是 run 在背景的狀態,所以需要使用 docker logs 的指令才可以看到 log 狀態
    -p:主機的 5000 port mapping 到 container 的 5000 port
    -v:因為 push 到 docker registry 的資料是放在 container 裡面的,如果把 docker container 刪除掉 docker registry 的 Image 資料就會不見,因此需要使用 –v 參數將主機的檔案路徑 mapping 到 container 裡面的檔案路徑,這樣 docker container 被刪除 docker registry 的 Image 資料還會存在
    --name:設定 docker container 的名稱

  • 啟用registry

$ docker start registry
  • 關掉firewall (比較正確的做法應該是開port,或只允許localhost)
systemctl stop firewalld
systemctl disable firewalld

這邊指令看看就好,實際要看您用哪種firewall
例如我是用ufw

# 停掉daemon
$ sudo ufw disable
# 啟用,但全都允許通過
$ sudo ufw enable
$ sudo ufw default allow

Docker Registry補充說明

使用憑證

參考官網文件
https://docs.docker.com/registry/deploying/#get-a-certificate

如果你是在對外營運的正式環境,假設您已有
-已經有買domain name,假設是https://myregistrydomain.com/
-DNS、routeing、firewall允許port 443
-已經有買憑證

自簽憑證

https://docs.docker.com/registry/insecure/#use-self-signed-certificates

$ openssl req \
  -newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key \
  -x509 -days 365 -out certs/domain.crt # 放到certs/,其他都一樣

# ubuntu
# 把憑證copy到OS,讓OS也認這張憑證
$ cp certs/domain.crt /usr/local/share/ca-certificates/myregistrydomain.com.crt
$ update-ca-certificates

-設定Docker daemon去信任你的自簽憑證
把domain.crt copy到每個Docker的/etc/docker/certs.d/myregistrydomain.com:5000/ca.crt
然後重啟docker daemon

$ systemctl restart docker
或
$ service docker restart
$ mkdir -p certs
# copy domain.crt跟domain.key 到 certs/
$ docker container stop registry
$ docker run -d \
  --restart=always \
  --name registry \
  -v `pwd`/certs:/certs \ # 把host的$(pwd)/certs mount到 container的certs/
  -e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
  -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \ # 餵 憑證 跟 private key
  -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
  -p 443:443 \
  registry:2

試玩一下
-從docker hub抓image下來,加tag,放到私有的private docker registry

$ docker pull ubuntu:16.04
$ docker tag ubuntu:16.04 myregistrydomain.com/my-ubuntu
$ docker push myregistrydomain.com/my-ubuntu
$ docker pull myregistrydomain.com/my-ubuntu

大部分時候,憑證是一層信認一層(從root ca->...->發你憑證的CA),
這中間的憑證(intermediate certificate)都要串接起來

$cat domain.crt intermediate-certificates.pem > certs/domain.crt

上面是把registry跑成獨立的container,
下面我們把他跑成service

Run the registry as a service

(常用於 Docker Swarm,架構上會有多個node)

# 將TLS certificate和key保存為secrets
$ docker secret create domain.crt certs/domain.crt
$ docker secret create domain.key certs/domain.key

# 加label
$ docker node ls # 列出你有哪些node
# 標注你的registry跑在哪個node
$ docker node update --label-add registry=true node1 # 假設跑在node1

# 最後,把service registry跑起來
$ docker service create \
  --name registry \
  --secret domain.crt \
  --secret domain.key \
  --constraint 'node.labels.registry==true' \
  --mount type=bind,src=/mnt/registry,dst=/var/lib/registry \
  -e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
  -e REGISTRY_HTTP_TLS_CERTIFICATE=/run/secrets/domain.crt \
  -e REGISTRY_HTTP_TLS_KEY=/run/secrets/domain.key \
  --publish published=443,target=443 \
  --replicas 1 \ # 同一時間只跑single replica
  registry:2

secrets會放在/run/secrets/<secret-name> # service的secrets預設都放這裡吧?

# 如此就可在所有的swarm node透過port 443用這個service

今天最後介紹…

使用Docker Registry的API

請參考官方文件
https://docs.docker.com/engine/api/version-history/
因為版本更新太快了,最新版請找(latest stable)
點左邊的指令,就中間就是說明,右邊就是實際用法。

$ curl -X GET http://192.168.182.134:5000/v2/_catalog
$ curl -X GET http://192.168.182.134:5000/v2/mytomcat/tags/list # API的版本,image name,列出tag清單
  • 建一個hyper/docker-regitry-web的container,給他環境變數REGISTRY_URL,就能用localhost:8080看
$ docker run -d -p 8080:8080 --name registry-web --link registry -e REGISTRY_URL=http://192.168.182.134:5000/v2 hyper/docker-registry-web
  • 修改host的/etc/docker/daemon.json
{
  "live-restore": true,
  "group": "dockerroot",
  "insecure-registries": ["192.168.182.134:5000"],
# 讓外面的host連進來用API 
  "hosts": [
     "unix:///var/run/docker.sock",
     "tcp://192.168.182.130:2375"
  ]

}
$ systemctl restart docker # 改完後重啟
  • push image
$ docker tag mytomcat 192.168.182.134:5000/mytomcat # 先tag
$ docker push 192.168.182.134:5000/mytomcat
  • pull image
$ docker pull 192.168.182.134:5000/mytomcat # 抓image
  • 其他API操作
$ curl -X POST http://192.168.182.130:2375/images/create?fromImage=nginx:latest
http://192.168.182.130:2375/images/json # 用瀏覽器開啟
curl -X GET http://192.168.182.130:2375/containers/json # 類似 docker ps

# 從Docker Hub來pull nginx:latest
curl -X POST http://192.168.182.130:2375/images/create?fromImage=nginx:latest
# 執行container
curl -X POST http://192.168.182.130:2375/containers/nginx_container/start
# 刪除container
$ curl -X POST http://192.168.182.130:2375/containers/nginx_container/stop
$ curl -X DELETE http://192.168.182.130:2375/containers/nginx_container

API實在太強大了,很方便用各種語言用http操作,
想像一個情境:
以後測試,就可以用API動態建一個測試環境(例如:塞假資料的的測試資料庫),測完刪掉container

其實前端若要練HTTP,例如:Angular,若要練HttpClient,
跑個hyper/docker-regitry-web的container就有API能玩了~
科科科


上一篇
day02_docker01_基礎指令
下一篇
day05_docker04_Jenkins
系列文
在地端建置Angular+ASP.NET Core的DevOps環境31

尚未有邦友留言

立即登入留言