容器化部署持续交付
1,课程导学
snapshot 是开发版本
release 是发布版本
devOps(敏捷开发)
2,如何持续集成
计划--->代码--->构建(敏捷开发)--->测试(持续集成)--->发布(持续交付)--->部署(持续部署)--->运维(devOps)
jenkins--->ansible--->Vault--->不同环境
发布
灰度(蓝绿发布)
先一小部分用户体验新版本
金丝雀发布
部署25%的机器,根据监控数据决策是否进一步部署
开关功能
前后端功能没对接功能可用开关控制后先部署
3,需求任务管理
使用Jira创建Sprint,用户故事和任务
敏捷项目管理和Jira
release(月)
sprint(周)
issue(问题)
epic(史诗)
story(用户故事)
task(任务)
bug(故障)
创建Sprint(冲刺)
sprint需要关联带开发的任务
sprint需要被关联到某一个release
创建用户故事
定义用户故事的类型
定义用户故事的内容描述
分配给某个开发者
创建任务,并分配给工程师
将任务与用户故事关联
将任务放入sprint中
任务的排期和追踪
查看release版本信息
查看release任务
为任务预估story point
工作量
复杂度
风险和不确定性
查看sprint
查看sprint各个任务的进度
创建任务燃尽图
每日站会如何开
昨天做了什么,今天要做什么,有什么阻塞问题,需要什么帮助
docker 安装jira
#!/bin/bash
docker build -t mysql .
# docker run --name mysql8.0 --privileged=true -v /home/project/mysql/conf:/etc/mysql -v /home/project/mysql/logs:/logs -v /home/project/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=swj5201314 -p 3306:3306 -d mysql:8.0
docker run -p 3306:3306 --name mysql -v /home/project/mysql/conf:/etc/mysql -v /home/project/mysql/logs:/var/log/mysql -v /home/project/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=swj5201314 -d mysql:5.7 --default-storage-engine=INNODB --character_set_server=utf8mb4 --innodb_default_row_format=DYNAMIC --innodb_large_prefix=ON --innodb_file_format=Barracuda --innodb_log_file_size=2G
# mysql8.0
# mysql -u root -p #登录
# use mysql; #选择数据库
# 远程连接请将'localhost'换成'%'
# ALTER USER 'root'@'%' IDENTIFIED BY 'Swj5201314' PASSWORD EXPIRE NEVER; #更改加密方式
# ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'Swj5201314'; #更新用户密码
# FLUSH PRIVILEGES; #刷新权限
# my.cnf
# [mysqld]
# pid-file = /var/run/mysqld/mysqld.pid
# socket = /var/run/mysqld/mysqld.sock
# datadir = /var/lib/mysql
# secure-file-priv= NULL
## Custom config should go here
# secure_file_priv=/var/lib/mysql
# default-storage-engine=INNODB
# character_set_server=utf8mb4
# innodb_default_row_format=DYNAMIC
# innodb_log_file_size=2G
## remove this if it exists
## sql_mode = NO_AUTO_VALUE_ON_ZERO
# mysql5.7
# CREATE DATABASE jiradb CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
# GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,ALTER,INDEX on jiradb.* TO 'root'@'%' IDENTIFIED BY 'swj5201314';
# flush privileges;
#!/bin/bash
docker build -t jira .
docker run -v /home/project/jira/jiraData:/var/atlassian/application-data/jira --name=jira -d --restart always -p 8080:8080 atlassian/jira-software
docker exec --user root jira mv /opt/atlassian/jira/atlassian-jira/WEB-INF/lib/atlassian-extras-3.4.6.jar /opt/atlassian/jira/atlassian-jira/WEB-INF/lib/atlassian-extras-3.4.6.jar_bak
# docker cp atlassian-extras-3.2.jar jira:/opt/atlassian/jira/atlassian-jira/WEB-INF/lib/
docker cp atlassian-agent.jar jira:/opt/atlassian/jira/
docker cp mysql-connector-java-8.0.27.jar jira:/opt/atlassian/jira/atlassian-jira/WEB-INF/lib/
docker restart jira
# jdbc:mysql://120.78.81.53:3306/jiradb?autoReconnect=true&useUnicode=true&characterEncoding=UTF8
# com.mysql.jdbc.Driver
# 破解
# java -jar atlassian-agent.jar -d -m [email protected] -n XINGYUE -p jira -o http://120.78.81.53 -s BQ3E-7TIT-ZETL-TCKE
# AAAB4g0ODAoPeNp9kl9zmkAUxd/5FMz0pZ0OBIiicYaZJrhWWkALWuKMLytedRNZyC6o5NOXfxmtGh8X7j33d8+5XwJYim68E7WWqCi9druntkTTn4iaoqnCK+R/gXESU0PVFaWjdO/vVWHNAOgmThJgsk1CoBzQkqRlFXInyBt7lo8EN4sWwEarKS8UDEkVzJimOExdHIGR7xeqInd/vL3JYRwJL4Rh+aJhnLFwgzn0cQpGySOpqqS1hGbmJE+gEjNHjoM803q0P36hQ0JYftKnlX0NAHIw2Z4T+MB2wKy+8eTpHUmfBbYUDNpTadRFQY2XsHiZhalcPiQer9I9ZiAXemQHRsoyuFVWoGATaAqsLt3WnEPMN4Zj7s3B0J1G6Pf7bPB6uLMdZ/hzrAeHRRTRFn/ceG3Tj/Ds6XvwjPJnmpprxXvZWlaqt/7Mjbkh+NmCh4wkVQZHls/DuRLhNTsLpwpmimn4iaU3Vr6Is5lTeGxbfR+5kq12Og+a3lZrmXOPihLjStn1aX6KWdm5wlsOwoitMSUcV2sfCF3nGbxvSJ5RwWRQfT4/qiaRj3PX/rOookoY4U3SfTja/avgEP2GQ/xabiHWa3yb90S0w9usGljTX9zLDfdPCU77jpr1+x8vdEosMCwCFBqrnaeoM9DYMePkober+TAWltNuAhQ6GqlBXAvFdth4kUKnjz7vsWuZqg==X02mu
# xingyue
# xingyue@5201314
在开发工具里集成jira插件
在idea里集成jira插件
jira integration
Tasks
Servers
在idea里快速获取自己的开发任务
通过插件创建分支,开发代码
提交代码并更改jira任务状态
gitflow vs Trunk base 分支模型哪个更适合团队
gitflow 是一种分支开发模型
master 线上分支
develop 开发主分支
所有分支最后都需要合并到develop分支
feature 功能分支
分支名称 feature-*
release 发布分支
分支名称 release-*
hotfix 功能修复分支
分支名称 hotfix-*
适用场景
软件本身对稳定性要求高
团队少量资深研发,多数初,中级研发
开源项目
功能开关
主干开发分支模型
适用场景
软件本身迭代较快
团队中级,资深研发较多,初级研发较少
互联网产品
开发一个springboot 项目
创建springcloud服务注册中心
依赖/注解/配置
在服务应用前端加上网关
springcloud zuul 网关用法
zuul:
routes:
guestbook:
path: /**
serviceId: guestbook-service
zuul:
routes:
guestbook:
path: /**
uri: http://service:8080/guestbook/
服务链路追踪zipkin
docker run --name zipkin -d -p 9411:9411 openzipkin/zipkin
应用添加配置
spring:
zipkin:
base-url: http://localhost:9411
搭建maven私服
搭建JFrog Artifactory OSS 开源
创建Maven仓库
配置Maven连接到Arifactory
搭建JFrog Artifactory OSS 开源版
使用docker
export JFROG_HOME=/Users/xingyue/.jfrog/JFROG_HOME
# export JFROG_HOME=/home/docker-jfrog/.jfrog/JFROG_HOME
docker run -d --name artifactory-oss-6.18.1 -v /Users/xingyue/Home/xingyue/学习/工程化/artifactory:/var/opt/jfrog/artifactory -p 8081:8081 docker.bintray.io/jfrog/artifactory-oss:6.18.1
注意使用ip访问
默认用户名/密码 admin/password
maven仓库结构
开发者 ---> git ---> jenkins(service) ---> artifactory(local/remote(下载到jenkins) ---> JCenter)
进入界面Artifact Repository Browser
1,使用虚拟仓库libs-release
新建远程仓库,新建本地仓库,新建虚拟仓库(将本地和远程一起添加)
2,生成settings.xml文件,替换到maven的settings.xml文件
发布应用到maven私服
artifact repsitory browser ---> libs-release ---> set me up
mvn package
mvn deploy
根据version自动区分打到那个仓库
元数据打标签 properties
命名规范
面板 admin ---> layouts ---> maven-2-default
[orgPath]/[module]/[baseRev](-[folderItegRev])/[module]-[baseRev](-[fileItegRev])(-[classifier]).[ext]
使用curl下载制品包 右上角用户信息 ---> edit profile --->apikey
输入账号密码
AKCp8k8srBKRuXbGYJXMrQbH4i5Gz8rVhn869DmSH21Un4nhPqzJD5rq3j5PnswGe9a4UPVMJ
curl -u admin:AKCp8k8srBKRuXbGYJXMrQbH4i5Gz8rVhn869DmSH21Un4nhPqzJD5rq3j5PnswGe9a4UPVMJ http://120.78.81.53:8081/articactory/libs-release-local/com/xingyuezhiyun/gateway-service/1.3/gateway-service-1.3.jar --output gateway-service-1.3.jar
----------自动化测试----------
#!/bin/bash
mkdir jenkins_home
chmod -R 777 `pwd`/jenkins_home
docker run -d -v `pwd`/jenkins_home:/var/jenkins_home -p 8082:8080 -p 50000:50000 jenkins/jenkins:lts-jdk11
查看容器日志获取密码
ff7a5ab958744ad98535516c2f16b961
jenkins 核心
2.0 可以使用pipeline 流水线
jenkins
project项目
build构建
workspace工作空间
credentials凭据
jenkins 持续集成流水线
集群执行
两种语法
scripted groovy
脚本式流水线
declerative 预制的标签进行结构化的编写,功能受限但更加标准化
声明式流水线严格规范
jenkins 集成Artifactory
安装jenkins Artifactory 插件
配置Artifactory插件 http://ip:port/artifactory
Connect to localhost:8083 [localhost/127.0.0.1] failed: Connection refused (Connection refused)
配置Artifactory credentials
在流水线中使用Artifactory进行依赖下载,制品上传
jenkins流水线集成jira
安装jenkins jira插件 jira plugin
配置jira credentials
配置jira插件
提交代码时,管理jira任务id git commit -m "taskId xxx"
在构建结果中查看任务id
jenkins 集成sonarqube
docker pull library/sonarqube:lts
docker run -d -p 9000:9000 sonarqube
访问http://localhost:9000
账号密码 admin/admin
创建项目,生成token
携带登录的token
idea安装sonarqube插件
jenkins调用sonarqube 接口,获取状态,如果质量太低就构建失败
jenkins 集成接口测试工具YAPI(去哪儿)
http://github.com/YMFE/yapi
ui自动化测试工具selenium
https://www.selenuim.dev
下载 Chrome webDriver
mac/linux: 将文件放入/usr/local/bin
在项目中引入依赖
在JUnit中调用ChromeDriver
在测试用例中寻找按钮并执行点击操作,判断结果是否符合预期
编写单元测试springboot test
idea 安装sonarlint 插件
yapi对接口进行测试
参考官网:https://hellosean1025.github.io/yapi/devops/index.html
----------自动化运维----------
Ansible 配置管理和应用部署的工具
Control node 控制节点
Managed nodes 受管控节点
Inventory 库存表
Modules 模块
Tasks 任务
Playbooks 剧本
Ansible 安装和配置
安装python
yum install ansible -y
创建软连接
mac
sudo ln -s /Users/xingyue/Library/Python/3.9/bin/ansible /usr/bin/ansible
创建基础的库存表
vi /etc/ansible/hosts
all:
hosts:
maol.example.com
children:
webservers:
hosts:
foo.example.com
bar.example.com
aaa.com
默认在[all]组下
[webservers] 组
xxx.com
yyy.com
设置变量给playbook使用
Ansible的配置
远程主机免密登录
配置ssh生产ssh-key
1,管理节点生产ssh-key
ssh-keygen
2,拷贝当前主机的ssh key到远程主机,ip地址替换为远程地址
ssh-copy-id [email protected]
3,保存远程主机ip,保存到当前主机的known_host
ssh-keyscan prod.server >> ~/.ssh/konwn_hosts
ssh [email protected]
cat /etc/ansible/hosts
[prod] #定义生产组
prod.server # 远程服务地址
ansible all -m ping -u root
ansible prod -m copy -a "src=note-book-1.0.jar dest=/tmp" -u root
Ad-hoc 命令
用来重启机器,拷贝文件,管理包和用户
管理用户和组
ansible all -m user -a "name=foo state=absent"
管理服务
ansible webservers -m service -a "name=httpd" state=started
获取系统变量
ansible all -m setup -u root
重启服务器
ansible beijing -a "/sbin/reboot"
管理文件
ansible beijing -m copy -a "src=/etc/hosts dest=/tmp/hosts"
管理包
ansible beijing -m yum -a "name=acme state=latest"
Ansible playbook 介绍
复杂的部署编排场景,同步或者异步的发起任务
一组机器被映射为定义好的角色,playbook的内容被称为tasks,一个任务是一个对ansible模块的调用
语言介绍
基础
执行一个playbook
- hosts: prod # [webservers]
vars:
http_port: 80
max_clients: 200
remote_user: root
tasks:
- name: ping
ping:
remote_user:xxx # 用户控制
- name:ensure apache is at the latest version
yum: pkg=httpd state=latest
- name:write the apache config file
template:src=/srv/httpd.j2 dest=/etc/httpd.conf
notify:
- restart apache
- name ensure apache is running
service:name=httpd state=started
handlers:
- name:restart apache
service:name=httpd state=restarted
执行
ansible-playbook xxx.yml
可复用的playbook
import xxx.yml
动态vs静态引用
如何使用变量
引用变量{{}}
系统变量
- debug: var=ansible_facts
{{ ansible_facts['devices']['xvda']['model']}}
循环
loop: "{{ groups['all'] }}"
条件 condition
when:
Roles
用于自动化加载一些默认的变量,任务等
任务
handler
defaults
vars
files
templates
meta
如果roles/x/tasks/main.yml存在,则里面的任务会被加载到当前的play
---
- hosts: webservers
roles:
- common
- webservers
编写notebook的playbook
-hosts: prod
remote_user: root
tasks:
-name: Copy jar files to prod
copy: src=notebook-service-1.0.jar dest=/tmp
owner=root group=root mode=0644
-name: start jar
shell: nohup java -jar /tmp/notebook-service-1.0.jar &
-name: sleep 20 s
shell: sleep 20
-name: shut down
shell: kill-9 $(lsof -t -i:1111)
流水线集成ansible
新增pipe line
node {
stage('Pull source code') {
git 'https://git.imooc.com/coding-439/Notebook-k8s.git'
}
dir('Final/notebook-service') {
//构建 Maven
stage('Build and UI test'){
sh ' mvn package -Dmaven.test.skip=true'
}
}
dir('Chapter-8') {
//部署 notebook.jar to remote server
stage('Ansible Deploy to remote server'){
sh 'cp ../Final/notebook-service/target/notebook-service-1.0.jar ./'
sh 'ansible-playbook notebook-playbook.yml'
}
}
}
git clone --depth=1
最佳实践
目录结构
production #生产环境的资源目录
staging #准生产环境的资源目录
group_vars/
group1.yml #某个组的环境变量
host_vars/
hostname_1.yml #针对某种系统的变量
library/
filter_plugins
site.yml #主要的playbook入口
webservers.yml
dbservers.yml
roles/
区分生产和准生产环境配置
使用不用的文件分别存储不同环境的域名信息
#file: production
[bj_webservers]
www-bj-1.example.com
[sh_webservers]
www-sh-1.example.com
合理利用组
只配置webserver
ansible-playbook -i production webservers.yml
只配置北京的webserver
ansible-playbook -i production webserevers.yml --limit beijing
滚动执行配置北京的webserver
ansible-playbook -i production webservers.yml --limit beijing[0:9]
用roles进行复用
使用roles进行隔离
- import_playbook: webservers.yml
在webservers组中加载默认的role
定义roles的变量(明文)
变量抽取到#file group_vars/dbservers
ansible vault(加密)
实现滚动升级(先升级一个,成功了再升级其他)
升级前
升级后
docker
使用CGroup进行CPU,内存隔离
sys/fs/cgroup/cpu
创建文件夹 设置 cpu.cfs_quota_us进行限流
echo 20000 > /sys/fs/cgroup/cpu/cgroups_test/cpu.cfs_quota_us
将任务进程绑定到当前文件夹的tasks中
echo xxxxx > /sys/fs/cgroup/cpu/cgroups_test/tasks
docker run -it --cpus=.5 xxx /bin/bash
namespace 资源隔离
文件系统隔离
aufs联合挂载
/var/lib/docker/aufs
/diff 管理docker镜像每一层的内容
/layer 管理docker镜像的元数据,层级关系
/mnt 管理挂载点,通常对应一个镜像,或者layer,用于描述一个容器镜像的所有层级内容
docker常用命令
搭建docker镜像仓库
hub.docker.com 镜像中心
JCR
docker run -d --name artifactory-jcr -v /Users/xingyue/Home/xingyue/学习/工程化/jcr/var:/var/opt/jfrog/artifactory -p 8083:8081 -p 8084:8082 docker.bintray.io/jfrog/artifactory-jcr:latest
admin/password
1,为docker客户端增加JCR本地非安全注册中心
远程docker操作(120.78.81.53)
export DOCKER_OPTS+=" --insecure-registry 120.78.81.53:8084"
{
"insecure-registries": ["120.78.81.53:8084"]
}
尝试本地docker添加"insecure-registries": ["120.78.81.53:8084"]
docker login 120.78.81.53:8084 -uadmin -ppassword
重启后登陆成功
本地docker操作(本机)
Insecure Registry: art.local:8083
2,配置本地域名解析
127.0.0.1 art.local
3,本地docker客户端登录docker镜像中心
docker login art.local:8081 -uadmin -ppassword
上传下载镜像
docker build -t art.local:8081/docker-local/notebook-k8s/notebook-service:latest .
docker push art.local:8081/docker-local/notebook-k8s/notebook-service:latest
docker pull art.local:8081/docker-local/notebook-k8s/notebook-service:latest
docker build -t docker-jcr/notebook-service:latest .
docker push docker-jcr/notebook-service:latest
docker pull docker-jcr/notebook-service:latest
编写notebook的dockerfile
RUN
CMD
ADD
ENTRYPOINT
docker镜像中心
虚拟仓库
dockerfile 最佳实践
避免安装不必要的包
每个容器只关心一个问题
最小化层数
依赖库从制品库中获取,避免在容器中构建,提升镜像构建速度
尽可能使用官方镜像,推荐Debian镜像作为基础镜像,它被严格控制并且保持最小,同时是一个完整的发行版
避免ADD一个远程文件,而应该使用curl或者wget获取远程文件,减少镜像层数
&& curl -SL http://xxx.com/big.tar.xz \ |tar -xJC / usr/src/things
ADD
ENV
在容器中切换目录时使用WORKDIR,避免一下写法
RUN cd ... && dosomething
应该使用WORKDIR命令切换工作目录
WORKDIR
ENV foo/bar
WORKDIR ${foo}
构建微服务的docker镜像,先推送到local仓库
docker login art.local:8081 admin/passw0rd
docker build -t art.local:8081/docker-dev-local/notebook-k8s/notebook-service:latest
docker push att.lcoal:8081/docker-dev-local/notebook-k8s/notebook-service:latest
使用docker运行多个微服务(生成环境不用,使用chart)
docker run --name notebook-service -d -p 1111:1111
--link discovery-service:eureka-server
--link zipkin-service:zipkin-server
art.local:8081/docker/notebook-k8s/notebook-service:latest
jcr仓库制品晋级
在流水线中使用curl脚本晋级docker镜像
HTTP POST : http://localhost:8082/ui/api/v1/ui/artifactactions/copy
{
"repoKey": "docker-dev-local",
"path": "notebook-k8s/notebook-service/latest",
"targetRepoKey": "docker-release-local",
"targetPath": "notebook-k8s/notebook-service/latest"
}
搭建minikube
linux
minikube 不能以root方式启动,我们先创建个账号并且切过去
sudo useradd xingyue -g docker
passwd xingyue
1.切换到超级用户:$ su
2.打开/etc/sudoers文件:$vim /etc/sudoers
3.修改文件内容:
找到“root ALL=(ALL) ALL”一行,在下面插入新的一行,内容是“hadoop ALL=(ALL) ALL”,然后在vim键入命令“:wq!”保存并退出。
sudo groupadd docker
sudo usermod -aG docker ${USER}
sudo su - docker
yum update & yum clean all & yum list
curl -Lo kubectl http://kubernetes.oss-cn-hangzhou.aliyuncs.com/kubernetes-release/release/v1.20.0/bin/linux/amd64/kubectl && chmod +x ./kubectl && mv ./kubectl /usr/local/bin/kubectl;
curl -Lo minikube http://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/releases/v1.20.0/minikube-linux-amd64 && chmod +x ./minikube && mv ./minikube /usr/local/bin/minikube;
mac
curl -Lo kubectl http://kubernetes.oss-cn-hangzhou.aliyuncs.com/kubernetes-release/release/v1.20.0/bin/darwin/amd64/kubectl && chmod +x ./kubectl && mv ./kubectl /usr/local/bin/kubectl
curl -Lo minikube http://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/releases/v1.20.0/minikube-darwin-amd64 && chmod +x ./minikube && mv ./minikube /usr/local/bin/minikube
版本 v1.16.0
yum install -y conntrack
启动 2核8G(需要比分配给docker的内存小)
root用户启动,可能有问题
# minikube start --driver=none
其他用户(xingyue)启动
minikube start --driver=docker
# minikube start --cpus 2 --memory=8192mb;
# ! To use kubectl or minikube commands as your own user, you may need to relocate them. For example, to overwrite your own settings, run:
# *
# - sudo mv /root/.kube /root/.minikube $HOME
# - sudo chown -R $USER $HOME/.kube $HOME/.minikube
# *
# * This can also be done automatically by setting the env var CHANGE_MINIKUBE_NONE_USER=true
minikube status
启动docker镜像中心jcr
配置In-secure私有镜像中心
将本地docker镜像中心添加到Minikube中docker引擎的非安全白名单
/Users/xingyue/.minikube/machines/minikube/config.json
"120.78.81.53:8084"
docker login 120.78.81.53:8084 -uadmin -pXingyue5201314
添加minikube里jcr的域名解析
minikube ssh
su
sudo echo "172.19.200.145 art.local" >> /etc/hosts
kubectl create deployment nginx --image=nginx
minikube dashboard
端口在下面开启,同时在阿里云打开
用kubectl做个代理,代理到外网ip上
xingyue用户设置ip代理,记得要开启阿里云安全组,这样就能在外部访问了
nohup kubectl proxy --port=35960 --address='172.18.186.11' --accept-hosts='^.*' &
这行命令表示 该命令后台常驻运行。
并且暴漏外面端口 33721,代理地址到172.18.186.11 允许所有人访问。
然后我阿里云内网ip 192.168.0.191 自动转发到我阿里云外网ip,我就可以通过外网打开 dashboard了
利用命名空间为不同团队创建kubernates环境
多团队需要不同的kubernetes环境进行测试,生产部署
根据用户进行资源配额
default 默认命名空间
kube-system 环境使用的空间
kube-public 自动创建, 对所有用户可见,全局共享的资源使用
kubectl create namespace dev
kubectl delete namespace sit
kubectl run nginx --image=nginx -n dev
在dev namespace中创建pod
kubectl create -f k8s-deploy/discovery.yaml -n prod
kubectl get po -n dev
在kubernetes中创建pod
核心概念
cluster
namespace
nodes
persistent volumes
roles
storage classes
workloads
cron jobs
daemon sets
deployments
jobs
pods
replica sets
replication controllers
stateful sets
discovery and load balancing
ingress
services
config and storage
config maps
persistent volume claims
secrets
pod生命周期
pending 某一个容器没有被成功创建
running pod被分配到某个node正常运行
succeeded 正确终止
fail 至少有一个容器没有被正确终止
unkonw 失去通信
创建一个pod
kubectl run --image=nginx nginx-app --port=80
deployment.apps/nginx-app created
kubectl get pods
kubectl describe pods
一个pod一个容器(应用广泛), 共享资源
一个pod多个容器(共享资源,不好控制)
3种控制器
Deployment 维护pod在集群内部的部署和扩容
StatefulSet 维护有状态的pod在集群内部的部署和扩容(有编号)
DaemonSet 保证在集群的各个node上pod的副本在运行
创建notebook应用的service
用来描述pod
定义一个service
apiVersion: v1
kind: Service
metedata:
name: my-service
spec:
selector:
app: Myapp
ports:
-protpcol: TCP
port: 80
targetPort: 9376
service 对外暴露服务的方法
ClusterIP
NodePort
LoadBalancer(生产推荐)
External Name 外部域名
集群内部如何发现需要的Service
Environment variavles(系统环境变量)
当pod运行在node上,kubelet会为容器增加当前活动的service作为环境变量进行域名解析
{SVCNAME_SERVICE_HOST} {SVCNAME}_SERVICE_PORT (service名字会被转化成大写)
进入容器
kubelet exec -it xxx /bin/sh
printenv
DNS
cluster-aware DNS server -CoreDNS
kubectl get po
kubectl exec -it xxx /bin/sh
printenv
service 和 pod之间的调度 kube-proxy
随机
iptables
ipvs proxy mode (生产推荐) 可配置以什么为最优
IPVS规则和kubernetes
service定期同步
直接重定向最优服务器
性能优于Iptalbes Proxy
kubectl delete -f xxx.yaml
nodeport 指定端口
持久化存储
volumes 类型
emptydir 生命周期和pod相同 检查点,临时存放文件
local 必须配置nodeAffinity
nfs 共享存储
persistentVolumeClaim 持久化存储
cephfs
glusterfs 分布式多写
access mode
ReadWriteOnce 卷可以被单个node挂载为可读写卷
ReadOnlyMany 卷可以被多个node挂载为只读卷
ReadWriteMany 卷可以被多个node挂载为可读写卷
在Deployment中声明卷的挂载
在Deployment中声明PVC进行PV的匹配
storageClassName匹配
selector匹配存储的逻辑分类
这样即使重启,也不会丢失数据
声明pv
kind: PersistentVolume
apiVersion:v1
metadata:
name: task-pv-volume
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 3Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/data/jenkins-home"
使用pv
spec:
containers:
- name: jenkins
image: jenkins/jenkins:lts
ports:
- containerPort: 8080
volumeMounts:
- name: task-pv-storage
mountPath: "/var/jenkins_home"
volumes:
- name: task-pv-storage
persistentVolumeClaim:
claimName: task-pv-claim
为notebook创建deployment
提供pod和ReplicaSets的更新管理
Workloads
Pods
Controllers
ReplicaSet
ReplicationController
Deployments
StatefulSets
DaemonSet
Garbage Collection
TTL Controller for Finished Resources
Jobs - Run to Completion
CronJob
kubectl apply -f https://k8s.io/examples/controllers/nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
-name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
kubectl get deployments
更新deployment(版本升级)
kubectl --record deployment.apps/nginx-deployment set image deployment.v1.apps/nginx-deployment nginx=nginx:1.16.1
deployment.apps/nginx-deployment image updated
其中--record用于记录每次Deployment的差异
kubectl get rs
kubectl get pods
deployment 会保持副本数
deployment部署失败可能的原因
配额不够
Readiness探针检测失败
image拉取失败
权限访问不到
超出了资源限制范围
应用运行时配置错误
为 pod 创建探针
livenessProbe 表示容器是否运行
readinessProbe 表示容器内的应用是否可以开始提供服务
startupProbe 表示容器内部的应用已经启动,如果设置了该探针,在它成功之前,其他类型的探针不会生效
execAtion探针 在容器内部执行特定命令
apiVersion: v1
kind: Pod
metadata:
labels:
test:liveness
name: liveness-exec
spec:
containers:
- name: liveness
image: k8s.gcr.io/busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
livenessprobe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
TCPSocketAction 调用TCP请求确认容器是否正常服务
HTTPGetAction探针 发起一个http get 请求访问应用的某个端口和路径
livenessprobe:
httpGet:
path: /
port: 8761
initialDelaySeconds: 15
periodSeconds: 15
kubectl describe pod notebook-service-xx-xx 可以查看探针的状态
为应用添加configmap
apiVersion: v1
kind: ConfigMap
metadata:
name: game-demo
data:
play_inital_lives: 3
ui_properties_file_name: "user-interface.properties"
game.properties: /
enemy.types=aliens,monsters
player.maximum-lives=5
user-interface.properties: /
color.good=purple
color.gad=yellow
allow.textmode=true
存在etcd
明文
4种方式引用configmap
1,通过命令行参数的方式注入到容器的entrypoint
2,容器的环境变量
3,在卷中增加一个只读文件,供所有应该读取
4,在应用代码中调用kbs的api,读取configmap的信息
创建configmap
kubectl create configmap special-config --form-literal=special.how=very
创建configmapTest.yaml
kubectl create -f configmapTest.yaml
command:["/bin/sh", "-c", "env"]
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: k8s.gcr.io/busybox
command: ["/bin/sh", "-c", "env"]
env:
- name: SPECIAL_LEVEL_KEY
valueFrom:
configMapKeyRef:
name: special-config
key: special.how
restartPolicy: Never
kubectl logs xxx-xx-xxx
部署notebook微服务到k8s
常用命令
create kubectl create -f filename 创建一个或多个资源
apply kubectl apply -f filename 对某个资源进行变更
exec kubectl exec POD command 在pod中执行命令
get kubectl get type 列出一个或多个资源
logs kubectl 打印pod中容器的日志
top kubectl top 列出集群中的资源消耗情况
describe kubectl describe type 列出资源信息
delete kubectl delete -f pod.yaml 删除某些k8s对象
-o
--sort by (过滤)
-n (限定命名空间)
kubelet get svc
minikube ip
kubectl logs pod-name -f
sidecar
fluentD agent
pod 添加密钥
k8s的secret
作为文件挂载到一个或多个容器
作为容器的环境变量使用
在容器启动时,从kubelet从镜像中心拉取镜像
1,创建一个本地文件
echo -n 'admin' > ./username.txt
echo -n '1f2d1e2e67df' > ./password.txt
2,创建secret对象
kubectl create secret generic db-user-pass --form-file=./username.txt --from-file=./password.txt
kubectl get secrets
kubectl delete secrets xxx-xxx-xxx
3,创建一个docker镜像的secret
kubectl create secret docker-registry regcred-local --docker-server=art.local:8081 --docker-username=admin --docker-password=passw0rd [email protected] -n dev
4,查看日志
secret "db-user-pass" created
秘钥管理的最佳实践
1,管理员应该启用etcd文件目录的加密
2,管理员应该限制etcd的访问权限
3,管理员要定期删除etcd的文件和磁盘,如果不再使用的话
4,如果在集群里运行etcd,管理员应该启用SSL/TSL的通信
使用RBAC基于角色的权限控制管理密钥
service count
秘钥的watch和list的请求权限应该被保留在有限的系统管理员
为应用提供一个有限的秘钥访问白名单
helm入门
管理复杂的多容器部署
tar -zxvf helm-v3.0.0-linux-amd64.tar.gz
mv linux-amd64/helm /usr/local/bin/helm
在JCR中创建Helm远程仓库
远程仓库可以指向国内源:http://mirror.azure.cn/kubernetes/charts/
在本地配置远程仓库
helm repo add stable http://120.78.81.53:8081/artifactory/helm
setme up
helm repo add helm-virtual http://120.78.81.53:8084/artifactory/api/helm/helm-virtual --username admin --password Xingyue@5201314
helm repo update
helm install stable/mysql --generate-name
helm ls
创建第一个Helm Chart
helm create foo
部署一个helm chart到kubernetes
helm install --set name=prod myredis ./redis
覆盖
helm install -f myvalues.yaml -f override.yaml myredis ./redis
从helm仓库安装
helm install mymaria example/mariadb
安装一个helm chart包
helm install mynginx ./nginx-1.2.3.tgz
从Chart目录安装
helm install mynginx ./nginx
从Chart绝对路径安装
heml install mynginx https://example.com/chart/nginx-1.2.3.tgz
指定仓库路径安装
helm install --repo https://example.com/charts/mynginx nginx
更新,一键升级
helm upgrade -f myvalues.yaml -f override.yaml redis ./redis
charts 目录存放依赖的chart
Chart.yaml 包含Chart的基本信息,包括chart版本,名称等
templates 目录下存放应用一系列 k8s 资源的 yaml 模板
_helpers.tpl 此文件中定义一些可重用的模板片断,此文件中的定义在任何资源定义模板中可用
NOTES.txt 介绍chart 部署后的帮助信息,如何使用chart等
values.yaml 包含了必要的值定义(默认值), 用于存储 templates 目录中模板文件中用到变量的值
为notebook服务创建helmchart
在jcr镜像仓库中创建helm-local仓库
远程仓库可以指向国内源
http://mirror.azure.cn/kubernetes/charts/
在jcr中创建helm虚拟仓库
虚拟仓库聚合,从上往下找
set me up
在helm客户端配置helm仓库
helm repo add helm http://localhost:8081/artifactory/helm --username admin --password Xxx
deploy 上传
resolve 提供下载给别人用
推荐使用3.0部署
helm repo ls
从源码部署
helm install -f values.yaml notebook ./
打包chart,上传chart到jcr
cd charts/
helm package notebook
curl -uadmin:passw0rd -T ~/code/notebook-k8s/kube-depoly/charts/notebook-0.1.1.tgz "http://localhost:8081/artifactory/helm/notebook-0.1.1.tgz"
helm search repo notebook
本地更新
helm repo update
提供拉取使用
helm install notebook helm/notebook
使用helm进行应用的升级和回滚
修改版本,修改副本数,打包
上传到jcr
helm search repo notebook
指定更新版本
helm upgrade notebook helm/notebook --version 0.2.0
helm ls
helm rollback notebook 1
编写notebook应用新功能关联lira需求并运行在本地测试环境
使用jira
提交代码到master
在jenkins流水线进行打包代码扫描镜像构建
dockerfile
推送到本地jcr
不集成YAPI
在jenkins里将该镜像上传到JCR并部署到k8s的测试环境空间
在jenkins中触发流水线
上传notebook的镜像,和chart到jcr
通过helm install 部署notebook等多个服务
登录k8s查看状态
jenkins触发接口自动化测试
在YAPI中创建容器dev环境
在jenkins中对该docker镜像晋级到prod仓库
jenkins 打生产环境的包推送到制品库
在jenkins里将该镜像部署到k8s的生产环境空间
修改脚本,不同命名空间
docker 可视化
docker volume create portainer_data
docker run --name portainer -d -p 8000:8000 -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer
k8s可视化
kubeview
docker pull ghcr.io/benc-uk/kubeview:latest
# 添加仓库
helm repo add kubeview https://benc-uk.github.io/kubeview/charts
# 下载kubeview到本地
helm pull kubeview/kubeview
# 解压下载的kubeview
tar -zxvf kubeview-0.1.20.tgz
# 根据需要修改values.yaml文件
vim kubeview/valus.yaml
# 启动kubeview
helm install kubeview kubeview/kubeview -f kubeview/valus.yaml
rancher
容器管理