dockerfedora1

Develop Application บน Docker สำหรับ Fedora

สำหรับ การใช้าน Docker บน  Fedora 24 มีขั้นตอนดังนี้ โดยอ้างอิงตาม https://docs.docker.com/engine/installation/linux/fedora/  ข้อกำหนดเบื้องต้นสำหรับการทำงานของ Docker จะต้อง run อยู่บนเครื่อง 64 บิต และต้องมี kernel อย่างน้อย 3.10 เป็นต้นไป การติดตั้ง สามารถติดตั้งได้ 2 วิธี คือติดตั้งผ่าน dnf package manager หรือ สามารถที่จะ ติดตั้งได้ด้วย script ด้วยการ download โดยใช้คำสั่ง curl

$ sudo dnf update -y
$ uname -r
4.6.5-300.fc24.x86_64

วิธี 1 ติดตั้งด้วย dnf
ติดตั้ง repo

$ sudo tee /etc/yum.repos.d/docker.repo <<-'EOF'
[dockerrepo]
name=Docker Repository
baseurl=https://yum.dockerproject.org/repo/main/fedora/$releasever/
enabled=1
gpgcheck=1
gpgkey=https://yum.dockerproject.org/gpg
EOF

ติดตั้ง package

sudo dnf install docker-engine
sudo systemctl enable docker.service
sudo systemctl start docker

## view process
root      9446     1  0 15:15 ?        00:00:00 /usr/bin/dockerd
root      9464  9446  0 15:15 ?        00:00:00 docker-containerd -l unix:///var/run/docker/libcontainerd/docker-containerd.sock --shim docker-containerd-shim --metrics-interval=0 --start-timeout 2m --state-dir /var/run/docker/libcontainerd/containerd --runtime docker-runc

## test
sudo docker run hello-world

ตั้งค่าให้ user สามารถใช้คำสั่ง docker ได้โดยตรง ไม่ต้องใช้ sudo
เนื่องจาก docker daemon เชื่อมต่อกับ unix socket แทนที่จะเชื่อมไปยัง TCP port โดยค่า default unit socket จะมี root เป็น owner และ userอื่นๆ จะต้องใช้สิทธิ sudo จากเหตุผลข้างต้นนี้ docker daemon จะต้อง run ด้วย user root เสมอ ดังนั้นให้เพิ่ม user ที่ใช้งานปัจจุบันให้อยู่ใน group ของ docker ก่อน ดังนี้

sudo usermod -a -G docker ${USER}
sudo newgrp docker
## ให้ logout and logback เพื่อให้ทำงานด้วย permission ที่ถูกต้อง
## test ไม่ต้องใช้ sudo
docker info
docker run hello-world

วิธี 2 ติดตั้งด้วย curl + script

$ curl -fsSL https://get.docker.com/ | sh
sudo systemctl enable docker.service
sudo systemctl start docker

เริ่มต้นการเรียนรู้
โดยจะแบ่งออกส่วนๆ เพื่อให้สามารถติดตามและทำความเข้าใจได้ดังนี้

1 Docker run และความหมาย

$ docker run busybox /bin/echo this is an echo
Unable to find image 'busybox:latest' locally
latest: Pulling from library/busybox
8ddc19f16526: Pull complete 
Digest: sha256:a59906e33509d14c036c8678d687bd4eec81ed7c4b8ce907b888c607f6a1e0e6
Status: Downloaded newer image for busybox:latest
this is an echo

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS               NAMES
c2d9777c7668        busybox             "/bin/echo this is an"   50 seconds ago      Exited (0) 46 seconds ago                       reverent_hodgkin

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
busybox             latest              2b8fd9751c4c        7 weeks ago         1.093 MB

คำสั่งด้านบน คือ pull image ‘busybox’ และ run busybox และเรียกใช้ /bin/echo และส่งค่า string “this is an echo” ไปยัง busy box

$ docker run -i -t 2b8fd9751c4c
/ # ls
bin   dev   etc   home  proc  root  sys   tmp   usr   var
/ # exit

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS                      PORTS               NAMES
5e721f04e31c        2b8fd9751c4c        "sh"                     46 seconds ago       Exited (0) 24 seconds ago                       focused_mclean
c2d9777c7668        busybox             "/bin/echo this is an"   4 minutes ago        Exited (0) 4 minutes ago                        reverent_hodgkin

คำสั่งด้านบน เป็นการ run image ซ้ำอีกครั้ง และเรีียกคำสั่ง sh อัตโนมัติ ทุกครั้งที่มีการสั่งคำสั่ง docker run ก็ได้ container ใหม่ทุกครั้ง

$ docker attach 5e721f04e31c
You cannot attach to a stopped container, start it first

$ docker start 5e721f04e31c
5e721f04e31c

$ docker attach 5e721f04e31c
/ # touch test.txt
/ # exit

$ docker diff 5e721f04e31c
C /root
A /root/.ash_history
A /test.txt


คำสั่งด้านบน เป็นการ attach ไปยัง container 5e721f04e31c เดิมที่เคย run ไว้ก่อนแล้ว แต่ต้อง start ก่อน ก่อนที่ ทำการ attach เมืื่อ attach แล้วให้มีการเปลี่ยนแปลง file system ด้วยการสร้าง file test.txt ต่อมาก็ติดตามการเปลี่ยนแปลงโดยการใช้คำสั่ง docker diff

2 ทดสอบกับ image fedora

$ docker run -i -t fedora /bin/bash 
Unable to find image 'fedora:latest' locally
latest: Pulling from library/fedora
7c91a140e7a1: Pull complete 
Digest: sha256:a97914edb6ba15deb5c5acf87bd6bd5b6b0408c96f48a5cbd450b5b04509bb7d
Status: Downloaded newer image for fedora:latest
[root@854c83ca477e /]# 

สั่ง run fedora image และเชื่อมต่อ interactive session ด้วย option -i -t หากต้องการออกจาก session โดยที่ container ยังคงทำงานอยู่ (up status) ให้กด “Ctrl+p” ตามด้วย “Ctrl+q”

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
854c83ca477e        fedora              "/bin/bash"         3 minutes ago       Up 3 minutes                            elegant_nobel

$ docker attach  854c83ca477e
[root@854c83ca477e /]# 

$ Ctrl+p  Ctrl+9
$ docker kill 854c83ca477e
854c83ca477e

หลังจากยกเลิกการเชื่อมต่อ session แต่ container 854c83ca477e ยังคงทำงานอยู่ และสามารถเชื่อมต่อกลับไปด้วย docker attach หากต้องการ kill process ของ container สามารถทำได้โดย docker kill หากไม่มี error แต่ประการใด docker จะแจ้ง id กลับมา

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

$ docker ps -a -n 1
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                            PORTS               NAMES
854c83ca477e        fedora              "/bin/bash"         12 minutes ago      Exited (137) About a minute ago  

เมื่อตรวจสอบด้วย docker ps จะไม่ปรากฎ container แต่เมื่อ docker ps -a -n 1 อีกครั้ง container จะมีสถานะ เป็น exit

3 เพิ่ม docker image ให้แก่ระบบ
ต่อไปเราจะทำการ update image official ที่ docker ได้ pull ลงมาเพื่อสร้าง image ใหม่ เช่น ทำการเพิ่ม package http แก่ official fedora image

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
busybox             latest              2b8fd9751c4c        7 weeks ago         1.093 MB
fedora              latest              f9873d530588        7 weeks ago         204.4 MB

ใช้คำสั่ง docker images เพื่อ list ดู image ที่ได้ pull มาก่อนแล้ว

$ docker run fedora /bin/bash -c "dnf -y update; dnf -y install httpd" 
$ docker ps -a -n 1
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS               NAMES
1a151144b6fb        fedora              "/bin/bash -c 'dnf -y"   11 minutes ago      Exited (0) 4 minutes ago                       prickly_fermi

$ docker commit 1a151144b6fb images/fedora_httpd
sha256:1d4970b9b169715094fd8f1e60cfc407d1f5f69f4936258f771327aba8951b8d

$ docker images
REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
images/fedora_httpd   latest              1d4970b9b169        3 minutes ago       626.9 MB

คำสั่งด้านบนเป็นการ start container และ run command เพื่อupdate และ ติดตั้ง httpd package จะได้ container ใหม่ 1a151144b6fb ต่อมาเราจะทำการเปลี่ยน container ให้เป็น image โดยการใช้คำสั่ง docker commit เพื่อระบบว่าจะได้ save เป็น image

4 Start Container จาก image ที่สร้างใหม่

$ docker run images/fedora_httpd /usr/sbin/httpd -V

AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
Server version: Apache/2.4.23 (Fedora)
Server built:   Jul 18 2016 15:38:14
Server's Module Magic Number: 20120211:61
Server loaded:  APR 1.5.2, APR-UTIL 1.5.4
Compiled using: APR 1.5.2, APR-UTIL 1.5.4
Architecture:   64-bit
Server MPM:     prefork
  threaded:     no
    forked:     yes (variable process count)
Server compiled with....
 -D APR_HAS_SENDFILE
 -D APR_HAS_MMAP
 -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
 -D APR_USE_SYSVSEM_SERIALIZE
 -D APR_USE_PTHREAD_SERIALIZE
 -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
 -D APR_HAS_OTHER_CHILD
 -D AP_HAVE_RELIABLE_PIPED_LOGS
 -D DYNAMIC_MODULE_LIMIT=256
 -D HTTPD_ROOT="/etc/httpd"
 -D SUEXEC_BIN="/usr/sbin/suexec"
 -D DEFAULT_PIDLOG="/run/httpd/httpd.pid"
 -D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
 -D DEFAULT_ERRORLOG="logs/error_log"
 -D AP_TYPES_CONFIG_FILE="conf/mime.types"
 -D SERVER_CONFIG_FILE="conf/httpd.conf"

$ docker ps -a
CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS                        PORTS               NAMES
9be777c37fd2        images/fedora_httpd   "/usr/sbin/httpd -V"     22 seconds ago      Exited (0) 18 seconds ago                         ecstatic_mahavira

ทุกครั้งที่สั่ง docker run จะได้ container ใหม่ 9be777c37fd2

5 เริ่มต้นการใช้งาน webserver ที่อยู่ใน Container

โดย webserver จะทำงาน ที่ port 80 แต่ว่าอยู่ใน namespace ของ container ดังนั้นจะต้องมีการ เชื่อมต่อกับ host ด้วยการใช้ option ” -p  host_port:container_port”

$ docker run -it -p 8081:80 images/fedora_httpd /bin/bash
# run httpd ในโหมด backgroud
[root@233d6d53eff5 /]# /usr/sbin/httpd &

เปิด webbrowser ไปยัง http://localhost:8081/

fedora_container

6 สร้าง image แบบอัตโนมัติด้วย Dockerfile
ภายในไฟล์ Dockerfile จะประกอบด้วยคำสั่ง (Instruction) และ ค่าที่ต้องส่งไปยัง Instruction เรียกว่า argument

INSTRUCTION Description
FROM กำหนดว่าจะสร้าง image จาก base image ใด
MAINTAINER ชื่อ Author ผู้ที่สร้าง image
RUN ใช้สั่งคำสั่งที่กำหนดตามในขณะที่มีการสร้าง images
CMD คำสั่งนี้จะทำงานเมื่อ Container ถูก execute
ENTRYPOINT คำสั่งนี้จะทำงานเมื่อ Container ถูก execute
LABEL เพิ่ม metadata ให้แก่ images
EXPOSE บอกให้ Docker บน host รู้ว่า container ที่ run จะฟัง อยู่ที่ network port อะไร ใน ขณะ runtime เพื่อให้สามารถสื่อสารกับ container ได้
ENV กำหนดค่าของ environment variable
ADD ใช้สำหรับ copy files directory หรือ remotefile เพื่อมาใช้งาน
COPY ใช้สำหรับ copy files directory หรือ remotefile เช่นเดียวกับคำสั่ง ADD แต่ไม่สามารถแตกไฟล์ที่เป็น archive ได้
VOLUME ใช้สำหรับสร้าง mountpoint ไปยัง host หรือ container อื่น
USER กำหนด username หรือ UID
WORDDIR กำหนด working directory

เตรียมพร้อมการทดสอบ

docker stop $(docker ps -a -q)
docker rm $(docker ps -a -q)

คำสั่งข้างบนจะทำการลบ container ทั้งหมด

ตัวอย่าง Dockerfile
ตัวอย่าง 1 สร้าง fedora และ httpd

mkdir ~/DockerLab
cd ~/DockerLab
mkdir fedora_http
cd fedora_http
#สร้างfile Dockerfile
vi Dockerfile

FROM fedora
MAINTAINER youname <youname@domain.com>
RUN dnf -y install httpd
RUN echo "Hello DockerFile" > /var/www/html/index.html
EXPOSE 80
CMD ["-D", "FOREGROUND"]
ENTRYPOINT ["/usr/sbin/httpd"]

#สร้าง image จาก Dockerfile ด้วยคำสั่ง docker build
$ docker build -t images/fedora_httpd:v1.0 . 

Sending build context to Docker daemon 2.048 kB
Step 1 : FROM fedora
 ---> f9873d530588
Step 2 : MAINTAINER yourname <yourname@domain.com>
 ---> Running in e2686dec21d7
 ---> a9fc5077f8d1
Removing intermediate container e2686dec21d7
Step 3 : RUN dnf -y install httpd
 ---> Running in f9732ab53014
Last metadata expiration check: 0:00:11 ago on Sat Aug 13 15:50:45 2016.
Dependencies resolved.
================================================================================
 Package                  Arch         Version              Repository     Size
================================================================================
Installing:
 apr                      x86_64       1.5.2-3.fc24         fedora        112 k
 apr-util                 x86_64       1.5.4-3.fc24         fedora         94 k
 fedora-logos-httpd       noarch       22.0.0-3.fc24        fedora         34 k
 httpd                    x86_64       2.4.23-4.fc24        updates       1.3 M
 httpd-filesystem         noarch       2.4.23-4.fc24        updates        26 k
 httpd-tools              x86_64       2.4.23-4.fc24        updates        88 k
 mailcap                  noarch       2.1.46-1.fc24        fedora         37 k

Transaction Summary
================================================================================
Install  7 Packages

Total download size: 1.7 M
Installed size: 4.7 M
Downloading Packages:
...
Complete!
 ---> 290a25d54399
Removing intermediate container f9732ab53014
Step 4 : RUN echo "Hello DockerFile" > /var/www/html/index.html
 ---> Running in 0866a9638cc5
 ---> 62625250dbf5
Removing intermediate container 0866a9638cc5
Step 5 : EXPOSE 80
 ---> Running in 6cc9dd4ad3ea
 ---> 320d586843ef
Removing intermediate container 6cc9dd4ad3ea
Step 6 : CMD -D FOREGROUND
 ---> Running in 5da2c4987f62
 ---> f08579d95834
Removing intermediate container 5da2c4987f62
Step 7 : ENTRYPOINT /usr/sbin/httpd
 ---> Running in d11e0d5b271c
 ---> e066399a9b0f
Removing intermediate container d11e0d5b271c
Successfully built e066399a9b0f

$ docker images
REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
images/fedora_httpd   v1.0                e066399a9b0f        34 seconds ago      355.6 MB

เมื่อ build สำเร็จก็บอก image id (e066399a9b0f) และจะทำการ ลบ container ทิ้งไป เราก็จะมี image พร้อมใช้งาน ด้วยการสั่ง docker run ดังต่อไปนี้

options ความหมาย
docker build -t
$ docker run -d -p 80:80 images/fedora_httpd:v1.0
01f4cc847ad9407b9676f85a47264c44d8f395451858550579eee180a45d9371

$ docker ps
CONTAINER ID        IMAGE                      COMMAND                  CREATED             STATUS              PORTS                NAMES
01f4cc847ad9        images/fedora_httpd:v1.0   "/usr/sbin/httpd -D F"   16 seconds ago      Up 11 seconds       0.0.0.0:80->80/tcp   grave_swartz

#ทำสอบ
$ curl http://localhost/ 
Hello DockerFile

ตาราง options

Option ความหมาย
-d or –detach สั่ง run container ให้เป็น backgroud mode พร้อม แสดง ค่า container id ทั้งหมด (แต่ใช้ reference 12 หลัก)
-p or –publish สั่ง ให้มีการเชื่อมต่อ port ของ container ที่ publish ออกมาก เข้ากับ port ของ host -p host_port:container_port

ตัวอย่าง 2 สร้าง fedora และ nginx

cd ~/DockerLab
mkdir fedora_nginx
cd fedora_nginx/
# สร้าง Dockerfile
vi Dockerfile
FROM fedora
MAINTAINER youname <youname@domain.com>

RUN dnf -y update && dnf clean all
RUN dnf -y install nginx && dnf clean all
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
RUN echo "nginx on Fedora" > /usr/share/nginx/html/index.html

EXPOSE 80

CMD [ "/usr/sbin/nginx" ]

$ docker build -t images/fedora_nginx:v1.0 .

7 Fedora-Dockerfile
https://github.com/fedora-cloud/Fedora-Dockerfiles
Fedora 24 ได้เตรียม Dockerfile ให้เพื่อที่ใช้เป็นต้นแบบ ศึกษาเรียนรู้

git clone https://github.com/fedora-cloud/Fedora-Dockerfiles.git

8 สร้าง account บน hub.docker.com
1. ไปยัง https://hub.docker.com เพื่อสร้าง account
2. หลังจาก สร้าง docker id แล้วก็ให้ login ผ่านทาง cli

$ docker login
Username: <yourusername>
Password: <yourpassword>
Login Succeeded

3. เวลาตั้งชื่อ image จะต้องตั้ง เป็น -t “username/imagename:tag”

$ docker build -t itbakery/fedora_nginx:v1.0 .
$ docker images
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
itbakery/fedora_nginx   v1.0                9fd5bfc2dcdd        13 seconds ago      514.1 MB

การ tag image
tagger

$ docker tag  9fd5bfc2dcdd itbakery/fedora_nginx:latest
$ docker images
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
itbakery/fedora_nginx   latest              9fd5bfc2dcdd        3 minutes ago       514.1 MB
itbakery/fedora_nginx   v1.0                9fd5bfc2dcdd        3 minutes ago       514.1 MB

$ docker push itbakery/fedora_nginx:latest
The push refers to a repository [docker.io/itbakery/fedora_nginx]
b3b740c1dd04: Pushed 
dfdcde44621d: Pushed 
d8c75cbdacd2: Pushed 
410b4a224342: Pushed 
6c992a0e818a: Mounted from library/fedora 
latest: digest: sha256:65534e204f76ad363b8809d5c8fb7a9b39bf9b47d0c386709601f5394707f551 size: 1368

จะพบว่าทั้งสอง image จะมี image id เดียวกัน และ upload ไปยัง repository ด้วยคำสั่ง docker push

fedora_container2
4. ค้นหา image ที่ต้องการจาก repositoty

$ docker search centos
NAME                          DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
centos                        The official build of CentOS.                   2535      [OK] 
...
$ docker pull centos
Using default tag: latest
latest: Pulling from library/centos
3d8673bd162a: Pull complete 
Digest: sha256:a66ffcb73930584413de83311ca11a4cb4938c9b2521d331026dad970c19adf4
Status: Downloaded newer image for centos:latest

8 พื้นฐานการสร้าง wordpress + mariadb
อ้างอิงจาก
https://github.com/fedora-cloud/Fedora-Dockerfiles/tree/master/wordpress

# ให้ทำการ clone มาเก็บไว้ใน project directory DockerLab ที่สร้างไว้
cd ~/DockerLab
git clone https://github.com/fedora-cloud/Fedora-Dockerfiles.git
ls Fedora-Dockerfiles

# copy source 
cp -avR Fedora-Dockerfiles/mariadb  .
cp -avR Fedora-Dockerfiles/wordpress  .

ให้ build image ของ mariadb, wordpress

cd mariadb
#docker build --rm -t <yourname>/mariadb .
docker build --rm -t itbakery/mariadb .

cd wordpress
#docker build --rm -t <yourname>/wordpress .
docker build --rm -t itbakery/wordpress .


# ต่อมาให้ run mariadb container
$ docker run --name=mydb -e USER=wordpress -e PASS=$(pwgen -s -1) -e NAME=wordpress -d itbakery/mariadb

# run wordpress container ให้ alias 'db' เชื่อมกับ 'mydb' ของ mariadb
CID=$(docker run -p 80 --link=mydb:db -d itbakery/wordpress)

# กำหนด external port เป็น 80
docker port $CID 80 

9 พื้นฐานการใช้งาน volume เพื่อให้ Dataคงอยู่ไม่หายไปหลังจากลบ container
เพื่อต้องการแยก data volume ของ mariadb และ wordpress content ที่อยู่ที่ wordpress_content (media, themes, plugins) เป็นต้น

$ docker run -e USER=wordpress -e PASS=$(pwgen -s -1) -e NAME=wordpress \
    -v /mnt/db:/var/lib/mysql -d itbakery/mariadb

$ docker run --link=the-mariadb-container:db -p 80 \
    -v /mnt/wp-content:/var/www/html/wp-content -d itbakery/wordpress

Posted in linux.

Leave a Reply

Your email address will not be published. Required fields are marked *