中文字幕人妻中文_99精品欧美一区二区三区综合在线_精品久久久久一区二区_色月丁香_免费福利在线视频_欧美大片免费观看网址_国产伦精品一区二区三区在线播放_污污污污污污www网站免费_久久月本道色综合久久_色69激情爱久久_尹人香蕉久久99天天拍_国产美女www_亚洲国产精品无码7777一线_五月婷婷六月激情_看免费一级片_精品久久久久久成人av_在线色亚洲_女人另类性混交zo_国产精品青青在线观看爽香蕉_人人澡人人添人人爽一区二区

主頁 > 知識庫 > 基于Docker+K8S+GitLab/SVN+Jenkins+Harbor搭建持續集成交付環境的詳細教程

基于Docker+K8S+GitLab/SVN+Jenkins+Harbor搭建持續集成交付環境的詳細教程

熱門標簽:打400電話怎么辦理收費 福州企業電銷機器人排名 上海申請高400開頭的電話 宿城區電話機器人找哪家 怎么找到沒有地圖標注的店 10086外包用的什么外呼系統 河南防封號電銷機器人是什么 400電話辦理介紹信 麗江真人語音電話外呼系統

環境搭建概述

親愛的家人們可以到鏈接:http://xiazai.jb51.net/202105/yuanma/javayaml_jb51.rar  下載所需要的yaml文件。

1.K8S是什么?

K8S全稱是Kubernetes,是一個全新的基于容器技術的分布式架構領先方案,基于容器技術,目的是實現資源管理的自動化,以及跨多個數據中心的資源利用率的最大化。

如果我們的系統設計遵循了kubernetes的設計思想,那么傳統系統架構中那些和業務沒有多大關系的底層代碼或功能模塊,都可以使用K8S來管理,我們不必再費心于負載均衡的選型和部署實施問題,不必再考慮引入或自己開發一個復雜的服務治理框架,不必再頭疼與服務監控和故障處理模塊的開發。總之,使用kubernetes提供的解決方案,會大大減少開發成本,同時可以將精力更加集中于業務本身,而且由于kubernetes提供了強大的自動化機制,所以系統后期的運維難度和運維成本大幅降低。

2.為什么要用K8S?

Docker 這個新興的容器化技術當前已經被很多公司所采用,其從單機走向集群已成必然,而云計算的蓬勃發展正在加速這一進程。Kubernetes 作為當前唯一被業界廣泛認可和看好的 Docker 分布式系統解決方案。可以預見,在未來幾年內,會有大量的新系統選擇它,不管是運行在企業本地服務器上還是被托管到公有云上。

3.使用K8S有哪些好處?

使用Kubernetes就是在全面部署微服務架構。微服務架構的核心就是將一個巨大的單體應用分解為很多小的互相連接的微服務,一個微服務背后可能有多個實例副本在支撐,副本的數量可能會隨著系統的負荷變化而進行調整,內嵌的負載均衡器在 k8s 平臺中有多個實例副本在支撐,副本的數量可能會隨著系統的負荷變化而進行調整,內嵌的負載均衡器 在k8s 平臺中發揮了重要的作用。微服務架構使得每個服務都可以由專門的開發團隊來開發,開發者可以自由選擇開發技術,這對于大規模團隊來說很有價值。另外,每個微服務獨立開發、升級、擴展,使得系統具備很高的穩定性和快速迭代進化能力。

4.環境構成

整套環境的搭建包含:Docker環境的搭建、docker-compose環境的搭建、K8S集群的搭建、GitLab代碼倉庫的搭建、SVN倉庫的搭建、Jenkins自動化部署環境的搭建、Harbor私有倉庫的搭建。

本文檔中,整套環境的搭建包括:

  • 安裝Docker環境
  • 安裝docker-compose
  • 安裝K8S集群環境
  • 重啟K8S集群引起的問題
  • K8S安裝ingress-nginx
  • K8S安裝gitlab代碼倉庫
  • 安裝Harbor私有倉庫
  • 安裝Jenkins
  • 物理機安裝SVN(推薦)
  • 物理機安裝Jenkins(推薦)
  • 配置Jenkins運行環境
  • Jenkins發布Docker項目到K8S

服務器規劃

IP 主機名 節點 操作系統
192.168.0.10 test10 K8S Master CentOS 8.0.1905
192.168.0.11 test11 K8S Worker CentOS 8.0.1905
192.168.0.12 test12 K8S Worker CentOS 8.0.1905

安裝環境

軟件名稱 軟件版本 說明
Docker 19.03.8 提供容器環境
docker-compose 1.25.5 定義和運行由多個容器組成的應用
K8S 1.18.2 是一個開源的,用于管理云平臺中多個主機上的容器化的應用,Kubernetes的目標是讓部署容器化的應用簡單并且高效(powerful),Kubernetes提供了應用部署,規劃,更新,維護的一種機制。
GitLab 12.1.6 代碼倉庫
Harbor 1.10.2 私有鏡像倉庫
Jenkins 2.222.3 持續集成交付

安裝Docker環境

Docker 是一個開源的應用容器引擎,基于 Go 語言 并遵從 Apache2.0 協議開源。

Docker 可以讓開發者打包他們的應用以及依賴包到一個輕量級、可移植的容器中,然后發布到任何流行的 Linux 機器上,也可以實現虛擬化。

本文檔基于Docker 19.03.8 版本搭建Docker環境。

在所有服務器上創建install_docker.sh腳本,腳本內容如下所示。

#使用阿里云鏡像中心
export REGISTRY_MIRROR=https://registry.cn-hangzhou.aliyuncs.com
#安裝yum工具
dnf install yum*
#安裝docker環境
yum install -y yum-utils device-mapper-persistent-data lvm2
#配置Docker的yum源
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
#安裝容器插件
dnf install https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/stable/Packages/containerd.io-1.2.13-3.1.el7.x86_64.rpm
#指定安裝docker 19.03.8版本
yum install -y docker-ce-19.03.8 docker-ce-cli-19.03.8
#設置Docker開機啟動
systemctl enable docker.service
#啟動Docker
systemctl start docker.service
#查看Docker版本
docker version

在每臺服務器上為install_docker.sh腳本賦予可執行權限,并執行腳本,如下所示。

# 賦予install_docker.sh腳本可執行權限
chmod a+x ./install_docker.sh
# 執行install_docker.sh腳本
./install_docker.sh

安裝docker-compose

Compose 是用于定義和運行多容器 Docker 應用程序的工具。通過 Compose,您可以使用 YML 文件來配置應用程序需要的所有服務。然后,使用一個命令,就可以從 YML 文件配置中創建并啟動所有服務。

注意:在每臺服務器上安裝docker-compose

1.下載docker-compose文件

#下載并安裝docker-compose
curl -L https://github.com/docker/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose 

2.為docker-compose文件賦予可執行權限

#賦予docker-compose可執行權限
chmod a+x /usr/local/bin/docker-compose

3.查看docker-compose版本

#查看docker-compose版本
[root@binghe ~]# docker-compose version
docker-compose version 1.25.5, build 8a1c60f6
docker-py version: 4.1.0
CPython version: 3.7.5
OpenSSL version: OpenSSL 1.1.0l  10 Sep 2019

安裝K8S集群環境

Kubernetes是一個開源的,用于管理云平臺中多個主機上的容器化的應用,Kubernetes的目標是讓部署容器化的應用簡單并且高效(powerful),Kubernetes提供了應用部署,規劃,更新,維護的一種機制。

本文檔基于K8S 1.8.12版本來搭建K8S集群

安裝K8S基礎環境

在所有服務器上創建install_k8s.sh腳本文件,腳本文件的內容如下所示。

#################配置阿里云鏡像加速器開始########################
mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://zz3sblpi.mirror.aliyuncs.com"]
}
EOF
systemctl daemon-reload
systemctl restart docker
######################配置阿里云鏡像加速器結束#########################
#安裝nfs-utils
yum install -y nfs-utils
#安裝wget軟件下載命令
yum install -y wget

#啟動nfs-server
systemctl start nfs-server
#配置nfs-server開機自啟動
systemctl enable nfs-server

#關閉防火墻
systemctl stop firewalld
#取消防火墻開機自啟動
systemctl disable firewalld

#關閉SeLinux
setenforce 0
sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config

# 關閉 swap
swapoff -a
yes | cp /etc/fstab /etc/fstab_bak
cat /etc/fstab_bak |grep -v swap > /etc/fstab

############################修改 /etc/sysctl.conf開始###########################
# 如果有配置,則修改
sed -i "s#^net.ipv4.ip_forward.*#net.ipv4.ip_forward=1#g"  /etc/sysctl.conf
sed -i "s#^net.bridge.bridge-nf-call-ip6tables.*#net.bridge.bridge-nf-call-ip6tables=1#g"  /etc/sysctl.conf
sed -i "s#^net.bridge.bridge-nf-call-iptables.*#net.bridge.bridge-nf-call-iptables=1#g"  /etc/sysctl.conf
sed -i "s#^net.ipv6.conf.all.disable_ipv6.*#net.ipv6.conf.all.disable_ipv6=1#g"  /etc/sysctl.conf
sed -i "s#^net.ipv6.conf.default.disable_ipv6.*#net.ipv6.conf.default.disable_ipv6=1#g"  /etc/sysctl.conf
sed -i "s#^net.ipv6.conf.lo.disable_ipv6.*#net.ipv6.conf.lo.disable_ipv6=1#g"  /etc/sysctl.conf
sed -i "s#^net.ipv6.conf.all.forwarding.*#net.ipv6.conf.all.forwarding=1#g"  /etc/sysctl.conf
# 可能沒有,追加
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
echo "net.bridge.bridge-nf-call-ip6tables = 1" >> /etc/sysctl.conf
echo "net.bridge.bridge-nf-call-iptables = 1" >> /etc/sysctl.conf
echo "net.ipv6.conf.all.disable_ipv6 = 1" >> /etc/sysctl.conf
echo "net.ipv6.conf.default.disable_ipv6 = 1" >> /etc/sysctl.conf
echo "net.ipv6.conf.lo.disable_ipv6 = 1" >> /etc/sysctl.conf
echo "net.ipv6.conf.all.forwarding = 1"  >> /etc/sysctl.conf
############################修改 /etc/sysctl.conf結束###########################
# 執行命令使修改后的/etc/sysctl.conf文件生效
sysctl -p

################# 配置K8S的yum源開始#############################
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
       http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
################# 配置K8S的yum源結束#############################

# 卸載舊版本K8S
yum remove -y kubelet kubeadm kubectl

# 安裝kubelet、kubeadm、kubectl,這里我安裝的是1.18.2版本,你也可以安裝1.17.2版本
yum install -y kubelet-1.18.2 kubeadm-1.18.2 kubectl-1.18.2

# 修改docker Cgroup Driver為systemd
# # 將/usr/lib/systemd/system/docker.service文件中的這一行 ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
# # 修改為 ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --exec-opt native.cgroupdriver=systemd
# 如果不修改,在添加 worker 節點時可能會碰到如下錯誤
# [WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd". 
# Please follow the guide at https://kubernetes.io/docs/setup/cri/
sed -i "s#^ExecStart=/usr/bin/dockerd.*#ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --exec-opt native.cgroupdriver=systemd#g" /usr/lib/systemd/system/docker.service

# 設置 docker 鏡像,提高 docker 鏡像下載速度和穩定性
# 如果訪問 https://hub.docker.io 速度非常穩定,也可以跳過這個步驟,一般不需配置
# curl -sSL https://kuboard.cn/install-script/set_mirror.sh | sh -s ${REGISTRY_MIRROR}

# 重新加載配置文件
systemctl daemon-reload
#重啟 docker
systemctl restart docker
# 將kubelet設置為開機啟動并啟動kubelet
systemctl enable kubelet && systemctl start kubelet
# 查看docker版本
docker version

在每臺服務器上為install_k8s.sh腳本賦予可執行權限,并執行腳本

# 賦予install_k8s.sh腳本可執行權限
chmod a+x ./install_k8s.sh
# 運行install_k8s.sh腳本
./install_k8s.sh

初始化Master節點

只在test10服務器上執行的操作。

1.初始化Master節點的網絡環境

注意:下面的命令需要在命令行手動執行。

# 只在 master 節點執行
# export 命令只在當前 shell 會話中有效,開啟新的 shell 窗口后,如果要繼續安裝過程,請重新執行此處的 export 命令
export MASTER_IP=192.168.0.10
# 替換 k8s.master 為 您想要的 dnsName
export APISERVER_NAME=k8s.master
# Kubernetes 容器組所在的網段,該網段安裝完成后,由 kubernetes 創建,事先并不存在于物理網絡中
export POD_SUBNET=172.18.0.1/16
echo "${MASTER_IP}    ${APISERVER_NAME}" >> /etc/hosts

2.初始化Master節點

在test10服務器上創建init_master.sh腳本文件,文件內容如下所示。

#!/bin/bash
# 腳本出錯時終止執行
set -e

if [ ${#POD_SUBNET} -eq 0 ] || [ ${#APISERVER_NAME} -eq 0 ]; then
  echo -e "\033[31;1m請確保您已經設置了環境變量 POD_SUBNET 和 APISERVER_NAME \033[0m"
  echo 當前POD_SUBNET=$POD_SUBNET
  echo 當前APISERVER_NAME=$APISERVER_NAME
  exit 1
fi


# 查看完整配置選項 https://godoc.org/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2
rm -f ./kubeadm-config.yaml
cat <<EOF > ./kubeadm-config.yaml
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
kubernetesVersion: v1.18.2
imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers
controlPlaneEndpoint: "${APISERVER_NAME}:6443"
networking:
  serviceSubnet: "10.96.0.0/16"
  podSubnet: "${POD_SUBNET}"
  dnsDomain: "cluster.local"
EOF

# kubeadm init
# 初始化kebeadm
kubeadm init --config=kubeadm-config.yaml --upload-certs

# 配置 kubectl
rm -rf /root/.kube/
mkdir /root/.kube/
cp -i /etc/kubernetes/admin.conf /root/.kube/config

# 安裝 calico 網絡插件
# 參考文檔 https://docs.projectcalico.org/v3.13/getting-started/kubernetes/self-managed-onprem/onpremises
echo "安裝calico-3.13.1"
rm -f calico-3.13.1.yaml
wget https://kuboard.cn/install-script/calico/calico-3.13.1.yaml
kubectl apply -f calico-3.13.1.yaml

賦予init_master.sh腳本文件可執行權限并執行腳本。

# 賦予init_master.sh文件可執行權限
chmod a+x ./init_master.sh
# 運行init_master.sh腳本
./init_master.sh

3.查看Master節點的初始化結果

(1)確保所有容器組處于Running狀態

# 執行如下命令,等待 3-10 分鐘,直到所有的容器組處于 Running 狀態
watch kubectl get pod -n kube-system -o wide

具體執行如下所示。

[root@test10 ~]# watch kubectl get pod -n kube-system -o wide
Every 2.0s: kubectl get pod -n kube-system -o wide                                                                                                                          test10: Sun May 10 11:01:32 2020

NAME                                       READY   STATUS    RESTARTS   AGE    IP                NODE        NOMINATED NODE   READINESS GATES          
calico-kube-controllers-5b8b769fcd-5dtlp   1/1     Running   0          118s   172.18.203.66     test10   <none>           <none>          
calico-node-fnv8g                          1/1     Running   0          118s   192.168.0.10   test10   <none>           <none>          
coredns-546565776c-27t7h                   1/1     Running   0          2m1s   172.18.203.67     test10   <none>           <none>          
coredns-546565776c-hjb8z                   1/1     Running   0          2m1s   172.18.203.65     test10   <none>           <none>          
etcd-test10                             1/1     Running   0          2m7s   192.168.0.10   test10   <none>           <none>          
kube-apiserver-test10                   1/1     Running   0          2m7s   192.168.0.10   test10   <none>           <none>          
kube-controller-manager-test10          1/1     Running   0          2m7s   192.168.0.10   test10   <none>           <none>          
kube-proxy-dvgsr                           1/1     Running   0          2m1s   192.168.0.10   test10   <none>           <none>          
kube-scheduler-test10                   1/1     Running   0          2m7s   192.168.0.10   test10   <none> 

(2) 查看 Master 節點初始化結果

# 查看Master節點的初始化結果
kubectl get nodes -o wide

具體執行如下所示。

[root@test10 ~]# kubectl get nodes -o wide
NAME        STATUS   ROLES    AGE     VERSION   INTERNAL-IP       EXTERNAL-IP   OS-IMAGE                KERNEL-VERSION         CONTAINER-RUNTIME
test10   Ready    master   3m28s   v1.18.2   192.168.0.10   <none>        CentOS Linux 8 (Core)   4.18.0-80.el8.x86_64   docker://19.3.8

初始化Worker節點

1.獲取join命令參數

在Master節點(test10服務器)上執行如下命令獲取join命令參數。

kubeadm token create --print-join-command

具體執行如下所示。

[root@test10 ~]# kubeadm token create --print-join-command
W0510 11:04:34.828126   56132 configset.go:202] WARNING: kubeadm cannot validate component configs for API groups [kubelet.config.k8s.io kubeproxy.config.k8s.io]
kubeadm join k8s.master:6443 --token 8nblts.62xytoqufwsqzko2     --discovery-token-ca-cert-hash sha256:1717cc3e34f6a56b642b5751796530e367aa73f4113d09994ac3455e33047c0d 

其中,有如下一行輸出。

kubeadm join k8s.master:6443 --token 8nblts.62xytoqufwsqzko2     --discovery-token-ca-cert-hash sha256:1717cc3e34f6a56b642b5751796530e367aa73f4113d09994ac3455e33047c0d 

這行代碼就是獲取到的join命令。

注意:join命令中的token的有效時間為 2 個小時,2小時內,可以使用此 token 初始化任意數量的 worker 節點。

2.初始化Worker節點

針對所有的 worker 節點執行,在這里,就是在test11服務器和test12服務器上執行。

在命令分別手動執行如下命令。

# 只在 worker 節點執行
# 192.168.0.10 為 master 節點的內網 IP
export MASTER_IP=192.168.0.10
# 替換 k8s.master 為初始化 master 節點時所使用的 APISERVER_NAME
export APISERVER_NAME=k8s.master
echo "${MASTER_IP}    ${APISERVER_NAME}" >> /etc/hosts

# 替換為 master 節點上 kubeadm token create 命令輸出的join
kubeadm join k8s.master:6443 --token 8nblts.62xytoqufwsqzko2     --discovery-token-ca-cert-hash sha256:1717cc3e34f6a56b642b5751796530e367aa73f4113d09994ac3455e33047c0d 

具體執行如下所示。

[root@test11 ~]# export MASTER_IP=192.168.0.10
[root@test11 ~]# export APISERVER_NAME=k8s.master
[root@test11 ~]# echo "${MASTER_IP}    ${APISERVER_NAME}" >> /etc/hosts
[root@test11 ~]# kubeadm join k8s.master:6443 --token 8nblts.62xytoqufwsqzko2     --discovery-token-ca-cert-hash sha256:1717cc3e34f6a56b642b5751796530e367aa73f4113d09994ac3455e33047c0d 
W0510 11:08:27.709263   42795 join.go:346] [preflight] WARNING: JoinControlPane.controlPlane settings will be ignored when control-plane flag is not set.
[preflight] Running pre-flight checks
        [WARNING FileExisting-tc]: tc not found in system path
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml'
[kubelet-start] Downloading configuration for the kubelet from the "kubelet-config-1.18" ConfigMap in the kube-system namespace
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Starting the kubelet
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...

This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.

Run 'kubectl get nodes' on the control-plane to see this node join the cluster.

根據輸出結果可以看出,Worker節點加入了K8S集群。

注意:kubeadm join…就是master 節點上 kubeadm token create 命令輸出的join。

3.查看初始化結果

在Master節點(test10服務器)執行如下命令查看初始化結果。

kubectl get nodes -o wide

具體執行如下所示。

[root@test10 ~]# kubectl get nodes
NAME        STATUS   ROLES    AGE     VERSION
test10   Ready    master   20m     v1.18.2
test11   Ready    <none>   2m46s   v1.18.2
test12   Ready    <none>   2m46s   v1.18.2

注意:kubectl get nodes命令后面加上-o wide參數可以輸出更多的信息。

重啟K8S集群引起的問題

1.Worker節點故障不能啟動

Master 節點的 IP 地址發生變化,導致 worker 節點不能啟動。需要重新安裝K8S集群,并確保所有節點都有固定的內網 IP 地址。

2.Pod崩潰或不能正常訪問

重啟服務器后使用如下命令查看Pod的運行狀態。

#查看所有pod的運行情況
kubectl get pods --all-namespaces

發現很多 Pod 不在 Running 狀態,此時,需要使用如下命令刪除運行不正常的Pod。

kubectl delete pod <pod-name> -n <pod-namespece>

注意:如果Pod 是使用 Deployment、StatefulSet 等控制器創建的,K8S 將創建新的 Pod 作為替代,重新啟動的 Pod 通常能夠正常工作。

其中,pod-name表示運行在K8S中的pod的名稱,pod-namespece表示命名空間。例如,需要刪除pod名稱為pod-test,命名空間為pod-test-namespace的pod,可以使用下面的命令。

kubectl delete pod pod-test -n pod-test-namespace

K8S安裝ingress-nginx

作為反向代理將外部流量導入集群內部,將 Kubernetes 內部的 Service 暴露給外部,在 Ingress 對象中通過域名匹配 Service,這樣就可以直接通過域名訪問到集群內部的服務了。相對于 traefik 來說,nginx-ingress 性能更加優秀。

注意:在Master節點(test10服務器上執行)

1.創建ingress-nginx命名空間

創建ingress-nginx-namespace.yaml文件,主要的作用是創建ingress-nginx命名空間,文件內容如下所示。

apiVersion: v1
kind: Namespace
metadata:
  name: ingress-nginx
  labels:
    name: ingress-nginx

執行如下命令創建ingress-nginx命名空間。

kubectl apply -f ingress-nginx-namespace.yaml

2.安裝ingress controller

創建ingress-nginx-mandatory.yaml文件,主要的作用是安裝ingress-nginx。文件內容如下所示。

apiVersion: v1
kind: Namespace
metadata:
  name: ingress-nginx

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: default-http-backend
  labels:
    app.kubernetes.io/name: default-http-backend
    app.kubernetes.io/part-of: ingress-nginx
  namespace: ingress-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: default-http-backend
      app.kubernetes.io/part-of: ingress-nginx
  template:
    metadata:
      labels:
        app.kubernetes.io/name: default-http-backend
        app.kubernetes.io/part-of: ingress-nginx
    spec:
      terminationGracePeriodSeconds: 60
      containers:
        - name: default-http-backend
          # Any image is permissible as long as:
          # 1. It serves a 404 page at /
          # 2. It serves 200 on a /healthz endpoint
          image: registry.cn-qingdao.aliyuncs.com/kubernetes_xingej/defaultbackend-amd64:1.5
          livenessProbe:
            httpGet:
              path: /healthz
              port: 8080
              scheme: HTTP
            initialDelaySeconds: 30
            timeoutSeconds: 5
          ports:
            - containerPort: 8080
          resources:
            limits:
              cpu: 10m
              memory: 20Mi
            requests:
              cpu: 10m
              memory: 20Mi

---
apiVersion: v1
kind: Service
metadata:
  name: default-http-backend
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: default-http-backend
    app.kubernetes.io/part-of: ingress-nginx
spec:
  ports:
    - port: 80
      targetPort: 8080
  selector:
    app.kubernetes.io/name: default-http-backend
    app.kubernetes.io/part-of: ingress-nginx

---

kind: ConfigMap
apiVersion: v1
metadata:
  name: nginx-configuration
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---

kind: ConfigMap
apiVersion: v1
metadata:
  name: tcp-services
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---

kind: ConfigMap
apiVersion: v1
metadata:
  name: udp-services
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---

apiVersion: v1
kind: ServiceAccount
metadata:
  name: nginx-ingress-serviceaccount
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: nginx-ingress-clusterrole
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
rules:
  - apiGroups:
      - ""
    resources:
      - configmaps
      - endpoints
      - nodes
      - pods
      - secrets
    verbs:
      - list
      - watch
  - apiGroups:
      - ""
    resources:
      - nodes
    verbs:
      - get
  - apiGroups:
      - ""
    resources:
      - services
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - "extensions"
    resources:
      - ingresses
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - ""
    resources:
      - events
    verbs:
      - create
      - patch
  - apiGroups:
      - "extensions"
    resources:
      - ingresses/status
    verbs:
      - update

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
  name: nginx-ingress-role
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
rules:
  - apiGroups:
      - ""
    resources:
      - configmaps
      - pods
      - secrets
      - namespaces
    verbs:
      - get
  - apiGroups:
      - ""
    resources:
      - configmaps
    resourceNames:
      # Defaults to "<election-id>-<ingress-class>"
      # Here: "<ingress-controller-leader>-<nginx>"
      # This has to be adapted if you change either parameter
      # when launching the nginx-ingress-controller.
      - "ingress-controller-leader-nginx"
    verbs:
      - get
      - update
  - apiGroups:
      - ""
    resources:
      - configmaps
    verbs:
      - create
  - apiGroups:
      - ""
    resources:
      - endpoints
    verbs:
      - get

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
  name: nginx-ingress-role-nisa-binding
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: nginx-ingress-role
subjects:
  - kind: ServiceAccount
    name: nginx-ingress-serviceaccount
    namespace: ingress-nginx

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: nginx-ingress-clusterrole-nisa-binding
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: nginx-ingress-clusterrole
subjects:
  - kind: ServiceAccount
    name: nginx-ingress-serviceaccount
    namespace: ingress-nginx

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-ingress-controller
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: ingress-nginx
      app.kubernetes.io/part-of: ingress-nginx
  template:
    metadata:
      labels:
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/part-of: ingress-nginx
      annotations:
        prometheus.io/port: "10254"
        prometheus.io/scrape: "true"
    spec:
      serviceAccountName: nginx-ingress-serviceaccount
      containers:
        - name: nginx-ingress-controller
          image: registry.cn-qingdao.aliyuncs.com/kubernetes_xingej/nginx-ingress-controller:0.20.0
          args:
            - /nginx-ingress-controller
            - --default-backend-service=$(POD_NAMESPACE)/default-http-backend
            - --configmap=$(POD_NAMESPACE)/nginx-configuration
            - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
            - --udp-services-configmap=$(POD_NAMESPACE)/udp-services
            - --publish-service=$(POD_NAMESPACE)/ingress-nginx
            - --annotations-prefix=nginx.ingress.kubernetes.io
          securityContext:
            capabilities:
              drop:
                - ALL
              add:
                - NET_BIND_SERVICE
            # www-data -> 33
            runAsUser: 33
          env:
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
          ports:
            - name: http
              containerPort: 80
            - name: https
              containerPort: 443
          livenessProbe:
            failureThreshold: 3
            httpGet:
              path: /healthz
              port: 10254
              scheme: HTTP
            initialDelaySeconds: 10
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 1
          readinessProbe:
            failureThreshold: 3
            httpGet:
              path: /healthz
              port: 10254
              scheme: HTTP
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 1

---

執行如下命令安裝ingress controller。

kubectl apply -f ingress-nginx-mandatory.yaml

3.安裝K8S SVC:ingress-nginx

主要是用來用于暴露pod:nginx-ingress-controller。

創建service-nodeport.yaml文件,文件內容如下所示。

apiVersion: v1
kind: Service
metadata:
  name: ingress-nginx
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
spec:
  type: NodePort
  ports:
    - name: http
      port: 80
      targetPort: 80
      protocol: TCP
      nodePort: 30080
    - name: https
      port: 443
      targetPort: 443
      protocol: TCP
      nodePort: 30443
  selector:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

執行如下命令安裝。

kubectl apply -f service-nodeport.yaml

4.訪問K8S SVC:ingress-nginx

查看ingress-nginx命名空間的部署情況,如下所示。

[root@test10 k8s]# kubectl get pod -n ingress-nginx
NAME                                        READY   STATUS    RESTARTS   AGE
default-http-backend-796ddcd9b-vfmgn        1/1     Running   1          10h
nginx-ingress-controller-58985cc996-87754   1/1     Running   2          10h

在命令行服務器命令行輸入如下命令查看ingress-nginx的端口映射情況。

kubectl get svc -n ingress-nginx 

具體如下所示。

[root@test10 k8s]# kubectl get svc -n ingress-nginx 
NAME                   TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)                      AGE
default-http-backend   ClusterIP   10.96.247.2   <none>        80/TCP                       7m3s
ingress-nginx          NodePort    10.96.40.6    <none>        80:30080/TCP,443:30443/TCP   4m35s

所以,可以通過Master節點(test10服務器)的IP地址和30080端口號來訪問ingress-nginx,如下所示。

[root@test10 k8s]# curl 192.168.0.10:30080       
default backend - 404

也可以在瀏覽器打開http://192.168.0.10:30080 來訪問ingress-nginx,如下所示。

K8S安裝gitlab代碼倉庫

GitLab是由GitLabInc.開發,使用MIT許可證的基于網絡的Git倉庫管理工具,且具有Wiki和issue跟蹤功能。使用Git作為代碼管理工具,并在此基礎上搭建起來的web服務。

注意:在Master節點(test10服務器上執行)

1.創建k8s-ops命名空間

創建k8s-ops-namespace.yaml文件,主要作用是創建k8s-ops命名空間。文件內容如下所示。

apiVersion: v1
kind: Namespace
metadata:
  name: k8s-ops
  labels:
    name: k8s-ops

執行如下命令創建命名空間。

kubectl apply -f k8s-ops-namespace.yaml 

2.安裝gitlab-redis

創建gitlab-redis.yaml文件,文件的內容如下所示。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis
  namespace: k8s-ops
  labels:
    name: redis
spec:
  selector:
    matchLabels:
      name: redis
  template:
    metadata:
      name: redis
      labels:
        name: redis
    spec:
      containers:
      - name: redis
        image: sameersbn/redis
        imagePullPolicy: IfNotPresent
        ports:
        - name: redis
          containerPort: 6379
        volumeMounts:
        - mountPath: /var/lib/redis
          name: data
        livenessProbe:
          exec:
            command:
            - redis-cli
            - ping
          initialDelaySeconds: 30
          timeoutSeconds: 5
        readinessProbe:
          exec:
            command:
            - redis-cli
            - ping
          initialDelaySeconds: 10
          timeoutSeconds: 5
      volumes:
      - name: data
        hostPath:
          path: /data1/docker/xinsrv/redis

---
apiVersion: v1
kind: Service
metadata:
  name: redis
  namespace: k8s-ops
  labels:
    name: redis
spec:
  ports:
    - name: redis
      port: 6379
      targetPort: redis
  selector:
    name: redis

首先,在命令行執行如下命令創建/data1/docker/xinsrv/redis目錄。

mkdir -p /data1/docker/xinsrv/redis

執行如下命令安裝gitlab-redis。

kubectl apply -f gitlab-redis.yaml 

3.安裝gitlab-postgresql

創建gitlab-postgresql.yaml,文件內容如下所示。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgresql
  namespace: k8s-ops
  labels:
    name: postgresql
spec:
  selector:
    matchLabels:
      name: postgresql
  template:
    metadata:
      name: postgresql
      labels:
        name: postgresql
    spec:
      containers:
      - name: postgresql
        image: sameersbn/postgresql
        imagePullPolicy: IfNotPresent
        env:
        - name: DB_USER
          value: gitlab
        - name: DB_PASS
          value: passw0rd
        - name: DB_NAME
          value: gitlab_production
        - name: DB_EXTENSION
          value: pg_trgm
        ports:
        - name: postgres
          containerPort: 5432
        volumeMounts:
        - mountPath: /var/lib/postgresql
          name: data
        livenessProbe:
          exec:
            command:
            - pg_isready
            - -h
            - localhost
            - -U
            - postgres
          initialDelaySeconds: 30
          timeoutSeconds: 5
        readinessProbe:
          exec:
            command:
            - pg_isready
            - -h
            - localhost
            - -U
            - postgres
          initialDelaySeconds: 5
          timeoutSeconds: 1
      volumes:
      - name: data
        hostPath:
          path: /data1/docker/xinsrv/postgresql
---
apiVersion: v1
kind: Service
metadata:
  name: postgresql
  namespace: k8s-ops
  labels:
    name: postgresql
spec:
  ports:
    - name: postgres
      port: 5432
      targetPort: postgres
  selector:
    name: postgresql

首先,執行如下命令創建/data1/docker/xinsrv/postgresql目錄。

mkdir -p /data1/docker/xinsrv/postgresql

接下來,安裝gitlab-postgresql,如下所示。

kubectl apply -f gitlab-postgresql.yaml

4.安裝gitlab

(1)配置用戶名和密碼

首先,在命令行使用base64編碼為用戶名和密碼進行轉碼,本示例中,使用的用戶名為admin,密碼為admin.1231

轉碼情況如下所示。

[root@test10 k8s]# echo -n 'admin' | base64 
YWRtaW4=
[root@test10 k8s]# echo -n 'admin.1231' | base64 
YWRtaW4uMTIzMQ==

轉碼后的用戶名為:YWRtaW4= 密碼為:YWRtaW4uMTIzMQ==

也可以對base64編碼后的字符串解碼,例如,對密碼字符串解碼,如下所示。

[root@test10 k8s]# echo 'YWRtaW4uMTIzMQ==' | base64 --decode 
admin.1231

接下來,創建secret-gitlab.yaml文件,主要是用戶來配置GitLab的用戶名和密碼,文件內容如下所示。

apiVersion: v1
kind: Secret
metadata:
  namespace: k8s-ops
  name: git-user-pass
type: Opaque
data:
  username: YWRtaW4=
  password: YWRtaW4uMTIzMQ==

執行配置文件的內容,如下所示。

kubectl create -f ./secret-gitlab.yaml

(2)安裝GitLab

創建gitlab.yaml文件,文件的內容如下所示。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: gitlab
  namespace: k8s-ops
  labels:
    name: gitlab
spec:
  selector:
    matchLabels:
      name: gitlab
  template:
    metadata:
      name: gitlab
      labels:
        name: gitlab
    spec:
      containers:
      - name: gitlab
        image: sameersbn/gitlab:12.1.6
        imagePullPolicy: IfNotPresent
        env:
        - name: TZ
          value: Asia/Shanghai
        - name: GITLAB_TIMEZONE
          value: Beijing
        - name: GITLAB_SECRETS_DB_KEY_BASE
          value: long-and-random-alpha-numeric-string
        - name: GITLAB_SECRETS_SECRET_KEY_BASE
          value: long-and-random-alpha-numeric-string
        - name: GITLAB_SECRETS_OTP_KEY_BASE
          value: long-and-random-alpha-numeric-string
        - name: GITLAB_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: git-user-pass
              key: password
        - name: GITLAB_ROOT_EMAIL
          value: 12345678@qq.com
        - name: GITLAB_HOST
          value: gitlab.binghe.com
        - name: GITLAB_PORT
          value: "80"
        - name: GITLAB_SSH_PORT
          value: "30022"
        - name: GITLAB_NOTIFY_ON_BROKEN_BUILDS
          value: "true"
        - name: GITLAB_NOTIFY_PUSHER
          value: "false"
        - name: GITLAB_BACKUP_SCHEDULE
          value: daily
        - name: GITLAB_BACKUP_TIME
          value: 01:00
        - name: DB_TYPE
          value: postgres
        - name: DB_HOST
          value: postgresql
        - name: DB_PORT
          value: "5432"
        - name: DB_USER
          value: gitlab
        - name: DB_PASS
          value: passw0rd
        - name: DB_NAME
          value: gitlab_production
        - name: REDIS_HOST
          value: redis
        - name: REDIS_PORT
          value: "6379"
        ports:
        - name: http
          containerPort: 80
        - name: ssh
          containerPort: 22
        volumeMounts:
        - mountPath: /home/git/data
          name: data
        livenessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 180
          timeoutSeconds: 5
        readinessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
          timeoutSeconds: 1
      volumes:
      - name: data
        hostPath:
          path: /data1/docker/xinsrv/gitlab
---
apiVersion: v1
kind: Service
metadata:
  name: gitlab
  namespace: k8s-ops
  labels:
    name: gitlab
spec:
  ports:
    - name: http
      port: 80
      nodePort: 30088
    - name: ssh
      port: 22
      targetPort: ssh
      nodePort: 30022
  type: NodePort
  selector:
    name: gitlab

---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: gitlab
  namespace: k8s-ops
  annotations:
    kubernetes.io/ingress.class: traefik
spec:
  rules:
  - host: gitlab.binghe.com
    http:
      paths:
      - backend:
          serviceName: gitlab
          servicePort: http

注意:在配置GitLab時,監聽主機時,不能使用IP地址,需要使用主機名或者域名,上述配置中,我使用的是gitlab.binghe.com主機名。

在命令行執行如下命令創建/data1/docker/xinsrv/gitlab目錄。

mkdir -p /data1/docker/xinsrv/gitlab

安裝GitLab,如下所示。

kubectl apply -f gitlab.yaml

5.安裝完成

查看k8s-ops命名空間部署情況,如下所示。

[root@test10 k8s]# kubectl get pod -n k8s-ops
NAME                          READY   STATUS    RESTARTS   AGE
gitlab-7b459db47c-5vk6t       0/1     Running   0          11s
postgresql-79567459d7-x52vx   1/1     Running   0          30m
redis-67f4cdc96c-h5ckz        1/1     Running   1          10h

也可以使用如下命令查看。

[root@test10 k8s]# kubectl get pod --namespace=k8s-ops
NAME                          READY   STATUS    RESTARTS   AGE
gitlab-7b459db47c-5vk6t       0/1     Running   0          36s
postgresql-79567459d7-x52vx   1/1     Running   0          30m
redis-67f4cdc96c-h5ckz        1/1     Running   1          10h

二者效果一樣。

接下來,查看GitLab的端口映射,如下所示。

[root@test10 k8s]# kubectl get svc -n k8s-ops
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                     AGE
gitlab       NodePort    10.96.153.100   <none>        80:30088/TCP,22:30022/TCP   2m42s
postgresql   ClusterIP   10.96.203.119   <none>        5432/TCP                    32m
redis        ClusterIP   10.96.107.150   <none>        6379/TCP                    10h

此時,可以看到,可以通過Master節點(test10)的主機名gitlab.binghe.com和端口30088就能夠訪問GitLab。由于我這里使用的是虛擬機來搭建相關的環境,在本機訪問虛擬機映射的gitlab.binghe.com時,需要配置本機的hosts文件,在本機的hosts文件中加入如下配置項。

192.168.0.10 gitlab.binghe.com

注意:在Windows操作系統中,hosts文件所在的目錄如下。

C:\Windows\System32\drivers\etc

接下來,就可以在瀏覽器中通過鏈接:http://gitlab.binghe.com:30088 來訪問GitLab了,如下所示。

此時,可以通過用戶名root和密碼admin.1231來登錄GitLab了。

注意:這里的用戶名是root而不是admin,因為root是GitLab默認的超級用戶。

到此,K8S安裝gitlab完成。

安裝Harbor私有倉庫

Habor是由VMWare公司開源的容器鏡像倉庫。事實上,Habor是在Docker Registry上進行了相應的企業級擴展,從而獲得了更加廣泛的應用,這些新的企業級特性包括:管理用戶界面,基于角色的訪問控制 ,AD/LDAP集成以及審計日志等,足以滿足基本企業需求。

注意:這里將Harbor私有倉庫安裝在Master節點(test10服務器)上,實際生產環境中建議安裝在其他服務器。

1.下載Harbor的離線安裝版本

wget https://github.com/goharbor/harbor/releases/download/v1.10.2/harbor-offline-installer-v1.10.2.tgz

2.解壓Harbor的安裝包

tar -zxvf harbor-offline-installer-v1.10.2.tgz

解壓成功后,會在服務器當前目錄生成一個harbor目錄。

3.配置Harbor

注意:這里,我將Harbor的端口修改成了1180,如果不修改Harbor的端口,默認的端口是80。

(1)修改harbor.yml文件

cd harbor
vim harbor.yml

修改的配置項如下所示。

hostname: 192.168.0.10
http:
  port: 1180
harbor_admin_password: binghe123
###并把https注釋掉,不然在安裝的時候會報錯:ERROR:root:Error: The protocol is https but attribute ssl_cert is not set
#https:
  #port: 443
  #certificate: /your/certificate/path
  #private_key: /your/private/key/path

(2)修改daemon.json文件

修改/etc/docker/daemon.json文件,沒有的話就創建,在/etc/docker/daemon.json文件中添加如下內容。

[root@binghe~]# cat /etc/docker/daemon.json
{
  "registry-mirrors": ["https://zz3sblpi.mirror.aliyuncs.com"],
  "insecure-registries":["192.168.0.10:1180"]
}

也可以在服務器上使用 ip addr 命令查看本機所有的IP地址段,將其配置到/etc/docker/daemon.json文件中。這里,我配置后的文件內容如下所示。

{
    "registry-mirrors": ["https://zz3sblpi.mirror.aliyuncs.com"],
    "insecure-registries":["192.168.175.0/16","172.17.0.0/16", "172.18.0.0/16", "172.16.29.0/16", "192.168.0.10:1180"]
}

4.安裝并啟動harbor

配置完成后,輸入如下命令即可安裝并啟動Harbor

[root@binghe harbor]# ./install.sh 

5.登錄Harbor并添加賬戶

安裝成功后,在瀏覽器地址欄輸入http://192.168.0.10:1180打開鏈接,輸入用戶名admin和密碼binghe123,登錄系統。

接下來,我們選擇用戶管理,添加一個管理員賬戶,為后續打包Docker鏡像和上傳Docker鏡像做準備。

密碼為Binghe123。點擊確,此時,賬戶binghe還不是管理員,此時選中binghe賬戶,點擊“設置為管理員”。

此時,binghe賬戶就被設置為管理員了。到此,Harbor的安裝就完成了。

6.修改Harbor端口

如果安裝Harbor后,大家需要修改Harbor的端口,可以按照如下步驟修改Harbor的端口,這里,我以將80端口修改為1180端口為例

(1)修改harbor.yml文件

cd harbor
vim harbor.yml

修改的配置項如下所示。

hostname: 192.168.0.10
http:
  port: 1180
harbor_admin_password: binghe123
###并把https注釋掉,不然在安裝的時候會報錯:ERROR:root:Error: The protocol is https but attribute ssl_cert is not set
#https:
  #port: 443
  #certificate: /your/certificate/path
  #private_key: /your/private/key/path

(2)修改docker-compose.yml文件

vim docker-compose.yml

修改的配置項如下所示。

ports:
      - 1180:80

(3)修改config.yml文件

cd common/config/registry
vim config.yml

修改的配置項如下所示。

realm: http://192.168.0.10:1180/service/token

(4)重啟Docker

systemctl daemon-reload
systemctl restart docker.service

(5)重啟Harbor

[root@binghe harbor]# docker-compose down
Stopping harbor-log ... done
Removing nginx             ... done
Removing harbor-portal     ... done
Removing harbor-jobservice ... done
Removing harbor-core       ... done
Removing redis             ... done
Removing registry          ... done
Removing registryctl       ... done
Removing harbor-db         ... done
Removing harbor-log        ... done
Removing network harbor_harbor
 
[root@binghe harbor]# ./prepare
prepare base dir is set to /mnt/harbor
Clearing the configuration file: /config/log/logrotate.conf
Clearing the configuration file: /config/nginx/nginx.conf
Clearing the configuration file: /config/core/env
Clearing the configuration file: /config/core/app.conf
Clearing the configuration file: /config/registry/root.crt
Clearing the configuration file: /config/registry/config.yml
Clearing the configuration file: /config/registryctl/env
Clearing the configuration file: /config/registryctl/config.yml
Clearing the configuration file: /config/db/env
Clearing the configuration file: /config/jobservice/env
Clearing the configuration file: /config/jobservice/config.yml
Generated configuration file: /config/log/logrotate.conf
Generated configuration file: /config/nginx/nginx.conf
Generated configuration file: /config/core/env
Generated configuration file: /config/core/app.conf
Generated configuration file: /config/registry/config.yml
Generated configuration file: /config/registryctl/env
Generated configuration file: /config/db/env
Generated configuration file: /config/jobservice/env
Generated configuration file: /config/jobservice/config.yml
loaded secret from file: /secret/keys/secretkey
Generated configuration file: /compose_location/docker-compose.yml
Clean up the input dir
 
[root@binghe harbor]# docker-compose up -d
Creating network "harbor_harbor" with the default driver
Creating harbor-log ... done
Creating harbor-db   ... done
Creating redis       ... done
Creating registry    ... done
Creating registryctl ... done
Creating harbor-core ... done
Creating harbor-jobservice ... done
Creating harbor-portal     ... done
Creating nginx             ... done
 
[root@binghe harbor]# docker ps -a
CONTAINER ID        IMAGE                                               COMMAND                  CREATED             STATUS                             PORTS

安裝Jenkins(一般的做法)

Jenkins是一個開源的、提供友好操作界面的持續集成(CI)工具,起源于Hudson(Hudson是商用的),主要用于持續、自動的構建/測試軟件項目、監控外部任務的運行(這個比較抽象,暫且寫上,不做解釋)。Jenkins用Java語言編寫,可在Tomcat等流行的servlet容器中運行,也可獨立運行。通常與版本管理工具(SCM)、構建工具結合使用。常用的版本控制工具有SVN、GIT,構建工具有Maven、Ant、Gradle。

1.安裝nfs(之前安裝過的話,可以省略此步)

使用 nfs 最大的問題就是寫權限,可以使用 kubernetes 的 securityContext/runAsUser 指定 jenkins 容器中運行 jenkins 的用戶 uid,以此來指定 nfs 目錄的權限,讓 jenkins 容器可寫;也可以不限制,讓所有用戶都可以寫。這里為了簡單,就讓所有用戶可寫了。

如果之前已經安裝過nfs,則這一步可以省略。找一臺主機,安裝 nfs,這里,我以在Master節點(test10服務器)上安裝nfs為例。

在命令行輸入如下命令安裝并啟動nfs。

yum install nfs-utils -y
systemctl start nfs-server
systemctl enable nfs-server

2.創建nfs共享目錄

在Master節點(test10服務器)上創建 /opt/nfs/jenkins-data目錄作為nfs的共享目錄,如下所示。

mkdir -p /opt/nfs/jenkins-data

接下來,編輯/etc/exports文件,如下所示。

vim /etc/exports

在/etc/exports文件文件中添加如下一行配置。

/opt/nfs/jenkins-data 192.168.175.0/24(rw,all_squash)

這里的 ip 使用 kubernetes node 節點的 ip 范圍,后面的 all_squash 選項會將所有訪問的用戶都映射成 nfsnobody 用戶,不管你是什么用戶訪問,最終都會壓縮成 nfsnobody,所以只要將 /opt/nfs/jenkins-data 的屬主改為 nfsnobody,那么無論什么用戶來訪問都具有寫權限。

這個選項在很多機器上由于用戶 uid 不規范導致啟動進程的用戶不同,但是同時要對一個共享目錄具有寫權限時很有效。

接下來,為 /opt/nfs/jenkins-data目錄授權,并重新加載nfs,如下所示。

#為/opt/nfs/jenkins-data/目錄授權
chown -R 1000 /opt/nfs/jenkins-data/
#重新加載nfs-server
systemctl reload nfs-server

在K8S集群中任意一個節點上使用如下命令進行驗證:

#查看nfs系統的目錄權限
showmount -e NFS_IP

如果能夠看到 /opt/nfs/jenkins-data 就表示 ok 了。

具體如下所示。

[root@test10 ~]# showmount -e 192.168.0.10
Export list for 192.168.0.10:
/opt/nfs/jenkins-data 192.168.175.0/24

[root@test11 ~]# showmount -e 192.168.0.10
Export list for 192.168.0.10:
/opt/nfs/jenkins-data 192.168.175.0/24

3.創建PV

Jenkins 其實只要加載對應的目錄就可以讀取之前的數據,但是由于 deployment 無法定義存儲卷,因此我們只能使用 StatefulSet。

首先創建 pv,pv 是給 StatefulSet 使用的,每次 StatefulSet 啟動都會通過 volumeClaimTemplates 這個模板去創建 pvc,因此必須得有 pv,才能供 pvc 綁定。

創建jenkins-pv.yaml文件,文件內容如下所示。

apiVersion: v1
kind: PersistentVolume
metadata:
  name: jenkins
spec:
  nfs:
    path: /opt/nfs/jenkins-data
    server: 192.168.0.10
  accessModes: ["ReadWriteOnce"]
  capacity:
    storage: 1Ti

我這里給了 1T存儲空間,可以根據實際配置。

執行如下命令創建pv。

kubectl apply -f jenkins-pv.yaml 

4.創建serviceAccount

創建service account,因為 jenkins 后面需要能夠動態創建 slave,因此它必須具備一些權限。

創建jenkins-service-account.yaml文件,文件內容如下所示。

apiVersion: v1
kind: ServiceAccount
metadata:
  name: jenkins

---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: jenkins
rules:
  - 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: RoleBinding
metadata:
  name: jenkins
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: jenkins
subjects:
  - kind: ServiceAccount
    name: jenkins

上述配置中,創建了一個 RoleBinding 和一個 ServiceAccount,并且將 RoleBinding 的權限綁定到這個用戶上。所以,jenkins 容器必須使用這個 ServiceAccount 運行才行,不然 RoleBinding 的權限它將不具備。

RoleBinding 的權限很容易就看懂了,因為 jenkins 需要創建和刪除 slave,所以才需要上面這些權限。至于 secrets 權限,則是 https 證書。

執行如下命令創建serviceAccount。

kubectl apply -f jenkins-service-account.yaml 

5.安裝Jenkins

創建jenkins-statefulset.yaml文件,文件內容如下所示。

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: jenkins
  labels:
    name: jenkins
spec:
  selector:
    matchLabels:
      name: jenkins
  serviceName: jenkins
  replicas: 1
  updateStrategy:
    type: RollingUpdate
  template:
    metadata:
      name: jenkins
      labels:
        name: jenkins
    spec:
      terminationGracePeriodSeconds: 10
      serviceAccountName: jenkins
      containers:
        - name: jenkins
          image: docker.io/jenkins/jenkins:lts
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 8080
            - containerPort: 32100
          resources:
            limits:
              cpu: 4
              memory: 4Gi
            requests:
              cpu: 4
              memory: 4Gi
          env:
            - name: LIMITS_MEMORY
              valueFrom:
                resourceFieldRef:
                  resource: limits.memory
                  divisor: 1Mi
            - name: JAVA_OPTS
              # value: -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:MaxRAMFraction=1 -XshowSettings:vm -Dhudson.slaves.NodeProvisioner.initialDelay=0 -Dhudson.slaves.NodeProvisioner.MARGIN=50 -Dhudson.slaves.NodeProvisioner.MARGIN0=0.85
              value: -Xmx$(LIMITS_MEMORY)m -XshowSettings:vm -Dhudson.slaves.NodeProvisioner.initialDelay=0 -Dhudson.slaves.NodeProvisioner.MARGIN=50 -Dhudson.slaves.NodeProvisioner.MARGIN0=0.85
          volumeMounts:
            - name: jenkins-home
              mountPath: /var/jenkins_home
          livenessProbe:
            httpGet:
              path: /login
              port: 8080
            initialDelaySeconds: 60
            timeoutSeconds: 5
            failureThreshold: 12 # ~2 minutes
          readinessProbe:
            httpGet:
              path: /login
              port: 8080
            initialDelaySeconds: 60
            timeoutSeconds: 5
            failureThreshold: 12 # ~2 minutes
  # pvc 模板,對應之前的 pv
  volumeClaimTemplates:
    - metadata:
        name: jenkins-home
      spec:
        accessModes: ["ReadWriteOnce"]
        resources:
          requests:
            storage: 1Ti

jenkins 部署時需要注意它的副本數,你的副本數有多少就要有多少個 pv,同樣,存儲會有多倍消耗。這里我只使用了一個副本,因此前面也只創建了一個 pv。

使用如下命令安裝Jenkins。

kubectl apply -f jenkins-statefulset.yaml 

6.創建Service

創建jenkins-service.yaml文件,主要用于后臺運行Jenkins,文件內容如下所示。

apiVersion: v1
kind: Service
metadata:
  name: jenkins
spec:
  # type: LoadBalancer
  selector:
    name: jenkins
  # ensure the client ip is propagated to avoid the invalid crumb issue when using LoadBalancer (k8s >=1.7)
  #externalTrafficPolicy: Local
  ports:
    - name: http
      port: 80
      nodePort: 31888
      targetPort: 8080
      protocol: TCP
    - name: jenkins-agent
      port: 32100
      nodePort: 32100
      targetPort: 32100
      protocol: TCP
  type: NodePort

使用如下命令安裝Service。

kubectl apply -f jenkins-service.yaml 

7.安裝 ingress

jenkins 的 web 界面需要從集群外訪問,這里我們選擇的是使用 ingress。創建jenkins-ingress.yaml文件,文件內容如下所示。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: jenkins
spec:
  rules:
    - http:
        paths:
          - path: /
            backend:
              serviceName: jenkins
              servicePort: 31888
      host: jekins.binghe.com

這里,需要注意的是host必須配置為域名或者主機名,否則會報錯,如下所示。

The Ingress "jenkins" is invalid: spec.rules[0].host: Invalid value: "192.168.0.10": must be a DNS name, not an IP address

使用如下命令安裝ingress。

kubectl apply -f jenkins-ingress.yaml 

最后,由于我這里使用的是虛擬機來搭建相關的環境,在本機訪問虛擬機映射的jekins.binghe.com時,需要配置本機的hosts文件,在本機的hosts文件中加入如下配置項。

192.168.0.10 jekins.binghe.com

注意:在Windows操作系統中,hosts文件所在的目錄如下。

C:\Windows\System32\drivers\etc

接下來,就可以在瀏覽器中通過鏈接:http://jekins.binghe.com:31888 來訪問Jekins了。

物理機安裝SVN

Apache Subversion 通常被縮寫成 SVN,是一個開放源代碼的版本控制系統,Subversion 在 2000 年由 CollabNet Inc 開發,現在發展成為 Apache 軟件基金會的一個項目,同樣是一個豐富的開發者和用戶社區的一部分。

SVN相對于的RCS、CVS,采用了分支管理系統,它的設計目標就是取代CVS。互聯網上免費的版本控制服務多基于Subversion。

這里,以在Master節點(binghe101服務器)上安裝SVN為例。

1.使用yum安裝SVN

在命令行執行如下命令安裝SVN。

yum -y install subversion 

2.創建SVN庫

依次執行如下命令。

#創建/data/svn
mkdir -p /data/svn 
#初始化svn
svnserve -d -r /data/svn
#創建代碼倉庫
svnadmin create /data/svn/test

3.配置SVN

mkdir /data/svn/conf
cp /data/svn/test/conf/* /data/svn/conf/
cd /data/svn/conf/
[root@binghe101 conf]# ll
總用量 20
-rw-r--r-- 1 root root 1080 5月  12 02:17 authz
-rw-r--r-- 1 root root  885 5月  12 02:17 hooks-env.tmpl
-rw-r--r-- 1 root root  309 5月  12 02:17 passwd
-rw-r--r-- 1 root root 4375 5月  12 02:17 svnserve.conf

配置authz文件,

vim authz

配置后的內容如下所示。

[aliases]
# joe = /C=XZ/ST=Dessert/L=Snake City/O=Snake Oil, Ltd./OU=Research Institute/CN=Joe Average

[groups]
# harry_and_sally = harry,sally
# harry_sally_and_joe = harry,sally,&joe
SuperAdmin = admin
binghe = admin,binghe

# [/foo/bar]
# harry = rw
# &joe = r
# * =

# [repository:/baz/fuz]
# @harry_and_sally = rw
# * = r

[test:/]
@SuperAdmin=rw
@binghe=rw

配置passwd文件

vim passwd

配置后的內容如下所示。

[users]
# harry = harryssecret
# sally = sallyssecret
admin = admin123
binghe = binghe123

配置 svnserve.conf

vim svnserve.conf

配置后的文件如下所示。

### This file controls the configuration of the svnserve daemon, if you
### use it to allow access to this repository.  (If you only allow
### access through http: and/or file: URLs, then this file is
### irrelevant.)

### Visit http://subversion.apache.org/ for more information.

[general]
### The anon-access and auth-access options control access to the
### repository for unauthenticated (a.k.a. anonymous) users and
### authenticated users, respectively.
### Valid values are "write", "read", and "none".
### Setting the value to "none" prohibits both reading and writing;
### "read" allows read-only access, and "write" allows complete 
### read/write access to the repository.
### The sample settings below are the defaults and specify that anonymous
### users have read-only access to the repository, while authenticated
### users have read and write access to the repository.
anon-access = none
auth-access = write
### The password-db option controls the location of the password
### database file.  Unless you specify a path starting with a /,
### the file's location is relative to the directory containing
### this configuration file.
### If SASL is enabled (see below), this file will NOT be used.
### Uncomment the line below to use the default password file.
password-db = /data/svn/conf/passwd
### The authz-db option controls the location of the authorization
### rules for path-based access control.  Unless you specify a path
### starting with a /, the file's location is relative to the
### directory containing this file.  The specified path may be a
### repository relative URL (^/) or an absolute file:// URL to a text
### file in a Subversion repository.  If you don't specify an authz-db,
### no path-based access control is done.
### Uncomment the line below to use the default authorization file.
authz-db = /data/svn/conf/authz
### The groups-db option controls the location of the file with the
### group definitions and allows maintaining groups separately from the
### authorization rules.  The groups-db file is of the same format as the
### authz-db file and should contain a single [groups] section with the
### group definitions.  If the option is enabled, the authz-db file cannot
### contain a [groups] section.  Unless you specify a path starting with
### a /, the file's location is relative to the directory containing this
### file.  The specified path may be a repository relative URL (^/) or an
### absolute file:// URL to a text file in a Subversion repository.
### This option is not being used by default.
# groups-db = groups
### This option specifies the authentication realm of the repository.
### If two repositories have the same authentication realm, they should
### have the same password database, and vice versa.  The default realm
### is repository's uuid.
realm = svn
### The force-username-case option causes svnserve to case-normalize
### usernames before comparing them against the authorization rules in the
### authz-db file configured above.  Valid values are "upper" (to upper-
### case the usernames), "lower" (to lowercase the usernames), and
### "none" (to compare usernames as-is without case conversion, which
### is the default behavior).
# force-username-case = none
### The hooks-env options specifies a path to the hook script environment 
### configuration file. This option overrides the per-repository default
### and can be used to configure the hook script environment for multiple 
### repositories in a single file, if an absolute path is specified.
### Unless you specify an absolute path, the file's location is relative
### to the directory containing this file.
# hooks-env = hooks-env

[sasl]
### This option specifies whether you want to use the Cyrus SASL
### library for authentication. Default is false.
### Enabling this option requires svnserve to have been built with Cyrus
### SASL support; to check, run 'svnserve --version' and look for a line
### reading 'Cyrus SASL authentication is available.'
# use-sasl = true
### These options specify the desired strength of the security layer
### that you want SASL to provide. 0 means no encryption, 1 means
### integrity-checking only, values larger than 1 are correlated
### to the effective key length for encryption (e.g. 128 means 128-bit
### encryption). The values below are the defaults.
# min-encryption = 0
# max-encryption = 256

接下來,將/data/svn/conf目錄下的svnserve.conf文件復制到/data/svn/test/conf/目錄下。如下所示。

[root@binghe101 conf]# cp /data/svn/conf/svnserve.conf /data/svn/test/conf/
cp:是否覆蓋'/data/svn/test/conf/svnserve.conf'? y

4.啟動SVN服務

(1)創建svnserve.service服務

創建svnserve.service文件

vim /usr/lib/systemd/system/svnserve.service

文件的內容如下所示。

[Unit]
Description=Subversion protocol daemon
After=syslog.target network.target
Documentation=man:svnserve(8)

[Service]
Type=forking
EnvironmentFile=/etc/sysconfig/svnserve
#ExecStart=/usr/bin/svnserve --daemon --pid-file=/run/svnserve/svnserve.pid $OPTIONS
ExecStart=/usr/bin/svnserve --daemon $OPTIONS
PrivateTmp=yes

[Install]
WantedBy=multi-user.target

接下來執行如下命令使配置生效。

systemctl daemon-reload

命令執行成功后,修改 /etc/sysconfig/svnserve 文件。

vim /etc/sysconfig/svnserve 

修改后的文件內容如下所示。

# OPTIONS is used to pass command-line arguments to svnserve.
# 
# Specify the repository location in -r parameter:
OPTIONS="-r /data/svn"

(2)啟動SVN

首先查看SVN狀態,如下所示。

[root@test10 conf]# systemctl status svnserve.service
● svnserve.service - Subversion protocol daemon
   Loaded: loaded (/usr/lib/systemd/system/svnserve.service; disabled; vendor preset: disabled)
   Active: inactive (dead)
     Docs: man:svnserve(8)

可以看到,此時SVN并沒有啟動,接下來,需要啟動SVN。

systemctl start svnserve.service

設置SVN服務開機自啟動。

systemctl enable svnserve.service

接下來,就可以下載安裝TortoiseSVN,輸入鏈接svn://192.168.0.10/test 并輸入用戶名binghe,密碼binghe123來連接SVN了。

Docker安裝SVN

拉取SVN鏡像

docker pull docker.io/elleflorio/svn-server

啟動SVN容器

docker run -v /usr/local/svn:/home/svn -v /usr/local/svn/passwd:/etc/subversion/passwd -v /usr/local/apache2:/run/apache2 --name svn_server -p 3380:80 -p 3690:3960 -e SVN_REPONAME=repos -d docker.io/elleflorio/svn-server

進入SVN容器內部

docker exec -it svn_server bash

進入容器后,可以參照物理機安裝SVN的方式配置SVN倉庫。

物理機安裝Jenkins

注意:安裝Jenkins之前需要安裝JDK和Maven,我這里同樣將Jenkins安裝在Master節點(binghe101服務器)。

1.啟用Jenkins庫

運行以下命令以下載repo文件并導入GPG密鑰:

wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat-stable/jenkins.repo
rpm --import https://jenkins-ci.org/redhat/jenkins-ci.org.key

2.安裝Jenkins

執行如下命令安裝Jenkis。

yum install jenkins

接下來,修改Jenkins默認端口,如下所示。

vim /etc/sysconfig/jenkins

修改后的兩項配置如下所示。

JENKINS_JAVA_CMD="/usr/local/jdk1.8.0_212/bin/java"
JENKINS_PORT="18080"

此時,已經將Jenkins的端口由8080修改為18080

3.啟動Jenkins

在命令行輸入如下命令啟動Jenkins。

systemctl start jenkins

配置Jenkins開機自啟動。

systemctl enable jenkins

查看Jenkins的運行狀態。

[root@test10 ~]# systemctl status jenkins
● jenkins.service - LSB: Jenkins Automation Server
   Loaded: loaded (/etc/rc.d/init.d/jenkins; generated)
   Active: active (running) since Tue 2020-05-12 04:33:40 EDT; 28s ago
     Docs: man:systemd-sysv-generator(8)
    Tasks: 71 (limit: 26213)
   Memory: 550.8M

說明,Jenkins啟動成功。

配置Jenkins運行環境

1.登錄Jenkins

首次安裝后,需要配置Jenkins的運行環境。首先,在瀏覽器地址欄訪問鏈接http://192.168.0.10:18080,打開Jenkins界面。

根據提示使用如下命令到服務器上找密碼值,如下所示。

[root@binghe101 ~]# cat /var/lib/jenkins/secrets/initialAdminPassword
71af861c2ab948a1b6efc9f7dde90776

將密碼71af861c2ab948a1b6efc9f7dde90776復制到文本框,點擊繼續。會跳轉到自定義Jenkins頁面,如下所示。

這里,可以直接選擇“安裝推薦的插件”。之后會跳轉到一個安裝插件的頁面,如下所示。

此步驟可能有下載失敗的情況,可直接忽略。

2.安裝插件

需要安裝的插件

  • Kubernetes Cli Plugin:該插件可直接在Jenkins中使用kubernetes命令行進行操作。
  • Kubernetes plugin: 使用kubernetes則需要安裝該插件Kubernetes
  • Continuous Deploy Plugin:kubernetes部署插件,可根據需要使用

還有更多的插件可供選擇,可點擊 系統管理->管理插件進行管理和添加,安裝相應的Docker插件、SSH插件、Maven插件。其他的插件可以根據需要進行安裝。如下圖所示。

3.配置Jenkins

(1)配置JDK和Maven

在Global Tool Configuration中配置JDK和Maven,如下所示,打開Global Tool Configuration界面。

接下來就開始配置JDK和Maven了。

由于我在服務器上將Maven安裝在/usr/local/maven-3.6.3目錄下,所以,需要在“Maven 配置”中進行配置,如下圖所示。

接下來,配置JDK,如下所示。

注意:不要勾選“Install automatically”

接下來,配置Maven,如下所示。

注意:不要勾選“Install automatically”

(2)配置SSH

進入Jenkins的Configure System界面配置SSH,如下所示。

找到 SSH remote hosts 進行配置。

配置完成后,點擊Check connection按鈕,會顯示 Successfull connection。如下所示。

至此,Jenkins的基本配置就完成了。

Jenkins發布Docker項目到K8s集群

1.調整SpringBoot項目的配置

實現,SpringBoot項目中啟動類所在的模塊的pom.xml需要引入打包成Docker鏡像的配置,如下所示。

 <properties>
  	 	<docker.repostory>192.168.0.10:1180</docker.repostory>
        <docker.registry.name>test</docker.registry.name>
        <docker.image.tag>1.0.0</docker.image.tag>
        <docker.maven.plugin.version>1.4.10</docker.maven.plugin.version>
  </properties>

<build>
  		<finalName>test-starter</finalName>
		<plugins>
            <plugin>
			    <groupId>org.springframework.boot</groupId>
			    <artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
			
			<!-- docker的maven插件,官網:https://github.com/spotify/docker‐maven‐plugin -->
			<!-- Dockerfile maven plugin -->
			<plugin>
			    <groupId>com.spotify</groupId>
			    <artifactId>dockerfile-maven-plugin</artifactId>
			    <version>${docker.maven.plugin.version}</version>
			    <executions>
			        <execution>
			        <id>default</id>
			        <goals>
			            <!--如果package時不想用docker打包,就注釋掉這個goal-->
			            <goal>build</goal>
			            <goal>push</goal>
			        </goals>
			        </execution>
			    </executions>
			    <configuration>
			    	<contextDirectory>${project.basedir}</contextDirectory>
			        <!-- harbor 倉庫用戶名及密碼-->
			        <useMavenSettingsForAuth>useMavenSettingsForAuth>true</useMavenSettingsForAuth>
			        <repository>${docker.repostory}/${docker.registry.name}/${project.artifactId}</repository>
			        <tag>${docker.image.tag}</tag>
			        <buildArgs>
			            <JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
			        </buildArgs>
			    </configuration>
			</plugin>

        </plugins>
        
		<resources>
			<!-- 指定 src/main/resources下所有文件及文件夾為資源文件 -->
			<resource>
				<directory>src/main/resources</directory>
				<targetPath>${project.build.directory}/classes</targetPath>
				<includes>
					<include>**/*</include>
				</includes>
				<filtering>true</filtering>
			</resource>
		</resources>
	</build>

接下來,在SpringBoot啟動類所在模塊的根目錄創建Dockerfile,內容示例如下所示。

#添加依賴環境,前提是將Java8的Docker鏡像從官方鏡像倉庫pull下來,然后上傳到自己的Harbor私有倉庫中
FROM 192.168.0.10:1180/library/java:8
#指定鏡像制作作者
MAINTAINER binghe
#運行目錄
VOLUME /tmp
#將本地的文件拷貝到容器
ADD target/*jar app.jar
#啟動容器后自動執行的命令
ENTRYPOINT [ "java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/app.jar" ]

根據實際情況,自行修改。

注意:FROM 192.168.0.10:1180/library/java:8的前提是執行如下命令。

docker pull java:8
docker tag java:8 192.168.0.10:1180/library/java:8
docker login 192.168.0.10:1180
docker push 192.168.0.10:1180/library/java:8

在SpringBoot啟動類所在模塊的根目錄創建yaml文件,錄入叫做test.yaml文件,內容如下所示。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: test-starter
  labels:
    app: test-starter
spec:
  replicas: 1
  selector:
    matchLabels:
      app: test-starter
  template:
    metadata:
      labels:
        app: test-starter
    spec:
      containers:
      - name: test-starter
        image: 192.168.0.10:1180/test/test-starter:1.0.0
        ports:
        - containerPort: 8088
      nodeSelector:
        clustertype: node12

---
apiVersion: v1
kind: Service
metadata:
  name: test-starter
  labels:
    app: test-starter
spec:
  ports:
    - name: http
      port: 8088
      nodePort: 30001
  type: NodePort
  selector:
    app: test-starter

2.Jenkins配置發布項目

將項目上傳到SVN代碼庫,例如地址為svn://192.168.0.10/test

接下來,在Jenkins中配置自動發布。步驟如下所示。

點擊新建Item。

在描述文本框中輸入描述信息,如下所示。

接下來,配置SVN信息。

注意:配置GitLab的步驟與SVN相同,不再贅述。

定位到Jenkins的“構建模塊”,使用Execute Shell來構建發布項目到K8S集群。

執行的命令依次如下所示。

#刪除本地原有的鏡像,不會影響Harbor倉庫中的鏡像
docker rmi 192.168.0.10:1180/test/test-starter:1.0.0
#使用Maven編譯、構建Docker鏡像,執行完成后本地Docker容器中會重新構建鏡像文件
/usr/local/maven-3.6.3/bin/mvn -f ./pom.xml clean install -Dmaven.test.skip=true
#登錄 Harbor倉庫
docker login 192.168.0.10:1180 -u binghe -p Binghe123
#上傳鏡像到Harbor倉庫
docker push 192.168.0.10:1180/test/test-starter:1.0.0
#停止并刪除K8S集群中運行的
/usr/bin/kubectl delete -f test.yaml
#將Docker鏡像重新發布到K8S集群
/usr/bin/kubectl apply -f test.yaml

到此這篇關于基于Docker+K8S+GitLab/SVN+Jenkins+Harbor搭建持續集成交付環境(環境搭建篇)的文章就介紹到這了,更多相關docker K8S持續集成交付環境內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持腳本之家!

標簽:朝陽 隴南 雞西 運城 連云港 遵義 面試通知 荊門

巨人網絡通訊聲明:本文標題《基于Docker+K8S+GitLab/SVN+Jenkins+Harbor搭建持續集成交付環境的詳細教程》,本文關鍵詞  基于,Docker+K8S+GitLab,SVN+Jenkins+Harbor,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《基于Docker+K8S+GitLab/SVN+Jenkins+Harbor搭建持續集成交付環境的詳細教程》相關的同類信息!
  • 本頁收集關于基于Docker+K8S+GitLab/SVN+Jenkins+Harbor搭建持續集成交付環境的詳細教程的相關信息資訊供網民參考!
  • 推薦文章
    主站蜘蛛池模板: 塑料机械 有限公司| 大连东拓工程机械制造有限公司| 昆山铁生机械有限公司| 东莞市华森重工有限公司 | 杭州精密机械有限公司| 江苏双轮泵业机械制造有限公司| 济南机械设备有限公司| 西安 机械设备有限公司| 台州宏汇机械有限公司| 江苏双箭输送机械有限公司| 江苏利普机械有限公司| 海宁市腾达机械有限公司| 豫工机械设备有限公司 | 卓郎智能机械有限公司| 食品机械制造有限公司| 荣精密机械有限公司| 宁波拓诚机械有限公司| 济南升降机械有限公司| 青岛橡胶机械有限公司| 江阴市华科机械设备有限公司| 浙江达青机械有限公司| 佛山市永盛达机械有限公司| 重庆工程机械有限公司| 昆山贝奇精密机械有限公司 | 江源机械制造有限公司| 深圳步先包装机械有限公司| 山东龙起重工有限公司| 上海远跃制药机械有限公司 | 河北输送机械有限公司| 重庆宏工工程机械有限公司| 扬州中孚机械有限公司| 江西省机械有限公司| 吉林小松工程机械有限公司| 上海合升机械有限公司| 山东机械设备有限公司怎么样| 山东硕诚机械有限公司| 德阳 机械有限公司| 山西海威钢铁有限公司| 江苏华澄重工有限公司| 广州金本机械设备有限公司| 昆山大风机械有限公司| 新乡市海纳筛分机械制造有限公司| 杭州纳源传动机械有限公司| 苏州精锐精密机械有限公司| 精一机械(中山)有限公司| 郑州重型机械有限公司| 万杰食品机械有限公司| 北京恒机械有限公司| 保定东利机械制造有限公司| 廊坊机械设备有限公司| 广州金宗机械有限公司| 郑州志乾机械设备有限公司| 星塔机械深圳有限公司| 江苏中热机械设备有限公司怎么样| 东莞大禹机械有限公司| 沈阳瑞熠机械有限公司| 佛山精密机械有限公司| 山西万泽锦达机械制造有限公司| 苏州荣业机械有限公司| 河南省矿山起重机制造有限公司| 上海凌鹰机械有限公司| 临沂大阳通用机械有限公司| 德锐尔机械有限公司| 山东精密机械有限公司| 固精密机械有限公司| 山东神力起重机械有限公司| 山东碧海机械有限公司| 咸阳经纬纺织机械有限公司| 扬州禹笑水利机械有限公司| 东莞智荣机械有限公司| 佛山松川机械设备有限公司| 山东数控机械有限公司| 扬州伏尔坎机械制造有限公司 | 全椒 机械有限公司| 深圳市铭利达精密机械有限公司| 郑州万谷机械有限公司| 苏州博机械有限公司| 浙江双畅起重机械有限公司| 洛阳工程机械有限公司| 杭州宏展机械有限公司| 河南工程机械有限公司| 浙江仁工机械有限公司| 印刷包装机械有限公司| 上海山威路桥机械有限公司| 江西蓝翔重工有限公司| 山东润通机械制造有限公司| 中核华兴达丰机械工程有限公司 | 广州九盈机械有限公司| 青岛 塑料机械有限公司| 浙江森工木工机械有限公司| 招远矿山机械有限公司| 武汉萱裕机械有限公司| 湖南嘉龙机械设备贸易有限公司| 安徽永成电子机械技术有限公司| 宁江精密机械有限公司| 上海传动机械有限公司| 首钢长治钢铁有限公司地址| 上海信烨精密机械有限公司| 沈阳三重机械有限公司| 山东枭隆机械有限公司| 泉州市恒兴工业机械有限公司| 上海淘乐机械有限公司| 江苏国瑞液压机械有限公司| 科尼起重机设备(上海)有限公司| 常州化工机械有限公司| 马鞍山 机械有限公司| 重的机械有限公司招聘| 章丘市机械有限公司| 青岛诺机械有限公司| 唐山市钢铁有限公司| 安微博达重工有限公司| 浙江传动机械有限公司| 河北永明地质工程机械有限公司| 海狮洗涤机械有限公司| 苏州朗威电子机械有限公司| 常州机械制造有限公司| 太原重工轨道交通设备有限公司 | 威海环宇化工机械有限公司| 山东临工工程机械有限公司招聘| 东元精密机械有限公司| 浙江雄鹏机械有限公司| 重庆红江机械有限公司| 沂水巨龙机械有限公司| 广州日森机械有限公司| 无锡兆立精密机械有限公司| 广西徐重机械有限公司| 淄博捷达机械有限公司| 上海盟申机械设备有限公司| 龙口中宇机械有限公司| 上海贝得尔石化机械设备有限公司 | 湖南运想重工有限公司| 上海德托机械有限公司| 自动化机械设备有限公司| 天津市仁翼钢铁有限公司| 宁波星峰机械有限公司| 济南铭机械有限公司| 河南万杰食品机械有限公司| 宇进注塑机械有限公司| 桂林中天机械有限公司| 长沙中南福鼎机械设备有限公司| 江苏华光双顺机械制造有限公司| 杭州春江制药机械有限公司| 济南欧亚德数控机械有限公司 | 遵化建龙钢铁有限公司| 北方机械制造有限公司| 山东博精化工机械有限公司| 厦门宇龙机械有限公司| 台湾精密机械有限公司| 南通牧野机械有限公司| 常州工程机械有限公司| 深圳华盛昌机械实业有限公司| 上海捷赛机械有限公司| 重庆动力机械有限公司| 山东金大丰机械有限公司| 温州佳诚机械有限公司| 上海乾承机械设备有限公司 | 南通密炼捏合机械有限公司| 有限公司发起人协议| 江西为民机械有限公司| 金鹰重型工程机械有限公司| 浙江陀曼精密机械有限公司 | 江苏苏盐阀门机械有限公司| 苏州纺织机械有限公司| 上海申德机械有限公司| 哈尔滨纳诺机械设备有限公司 | 新乡市佳盛振动机械有限公司| 成都兴业邦达重工机械有限公司 | 河南人从众机械制造有限公司| 常州豪凯机械有限公司| 山西太行钢铁有限公司| 常州儒邦机械有限公司| 佛山市信虹精密机械有限公司 | 东莞市森佳机械有限公司| 河北鑫晟德农业机械制造有限公司 | 武汉包装机械有限公司| 江阴市三 机械有限公司| 江苏坤泰机械有限公司| 武汉格瑞拓机械有限公司| 赛柏精密机械有限公司| 章丘丰源机械有限公司| 青岛如隆机械有限公司| 广西利维重工有限公司| 常州 重工有限公司| 常州包装机械有限公司| 郑州永兴重工机械有限公司| 东莞市森人机械有限公司| 青州三和机械有限公司| 杭州亿安机械设备有限公司| 武汉纵能机械制造有限公司| 浙江亿森机械有限公司| 法麦凯尼柯机械有限公司| 无锡九明机械有限公司| 浙江超洋机械有限公司| 东莞市泽源机械有限公司| 上海沛愉机械制造有限公司| 诸城市美川机械有限公司| 广州联冠机械有限公司| 杭州容瑞机械技术有限公司| 荣精密机械有限公司| 上海达和荣艺包装机械有限公司| 嘉善远景机械有限公司| 恒兴机械设备有限公司| 山东鲁樽机械有限公司| 济南迈动数控机械有限公司| 上海信进精密机械有限公司| 青岛木业机械有限公司| 常州昊博机械有限公司| 德州佳永机械制造有限公司| 滨州市机械有限公司| 张家港市机械制造有限公司| 沈阳六合机械有限公司| 荣龙精密机械有限公司| 芜湖电工机械有限公司| 戴氏印刷机械有限公司| 嘉兴机械有限公司招聘| 郑州 机械 有限公司| 苏州工业园区嘉宝精密机械有限公司 | 滁州富达机械电子有限公司| 沂水阳东机械有限公司| 辽宁天一重工有限公司| 昆山拓可机械有限公司| 杭州宏展机械有限公司| 盐城三益石化机械有限公司| 唐山荣程钢铁有限公司| 上海三都机械有限公司| 诚泰精密机械有限公司| 苏州精锐精密机械有限公司| 射阳 机械有限公司| 烟台绿林机械设备制造有限公司| 上海山启机械制造有限公司| 北京航天振邦精密机械有限公司 | 杭州山虎机械有限公司| 浙江双鸟机械有限公司| 诸城市铭威食品机械有限公司 | 中热机械设备有限公司| 石家庄米兹机械设备有限公司 | 东莞 机械有限公司| 山东欣弘发机械有限公司| 泉州工程机械有限公司| 大连 机械有限公司| 武汉钢铁有限公司疫情| 深圳市机械设备有限公司| 临工金利机械有限公司| 安徽 机械制造有限公司| 东莞市英豪机械有限公司| 均强机械苏州有限公司| 广东食品机械有限公司| 重庆信鼎精密机械有限公司| 杭州方圆塑料机械有限公司| 江苏莱宝机械制造有限公司| 江苏鹤溪机械有限公司| 瑞特精密机械有限公司| 陕西通运机械有限公司| 东莞市金联吹塑机械有限公司 | 上海恒启机械设备有限公司| 中原圣起起重机械有限公司| 温州镇田机械有限公司| 大连机械设备有限公司| 南京起重机械总厂有限公司| 济南机械设备有限公司| 新疆昆玉钢铁有限公司| 郑州华宏机械设备有限公司| 江苏科力机械有限公司| 东莞信易电热机械有限公司| 建筑工程有限公司起名| 无锡邦得机械有限公司| 南京工程机械有限公司| 安徽威萨重工机械有限公司| 济南金胜星机械设备有限公司| 德阳机械制造有限公司| 常州万裕机械有限公司| 四川沱江起重机有限公司 | 上海 机械 有限公司| 恩德特机械(苏州)有限公司| 山东精密机械有限公司| 江西平起实业有限公司| 青岛博朗特机械设备有限公司| 无锡旭辉机械有限公司| 中天印刷机械有限公司| 山东银鹰炊事机械有限公司| 昆山 机械设备有限公司| 中船重工环境工程有限公司怎么样 | 山东山鼎工程机械有限公司| 太平洋机械有限公司| 中山中炬精工机械有限公司| 南京寿旺机械设备有限公司| 重庆爱扬机械有限公司| 特雷克斯常州机械有限公司| 溧阳市机械有限公司| 上海久协机械设备有限公司| 蚌埠液力机械有限公司| 亿传玻璃机械有限公司| 东莞市恩必信塑胶机械有限公司 | 安徽宏远机械制造有限公司| 阿特拉斯机械设备有限公司| 青岛奥威机械有限公司| 无锡锡科机械制造有限公司| 芜湖中安重工自动化装备有限公司 | 武汉餐至饮机械设备有限公司| 茂名重力石化机械制造有限公司| 苏州松博机械有限公司| 烟台拓伟机械有限公司| 甘肃机械化建设工程有限公司| 山东联亿重工有限公司| 云南昆鼎机械设备有限公司| 阜新恒泰机械有限公司| 上海铁杉机械有限公司| 天津聚鑫贵泽钢铁贸易有限公司| 浙江仁工机械有限公司| 上海 鑫机械设备有限公司| 重庆洲泽机械制造有限公司| 宝鸡至信机械有限公司| 输送机械设备有限公司| 河北太行机械工业有限公司| 浙江锦峰纺织机械有限公司| 新乡高服机械有限公司| 唐河大华机械有限公司| 临沂江鑫钢铁有限公司| 晋江机械制造有限公司| 温州博大机械有限公司| 浙江炬达机械有限公司| 旭海机械设备有限公司| 四平红嘴钢铁有限公司| 淄博 机械设备有限公司| 宁海奇精机械有限公司| 京西重工上海有限公司| 唐山市德龙钢铁有限公司| 临沂胜代机械有限公司| 齐齐哈尔机械有限公司| 苏州威邦自动化机械有限公司| 青岛南牧机械设备有限公司| 张家港市通惠化工机械有限公司| 江苏华雕机械有限公司| 绵阳新晨动力机械有限公司| 沈阳西城钢铁有限公司| 苏州勤堡精密机械有限公司| 汽车销售有限公司起名| 上海威士机械有限公司| 江苏银河机械有限公司| 广州科盛隆纸箱包装机械有限公司| 杭州西子重工有限公司| 东莞巨冈机械有限公司| 杭州亿安机械设备有限公司| 江苏昆仲机械有限公司| 临广电气机械有限公司| 浙江盾安机械有限公司| 长江液压机械有限公司| 衡阳纺织机械有限公司| 吉首市中诚制药机械有限公司 | 江阴化工机械有限公司| 山东杰卓机械有限公司| 招远市矿山机械有限公司| 济南恒迪机械有限公司| 山东精密机械有限公司| 浙江永创机械有限公司| 无锡市钢铁有限公司| 上海光华印刷机械有限公司| 汉中群峰机械制造有限公司| 威海坤豪机械有限公司| 比力特机械有限公司| 昆山大风机械有限公司| 江苏华光双顺机械制造有限公司| 上海板换机械设备有限公司| 张家港市贝尔机械有限公司| 丰机械有限公司怎么样| 宁波凯特机械有限公司| 重庆春仁机械有限公司| 泰兴机械制造有限公司| 河南真牛起重机有限公司| 苏州鼎木机械设备有限公司 | 汕头机械厂有限公司| 东莞市业佳精密机械有限公司| 泉州恒泉机械有限公司| 杭州博阳机械有限公司| 郑州中嘉重工有限公司| 苏州爱恩机械有限公司| 昆山烽禾升精密机械有限公司| 瑞安市机械制造有限公司| 南通图海机械有限公司| 上海大松机械有限公司| 深圳电子机械有限公司| 曲阜机械设备有限公司| 浙江达青机械有限公司| 中铁重工有限公司武汉| 河北航天振邦精密机械有限公司| 山东首钢钢铁贸易有限公司| 浙江隆信机械制造有限公司| 佛山市钢铁有限公司| 徐工重型机械有限公司| 合肥春华起重机械有限公司 | 徐州世通重工机械制造有限公司| 上海机械进出口有限公司| 雷州雷宝机械有限公司| 上海宝日机械制造有限公司| 渭南金狮机械有限公司| 浙江传动机械有限公司| 安徽金龙机械有限公司| 温岭市大众精密机械有限公司| 海盐鼎盛机械有限公司| 西安鸿运机械有限公司| 旭能机械制造有限公司| 唐山鑫鑫钢铁有限公司| 广东富华重工制造有限公司| 北京洛克机械有限公司| 河北华昌机械设备有限公司 | 上海鑫水机械有限公司| 四平方向机械有限公司| 重庆维庆液压机械有限公司| 江苏聚丰园林机械有限公司| 泉州市机械有限公司| 河北太行机械工业有限公司| 永兴机械设备有限公司| 宁波旭升机械有限公司| 常州奥恒机械有限公司| 江苏江南起重机械有限公司| 青岛吉瑞特机械制造有限公司| 北京机械租赁有限公司| 江苏中热机械设备有限公司| 卓郎智能机械有限公司| 上海沪临重工有限公司| 张家港市贝尔机械有限公司| 山东博杰重型工程机械有限公司| 郑州市同鼎机械设备有限公司| 河南奥创机械设备有限公司| 福建机械设备有限公司| 石家庄工程机械有限公司| 邢台机械轧辊有限公司| 江苏红旗印染机械有限公司| 北京洛克机械有限公司| 重庆墨龙机械有限公司| 江苏海豚船舶机械有限公司| 上海德珂斯机械自动化技术有限公司 | 山西高义钢铁有限公司| 新乡市东振机械制造有限公司 | 安丰钢铁有限公司电话| 江苏正兴建设机械有限公司| 常州汤姆包装机械有限公司| 江苏贸隆机械制造有限公司| 沈阳西城钢铁有限公司| 合肥逸飞包装机械有限公司| 徐州天地重型机械制造有限公司| 富华重工有限公司老板| 天津 机械设备有限公司| 长沙机械与制造有限公司| 中交天和机械设备制造有限公司| 威海环宇化工机械有限公司| 如东宏信机械制造有限公司| 上海敏杰机械有限公司| 江苏冶金机械有限公司| 佛山市液压机械有限公司| 保定市机械制造有限公司| 江苏江成机械有限公司| 上海机械工程有限公司| 滕州市美力机械有限公司| 河南明天机械有限公司| 起步有限公司上市排名| 南京三友机械有限公司| 泰而勒食品机械贸易(上海)有限公司 | 东莞市宝腾机械有限公司| 广州领新机械实业有限公司| 天津瑞星传动机械有限公司| 上海澳昊机械制造有限公司| 九江萍钢钢铁有限公司电话| 顺昌机械制造有限公司| 河北德林机械有限公司| 天津包装机械有限公司| 南京创力传动机械有限公司| 龙扬机械)有限公司| 嘉兴机械设备有限公司| 青岛纺织机械有限公司| 阳春市新钢铁有限公司| 南通路捷机械有限公司| 郑州鑫宇机械制造有限公司| 福建信达机械有限公司| 江西台鑫钢铁有限公司| 山东重工机械有限公司| 咸阳经纬纺织机械有限公司| 柳州瑞利机械有限公司| 中海福陆重工有限公司| 江苏银华春翔机械制造有限公司 | 河北永明地质工程机械有限公司| 杭州杭达机械有限公司| 大连孚德机械有限公司| 苏州通润机械铸造有限公司| 浙江瑞浦机械有限公司| 烟台金元矿业机械有限公司| 天津千百顺钢铁贸易有限公司| 江苏霸马机械有限公司| 常州双鸟起重机械有限公司| 长城机械制造有限公司| 起重机械制造有限公司| 合肥康恒机械有限公司| 常熟神马机械有限公司| 宁波裕民机械工业有限公司 | 有限公司发起人协议| 南通力威机械有限公司| 东莞%机械制造有限公司| 北京盛美食品机械有限公司| 漳州震东机械有限公司| 山东莱工机械制造有限公司| 江阴市祥达机械制造有限公司| 安徽泰源工程机械有限公司| 东方液压机械有限公司| 连云港市机械有限公司| 浙江建机工程机械有限公司| 河南铁山起重设备有限公司| 航星洗涤机械(泰州)有限公司| 河南启瀚机械设备有限公司| 深圳新添润彩印机械设备有限公司| 温州镇田机械有限公司| 招远市矿山机械有限公司| 东营嘉信机械有限公司| 山东大汉建设机械有限公司| 徐州福曼随车起重机有限公司| 安徽工程机械有限公司| 深圳创能机械有限公司| 浙江华球机械制造有限公司 | 北京液压机械有限公司| 重庆钢实机械有限公司| 潍坊华耀磁电机械有限公司 | 苏州丰裕机械工程有限公司| 常德三一机械有限公司| 河南机械制造有限公司| 博硕机械制造有限公司| 佶缔纳士机械有限公司| 台州启运机械有限公司| 浙江康明斯机械有限公司| 云南昆鼎机械设备有限公司| 宁波博日机械有限公司| 潍坊机械设备有限公司| 爱可机械深圳有限公司| 济南包装机械械有限公司| 西安飞鸿机械有限公司| 捷赛机械苏州有限公司| 上海瑞阳机械有限公司| 宣威凤凰钢铁有限公司| 辽阳喜旺机械制造有限公司| 烟台鼎科机械有限公司| 扬州 液压机械有限公司| 新乡市辰威机械有限公司| 青岛德盛机械制造有限公司| 约翰迪尔佳木斯农业机械有限公司| 青岛机械制造有限公司| 张家港精密机械有限公司| 昆山协扬机械有限公司| 鞍山机械重工有限公司| 河南力神机械有限公司| 台州 精密机械有限公司| 中山冠力机械有限公司| 东莞市沃德精密机械有限公司| 东莞市联顺机械有限公司| 佛山市 重工有限公司| 郑州华隆机械有限公司| 河北普阳钢铁有限公司| 常州超通机械有限公司| 重庆 机械有限公司| 诺尔起重设备有限公司| 江苏仁达机械有限公司怎么样| 厦门船舶重工有限公司| 广西机械制造有限公司| 荏原机械烟台有限公司| 禹州市机械有限公司| 温州锐光机械有限公司| 陕西至信机械制造有限公司怎么样 | 上海剑豪传动机械有限公司| 苏州机械设备有限公司| 杭州定江机械有限公司| 上海众星洗涤机械制造有限公司 | 青岛塑料机械有限公司| 徐州彭贝机械制造有限公司| 山东工大机械有限公司| 长沙建鑫机械有限公司| 青岛机械设备有限公司| 常德烟草机械有限公司| 阿特拉斯工程机械有限公司| 青岛诺机械有限公司| 南京惠德机械有限公司| 佛山市创利宝包装机械有限公司| 唐山 机械设备有限公司| 临沂盖氏机械有限公司| 上海西马特制药机械有限公司| 杭州嘉诚机械有限公司| 振华真空机械有限公司| 青岛木工机械有限公司| 宁波利豪机械有限公司| 玉环宝捷机械有限公司| 嘉兴机械制造有限公司| 正扬电子机械有限公司| 上海牛力机械有限公司| 压机械制造有限公司| 中山力劲机械有限公司| 扬州凯勒机械有限公司| 大连东拓工程机械制造有限公司 | 苏州市恒升机械有限公司| 东莞市 机械有限公司| 石家庄嘉祥精密机械有限公司| 重庆驰骋机械有限公司| 上海创灵包装机械制造有限公司| 河北唐银钢铁有限公司| 长沙中京机械有限公司| 吴江迈锐机械有限公司怎么样| 重庆比德机械有限公司| 大连仁海重工有限公司| 无锡市阳通机械设备有限公司| 辽宁三君工程机械有限公司| 京山 机械有限公司| 天津天重江天重工有限公司| 上海昱庄机械有限公司| 上海保成机械有限公司| 富达机械制造有限公司| 陕西鑫钢机械有限公司| 南通 机械有限公司| 青岛新大成塑料机械有限公司 | 广州轻工机械有限公司| 东泰机械制造有限公司| 东莞市兆恒机械有限公司| 济南金迈达机械有限公司| 佛山市浩铭达机械制造有限公司| 郑州宇通重工有限公司| 罗源闽光钢铁有限公司| 上海中吉机械有限公司| 华通动力重工有限公司| 万兹莱压缩机械(上海)有限公司| 烟台海兰德机械设备有限公司| 临清 机械有限公司| 四川凌峰航空液压机械有限公司| 临海正大机械有限公司| 山东造纸机械厂有限公司| 佛山市洛德机械设备有限公司| 友隆精密机械有限公司| 嘉兴 精密机械有限公司| 南京华创包装机械设备有限公司| 福建巨邦机械有限公司| 西安帕吉特精密机械有限公司| 常州倍安特动力机械有限公司| 杭州灵达机械有限公司| 苏州鼎木机械设备有限公司 | 宁波迈拓斯数控机械有限公司| 杭州神钢建设机械有限公司| 上海捷舟工程机械有限公司| 三星重工业宁波有限公司招聘| 青岛西城铸造机械有限公司| 烟台海兰德机械设备有限公司| 河南启瀚机械设备有限公司| 瑞安市机械制造有限公司| 陕西柴油机重工有限公司| 江西机械设备有限公司| 山东金亿机械制造有限公司| 安徽鸿泰钢铁有限公司| 陆丰机械郑州有限公司| 振华真空机械有限公司| 昆山协扬机械有限公司| 德龙钢铁有限公司招聘| 烟台瑞进精密机械有限公司| 哈克农业机械装备制造有限公司| 佛山市万为包装机械有限公司 | 襄阳通威机械有限公司| 上海立帆机械有限公司| 上海展焱包装机械有限公司| 徐州荣阳钢铁有限公司| 昆明远桥机械有限公司| 南阳奇丰机械有限公司| 郑州华宏机械设备有限公司| 无锡沃利数控机械有限公司| 太仓悦凯精密机械有限公司| 山东泰力起重设备有限公司 | 龙口富元机械有限公司| 青岛广德机械有限公司| 定州宏远机械有限公司| 山东工程机械有限公司| 浙江志高机械有限公司| 北京印刷机械有限公司| 南京 机械制造有限公司| 无锡市浦尚精密机械有限公司| 潍坊华耀磁电机械有限公司| 河南德润钢铁有限公司| 好烤克食品机械有限公司| 杭州博阳机械有限公司| 三益精密机械有限公司| 湖南湘船重工有限公司| 台州万州机械有限公司| 塑料机械 有限公司| 苏州金德纬机械有限公司| 苏州君驰联动机械有限公司| 苏州雁达机械有限公司| 佛山新元机械有限公司| 常州制药机械有限公司| 舞钢中加钢铁有限公司| 无锡锡科机械制造有限公司| 绍兴联科机械有限公司| 佛山市创利宝包装机械有限公司| 昆山富邦机械有限公司| 苏州爱恩机械有限公司| 机械化工工程有限公司| 新乡市福泽机械设备有限公司| 创宝包装机械有限公司| 上海紫永机械有限公司| 东莞丰堡精密机械有限公司| 山东起重机械有限公司| 万则盛机械有限公司| 机械设计 有限公司| 徐州荣阳钢铁有限公司| 广西玉柴动力机械有限公司| 威马农业机械有限公司| 湖北 钢铁有限公司| 合心机械制造有限公司| 烟台拓伟机械有限公司| 烟台鼎科机械有限公司| 山东龙腾机械有限公司| 上海德机械设备有限公司| 无锡市川中五金机械有限公司| 北京富佳伟业机械制造有限公司| 科瑞森机械有限公司| 柳工常州机械有限公司| 合肥汉杰包装机械喷码有限公司 | 滨州市机械有限公司| 山东天龙机械有限公司| 江苏海豚船舶机械有限公司| 广东先达数控机械有限公司| 星 精密机械有限公司| 浙江隆信机械制造有限公司| 山东博宇机械有限公司| 青岛橡塑机械有限公司| 襄阳亚舟重型工程机械有限公司| 常州达德机械有限公司| 广东省建筑工程机械施工有限公司| 上海隆麦机械有限公司| 温州华推机械有限公司| 杭州中亚机械 有限公司| 机械有限公司起名大全| 河南三兄重工有限公司| 宜兴市华鼎机械有限公司| 永川海通机械有限公司| 宁波延晟机械有限公司| 盘锦 机械有限公司| 徐州斗山工程机械有限公司 | 亨内基机械上海有限公司| 杭州三普机械有限公司| 烟台金土源机械化工程有限公司| 迪威玻璃机械有限公司| 无锡纺织机械有限公司| 江苏迈安德食品机械有限公司 | 福州协展机械有限公司| 青岛晟森机械有限公司| 福建 机械有限公司| 江苏金梧机械有限公司| 洛阳震动机械有限公司| 河北坤达起重设备有限公司 | 广东马氏机械有限公司| 河北液压机械有限公司| 嘉兴市机械有限公司| 盐城三益石化机械有限公司 | 新兴重工天津国际贸易有限公司| 浙江华昌液压机械有限公司 | 福建鼎盛钢铁有限公司| 上海腾迈机械有限公司| 洛阳震动机械有限公司| 玉环万全机械有限公司| 新劲力机械有限公司| 河南黄河防爆起重机有限公司 | 徐州二川机械有限公司| 广州市 机械有限公司| 淄博中升机械有限公司| 工机械制造有限公司| 昆山瑞钧机械设备有限公司| 济南工程机械有限公司| 浙江勇力机械有限公司| 江苏包装机械有限公司| 广州金宗机械有限公司| 西安科迅机械制造有限公司| 绵阳新晨动力机械有限公司| 河北金维重工有限公司| 青州市远航机械设备有限公司| 苏州海骏自动化机械有限公司| 山东万力起重机械有限公司| 济宁机械制造有限公司| 上海星贝包装机械有限公司| 苏州工业园区嘉宝精密机械有限公司 | 浙江正信机械有限公司| 南通惠生重工有限公司| 南京竣业过程机械设备有限公司 | 奉化市机械有限公司| 成都固特机械有限公司| 无锡耀杰机械有限公司| 河北实阳机械有限公司| 中山市凌宇机械有限公司| 小松山东工程机械有限公司| 新乡市矿山起重机械有限公司 | 上海理贝包装机械有限公司| 马鞍山 重工机械有限公司| 青岛金福鑫塑料机械有限公司 | 上海浩勇精密机械有限公司| 广州市机械制造有限公司| 合肥永升机械有限公司| 潍坊圣旋机械有限公司| 桂林科丰机械有限公司| 江苏苏东机械有限公司| 宁波市北仑机械制造有限公司| 北京机械施工有限公司| 东莞市业佳精密机械有限公司| 泉州市恒兴工业机械有限公司| 山东腾机械有限公司| 三一汽车起重机械有限公司| 源田床具机械有限公司| 雄克精密机械有限公司| 苏州凯威塑料机械有限公司 | 晋江市机械有限公司| 江阴钢铁贸易有限公司| 湖南博长钢铁贸易有限公司| 徐州二川机械有限公司| 安徽唐兴机械装备有限公司| 苏州宇钻机械有限公司| 河北小松工程机械贸易有限公司 | 深圳美鹏机械设备有限公司| 广州田田机械设备有限公司| 河北实阳机械有限公司| 章丘市机械有限公司| 宜昌机械设备有限公司| 长沙三一重工有限公司| 青岛万邦包装机械有限公司| 盐城机械设备有限公司| 泰安市民乐机械制造有限公司 | 嘉兴扬鑫机械有限公司| 中安重工自动化装备有限公司| 上海福源机械有限公司| 上海科熙起重设备有限公司| 河北鑫晟机械有限公司| 大方起重机器有限公司| 长沙机械制造有限公司| 昆山 机械设备有限公司| 泰钢钢铁贸易有限公司| 张家口煤机械有限公司| 杭州液压机械有限公司| 山东塑机械有限公司| 杭州海的机械有限公司| 泰安机械有限公司招聘| 青岛胜代机械有限公司| 洛阳古城机械有限公司| 山东岳峰起重机械有限公司| 浙江晨雕机械有限公司| 浙江华昌液压机械有限公司 | 辽阳喜旺机械制造有限公司| 康铖机械设备有限公司| 新余钢铁厂有限公司| 上海众星洗涤机械制造有限公司| 福建起然燃气设备有限公司| 无锡博雅德精密机械有限公司| 江苏仁达机械有限公司| 江苏润明机械设备有限公司怎么样| 新疆 机械有限公司| 盐城丰炜机械制造有限公司| 济南 机械 有限公司| 郑州志乾机械设备有限公司| 北京食之秀机械设备有限公司| 太原 机械 有限公司| 郑州年旭机械有限公司| 青岛弗林斯曼机械制造有限公司| 哈尔滨恒力达机械有限公司| 上海佳成服装机械有限公司 | 信阳众泰机械设备有限公司| 济南耐刻机械设备有限公司 | 山东华伟重工机械有限公司| 福建海源机械有限公司| 常州博成机械有限公司| 浙江德鹏机械有限公司| 苏州日拓机械有限公司| 常德烟草机械有限公司| 河南北工机械制造有限公司| 广西中源机械有限公司| 常州市工程机械有限公司| 重庆有限公司 机械| 佛山市鹏轩机械制造有限公司 | 山东精密机械有限公司| 河南省浩业矿山机械有限公司| 常州华威起重工具有限公司| 无锡诺德传动机械有限公司| 沧州沧狮磨浆机械有限公司 | 上海西马特机械制造有限公司| 安庆恒昌机械有限公司| 大连矢岛机械有限公司| 沈阳鸿本机械有限公司| 武汉瑞威特机械有限公司 | 石油机械设备有限公司| 东莞市亚龙玻璃机械有限公司| 上海得力起重索具有限公司 | 上海板换机械设备有限公司| 常州数控机械有限公司| 山东正丰钢铁有限公司| 嘉兴瑞宏精密机械有限公司| 南通龙威机械有限公司| 浙江卓驰机械有限公司| 淮安机械制造有限公司| 华世丹机械有限公司| 广东顺发起重设备有限公司| 天津同力重工有限公司| 天津 津工机械有限公司| 上海昊宇机械有限公司| 东莞宏起塑胶电子有限公司| 台州迈兴机械有限公司| 张家港机械有限公司| 襄阳 机械 有限公司| 济南市恒宇机械有限公司| 广西清隆机械制造有限公司| 瀚乐电子机械有限公司| 铜陵群力机械有限公司| 青州东威机械有限公司| 郑州中意矿山机械有限公司| 佛山市宝陶机械设备有限公司| 长城重工机械有限公司| 徐州液压机械有限公司| 机电设备有限公司起名| 石家庄聚力特机械有限公司| 穗华机械设备有限公司| 大连 起 有限公司| 焦作市虹起制动器有限公司| 广东三浦重工有限公司| 南京起重机械总厂有限公司| 佛山市南海鼎工包装机械有限公司| 济南东泰机械制造有限公司| 丰凯机械制造有限公司| 沈阳捷优机械设备有限公司| 河北明芳钢铁有限公司| 苏州启点机械有限公司| 温州 轻工机械有限公司| 青州市远航机械设备有限公司| 江西四通重工机械有限公司| 山东天元建设机械有限公司| 临沂工程机械有限公司| 西安鸿运机械有限公司| 江苏迪迈机械有限公司| 台州 精密机械有限公司| 旭恒精工机械制造有限公司| 湖南博长钢铁贸易有限公司| 新湾机械有限公司招聘| 大连亨益机械有限公司| 诚鑫诚机械有限公司| 江苏博森机械制造有限公司| 辽宁营口钢铁有限公司| 宁波钢铁有限公司工作| 沈阳友维机械有限公司| 江苏重型机械有限公司| 青岛鲁奥机械有限公司| 江苏鑫锋重工机床有限公司| 北京大森长空包装机械有限公司| 人科机械设备有限公司| 成都机械制造有限公司| 无锡锡南铸造机械有限公司| 德瑞机械设备有限公司| 亨沃机械设备有限公司| 徐州徐工基础工程机械有限公司 | 北京恒博立华机械设备有限公司 | 江西四通重工机械有限公司| 新疆昆仑钢铁有限公司| 长沙中南福鼎机械设备有限公司| 唐山化工机械有限公司| 苏州锐豪机械制造有限公司| 溧阳申特钢铁有限公司| 上海楷钛机械制造有限公司| 上海三久机械有限公司| 上海应晓食品机械有限公司| 京西重工上海有限公司| 苏州亿泛精密机械有限公司| 扬州恒润钢铁有限公司| 宁波天竺工程机械有限公司| 杰西博工程机械有限公司| 南通贝思特机械工程有限公司| 杭州爱科机械有限公司| 浩博海门机械有限公司| 东莞市东机械设备有限公司| 大江重工焦作有限公司| 江苏普格机械有限公司| 杭州灵达机械有限公司| 济南铭机械有限公司| 浙江恒齿传动机械有限公司| 湖南天雁机械责任有限公司| 临沂盛德机械有限公司| 无锡联通焊接机械有限公司| 安徽永成电子机械技术有限公司| 全氏食品机械(上海)有限公司| 昆山精工机械有限公司| 温州科瑞机械有限公司| 江阴乐帕克智能机械有限公司| 上海轩世机械有限公司| 上海理贝包装机械有限公司| 南通液压机械有限公司| 泉州群峰机械有限公司| 南阳 机械制造有限公司| 郑州兆明机械有限公司| 湖北天腾重型机械制造有限公司| 杭州嘉诚机械有限公司| 常州常发动力机械有限公司| 三莲机械制造有限公司| 众力达机械有限公司| 东莞新宇机械有限公司| 安徽玻璃机械有限公司| 河南真牛起重机有限公司| 湖南龙凤机械制造有限公司| 中交西安筑路机械有限公司| 宁波美宁机械有限公司|