日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線(xiàn)溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
基于Kubernetes的Jenkins服務(wù)也可以去Docker了

基于 Kubernetes 的 Jenkins 服務(wù)也可以去 docker 了

作者:陳少文 2021-02-26 08:37:47
云計(jì)算 在 1.20 版本之后, Kubernetes 社區(qū)放棄了對(duì) Docker 的支持, 而后又有其他社區(qū)接手, 隱約給 Docker 蒙上了一層陰影。在這樣的背景下, 我們開(kāi)始考慮非 Docker 環(huán)境下, 如何進(jìn)行 CICD 實(shí)踐。

網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)!專(zhuān)注于網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開(kāi)發(fā)、成都小程序開(kāi)發(fā)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶(hù)創(chuàng)新互聯(lián)還提供了巴彥淖爾免費(fèi)建站歡迎大家使用!

本文轉(zhuǎn)載自微信公眾號(hào)「問(wèn)其」,作者陳少文 。轉(zhuǎn)載本文請(qǐng)聯(lián)系問(wèn)其公眾號(hào)。

1. 去 Docker 給 CICD 帶來(lái)新的挑戰(zhàn)

在 CICD 場(chǎng)景下, 我們經(jīng)常需要在流水線(xiàn)中構(gòu)建和推送鏡像。

在之前的文檔 《在 Kubernetes 上動(dòng)態(tài)創(chuàng)建 Jenkins Slave》[1] 中, 我描述了通過(guò)掛載 /var/run/docker.sock 文件, 允許在 Docker 驅(qū)動(dòng)的 Kubernetes 集群中構(gòu)建和推送鏡像。在文檔 《如何在 Docker 中使用 Docker》[2]中, 我又進(jìn)行了更加詳細(xì)地闡述, 其原理是共享主機(jī) Docker Daemon。

在 1.20 版本之后, Kubernetes 社區(qū)放棄了對(duì) Docker 的支持, 而后又有其他社區(qū)接手, 隱約給 Docker 蒙上了一層陰影。在這樣的背景下, 我們開(kāi)始考慮非 Docker 環(huán)境下, 如何進(jìn)行 CICD 實(shí)踐。

非 Docker 環(huán)境意味著之前掛載 /var/run/docker.sock 的方式失效了, 我們需要尋找新的解決方案。

2. 測(cè)試集群環(huán)境

2.1 Kubernetes - 1.17.9

執(zhí)行如下命令, 查看 Kubernetes 版本:

  
 
 
  1. kubectl version 
  2.  
  3. Client Version: version.Info{Major:"1", Minor:"17", GitVersion:"v1.17.9", GitCommit:"4fb7ed12476d57b8437ada90b4f93b17ffaeed99", GitTreeState:"clean", BuildDate:"2020-07-15T16:18:16Z", GoVersion:"go1.13.9", Compiler:"gc", Platform:"linux/amd64"} 
  4. Server Version: version.Info{Major:"1", Minor:"17", GitVersion:"v1.17.9", GitCommit:"4fb7ed12476d57b8437ada90b4f93b17ffaeed99", GitTreeState:"clean", BuildDate:"2020-07-15T16:10:45Z", GoVersion:"go1.13.9", Compiler:"gc", Platform:"linux/amd64"} 

2.2 Containerd - 1.4.3

執(zhí)行如下命令, 查看 containerd 版本:

  
 
 
  1. containerd --version 
  2.  
  3. containerd github.com/containerd/containerd v1.4.3 269548fa27e0089a8b8278fc4fc781d7f65a939b 

3. 鏡像管理工具 Podman

由于 Containerd 不支持 Docker API, 常見(jiàn)的 docker build、docker push 等命令在 Containerd 環(huán)境下無(wú)法使用。因此, 需要一種不依賴(lài)于 Docker, 針對(duì) OCI 標(biāo)準(zhǔn)的鏡像構(gòu)建和推送工具。

3.1 Podman 簡(jiǎn)介

Podman 是一個(gè)實(shí)現(xiàn) OCI 標(biāo)準(zhǔn)的容器和鏡像管理工具, 同時(shí)也是 Daemonless, 不需要守護(hù)進(jìn)程, 也支持非特權(quán)用戶(hù)使用。Podman 提供了類(lèi)似 Docker CLI 的功能, 大部分情況下可以執(zhí)行 alias docker=podman 使用 Podman 替換 Docker , 而不會(huì)有任何問(wèn)題。

3.2 Podman 安裝

  • 安裝 Podman 命令行工具

安裝方法可以參考 Podman 的安裝指引[3]。這里以 CentOS 7 為例:

  
 
 
  1. curl -L -o /etc/yum.repos.d/devel:kubic:libcontainers:stable.repo https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/CentOS_7/devel:kubic:libcontainers:stable.repo 
  2. yum -y install podman 
  • 查看 Podman 版本
  
 
 
  1. podman --version 
  2.  
  3. podman version 3.0.1 
  • 查看命令參數(shù)

這里為了方便查閱, 貼出完整的幫助文檔。

  
 
 
  1. podman --help 
  2. manage pods and images 
  3.  
  4. Usage: 
  5.   podman [flags] 
  6.   podman [command] 
  7.  
  8. Available Commands: 
  9.   attach      Attach to a running container 
  10.   build       Build an image using instructions from Containerfiles 
  11.   commit      Create new image based on the changed container 
  12.   container   Manage Containers 
  13.   cp          Copy files/folders between a container and the local filesystem 
  14.   create      Create but do not start a container 
  15.   diff        Inspect changes on container's file systems 
  16.   events      Show podman events 
  17.   exec        Run a process in a running container 
  18.   export      Export container's filesystem contents as a tar archive 
  19.   generate    Generated structured data 
  20.   healthcheck Manage Healthcheck 
  21.   help        Help about any command 
  22.   history     Show history of a specified image 
  23.   image       Manage images 
  24.   images      List images in local storage 
  25.   import      Import a tarball to create a filesystem image 
  26.   info        Display podman system information 
  27.   init        Initialize one or more containers 
  28.   inspect     Display the configuration of a container or image 
  29.   kill        Kill one or more running containers with a specific signal 
  30.   load        Load an image from container archive 
  31.   login       Login to a container registry 
  32.   logout      Logout of a container registry 
  33.   logs        Fetch the logs of a container 
  34.   mount       Mount a working container's root filesystem 
  35.   network     Manage Networks 
  36.   pause       Pause all the processes in one or more containers 
  37.   play        Play a pod 
  38.   pod         Manage pods 
  39.   port        List port mappings or a specific mapping for the container 
  40.   ps          List containers 
  41.   pull        Pull an image from a registry 
  42.   push        Push an image to a specified destination 
  43.   restart     Restart one or more containers 
  44.   rm          Remove one or more containers 
  45.   rmi         Removes one or more images from local storage 
  46.   run         Run a command in a new container 
  47.   save        Save image to an archive 
  48.   search      Search registry for image 
  49.   start       Start one or more containers 
  50.   stats       Display a live stream of container resource usage statistics 
  51.   stop        Stop one or more containers 
  52.   system      Manage podman 
  53.   tag         Add an additional name to a local image 
  54.   top         Display the running processes of a container 
  55.   umount      Unmounts working container's root filesystem 
  56.   unpause     Unpause the processes in one or more containers 
  57.   unshare     Run a command in a modified user namespace 
  58.   varlink     Run varlink interface 
  59.   version     Display the Podman Version Information 
  60.   volume      Manage volumes 
  61.   wait        Block on one or more containers 
  62.  
  63. Flags: 
  64.       --cgroup-manager string     Cgroup manager to use (cgroupfs or systemd) (default "systemd") 
  65.       --cni-config-dir string     Path of the configuration directory for CNI networks 
  66.       --config string             Path of a libpod config file detailing container server configuration options 
  67.       --conmon string             Path of the conmon binary 
  68.       --cpu-profile string        Path for the cpu profiling results 
  69.       --events-backend string     Events backend to use 
  70.       --help                      Help for podman 
  71.       --hooks-dir strings         Set the OCI hooks directory path (may be set multiple times) 
  72.       --log-level string          Log messages above specified level: debug, info, warn, error, fatal or panic (default "error") 
  73.       --namespace string          Set the libpod namespace, used to create separate views of the containers and pods on the system 
  74.       --network-cmd-path string   Path to the command for configuring the network 
  75.       --root string               Path to the root directory in which data, including images, is stored 
  76.       --runroot string            Path to the 'run directory' where all state information is stored 
  77.       --runtime string            Path to the OCI-compatible binary used to run containers, default is /usr/bin/runc 
  78.       --storage-driver string     Select which storage driver is used to manage storage of images and containers (default is overlay) 
  79.       --storage-opt stringArray   Used to pass an option to the storage driver 
  80.       --syslog                    Output logging information to syslog as well as the console 
  81.       --tmpdir string             Path to the tmp directory 
  82.       --trace                     Enable opentracing output 
  83.   -v, --version                   Version of podman 
  84.  
  85. Use "podman [command] --help" for more information about a command. 

Podman 在覆蓋 Docker 命令的同時(shí),增加了對(duì) Pod 操作的支持。

3.3 主機(jī)上測(cè)試編譯并推送鏡像

在使用上可以直接將 docker 命令替換為 podman 即可。

  • 編譯鏡像
  
 
 
  1. echo -e 'FROM busybox\nRUN echo "hello world"' | podman build -t docker.io/shaowenchen/myimage:latest - 
  2.  
  3. STEP 1: FROM busybox 
  4. Getting image source signatures 
  5. Copying blob 5c4213be9af9 done 
  6. Copying config 491198851f done 
  7. Writing manifest to image destination 
  8. Storing signatures 
  9. STEP 2: RUN echo "hello world" 
  10. hello world 
  11. STEP 3: COMMIT 
  12. 4c8794086d9de80f71d182457b6d2cb18b9d61975b98bcd4cb167bdcabae5b2c 
  13. 4c8794086d9de80f71d182457b6d2cb18b9d61975b98bcd4cb167bdcabae5b2c 
  • 查看編譯的鏡像
  
 
 
  1. podman images |grep shaowenchen 
  2. docker.io/shaowenchen/myimage   latest   4c8794086d9d   4 minutes ago   1.46 MB 
  • 登錄 DockerHub
  
 
 
  1. podman login docker.io -u shaowenchen 
  2.  
  3. Password: 
  4. Login Succeeded! 
  • 推送鏡像
  
 
 
  1. podman push docker.io/shaowenchen/myimage:latest 
  2.  
  3. Getting image source signatures 
  4.  
  5. Copying blob 2893437c336c done 
  6. Copying blob 84009204da3f done 
  7. Copying config 4c8794086d done 
  8. Writing manifest to image destination 
  9. Storing signatures 

4. Jenkns 中使用 Podman 構(gòu)建鏡像

4.1 關(guān)鍵配置

  • 使用 hostPath 將 /var/lib/containers 掛載到主機(jī)上

也可以使用 PVC,但是 PVC 可能需要加參數(shù),見(jiàn)下文。

否則會(huì)有如下報(bào)錯(cuò):

  
 
 
  1. Error: 'overlay' is not supported over overlayfs, a mount_program is required: backing file system is unsupported for this graph driver 
  • privileged 特權(quán)模式

否則會(huì)有如下報(bào)錯(cuò):

  
 
 
  1. Error: kernel does not support overlay fs: 'overlay' is not supported over extfs at "/var/lib/containers/storage/overlay": backing file system is unsupported for this graph driver 
  • Podman 參數(shù) --cgroup-manager=cgroupfs

在使用 PVC 作為存儲(chǔ)目錄時(shí), 需要考慮這項(xiàng)配置。內(nèi)核通過(guò) Cgroup Driver 隔離一組資源, 可選的參數(shù)有 cgroupfs 和 systemd, 需要與集群環(huán)境保持一致, 因?yàn)樗麄児灿靡粋€(gè)內(nèi)核。我的測(cè)試環(huán)境使用的是 cgroupfs 。

否則會(huì)有如下報(bào)錯(cuò):

  
 
 
  1. unable to write system event: "write unixgram @0011c->/run/systemd/journal/socket: sendmsg: no such file or directory 
  • Podman 參數(shù) --events-backend=file

這項(xiàng)配置通常不會(huì) Block 執(zhí)行流程,如果你想保持日志更加干凈,可以添加。

否則會(huì)有如下報(bào)錯(cuò):

  
 
 
  1. unable to write system event: "write unixgram @0011c->/run/systemd/journal/socket: sendmsg: no such file or directory 

4.2 示例一: 在 Jenkinsfile 中顯式使用 yaml 模板

這里將容器 /var/lib/containers 掛載到主機(jī) /var/lib/containers 目錄,也可以?huà)燧d到主機(jī) /tmp 目錄,并沒(méi)有強(qiáng)制要求。主機(jī)目錄只是提供一個(gè)存放數(shù)據(jù)的地方。

  
 
 
  1. pipeline { 
  2.   agent { 
  3.     kubernetes { 
  4.       yaml """ 
  5. apiVersion: v1 
  6. kind: Pod 
  7. spec: 
  8.   containers: 
  9.   - name: centos 
  10.     image: centos:7 
  11.     command: 
  12.     - cat 
  13.     tty: true 
  14.     securityContext: 
  15.         privileged: true 
  16.     volumeMounts: 
  17.     - name: storage 
  18.       mountPath: /var/lib/containers 
  19.   volumes: 
  20.   - name: storage 
  21.     hostPath: 
  22.       path: /var/lib/containers 
  23. """ 
  24.    }} 
  25.    stages { 
  26.       stage('Hello') { 
  27.          steps { 
  28.             container('centos') { 
  29.               sh ''' 
  30.               curl -L -o /etc/yum.repos.d/devel:kubic:libcontainers:stable.repo https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/CentOS_7/devel:kubic:libcontainers:stable.repo 
  31.               yum -y install podman 
  32.               echo -e 'FROM busybox\nRUN echo "hello world"' | podman --events-backend=file build -t docker.io/shaowenchen1/myimage:latest - 
  33.               podman --events-backend=file images |grep shaowenchen1 
  34.               ''' 
  35.             } 
  36.          } 
  37.       } 
  38.    } 

Jenkins 的執(zhí)行日志:

  
 
 
  1. ··· 
  2. Dependency Updated: 
  3.   systemd.x86_64 0:219-78.el7_9.3      systemd-libs.x86_64 0:219-78.el7_9.3      
  4.  
  5. Complete! 
  6. + podman --events-backend=file build -t docker.io/shaowenchen1/myimage:latest - 
  7. + echo -e 'FROM busybox 
  8. RUN echo "hello world"' 
  9. STEP 1: FROM busybox 
  10. STEP 2: RUN echo "hello world" 
  11. --> Using cache 4c8794086d9de80f71d182457b6d2cb18b9d61975b98bcd4cb167bdcabae5b2c 
  12. STEP 3: COMMIT docker.io/shaowenchen1/myimage:latest 
  13. --> 4c8794086d9 
  14. 4c8794086d9de80f71d182457b6d2cb18b9d61975b98bcd4cb167bdcabae5b2c 
  15. + podman --events-backend=file images 
  16. + grep shaowenchen1 
  17. docker.io/shaowenchen1/myimage  latest  4c8794086d9d  19 hours ago  1.46 MB 

4.3 示例二: 使用 PVC 掛載 /var/lib/containers 目錄

在使用 PVC 存儲(chǔ) Podman 數(shù)據(jù)時(shí),需要提前準(zhǔn)備好集群的存儲(chǔ)。

  • 查看集群是否有默認(rèn)的 StorageClass
  
 
 
  1. kubectl get sc 
  2.  
  3. NAME                         PROVISIONER                                                RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE 
  4. openebs-device               openebs.io/local                                           Delete          WaitForFirstConsumer   false                  19d 
  5. openebs-hostpath (default)   openebs.io/local                                           Delete          WaitForFirstConsumer   false                  19d 
  6. openebs-jiva-default         openebs.io/provisioner-iscsi                               Delete          Immediate              false                  19d 
  7. openebs-snapshot-promoter    volumesnapshot.external-storage.k8s.io/snapshot-promoter   Delete          Immediate              false                  19d 
  • 為 Podman 創(chuàng)建一個(gè) PVC

這里的 namespace 需要與 Jenkins 中動(dòng)態(tài) Agent 所在的 namespace 保持一致。

  
 
 
  1. cat <
  2. apiVersion: v1 
  3. kind: PersistentVolumeClaim 
  4. metadata: 
  5.   name: storage 
  6.   namespace: default 
  7. spec: 
  8.   accessModes: 
  9.     - ReadWriteOnce 
  10.   resources: 
  11.     requests: 
  12.       storage: 30Gi 
  13. EOF 
  • 查看創(chuàng)建的 PVC
  
 
 
  1. kubectl -n default get pvc 
  2.  
  3. NAME         STATUS    VOLUME                                     CAPACITY   ACCESS MODES    
  4. storage      Pending                                                                        openebs-hostpath   11s 

由于使用的是 WaitForFirstConsumer 模式,需要等到有 Pod 使用 PVC 時(shí),才會(huì)綁定 PV。

  • 創(chuàng)建 Jenkins 流水線(xiàn)執(zhí)行
  
 
 
  1. pipeline { 
  2.   agent { 
  3.     kubernetes { 
  4.       yaml """ 
  5. apiVersion: v1 
  6. kind: Pod 
  7. spec: 
  8.   containers: 
  9.   - name: centos 
  10.     image: centos:7 
  11.     command: 
  12.     - cat 
  13.     tty: true 
  14.     securityContext: 
  15.         privileged: true 
  16.     volumeMounts: 
  17.     - name: storage 
  18.       mountPath: /var/lib/containers 
  19.   volumes: 
  20.   - name: storage 
  21.     persistentVolumeClaim: 
  22.       claimName: storage 
  23. """ 
  24.    }} 
  25.    stages { 
  26.       stage('Hello') { 
  27.          steps { 
  28.             container('centos') { 
  29.               sh ''' 
  30.               curl -L -o /etc/yum.repos.d/devel:kubic:libcontainers:stable.repo https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/CentOS_7/devel:kubic:libcontainers:stable.repo 
  31.               yum -y install podman 
  32.               echo -e 'FROM busybox\nRUN echo "hello world"' | podman --events-backend=file build -t docker.io/shaowenchen2/myimage:latest - 
  33.               podman --events-backend=file images |grep shaowenchen2 
  34.               ''' 
  35.             } 
  36.          } 
  37.       } 
  38.    } 

Jenkins 的執(zhí)行日志:

  
 
 
  1. ··· 
  2. Dependency Updated: 
  3.   systemd.x86_64 0:219-78.el7_9.3      systemd-libs.x86_64 0:219-78.el7_9.3      
  4.  
  5. Complete! 
  6. + echo -e 'FROM busybox 
  7. RUN echo "hello world"' 
  8. + podman --events-backend=file build -t docker.io/shaowenchen2/myimage:latest - 
  9. STEP 1: FROM busybox 
  10. STEP 2: RUN echo "hello world" 
  11. --> Using cache f4676f5b5e47a78970f2d97f4a5b77423f381e9742faae06d8c1a2d93bdb27c2 
  12. STEP 3: COMMIT docker.io/shaowenchen2/myimage:latest 
  13. --> f4676f5b5e4 
  14. f4676f5b5e47a78970f2d97f4a5b77423f381e9742faae06d8c1a2d93bdb27c2 
  15. + podman --events-backend=file images 
  16. + grep shaowenchen2 
  17. docker.io/shaowenchen2/myimage  latest  f4676f5b5e47  2 hours ago  1.46 MB 

5. 總結(jié)

本文主要提供了一種在非 Docker 驅(qū)動(dòng)的 Kubernetes 集群中,進(jìn)行 CICD 鏡像構(gòu)建的思路,使用 Podman 替換 Docker 。選擇 Podman 的原因是, 其使用方式更貼近 Docker,而 Buildah 需要用戶(hù)修改鏡像編譯指令,因?yàn)?Buildah 使用的是 buildah bud。

在生產(chǎn)實(shí)踐過(guò)程中,我們需要將 Podman 命令打包到 CI Agent 的基礎(chǔ)鏡像中。通過(guò) alias docker=podman , 對(duì)基于 Docker 命令的流水線(xiàn)進(jìn)行替換。

下面簡(jiǎn)單總結(jié)一下,使用 Podman 的要點(diǎn):

  • 支持緩存。通過(guò)掛載 /var/lib/containers 目錄,可以緩存鏡像,并且可以根據(jù)業(yè)務(wù)劃分到不同目錄。
  • 與 Docker 無(wú)縫替換。如果有 hook 的地方,可以用戶(hù)無(wú)感知地切換。
  • 更加通用。針對(duì) OCI 標(biāo)準(zhǔn)實(shí)現(xiàn),不依賴(lài)具體組件。
  • 特權(quán)模式。容器中運(yùn)行 Podman 需要特權(quán)模式。容器套娃很難擺脫的運(yùn)行模式。

6. 參考

https://github.com/kubernetes-sigs/cri-tools

http://docs.podman.io/en/latest/

參考資料

[1]《在 Kubernetes 上動(dòng)態(tài)創(chuàng)建 Jenkins Slave》: https://www.chenshaowen.com/blog/creating-jenkins-slave-dynamically-on-kubernetes.html

[2]《如何在 Docker 中使用 Docker》: https://www.chenshaowen.com/blog/how-to-use-docker-in-docker.html

[3]Podman 的安裝指引: https://podman.io/getting-started/installation


當(dāng)前題目:基于Kubernetes的Jenkins服務(wù)也可以去Docker了
標(biāo)題路徑:http://www.dlmjj.cn/article/coccoji.html