對於企業級開發團隊,搭建軟件包的鏡像站點(以及Docker Images Registry鏡像站點)是減小網絡帶寬佔用、加速軟件開發過程的必備措施。html
對與Ubuntu(以及其餘基於deb的系統)來講,通常有幾種方法:nginx
上面的這幾種方法都是使用apt-mirror來完成,須要配置鏡像參數,指定須要的版本。git
若是須要完整的Ubuntu Archive鏡像,能夠編寫一個腳本(參考:建立Ubuntu安裝包服務鏡像的腳本),使用rsync所有鏡像Ubuntu archive倉庫,速度更快,但會佔用較大的磁盤空間(>1TB),初始同步須要較多的時間。而後,再建立一個Nginx實例提供服務。github
爲了便於管理,我將同步腳本建立爲一個容器,而後掛載到Kubernetes中的定時任務中執行。ubuntu
#/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)
#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
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
建立一個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
第一次同步的時間比較長(下載將近1TB,通常要7天左右)。之後只是更新,就快多了。負載均衡
由於使用了Kubernertes,須要的話能夠對Nginx服務站點進行伸縮,遇到故障時系統能夠自動重啓或節點漂移,能夠知足大規模數據中心級的軟件安裝和更新的須要。爲了更高的可靠性,Kubernetes集羣自己應該配置Master高可用機制,存儲系統應該有備份和多拷貝。
正如上面所述,這種鏡像機制能夠對內部網的軟件安裝和更新過程大幅度加速,可是目前傳輸速度仍是不夠快,並且依賴於上級的鏡像站點的可靠性。若是與BT和IPFS之類的p2p傳輸機制結合,將會進一步帶來速度和可靠性的大幅度提高。
目前的狀態,還存在一些障礙有待攻克,可是隨着IPFS等的改進和FileCoin的推出和完善,這一方案最終是徹底可行的,留待後述。