Kubernetes創建數據中心級apt鏡像站點

對於企業級開發團隊,搭建軟件包的鏡像站點(以及Docker Images Registry鏡像站點)是減小網絡帶寬佔用、加速軟件開發過程的必備措施。html

一、基本用法

對與Ubuntu(以及其餘基於deb的系統)來講,通常有幾種方法:nginx

上面的這幾種方法都是使用apt-mirror來完成,須要配置鏡像參數,指定須要的版本。git

二、高級用法

若是須要完整的Ubuntu Archive鏡像,能夠編寫一個腳本(參考:建立Ubuntu安裝包服務鏡像的腳本),使用rsync所有鏡像Ubuntu archive倉庫,速度更快,但會佔用較大的磁盤空間(>1TB),初始同步須要較多的時間。而後,再建立一個Nginx實例提供服務。github

第一步,建立CronJob

爲了便於管理,我將同步腳本建立爲一個容器,而後掛載到Kubernetes中的定時任務中執行。ubuntu

A、同步腳本

  • 內容以下:
#/bin/dash

fatal() {
  echo "$1"
  exit 1
}

warn() {
  echo "$1"
}

# Find a source mirror near you which supports rsync on
# https://launchpad.net/ubuntu/+archivemirrors
# rsync://<iso-country-code>.rsync.archive.ubuntu.com/ubuntu should always work
#RSYNCSOURCE=rsync://archive.ubuntu.mirror.isp.com/ubuntu
# 實驗發現rsync不通了,用下面這個:
RSYNCSOURCE=archive.ubuntu.com::ubuntu

# Define where you want the mirror-data to be on your mirror
#BASEDIR=/var/www/ubuntuarchive/ 
# 改爲本身的目錄:
#BASEDIR=/media/smw/Appdata/ipfs-export/mirrors/ubuntu
BASEDIR=/home/mirror-ubuntu

echo "From:" $RSYNCSOURCE
echo "To:" $BASEDIR

if [ ! -d ${BASEDIR} ]; then
  warn "${BASEDIR} does not exist yet, trying to create it..."
  mkdir -p ${BASEDIR} || fatal "Creation of ${BASEDIR} failed."
fi

rsync --recursive --times --links --safe-links --hard-links \
  --stats \
  --exclude "Packages*" --exclude "Sources*" \
  --exclude "Release*" --exclude "InRelease" \
  ${RSYNCSOURCE} ${BASEDIR} || fatal "First stage of sync failed."

rsync --recursive --times --links --safe-links --hard-links \
  --stats --delete --delete-after \
  ${RSYNCSOURCE} ${BASEDIR} || fatal "Second stage of sync failed."

date -u > ${BASEDIR}/project/trace/$(hostname -f)

B、容器建立Dockerfile

  • 內容以下:
#This Docker Mirror Ubuntu Archive to a persistent volume of kubernetes.
#Created by openthings,2018-09-04. NO WARRANTS. 
#Please visit https://github.com/openthings/kubernetes-tools/mirror-ubuntu.
FROM ubuntu:16.04

RUN apt update && \
    apt upgrade -y
RUN apt install -y rsync 

COPY mirror-ubuntu.sh /home

C、定時任務CronJob

  • 內容以下:
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: mirror-ubuntu-cronjob
  namespace: ipfs2
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: OnFailure
          containers:
          - name: mirror-ubuntu
            image: openthings/mirror-ubuntu
            args:
            - /bin/sh
            - /home/mirror-ubuntu.sh
            imagePullPolicy: "IfNotPresent"
            volumeMounts:
              - name: mirror-volume
                mountPath: /home/mirror-ubuntu
                subPath: mirror-ubuntu
          volumes:
            - name: mirror-volume
              persistentVolumeClaim:
                claimName: ipfs-storage-ipfs2-ipfs-0

將上面的內容保存爲文件,而後運行Docker build進行容器構建和Kubectl apply安裝,便可看到Kubernetes集羣中job和pod被建立出來,而後Ubuntu Archive的數據開始同步。api

  • 注意,這裏的ipfs-storage-ipfs2-ipfs-0是我爲了下一步的工做,與IPFS服務共用的存儲卷,你能夠改爲使用本身的PVC存儲卷聲明。

第二步,建立Nginx服務

建立一個Nginx服務站點,將其主目錄指向上面同步的同一個存儲目錄,而後開啓目錄瀏覽功能。瀏覽器

Kubernetes中的配置文件,內容以下:網絡

apiVersion: v1
kind: ServiceAccount
metadata:
  name: apt-mirror
  namespace: ipfs2
---
kind: Service
apiVersion: v1
metadata:
  name: mirror-ubuntu-service
  namespace: ipfs2
  labels:
    app: mirror-ubuntu-service
spec:
  ports:
    - name: mirror-service
      port: 80
  type: LoadBalancer
  selector:
    app: mirror-ubuntu-service
---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: mirror-ubuntu-service
  namespace: ipfs2
spec:
  selector:
    matchLabels:
      app: mirror-ubuntu-service
  replicas: 1
  strategy:
    type: Recreate 
  template:
    metadata:
      labels:
        app: mirror-ubuntu-service
    spec:
      serviceAccount: apt-mirror
      containers:
        - name: mirror-ubuntu-service
          image: nginx
          ports:
            - name: mirror-service
              containerPort: 80
          securityContext:
            capabilities:
              add:
                - DAC_READ_SEARCH
                - SYS_RESOURCE
          env:
            - name: RESYNC_PERIOD
              value: 2h
          imagePullPolicy: "IfNotPresent"
          volumeMounts:
            - name: mirror-volume
              mountPath: /usr/share/nginx/html
              subPath: mirror-ubuntu
            - name: mirror-volume
              mountPath: /etc/nginx/conf.d/
              subPath: mirror-ubuntu/service-config
      volumes:
        - name: mirror-volume
          persistentVolumeClaim:
            claimName: ipfs-storage-ipfs2-ipfs-0

我在其中建立了一個帳戶、一個Service和一個Nginx的Deployment。安裝後,就能夠經過瀏覽器來訪問鏡像站點了。app

  • 其中,映射了兩個卷,一個爲數據卷、一個爲Nginx的配置文件,都對應到主存儲PVC的子目錄中。
  • Nginx爲官網的鏡像(沒有任何定製修改),啓動時從配置子目錄讀取參數,啓用目錄瀏覽功能。
  • 服務使用了LoadBalancer,本地集羣能夠安裝MetalLB來實現,雲上使用廠商提供的負載均衡器。

第一次同步的時間比較長(下載將近1TB,通常要7天左右)。之後只是更新,就快多了。負載均衡

由於使用了Kubernertes,須要的話能夠對Nginx服務站點進行伸縮,遇到故障時系統能夠自動重啓或節點漂移,能夠知足大規模數據中心級的軟件安裝和更新的須要。爲了更高的可靠性,Kubernetes集羣自己應該配置Master高可用機制,存儲系統應該有備份和多拷貝。

三、極速方法

正如上面所述,這種鏡像機制能夠對內部網的軟件安裝和更新過程大幅度加速,可是目前傳輸速度仍是不夠快,並且依賴於上級的鏡像站點的可靠性。若是與BT和IPFS之類的p2p傳輸機制結合,將會進一步帶來速度和可靠性的大幅度提高。

目前的狀態,還存在一些障礙有待攻克,可是隨着IPFS等的改進和FileCoin的推出和完善,這一方案最終是徹底可行的,留待後述。

相關文章
相關標籤/搜索