Detailliertes Tutorial zum Erstellen einer Continuous-Integration-Delivery-Umgebung basierend auf Docker+K8S+GitLab/SVN+Jenkins+Harbor

Detailliertes Tutorial zum Erstellen einer Continuous-Integration-Delivery-Umgebung basierend auf Docker+K8S+GitLab/SVN+Jenkins+Harbor

Übersicht zur Umgebungseinrichtung

Liebe Familienmitglieder, Sie können dem Link http://xiazai.jb51.net/202105/yuanma/javayaml_jb51.rar folgen, um die erforderliche YAML-Datei herunterzuladen.

1.Was ist K8S?

K8S steht für Kubernetes, eine neue führende verteilte Architekturlösung auf Basis von Containertechnologie. Basierend auf der Containertechnologie zielt es darauf ab, das Ressourcenmanagement zu automatisieren und die Ressourcennutzung über mehrere Rechenzentren hinweg zu maximieren.

Wenn unser Systemdesign der Designphilosophie von Kubernetes folgt, können die zugrunde liegenden Codes oder Funktionsmodule in der traditionellen Systemarchitektur, die wenig mit dem Geschäft zu tun haben, mit K8S verwaltet werden. Wir müssen uns nicht mehr um die Auswahl und Bereitstellung des Lastausgleichs kümmern, müssen nicht mehr selbst über die Einführung oder Entwicklung eines komplexen Service-Governance-Frameworks nachdenken und müssen uns nicht mehr um die Entwicklung von Serviceüberwachungs- und Fehlerbehandlungsmodulen kümmern. Kurz gesagt: Durch die Nutzung der von Kubernetes bereitgestellten Lösungen können Sie die Entwicklungskosten erheblich senken und sich gleichzeitig stärker auf Ihr eigentliches Geschäft konzentrieren. Da Kubernetes zudem einen leistungsstarken Automatisierungsmechanismus bietet, werden der Aufwand und die Kosten für den späteren Systembetrieb und die Systemwartung erheblich reduziert.

2. Warum K8S verwenden?

Docker, eine aufstrebende Containertechnologie, wird bereits von vielen Unternehmen übernommen. Der Übergang von einer Einzelmaschine zu einem Cluster ist unvermeidlich und die boomende Entwicklung des Cloud-Computing beschleunigt diesen Prozess. Kubernetes ist derzeit die einzige verteilte Docker-Systemlösung, die in der Branche weithin anerkannt und bevorzugt wird. Es ist absehbar, dass sich in den nächsten Jahren eine große Zahl neuer Systeme dafür entscheiden werden, unabhängig davon, ob sie auf lokalen Unternehmensservern laufen oder in öffentlichen Clouds gehostet werden.

3. Welche Vorteile bietet die Verwendung von K8S?

Die Verwendung von Kubernetes ist eine umfassende Bereitstellung einer Microservices-Architektur. Der Kern der Microservice-Architektur besteht darin, eine riesige monolithische Anwendung in viele kleine, miteinander verbundene Microservices zu zerlegen. Ein Microservice kann durch mehrere Instanzkopien unterstützt werden, und die Anzahl der Kopien kann bei sich ändernder Systemlast angepasst werden. Der eingebettete Load Balancer wird in der k8s-Plattform durch mehrere Instanzkopien unterstützt, und die Anzahl der Kopien kann bei sich ändernder Systemlast angepasst werden. Der eingebettete Load Balancer spielt in der k8s-Plattform eine wichtige Rolle. Die Microservice-Architektur ermöglicht, dass jeder Dienst von einem dedizierten Entwicklungsteam entwickelt wird und Entwickler die Entwicklungstechnologien frei wählen können, was für große Teams sehr wertvoll ist. Darüber hinaus wird jeder Mikrodienst unabhängig entwickelt, aktualisiert und erweitert, was dem System eine hohe Stabilität verleiht und eine schnelle iterative Weiterentwicklung ermöglicht.

4. Umweltzusammensetzung

Der Aufbau der gesamten Umgebung umfasst: den Aufbau der Docker-Umgebung, den Aufbau der Docker-Compose-Umgebung, den Aufbau des K8S-Clusters, den Aufbau des GitLab-Code-Repositorys, den Aufbau des SVN-Repositorys, den Aufbau der automatisierten Bereitstellungsumgebung von Jenkins und den Aufbau des privaten Harbor-Repositorys.

In diesem Dokument umfasst der Aufbau der gesamten Umgebung:

  • Docker-Umgebung installieren
  • Installieren Sie Docker-Compose
  • Installieren Sie die K8S-Clusterumgebung
  • Probleme beim Neustart des K8S-Clusters
  • Installieren Sie ingress-nginx auf K8S
  • K8S installiert Gitlab-Code-Repository
  • Installieren Sie das private Harbor-Lager
  • Jenkins installieren
  • SVN auf einer physischen Maschine installieren (empfohlen)
  • Installieren Sie Jenkins auf einer physischen Maschine (empfohlen)
  • Konfigurieren der Jenkins-Betriebsumgebung
  • Jenkins veröffentlicht Docker-Projekt auf K8S

Serverplanung

IP Hostname Knoten Betriebssystem
192.168.0.10 test10 K8S Meister CentOS 8.0.1905
192.168.0.11 test11 K8S-Mitarbeiter CentOS 8.0.1905
192.168.0.12 test12 K8S-Mitarbeiter CentOS 8.0.1905

Installationsumgebung

Softwaretitel Softwareversion veranschaulichen
Docker 19.03.8 Bereitstellen einer Containerumgebung
Docker-Compose 1.25.5 Definieren und Ausführen von Anwendungen, die aus mehreren Containern bestehen
K8S 1.18.2 Es handelt sich um eine Open-Source-Plattform zur Verwaltung containerisierter Anwendungen für mehrere Hosts. Das Ziel von Kubernetes besteht darin, die Bereitstellung containerisierter Anwendungen einfach und leistungsstark zu gestalten. Kubernetes bietet einen Mechanismus für die Bereitstellung, Planung, Aktualisierung und Wartung von Anwendungen.
GitLab 12.1.6 Code-Repository
Hafen 1.10.2 Privates Bild-Repository
Jenkins 2.222.3 Kontinuierliche Integrationsbereitstellung

Docker-Umgebung installieren

Docker ist eine Open-Source-Anwendungscontainer-Engine, die auf der Sprache Go basiert und Open Source gemäß dem Apache 2.0-Protokoll ist.

Mit Docker können Entwickler ihre Anwendungen und abhängigen Pakete in einen leichten, portablen Container packen und diesen dann auf jeder gängigen Linux-Maschine veröffentlichen und auch Virtualisierung implementieren.

Dieses Dokument erstellt eine Docker-Umgebung basierend auf Docker-Version 19.03.8.

Erstellen Sie das Skript install_docker.sh auf allen Servern. Der Skriptinhalt ist wie folgt.

#Verwenden Sie Alibaba Cloud Mirror Center export REGISTRY_MIRROR=https://registry.cn-hangzhou.aliyuncs.com
#Installieren Sie das Yum-Tool dnf install yum*
#Installieren Sie die Docker-Umgebung yum install -y yum-utils device-mapper-persistent-data lvm2
#Konfigurieren Sie die Yum-Quelle von Docker yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
#Installieren Sie das Container-Plug-In 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
#Geben Sie die Installation der Docker-Version 19.03.8 an yum install -y docker-ce-19.03.8 docker-ce-cli-19.03.8
#Docker zum Starten einrichten systemctl enable docker.service
#Docker starten
systemctl starte docker.service
#Überprüfen Sie die Docker-VersionDocker-Version

Erteilen Sie dem Skript install_docker.sh auf jedem Server Ausführungsberechtigungen und führen Sie das Skript wie unten gezeigt aus.

#Geben Sie dem Skript install_docker.sh Ausführungsberechtigungen chmod a+x ./install_docker.sh
# Führen Sie das Skript install_docker.sh aus ./install_docker.sh

Installieren Sie Docker-Compose

Compose ist ein Tool zum Definieren und Ausführen von Docker-Anwendungen mit mehreren Containern. Mit Compose verwenden Sie eine YML-Datei, um alle Dienste zu konfigurieren, die Ihre Anwendung benötigt. Anschließend können Sie mit einem einzigen Befehl alle Dienste aus der YML-Dateikonfiguration erstellen und starten.

Hinweis: Installieren Sie Docker-Compose auf jedem Server

1. Laden Sie die Docker-Compose-Datei herunter

#Laden Sie docker-compose herunter und installieren Sie es
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. Erteilen Sie der Docker-Compose-Datei Ausführungsberechtigungen

#Geben Sie Docker-Compose ausführbare Berechtigungen chmod a+x /usr/local/bin/docker-compose

3. Überprüfen Sie die Docker-Compose-Version

# Docker-Compose-Version anzeigen [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. September 2019

Installieren Sie die K8S-Clusterumgebung

Kubernetes ist eine Open-Source-Plattform zur Verwaltung von Containeranwendungen auf mehreren Hosts in einer Cloud-Plattform. Das Ziel von Kubernetes besteht darin, die Bereitstellung von Containeranwendungen einfach und leistungsstark zu gestalten. Kubernetes bietet einen Mechanismus für die Bereitstellung, Planung, Aktualisierung und Wartung von Anwendungen.

Dieses Dokument basiert auf K8S Version 1.8.12 zum Aufbau eines K8S-Clusters

Installieren Sie die K8S-Basisumgebung

Erstellen Sie die Skriptdatei install_k8s.sh auf allen Servern. Der Inhalt der Skriptdatei ist wie folgt.

######################Alibaba Cloud Image Accelerator Start konfigurieren############################
mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
  "Registrierungsspiegel": ["https://zz3sblpi.mirror.aliyuncs.com"]
}
Ende der Laufzeit
systemctl daemon-reload
systemctl Neustart Docker
############################Ende der Konfiguration von Alibaba Cloud Mirror Accelerator############################
#Installieren Sie nfs-utils
yum install -y nfs-utils
#Installieren Sie den wget-Software-Download-Befehl yum install -y wget

#NFS-Server starten
systemctl starte NFS-Server
#Konfigurieren Sie den NFS-Server so, dass er beim Systemstart automatisch gestartet wird. systemctl enable nfs-server

#Firewall herunterfahren systemctl stop firewalld
#Brechen Sie den Firewall-Start ab systemctl disable firewalld

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

# Swap deaktivieren
Auslagerung -a
ja | cp /etc/fstab /etc/fstab_bak
cat /etc/fstab_bak |grep -v swap > /etc/fstab

####################################Ändern Sie /etc/sysctl.conf und starten Sie###############################
# Wenn eine Konfiguration vorhanden ist, ändern Sie 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
# Vielleicht nicht, fügen Sie echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf hinzu
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
#####################################Ändern Sie /etc/sysctl.confEnd###############################
# Führen Sie den Befehl aus, damit die geänderte Datei /etc/sysctl.conf wirksam wird sysctl -p

####################### Beginnen Sie mit der Konfiguration der Yum-Quelle von K8S###################################
Katze <<EOF > /etc/yum.repos.d/kubernetes.repo
[Kubernetes]
Name=Kubernetes
Basis-URL = http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
aktiviert=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
Ende der Laufzeit
##################### Ende der Konfiguration der Yum-Quelle von K8S################################

# Deinstallieren Sie die alte Version von K8S
yum entfernen -y kubelet kubeadm kubectl

#Installieren Sie kubelet, kubeadm, kubectl. Hier habe ich Version 1.18.2 installiert. Sie können auch Version 1.17.2 installieren. yum install -y kubelet-1.18.2 kubeadm-1.18.2 kubectl-1.18.2

# Ändern Sie den Docker-Cgroup-Treiber in systemd
# # Ändern Sie diese Zeile in der Datei /usr/lib/systemd/system/docker.service ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
# # Ändern in ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --exec-opt native.cgroupdriver=systemd
# Wenn Sie es nicht ändern, kann beim Hinzufügen eines Worker-Knotens der folgende Fehler auftreten. # [WARNUNG IsDockerSystemdCheck]: „cgroupfs“ als Docker-Cgroup-Treiber erkannt. Der empfohlene Treiber ist „systemd“. 
# Bitte folgen Sie der Anleitung unter 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

# Richten Sie das Docker-Image ein, um die Downloadgeschwindigkeit und Stabilität des Docker-Images zu verbessern. # Wenn die Zugriffsgeschwindigkeit auf https://hub.docker.io sehr stabil ist, können Sie diesen Schritt auch überspringen. Im Allgemeinen ist keine Konfiguration erforderlich. # curl -sSL https://kuboard.cn/install-script/set_mirror.sh | sh -s ${REGISTRY_MIRROR}

# Laden Sie die Konfigurationsdatei systemctl daemon-reload neu
#Docker neu starten
systemctl Neustart Docker
# Stellen Sie Kubelet so ein, dass es beim Booten startet, und starten Sie Kubelet
systemctl aktiviere kubelet und systemctl starte kubelet
# Zeigen Sie die Docker-Version an

Erteilen Sie dem Skript install_k8s.sh auf jedem Server Ausführungsberechtigungen und führen Sie das Skript aus.

#Geben Sie dem Skript install_k8s.sh die Ausführungsberechtigung chmod a+x ./install_k8s.sh
# Führen Sie das Skript install_k8s.sh aus ./install_k8s.sh

Initialisieren des Masterknotens

Operationen werden nur auf dem Test10-Server durchgeführt.

1. Initialisieren Sie die Netzwerkumgebung des Masterknotens

Hinweis: Die folgenden Befehle müssen manuell in der Befehlszeile ausgeführt werden.

# Nur auf dem Masterknoten ausführen # Der Exportbefehl ist nur in der aktuellen Shell-Sitzung gültig. Wenn Sie nach dem Öffnen eines neuen Shell-Fensters den Installationsvorgang fortsetzen möchten, führen Sie den Exportbefehl hier erneut aus: export MASTER_IP=192.168.0.10
# Ersetzen Sie k8s.master durch den gewünschten DNS-Namen
exportiere APISERVER_NAME=k8s.master
# Das Netzwerksegment, in dem sich die Kubernetes-Containergruppe befindet. Dieses Netzwerksegment wird nach der Installation von Kubernetes erstellt und existiert vorher nicht im physischen Netzwerk. export POD_SUBNET=172.18.0.1/16
echo "${MASTER_IP} ${APISERVER_NAME}" >> /etc/hosts

2. Initialisieren Sie den Masterknoten

Erstellen Sie die Skriptdatei init_master.sh auf dem Test10-Server. Der Dateiinhalt ist wie folgt.

#!/bin/bash
# Beenden Sie das Skript, wenn ein Fehler auftritt. set -e

wenn [ ${#POD_SUBNET} -eq 0 ] || [ ${#APISERVER_NAME} -eq 0 ]; dann
  echo -e "\033[31;1mStellen Sie sicher, dass Sie die Umgebungsvariablen POD_SUBNET und APISERVER_NAME \033[0m" festgelegt haben.
  echo Aktuelles POD_SUBNET=$POD_SUBNET
  echo Aktueller APISERVER_NAME=$APISERVER_NAME
  Ausfahrt 1
fi


# Vollständige Konfigurationsoptionen anzeigen https://godoc.org/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2
rm -f ./kubeadm-config.yaml
Katze <<EOF > ./kubeadm-config.yaml
API-Version: kubeadm.k8s.io/v1beta2
Art: ClusterKonfiguration
kubernetesVersion: v1.18.2
Bild-Repository: registry.cn-hangzhou.aliyuncs.com/google_containers
controlPlaneEndpoint: "${APISERVER_NAME}:6443"
Vernetzung:
  serviceSubnet: "10.96.0.0/16"
  podSubnetz: "${POD_SUBNET}"
  DNS-Domäne: "cluster.local"
Ende der Laufzeit

# kubeadm init
# Kebeadm initialisieren
kubeadm init --config=kubeadm-config.yaml --upload-certs

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

# Installieren Sie das Calico-Netzwerk-Plugin. # Lesen Sie die Dokumentation https://docs.projectcalico.org/v3.13/getting-started/kubernetes/self-managed-onprem/onpremises.
echo "Installiere 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

Gewähren Sie der Skriptdatei init_master.sh Ausführungsberechtigungen und führen Sie das Skript aus.

# Erteilen Sie der Datei init_master.sh Ausführungsberechtigungen chmod a+x ./init_master.sh
# Führen Sie das Skript init_master.sh aus./init_master.sh

3. Überprüfen Sie die Initialisierungsergebnisse des Masterknotens

(1) Stellen Sie sicher, dass sich alle Containergruppen im Status „Ausführen“ befinden

# Führen Sie den folgenden Befehl aus und warten Sie 3-10 Minuten, bis sich alle Containergruppen im Status „Ausführen“ befinden. Beobachten Sie kubectl get pod -n kube-system -o wide

Die konkrete Implementierung ist wie folgt.

[root@test10 ~]# beobachten Sie kubectl get pod -n kube-system -o wide
Alle 2,0 s: kubectl get pod -n kube-system -o wide test10: So., 10. Mai 2020, 11:01:32 Uhr

NAME BEREIT STATUS NEUSTART ALTER IP KNOTEN NOMINIERT KNOTEN BEREITSCHAFT GATES          
calico-kube-controllers-5b8b769fcd-5dtlp 1/1 Läuft 0 118s 172.18.203.66 test10 <keine> <keine>          
calico-node-fnv8g 1/1 Läuft 0 118s 192.168.0.10 test10 <keine> <keine>          
coredns-546565776c-27t7h 1/1 Läuft 0 2m1s 172.18.203.67 test10 <keine> <keine>          
coredns-546565776c-hjb8z 1/1 Läuft 0 2m1s 172.18.203.65 test10 <keine> <keine>          
etcd-test10 1/1 Läuft 0 2m7s 192.168.0.10 test10 <keine> <keine>          
kube-apiserver-test10 1/1 Läuft 0 2m7s 192.168.0.10 test10 <keine> <keine>          
kube-controller-manager-test10 1/1 Läuft 0 2m7s 192.168.0.10 test10 <keine> <keine>          
kube-proxy-dvgsr 1/1 Läuft 0 2m1s 192.168.0.10 test10 <keine> <keine>          
kube-scheduler-test10 1/1 Läuft 0 2m7s 192.168.0.10 test10 <keine>

(2) Zeigen Sie die Initialisierungsergebnisse des Masterknotens an

# Zeigen Sie die Initialisierungsergebnisse des Masterknotens an kubectl get nodes -o wide

Die konkrete Implementierung ist wie folgt.

[root@test10 ~]# kubectl get nodes -o wide
NAME STATUS ROLLEN ALTER VERSION INTERNE IP EXTERNE IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
test10 Bereit Master 3m28s v1.18.2 192.168.0.10 <keine> CentOS Linux 8 (Core) 4.18.0-80.el8.x86_64 docker://19.3.8

Worker-Knoten initialisieren

1. Holen Sie sich die Parameter des Join-Befehls

Führen Sie den folgenden Befehl auf dem Masterknoten (Test10-Server) aus, um die Parameter für den Beitrittsbefehl zu erhalten.

kubeadm-Token erstellen --Druck-Join-Befehl

Die konkrete Implementierung ist wie folgt.

[root@test10 ~]# kubeadm-Token erstellen --print-join-command
W0510 11:04:34.828126 56132 configset.go:202] WARNUNG: kubeadm kann Komponentenkonfigurationen für API-Gruppen nicht validieren [kubelet.config.k8s.io kubeproxy.config.k8s.io]
kubeadm beitreten k8s.master:6443 --token 8nblts.62xytoqufwsqzko2 --discovery-token-ca-cert-hash sha256:1717cc3e34f6a56b642b5751796530e367aa73f4113d09994ac3455e33047c0d

Darunter befindet sich die folgende Ausgabezeile.

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

Diese Codezeile ist der erhaltene Join-Befehl.

Hinweis: Das Token im Join-Befehl ist 2 Stunden lang gültig. Innerhalb von 2 Stunden können Sie dieses Token verwenden, um eine beliebige Anzahl von Worker-Knoten zu initialisieren.

2. Worker-Knoten initialisieren

Auf allen Worker-Knoten ausführen. Hier wird es auf dem Test11-Server und dem Test12-Server ausgeführt.

Führen Sie die folgenden Befehle manuell in der Befehlszeile aus.

# Wird nur auf Worker-Knoten ausgeführt. # 192.168.0.10 ist die Intranet-IP des Master-Knotens.
export MASTER_IP=192.168.0.10
#Ersetzen Sie k8s.master durch den APISERVER_NAME, der beim Initialisieren des Masterknotens verwendet wird
exportiere APISERVER_NAME=k8s.master
echo "${MASTER_IP} ${APISERVER_NAME}" >> /etc/hosts

# Ersetzen Sie es durch die Join-Ausgabe des Befehls „kubeadm token create“ auf dem Masterknoten.
kubeadm beitreten k8s.master:6443 --token 8nblts.62xytoqufwsqzko2 --discovery-token-ca-cert-hash sha256:1717cc3e34f6a56b642b5751796530e367aa73f4113d09994ac3455e33047c0d

Die konkrete Implementierung ist wie folgt.

[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] WARNUNG: JoinControlPane.controlPlane-Einstellungen werden ignoriert, wenn das Control-Plane-Flag nicht gesetzt ist.
[preflight] Ausführen von Pre-Flight-Checks
        [WARNUNG FileExisting-tc]: tc nicht im Systempfad gefunden
[Preflight] Konfiguration aus dem Cluster wird gelesen …
[preflight] Zu Ihrer Information: Sie können sich diese Konfigurationsdatei mit „kubectl -n kube-system get cm kubeadm-config -oyaml“ ansehen.
[kubelet-start] Herunterladen der Konfiguration für das Kubelet aus der ConfigMap „kubelet-config-1.18“ im Kube-System-Namespace
[kubelet-start] Schreibe die Kubelet-Konfiguration in die Datei „/var/lib/kubelet/config.yaml“
[kubelet-start] Schreibe eine Kubelet-Umgebungsdatei mit Flags in die Datei „/var/lib/kubelet/kubeadm-flags.env“
[kubelet-start] Starten des Kubelets
[kubelet-start] Warten darauf, dass Kubelet den TLS-Bootstrap ausführt …

Dieser Knoten ist dem Cluster beigetreten:
* Die Anforderung zur Zertifikatsignierung wurde an den API-Server gesendet und eine Antwort wurde empfangen.
* Das Kubelet wurde über die neuen sicheren Verbindungsdetails informiert.

Führen Sie „kubectl get nodes“ auf der Steuerebene aus, um zu sehen, wie dieser Knoten dem Cluster beitritt.

Den Ausgabeergebnissen zufolge ist der Worker-Knoten dem K8S-Cluster beigetreten.

Hinweis: kubeadm join… ist die Join-Ausgabe des Befehls „kubeadm token create“ auf dem Masterknoten.

3. Initialisierungsergebnisse anzeigen

Führen Sie den folgenden Befehl auf dem Masterknoten (Test10-Server) aus, um die Initialisierungsergebnisse anzuzeigen.

kubectl get nodes -o breit

Die konkrete Implementierung ist wie folgt.

[root@test10 ~]# kubectl get nodes
NAME STATUS ROLLEN ALTER VERSION
test10 Bereit Master 20m v1.18.2
test11 Bereit <keine> 2m46s v1.18.2
test12 Bereit <keine> 2m46s v1.18.2

Hinweis: Wenn Sie nach dem Befehl „kubectl get nodes“ den Parameter „-o wide“ hinzufügen, werden weitere Informationen ausgegeben.

Probleme beim Neustart des K8S-Clusters

1. Der Worker-Knoten ist ausgefallen und kann nicht gestartet werden

Die IP-Adresse des Masterknotens ändert sich, wodurch der Start des Workerknotens fehlschlägt. Sie müssen den K8S-Cluster neu installieren und sicherstellen, dass alle Knoten über feste Intranet-IP-Adressen verfügen.

2. Pod stürzt ab oder kann nicht normal aufgerufen werden

Verwenden Sie nach dem Neustart des Servers den folgenden Befehl, um den Laufstatus des Pods zu überprüfen.

#Zeigen Sie den Ausführungsstatus aller Pods an kubectl get pods --all-namespaces

Es wurde festgestellt, dass sich viele Pods nicht im Ausführungsstatus befinden. Zu diesem Zeitpunkt müssen Sie den folgenden Befehl verwenden, um die Pods zu löschen, die nicht ordnungsgemäß ausgeführt werden.

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

Hinweis: Wenn der Pod mit einem Controller wie Deployment oder StatefulSet erstellt wird, erstellt K8S als Ersatz einen neuen Pod und der neu gestartete Pod funktioniert normalerweise normal.

Darunter gibt „pod-name“ den Namen des in K8S ausgeführten Pods an und „pod-namespece“ den Namespace. Wenn Sie beispielsweise einen Pod mit dem Pod-Namen „pod-test“ und dem Namespace „pod-test-namespace“ löschen müssen, können Sie den folgenden Befehl verwenden.

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

Installieren Sie ingress-nginx auf K8S

Als Reverse-Proxy importiert es externen Datenverkehr in den Cluster, stellt den Dienst innerhalb von Kubernetes nach außen bereit und gleicht den Dienst nach Domänennamen im Ingress-Objekt ab, sodass auf den Dienst innerhalb des Clusters direkt nach Domänennamen zugegriffen werden kann. Im Vergleich zu Traefik hat Nginx-Ingress eine bessere Leistung.

Hinweis: Auf dem Master-Knoten (ausgeführt auf dem Test10-Server)

1. Erstellen Sie den Ingress-Nginx-Namespace

Erstellen Sie die Datei ingress-nginx-namespace.yaml. Ihre Hauptfunktion besteht darin, den Ingress-nginx-Namespace zu erstellen. Der Dateiinhalt ist wie folgt.

API-Version: v1
Art: Namespace
Metadaten:
  Name: ingress-nginx
  Beschriftungen:
    Name: ingress-nginx

Führen Sie den folgenden Befehl aus, um den Ingress-nginx-Namespace zu erstellen.

kubectl apply -f ingress-nginx-namespace.yaml

2. Ingress Controller installieren

Erstellen Sie die Datei ingress-nginx-mandatory.yaml, deren Hauptfunktion darin besteht, ingress-nginx zu installieren. Der Dateiinhalt ist wie folgt.

API-Version: v1
Art: Namespace
Metadaten:
  Name: ingress-nginx

---

API-Version: Apps/v1
Art: Bereitstellung
Metadaten:
  Name: Standard-http-Backend
  Beschriftungen:
    app.kubernetes.io/name: Standard-http-backend
    app.kubernetes.io/Teil von: ingress-nginx
  Namespace: ingress-nginx
Spezifikation:
  Replikate: 1
  Wähler:
    Übereinstimmungsetiketten:
      app.kubernetes.io/name: Standard-http-backend
      app.kubernetes.io/Teil von: ingress-nginx
  Vorlage:
    Metadaten:
      Beschriftungen:
        app.kubernetes.io/name: Standard-http-backend
        app.kubernetes.io/Teil von: ingress-nginx
    Spezifikation:
      KündigungsfristSekunden: 60
      Behälter:
        - Name: Standard-http-Backend
          # Jedes Bild ist zulässig, solange:
          # 1. Es liefert eine 404-Seite unter /
          # 2. Es bedient 200 auf einem /healthz-Endpunkt
          Bild: registry.cn-qingdao.aliyuncs.com/kubernetes_xingej/defaultbackend-amd64:1.5
          LivenessProbe:
            httpGet:
              Pfad: /healthz
              Port: 8080
              Schema: HTTP
            AnfangsverzögerungSekunden: 30
            TimeoutSekunden: 5
          Häfen:
            - ContainerPort: 8080
          Ressourcen:
            Grenzen:
              Zentralprozessor: 10 M
              Speicher: 20mi
            Anfragen:
              Zentralprozessor: 10 M
              Speicher: 20mi

---
API-Version: v1
Art: Dienstleistung
Metadaten:
  Name: Standard-http-Backend
  Namespace: ingress-nginx
  Beschriftungen:
    app.kubernetes.io/name: Standard-http-backend
    app.kubernetes.io/Teil von: ingress-nginx
Spezifikation:
  Häfen:
    - Anschluss: 80
      ZielPort: 8080
  Wähler:
    app.kubernetes.io/name: Standard-http-backend
    app.kubernetes.io/Teil von: ingress-nginx

---

Art: ConfigMap
API-Version: v1
Metadaten:
  Name: nginx-Konfiguration
  Namespace: ingress-nginx
  Beschriftungen:
    app.kubernetes.io/Name: ingress-nginx
    app.kubernetes.io/Teil von: ingress-nginx

---

Art: ConfigMap
API-Version: v1
Metadaten:
  Name: TCP-Dienste
  Namespace: ingress-nginx
  Beschriftungen:
    app.kubernetes.io/Name: ingress-nginx
    app.kubernetes.io/Teil von: ingress-nginx

---

Art: ConfigMap
API-Version: v1
Metadaten:
  Name: UDP-Dienste
  Namespace: ingress-nginx
  Beschriftungen:
    app.kubernetes.io/Name: ingress-nginx
    app.kubernetes.io/Teil von: ingress-nginx

---

API-Version: v1
Art: ServiceAccount
Metadaten:
  Name: nginx-ingress-serviceaccount
  Namespace: ingress-nginx
  Beschriftungen:
    app.kubernetes.io/Name: ingress-nginx
    app.kubernetes.io/Teil von: ingress-nginx

---
API-Version: rbac.authorization.k8s.io/v1beta1
Art: ClusterRole
Metadaten:
  Name: nginx-ingress-clusterrole
  Beschriftungen:
    app.kubernetes.io/Name: ingress-nginx
    app.kubernetes.io/Teil von: ingress-nginx
Regeln:
  -API-Gruppen:
      - ""
    Ressourcen:
      - Konfigurationskarten
      - Endpunkte
      - Knoten
      - Schoten
      - Geheimnisse
    Verben:
      - Liste
      - betrachten
  -API-Gruppen:
      - ""
    Ressourcen:
      - Knoten
    Verben:
      - erhalten
  -API-Gruppen:
      - ""
    Ressourcen:
      - Dienstleistungen
    Verben:
      - erhalten
      - Liste
      - betrachten
  -API-Gruppen:
      - "Erweiterungen"
    Ressourcen:
      - Eingänge
    Verben:
      - erhalten
      - Liste
      - betrachten
  -API-Gruppen:
      - ""
    Ressourcen:
      - Veranstaltungen
    Verben:
      - erstellen
      -Patch
  -API-Gruppen:
      - "Erweiterungen"
    Ressourcen:
      - Eingänge/Status
    Verben:
      - aktualisieren

---
API-Version: rbac.authorization.k8s.io/v1beta1
Art: Rolle
Metadaten:
  Name: nginx-ingress-Rolle
  Namespace: ingress-nginx
  Beschriftungen:
    app.kubernetes.io/Name: ingress-nginx
    app.kubernetes.io/Teil von: ingress-nginx
Regeln:
  -API-Gruppen:
      - ""
    Ressourcen:
      - Konfigurationskarten
      - Schoten
      - Geheimnisse
      - Namensräume
    Verben:
      - erhalten
  -API-Gruppen:
      - ""
    Ressourcen:
      - Konfigurationskarten
    Ressourcennamen:
      # Der Standardwert ist „<Wahl-ID>-<Eingangsklasse>“
      # Hier: „<ingress-controller-leader>-<nginx>“
      # Dies muss angepasst werden, wenn Sie einen der Parameter ändern
      # beim Starten des Nginx-Ingress-Controllers.
      - "Ingress-Controller-Leader-Nginx"
    Verben:
      - erhalten
      - aktualisieren
  -API-Gruppen:
      - ""
    Ressourcen:
      - Konfigurationskarten
    Verben:
      - erstellen
  -API-Gruppen:
      - ""
    Ressourcen:
      - Endpunkte
    Verben:
      - erhalten

---
API-Version: rbac.authorization.k8s.io/v1beta1
Art: RoleBinding
Metadaten:
  Name: nginx-ingress-role-nisa-binding
  Namespace: ingress-nginx
  Beschriftungen:
    app.kubernetes.io/Name: ingress-nginx
    app.kubernetes.io/Teil von: ingress-nginx
Rollenreferenz:
  API-Gruppe: rbac.authorization.k8s.io
  Art: Rolle
  Name: nginx-ingress-Rolle
Themen:
  - Art: ServiceAccount
    Name: nginx-ingress-serviceaccount
    Namespace: ingress-nginx

---
API-Version: rbac.authorization.k8s.io/v1beta1
Art: ClusterRoleBinding
Metadaten:
  Name: nginx-ingress-clusterrole-nisa-binding
  Beschriftungen:
    app.kubernetes.io/Name: ingress-nginx
    app.kubernetes.io/Teil von: ingress-nginx
Rollenreferenz:
  API-Gruppe: rbac.authorization.k8s.io
  Art: ClusterRole
  Name: nginx-ingress-clusterrole
Themen:
  - Art: ServiceAccount
    Name: nginx-ingress-serviceaccount
    Namespace: ingress-nginx

---

API-Version: Apps/v1
Art: Bereitstellung
Metadaten:
  Name: nginx-ingress-controller
  Namespace: ingress-nginx
  Beschriftungen:
    app.kubernetes.io/Name: ingress-nginx
    app.kubernetes.io/Teil von: ingress-nginx
Spezifikation:
  Replikate: 1
  Wähler:
    Übereinstimmungsetiketten:
      app.kubernetes.io/Name: ingress-nginx
      app.kubernetes.io/Teil von: ingress-nginx
  Vorlage:
    Metadaten:
      Beschriftungen:
        app.kubernetes.io/Name: ingress-nginx
        app.kubernetes.io/Teil von: ingress-nginx
      Anmerkungen:
        prometheus.io/port: "10254"
        prometheus.io/scrape: "wahr"
    Spezifikation:
      Dienstkontoname: nginx-ingress-serviceaccount
      Behälter:
        - Name: nginx-ingress-controller
          Bild: registry.cn-qingdao.aliyuncs.com/kubernetes_xingej/nginx-ingress-controller:0.20.0
          Argumente:
            - /nginx-ingress-controller
            - --default-backend-service=$(POD_NAMESPACE)/default-http-backend
            – –configmap=$(POD_NAMESPACE)/nginx-Konfiguration
            - --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
          Sicherheitskontext:
            Fähigkeiten:
              fallen:
                - ALLE
              hinzufügen:
                -NET_BIND_SERVICE
            # www-Daten -> 33
            Als Benutzer ausführen: 33
          Umgebung:
            - Name: POD_NAME
              Wert von:
                FeldRef:
                  Feldpfad: Metadatenname
            - Name: POD_NAMESPACE
              Wert von:
                FeldRef:
                  Feldpfad: metadata.namespace
          Häfen:
            - Name: http
              ContainerPort: 80
            - Name: https
              ContainerPort: 443
          LivenessProbe:
            Fehlerschwelle: 3
            httpGet:
              Pfad: /healthz
              Port: 10254
              Schema: HTTP
            AnfangsverzögerungSekunden: 10
            PeriodeSekunden: 10
            Erfolgsschwelle: 1
            TimeoutSekunden: 1
          Bereitschaftsprobe:
            Fehlerschwelle: 3
            httpGet:
              Pfad: /healthz
              Port: 10254
              Schema: HTTP
            PeriodeSekunden: 10
            Erfolgsschwelle: 1
            TimeoutSekunden: 1

---

Führen Sie den folgenden Befehl aus, um den Ingress-Controller zu installieren.

kubectl apply -f ingress-nginx-mandatory.yaml

3. Installieren Sie K8S SVC: ingress-nginx

Wird hauptsächlich zum Freigeben des Pods verwendet: nginx-ingress-controller.

Erstellen Sie die Datei service-nodeport.yaml mit dem folgenden Inhalt.

API-Version: v1
Art: Dienstleistung
Metadaten:
  Name: ingress-nginx
  Namespace: ingress-nginx
  Beschriftungen:
    app.kubernetes.io/Name: ingress-nginx
    app.kubernetes.io/Teil von: ingress-nginx
Spezifikation:
  Typ: NodePort
  Häfen:
    - Name: http
      Anschluss: 80
      ZielPort: 80
      Protokoll: TCP
      KnotenPort: 30080
    - Name: https
      Port: 443
      ZielPort: 443
      Protokoll: TCP
      KnotenPort: 30443
  Wähler:
    app.kubernetes.io/Name: ingress-nginx
    app.kubernetes.io/Teil von: ingress-nginx

Führen Sie den folgenden Befehl aus, um es zu installieren.

kubectl apply -f service-nodeport.yaml

4. Zugriff auf K8S SVC: ingress-nginx

Überprüfen Sie die Bereitstellung des Ingress-Nginx-Namespace, wie unten gezeigt.

[root@test10 k8s]# kubectl get pod -n ingress-nginx
NAME BEREIT STATUS NEUSTART ALTER
default-http-backend-796ddcd9b-vfmgn 1/1 Läuft 1 10h
nginx-ingress-controller-58985cc996-87754 1/1 Läuft 2 10h

Geben Sie den folgenden Befehl in die Befehlszeile des Befehlszeilenservers ein, um die Portzuordnung von Ingress-Nginx anzuzeigen.

kubectl get svc -n ingress-nginx

Die Einzelheiten sind wie folgt.

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

Daher können Sie auf ingress-nginx über die IP-Adresse des Masterknotens (Test10-Server) und die Portnummer 30080 zugreifen, wie unten gezeigt.

[root@test10 k8s]# curl 192.168.0.10:30080       
Standard-Backend – 404

Sie können auch auf ingress-nginx zugreifen, indem Sie http://192.168.0.10:30080 in Ihrem Browser öffnen, wie unten gezeigt.

K8S installiert Gitlab-Code-Repository

GitLab ist ein webbasiertes Git-Repository-Verwaltungstool, das von GitLab Inc. unter der MIT-Lizenz entwickelt wurde und über Wiki- und Issue-Tracking-Funktionen verfügt. Nutzen Sie Git als Code-Management-Tool und bauen Sie auf dieser Basis einen Webservice auf.

Hinweis: Auf dem Master-Knoten (ausgeführt auf dem Test10-Server)

1. Erstellen Sie einen k8s-ops-Namespace

Erstellen Sie die Datei k8s-ops-namespace.yaml, die hauptsächlich zum Erstellen des k8s-ops-Namespace verwendet wird. Der Dateiinhalt ist wie folgt.

API-Version: v1
Art: Namespace
Metadaten:
  Name: k8s-ops
  Beschriftungen:
    Name: k8s-ops

Führen Sie den folgenden Befehl aus, um einen Namespace zu erstellen.

kubectl apply -f k8s-ops-namespace.yaml

2. Installieren Sie gitlab-redis

Erstellen Sie die Datei gitlab-redis.yaml. Der Inhalt der Datei ist wie folgt.

API-Version: Apps/v1
Art: Bereitstellung
Metadaten:
  Name: Redis
  Namespace: k8s-ops
  Beschriftungen:
    Name: Redis
Spezifikation:
  Wähler:
    Übereinstimmungsetiketten:
      Name: Redis
  Vorlage:
    Metadaten:
      Name: Redis
      Beschriftungen:
        Name: Redis
    Spezifikation:
      Behälter:
      - Name: Redis
        Bild: sameersbn/redis
        imagePullPolicy: IfNotPresent
        Häfen:
        - Name: Redis
          ContainerPort: 6379
        Volumenhalterungen:
        - MountPfad: /var/lib/redis
          Name: Daten
        LivenessProbe:
          Ausführung:
            Befehl:
            - Redis-CLI
            - Klingeln
          AnfangsverzögerungSekunden: 30
          TimeoutSekunden: 5
        Bereitschaftsprobe:
          Ausführung:
            Befehl:
            - Redis-CLI
            - Klingeln
          AnfangsverzögerungSekunden: 10
          TimeoutSekunden: 5
      Bände:
      - Name: Daten
        Hostpfad:
          Pfad: /data1/docker/xinsrv/redis

---
API-Version: v1
Art: Dienstleistung
Metadaten:
  Name: Redis
  Namespace: k8s-ops
  Beschriftungen:
    Name: Redis
Spezifikation:
  Häfen:
    - Name: Redis
      Port: 6379
      ZielPort: redis
  Wähler:
    Name: Redis

Führen Sie zunächst den folgenden Befehl in der Befehlszeile aus, um das Verzeichnis /data1/docker/xinsrv/redis zu erstellen.

mkdir -p /data1/docker/xinsrv/redis

Führen Sie den folgenden Befehl aus, um gitlab-redis zu installieren.

kubectl apply -f gitlab-redis.yaml

3. Installieren Sie gitlab-postgresql

Erstellen Sie gitlab-postgresql.yaml. Der Inhalt der Datei ist wie folgt.

API-Version: Apps/v1
Art: Bereitstellung
Metadaten:
  Name: postgresql
  Namespace: k8s-ops
  Beschriftungen:
    Name: postgresql
Spezifikation:
  Wähler:
    Übereinstimmungsetiketten:
      Name: postgresql
  Vorlage:
    Metadaten:
      Name: postgresql
      Beschriftungen:
        Name: postgresql
    Spezifikation:
      Behälter:
      - Name: postgresql
        Bild: sameersbn/postgresql
        imagePullPolicy: IfNotPresent
        Umgebung:
        - Name: DB_USER
          Wert: gitlab
        - Name: DB_PASS
          Wert: password
        - Name: DB_NAME
          Wert: gitlab_production
        - Name: DB_EXTENSION
          Wert: pg_trgm
        Häfen:
        - Name: postgres
          ContainerPort: 5432
        Volumenhalterungen:
        -mountPath: /var/lib/postgresql
          Name: Daten
        LivenessProbe:
          Ausführung:
            Befehl:
            - pg_istbereit
            - -H
            - lokaler Host
            - -U
            - postgres
          AnfangsverzögerungSekunden: 30
          TimeoutSekunden: 5
        Bereitschaftsprobe:
          Ausführung:
            Befehl:
            - pg_istbereit
            - -H
            - lokaler Host
            - -U
            - postgres
          AnfangsverzögerungSekunden: 5
          TimeoutSekunden: 1
      Bände:
      - Name: Daten
        Hostpfad:
          Pfad: /data1/docker/xinsrv/postgresql
---
API-Version: v1
Art: Dienstleistung
Metadaten:
  Name: postgresql
  Namespace: k8s-ops
  Beschriftungen:
    Name: postgresql
Spezifikation:
  Häfen:
    - Name: postgres
      Port: 5432
      Zielport: postgres
  Wähler:
    Name: postgresql

Führen Sie zunächst den folgenden Befehl aus, um das Verzeichnis /data1/docker/xinsrv/postgresql zu erstellen.

mkdir -p /data1/docker/xinsrv/postgresql

Installieren Sie als Nächstes gitlab-postgresql wie unten gezeigt.

kubectl apply -f gitlab-postgresql.yaml

4. Installieren Sie Gitlab

(1) Benutzernamen und Passwort konfigurieren

Verwenden Sie zunächst die Base64-Kodierung, um den Benutzernamen und das Passwort in der Befehlszeile zu konvertieren. In diesem Beispiel lautet der verwendete Benutzername admin und das Passwort admin.1231

Die Transkodierung wird unten angezeigt.

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

Der konvertierte Benutzername lautet: YWRtaW4= Passwort: YWRtaW4uMTIzMQ==

Sie können auch eine Base64-codierte Zeichenfolge dekodieren, beispielsweise eine Kennwortzeichenfolge, wie unten gezeigt.

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

Erstellen Sie als Nächstes die Datei secret-gitlab.yaml, die hauptsächlich von Benutzern zum Konfigurieren des Benutzernamens und des Kennworts von GitLab verwendet wird. Der Dateiinhalt ist wie folgt.

API-Version: v1
Art: Geheim
Metadaten:
  Namespace: k8s-ops
  Name: Git-Benutzerkennwort
Typ: Undurchsichtig
Daten:
  Benutzername: YWRtaW4=
  Passwort: YWRtaW4uMTIzMQ==

Führen Sie den Inhalt der Konfigurationsdatei wie unten gezeigt aus.

kubectl create -f ./secret-gitlab.yaml

(2) GitLab installieren

Erstellen Sie eine gitlab.yaml-Datei mit dem folgenden Inhalt.

API-Version: Apps/v1
Art: Bereitstellung
Metadaten:
  Name: Gitlab
  Namespace: k8s-ops
  Beschriftungen:
    Name: Gitlab
Spezifikation:
  Wähler:
    Übereinstimmungsetiketten:
      Name: Gitlab
  Vorlage:
    Metadaten:
      Name: Gitlab
      Beschriftungen:
        Name: Gitlab
    Spezifikation:
      Behälter:
      - Name: gitlab
        Bild: sameersbn/gitlab:12.1.6
        imagePullPolicy: IfNotPresent
        Umgebung:
        - Name: TZ
          Wert: Asien/Shanghai
        - Name: GITLAB_TIMEZONE
          Wert: Peking
        - Name: GITLAB_SECRETS_DB_KEY_BASE
          Wert: lange und zufällige alphanumerische Zeichenfolge
        - Name: GITLAB_SECRETS_SECRET_KEY_BASE
          Wert: lange und zufällige alphanumerische Zeichenfolge
        - Name: GITLAB_SECRETS_OTP_KEY_BASE
          Wert: lange und zufällige alphanumerische Zeichenfolge
        - Name: GITLAB_ROOT_PASSWORD
          Wert von:
            geheimerSchlüsselRef:
              Name: Git-Benutzerkennwort
              Schlüssel: Passwort
        - Name: GITLAB_ROOT_EMAIL
          Wert: [email protected]
        - Name: GITLAB_HOST
          Wert: gitlab.binghe.com
        - Name: GITLAB_PORT
          Wert: „80“
        - Name: GITLAB_SSH_PORT
          Wert: „30022“
        - Name: GITLAB_NOTIFY_ON_BROKEN_BUILDS
          Wert: „true“
        - Name: GITLAB_NOTIFY_PUSHER
          Wert: „false“
        - Name: GITLAB_BACKUP_SCHEDULE
          Wert: täglich
        - Name: GITLAB_BACKUP_TIME
          Wert: 01:00
        - Name: DB_TYPE
          Wert: postgres
        - Name: DB_HOST
          Wert: postgresql
        - Name: DB_PORT
          Wert: „5432“
        - Name: DB_USER
          Wert: gitlab
        - Name: DB_PASS
          Wert: password
        - Name: DB_NAME
          Wert: gitlab_production
        - Name: REDIS_HOST
          Wert: redis
        - Name: REDIS_PORT
          Wert: „6379“
        Häfen:
        - Name: http
          ContainerPort: 80
        - Name: ssh
          ContainerPort: 22
        Volumenhalterungen:
        - MountPfad: /home/git/data
          Name: Daten
        LivenessProbe:
          httpGet:
            Weg: /
            Anschluss: 80
          AnfangsverzögerungSekunden: 180
          TimeoutSekunden: 5
        Bereitschaftsprobe:
          httpGet:
            Weg: /
            Anschluss: 80
          AnfangsverzögerungSekunden: 5
          TimeoutSekunden: 1
      Bände:
      - Name: Daten
        Hostpfad:
          Pfad: /data1/docker/xinsrv/gitlab
---
API-Version: v1
Art: Dienstleistung
Metadaten:
  Name: Gitlab
  Namespace: k8s-ops
  Beschriftungen:
    Name: Gitlab
Spezifikation:
  Häfen:
    - Name: http
      Anschluss: 80
      KnotenPort: 30088
    - Name: ssh
      Anschluss: 22
      ZielPort: ssh
      KnotenPort: 30022
  Typ: NodePort
  Wähler:
    Name: Gitlab

---
API-Version: Erweiterungen/v1beta1
Art: Ingress
Metadaten:
  Name: Gitlab
  Namespace: k8s-ops
  Anmerkungen:
    kubernetes.io/ingress.class: traefik
Spezifikation:
  Regeln:
  - Host: gitlab.binghe.com
    http:
      Pfade:
      - Backend:
          Dienstname: gitlab
          ServicePort: http

Hinweis: Wenn Sie GitLab konfigurieren, können Sie beim Abhören des Hosts nicht die IP-Adresse verwenden. Sie müssen den Hostnamen oder den Domänennamen verwenden. In der obigen Konfiguration verwende ich den Hostnamen gitlab.binghe.com.

Führen Sie den folgenden Befehl in der Befehlszeile aus, um das Verzeichnis /data1/docker/xinsrv/gitlab zu erstellen.

mkdir -p /data1/docker/xinsrv/gitlab

Installieren Sie GitLab wie unten gezeigt.

kubectl apply -f gitlab.yaml

5. Installation abgeschlossen

Überprüfen Sie die Bereitstellung des k8s-ops-Namespace wie unten gezeigt.

[root@test10 k8s]# kubectl get pod -n k8s-ops
NAME BEREIT STATUS NEUSTART ALTER
gitlab-7b459db47c-5vk6t 0/1 Läuft 0 11s
postgresql-79567459d7-x52vx 1/1 Wird ausgeführt 0 30 m
redis-67f4cdc96c-h5ckz 1/1 Läuft 1 10h

Sie können auch den folgenden Befehl verwenden, um es anzuzeigen.

[root@test10 k8s]# kubectl get pod --namespace=k8s-ops
NAME BEREIT STATUS NEUSTART ALTER
gitlab-7b459db47c-5vk6t 0/1 Läuft 0 36s
PostgreSQL-79567459D7-X52VX 1/1 Laufen 0 30m
Redis-67F4CDC96C-H5CKZ 1/1 1 10H

Die beiden haben den gleichen Effekt.

Überprüfen Sie als Nächstes die Port -Mapping für GitLab, wie unten gezeigt.

[root@test10 k8s]# kubectl Holen Sie sich SVC -n K8S -Ops
NAME TYP CLUSTER-IP EXTERNE-IP PORT(S) ALTER
Gitlab Nodeport 10.96.153.100 <Keine> 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

An diesem Punkt können Sie sehen, dass auf GitLab über den Hostnamen gitlab.binghe.com und Port 30088 des Master -Knotens (Test10) zugegriffen werden kann. Da ich eine virtuelle Maschine verwende, um die relevante Umgebung zu erstellen, müssen Sie die lokale Hostsdatei konfigurieren und der Datei der lokalen Hosts auf die Datei der lokalen Hosts hinzufügen.

192.168.0.10 gitlab.binghe.com

Hinweis: In Windows -Betriebssystemen befindet sich die Hosts -Datei im folgenden Verzeichnis.

C: \ Windows \ System32 \ Treiber \ usw.

Als nächstes können Sie über den Link in Ihrem Browser auf GitLab zugreifen: http://gitlab.binghe.com:30088, wie unten gezeigt.

An diesem Punkt können Sie sich bei GitLab mit dem Benutzernamen Root und Password Admin.1231 anmelden.

Hinweis: Der Benutzername hier ist root anstelle von admin, da root der Standard -Superbenutzer von GitLab ist.

Zu diesem Zeitpunkt ist die K8S -Installation von GitLab vollständig.

Installieren Sie Harbor Private Warehouse

HABOR ist ein von VMware entwickeltes Open -Source -Container -Image -Repository. Tatsächlich hat HABOR die entsprechenden Erweiterungen auf Unternehmensebene in der Docker-Registrierung aufgenommen, um eine breitere Anwendung zu erreichen.

HINWEIS: Hier wird das private Lagerhaus auf dem Masterknoten (Test10 -Server) installiert.

1. Laden Sie die Offline -Installationsversion von Harbor herunter

wGet https://github.com/goharbor/harbor/releass/download/v1.10.2/harbor--- offline-installer-v1.10.2.tgz

2. Entpaketen Sie das Hafeninstallationspaket

TAR-ZXVF HARBOR-OFFLINE-INSTALLER-V1.10.2.TGZ

Nach einer erfolgreichen Dekompression wird im aktuellen Verzeichnis des Servers ein Harbor -Verzeichnis generiert.

3. Konfigurieren Sie den Hafen

Hinweis: Hier habe ich den Hafen von Hafen auf 1180 geändert. Wenn Sie den Hafenhafen nicht ändern, beträgt der Standardhafen 80.

(1) Ändern Sie die Datei harbor.yml

CD Harbor
vim harbor.yml

Die geänderten Konfigurationselemente sind wie folgt.

Hostname: 192.168.0.10
http:
  Port: 1180
HARBOR_ADMIN_PASSWORD: Binghe123
### und kommentieren HTTPS, andernfalls wird ein Fehler während der Installation gemeldet
#https:
  #port: 443
  #Zertifikat: /Ihr/Zertifikat/Pfad
  #private_key: /Ihr/privater/Schlüssel/Pfad

(2) Ändern Sie die Datei von Daemon.json

Ändern Sie die Datei /etc/docker/daemon.json.

[root@binghe ~]# cat /etc/docker/daemon.json
{
  "Registry-Mirrors": ["https://zz3sblpi.mirror.aliyuncs.com"],
  "Unsichere Registrien": ["192.168.0.10:1180"]
}

Sie können auch den Befehl IP -AdDR auf dem Server verwenden, um alle IP -Adresssegmente des lokalen Computers anzuzeigen und diese in der Datei /etc/docker/daemon.json zu konfigurieren. Hier ist der Inhalt der Datei nach meiner Konfiguration wie folgt.

{
    "Registry-Mirrors": ["https://zz3sblpi.mirror.aliyuncs.com"],
    "Insecure-Registries": ["192.168.175.0/16"
}

4. Hafen installieren und starten Sie

Geben Sie nach Abschluss der Konfiguration den folgenden Befehl ein, um den Hafen zu installieren und zu starten

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

5. Melden Sie sich in Hafen an und fügen Sie ein Konto hinzu

Geben Sie nach einer erfolgreichen Installation http://192.168.0.10:1180 in die Browseradressleiste ein, um den Link zu öffnen, geben Sie den Benutzernamen -Administrator und das Passwort Binghe123 ein und melden Sie sich beim System an.

Als nächstes wählen wir die Benutzerverwaltung und fügen ein Administratorkonto hinzu, um die nachfolgende Verpackung und das Hochladen von Docker -Bildern vorzubereiten.

Das Passwort ist Binghe123. Klicken Sie auf OK.

Zu diesem Zeitpunkt wird das Binghe -Konto als Administrator festgelegt. Zu diesem Zeitpunkt ist die Installation von Hafen abgeschlossen.

6. Hafenhafen ändern

Wenn Sie nach der Installation den Hafen von Hafen ändern müssen, können Sie die folgenden Schritte ausführen, um den Hafen von Hafen zu ändern.

(1) Ändern Sie die Datei harbor.yml

CD Harbor
vim harbor.yml

Die geänderten Konfigurationselemente sind wie folgt.

Hostname: 192.168.0.10
http:
  Port: 1180
HARBOR_ADMIN_PASSWORD: Binghe123
### und kommentieren HTTPS, andernfalls wird ein Fehler während der Installation gemeldet
#https:
  #port: 443
  #Zertifikat: /Ihr/Zertifikat/Pfad
  #private_key: /Ihr/privater/Schlüssel/Pfad

(2) Ändern Sie die Datei docker-compose.yml

vim docker-compose.yml

Die geänderten Konfigurationselemente sind wie folgt.

Häfen:
      1180:80

(3) Ändern Sie die Datei config.yml

CD Common/Config/Registrierung
vim config.yml

Die geänderten Konfigurationselemente sind wie folgt.

Realm: http://192.168.0.10:1180/service/token

(4) Docker neu starten

systemctl daemon-reload
systemctl Neustart docker.service

(5) Hafen neu starten

[Root@Binghe Harbor]# Docker-Compose Down
Hafenprotokoll stoppen ... erledigt
Nginx wird entfernt ... fertig
Hafenportal entfernen ... fertig
Harbor-Jobservice wird entfernt ... fertig
Harbor-Core wird entfernt ... fertig
Redis wird entfernt ... fertig
Registrierung entfernen ... fertig
Registryctl wird entfernt ... fertig
Harbor-DB wird entfernt ... fertig
Hafenprotokoll entfernen ... fertig
Entfernen von Network Harbor_harbor
 
[root@binghe harbor]# ./prepare
Das Basisverzeichnis „prepare“ ist auf /mnt/harbour eingestellt.
Löschen der Konfigurationsdatei: /config/log/logrotate.conf
Löschen der Konfigurationsdatei: /config/nginx/nginx.conf
Löschen der Konfigurationsdatei: /config/core/env
Löschen der Konfigurationsdatei: /config/core/app.conf
Löschen der Konfigurationsdatei: /config/registry/root.crt
Löschen der Konfigurationsdatei: /config/registry/config.yml
Löschen der Konfigurationsdatei: /config/registryctl/env
Löschen der Konfigurationsdatei: /config/registryctl/config.yml
Löschen der Konfigurationsdatei: /config/db/env
Löschen der Konfigurationsdatei: /config/jobservice/env
Löschen der Konfigurationsdatei: /config/jobservice/config.yml
Generierte Konfigurationsdatei: /config/log/logrotate.conf
Generierte Konfigurationsdatei: /config/nginx/nginx.conf
Generierte Konfigurationsdatei: /config/core/env
Generierte Konfigurationsdatei: /config/core/app.conf
Generierte Konfigurationsdatei: /config/registry/config.yml
Generierte Konfigurationsdatei: /config/registryctl/env
Generierte Konfigurationsdatei: /config/db/env
Generierte Konfigurationsdatei: /config/jobservice/env
Generierte Konfigurationsdatei: /config/jobservice/config.yml
Geheimnis aus Datei geladen: /secret/keys/secretkey
Generierte Konfigurationsdatei: /compose_location/docker-compose.yml
Bereinigen Sie das Eingabeverzeichnis
 
[root@binghe harbor]# docker -compose up -d
Erstellen von Netzwerk "Harbor_harbor" mit dem Standardtreiber
Hafenlog erstellen ... fertig
Harbor-DB wird erstellt ... fertig
Redis erstellen ... fertig
Registrierung erstellen ... fertig
Registryctl erstellen ... fertig
Erstellen von Harbor-Core ... fertig
Erstellen von harbour-jobservice ... fertig
Hafenportal erstellen ... fertig
Nginx erstellen ... fertig
 
[root@binghe harbor]# docker ps -a
CONTAINER ID BILD BEFEHL ERSTELLT STATUS PORTS

Installieren Sie Jenkins (allgemeiner Ansatz)

Jenkins ist ein Open-Source-Tool für Continuous Integration (CI), das eine benutzerfreundliche Schnittstelle bietet. Jenkins ist in Java geschrieben und kann in beliebten Servlet -Containern wie Tomcat oder unabhängig betrieben werden. Es wird normalerweise in Verbindung mit Versionstools (Versionsmanagementtools) und Build -Tools verwendet. Zu den häufig verwendeten Versionskontrollwerkzeugen gehören SVN und Git sowie Build -Tools Maven, ANT und Gradle.

1. Installieren Sie NFS (wenn es zuvor installiert wurde, können Sie diesen Schritt überspringen).

Das größte Problem bei der Verwendung von NFS ist die Schreibberechtigung. Der Einfachheit halber dürfen alle Benutzer hier schreiben.

Wenn bereits NFS installiert wurde, kann dieser Schritt weggelassen werden. Finden Sie einen Host und installieren Sie NFS.

Geben Sie den folgenden Befehl in die Befehlszeile ein, um NFS zu installieren und zu starten.

yum installieren nfs -utils -y -y
Systemctl Start NFS-Server
SystemCTL aktivieren NFS-Server

2. Erstellen Sie ein NFS Shared Directory

Erstellen Sie das Verzeichnis /opt/nfs/jenkins-data im Master-Knoten (TEST10-Server) als gemeinsam genutztes Verzeichnis von NFS, wie unten gezeigt.

Mkdir -p/opt/nfs/jenkins -data

Bearbeiten Sie als nächstes die Datei /etc /exports wie unten gezeigt.

vim /etc/exports

Fügen Sie der Datei /etc /Exportdatei die folgende Konfigurationszeile hinzu.

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

Das IP verwendet die IP all_squash Reichweite des /opt/nfs/jenkins-data Knotens.

Diese Option ist sehr effektiv, wenn der Benutzer, der den Prozess startet, aufgrund unregelmäßiger Benutzer -UIDs bei vielen Maschinen unterschiedlich ist. Gleichzeitig hat jedoch Schreibberechtigungen in ein freigegebenes Verzeichnis.

Als nächstes gewähren Sie das Verzeichnis /opt/nfs/jenkins-data -Verzeichnis/opt/nFS/jenkins-data und laden Sie die NFS wie unten gezeigt nach.

#Authorisieren Sie/opt/nfs/jenkins-data/Verzeichnis Chown -r 1000/opt/nfs/jenkins-data/
#Reload NFS-Server
SystemCTL Reload NFS-Server

Verwenden Sie den folgenden Befehl, um auf einem beliebigen Knoten im K8S -Cluster zu überprüfen:

#Achten Sie auf die Verzeichnisberechtigungen des NFS -Systems Showmount -e NFS_IP

Wenn Sie/opt/nfs/jenkins-data sehen können, bedeutet dies, dass alles in Ordnung ist.

Die Einzelheiten sind wie folgt.

[root@test10 ~]# showmount -e 192.168.0.10
Exportliste für 192.168.0.10:
/opt/nfs/jenkins-data 192.168.175.0/24

[root@test11 ~]# showmount -e 192.168.0.10
Exportliste für 192.168.0.10:
/opt/nfs/jenkins-data 192.168.175.0/24

3. Erstellen Sie PV

Tatsächlich können Jenkins frühere Daten lesen, solange es das entsprechende Verzeichnis lädt. Da die Bereitstellung jedoch nicht Speichervolumina definieren kann, können wir nur einen Zustandsset verwenden.

Erstellen Sie zuerst eine PV.

Erstellen Sie die Jenkins-pv.yaml-Datei mit dem folgenden Inhalt.

API-Version: v1
Art: Persistentvolume
Metadaten:
  Name: Jenkins
Spezifikation:
  NFS:
    Pfad:/opt/nfs/jenkins-data
    Server: 192.168.0.10
  AccessModes: ["Readwriteonce"]
  Kapazität:
    Speicherung: 1Ti

Ich habe hier 1T Speicherplatz gegeben, was entsprechend den tatsächlichen Anforderungen konfiguriert werden kann.

Führen Sie den folgenden Befehl aus, um einen PV zu erstellen.

kubectl anwenden -f jenkins -pv.yaml

4. Erstellen Sie einen ServiceAccount

Erstellen Sie ein Servicekonto, da Jenkins in der Lage sein muss, später dynamisch Sklaven zu erstellen, damit es einige Berechtigungen haben muss.

Erstellen Sie die Datei jenkins service-account.yaml mit dem folgenden Inhalt.

API-Version: v1
Art: ServiceAccount
Metadaten:
  Name: Jenkins

---
Art: Rolle
API-Version: rbac.authorization.k8s.io/v1beta1
Metadaten:
  Name: Jenkins
Regeln:
  -apigroups: [""]
    Ressourcen: ["Pods"]
    Verben: ["erstellen", "löschen", "Get", "Liste", "Patch", "Update", "Watch"]
  -apigroups: [""]
    Ressourcen: ["Pods/Exec"]
    Verben: ["erstellen", "löschen", "Get", "Liste", "Patch", "Update", "Watch"]
  -apigroups: [""]
    Ressourcen: ["Pods/Log"]
    Verben: ["Get", "Liste", "Uhr"]
  -apigroups: [""]
    Ressourcen: ["Geheimnisse"]
    Verben: ["Get"]

---
API-Version: rbac.authorization.k8s.io/v1beta1
Art: RoleBinding
Metadaten:
  Name: Jenkins
Rollenreferenz:
  API-Gruppe: rbac.authorization.k8s.io
  Art: Rolle
  Name: Jenkins
Themen:
  - Art: ServiceAccount
    Name: Jenkins

In der obigen Konfiguration werden eine Rollenverbindung und ein ServiceAccount erstellt, und die Berechtigungen der Rollenbindung sind an diesen Benutzer gebunden. Daher muss der Jenkins -Container mit diesem serviceAccount ausgeführt werden, andernfalls hat er nicht die Berechtigungen der Rollenbindung.

Die Berechtigungen der Rollenverbindung sind leicht zu verstehen, da Jenkins Sklaven erstellen und löschen muss, sodass die oben genannten Berechtigungen erforderlich sind. In Bezug auf Geheimnisse berechtigt das HTTPS -Zertifikat.

Führen Sie den folgenden Befehl aus, um einen ServiceAccount zu erstellen.

kubectl anwenden -f jenkins-service-account.yaml 

5. Jenkins installieren

Erstellen Sie die Datei jenkins-statefulSet.yaml mit den folgenden Inhalten.

API-Version: Apps/v1
Art: StatefulSet
Metadaten:
  Name: Jenkins
  Beschriftungen:
    Name: Jenkins
Spezifikation:
  Wähler:
    Übereinstimmungsetiketten:
      Name: Jenkins
  Servicename: Jenkins
  Replikate: 1
  Updatestrategie:
    Typ: RollingUpdate
  Vorlage:
    Metadaten:
      Name: Jenkins
      Beschriftungen:
        Name: Jenkins
    Spezifikation:
      TerminationGraceperiodSeconds: 10
      serviceAccountName: Jenkins
      Behälter:
        - Name: Jenkins
          Bild: Docker.io/jenkins/jenkins:lts
          imagePullPolicy: IfNotPresent
          Häfen:
            - Containerport: 8080
            - Containerport: 32100
          Ressourcen:
            Grenzen:
              Zentralprozessor: 4
              Speicher: 4GI
            Anfragen:
              Zentralprozessor: 4
              Speicher: 4GI
          Umgebung:
            - Name: Limits_Memory
              Wert von:
                ResourceFieldref:
                  Ressource: Limits.Memory
                  Divisor: 1mi
            - Name: Java_Opts
              # Wert: -xx:+unlocexperimentalvMoptions -xx:+usecgroupmemorylimitforheap -xx: maxramfraction = 1 -xshowSets: VM -Dhudson.Slaves.NodeProvisioner.initieldelay = 0 -dhudson.Slaves.nodeProvisioner.marn. .Margin0 = 0,85
              Wert: -xmx $ (limits_memory) m -xshowSetting: vm -dhudson.slaves.nodeProvisioner.initialdelay = 0 -dhudson.slaves.nodeProvisioner.Margin = 50 -dhudson.slaves.nodeProvisioner.marin0 = 0.85 = 0.85
          Volumenhalterungen:
            - Name: Jenkins-Home
              MountPath: /var /jenkins_home
          LivenessProbe:
            httpGet:
              Pfad: /Login
              Port: 8080
            Initialdelaysseconds: 60
            Timeoutsconds: 5
            failurethreshold: 12 # ~ 2 Minuten
          Bereitschaftsprobe:
            httpGet:
              Pfad: /Login
              Port: 8080
            Initialdelaysseconds: 60
            Timeoutsconds: 5
            failurethreshold: 12 # ~ 2 Minuten
  # PVC -Vorlage, entsprechend dem vorherigen PV
  VolumeClaimTemplates:
    - Metadaten:
        Name: Jenkins-Home
      Spezifikation:
        AccessModes: ["Readwriteonce"]
        Ressourcen:
          Anfragen:
            Speicherung: 1Ti

Bei der Bereitstellung von Jenkins müssen Sie die Anzahl der Repliken beachten. Hier habe ich nur eine Kopie verwendet, so dass zuvor nur ein PV erstellt wurde.

Installieren Sie Jenkins mit dem folgenden Befehl.

kubectl anwenden -f jenkins -statefulSet.yaml 

6. Service erstellen

Erstellen Sie die Datei jenkins service.yaml, die hauptsächlich zum Ausführen von Jenkins im Hintergrund verwendet wird.

API-Version: v1
Art: Dienstleistung
Metadaten:
  Name: Jenkins
Spezifikation:
  # Typ: LoadBalancer
  Wähler:
    Name: Jenkins
  # Stellen Sie sicher, dass die Client -IP propagiert ist, um das Problem der ungültigen Krümel bei Verwendung von LoadBalancer (K8S> = 1,7) zu vermeiden.
  #externaltrafficpolicy: lokal
  Häfen:
    - Name: http
      Anschluss: 80
      Nodeport: 31888
      TargetPort: 8080
      Protokoll: TCP
    - Name: Jenkins-Agent
      Port: 32100
      Nodeport: 32100
      TargetPort: 32100
      Protokoll: TCP
  Typ: NodePort

Verwenden Sie den folgenden Befehl, um den Dienst zu installieren.

kubectl anwenden -f jenkins service.yaml

7. Eindringung installieren

Die Jenkins -Weboberfläche muss von außerhalb des Clusters zugegriffen werden, und hier verwenden wir Eingang. Erstellen Sie die Datei jenkins-Zugress.yaml mit dem folgenden Inhalt.

API-Version: Erweiterungen/v1beta1
Art: Ingress
Metadaten:
  Name: Jenkins
Spezifikation:
  Regeln:
    - http:
        Pfade:
          - Weg: /
            Backend:
              Servicename: Jenkins
              ServicePort: 31888
      Host: jekins.binghe.com

Hier ist zu beachten, dass der Host als Domänenname oder Hostname konfiguriert werden muss, andernfalls wird ein Fehler gemeldet, wie unten gezeigt.

Der Eingang "Jenkins" ist ungültig: Spec.Rules [0] .HOST: Ungültiger Wert: "192.168.0.10": Muss ein DNS -Name sein, keine IP -Adresse

Verwenden Sie den folgenden Befehl, um die Eindringung zu installieren.

kubectl anwenden -f jenkins -Zugress.yaml 

Da ich eine virtuelle Maschine benutze, um die relevante Umgebung zu erstellen, müssen Sie die lokale Hosts -Datei konfigurieren und die folgenden Konfigurationselemente in die lokale Hosts -Datei hinzufügen.

192.168.0.10 jekins.binghe.com

Hinweis: In Windows -Betriebssystemen befindet sich die Hosts -Datei im folgenden Verzeichnis.

C: \ Windows \ System32 \ Treiber \ usw.

Als nächstes können Sie über den Link auf Jenkins in Ihrem Browser zugreifen: http://jekins.binghe.com:31888.

Installieren Sie SVN auf einer physischen Maschine

Apache Subversion, häufig als SVN abgekürzt, ist ein Open -Source -Versionskontrollsystem.

Im Vergleich zu RCS und CVS verwendet SVN ein Zweig -Management -System, und sein Entwurfsziel ist es, CVS zu ersetzen. Die meisten kostenlosen Versionskontrolldienste im Internet basieren auf Subversion.

Hier nehmen wir als Beispiel die Installation von SVN auf dem Masterknoten (Binghe101 -Server).

1. Installieren Sie SVN mit Yum

Führen Sie den folgenden Befehl in der Befehlszeile aus, um SVN zu installieren.

yum -y -Subversion installieren 

2. Erstellen Sie ein SVN -Repository

Führen Sie die folgenden Befehle nacheinander aus.

#Create /data /svn
Mkdir -p /data /svn 
# SVN initialisieren
svnserve -d -r /data /svn
#Create ein Code -Repository Svnadmin create/data/svn/test

3. Konfigurieren Sie SVN

mkdir/data/svn/conf
cp/data/svn/test/conf/*/data/svn/conf/
cd/data/svn/conf/
[root@binghe101 conf]# ll
Gesamtdosis 20
-RW-R-R-- 1 Root Root 1080 12. Mai 02:17 Authz
-RW-R-R-- 1 Root Root 885 12. Mai 02:17 Hooks-env.tmpl
-RW-R-R-- 1 Root Root 309 12. Mai 02:17 Passwd
-RW-R-R-- 1 Root Root 4375 12. Mai 02:17 SVNSERVE.CONF

Konfigurieren Sie die Authz -Datei,

Vim Authz

Der Inhalt nach der Konfiguration ist wie folgt.

[Aliase]
# joe =/c = xz/st = Dessert/l = Schlangenstadt/o = Schlangenöl, Ltd./ou=research Institute/CN = Joe Average

[Gruppen]
# Harry_and_Sally = Harry, Sally
# Harry_Sally_and_joe = Harry, Sally und Joe
Superadmin = admin
Binghe = admin, Binghe

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

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

[prüfen:/]
@Superadmin = rw
@Binghe = rw

Konfigurieren Sie die PassWD -Datei

Vim Passwd

Der Inhalt nach der Konfiguration ist wie folgt.

[Benutzer]
# Harry = Harryssecret
# Sally = SallySsecret
admin = admin123
Binghe = Binghe123

Konfigurieren Sie svnserve.conf

vim svnserve.conf

Die konfigurierte Datei lautet wie folgt.

### Diese Datei steuert die Konfiguration des Svnserve -Daemons, wenn Sie
### verwenden es, um den Zugriff auf dieses Repository zu ermöglichen.
### Zugriff über http: und/oder Datei: URLs, dann ist diese Datei lautet
### irrelevant.)

### Besuchen Sie http://subversion.apache.org/ für weitere Informationen.

[allgemein]
### Die Optionen für Anon-Access und Auth-Access steuern den Zugriff auf die
### Repository für nicht authentifizierte (auch bekannt als anonyme) Benutzer und
### authentifizierte Benutzer.
### Gültige Werte sind "schreiben", "lesen" und "keine".
### Das Wert des Wertes auf "Keine" verbietet sowohl das Lesen als auch das Schreiben.
### "lesen" ermöglicht schreibgeschützte Zugriff, und "schreiben" ermöglicht die Vervollständigung 
### Lesen/Schreibzugriff auf das Repository.
### Die folgenden Beispieleinstellungen sind die Standardeinstellungen und geben Sie diese anonym an
### Benutzer haben schreibgeschützte Zugriff auf das Repository, während sie authentifiziert sind
### Benutzer haben Zugriff auf das Repository gelesen und schreiben.
anon-access = keine
auth-access = write
### Die Option Passwort-DB steuert den Speicherort des Kennworts
### Datenbankdatei.
### Der Speicherort der Datei ist relativ zum Verzeichnis, das enthält
### Diese Konfigurationsdatei.
### Wenn SASL aktiviert ist (siehe unten), wird diese Datei nicht verwendet.
### Überzeugen Sie die folgende Zeile, um die Standardkennwortdatei zu verwenden.
password-db =/data/svn/conf/passwd
### Die Option Authz-DB steuert den Ort der Autorisierung
### Regeln für die Pfadzugriffskontrolle.
### Beginnend mit A /ist der Standort der Datei relativ zur
### Verzeichnis mit dieser Datei.
### Repository Relative URL (^/) oder eine absolute Datei: // URL zu einem Text
### Datei in einem Subversion-Repository.
### Kein Pfad-basierter Zugriffskontrolle wird durchgeführt.
### Überzeugen Sie die folgende Zeile, um die Standardautorisierungsdatei zu verwenden.
authz-db =/data/svn/conf/authz
### Die Option Gruppen-DB steuert den Speicherort der Datei mit der Datei
### Gruppendefinitionen und ermöglicht die Aufrechterhaltung von Gruppen getrennt von der
### Autorisierungsregeln.
### Authz-DB-Datei und sollte einen einzelnen [Gruppen] -Abschnitt mit dem enthalten
### Gruppendefinitionen.
### enthalten einen Abschnitt [Gruppen].
### a /, der Speicherort der Datei ist relativ zum Verzeichnis, das dies enthält
### Datei.
### Absolute Datei: // url zu einer Textdatei in einem Subversion -Repository.
### Diese Option wird standardmäßig nicht verwendet.
# Gruppen-db = Gruppen
### Diese Option gibt den Authentifizierungsbereich des Repositorys an.
### Wenn zwei Repositorys den gleichen Authentifizierungsbereich haben, sollten sie es sollten
### haben die gleiche Passwortdatenbank und umgekehrt
### ist das UUID von Repository.
realm = svn
### Die Option für Kraftverbrauchername-Case führt dazu
### Benutzernamen Bevor Sie sie mit den Autorisierungsregeln in der vergleiche
### Authz-DB-Datei oben konfiguriert.
### Fall die Benutzernamen), "niedriger" (um die Benutzernamen zu unterbinden), und
### "Keine" (um Benutzernamen wie ohne Fallumwandlung zu vergleichen, welche
### ist das Standardverhalten).
# Force-Unername-Case = Keine
### Die Hooks-Env-Optionen gibt einen Pfad zur Hakenskriptumgebung an 
### Konfigurationsdatei.
### und kann verwendet werden, um die Hakenskriptumgebung für mehrere zu konfigurieren 
### Repositories in einer einzigen Datei, wenn ein absoluter Pfad angegeben ist.
### Sofern Sie einen absoluten Pfad angeben, ist der Speicherort der Datei relativ relativ
### in das Verzeichnis, das diese Datei enthält.
# Hooks-Env = Hooks-Env

[SASL]
### Diese Option gibt an, ob Sie den Cyrus SASL verwenden möchten
### Bibliothek zur Authentifizierung.
### Für diese Option muss SVNServe mit Cyrus gebaut werden
### SASL -Unterstützung;
### Lesen 'Cyrus SASL -Authentifizierung ist verfügbar.'
# use-sasl = true
### Diese Optionen geben die gewünschte Stärke der Sicherheitsschicht an
###, die SASL bereitstellen soll.
### Integritätsprüfung nur, Werte größer als 1 sind korreliert
### zur effektiven Schlüssellänge für die Verschlüsselung (z. B. 128 bedeutet 128-Bit
### Verschlüsselung).
# min-cryption = 0
# max-cryption = 256

Kopieren Sie als nächstes die Datei svnServe.conf in das Verzeichnis/data/svn/conf in das Verzeichnis/data/svn/test/conf/konf. Wie unten gezeigt.

[root@binghe101 conf]# cp /data/svn/conf/svnserve.conf/data/svn/test/conf/
CP: Überschreibe '/data/svn/test/conf/svnserve.conf'? j

4. Starten Sie den SVN -Dienst

(1) Erstellen Sie den SVNService -Service -Service

Erstellen Sie die Datei svnserve.Service

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

Der Inhalt der Datei ist unten angezeigt.

[Einheit]
Beschreibung = Subversion Protocol Dämon
After = syslog.target network.target
Dokumentation = Mann: SvnServe (8)

[Service]
Typ=Forking
EnvironmentFile =/etc/sysconfig/svnServe
#Execstart =/usr/bin/svnserve--daemon--pid-file =/run/svnserve/svnserve.pid $ option
ExecStart =/usr/bin/svnserve - -daemon $ option
Privatetmp = ja

[Installieren]
WantedBy=Mehrbenutzer.Ziel

Führen Sie als Nächstes den folgenden Befehl aus, um die Konfiguration in Kraft zu setzen.

systemctl daemon-reload

Nachdem der Befehl erfolgreich ausgeführt wurde, ändern Sie die Datei/etc/sysconfig/svnserve.

vim/etc/sysconfig/svnserve

Der geänderte Dateiinhalt ist wie folgt.

# Optionen werden verwendet, um Befehlszeilenargumente an SVNServe zu übergeben.
# 
# Geben Sie den Repository -Speicherort in -R -Parameter an:
Optionen = "-r /data /svn"

(2) SVN starten

Überprüfen Sie zunächst den SVN -Status wie unten gezeigt.

[root@test10 conf]# systemctl status svnserve.service
● SvnServe.Service - Subversion Protocol Dämon
   Laden: geladen (/usr/lib/systemd/system/svnserve.service; deaktiviert; Anbieter Preset: Deaktiviert)
   Aktiv: inaktiv (tot)
     Dokumente: Mann: Svnserve (8)

Wie Sie sehen können, wird SVN zu diesem Zeitpunkt nicht gestartet.

SystemCTL START SVNSERVE.Service

Legen Sie den SVN -Dienst so ein, dass sie automatisch beim BOOT gestartet werden.

SystemCTL aktivieren svnserve.service

Als nächstes können Sie Tortoisesvn herunterladen und installieren, den Link SVN: //192.168.0.10/test eingeben und den Benutzernamen Binghe und Passwort Binghe123 eingeben, um eine Verbindung zu SVN herzustellen.

Installieren Sie SVN mit Docker

Ziehen Sie das SVN -Bild ab

Docker Pull Docker.io/elleflorio/Svn-Server

Starten Sie den SVN -Behälter

Docker run -v/usr/local/svn:/home/svn -v/usr/local/svn/passwd:/etc/subversion/passwd -v/usr/local/apache2:/run/apache2 -name ver

Geben Sie den SVN -Container ein

Docker Exec -it SVN_SERVER BASH

Nach dem Eingeben des Containers können Sie das SVN -Repository konfigurieren, indem Sie sich auf die Methode zur Installation von SVN auf einer physischen Maschine verweisen.

Installieren Sie Jenkins auf einer physischen Maschine

HINWEIS: JDK und Maven müssen vor der Installation von Jenkins installiert werden.

1. Aktivieren Sie das Jenkins -Repository

Führen Sie die folgenden Befehle aus, um die Repo -Datei herunterzuladen und den GPG -Schlüssel zu importieren:

wget -o/
RPM-Import https://jenkins-ci.org/redhat/jenkins-ci.org.key

2. Installieren Sie Jenkins

Führen Sie den folgenden Befehl aus, um Jenkins zu installieren.

Yum Installieren Sie Jenkins

Ändern Sie als Nächstes den Standardport von Jenkins, wie unten gezeigt.

vim/etc/sysconfig/jenkins

Die beiden geänderten Konfigurationen sind unten angezeigt.

Jenkins_java_cmd = "/usr/local/jdk1.8.0_212/bin/java"
Jenkins_port = "18080"

Zu diesem Zeitpunkt wurde der Jenkins -Port von 8080 auf 18080 geändert

3. Starten Sie Jenkins

Geben Sie den folgenden Befehl in die Befehlszeile ein, um Jenkins zu starten.

Systemctl Start Jenkins

Konfigurieren Sie Jenkins, um automatisch am Boot zu starten.

SystemCTL aktivieren Jenkins

Überprüfen Sie den laufenden Status von Jenkins.

[root@test10 ~]# systemctl Status Jenkins
● Jenkins.Service - LSB: Jenkins Automation Server
   Laden: geladen (/etc/rc.d/init.d/jenkins; generiert)
   Aktiv: aktiv (laufend) seit Di 2020-05-12 04:33:40 EDT;
     DOCS: MAN: SYSTEMD-SYSV-Generator (8)
    Aufgaben: 71 (Grenze: 26213)
   Speicher: 550,8 m

Dies weist darauf hin, dass Jenkins erfolgreich gestartet wurde.

Konfigurieren Sie die Betriebsumgebung von Jenkins

1. Melden Sie sich bei Jenkins an

Nach der ersten Installation müssen Sie die Betriebsumgebung von Jenkins konfigurieren. Greifen Sie zunächst in der Browser -Adressleiste auf den Link zu http://192.168.0.10:18080, um die Jenkins -Schnittstelle zu öffnen.

Befolgen Sie die Eingabeaufforderungen und verwenden Sie den folgenden Befehl, um den Kennwortwert auf dem Server zu ermitteln, wie unten gezeigt.

[root@binghe101 ~]# cat/var/lib/jenkins/secrets/initialAdminpassword
71AF861C2AB948A1B6EFC9F7DDE90776

Kopieren Sie das Passwort 71AF861C2AB948A1B6EFC9F7DDE90776 in das Textfeld und klicken Sie auf Weiter. Sie werden wie unten gezeigt auf die Seite "Jenkins" anpassen.

Hier können Sie direkt "empfohlene Plug-Ins installieren" auswählen. Danach werden Sie zum Installieren des Plug-Ins zu einer Seite umgeleitet, wie unten gezeigt.

Dieser Schritt kann zum Download -Fehler führen, der ignoriert werden kann.

2. Installieren Sie das Plugin

Plug-Ins, die installiert werden müssen

  • Kubernetes CLI -Plugin: Mit diesem Plugin können Sie die Befehlszeile Kubernetes direkt in Jenkins verwenden.
  • Kubernetes -Plugin: Wenn Sie Kubernetes verwenden, müssen Sie dieses Plugin Kubernetes installieren
  • Continuous Deploy Plugin: Kubernetes Deployment Plugin kann nach Bedarf verwendet werden

Es gibt mehr Plug-Ins zur Auswahl. Andere Plugins können bei Bedarf installiert werden. Wie in der Abbildung unten gezeigt.

3. Konfigurieren Sie Jenkins

(1) Konfigurieren Sie JDK und Maven

Konfigurieren Sie JDK und Maven in der globalen Toolkonfiguration wie unten gezeigt.

Als nächstes werden wir mit der Konfiguration von JDK und Maven beginnen.

Da ich Maven im Verzeichnis /usr/local/maven-3.6.3 auf dem Server installiert habe, muss ich es in "Maven-Konfiguration" konfigurieren, wie in der Abbildung unten gezeigt.

Konfigurieren Sie als nächstes den JDK wie unten gezeigt.

Hinweis: Überprüfen Sie nicht "automatisch installieren"

Konfigurieren Sie Maven als nächstes wie unten gezeigt.

Hinweis: Überprüfen Sie nicht "automatisch installieren"

(2) SSH konfigurieren

Geben Sie die Konfigurationssystemschnittstelle von Jenkins ein und konfigurieren Sie SSH wie unten gezeigt.

Finden Sie SSH -Remote -Hosts und konfigurieren Sie es.

Nach Abschluss der Konfiguration klicken Sie auf die Schaltfläche Überprüfen und eine erfolgreiche Verbindung werden angezeigt. Wie unten gezeigt.

Zu diesem Zeitpunkt ist die grundlegende Konfiguration von Jenkins vollständig.

Jenkins veröffentlicht Docker Project an K8s Cluster

1. Passen Sie die Konfiguration des Springboot -Projekts an

Um es zu implementieren, muss die POM.xml -Datei des Moduls, in der sich die Startklasse im Springboot -Projekt befindet, die in das Docker -Bild verpackte Konfiguration einführen, wie unten gezeigt.

 <Eigenschaften>
  	 	<Docker.Repostory> 192.168.0.10:1180 </docker.reposterory>
        <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>
  </Eigenschaften>

<Bauen>
  		<Dendname> Test-Starter </FinalName>
		<Plugins>
            <Plugin>
			    <groupId>org.springframework.boot</groupId>
			    <artifactId>Spring-Boot-Maven-Plugin</artifactId>
			</plugin>
			
			<!-Docker Maven Plugin, offizielle Website: 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>
			    <Hinrichtungen>
			        <Ausführung>
			        <id>Standard</id>
			        <Ziele>
			            <!-Wenn Sie keine Docker-Verpackung verwenden möchten, kommentieren Sie dieses Ziel->
			            <goal>bauen</goal>
			            <goal>drücken</goal>
			        </Ziele>
			        </Ausführung>
			    </Ausführungen>
			    <Konfiguration>
			    	<contextDirectory> $ {project.basedir} </contextDirectory>
			        <!-Harbour Warehouse Benutzername und Passwort->
			        <UsemavensettingsforAuth> UsemavensettingsforAuth> True </UsemavensettingsforAuth>
			        <repository> $ {docker.repostory}/$ {docker.registry.name}/$ {project.artifactid} </repository>
			        <Tag> $ {docker.image.tag} </tag>
			        <BuildArgs>
			            <JAR_FILE>Ziel/${project.build.finalName}.jar</JAR_FILE>
			        </buildArgs>
			    </Konfiguration>
			</plugin>

        </plugins>
        
		<Ressourcen>
			<!-Geben Sie alle Dateien und Ordner unter SRC/Main/Ressourcen als Ressourcendateien an->
			<Ressource>
				<Verzeichnis>src/main/ressourcen</Verzeichnis>
				<TargetPath> $ {project.build.directory}/classes </targetPath>
				<beinhaltet>
					<Clycleat> **/*</include>
				</beinhaltet>
				<filtering>wahr</filtering>
			</Ressource>
		</Ressourcen>
	</bauen>

Erstellen Sie als nächstes eine Dockerfile im Stammverzeichnis des Moduls, in dem sich die Startklasse für Springboot befindet.

#Add Abhängigkeitsumgebung, die Prämisse besteht darin, das Java8 Docker -Bild aus dem offiziellen Image -Repository zu ziehen und es dann von 192.168.0.10:1180/library/java:8 in Ihr eigenes Hafen -Repository hochzuladen
#Geben Sie den Bildungsautor der Bilderstellung an, Binghe
#Run Verzeichnisvolumen /TMP
#Copy die lokalen Dateien zum Container Fügen Sie Ziel hinzu/*jar app.jar
#Commands, die automatisch ausgeführt werden, nachdem er den Container-Einstiegspunkt ["Java", "-djava.security.egd = Datei:/dev /./ urandom", "-jar", "/app.jar"] ausgeführt wird.

Ändern Sie es gemäß der tatsächlichen Situation.

Hinweis: Die Prämisse von 192.168.0.10:1180/library/java:8 besteht darin, den folgenden Befehl auszuführen.

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

Erstellen Sie eine YAML -Datei im Stammverzeichnis des Moduls, in dem sich die Springboot -Startklasse befindet.

API-Version: Apps/v1
Art: Bereitstellung
Metadaten:
  Name: Teststarter
  Beschriftungen:
    App: Teststarter
Spezifikation:
  Replikate: 1
  Wähler:
    Übereinstimmungsetiketten:
      App: Teststarter
  Vorlage:
    Metadaten:
      Beschriftungen:
        App: Teststarter
    Spezifikation:
      Behälter:
      - Name: Teststarter
        Bild: 192.168.0.10:1180/test/teststarter:1.0.0
        Häfen:
        - Containerport: 8088
      Knotenauswahl:
        clusternype: node12

---
API-Version: v1
Art: Dienstleistung
Metadaten:
  Name: Teststarter
  Beschriftungen:
    App: Teststarter
Spezifikation:
  Häfen:
    - Name: http
      Port: 8088
      Nodeport: 30001
  Typ: NodePort
  Wähler:
    App: Teststarter

2. Konfigurieren Sie Jenkins, um das Projekt zu veröffentlichen

Laden Sie das Projekt in das SVN -Code -Repository hoch. Die Adresse lautet beispielsweise SVN: //192.168.0.10/test

Konfigurieren Sie als nächstes die automatische Veröffentlichung in Jenkins. Die Schritte sind wie folgt.

Klicken Sie auf neues Element.

Geben Sie eine Beschreibung in das Textfeld Beschreibung ein, wie unten gezeigt.

Konfigurieren Sie als Nächstes die SVN -Informationen.

Hinweis: Die Schritte zum Konfigurieren von GitLab sind die gleichen wie für SVN und werden hier nicht wiederholt.

Suchen Sie das "Build -Modul" von Jenkins und verwenden Sie Execute Shell, um das Projekt im K8S -Cluster zu erstellen und zu veröffentlichen.

Die ausgeführten Befehle sind wie folgt.

#Delete Das ursprüngliche lokale Bild, das das Bild im Harbor Warehouse Docker RMI 192.168.0.10:1180/test/teststarter:1.0.0 nicht beeinflusst
#Verwenden Sie Maven, um das Docker -Bild zu kompilieren und zu erstellen.
#Log in Harbor Warehouse Docker Login 192.168.0.10:1180 -U Binghe -p Binghe123
#Upload das Bild an den Hafen-Repository Docker Push 192.168.0.10:1180/test/teststarter:1.0.0
#Stop und löschen/usr/bin/kubectl löschen -f -test.yaml im K8S -Cluster ausgeführt
#Repusiepish das Docker -Bild zum K8S Cluster/usr/bin/kubectl anwenden -f -test.yaml

Dies ist das Ende dieses Artikels zum Aufbau einer kontinuierlichen Integration und Lieferung, die auf Docker+K8S+Gitlab/SVN+Jenkins+Harbor (Umweltkonstruktion) für kontinuierliche Integration und Lieferumgebung für Docker K8s gesucht wird.

Das könnte Sie auch interessieren:
  • Verwenden der Docker+Jenkins+Python3-Umgebung zum Erstellen eines äußerst detaillierten Tutorials
  • Detailliertes Tutorial zur Installation des Jenkins-Containers in einer Docker-Umgebung
  • Beim Einrichten von Jenkins in einer Docker-Umgebung werden im Konsolenprotokoll beim Erstellen von Aufgaben verstümmelte chinesische Zeichen angezeigt
  • Über das Problem, die Jenkins -Umgebung mit Docker zu starten

<<:  Sechsstufiger Beispielcode für eine JDBC-Verbindung (Verbindung zu MySQL)

>>:  Zusammenfassung einiger gängiger Methoden von JavaScript-Arrays

Artikel empfehlen

Spielen Sie mit der Connect-Funktion mit Timeout in Linux

Im vorherigen Artikel haben wir mit Timeouts unte...

Auszeichnungssprache - Bildersetzung

Klicken Sie hier, um zum Abschnitt „HTML-Tutorial“...

So konvertieren Sie Chinesisch in HTML in UTF-8

In HTML kann die chinesische Phrase „學好好學“ als „學...

Tutorial zur Installation von MySQL 5.7.18 auf Mac OS 10.12

Ich habe das ganze Internet durchsucht und bin au...

Verwendung von Docker-Image-Speicher-Overlays

1. Übersicht Das Image in Docker ist in Schichten...

Detaillierte Erklärung der node.js-Installation und HbuilderX-Konfiguration

Tutorial zur npm-Installation: 1. Laden Sie das N...

Einführung in das Fokuselement document.activeELEment in JavaScript

Inhaltsverzeichnis 1. Der Fokus liegt standardmäß...

Eine kurze Erläuterung der $notify-Punkte des Elements

Meine ursprüngliche Absicht war, die $notify-Bena...

Methode und Optimierungsprinzip für langsame MySQL-Abfragen

1. Zum Vergleich der Datumsgröße muss das an XML ...