刚来公司一周,搭建了一套持续集成交付环境,研发效率直接提升20倍,CTO再次给我涨薪!!

#修改 /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

执行命令以应用

sysctl -p

配置K8S的yum源

cat < /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 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}

重启 docker,并启动 kubelet

systemctl daemon-reload

systemctl restart docker

systemctl enable kubelet && systemctl start kubelet

docker version

在每台服务器上为install_k8s.sh脚本赋予可执行权限,并执行脚本即可。

初始化Master节点

只在binghe101服务器上执行的操作。

1.初始化Master节点的网络环境

注意:下面的命令需要在命令行手动执行。

只在 master 节点执行

export 命令只在当前 shell 会话中有效,开启新的 shell 窗口后,如果要继续安装过程,请重新执行此处的 export 命令

export MASTER_IP=192.168.175.101

替换 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节点

在binghe101服务器上创建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 < ./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

根据服务器网速的情况,您需要等候 3 - 10 分钟

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脚本文件可执行权限并执行脚本。

3.查看Master节点的初始化结果

(1)确保所有容器组处于Running状态

执行如下命令,等待 3-10 分钟,直到所有的容器组处于 Running 状态

watch kubectl get pod -n kube-system -o wide

具体执行如下所示。

[root@binghe101 ~]# watch kubectl get pod -n kube-system -o wide

Every 2.0s: kubectl get pod -n kube-system -o wide binghe101: 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 binghe101

calico-node-fnv8g 1/1 Running 0 118s 192.168.175.101 binghe101

coredns-546565776c-27t7h 1/1 Running 0 2m1s 172.18.203.67 binghe101

coredns-546565776c-hjb8z 1/1 Running 0 2m1s 172.18.203.65 binghe101

etcd-binghe101 1/1 Running 0 2m7s 192.168.175.101 binghe101

kube-apiserver-binghe101 1/1 Running 0 2m7s 192.168.175.101 binghe101

kube-controller-manager-binghe101 1/1 Running 0 2m7s 192.168.175.101 binghe101

kube-proxy-dvgsr 1/1 Running 0 2m1s 192.168.175.101 binghe101

kube-scheduler-binghe101 1/1 Running 0 2m7s 192.168.175.101 binghe101

(2) 查看 Master 节点初始化结果

kubectl get nodes -o wide

具体执行如下所示。

[root@binghe101 ~]# kubectl get nodes -o wide

NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME

binghe101 Ready master 3m28s v1.18.2 192.168.175.101 CentOS Linux 8 (Core) 4.18.0-80.el8.x86_64 docker://19.3.8

初始化Worker节点

1.获取join命令参数

在Master节点(binghe101服务器)上执行如下命令获取join命令参数。

kubeadm token create --print-join-command

具体执行如下所示。

[root@binghe101 ~]# 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 节点执行,在这里,就是在binghe102服务器和binghe103服务器上执行。

在命令分别手动执行如下命令。

只在 worker 节点执行

192.168.175.101 为 master 节点的内网 IP

export MASTER_IP=192.168.175.101

替换 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@binghe102 ~]# export MASTER_IP=192.168.175.101

[root@binghe102 ~]# export APISERVER_NAME=k8s.master

[root@binghe102 ~]# echo “${MASTER_IP} ${APISERVER_NAME}” >> /etc/hosts

[root@binghe102 ~]# 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节点(binghe101服务器)执行如下命令查看初始化结果。

kubectl get nodes -o wide

具体执行如下所示。

[root@binghe101 ~]# kubectl get nodes

NAME STATUS ROLES AGE VERSION

binghe101 Ready master 20m v1.18.2

binghe102 Ready 2m46s v1.18.2

binghe103 Ready 2m46s v1.18.2

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

重启K8S集群引起的问题


1.Worker节点故障不能启动

Master 节点的 IP 地址发生变化,导致 worker 节点不能启动。需要重新安装K8S集群,并确保所有节点都有固定的内网 IP 地址。

2.Pod崩溃或不能正常访问

重启服务器后使用如下命令查看Pod的运行状态。

kubectl get pods --all-namespaces

发现很多 Pod 不在 Running 状态,此时,需要使用如下命令删除运行不正常的Pod。

kubectl delete pod -n

注意:如果Pod 是使用 Deployment、StatefulSet 等控制器创建的,K8S 将创建新的 Pod 作为替代,重新启动的 Pod 通常能够正常工作。

K8S安装ingress-nginx


注意:在Master节点(binghe101服务器上执行)

1.创建ingress-nginx命名空间

创建ingress-nginx-namespace.yaml文件,文件内容如下所示。

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文件,文件内容如下所示。

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 “-”

Here: “-”

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@binghe101 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@binghe101 k8s]# kubectl get svc -n ingress-nginx

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE

default-http-backend ClusterIP 10.96.247.2 80/TCP 7m3s

ingress-nginx NodePort 10.96.40.6 80:30080/TCP,443:30443/TCP 4m35s

所以,可以通过Master节点(binghe101服务器)的IP地址和30080端口号来访问ingress-nginx,如下所示。

[root@binghe101 k8s]# curl 192.168.175.101:30080

default backend - 404

也可以在浏览器打开http://192.168.175.101:30080 来访问ingress-nginx,如下所示。

在这里插入图片描述

K8S安装gitlab代码仓库


注意:在Master节点(binghe101服务器上执行)

1.创建k8s-ops命名空间

创建k8s-ops-namespace.yaml文件,文件内容如下所示。

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@binghe101 k8s]# echo -n ‘admin’ | base64

YWRtaW4=

[root@binghe101 k8s]# echo -n ‘admin.1231’ | base64

YWRtaW4uMTIzMQ==

转码后的用户名为:YWRtaW4= 密码为:YWRtaW4uMTIzMQ==

也可以对base64编码后的字符串解码,例如,对密码字符串解码,如下所示。

[root@binghe101 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@binghe101 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@binghe101 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@binghe101 k8s]# kubectl get svc -n k8s-ops

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE

gitlab NodePort 10.96.153.100 80:30088/TCP,22:30022/TCP 2m42s

postgresql ClusterIP 10.96.203.119 5432/TCP 32m

redis ClusterIP 10.96.107.150 6379/TCP 10h

此时,可以看到,可以通过Master节点(binghe101)的主机名gitlab.binghe.com和端口30088就能够访问GitLab。由于我这里使用的是虚拟机来搭建相关的环境,在本机访问虚拟机映射的gitlab.binghe.com时,需要配置本机的hosts文件,在本机的hosts文件中加入如下配置项。

192.168.175.101 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私有仓库


注意:这里将Harbor私有仓库安装在Master节点(binghe101服务器)上,实际生产环境中建议安装在其他服务器。

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.175.101

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.175.101: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.175.101:1180”]

}

4.安装并启动harbor

配置完成后,输入如下命令即可安装并启动Harbor

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

5.登录Harbor并添加账户

安装成功后,在浏览器地址栏输入http://192.168.175.101: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.175.101

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.175.101: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(一般的做法)


1.安装nfs(之前安装过的话,可以省略此步)

使用 nfs 最大的问题就是写权限,可以使用 kubernetes 的 securityContext/runAsUser 指定 jenkins 容器中运行 jenkins 的用户 uid,以此来指定 nfs 目录的权限,让 jenkins 容器可写;也可以不限制,让所有用户都可以写。这里为了简单,就让所有用户可写了。

如果之前已经安装过nfs,则这一步可以省略。找一台主机,安装 nfs,这里,我以在Master节点(binghe101服务器)上安装nfs为例。

在命令行输入如下命令安装并启动nfs。

yum install nfs-utils -y

systemctl start nfs-server

systemctl enable nfs-server

2.创建nfs共享目录

在Master节点(binghe101服务器)上创建 /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,如下所示。

chown -R 1000 /opt/nfs/jenkins-data/

systemctl reload nfs-server

在K8S集群中任意一个节点上使用如下命令进行验证:

showmount -e NFS_IP

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

具体如下所示。

[root@binghe101 ~]# showmount -e 192.168.175.101

Export list for 192.168.175.101:

/opt/nfs/jenkins-data 192.168.175.0/24

[root@binghe102 ~]# showmount -e 192.168.175.101

Export list for 192.168.175.101:

/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.175.101

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”]

写在最后

很多人感叹“学习无用”,实际上之所以产生无用论,是因为自己想要的与自己所学的匹配不上,这也就意味着自己学得远远不够。无论是学习还是工作,都应该有主动性,所以如果拥有大厂梦,那么就要自己努力去实现它。

最后祝愿各位身体健康,顺利拿到心仪的offer!

由于文章的篇幅有限,所以这次的蚂蚁金服和京东面试题答案整理在了PDF文档里

蚂蚁、京东Java岗4面:原理+索引+底层+分布式+优化等,已拿offer

蚂蚁、京东Java岗4面:原理+索引+底层+分布式+优化等,已拿offer

蚂蚁、京东Java岗4面:原理+索引+底层+分布式+优化等,已拿offer

1.安装nfs(之前安装过的话,可以省略此步)

使用 nfs 最大的问题就是写权限,可以使用 kubernetes 的 securityContext/runAsUser 指定 jenkins 容器中运行 jenkins 的用户 uid,以此来指定 nfs 目录的权限,让 jenkins 容器可写;也可以不限制,让所有用户都可以写。这里为了简单,就让所有用户可写了。

如果之前已经安装过nfs,则这一步可以省略。找一台主机,安装 nfs,这里,我以在Master节点(binghe101服务器)上安装nfs为例。

在命令行输入如下命令安装并启动nfs。

yum install nfs-utils -y

systemctl start nfs-server

systemctl enable nfs-server

2.创建nfs共享目录

在Master节点(binghe101服务器)上创建 /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,如下所示。

chown -R 1000 /opt/nfs/jenkins-data/

systemctl reload nfs-server

在K8S集群中任意一个节点上使用如下命令进行验证:

showmount -e NFS_IP

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

具体如下所示。

[root@binghe101 ~]# showmount -e 192.168.175.101

Export list for 192.168.175.101:

/opt/nfs/jenkins-data 192.168.175.0/24

[root@binghe102 ~]# showmount -e 192.168.175.101

Export list for 192.168.175.101:

/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.175.101

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”]

写在最后

很多人感叹“学习无用”,实际上之所以产生无用论,是因为自己想要的与自己所学的匹配不上,这也就意味着自己学得远远不够。无论是学习还是工作,都应该有主动性,所以如果拥有大厂梦,那么就要自己努力去实现它。

最后祝愿各位身体健康,顺利拿到心仪的offer!

由于文章的篇幅有限,所以这次的蚂蚁金服和京东面试题答案整理在了PDF文档里

[外链图片转存中…(img-7ZZGJLMX-1719189663754)]

[外链图片转存中…(img-Cq1fZXmY-1719189663754)]

[外链图片转存中…(img-6kLdKAFK-1719189663755)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值