2019.11.07 晚 21:00 直播.
一, Kubernetes 环境配置
https://github.com/easzlab/kubeasz
二, 通过 dockerfile 构建 BaseImage, 服务镜像
容器服务的基础镜像构建
- FROM harbor.qa.com.cn/public/CentOS:6.9
- LABEL vendor=OC sgplm-ep.is-production=""sgplm-ep.version="1.0.2"sgplm-ep.release-date="2018-10-24"
- COPY sysctl.conf /etc/sysctl.conf
- RUN rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm && yum -y update && yum install -y iperf mtr python-devel python-markupsafe python-pip openssl-devel swig python-setuptools wget ssmtp man openssh-clients subversion Git libtool cmake openssl-devel lua-filesystem yum-utils rpm-build patch make gcc gcc-c++ iftop telnet VIM-enhanced lua-socket tree bc iotop logrotate rsync haproxy vixie-cron && yum clean all && /bin/cp -f /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai'>/etc/timezone && useradd -s /sbin/nologin Redis && echo '10 00 * * * sync && echo 1> /proc/sys/vm/drop_caches>/dev/null 2>&1'>> /var/spool/cron/root && echo '23 30 * * * find /data/logs/ ! -path"/data/logs/redis/*"-mtime +5 -name"*.log.*"-exec rm -f {} \;>/dev/null 2>&1'>> /var/spool/cron/root && /etc/init.d/crond restart && mkdir /tmp/pkgs && cd /tmp/pkgs && wget http://172.31.0.19:8555/jdk-8u144-linux-x64.tar.gz && tar zxvf jdk-8u144-Linux-x64.tar.gz -C /usr/local/ && mv /usr/local/jdk1.8.0_144/ /usr/local/jdk1.8 && echo -e 'export JAVA_HOME="/usr/local/jdk1.8"\nPATH=$JAVA_HOME/bin:$PATH \nexport PATH\nCLASSPATH=$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar\nexport CLASSPATH'>>/etc/profile.d/java.sh && source /etc/profile.d/java.sh && wget http://172.31.0.19:8555/libzmq.tar.gz && tar zxf libzmq.tar.gz -C /usr/local/ && cd /usr/local/libzmq && if [ ! -d cmake-build ];then mkdir cmake-build;fi && cd cmake-build && cmake .. && make -j 4 && make test && make install && ldconfig && cd - && temp=`find / -name libzmq.so.5.1.3 | grep cmake-build/lib | tail -n 1` && ln -s $temp /usr/lib/ && ldconfig && wget http://172.31.0.19:8555/go1.8.3.linux-amd64.tar.gz && tar -C /usr/local -xzf go1.8.3.Linux-amd64.tar.gz && mkdir /home/gospace && echo -e 'export PATH=$PATH:/usr/local/go/bin \nexport GOPATH=/home/gospace \nexport GOROOT=/usr/local/go/'>>/etc/profile.d/go.sh && source /etc/profile.d/go.sh && export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig/ && go get "github.com/pebbe/zmq4" #&& temp=`find / -name libzmq.so.5.1.3 | grep cmake-build/lib` && ln -s $temp /usr/lib/ && ldconfig && wget http://172.31.0.19:8555/apache-maven-3.5.0-bin.tar.gz && tar zxf apache-maven-3.5.0-bin.tar.gz -C /usr/local/ && ln -s /usr/local/apache-maven-3.5.0 /usr/local/maven3 && echo -e 'export M3_HOME=/usr/local/maven3 \nexport PATH=${M3_HOME}/bin:${PATH}'>> /etc/profile.d/maven3.sh && source /etc/profile.d/maven3.sh && rm -rf /tmp/pkgs/*
- CMD [ "bash" ]
- sysctl.conf
- net.ipv4.ip_forward = 0
- net.ipv4.conf.default.rp_filter = 1
- net.ipv4.conf.default.accept_source_route = 0
- kernel.sysrq = 0
- kernel.core_uses_pid = 1
- net.ipv4.tcp_syncookies = 1
- kernel.msgmnb = 65536
- kernel.msgmax = 65536
- #kernel.shmmax = 4294967295
- #kernel.shmall = 268435456
- kernel.printk = 2
- net.ipv6.conf.all.disable_ipv6 = 1
- net.ipv4.conf.all.promote_secondaries = 1
- net.ipv4.conf.default.promote_secondaries = 1
- net.ipv6.neigh.default.gc_thresh3 = 4096
- net.ipv4.neigh.default.gc_thresh3 = 4096
- kernel.softlockup_panic = 1
- kernel.watchdog_thresh = 60
- net.ipv4.tcp_keepalive_time = 30
- net.ipv4.tcp_keepalive_probes = 3
- net.ipv4.tcp_keepalive_intvl = 10
- net.ipv4.tcp_fin_timeout = 30
- net.ipv4.tcp_max_tw_buckets = 180000
- kernel.core_pattern = /var/core/%e.%p-%c-%t.core
- vm.swappiness = 0
- vm.overcommit_memory = 1
- net.core.somaxconn= 1024
- net.ipv4.tcp_tw_reuse = 0
- net.ipv4.tcp_tw_recycle = 0
- net.ipv4.tcp_max_syn_backlog = 8192
- net.ipv4.tcp_max_tw_buckets = 262144
- net.netfilter.nf_conntrack_max = 655350
- net.netfilter.nf_conntrack_tcp_timeout_established = 300
编辑好 dockerfile, 准备好相关的文件, 执行 Build
docker build -t harbor.qa.com.cn/public/sgplm-ep:v1.2 .
容器服务 (GO) 使用 baseimage 构建
- FROM harbor.qa.com.cn/public/sgplm-ep:v1.2
- LABEL vendor=OC sgplm-signalproxy.is-production=""sgplm-signalproxy.version="1.1"sgplm-signalproxy.release-date="2019-06-06"MAINTAINER SignalingTeam"@s.com.cn"
- RUN mkdir -p /usr/local/signalproxy/cert /data/logs/signalproxy
- COPY signalproxy conf.JSON /usr/local/signalproxy/
- COPY cert /usr/local/signalproxy/cert
容器服务 (JAVA) 使用 baseimage 构建
- FROM harbor.qa.com.cn/public/sgplm-ep:v1.2
- LABEL vendor=OC sgplm-dispatcher.is-production=""sgplm-dispatcher.version="<build_tag>"sgplm-dispatcher.release-date="2019-06-06"MAINTAINER SignalingTeam"@s.com.cn"
- RUN mkdir -p /usr/local/dispatcher/ /data/logs/dispatcher
- COPY dispatcher /usr/local/dispatcher/dispatcher-etcd.jar
- COPY keyStore.p12 logback-spring.xml application.properties /usr/local/dispatcher/
三, Kubernetes 部署 Jenkins, 配置动态 slave(docker in docker)
新建一个 Deployment:(jenkins2.YAML)
- apiVersion: extensions/v1beta1
- kind: Deployment
- metadata:
- name: jenkins2
- namespace: ops
- spec:
- template:
- metadata:
- labels:
- App: jenkins2
- spec:
- terminationGracePeriodSeconds: 10
- serviceAccount: jenkins2
- containers:
- - name: jenkins
- image: jenkins/jenkins:lts
- imagePullPolicy: IfNotPresent
- ports:
- - containerPort: 8080
- name: web
- protocol: TCP
- - containerPort: 50000
- name: agent
- protocol: TCP
- resources:
- limits:
- CPU: 2
- memory: 2Gi
- requests:
- CPU: 2
- memory: 2048Mi
- livenessProbe:
- httpGet:
- path: /login
- port: 8080
- initialDelaySeconds: 60
- timeoutSeconds: 5
- failureThreshold: 12
- readinessProbe:
- httpGet:
- path: /login
- port: 8080
- initialDelaySeconds: 60
- timeoutSeconds: 5
- failureThreshold: 12
- volumeMounts:
- - name: jenkinshome
- subPath: jenkins2
- mountPath: /var/jenkins_home
- env:
- - name: LIMITS_MEMORY
- valueFrom:
- resourceFieldRef:
- resource: limits.memory
- divisor: 1Mi
- - name: JAVA_OPTS
- value: -Xmx$(LIMITS_MEMORY)m -XshowSettings:vm -Dhudson.slaves.NodeProvisioner.initialDelay=0 -Dhudson.slaves.NodeProvisioner.MARGIN=50 -Dhudson.slaves.NodeProvisioner.MARGIN0=0.85 -Duser.timezone=Asia/Shanghai
- securityContext:
- fsGroup: 1000
- volumes:
- - name: jenkinshome
- persistentVolumeClaim:
- claimName: jenkinspvc
- ---
- apiVersion: v1
- kind: Service
- metadata:
- name: jenkins2
- namespace: ops
- labels:
- App: jenkins2
- spec:
- selector:
- App: jenkins2
- type: NodePort
- ports:
- - name: Web
- port: 8080
- targetPort: Web
- nodePort: 30302
- - name: agent
- port: 50000
- targetPort: agent
资源对象都放置在一个名为 ops 的 namespace 下面, 所以我们需要添加创建一个 namespace:
kubectl create namespace ops
这里使用一个名为 jenkins/jenkins:lts 的镜像, 这是 jenkins 官方的 Docker 镜像, 然后也有一些环境变量, 当然我们也可以根据自己的需求来定制一个镜像, 比如我们可以将一些插件打包在自定义的镜像当中, 可以参考文档: https://github.com/jenkinsci/docker, 我们这里使用默认的官方镜像就行, 另外一个还需要注意的是我们将容器的 /var/jenkins_home 目录挂载到了一个名为 opspvc 的 PVC 对象上面, 所以我们同样还得提前创建一个对应的 PVC 对象, 当然我们也可以使用我们前面的 StorageClass 对象来自动创建:(pvc.YAML)
- apiVersion: v1
- kind: PersistentVolume
- metadata:
- name: jenkinspv
- spec:
- capacity:
- storage: 50Gi
- accessModes:
- - ReadWriteMany
- persistentVolumeReclaimPolicy: Delete
- nfs:
- server: 172.31.0.41
- path: /data/jenkins2
- ---
- kind: PersistentVolumeClaim
- apiVersion: v1
- metadata:
- name: jenkinspvc
- namespace: ops
- spec:
- accessModes:
- - ReadWriteMany
- resources:
- requests:
- storage: 50Gi
创建需要用到的 PVC 对象:
kubectl create -f pvc.YAML
另外我们这里还需要使用到一个拥有相关权限的 serviceAccount:jenkins2, 这里只是给 jenkins 赋予了一些必要的权限, 当然如果你对 serviceAccount 的权限不是很熟悉, 给这个 sa 绑定一个 cluster-admin 的集群角色权限也是可以的, 当然这样具有一定的安全风险:(rbac.YAML)
- apiVersion: v1
- kind: ServiceAccount
- metadata:
- name: jenkins2
- namespace: ops
- ---
- kind: ClusterRole
- apiVersion: rbac.authorization.k8s.io/v1beta1
- metadata:
- name: jenkins2
- rules:
- - apiGroups: ["extensions", "apps"]
- resources: ["deployments"]
- verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
- - apiGroups: [""]
- resources: ["services"]
- verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
- - apiGroups: [""]
- resources: ["pods"]
- verbs: ["create","delete","get","list","patch","update","watch"]
- - apiGroups: [""]
- resources: ["pods/exec"]
- verbs: ["create","delete","get","list","patch","update","watch"]
- - apiGroups: [""]
- resources: ["pods/log"]
- verbs: ["get","list","watch"]
- - apiGroups: [""]
- resources: ["secrets"]
- verbs: ["get"]
- ---
- apiVersion: rbac.authorization.k8s.io/v1beta1
- kind: ClusterRoleBinding
- metadata:
- name: jenkins2
- namespace: ops
- roleRef:
- apiGroup: rbac.authorization.k8s.io
- kind: ClusterRole
- name: jenkins2
- subjects:
- - kind: ServiceAccount
- name: jenkins2
- namespace: ops
创建 rbac 相关的资源对象:
kubectl create -f rbac.YAML
创建资源之前更改一下 nfs 服务共享目录的属主
chown -R 1000 /data/k8s/jenkins2
为了方便我们测试, 我们这里通过 NodePort 的形式来暴露 Jenkins 的 Web 服务, 固定为 30302 端口, 另外还需要暴露一个 agent 的端口, 这个端口主要是用于 Jenkins 的 master 和 slave 之间通信使用
资源准备好后, 我们直接创建 Jenkins 服务:
kubectl create -f jenkins2.YAML
创建完成后, 要去拉取镜像可能需要等待一会儿, 然后我们查看下 Pod 的状态:
- kubectl get pods -n ops
- NAME READY STATUS RESTARTS AGE
- jenkins2-6fd324fg31-poqtr 1/1 Running 0 2m
如果 pod 状态有问题, 使用 kubectl describe pod jenkins2-6fd324fg31-poqtr -n ops 和 kubectl logs -f jenkins2-6fd324fg31-poqtr -n ops 指令来排查问题
服务启动成功后, 我们就可以根据任意节点的 IP:30302 端口就可以访问 jenkins 服务了, 可以根据提示信息进行安装配置即可:
初始化的密码我们可以在 jenkins 的容器的日志中进行查看, 也可以直接在 nfs 的共享数据目录中查看:
cat /data/k8s/jenkins2/secrets/initAdminPassword
然后选择安装推荐的插件即可
安装完成后添加管理员帐号即可进入到 jenkins 主界面:
配置过程
第 1 步. 我们需要安装 kubernetes plugin, 点击 Manage Jenkins -> Manage Plugins -> Available -> Kubernetes plugin 勾选安装即可
第 2 步. 安装完毕后, 点击 Manage Jenkins -> Configure System -> (拖到最下方)Add a new cloud -> 选择 Kubernetes, 然后填写 Kubernetes 和 Jenkins 配置信息
注意 namespace, 我们这里填 ops, 然后点击 Test Connection, 如果出现 Connection test successful 的提示信息证明 Jenkins 已经可以和 Kubernetes 系统正常通信了, 然后下方的 Jenkins URL 地址: http://jenkins2.kube-ops.svc.cluster.local:8080, 这里的格式为: 服务名. namespace.svc.cluster.local:8080, 根据上面创建的 jenkins 的服务名填写, 我这里是之前创建的名为 jenkins, 如果是用上面我们创建的就应该是 jenkins2
另外需要注意, 如果这里 Test Connection 失败的话, 很有可能是权限问题, 这里就需要把我们创建的 jenkins 的 serviceAccount 对应的 secret 添加到这里的 Credentials 里面.
第 3 步. 配置 Pod Template, 其实就是配置 Jenkins Slave 运行的 Pod 模板, 命名空间我们同样是用 kube-ops,Labels 这里也非常重要, 对于后面执行 Job 的时候需要用到该值, 然后我们这里使用的是 zhangchuan/jenkins:jnlp 这个镜像, 这个镜像是在官方的 jnlp 镜像基础上定制的, 加入了 kubectl 等一些常用的工具.
这里需要注意我们这里需要在下面挂载两个主机目录, 一个是 /var/run/docker.sock, 该文件是用于 Pod 中的容器能够共享宿主机的 Docker, 这就是大家说的 docker in docker 的方式, Docker 二进制文件我们已经打包到上面的镜像中了, 另外一个目录下 /root/.kube 目录, 我们将这个目录挂载到容器的 /home/jenkins/.kube 目录下面这是为了让我们能够在 Pod 的容器中能够使用 kubectl 工具来访问我们的 Kubernetes 集群, 方便我们后面在 Slave Pod 部署 Kubernetes 应用.
因为 Jenkins Slave Pod 中没有配置权限, 所以需要配置上 ServiceAccount, 在 Slave Pod 配置的地方点击下面的高级, 添加上对应的 ServiceAccount 即可:
至此, Kubernetes 插件配置就完成了.
测试
在 Jenkins 首页点击 创建一个任务, 创建一个测试的任务, 输入任务名称, 然后我们选择 构建一个自由风格的软件项目 类型的任务:
注意在下面的 Label Expression 这里要填入 oc, 就是前面我们配置的 Slave Pod 中的 Label, 这两个地方必须保持一致
在 构建 区域选择 执行 shell
.........
完成的安装文档链接: https://pan.baidu.com/s/1GZfOl7Ry3J-2xlqRY3N6OA 提取码: iwy9
来源: http://www.bubuko.com/infodetail-3276106.html