找一臺服務器搭建一臺nfs服務器html
系統:Ubuntu 16.04node
IP:172.18.1.13linux
apt install nfs-common nfs-kernel-server -y #配置掛載信息 cat /etc/exports /data/k8s *(rw,sync,no_root_squash) #給目錄添加權限 chmod -R 777 /data/k8s #啓動 /etc/init.d/nfs-kernel-server start #開機啓動 systemctl enable nfs-kernel-server
#該目錄下是jenkins.mytest.io爲測試域名的自籤密鑰 ls jenkins.mytest.io/ cacerts.pem cacerts.srl cakey.pem create_self-signed-cert.sh jenkins.mytest.io.crt jenkins.mytest.io.csr jenkins.mytest.io.key openssl.cnf tls.crt tls.key --- cd jenkins.mytest.io #建立Jenkins所在的namespace kubectl create namespace kube-ops #將密文添加到kube-ops裏面 # 服務證書和私鑰密文 kubectl -n kube-ops create \ secret tls tls-jenkins-ingress \ --cert=./tls.crt \ --key=./tls.key # ca證書密文 kubectl -n kube-ops create secret \ generic tls-ca \ --from-file=cacerts.pem
cat jenkins-pvc.yamlgit
--- apiVersion: v1 kind: PersistentVolume metadata: name: jenkins-pv spec: capacity: storage: 20Gi accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Delete nfs: server: 172.18.1.13 path: /data/k8s --- kind: PersistentVolumeClaim apiVersion: v1 metadata: name: jenkins-pvc namespace: kube-ops spec: accessModes: - ReadWriteMany resources: requests: storage: 20Gi
cat rbac.yamlgithub
--- apiVersion: v1 kind: ServiceAccount metadata: name: jenkins namespace: kube-ops --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: name: jenkins rules: - apiGroups: ["extensions", "apps"] resources: ["deployments"] verbs: ["create", "delete", "get", "list", "watch", "patch", "update"] - apiGroups: [""] resources: ["services"] verbs: ["create", "delete", "get", "list", "watch", "patch", "update"] - apiGroups: [""] resources: ["pods"] verbs: ["create","delete","get","list","patch","update","watch"] - apiGroups: [""] resources: ["pods/exec"] verbs: ["create","delete","get","list","patch","update","watch"] - apiGroups: [""] resources: ["pods/log"] verbs: ["get","list","watch"] - apiGroups: [""] resources: ["secrets"] verbs: ["get"] --- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: name: jenkins namespace: kube-ops roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: jenkins subjects: - kind: ServiceAccount name: jenkins namespace: kube-ops
cat jenkins.yamlweb
--- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: jenkins namespace: kube-ops spec: template: metadata: labels: app: jenkins spec: terminationGracePeriodSeconds: 10 serviceAccount: jenkins containers: - name: jenkins image: jenkins/jenkins:lts imagePullPolicy: IfNotPresent ports: - containerPort: 8080 name: web protocol: TCP - containerPort: 50000 name: agent protocol: TCP resources: limits: cpu: 1000m memory: 1Gi requests: cpu: 500m memory: 512Mi livenessProbe: httpGet: path: /login port: 8080 initialDelaySeconds: 60 timeoutSeconds: 5 failureThreshold: 12 readinessProbe: httpGet: path: /login port: 8080 initialDelaySeconds: 60 timeoutSeconds: 5 failureThreshold: 12 volumeMounts: - name: jenkinshome subPath: jenkins mountPath: /var/jenkins_home env: - name: LIMITS_MEMORY valueFrom: resourceFieldRef: resource: limits.memory divisor: 1Mi - name: JAVA_OPTS value: -Xmx$(LIMITS_MEMORY)m -XshowSettings:vm -Dhudson.slaves.NodeProvisioner.initialDelay=0 -Dhudson.slaves.NodeProvisioner.MARGIN=50 -Dhudson.slaves.NodeProvisioner.MARGIN0=0.85 -Duser.timezone=Asia/Shanghai securityContext: fsGroup: 1000 volumes: - name: jenkinshome persistentVolumeClaim: claimName: jenkins-pvc --- apiVersion: v1 kind: Service metadata: name: jenkins namespace: kube-ops labels: app: jenkins spec: selector: app: jenkins type: NodePort ports: - name: web port: 8080 targetPort: web nodePort: 30002 - name: agent port: 50000 targetPort: agent --- apiVersion: extensions/v1beta1 kind: Ingress metadata: name: jenkins-lb namespace: kube-ops spec: tls: - secretName: tls-jenkins-ingress rules: - host: jenkins.mytest.io http: paths: - backend: serviceName: jenkins servicePort: 8080
建立Jenkinsdocker
kubectl create -f pvc.yaml kubectl create -f rbac.yaml kubectl create -f jenkins.yaml
在/etc/hosts配置域名解析shell
kube-ip jenkins.mytest.io
打開https://jenkins.mytes.iojson
安裝插件,選擇默認便可api
採用Jenkins裏面的kubernetes插件,讓Jenkins能夠調用kubernetes生成Jenkins-slave
https://github.com/jenkinsci/kubernetes-plugin
Manage Jenkins -> Manage Plugins -> Available -> Kubernetes plugin 勾選安裝便可。
Manage Jenkins —> Configure System —> (拖到最下方)Add a new cloud —> 選擇 Kubernetes,而後填寫 Kubernetes 和 Jenkins 配置信息。
kubernetes地址採用了kube的服務器發現https://kubernetes.default.svc.cluster.local
namespace填kube-ops,而後點擊Test Connection,若是出現 Connection test successful 的提示信息證實 Jenkins 已經能夠和 Kubernetes 系統正常通訊
其實就是配置 Jenkins Slave 運行的 Pod 模板,命名空間咱們一樣是用 kube-ops,Labels 這裏也很是重要,對於後面執行 Job 的時候須要用到該值,而後咱們這裏使用的是 cnych/jenkins:jnlp 這個鏡像,這個鏡像是在官方的 jnlp 鏡像基礎上定製的,加入了 kubectl 等一些實用的工具。
另外須要注意咱們這裏須要在下面掛載兩個主機目錄,一個是 /var/run/docker.sock,該文件是用於 Pod 中的容器可以共享宿主機的 Docker,這就是你們說的 docker in docker 的方式,Docker 二進制文件咱們已經打包到上面的鏡像中了,另一個目錄下 /root/.kube 目錄,咱們將這個目錄掛載到容器的 /home/jenkins/.kube 目錄下面這是爲了讓咱們可以在 Pod 的容器中可以使用 kubectl 工具來訪問咱們的 Kubernetes 集羣,方便咱們後面在 Slave Pod 部署 Kubernetes 應用。
另一些同窗在配置了後運行 Slave Pod 的時候出現了權限問題,由於 Jenkins Slave Pod 中沒有配置權限,因此須要配置上 ServiceAccount,在 Slave Pod 配置的地方點擊下面的高級,添加上對應的 ServiceAccount 便可:
測試的時候不添加帳號會告知沒有權限
在容器模板高級裏面添加kubernetes集羣中建立的jenkins帳號
建立一個測試任務
在pipeline的框裏面添加一下內容
def label = "jnlp-slave" podTemplate(inheritFrom: 'jnlp-slave', instanceCap: 0, label: 'jnlp-slave', name: '', namespace: 'kube-ops', nodeSelector: '', podRetention: always(), serviceAccount: '', workspaceVolume: emptyDirWorkspaceVolume(false), yaml: '') { node(label) { container('jnlp-slave'){ stage('Run shell') { sh 'docker info' sh 'kubectl get pods -n kube-ops' } } } }
開始構建任務
構建任務輸出
Started by user admin Running in Durability level: MAX_SURVIVABILITY [Pipeline] Start of Pipeline [Pipeline] podTemplate [Pipeline] { [Pipeline] node Still waiting to schedule task ‘Jenkins’ doesn’t have label ‘jnlp-slave’ Agent jnlp-slave-tbdnl is provisioned from template Kubernetes Pod Template Agent specification [Kubernetes Pod Template] (jnlp-slave): * [jnlp-slave] cnych/jenkins:jnlp Running on jnlp-slave-tbdnl in /home/jenkins/workspace/test-jnlp-slave [Pipeline] { [Pipeline] container [Pipeline] { [Pipeline] stage [Pipeline] { (Run shell) [Pipeline] sh + docker info Containers: 15 Running: 12 Paused: 0 Stopped: 3 Images: 12 Server Version: 18.09.6 Storage Driver: overlay2 Backing Filesystem: extfs Supports d_type: true Native Overlay Diff: false Logging Driver: json-file Cgroup Driver: cgroupfs Plugins: Volume: local Network: bridge host macvlan null overlay Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog Swarm: inactive Runtimes: runc Default Runtime: runc Init Binary: docker-init containerd version: bb71b10fd8f58240ca47fbb579b9d1028eea7c84 runc version: 2b18fe1d885ee5083ef9f0838fee39b62d653e30 init version: fec3683 Security Options: apparmor seccomp Profile: default Kernel Version: 4.15.0-1049-azure Operating System: Ubuntu 16.04.6 LTS OSType: linux Architecture: x86_64 CPUs: 2 Total Memory: 7.768GiB Name: test-kube-node-04 ID: YFTJ:FVHK:TAF3:HTAJ:HJ2A:5SFW:73RW:VQY5:Y64U:UGIR:KMJ2:XPRL Docker Root Dir: /var/lib/docker Debug Mode (client): false Debug Mode (server): false Registry: https://index.docker.io/v1/ Labels: Experimental: false Insecure Registries: 127.0.0.0/8 Registry Mirrors: https://kv3qfp85.mirror.aliyuncs.com/ Live Restore Enabled: false WARNING: No swap limit support [Pipeline] sh + kubectl get pods -n kube-ops NAME READY STATUS RESTARTS AGE jenkins-6b874b8d7-q28h4 1/1 Running 0 3h jnlp-slave-tbdnl 2/2 Running 0 15s [Pipeline] } [Pipeline] // stage [Pipeline] } [Pipeline] // container [Pipeline] } [Pipeline] // node [Pipeline] } [Pipeline] // podTemplate [Pipeline] End of Pipeline Finished: SUCCESS
上面步驟大部分都是根據陽明博客上的《基於 Jenkins 的 CI/CD(一)》思路跟進,可是因爲環境和本身認知問題,會出現各類出錯,憋了一天,沒什麼進展。
後來只能根據kubectl -n kube-ops logs -f jenkins-xxxxx
的命令一點點查出來的,搜過不少帖子大概思路一致,可是沒法解決本質問題,若是跑不起來,再高端也是個沒有用,後來根據kubernetes-plugin的github,具體讀了遍結合本身報的錯一點一點調整過來,總算搞出來了。
具體參考瞭如下幾遍優秀的文章:
基於 Jenkins 的 CI/CD(一)(陽明老師的文章很棒)
kubernetes Jenkins gitlab搭建CI/CD環境 (二)
GitHub-Jenkins-kubernetes-plugin:jenkinsci/kubernetes-plugin