最近学习ks8心得汇总,同时将遇到的问题全部记录,你看完跟着文章走也可以从0部署一套cicd.
涉及核心
- docker
- jenkins
- Kubernetes
- nginx
- Nexus
- 主要从2个方面讲述,第一个是前期准备,每个软件安装、基本使用。第二个是整体的串联(贴合实际工作 ),部署一套前后端分离项目。(前提会一点 lunix 的基本命令)
硬件
- 我用的云服务器,一共4台服务器,2台(2c4g),2台(1c2g),推荐买临时的不用了就断开,玩的时候在开启(穷的办法)
- 1台2c4g 用来部署 Kubernetes(master)
- 1台2c4g 用来部署 Nexus&jenkins(纯粹为了省钱)
- 2台1c2g 用来部署 Kubernetes(pod)
软件
docker
centos7.2中安装docker
- yum -y install docker-io
- docker version
- docker info
- 启动docker服务 systemctl start docker
- 阿里云加速
mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://fwvjnv59.mirror.aliyuncs.com"]
}
EOF
// 重新加载某个服务的配置文件,如果新安装了一个服务,归属于 systemctl 管理,要是新服务的服务程序配置文件生效,需重新加载。
systemctl daemon-reload
// 重启docker服务
systemctl restart docker
image
- git 和 svn 原理
- svn 每次变化,他会把文件生成一个快照 保存起来
- git 每次变化,仓库内存的只是相对上一次变化的内容 保存起来
- 基本操作
- 镜像: 后面的默认是latest(默认最新,不是最新则要加版本号) | 命令 | 含义 | 案例| | ----------- | ----------| ---- | | images | 查看全部镜像 | docker image ls| | search | 查找镜像 | docker search [imageName]| | pull | 拉取镜像 | docker image pull [imageName]| | rmi | 删除镜像 | docker image rmi [imageName]| | inspect | 镜像信息 | docker image rmi [imageName]| | tag | 镜像取名字(会多一条记录) | docker image tag [imageName] [myName]:latest(版本)|
容器
- docker container run hello-world 他会生成一个 容器,只打印一下日志就关闭(能启动后台服务的容器就不会关闭)
- 后缀 添加 -a 显示所有容器
- 后缀 -l 显示最新的容器
| 命令 | 含义 | 案例 |
|---|---|---|
| run | 从镜像运行一个容器 | docker container run ubuntu /bin/echo 'hello-world' |
| --rm | 运行完自动删除 | docker container run --rm ubuntu /bin/bash |
| ps | 查看当前运行的容器 | docker container ps -a -l |
| ls | 查看所有容器 | docker container ls -a |
| inspect | 查看容器信息 | docker container inspect [containerId] |
| kill [containerId] | 终止容器(发送SIGKILL ) | docker kill [containerId] |
| rm [containerId] | 删除容器 | docker rm [containerId] |
| start [containerId] | 启动已经生成、已经停止运行的容器文件 | docker start [containerId] |
| stop [containerId] | 终止容器运行 (发送 SIGTERM ) | docker stop [containerId] |
| logs [containerId] | 查看 docker 容器的输出 | docker logs --follow [containerId] |
| attach [containerId] | 进入容器 | docker attach [containerId] |
| run [containerId] | 进入一个正在运行的 docker 容器 | docker container run -it [container] /bin/bash(最后这个是执行的命令) |
| exit | docker 容器退出 | exit |
| cp [containerId] | 从正在运行的 Docker 容器里面,将文件拷贝到本机 | docker container cp [containID]:app/package.json |
制作镜像 && 使用
制作个性化镜像
docker commit -m"hello" -a "sg" [containerId] sg/hello:latest
docker images
docker run sg/hello /bin/bash
制作Dockerfile
- Docker 的镜像是用一层一层的文件组成的
- docker inspect命令可以查看镜像或者容器
- Layers就是镜像的层文件,只读不能修改。基于镜像创建的容器会共享这些文件层
- .dockerignore(忽略文件)
- .git
- node_modules
tip 编写Dockerfile
| 命令 | 含义 | 案例 |
|---|---|---|
| FROM | 继承的镜像 | FROM node |
| COPY | 拷贝 | COPY ./app /app |
| WORKDIR | 指定工作路径 | WORKDIR /app |
| RUN | 编译打包阶段运行命令 | RUN npm install |
| EXPOSE | 暴露端口 | EXPOSE 3000 |
| CMD | 容器运行阶段运行命令 | CMD npm run start |
Dockerfile编写例子 && 使用
1、node 安装
wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash
source ~/.bashrc
nvm install stable
node -v
npm i cnpm -g
npm i nrm -g
文件传输要安装 rz
yum install lrzsz
service nginx status //查看nginx开启状态
service nginx start
// 使用lsof
yum install lsof
lsof -i:8080 //查看8080端口
// 杀进程
kill -s 9 进程号
// 开启服务 后台运行
node serve.js &
// 安装 git
yum install -y git
// 创建git用户
useradd git
passwd git
2、安装express
npm install express-generator -g
express app
3、Dockerfile
vim Dockerfile
写入
FROM node
COPY ./app /app
WORKDIR /app
RUN npm install
EXPOSE 3000
4、运行 docker build -t express-demo .
-t用来指定image镜像的名称,后面还可以加冒号指定标签,如果不指定默认就是latest
.表示Dockerfile文件的所有路径,.就表示当前路径
5、使用
- -p 端口映射(容器内的端口映射到主机,p是publish-port缩写)
docker container run -p 3333:3000 -it express-demo /bin/bash
- 让 容器 的nginx 80端口 映射主机的8080端口,有人访问了主机的8080端口 他会映射到容器的80端口
docker run -p 8080:80 nginx
- -d 后台运行
docker run -d -p 8080:80 nginx
- top 查看进程 containerId只需要输入部分
docker container top [containerId]
- 一般一个服务对应一个docker 容器
6、发布
docker login
docker image tag [north_uc_1] [username]/[repository]:[tag]
docker image build -t [username]/[repository]:[tag] .
docker tag express-demo songge/express-demo:1.0.0
docker push songge/express-demo:1.0.0
Nexus(私服)
- 部署 Nexus 服务
- nexus-3.29.0-02 是nexus主程序文件夹
- sonatype-work 则是数据文件
- nexus 还支持停止,重启等命令。可以在 bin 目录下执行 ./nexus help 查看更多命令
cd /usr/local
wget https://dependency-fe.oss-cn-beijing.aliyuncs.com/nexus-3.29.0-02-unix.tar.gz
tar -zxvf ./nexus-3.29.0-02-unix.tar.gz
cd nexus-3.29.0-02/bin
./nexus start
firewall-cmd --zone=public --add-port=8081/tcp --permanent
firewall-cmd --zone=public --add-port=8082/tcp --permanent
http://8.144.177.239:8081/
配置 Nexus
- 可以使用admin用户登录Nexus
- 注意请立即更改密码
- Enable anonymous access
cat /root/sonatype-work/nexus3/admin.password
创建Docker私服
- 密码:Sg920322
- 登录 => 齿轮图标 => Repositories => Create repository => docker(hosted) => HTTP(8082)
- 8082 修改仓库的port 默认是8081
- proxy: 此类型制品库原则上只下载,不允许用户推送
- hosted:此类型制品库和 proxy 相反,原则上 只允许用户推送,不允许缓存。这里只存放自己的私有镜像或制品
- group:此类型制品库可以将以上两种类型的制品库组合起来
添加访问权限
- 齿轮图标 => Realms => Docker Bearer Token Realm => 添加到右边的 Active =>保存
- copy http://118.190.142.109:8081/repository/dockcer-repository/
登录制品库
- 默认情况下不能识别http协议的 他认为不安全 需要加下面配置 ip是仓库地址
- vi /etc/docker/daemon.json
{
# 通过https 请求
"insecure-registries" : [
"8.144.177.239:8082"
],
"registry-mirrors": ["https://fwvjnv59.mirror.aliyuncs.com"]
}
systemctl restart docker # 记得要重启
docker login 8.142.41.191:8082 //注意此处要和insecure-registries里的地址一致
Username: xxx
Password: xxxxx
推送镜像到制品库
- 设置界面 => 构建环境 => 勾选 Use secret text(s) or file(s) => 新增选择 => Username and password (separated)
- DOCKER_LOGIN_USERNAME
- DOCKER_LOGIN_PASSWORD
- 接着在下面指定凭据=>添加jenkins=>选择类型Username with password,输入用户名和密码然后点添加确定
- 打包的时候 一定要吧ip:port携带上 例如:
8.142.41.191:8082/xxx,如果不带 push不了
#!/bin/sh -l
npm install --registry=https://registry.npm.taobao.org
npm run build
time=$(date "+%Y%m%d%H%M%S")DOCKER_LOGIN_PASSWORD
# 在nexus 上会分层显示
# 8.142.41.191:8082 ip
# cicd-backend 镜像名字
# target $time
docker build -t 8.142.41.191:8082/cicd-backend:$time .
docker login -u $DOCKER_LOGIN_USERNAME -p $DOCKER_LOGIN_PASSWORD 8.142.41.191:8082
docker push 8.142.41.191:8082/cicd-backend:$time
- 然后就可以查看镜像了,注意端口是8081
拉取私有镜像
docker pull 8.144.177.239:8082/xxx
nginx
- 安装模块
- yum -y install gcc gcc-c++ autoconf pcre pcre-devel make automake
- yum -y install wget httpd-tools vim
- nginx安装文档
CentOS下YUM安装
vim
/etc/yum.repos.d/nginx.repo
写入:
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1
运行
yum install nginx -y
nginx -v
工作流程
- 1、Nginx 在启动后,会有一个 master 进程和多个相互独立的 worker 进程。
- 2、接收来自外界的信号,向各worker进程发送信号,每个进程都有可能来处理这个连接。
- 3、master 进程能监控 worker 进程的运行状态,当 worker 进程退出后(异常情况下),会自动启动新的 worker 进程。
- worker 进程数,一般会设置成机器 cpu 核数。因为更多的worker 数,只会导致进程相互竞争 cpu,从而带来不必要的上下文切换
- 使用多进程模式,不仅能提高并发率,而且进程之间相互独立,一个 worker 进程挂了不会影响到其他 worker 进程
安装目录
- 查看nginx安装的配置文件和目录
rpm -ql nginx
--prefix=/etc/nginx //安装目录
--sbin-path=/usr/sbin/nginx //可执行文件
--modules-path=/usr/lib64/nginx/modules //安装模块
--conf-path=/etc/nginx/nginx.conf //配置文件路径
--error-log-path=/var/log/nginx/error.log //错误日志
--http-log-path=/var/log/nginx/access.log //访问日志
--pid-path=/var/run/nginx.pid //进程ID
--lock-path=/var/run/nginx.lock //加锁对象
nginx 命令
- 文件配置目录
- /etc/nginx/nginx.conf
- /etc/nginx/conf.d/*.conf /etc/nginx/conf.d/default.conf
- 值指令是向上覆盖的,子配置不存在,可以使用父配置块的指令,如果子指令存在,会覆盖父配置块中的指令
主配置文件
/etc/nginx/conf.d/default.conf默认http服务器配置文件/etc/nginx/nginx.conf核心配置文件
# 启动nginx 用户
user nginx;
# work进程数 一般和cpu核数相等
worker_processes auto;
# 错误日志路径
error_log /var/log/nginx/error.log;
# 进程id写入的文件
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
# 事件模块 和node类似 单进程单线程 事件驱动的 注意制作镜像的时候 events要配置 否则会有问题
events {
# 工作进程的 最大链接数 超过这个就不扔掉了
# 1024并发量
# 每个进程允许的最大连接数 10000
worker_connections 1024;
}
# http配置
http {
# 定义日志的格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# 访问日志
access_log /var/log/nginx/access.log main;
# 打开 零拷贝
sendfile on;
# 后面
tcp_nopush on;
tcp_nodelay on;
# 保持连接的超时时间
keepalive_timeout 65;
types_hash_max_size 4096;
# 是否启动gzip压缩
#gzip on;
# 包含mime文件 根据文件后缀 找服务器的相应头 Content-type
include /etc/nginx/mime.types;
# 默认类型 二进制文件
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
# 包含里面的所有文件
include /etc/nginx/conf.d/*.conf;
# server 配置服务的
server {
listen 80;
listen [::]:80;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
server
/etc/nginx/conf.d/default.conf- 一个server下面可以配置多个location
# 服务配置 他是最核心的配置文件
server {
#监听的端口号
listen 80;
#服务名字 后者域名 或者IP
server_name localhost;
#俄语字符集
#charset koi8-r;
#访问日志文件和名称
#access_log /var/log/nginx/host.access.log main;
# 重点 location是路径的意思 / 匹配所有
location / {
#静态文件根目录
root /usr/share/nginx/html;
#首页的索引文件
index index.html index.htm;
}
# = 代表路径全等 不加等号 则匹配前缀 /a/d能匹配到
location = /a {
#静态文件根目录
root /usr/share/nginx/html;
#首页的索引文件
index index.html index.htm;
}
#指定错误页面
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
# 把后台错误重定向到静态的50x.html页面
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
启动和重新加载
- systemctl restart nginx.service
- systemctl reload nginx.service
- nginx -s reload
Jenkins
安装java
- 安装JDK
// 下载包
wget http://img.zhufengpeixun.cn/jdk1.8.0_211.tar.gz
// 解压包 x解压 z原来是一个gz的包 v显示解压的过程 f指定文件名
tar -xzvf jdk1.8.0_211.tar.gz
// 将解压的文件 cp 走
cp -r jdk1.8.0_211 /usr/java
// java的执行文件
/use/java/jdk1.8.0_211/bin/java
// 执行查看版本
/use/java/jdk1.8.0_211/bin/java -version
// 将java执行文件 链接到一个文件 /usr/bin/java 就指代java执行文件
ln -s /use/java/jdk1.8.0_211/bin/java /usr/bin/java
// 配置环境变量 java 就可以在全局访问到了
vi /etc/profile
// 在文件最后加入 下面的 路径根据自己的情况
JAVA_HOME=/usr/java/jdk1.8.0_211
export CLASSPATH=.:${JAVA_HOME}/jre/lib/rt.jar:${JAVA_HOME}/lib/dt.jar:${JAVA_HOME}/lib/tools.jar
export PATH=$PATH:${JAVA_HOME}/bin
// 使刚才的配置文件生效
source /etc/profile
// 这样全局就可以使用 java了
java -version
安装jenkins
// 1
sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
// 2
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key
// 3
yum install jenkins
// 卸载
service jenkins stop
yum clean all
yum -y remove jenkins
// 启动
systemctl start jenkins
// 重启
systemctl restart jenkins
// 查看状态
systemctl status jenkins
// 密码存放位子
/var/lib/jenkins/secrets/initialAdminPassword
// 修改jenkins 默认端口
vim /etc/sysconfig/jenkins
// 找到 JENKINS_PORT="8080" 这个就是默认的8080 将他修改即可
- 关闭防火墙
systemctl stop firewalld.service
systemctl disable firewalld.service
jenkins使用
角色和用户管理
-
安装 Role-based Authorization Strategy 插件
-
首先注册2个账号分别 zhangsan/lisi
-
系统管理->Manage Roles配置管理角色 -
系统管理->Assign Roles配置分配角色 -
新建任务
dev-first&&qa-first -
新建任务 构建过程加上git,配置如下
-
有几点要注意
-
1、jenkins 拉去git代码 需要jenkins 获取ssh公钥,配置到git服务器中
-
2、修改jenkins配置文件 将用户修改成root,
vim /etc/sysconfig/jenkins,修改为JENKINS_USER="root" -
3、Repository URL 写git的地址
-
只要服务器有新的分支 jenkins 就能更新到
安装 Nodejs 环境
- 我们其实并没有在服务端安装 Node 环境。如果想要安装 Node 环境,有以下两个办法:
- 源码编译:这种方式是将 Node 源码拉下来后,在服务器端编译完成后才可以使用。时间比较长,流程也略复杂
- 使用 Jenkins Plugin 中 NodeJS 插件自动配置安装
- 我们打开 Jenkins 首页,找到左侧的系统配置 => 插件管理 => 可选插件,搜索 Node 。选中 NodeJS 后,点击左下角的 直接安装 开始安装插件
-
等待安装完毕后,返回 Jenkins 首页。找到
Global Tool Configuration=>NodeJS=>新增NodeJS -
接着回到 Jenkins 首页,找到左侧的
系统配置,选择全局工具配置 -
找到下面的 NodeJS ,点击 NodeJS 安装,选择相应的版本填写信息保存即可。
如何使用
- 那我们在任务中如何使用呢?我们只需要在任务的配置中,找到构建环境,选中 Provide Node & npm bin/ folder to PATH ,选择刚才配置好的 NodeJS 即可。
- 第一次执行会下载对应的 Node 版本,后续不会下载。
使用 SSH 协议集成 Git 仓库源
- 这一步,我们使用 Jenkins 集成外部 Git 仓库,实现对真实代码的拉取和构建。在这里,我们选用 Gitee 作为我们的代码源 。这里准备一个 vue-cli 项目来演示构建。
生成公钥私钥
- 首先,我们先来配置公钥和私钥。这是 Jenkins 访问 Git 私有库的常用认证方式。我们可以使用 ssh-keygen 命令即可生成公钥私钥。在本地机器执行生成即可。这里的邮箱可以换成你自己的邮箱:
ssh-keygen -t rsa -C "xxx@qq.com"
- 一路回车即可。
- 结束后,你会得到两个文件。分别是 xxx 和 xxx.pub。
- 其中,xxx 是私钥文件,xxx.pub 是对应的公钥文件。我们需要在 Git 端配置公钥,在 Jenkins 端使用私钥与 Git 进行身份校验
在 Gitee 配置公钥
- 在 Gitee 中,如果你要配置公钥有2种方式:仓库公钥 和 个人公钥。其中,如果配置了仓库公钥,则该公钥只能对配置的仓库进行访问。如果配置了个人公钥,则账号下所有私有仓库都可以访问。
- 这里我们就以配置个人公钥为例子。首先打开右上角的设置 ,点击下面的 安全设置 => SSH公钥
- 在下方有个添加公钥,填入信息即可。
- 其中的标题为公钥标题,这里可以自定义标题;公钥则为刚才生成的 xxx.pub 文件。使用 cat 命令查看下文件内容,将内容填入输入框并保存。接着去 Jenkins 端配置私钥
在 Jenkins 配置私钥
- 回到 Jenkins。在 Jenkins 中,私钥/密码 等认证信息都是以 凭证 的方式管理的,所以可以做到全局都通用。
- 我们可以在配置任务时,来添加一个自己的凭证。点击项目的 配置,依次找到 源码管理 => Git => Repositories
构建镜像
编写 DockerFile
- 基于 nginx:1.15 镜像做底座。
- 拷贝本地 html 文件夹内的文件,到镜像内 /etc/nginx/html 文件夹。
- 拷贝本地 conf 文件夹内的文件,到镜像内 /etc/nginx/ 文件夹。
FROM nginx:1.15-alpine
COPY html /etc/nginx/html
COPY conf /etc/nginx/
WORKDIR /etc/nginx/html
- 编写完成后,怎么生成镜像呢?我们只需要使用 docker build 命令就可以构建一个镜像了:
- -t: 声明要打一个镜像的Tag标签,紧跟着的后面就是标签。标签格式为 镜像名:版本
docker build -t imagename:version .
- 因为我们的镜像只包含一个 nginx,所以 dockerfile 内容比较简单。我们只需要在代码根目录下新建一个名为 DockerFile 的文件,输入以下内容,并将其提交到代码库即可。
vi DockerFile
FROM nginx:1.15-alpine
COPY html /etc/nginx/html
COPY conf /etc/nginx/
WORKDIR /etc/nginx/html
git add ./DockerFile
git commit -m "chore: add dockerfile"
git push
Jenkins 端配置
- 在代码源和 DockerFile 准备就绪后,我们只需在 Jenkins 端配置下要执行的 Shell 脚本即可。找到项目的配置,依次找到 构建 => Execute shell。输入以下脚本:
#!/bin/sh -l
npm install --registry=https://registry.npm.taobao.org
npm run build
docker build -t jenkins-test .
- 这里脚本很简单,主要就是 安装依赖 => 构建文件 => 构建镜像。填写完毕后保存
Kubernetes
- 后面才是核心,发现后面东西还有很多,分2次分享