Viblo Code
+4

Triển khai private Docker Registry

Giới thiệu

Docker registry là nơi chứa các image trong quá trình khởi động các container. Hầu hết mọi người đang sử dụng các image có sẵn và nếu chưa biết thì nó được host tại Docker hub chính thức. Tuy nhiên, có một số hạn chế khi sử dụng docker hub như sau:

– Server đặt ở nước ngoài (khác VN)

– Tính phí cho các private image. Bạn không thể nào public các image nội bộ nên bạn chỉ có lựa chọn private image. Nếu bạn có một vài project thì chi phí không cao. Nhưng nếu bạn phát triển theo hướng microservice thì sẽ có vài chục đến vài trăm private image, nếu thuê theo gói thì hoàn toàn không kinh tế lắm.

Với 2 hạn chế trên thì hầu hết các công ty tự triển khai các registry cho riêng mình vì registry cũng là open source. Bạn thuê / mua một con server, vps và start cái image registry 2.0 là xong, và có rất nhiều hướng dẫn trên mạng chỉ bạn cách dựng một private registry như vậy. Tuy nhiên, registry bạn dựng lên hầu như không thực tế và chỉ để test mà thôi. Nội dung bài viết này mình hướng đến một cài đặt registry production tức là chạy thực sự chứ không phải để test đòi hỏi một số yêu cầu như tên miền riêng, ngắn, hỗ trợ https, có backup và có hỗ trợ ACL (Access Control List).

Giới thiệu 1 số dịch vụ Docker Registry

Chúng ta sẽ đánh giá một số các nhà cung cấpdịch vụ registry. Ở đây mình sẽ nói về tính năng chính và tổng quát về các dịch vụ trên các tiêu chí sau đây.

  • Workflow (xây dựng / triển khai, hợp tác, dễ sử dụng và khả năng hiển thị)
  • Xác thực và ủy quyền
  • Tính sẵn sàng và hiệu năng
  • Chi phí

Docker Hub

Quy trình làm việc:

  • Tích hợp với Github và BitBucket

  • Mô hình quen thuộc giống Github

  • Liên kết repository, cho xây dựng tự động

  • Tài liệu đầy đủ, dễ sử dụng

Xác thực và ủy quyền:

  • Có thể tạo organizations
  • Thiếu kiểm soát access control cho từng user

  • Thiếu hỗ trợ cho các nhà cung cấp chứng thực bên ngoài, ví dụ LDAP, SAML và OAuth

Tính sẵn sàng và hiệu năng:

  • Hiệu suất ổn định

giá cả:

  • Giá rẻ và sử dụng độc lập

Quay.io

Quy trình làm việc:

  • Giao diện dễ sự dụng, trực quan và sắp xếp hợp lý

  • Automatic build

  • Có thông báo về các sự kiện

Xác thực và ủy quyền:

  • Khả năng tạo ra các organizations and teams

  • Kiểm soát truy cập thông qua

  • Chỉ hỗ trợ xác thực qua OAuth

Tính sẵn sàng và hiệu năng:

  • Không hỗ trợ

giá cả:

  • Tương đối rẻ tiền và sử dụng độc lập

Artifactory

Quy trình làm việc:

  • All in one
  • Dễ dàng cho người mới sử dụng

Xác thực và ủy quyền:

  • Khả năng xác thực toàn diện

Sự sẵn có và hiệu suất:

  • Remote repository cho HA

giá cả:

  • Chi phí cao

Google Container Registry

Quy trình làm việc:

  • Không tương thích với Docker client

  • Ít hỗ trợ cho việc tích hợp với build and deployment

Xác thực và ủy quyền:

  • Kiểm soát truy cập với GCS ACL

  • Tăng cường bảo mật thông qua auth token ngắn hạn

  • Hỗ trợ đồng bộ hóa LDAP

Hiệu suất và tính sẵn sàng:

  • Sử dụng HA có sẵn của Google cloud storage

giá cả:

  • Chi phí thấp

Triển khai Docker Registry

1. Tên miền và SSL Certificate cho Docker Registry

Tên miền

Bạn cần chọn một tên miền cho registry của mình. Bạn có thể mua tên miền và tạo A record trở đến IP của VPS/Server của bạn.Ví dụ mình chọn tên miền infra.framgia.vn là registry của mình.

SSL Certificate

Vì private registry mặc định hỗ trợ https nên bạn cần phải có SSL Certificate cho domain của mình. Các bạn có thể mua SSL của một nhà cung cấp dịch vụ SSL như GeoTrust, RapidSSL, Verisign... Ở đây mình sử dụng 1 dịch vụ SSL miễn phí là letsencypt. Cách tạo cert rất đơn giản chỉ cần download script về chạy là xong.

wget https://dl.eff.org/certbot-auto

chmod a+x certbot-auto

/path/to/certbot-auto certonly --standalone -d example.com

Ssl sau khi tạo xong sẽ được lưu ở đường dẫn sau

/etc/letsencrypt/archive/[domain_name]/

Đây là cert mình gen ra :

Screenshot at Oct 24 13-55-22.png

Như hình trên bạn sẽ dùng file fullchain1.pem và privkey1.pem bundle là có thể cấu hình được https.

Để thuận tiện cho các bước chạy các container, đổi tên file bundle crt thành file “cert.pem” và file .key thành “key.pem”. Tiến hành đến bước khởi tạo private registry.

2. Cài đặt

Để thiết lập bảo mật cho Docker Registry đó là tốt nhất để sử dụng Docker Compose. Bằng cách này chúng ta có thể dễ dàng chạy Docker Registry trên một container và để cho Nginx xử lý và giao tiếp với phía ngoài . Cài đặt docker-compose :

curl -L "https://github.com/docker/compose/releases/download/1.8.1/docker-compose-$(uname -s)-$(uname -m)" > /usr/local/bin/docker-compose

chmod +x /usr/local/bin/docker-compose

Vì chúng ta sẽ sử dụng Nginx để xác thực, để lưu trữ danh sách của tên người dùng và mật khẩu muốn truy cập registry. Ta sẽ cài đặt gói apache2-utils trong đó có các tiện ích htpasswd có thể dễ dàng tạo ra basic authenticate:

sudo apt-get -y install apache2-utils

Đầu tiên tạo ra một thư mục nơi chứa các tập tin :

mkdir ~/docker-registry

mkdir data

mkdir nginx

Tạo file docker-compose.yml như sau :

nginx:

  image: "nginx:1.9"
  ports:
    - 443:443
  links:
    - registry:registry
  volumes:
    - ./nginx/:/etc/nginx/conf.d:ro
registry:
  image: registry:2
  ports:
    - 127.0.0.1:5000:5000
  environment:
    REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
  volumes:
    - ./data:/data

Nginx container

image : image nginx 1.9

ports : port Nginx container 443 sẽ map tới port 443 của máy host.

links : Khi Nginx container chạy, nó sẽ liên kết tới registry container với hostname là registry và không cần quan tâm IP của registry container là gì. Thực ra Docker đã insert vào /etc/hosts trong nginx container hostname của registry container.

volumes: lưu trữ config files của nginx trên máy host, folder /etc/nginx/conf.d/ trên container sẽ được mount vào thư mục ~/docker-registry/nginx trên máy host.

Tạo file registry.conf với nội dung như sau:

nano ~/docker-registry/nginx/registry.conf
upstream docker-registry {
  server registry:5000;
}

server {
  listen 443;
  server_name infra.framgia.vn;
  # SSL
   ssl on;
   ssl_certificate /etc/nginx/conf.d/cert.pem;
   ssl_certificate_key /etc/nginx/conf.d/key.pem;

  # disable any limits to avoid HTTP 413 for large image uploads
  client_max_body_size 0;

  # required to avoid HTTP 411: see Issue #1486 (https://github.com/docker/docker/issues/1486)
  chunked_transfer_encoding on;

  location /v2/ {
    # Do not allow connections from docker 1.5 and earlier
    # docker pre-1.6.0 did not properly set the user agent on ping, catch "Go *" user agents
    if ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*$" ) {
      return 404;
    }

    # To add basic authentication to v2 use auth_basic setting plus add_header
     auth_basic "registry.localhost";
     auth_basic_user_file /etc/nginx/conf.d/registry.password;
     add_header 'Docker-Distribution-Api-Version' 'registry/2.0' always;

    proxy_pass                          http://docker-registry;
    proxy_set_header  Host              $http_host;   # required for docker client's sake
    proxy_set_header  X-Real-IP         $remote_addr; # pass on real client's IP
    proxy_set_header  X-Forwarded-For   $proxy_add_x_forwarded_for;
    proxy_set_header  X-Forwarded-Proto $scheme;
    proxy_read_timeout                  900;
  }
}

Tạo file registry.password chứa thông tin đăng nhập vào registry

htpasswd -c registry.password USERNAME

Cuối cùng là Copy SSL certifcate, bạn sẽ có cây thư mục như sau:

Screenshot at Oct 24 17-29-25.png

Registry container

image : registry version 2

port : port Registry container 5000 sẽ map tới port 5000 của máy host và chỉ listen trên localhost (127.0.0.1)

environment: env trên Docker registry container được set về /data. Docker registry sẽ kiểm tra các biến môi trường khi khởi động và lưu trữ dữ liệu tại đây.

3. Sử dụng private registry từ client

Thêm certificate vào client. Bạn sẽ copy nội dung nội dung file cert.pem sau đó add vào client tuỳ theo OS.

Mac OS X

Add
Use command:

sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ~/new-root-certificate.crt

Windows

Add
Use command:

certutil -addstore -f "ROOT" new-root-certificate.crt

Linux (Ubuntu, Debian)

Add
Copy your CA to dir /usr/local/share/ca-certificates/

Use command:

sudo cp foo.crt /usr/local/share/ca-certificates/foo.crt

Update the CA store:

sudo update-ca-certificates

Linux (CentOs 6)

Add
Install the ca-certificates package:

yum install ca-certificates

Enable the dynamic CA configuration feature:

update-ca-trust force-enable

Add it as a new file to /etc/pki/ca-trust/source/anchors/:

cp foo.crt /etc/pki/ca-trust/source/anchors/

Use command:

update-ca-trust extract

Restart Kerio Connect to reload the certificates in the 32-bit version.

Linux (CentOs 5)

Add
Append your trusted certificate to file /etc/pki/tls/certs/ca-bundle.crt

cat foo.crt >> /etc/pki/tls/certs/ca-bundle.crt

Kiểm tra bằng cách push và pull image

Publish image tới docker registry Screenshot at Oct 24 08-20-03.png

Screenshot at Oct 24 08-19-20.png

Screenshot at Oct 24 08-18-15.png

Screenshot at Oct 24 17-47-51.png

Pull image từ docker registry

Screenshot at Oct 24 17-51-35.png

Chúc các bạn thành công 😃


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.