hello
发布于 2022-04-26
/
18 阅读
基于docker、K8S的CICD应用环境
前言
(本书关注基于docker的生态系统搭建、运维、开发、测试)
如何搭建python(django/flask)、php、tomcat等docker的开发环境?
如何运用yum本地源、gitlab软件仓库、registry应用仓库、kubernetes完成CICD?
版本:
KVM+CoreOS(1855.4, docker 18.06)
微信文章
docker 基础
基本概念
docker是什么?docker仓库是什么?
为了解决应用环境配置的难题,将一个个应用打包成镜相(image),存放这个镜相的地方称为docker仓库(registry),运行起来的实例称为容器(container)
站在 Docker 的角度,软件就是容器的组合:业务逻辑容器、数据库容器、储存容器、队列容器……Docker 使得软件可以拆分成若干个标准化容器,然后像搭积木一样组合起来。
如何使用?
通过一组docker命令来实现打包、运行、起动、停止、删除、上传、下载等一系列相关操作。
有何特性?
package once, run anywhere.
安装
升级docker
[root@docker ~]# yum install docker-ce
测试容器:
docker run –name busybox -d busybox /bin/sh -c “while true; do sleep 1; done”
docker exec -it busybox sh
docker run –name dbtest -itd debian bash
docker run –name ubtest -itd ubuntu bash
常用配置
镜像源为国内官方源以及内部仓库
[root@docker ~]# vim /etc/docker/daemon.json
“insecure-registries”: [ “192.168.31.140:5000″,”192.168.100.222:5000”]
或者通过修改/etc/default/docker
DOCKER_OPTS=”–registry-mirror=https://registry.docker-cn.com”
$DOCK_REG_IP=”192.168.31.140″
#IP=`ip addr show dev eth0|grep -Po ‘inet \K\w*.\w*.\w*.\w*’`
sed -i.ori “s#ExecStart=/usr/bin/dockerd#ExecStart=/usr/bin/dockerd –insecure-registry $DOCK_REG_IP:4000 –mtu 1400#” /usr/lib/systemd/system/docker.service
重启docker: systemctl restart docker
基本命令
docker start/stop/logs/restart
dockerfiile
ubuntu jenkins example
RUN echo ” > /etc/apt/sources.list.d/jessie-backports.list && \
apt-get update && apt-get install -y git
使用supervisord示例
Dockerfile
RUN yum install epel-release -y
RUN yum install nginx supervisor -y && yum clean all
RUN sed -i ’47a proxy_pass http://127.0.0.1:9000;’ /etc/nginx/nginx.conf
COPY supervisord.conf /etc/supervisord.conf
ENV PATH /usr/local/jdk/bin:$PATH
CMD [“/usr/bin/supervisord”]
supervisord.conf
command=/usr/local/jdk/bin/java -jar /tale/tale-least.jar
command=/usr/sbin/nginx -g “daemon off;”
docker-compose
升级docker-compose至指定版本
chmod +x /usr/local/bin/docker-compose
docker-compose.yml
mkdir /opt/cmp_bind;cd /opt/cmp_bind;
vi docker-compose.yml
bind:
– /opt/bind/entrypoint.sh:/sbin/entrypoint.sh
基本命令
docker-compose start/stop/rm/restart/logs
docker registry
registry-srv
docker run
-v /mnt/registry:/var/lib/registry \
-v `pwd`/config-srv.yml:/etc/docker/registry/config.yml \
测试
docker tag busybox localhost:5000/busybox
docker push localhost:5000/busybox
registry-web
docker run
-v $(pwd)/config-web.yml:/conf/config.yml:ro \
-e REGISTRY_BASIC_AUTH=”`echo adm:123123|base64`” \
hyper/docker-registry-web
参考
https://hub.docker.com/_/registry/
https://hub.docker.com/r/hyper/docker-registry-web/
https://docs.docker.com/registry/configuration/#list-of-configuration-options
https://blog.csdn.net/mideagroup/article/details/52052618
https://blog.csdn.net/snipercai/article/details/78589368
registry portus
安装
git clone https://github.com/SUSE/Portus.git
sed -i ‘s#https://rubygems.org#http://rubygems.org#’ ./Gemfile
sed -i ‘s#https://rubygems.org#http://rubygems.org#’ ./Gemfile.lock
docker清理数据
docker image prune:删除无用的镜像。
docker container prune:删除无用的容器。
docker volume prune:删除无用的卷。
docker network prune:删除无用的网络。
docker system prune:删除无用的镜像、容器、卷、网络。
压缩镜相工具dive
docker run –rm -it -v /var/run/docker.sock:/var/run/docker.sock -e DOCKER_API_VERSION=1.39 wagoodman/dive:latest <image name>
docker搭建基础应用环境
yum 源
示例: openstack.repo:
name=OpenStack Havana Repository
createrepo
createrepo –update /usr/local/apache/htdocs/centos/extra 更新索引
DNS
理论:
有如下记录类型:A,AAAA,PTR,SOA,NS,CNAME,MX
A:Internet Address,作用,FQDN 到 IP
NS:Name Server,专用于表明当前区域的DNS服务器
CNAME:Canonical Name,别名记录
主从
问题:使用docker搭建主从同步,无法同步记录connect refuse
docker
docker pull docker.io/jpillora/dnsmasq
docker run –name dnsmasq -d \
-p 53:53/udp -p 8080:8080 \
-v /opt/dnsmasq.conf:/etc/dnsmasq.conf \
-e “HTTP_USER=admin” -e “HTTP_PASS=admin” \
–restart always jpillora/dnsmasq
docker run –name bind -d \
-e WEBMIN_ENABLED=false \
-v /opt/bind/entrypoint.sh:/sbin/entrypoint.sh \
docker-compose
mkdir /opt/cmp_bind;cd /opt/cmp_bind;
– /opt/bind/entrypoint.sh:/sbin/entrypoint.sh
mysql
基本命令
示例:
#备份
mysqldump -uroot -p<pwd> -h172.16.40.7 –all-databases >mysqlbakdate +%Y%m%d-%H%M%S .sql
mysql -e “show databases;” -uroot -ppassword -h172.16.40.7| grep -Ev “Database|information_schema|mysql|performance_schema|dbtest|sys”| xargs mysqldump -uroot -ppassword -h172.16.40.7 –set-gtid-purged=OFF –no-tablespaces –databases > mysqlbak`date +%Y%m%d-%H%M%S`.sql
#sql 字符index号,长度:
select position(‘/’ in @str) as i;
select substring(@str,position(‘/’ in @str)+1,LENGTH(@str)) join
select substring(@str,1,position(‘/’ in @str)-1);
select cast(substring(@str,position(‘/’ in @str)+1,LENGTH(@str)) as decimal);
$sql=”select `date`,b.hostname,a.ip,cpu,mem,`storage`,net from ($table_name as a inner join hostip as b on trim(a.ip)=trim(b.ip)) order by cast(substring(mem,position(‘/’ in mem)+1,LENGTH(mem)) as decimal)”
#mysql 加一用户可任意IP登陆
CREATE USER yanght@’%’ IDENTIFIED BY ‘123456’;
grant all privileges on *.* to yanght@’%’ identified by ‘123456’;
#限子网段访问
grant all on *.* to ‘account’@’192.168.0.%’ identified by ‘acc430’;
#mysql max_connections
Edit file /usr/lib/systemd/system/mysqld.service
$ systemctl daemon-reload
$ systemctl restart mysqld.service
#load data:
LOAD DATA INFILE ‘/home/test/dump/ip_location.csv’
#create table test.mteveryday select …from…
#drop table test.mteveryday
#update join
UPDATE friends INNER JOIN users ON friends.friendid=users.userid
SET friends.friendname=users.username
#insert into
insert into table1(field1,field2..)
select col1,col2 from table2
docker run
docker run –name yunwei-mariadb \
-e MYSQL_ROOT_PASSWORD=123321 \
-v /opt/mysql:/var/lib/mysql \
docker-compose.yml
mkdir /opt/cmp_mysql;cd /opt/cmp_mysql;
– MYSQL_ROOT_PASSWORD=123321
双主结构
1.优化系统
cat >>/etc/security/limits.conf<<eof
cat >>/etc/sysctl.conf<<eof
2.配置my.cnf
#server1——————————
log_bin = /var/log/mysql/mariadb-bin
log_bin_index = /var/log/mysql/mariadb-bin.index
binlog-do-db = tudou1 #需要同步的数据库,这里同步tudou1和tudou2两个数据库
binlog-ignore-db = mysql #忽略同步的数据库
log_slave_updates #把从库的写操作记录到binlog中 (缺少之后,双主创建失败)
expire_logs_days = 365 #日志文件过期天数,默认是 0,表示不过期
auto_increment_increment= 2 #设定为主服务器的数量,防止auto_increment字段重复
auto_increment_offset = 1 #自增长字段的初始值,在多台master环境下,不会出现自增长ID重复
#server2——————————
log_bin = /var/log/mysql/mariadb-bin
log_bin_index = /var/log/mysql/mariadb-bin.index
binlog-do-db = tudou1 #需要同步的数据库,这里同步tudou1和tudou2两个数据库
binlog-ignore-db = mysql #忽略同步的数据库
log_slave_updates #把从库的写操作记录到binlog中 (缺少之后,双主创建失败)
expire_logs_days = 365 #日志文件过期天数,默认是 0,表示不过期
auto_increment_increment= 2 #设定为主服务器的数量,防止auto_increment字段重复
auto_increment_offset = 2 #自增长字段的初始值,在多台master环境下,不会出现自增长ID重复
3.创建同步账户
GRANT REPLICATION SLAVE ON *.* TO ‘repuser’@’server-2’ IDENTIFIED BY ‘repuser’;
GRANT REPLICATION SLAVE ON *.* TO ‘repuser’@’server-1’ IDENTIFIED BY ‘repuser’;
可以顺便在另一台服务器测试能不能登录,如果不能,把 bind-address 那行注释掉即可。
$ mysql -urepuser -prepuser -hserver-1
4.查看 master 状态
MariaDB [mysql]> show master status;
+——————–+———-+————–+——————+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+——————–+———-+————–+——————+
| mariadb-bin.000514 | 639 | xxxxxxxx | mysql |
+——————–+———-+————–+——————+
MariaDB [mysql]> show master status;
+——————–+———-+————–+——————+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+——————–+———-+————–+——————+
| mariadb-bin.000006 | 1057 | xxxxxxxx | mysql |
+——————–+———-+————–+——————+
5.设置同步
MariaDB [mysql]> CHANGE MASTER TO MASTER_HOST=’server-1′,MASTER_PORT=3306,MASTER_USER=’repuser’,MASTER_PASSWORD=’repuser’,MASTER_LOG_FILE=’mariadb-bin.000514′,MASTER_LOG_POS=639;
MariaDB [mysql]> START SLAVE;
MariaDB [mysql]> CHANGE MASTER TO MASTER_HOST=’server-2′,MASTER_PORT=3306,MASTER_USER=’repuser’,MASTER_PASSWORD=’repuser’,MASTER_LOG_FILE=’mariadb-bin.000006′,MASTER_LOG_POS=1057;
MariaDB [mysql]> START SLAVE;
6.测试:
MariaDB [mysql]> SHOW SLAVE STATUS\G
在服务器 1 数据库中创建一个表,看看服务器 2 会不会出现,按照上面教程,如果没问题的话,就是可以同步的。
mariadb-server-galeara 多主结构
nfs
docker
-v /some/where/fileshare:/nfsshare \
-e SHARED_DIRECTORY=/nfsshare \
itsthenetwork/nfs-server-alpine:latest
docker-compose
mkdir /opt/cmp1_nfs;cd /opt/cmp_nfs;
image: itsthenetwork/nfs-server-alpine
# Required to load kernel NFS module
– SHARED_DIRECTORY=/nfsshare
exportfs
/nfsshare *(rw,fsid=0,async,no_subtree_check,no_auth_nlm,insecure,no_root_squash)
#注意 :将原root_squash改为no_root_squash,否则root将不能写挂载的NFS卷
#client:
mount -t nfs4 <host>:/ /opt
NGINX
docker run
docker run –name mynginx \
-v /opt/nginx:/etc/nginx \
-v /opt/nginxlog:/var/log/nginx \
-v /opt/nginx/hosts:/etc/hosts \
docker-compose.yml
mkdir /opt/cmp_nginx;cd /opt/cmp_nginx;
– /opt/nginxlog:/var/log/nginx
– /opt/nginx/hosts:/etc/hosts
http 下载
#more download.yunwei.edu.conf
server_name download.yunwei.edu;
access_log /var/log/nginx/download.access_log access;
error_log /var/log/nginx/download.error_log info;
autoindex_exact_size off;
#关闭详细文件大小统计,让文件大小显示MB,GB单位,默认为b;
if ($request_filename ~* ^.*?\.(txt|doc|pdf|rar|gz|zip|docx|exe|xlsx|ppt|pptx|tgz
add_header Content-Disposition: ‘attachment;’;
参考:
http://blog.csdn.net/hzsunshine/article/details/63687054
http://blog.csdn.net/zzq900503/article/details/70049348
https://www.cnblogs.com/zhouxinfei/p/7862285.html
openvpn
docker-compose.yml
mkdir cmp_ovpn;cd cmp_ovpn
– ./ovpn_data:/etc/openvpn
配置:
server: openvpn.conf
================================================
server 192.168.255.0 255.255.255.0
key /etc/openvpn/pki/private/192.168.31.140.key
ca /etc/openvpn/pki/ca.crt
cert /etc/openvpn/pki/issued/192.168.31.140.crt
dh /etc/openvpn/pki/dh.pem
tls-auth /etc/openvpn/pki/ta.key
# Rely on Docker to do port mapping, internally always 1194
status /tmp/openvpn-status.log
client-config-dir /etc/openvpn/ccd
### Route Configurations Below
route 192.168.254.0 255.255.255.0
### Push Configurations Below
push “dhcp-option DNS 114.114.114.114”
push “dhcp-option DNS 223.5.5.5”
server: ccd
====================================================
root@docker116:50:12/opt/ovpn_data#more ccd/client*
ifconfig-push 192.168.255.10 192.168.255.9
ifconfig-push 192.168.255.14 192.168.255.13
ifconfig-push 192.168.255.18 192.168.255.17
生成证书与client配置
docker pull kylemanna/openvpn
#OVPN_DATA=”/root/ovpn-data”
OVPN_DATA=”/opt/cmp_ovpn/ovpn_data”
docker run -v ${OVPN_DATA}:/etc/openvpn –rm kylemanna/openvpn ovpn_genconfig -u tcp://${IP}
docker run -v ${OVPN_DATA}:/etc/openvpn –rm -it kylemanna/openvpn ovpn_initpki
Enter PEM pass phrase: 输入123456(你是看不见的)
Verifying – Enter PEM pass phrase: 输入123456(你是看不见的)
Common Name (eg: your user, host, or server name) [Easy-RSA CA]:回车一下
Enter pass phrase for /etc/openvpn/pki/private/ca.key:输入123456
#docker run -v ${OVPN_DATA}:/etc/openvpn –rm -it kylemanna/openvpn easyrsa build-client-full CLIENTNAME nopass
docker run -v ${OVPN_DATA}:/etc/openvpn –rm -it kylemanna/openvpn easyrsa build-client-full client1 nopass
Enter pass phrase for /etc/openvpn/pki/private/ca.key:输入123321
#docker run -v ${OVPN_DATA}:/etc/openvpn –rm kylemanna/openvpn ovpn_getclient CLIENTNAME > ${OVPN_DATA}/CLIENTNAME.ovpn
docker run -v ${OVPN_DATA}:/etc/openvpn –rm kylemanna/openvpn ovpn_getclient client1 > ${OVPN_DATA}/client1.ovpn
docker run –name openvpn -v ${OVPN_DATA}:/etc/openvpn -d -p 1194:1194 –privileged kylemanna/openvpn
增加client
OVPN_DATA=”/opt/cmp_ovpn/ovpn_data”
docker run -v ${OVPN_DATA}:/etc/openvpn –rm -it kylemanna/openvpn easyrsa build-client-full $NAME nopass
docker run -v ${OVPN_DATA}:/etc/openvpn –rm kylemanna/openvpn ovpn_getclient $NAME > ${OVPN_DATA}/$NAME.ovpn
sed -i ‘s/192.168.31.140/139.198.16.150/’ ${OVPN_DATA}/$NAME.ovpn
路由与NAT
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
vsFTP
docker-compose.yml
mkdir /opt/cmp_vsftpd;cd /opt/cmp_vsftpd;
– “21100-21110:21100-21110”
– ./vsftpd.conf:/etc/vsftpd/vsftpd.conf
– ./run-vsftpd.sh:/usr/sbin/run-vsftpd.sh
# – PASV_ADDRESS=192.168.100.222
docker run
-v /my/data/directory:/home/vsftpd \
-p 21100-21110:21100-21110 \
-e FTP_USER=myuser -e FTP_PASS=mypass \
-e PASV_ADDRESS=127.0.0.1 \
vsftpd.conf
# Run in the foreground to keep the container running:
# Allow anonymous FTP? (Beware – allowed by default if you comment this out).
anon_world_readable_only=yes
anon_other_write_enable=YES
anon_mkdir_write_enable=yes
anon_root=/home/vsftpd/anonymous
# Uncomment this to allow local users to log in.
## Virtual users will use the same permissions as anonymous
virtual_use_local_privs=YES
# Uncomment this to enable any form of FTP write command.
pam_service_name=vsftpd_virtual
## Home Directory for virtual users
# You may specify an explicit list of local users to chroot() to their home
# directory. If chroot_local_user is YES, then this list becomes a list of
# Workaround chroot check.
# See https://www.benscobie.com/fixing-500-oops-vsftpd-refusing-to-run-with-writable-root-inside-chroot/
# and http://serverfault.com/questions/362619/why-is-the-chroot-local-user-of-vsftpd-insecure
allow_writeable_chroot=YES
## Set passive port address
xferlog_file=/var/log/vsftpd/vsftpd.log
## Disable seccomp filter sanboxing
pasv_address=192.168.31.141
run-vsftpd.sh
# If no env var for FTP_USER has been specified, use ‘admin’:
if [ “$FTP_USER” = “**String**” ]; then
# If no env var has been specified, generate a random password for FTP_USER:
if [ “$FTP_PASS” = “**Random**” ]; then
export FTP_PASS=`cat /dev/urandom | tr -dc A-Z-a-z-0-9 | head -c${1:-16}`
# Do not log to STDOUT by default:
if [ “$LOG_STDOUT” = “**Boolean**” ]; then
# Create home dir and update vsftpd user db:
mkdir -p “/home/vsftpd/${FTP_USER}”
chown -R ftp:ftp /home/vsftpd/
echo -e “${FTP_USER}\n${FTP_PASS}” > /etc/vsftpd/virtual_users.txt
/usr/bin/db_load -T -t hash -f /etc/vsftpd/virtual_users.txt /etc/vsftpd/virtual_users.db
# Set passive mode parameters:
if [ “$PASV_ADDRESS” = “**IPv4**” ]; then
export PASV_ADDRESS=$(/sbin/ip route|awk ‘/default/ { print $3 }’)
###echo “pasv_address=${PASV_ADDRESS}” >> /etc/vsftpd/vsftpd.conf
###echo “pasv_max_port=${PASV_MAX_PORT}” >> /etc/vsftpd/vsftpd.conf
###echo “pasv_min_port=${PASV_MIN_PORT}” >> /etc/vsftpd/vsftpd.conf
export LOG_FILE=`grep xferlog_file /etc/vsftpd/vsftpd.conf|cut -d= -f2`
if [ ! $LOG_STDOUT ]; then
*************************************************
* Docker image: fauria/vsftd *
* https://github.com/fauria/docker-vsftpd *
*************************************************
· FTP Password: $FTP_PASS
· Redirect vsftpd log to STDOUT: No.
/usr/bin/ln -sf /dev/stdout $LOG_FILE
&>/dev/null /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf
sendmail
dockerfile
mkdir /opt/cmp_sendmail; cd /opt/cmp_sendmail
MAINTAINER yht yanght “me@yunwei.edu”
RUN set -e && apt-get update && apt-get install -y sendmail
#COPY sendmail.mc /etc/mail/sendmail.mc
RUN m4 sendmail.mc > sendmail.cf && \
echo “Connect:172 RELAY” >> access && \
echo “Connect:10 RELAY” >> access && \
echo “Connect:192 RELAY” >> access && \
echo “Connect:yunwei.edu RELAY” >> access && \
CMD /usr/lib/sendmail -bD -X /proc/self/fd/1
docker run配置
docker build -t ubuntu.sendmail ./
docker run –name sendmail -p 25:25 -d ubuntu.sendmail
docker cp sendmail:/etc/mail/sendmail.mc .
sed ‘s/127.0.0.1/0.0.0.0/g’ sendmail.mc
docker cp ./sendmail.mc sendmail:/etc/mail/sendmail.mc
docker exec -it sendmail bash
m4 sendmail.mc >sendmail.cf
docker-compose
– ./sendmail.cf:/etc/mail/sendmail.cf
– ./access.db:/etc/mail/access.db
DHCP
固定IP分配
host Client_C { #有一个主机 ,叫Client_C
hardware ethernet 08:00:27:5e:04:27; #MAC地址是08 :…:27的网卡
fixed-address 192.168.233.123;#分配给它192 .168.233.123的IP
kubernetes
概念
svc pod node ep container
clusterip ep nodeip containerip
Kubernetes是:
Kubernetes是Google开源的容器集群管理系统,是Docker容器的主要集群管理系统之一。
主要功能如下:
1)将多台Docker主机抽象为一个资源,以集群方式管理容器,包括任务调度、资源管理、弹性伸缩、滚动升级等功能。
2)使用编排系统(YAML File)快速构建容器集群,提供负载均衡,解决容器直接关联及通信问题
3)自动管理和修复容器,简单说,比如创建一个集群,里面有十个容器,如果某个容器异常关闭,那么,会尝试重启或重新分配容器,始终保证会有十个容器在运行,反而杀死多余的。
Kubernetes中的PodIP、ClusterIP和外部IP
Kubernetes中管理主要有三种类型的IP:Pod IP 、Cluster IP 和 外部IP。
Pod IP
Kubernetes的最小部署单元是Pod。利用Flannel作为不同HOST之间容器互通技术时,由Flannel和etcd维护了一张节点间的路由表。Flannel的设计目的就是为集群中的所有节点重新规划IP地址的使用规则,从而使得不同节点上的容器能够获得“同属一个内网”且”不重复的”IP地址,并让属于不同节点上的容器能够直接通过内网IP通信。
每个Pod启动时,会自动创建一个镜像为gcr.io/google_containers/pause:0.8.0的容器,容器内部与外部的通信经由此容器代理,该容器的IP也可以称为Pod IP。
Cluster IP
Pod IP 地址是实际存在于某个网卡(可以是虚拟设备)上的,但Service Cluster IP就不一样了,没有网络设备为这个地址负责。它是由kube-proxy使用Iptables规则重新定向到其本地端口,再均衡到后端Pod的。
就拿上面我们提到的图像处理程序为例。当我们的Service被创建时,Kubernetes给它分配一个地址10.0.0.1。这个地址从我们启动API的service-cluster-ip-range参数(旧版本为portal_net参数)指定的地址池中分配,比如–service-cluster-ip-range=10.0.0.0/16。假设这个Service的端口是1234。集群内的所有kube-proxy都会注意到这个Service。当proxy发现一个新的service后,它会在本地节点打开一个任意端口,建相应的iptables规则,重定向服务的IP和port到这个新建的端口,开始接受到达这个服务的连接。
当一个客户端访问这个service时,这些iptable规则就开始起作用,客户端的流量被重定向到kube-proxy为这个service打开的端口上,kube-proxy随机选择一个后端pod来服务客户。这个流程如下图所示:
根据Kubernetes的网络模型,使用Service Cluster IP和Port访问Service的客户端可以坐落在任意代理节点上。外部要访问Service,我们就需要给Service外部访问IP。
外部IP
Service对象在Cluster IP range池中分配到的IP只能在内部访问,如果服务作为一个应用程序内部的层次,还是很合适的。如果这个Service作为前端服务,准备为集群外的客户提供业务,我们就需要给这个服务提供公共IP了。
外部访问者是访问集群代理节点的访问者。为这些访问者提供服务,我们可以在定义Service时指定其spec.publicIPs,一般情况下publicIP 是代理节点的物理IP地址。和先前的Cluster IP range上分配到的虚拟的IP一样,kube-proxy同样会为这些publicIP提供Iptables 重定向规则,把流量转发到后端的Pod上。有了publicIP,我们就可以使用load balancer等常用的互联网技术来组织外部对服务的访问了。
spec.publicIPs在新的版本中标记为过时了,代替它的是spec.type=NodePort ,这个类型的service,系统会给它在集群的各个代理节点上分配一个节点级别的端口,能访问到代理节点的客户端都能访问这个端口,从而访问到服务。
kubernetes角色组成:
1)Pod
Pod是kubernetes的最小操作单元,一个Pod可以由一个或多个容器组成;同一个Pod只能运行在同一个主机上,共享相同的volumes、network、namespace;
2)ReplicationController(RC)
RC用来管理Pod,一个RC可以由一个或多个Pod组成,在RC被创建后,系统会根据定义好的副本数来创建Pod数量。在运行过程中,如果Pod数量小于定义的,就会重启停止的或重新分配Pod,反之则杀死多余的。当然,也可以动态伸缩运行的Pods规模。
RC通过label关联对应的Pods,在滚动升级中,RC采用一个一个替换要更新的整个Pods中的Pod。
Replication Controller是Kubernetes系统中最有用的功能,实现复制多个Pod副本,往往一个应用需要多个Pod来支撑,并且可以保证其复制的副本数,即使副本所调度分配的主宿机出现异常,通过Replication Controller可以保证在其它主宿机启用同等数量的Pod。Replication Controller可以通过repcon模板来创建多个Pod副本,同样也可以直接复制已存在Pod,需要通过Label selector来关联。
3)Service
Service定义了一个Pod逻辑集合的抽象资源,Pod集合中的容器提供相同的功能。集合根据定义的Label和selector完成,当创建一个Service后,会分配一个Cluster IP,这个IP与定义的端口提供这个集合一个统一的访问接口,并且实现负载均衡。
Services是Kubernetes最外围的单元,通过虚拟一个访问IP及服务端口,可以访问我们定义好的Pod资源,目前的版本是通过iptables的nat转发来实现,转发的目标端口为Kube_proxy生成的随机端口
4)Label
Label是用于区分Pod、Service、RC的key/value键值对;
Pod、Service、RC可以有多个label,但是每个label的key只能对应一个;
主要是将Service的请求通过lable转发给后端提供服务的Pod集合;
Labels是用于区分Pod、Service、Replication Controller的key/value键值对,仅使用在Pod、Service、 Replication Controller之间的关系识别,但对这些单元本身进行操作时得使用name标签。
5) Proxy
Proxy不但解决了同一主宿机相同服务端口冲突的问题,还提供了Service转发服务端口对外提供服务的能力,Proxy后端使用了随机、轮循负载均衡算法。
kubernetes组件组成:
1)kubectl
客户端命令行工具,将接受的命令格式化后发送给kube-apiserver,作为整个系统的操作入口。
2)kube-apiserver
作为整个系统的控制入口,以REST API服务提供接口。
3)kube-controller-manager
用来执行整个系统中的后台任务,包括节点状态状况、Pod个数、Pods和Service的关联等。
4)kube-scheduler
负责节点资源管理,接受来自kube-apiserver创建Pods任务,并分配到某个节点。
6)kube-proxy
运行在每个计算节点上,负责Pod网络代理。定时从etcd获取到service信息来做相应的策略。
7)kubelet
运行在每个计算节点上,作为agent,接受分配该节点的Pods任务及管理容器,周期性获取容器状态,反馈给kube-apiserver。
8)DNS
一个可选的DNS服务,用于为每个Service对象创建DNS记录,这样所有的Pod就可以通过DNS访问服务了。
Kubernetes 暴露服务的有三种方式
我们知道,到目前为止 Kubernetes 暴露服务的有三种方式,分别为 LoadBlancer Service、NodePort Service、Ingress。
官网对 Ingress 的定义为管理对外服务到集群内服务之间规则的集合,通俗点讲就是它定义规则来允许进入集群的请求被转发到集群中对应服务上,从来实现服务暴漏。 Ingress 能把集群内 Service 配置成外网能够访问的 URL,流量负载均衡,终止SSL,提供基于域名访问的虚拟主机等等。
LoadBlancer Service
LoadBlancer Service 是 Kubernetes 结合云平台的组件,如国外 GCE、AWS、国内阿里云等等,使用它向使用的底层云平台申请创建负载均衡器来实现,有局限性,对于使用云平台的集群比较方便。
NodePort Service
NodePort Service 是通过在节点上暴漏端口,然后通过将端口映射到具体某个服务上来实现服务暴漏,比较直观方便,但是对于集群来说,随着 Service 的不断增加,需要的端口越来越多,很容易出现端口冲突,而且不容易管理。当然对于小规模的集群服务,还是比较不错的。
Ingress
Ingress 使用开源的反向代理负载均衡器来实现对外暴漏服务,比如 Nginx、Apache、Haproxy等。Nginx Ingress 一般有三个组件组成:
Ingress Controller
Ingress Controller 可以理解为控制器,它通过不断的跟 Kubernetes API 交互,实时获取后端 Service、Pod 等的变化,比如新增、删除等,然后结合 Ingress 定义的规则生成配置,然后动态更新上边的 Nginx 负载均衡器,并刷新使配置生效,来达到服务自动发现的作用。
Ingress
Ingress 则是定义规则,通过它定义某个域名的请求过来之后转发到集群中指定的 Service。它可以通过 Yaml 文件定义,可以给一个或多个 Service 定义一个或多个 Ingress 规则。
1.9版本安装使用
下载镜相的方法
1.12.1相关TAR包的方法:
docker pull mirrorgooglecontainers/kube-apiserver-amd64:v1.12.1
安装
后加节点:
kubeadm token create –print-join-command
coreos
前言:
coreOS+k8s+calico网络, 对行性能来说,也许是最佳选择,我们花些时间来研究一下
概念:
coreOS,是一种containerOS, 以docker为应用载体,以集群运行的理念,删繁就简,据称会比一般系统运行容器快N倍,强大到AWS、GOOGLE都是使用他做底层系统的,据称前身是ChromeOS,ETCD、CNI等很多技术都是这家公司提出的。
安装
方法一:直接下载官方 镜相
安装qemu:
yum install qemu-system-x86 qemu-img -y
下载
gpg –verify coreos_production_qemu.sh.sig
gpg –verify coreos_production_qemu_image.img.bz2.sig
bzip2 -d coreos_production_qemu_image.img.bz2
启动
./coreos_production_qemu.sh -nographic
ssh config
ssh -l core -p 2222 localhost
config:
cat >>~/.ssh/config <<EOF
UserKnownHostsFile /dev/null
转到kvm上:(上面的官网提供的方法,用qemu不好管理,不知道怎么关机、clone等,但可以转到KVM上,用virsh管理)
编一个虚拟机的XML,可以从已有的虚拟机导出再编辑一下:
virsh dumpxml kvm01 > coreos01.xml
vi coreos01.xml #修改硬盘位置为下载的img文件 ,改名字改mac地址,UUID删除
启动测试: virsh start coreos01
方法二:使用ISO启动安装到KVM虚拟硬盘(方法一的缺点是默认img的硬盘空间有限,根目录只有6G且不容易扩充)
准备http下载和相关文件
如没有http下载,可以临时架一个:
mkdir /mnt/smhttp;cd /mnt/smhttp; python -m SimpleHTTPServer 80
准备cloud-config.yml (安装的配置文件)
安装虚拟机 (内存要大于1G)
virt-install -n coreosbase -r 2048 \
–disk /mnt/kvm/coreosbase.img,format=qcow2,size=20 \
–os-type=linux –os-variant=rhel7 \
–cdrom /mnt/download/coreos/coreos_production_iso_image.iso \
–vnc –vncport=5910 –vnclisten=0.0.0.0
# iso启动后,VNC连接上:
临时配个IP: sudo ifconfig eth0 192.168.31.122 # 如果br0网络有DHCP,可以省略此步
sudo wget http://192.168.31.202/cloud-config.yaml
sudo coreos-install -d /dev/vda -c cloud-config.yaml -b http://192.168.31.202
装完重启并连接:
ssh core@192.168.31.22 # IP是cloud-config.yaml里配置的
cat >>/etc/docker/daemon.json <<EOF
“storage-driver”: “overlay”,
“insecure-registries”: [ “192.168.31.140:5000″,”192.168.100.222:5000”]
docker info
df -h
方法三:使用vagrant启动多台coreOS
步骤
cp user-data.sample user-data
curl https://discovery.etcd.io/new?size=3
#add at below etcd2: discovery: https://discovery.etcd.io/a078d2a6b509d8026e20d6ea53e52295
cp config.rb.sample config.rb
修改IP:
vi /var/lib/coreos-install/user_data #即clould-config配置 ,重启后不会复原
查看配置: ssh core@coreb1 ‘sudo cat /var/lib/coreos-install/user_data’
修改配置:
ssh core@coreb1 “sudo sed ‘s/hostname: .*/hostname: coreb1/g’ /var/lib/coreos-install/user_data”
ssh core@coreb1 “sudo sed ‘s#Address=.*#Address=192.168.31.24/24#g’ /var/lib/coreos-install/user_data”
参考:
安装:
https://coreos.com/os/docs/latest/installing-to-disk.html
https://coreos.com/os/docs/latest/cloud-config.html
ct 工具
https://github.com/coreos/container-linux-config-transpiler/releases
marchbox网络安装
https://coreos.com/matchbox/docs/latest/matchbox.html
cloud-config: 即安装后的/var/lib/coreos-install/user_data
加网卡
在/var/lib/coreos-install/user_data加
Address=192.168.122.101/24
sudo systemctl restart systemd-networkd
coreos上安装k8s1.9:
前言:
上篇,我们装好了最新版的coreos, 今天来看看怎么在coreOS上安装k8s 1.9
实际:(网络原因需要手动下)
安装:(master和node都需要)
tar -C /opt/cni/bin -xzf cni-plugins-amd64-v0.6.0.tgz
tar zxvf kubernetes-server-linux-amd64.tar.gz
cd /opt/bin; cp /home/core/kubernetes/server/bin/{kubeadm,kubelet,kubectl} .
chmod +x {kubeadm,kubelet,kubectl}
mkdir -p /etc/systemd/system/kubelet.service.d
systemctl enable kubelet && systemctl start kubelet
export PATH=$PATH:/opt/bin;
#master上执行 :
./kubeadm init –kubernetes-version=v1.9.0 –pod-network-cidr=10.244.0.0/16 –apiserver-advertise-address=0.0.0.0 –apiserver-cert-extra-sans 192.168.31.21
#配置kubectl
echo “export KUBECONFIG=/etc/kubernetes/admin.conf” >> ~/.bash_profile
#node添加 :
kubeadm join –token 3a072a.d05a2aef1c9d621f 192.168.31.21:6443 –discovery-token-ca-cert-hash sha256:69bfd9605e565d6d54b77cc1ff78e34b0f528c5475254f61df8cc11250e1b885
#网络
kubectl create -f kube-flannel.yml
#注 :coreos的/usr 目录只读,允许core用户登陆,不允许root远程登陆,安装时注意用sudo执行,必要时切换用户
# dashboard, auth
kubectl get pod –all-namespaces
kubectl create -f kubernetes-dashboard.yaml
echo ‘admin,admin,2’ > /etc/kubernetes/pki/basic_auth_file
sed -i.ori ‘/authorization-mode=Node,RBAC/a \ – –basic_auth_file=/etc/kubernetes/pki/basic_auth_file’ /etc/kubernetes/manifests/kube-apiserver.yaml
grep ‘auth’ /etc/kubernetes/manifests/kube-apiserver.yaml
kubectl create clusterrolebinding \
login-on-dashboard-with-cluster-admin \
–clusterrole=cluster-admin –user=admin
kubectl get clusterrolebinding/login-on-dashboard-with-cluster-admin -o yaml
# test
curl –insecure https://kube-node2:6443 -basic -u admin:admin
#curl –insecure https://10.104.204.144:443
#firefox: https://192.168.100.62:32666
calico(把flannel网络换成calico)
步骤
#etcd :
#多masterHA集群时 ,修改etcd为deployment, replicas =1 或者改到集群的etcd
#修改IP :
sed -i ‘s#192.168.0.0#10.244.0.0#g’ calico.yaml
#安装calico :
kubectl apply -f calico.yaml
#删除flannel :
kubectl delete -f kube-flannel.yml
问题: 下不到镜相,只好用阿里云转一下,master上4个全要下,node上只要node/cni
docker pull registry.cn-zhangjiakou.aliyuncs.com/yanghaitao/myhub:3.2.3-1
docker pull registry.cn-zhangjiakou.aliyuncs.com/yanghaitao/myhub:3.2.3-2
docker pull registry.cn-zhangjiakou.aliyuncs.com/yanghaitao/myhub:3.2.3-3
docker pull registry.cn-zhangjiakou.aliyuncs.com/yanghaitao/myhub:3.2.3-4
docker tag registry.cn-zhangjiakou.aliyuncs.com/yanghaitao/myhub:3.2.3-1 quay.io/calico/kube-controllers:v3.2.3
docker tag registry.cn-zhangjiakou.aliyuncs.com/yanghaitao/myhub:3.2.3-2 quay.io/calico/cni:v3.2.3
docker tag registry.cn-zhangjiakou.aliyuncs.com/yanghaitao/myhub:3.2.3-3 quay.io/calico/node:v3.2.3
docker tag registry.cn-zhangjiakou.aliyuncs.com/yanghaitao/myhub:3.2.3-4 quay.io/coreos/etcd:v3.3.9
问题2:连接不到bgp或POD启动不启来,原因是CNI网络没有正常启动
k8s 1.12 on coreos
下载:
1.12.1相关TAR包的方法:
docker pull mirrorgooglecontainers/kube-apiserver-amd64:v1.12.1
CRI:这个包感觉可有可无,因为默认就是使用docker
文件列表
scp 到各server
scp -r coreos-k8s core@coreb1:.
scp -r coreos-k8s core@coreb2:.
分别登陆master和node: ssh core@coreb1 ssh core@coreb2
mkdir -p /opt/{bin,cni/bin}
tar -C /opt/cni/bin -xzf cni-plugins-amd64-v0.6.0.tgz
cd /opt/bin; cp /home/core/coreos-k8s/{kubeadm,kubelet,kubectl} .
chmod +x {kubeadm,kubelet,kubectl}
mkdir -p /etc/systemd/system/kubelet.service.d
systemctl enable kubelet && systemctl start kubelet
master: kubeadm init
export PATH=$PATH:/opt/bin;
kubeadm init –kubernetes-version=v1.12.1 –pod-network-cidr=10.244.0.0/16 –apiserver-advertise-address=0.0.0.0 –apiserver-cert-extra-sans 192.168.31.24
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
#—dashboard 1.10—
kubectl apply -f ./kubernetes-dashboard.yaml
kubectl apply -f dashboard-adminuser.yaml
kubectl apply -f dashboard-rolebonding.yaml
node:
export PATH=$PATH:/opt/bin;
kubeadm join 192.168.31.24:6443 –token vls547.fd01ne3ixp6j5to0 –discovery-token-ca-cert-hash sha256:abc3e2c072535ced4dadc8b1408f386d680c59986118458541fbb261f9f34062 # 来自 kubeadm init 的输出
fabric自动安装k8s on coreos
前言
本篇说一说使用fabric autoinstall k8s on coreOS, 为何不用ansible? 原因是ansible需要python支持,而coreos上没有python;
版本:k8s 1.12.1; coreOS1855;fabric 1.14
更新说明:
配置文件由hosts改为CONFIG, 可配置是否安装helm和ingress;
dashboard1.10版本,登录token记录在log文件内;
coreos-k8s.tgz已更新,加入helm/ingress的内容;
安装基础组件时间大约5分钟,带helm/ingress大约10分钟;
相关文件
各文件说明:
CONFIG #配置master&node的IP, 可配置addon组件是否安装,true表示安装,node结点IP可配多个,用逗号分隔
fab_inst.py # fabric的执行脚本
coreos-k8s.tgz # 包含k8s 1.12.1基础组件和image, 大小388MB
k8s-addon.tgz # addon组件包,helm/ingress/efk/prometheus,1.1GB
步骤:
2. clone两台以上coreos虚拟机并配置好IP,安装方法见前篇《基础架构八》;
3. 配置CONFIG
master&node的IP, 单个master, 多个NODE间以逗号分隔;
验证:
大约5-10分钟安装完成,cat log, 使用token登陆dashboard,验证安装的正确性
如使用clusterIP登陆,需要加路由:route add 10.0.0.0 mask 255.0.0.0 192.168.31.24 #某结点IP
[集群自动安装] 三分钟 READY for k8s-HA-cluster
问题:
1.clone脚本问题
clone脚本前先修改CONFIG和basekvm里的IP与配置相符,否则不能正常配置
2.镜相问题
xml换机器后CPU兼容问题:virt-manager上选复制本机CPU配置
xml中的网卡接到br0网桥需要根据实际调整,新环境是br1
添加了一块网卡,连接到default virbr0,不过k8s用不到
5. coreos镜相配置调整
更新策略文件是 more /etc/coreos/update.conf
加网卡2配置IP:more /var/lib/coreos-install/user_data
Address=192.168.122.101/24
6. coreos update手动:
update_engine_client -check_for_update #检查
journal -xe # 日志里可看到是否有更新
update_engine_client -update # 更新
基本结构:
前端:keepalived’s VIP+haproxy’s 8443 to real IP’s 6443
clone KVM并配置IP的脚本
cloud-config文件的写法(user_data)
验证安装:
安装完毕会显示dashboard 的nodeport端口与登陆token
使用firefox 登录dashboard:(任一结点IP的nodeport端口)
相关步骤分解说明:
haproxy
haproxy.cfg :由haproxy_conf.sh根据CONFIG自动生成,不必理睬
etcd
状态检查:etcdctl –key-file ssl/etcd-key.pem –cert-file ssl/etcd.pem –ca-file ssl/ca.pem –endpoints=https://192.168.253.31:2379 cluster-health
installha.sh p5:准备好ha.tgz,包括config/haproxy/keepalived/etcd,并启动集群三件套haproxy/keepalived/etcd
master1:
kubeadm init –config kubeadm-config.yaml
init后,三running三pending状态正常:
master2:
master2/3: kubeadm init –config kubeadm-config.yaml
Q&A:
问题一:calico 网络问题:
像单master安装时一样apply后,发现calico node一直不正常,重启,coredns也是;查calico-etcd有三个,member list只有一个,官网只有单master的介绍,etcd.yaml是个daemonset, 会在每个master上启一个etcd pod, 可导致calico etcd的服务不正常, 连锁反应是calico node/coredns/dashboard等都不正常;
解决方法一:
把calico etcd的daemonset 改为deployment, replicas 设为1
方法二:
把etcd的指向到kubernetes集群的etcd上去,configmap里配置好ca验证
方法三:
用打标签的方法让calico etcd只运行在指定的master上,临时解决方法,没法高可用;
改etcd.yaml, nodeselector, =master1
reboot所有结点或删除重启calico相关pods
问题二:无外网情况下,kubeadm init 后,无coredns/kube-proxy的pods出现:
问题三:k8s集群kubeadm的官方介绍方法有两种:
方法一是使用k8s自身的etcd,安装起来速度慢,常出现莫名的故障;
方法二即自建外部etcd的方法,速度快且稳定,install.sh采用此方法;
k8s前端ingress
前言:
上一篇,我们把python django框架编写的学籍管理小项目,通过gitlab-runner的步署到了kubernetes里,名为student的服务,此篇我们看一看如何接到前端的nginx上,方便用户访问;
kubernetes前端的三种方式:
serviceIP方式:
加路由:
route add 10.0.0.0 mask 255.0.0.0 192.168.31.20 (windows)
route add -net 10.0.0.0/8 gw 192.168.31.20 #(LINUX) 192.168.31.20是k8s某个结点的IP
kubectl get svc –all-namespaces # 记录services的cluster IP与端口
nodePort方式:
kubectl get svc –all-namespaces # 记录services的NodePort端口
在前端nginx配置中加入相应的转发配置即可, IP为任一node的IP
ingress方式:
nginx装在k8s内,作为一个services有一个clusterIP,和nodePort
ingress安装:
kubectl apply -f mandatory.yaml
或者vi mandatory.yaml修改image行,再kubectl apply一遍
ls -l *yaml
configmap.yaml mandatory.yaml namespace.yaml rbac.yaml with-rbac.yaml
mandatory包含了其它四个yaml内容
kubectl apply -f provider/baremetal/service-nodeport.yaml # 启动service
使用示例 :
http后端添加:
# 创建 ingress
kubectl create -f ingress-student.yaml
# 查看 ingress
kubectl get ingress –all-namespaces
设定DNS指定任一node的IP即可,用nodePort的形式测试
https后端添加:
# vi with-rbac.yaml 增加 – –enable-ssl-passthrough
kubectl apply -f with-rbac.yaml
vim ingress-dashboard.yaml
# 创建 ingress
kubectl create -f ingress-dashboard.yaml
# 查看 ingress
kubectl get ingress –all-namespaces
把DNS改到外面的nginx IP上,配置外部nginx转发到ingress
后端 http协议的student服务转发没有问题,
可以转到student的clusterIP和nodePort, 正常访问
也可以转到ingress的clusterIP和nodePort上,都可以正常访问;
后端https协议的dashboard服务不能转发到ingress的nodePort和clusterIP上,但可以转到dashboard的clusterIP或nodePort上;
显示404,同样用结点IP+nodePort访问也会报404,clusterIP一样404;
初步结论是被ingress定义的https服务,被绑定了域名,只能用域名访问;
日志 efk (fluentd EK)
#Question: error for fluent-es: no plugin concat
#Answer:
docker run -it –name fluent k8s.gcr.io/fluentd-elasticsearch:v2.2.0 bash
gem sources –add https://gems.ruby-china.com/ –remove https://rubygems.org/
gem install fluent-plugin-concat
docker commit fluent k8s.gcr.io/fluentd-elasticsearch:v2.2.1
docker save k8s.gcr.io/fluentd-elasticsearch:v2.2.1 >fluent-es-v2.2.1.tar
scp fluent-es-v2.2.1.tar core@coreb1:.
docker load <./fluent-es-v2.2.1.tar
kubectl set image daemonset fluentd-es-v2.2.1 fluentd-es=k8s.gcr.io/fluentd-elasticsearch:v2.2.1 -n kube-system
#May be cause low performance of cluster
#Question: kibana’s.yaml SERVER_BASEPATH
#Question: fluentd-es’s yaml nodeSelector
or lable node
istio 微服务治理
安装:
cp istio/istioctl /opt/bin/
kubectl apply -f istio/install/kubernetes/helm/istio/templates/crds.yaml
helm template istio/install/kubernetes/helm/istio –name istio –namespace istio-system –set sidecarInjectorWebhook.enabled=true –set ingress.service.type=NodePort –set gateways.istio-ingressgateway.type=NodePort –set gateways.istio-egressgateway.type=NodePort –set tracing.enabled=true –set servicegraph.enabled=true –set prometheus.enabled=true –set tracing.jaeger.enabled=true –set grafana.enabled=true > istio.yaml
kubectl create namespace istio-system
kubectl create -f istio.yaml
自动注入:
kubectl label namespace default istio-injection=enabled
kubectl get namespace -L istio-injection
规则配置
Istio 提供了一个简单的配置模型,用来控制 API 调用以及应用部署内多个服务之间的四层通信。运维人员可以使用这个模型来配置服务级别的属性,这些属性可以是断路器、超时、重试,以及一些普通的持续发布任务,例如金丝雀发布、A/B 测试、使用百分比对流量进行控制,从而完成应用的逐步发布等。
Istio 中包含有四种流量管理配置资源,分别是 VirtualService(虚拟服务)、DestinationRule(重点规则)、ServiceEntry(服务入口) 以及 Gateway(网关)。下面会讲一下这几个资源的一些重点。在网络参考中可以获得更多这方面的信息。
VirtualService 在 Istio 服务网格中定义路由规则,控制路由如何路由到服务上。
DestinationRule 是 VirtualService 路由生效后,配置应用与请求的策略集
ServiceEntry 是通常用于在 Istio 服务网格之外启用对服务的请求。
Gateway 为 HTTP/TCP 流量配置负载均衡器,最常见的是在网格的边缘的操作,以启用应用程序的入口流量。
k8s集群故障解决思路与方法
熟悉架构
了解各组件的作用
组件: etcd/kube-api/kube-controller/kube-scheduler/kube-proxy/kube-dns/kubelet/calico
熟悉常用命令:当集群出现问题,我们会用一些命令或dashboard观察和获取到错误信息,有时dashboard也无法使用
基础网络 :
iptables/nslookup/curl/tracerroute/route/ping/tcpdump/ss -nltp/ip a/等
etcd集群状态:
etcdctl –cert-file /etc/etcd/ssl/etcd.pem –key-file /etc/etcd/ssl/etcd-key.pem –ca-file /etc/etcd/ssl/ca.pem –endpoints https://$CP1_IP:2379 cluster-health
k8s服务与PODS状态:
kubectl get pods –all-namespaces -o wide
kubectl get svc –all-namespaces -o wide
kubectl describe pods <PODNAME> -n <NAMESPACE>
容器状态与日志:
docker logs <ContainerID>
排查思路与顺序
基础网络–>etcd集群->api->calico网络->cubeDNS->基础组件->其它SVC与PODS
基础网络的故障,会导致etcd集群故障,etcd又会导致kube-apiserver故障,apiserver故障导致整个集群无法访问;
故障现象五花八门,同一种现象解决的办法不一定相同,不同的版本解决方法不一定相同;
在保证集群基础组件运行正常的前提下,容器的日志往往比较准确的反应问题的实质
理论+经验+baidu/google/bing+细心
常见故障例
安装时下载镜相类问题
问题: 下不到calico镜相,可以用阿里云转一下,master上4个全要下,node上只要node/cni
docker pull registry.cn-zhangjiakou.aliyuncs.com/yanghaitao/myhub:3.2.3-1
docker pull registry.cn-zhangjiakou.aliyuncs.com/yanghaitao/myhub:3.2.3-2
docker pull registry.cn-zhangjiakou.aliyuncs.com/yanghaitao/myhub:3.2.3-3
docker pull registry.cn-zhangjiakou.aliyuncs.com/yanghaitao/myhub:3.2.3-4
docker tag registry.cn-zhangjiakou.aliyuncs.com/yanghaitao/myhub:3.2.3-1 quay.io/calico/kube-controllers:v3.2.3
docker tag registry.cn-zhangjiakou.aliyuncs.com/yanghaitao/myhub:3.2.3-2 quay.io/calico/cni:v3.2.3
docker tag registry.cn-zhangjiakou.aliyuncs.com/yanghaitao/myhub:3.2.3-3 quay.io/calico/node:v3.2.3
docker tag registry.cn-zhangjiakou.aliyuncs.com/yanghaitao/myhub:3.2.3-4 quay.io/coreos/etcd:v3.3.9
权限类问题
kubectl 使用$HOME/.kube/config(即/etc/kubernetes/admin.conf)的配置来访问集群
网络类问题
问题一:calico 网络问题:
现象:像单master安装时一样apply后,发现calico node一直不正常,重启,coredns也是;
查询原因:查calico-etcd有三个,member list只有一个,官网只有单master的介绍,etcd.yaml是个daemonset, 会在每个master上启一个etcd pod, 可导致calico etcd的服务不正常, 连锁反应是calico node/coredns/dashboard等都不正常;
解决方法一:
把calico etcd的daemonset 改为deployment, replicas 设为1
方法二:
把etcd的指向到kubernetes集群的etcd上去,configmap里配置好ca验证
方法三:
用打标签的方法让calico etcd只运行在指定的master上,临时解决方法,没法高可用;
改etcd.yaml, nodeselector, =master1
reboot所有结点或删除重启calico相关pods
问题二:kubeadm init 后,无coredns/kube-proxy的pods出现:
其它问题:
问题三:k8s集群kubeadm的官方介绍方法有两种:
方法一是使用k8s自身的etcd,安装起来速度慢,常出现莫名的故障;
方法二即自建外部etcd的方法,速度快且稳定,install.sh采用此方法;
helm包管理
前言:
helm是k8s的包管理器,本篇,我们将前期制作的student项目,使用helm来打包、安装、升级、回滚等操作,演练helm的安装和使用
准备
完成前期 《基础架构五 k8s与gitlab-ci》
概念简介
Helm
Helm 是一个命令行下的客户端工具。主要用于 Kubernetes 应用程序 Chart 的创建、打包、发布以及创建和管理本地和远程的 Chart 仓库。
Tiller
Tiller 是 Helm 的服务端,部署在 Kubernetes 集群中。Tiller 用于接收 Helm 的请求,并根据 Chart 生成 Kubernetes 的部署文件( Helm 称为 Release ),然后提交给 Kubernetes 创建应用。Tiller 还提供了 Release 的升级、删除、回滚等一系列功能。
Chart
Helm 的软件包,采用 TAR 格式。类似于 APT 的 DEB 包或者 YUM 的 RPM 包,其包含了一组定义 Kubernetes 资源相关的 YAML 文件。
Repoistory
Helm 的软件仓库,Repository 本质上是一个 Web 服务器,该服务器保存了一系列的 Chart 软件包以供用户下载,并且提供了一个该 Repository 的 Chart 包的清单文件以供查询。Helm 可以同时管理多个不同的 Repository。
Release
使用 helm install 命令在 Kubernetes 集群中部署的 Chart 称为 Release
step1:安装
下载
#解包并将二进制文件helm拷贝到/usr/local/bin目录下
tar -zxvf helm-v2.6.1-linux-amd64.tgz && cp linux-amd64/helm /usr/local/bin/helm
helm init –upgrade -i registry.cn-hangzhou.aliyuncs.com/google_containers/tiller:v2.11.0 –stable-repo-url https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
权限:
kubectl create serviceaccount –namespace kube-system tiller
kubectl create clusterrolebinding tiller-cluster-rule –clusterrole=cluster-admin –serviceaccount=kube-system:tiller
kubectl patch deploy –namespace kube-system tiller-deploy -p ‘{“spec”:{“template”:{“spec”:{“serviceAccount”:”tiller”}}}}’
删除Tiller: (当需要重新步署helm时)
$helm reset 或 $helm reset -f(强制删除k8s集群上的pod.)
当要移除helm init创建的目录等数据时,执行helm reset –remove-helm-home
step2:部署release
helm install –name my-release –set Persistence.StorageClass=slow stable/jenkins (不加–set参数会出现SchedulerPredicates failed due to PersistentVolumeClaim is not bound: “my-release-jenkins”, which is unexpected问题)
使用第三方chat库
添加fabric8库
$helm repo add fabric8 https://fabric8.io/helm
搜索fabric8提供的工具(主要就是fabric8-platform工具包,包含了CI,CD的全套工具)
常用命令
查看状态 $helm status my-release 或通过$helm list -a 查看全部的release
更新版本 $helm upgrade my-release -f mysql/values.yaml –set resources.requests.memory=1024Mi my-release
版本回滚 $helm rollback mysql 1 //1为版本号,可以添加 –debug打印调试信息
查看release的版本信息 $helm hist my-release
删除release $helm delete my-release ,可以通过$helm ls -a myrelease来确认是否删除,还可以通过回滚来恢复已经删除的release,如果希望彻底删除的话$helm delete –purge my-release
部署有多种方式:
指定chart: helm install stable/mariadb
指定打包的chart: helm install ./nginx-1.2.3.tgz
指定打包目录: helm install ./nginx
指定chart包URL: helm install https://example.com/charts/nginx-1.2.3.tgz
如果要覆盖chart中的默认值,
先导出values:helm inspect stable/mysql >myvalues.yml
通过指定配置文件方式 helm install -f myvalues.yaml ./redis
或通过–set key=value方式 helm install –set name=prod ./redis
例:helm install -n mysql -f myvalues.yaml –set resources.requests.memory=512Mi mysql
step3:编写chart项目
helm create student
修改配置默认值,将例子里的nginx换为student相关的内容:
测试:
helm install –dry-run –debug student
dashboard上查看,出错:
grep -r liveness student #找到liveness的配置在templates /deployment.yaml里
vim student/templates/deployment.yaml
更新:
helm upgrade sappy-wildebeest student
删除
helm delete sappy-wildebeest
重新安装,加个名字:
helm install student -n my
升级
helm upgrade –set image.tag=v20181014-142439 my student # tag见《基础架构五》,我用日期时间做为tag
查看是否修改:kubectl get deployment my-student -o wide
生成helm仓库index
mv student-0.1.0.tgz myrepo/
ls myrepo/
index.yaml student-0.1.0.tgz
增加myrepo
helm install myrepo/student -n my2 –dry-run –debug # 用myrepo测试安装
helm repo update # 当有新chart增加时
helm应用配置
k8s内应用使用helm配置
mysql
helm inspect values stable/mysql >mysqlvalues.yaml
vi mysqlvalues.yaml # 加 clusterIP: 10.96.100.1
tar zxvf ~/.helm/cache/archive/mysql-0.3.5.tgz
cd mysql; vi templates/svc.yaml # 加 :clusterIP: {{ .Values.service.clusterIP }}
tar zcvf mysql5.0.7.tgz mysql
helm install –values=mysqlvalues.yaml ./mysql5.0.7.tgz -n mysql
search
修改clusterIP: 10.96.100.3,port 8103
download
修改clusterIP: 10.96.100.4,port 80
k8s外部基础应用
NFS存储(用docker-compose配置,不在k8s里),考虑用ceph或HDFS代替
mkdir -P /export/nfs/{mysql,config,download}
#cat cmp_nfs/docker-compose.yml
image: 192.168.254.211:5000/itsthenetwork/nfs-server-alpine
# Required to load kernel NFS module
– SHARED_DIRECTORY=/nfsshare
– ./exports.tmpl:/etc/confd/templates/exports.tmpl
前端 nginx/haproxy/keepalived
ceph
概念
Ceph:
开源的分布式存储系统。主要分为对象存储、块设备存储、文件系统服务。Ceph核心组件包括:Ceph OSDs、Monitors、Managers、MDSs。Ceph存储集群至少需要一个Ceph Monitor,Ceph Manager和Ceph OSD(对象存储守护进程)。运行Ceph Filesystem客户端时也需要Ceph元数据服务器( Metadata Server )。
Monitors:
Ceph Monitor(ceph-mon) 维护着展示集群状态的各种图表,包括监视器图、 OSD 图、归置组( PG )图、和 CRUSH 图。 Ceph 保存着发生在Monitors 、 OSD 和 PG上的每一次状态变更的历史信息(称为 epoch )。监视器还负责管理守护进程和客户端之间的身份验证。冗余和高可用性通常至少需要三个监视器。
OSDs:
Ceph OSD 守护进程(ceph-osd)的功能是存储数据,处理数据的复制、恢复、回填、再均衡,并通过检查其他 OSD 守护进程的心跳来向 Ceph Monitors 提供一些监控信息。冗余和高可用性通常至少需要3个Ceph OSD。当 Ceph 存储集群设定为有2个副本时,至少需要2个 OSD 守护进程,集群才能达到 active+clean 状态( Ceph 默认有3个副本,但你可以调整副本数)。
Ceph OSD:Ceph Object Storage Device 主要功能包括:存储数据,副本数据处理,数据恢复,数据回补,平衡数据分布,并将数据相关的一些儿监控信息提供给至少2个Ceph OSD,才能有效保存两份数据.
OSD节点安装有两种方案,一种是在节点上挂载全新的硬盘设备,第二种是将已安装好的系统的指定目录作为OSD。
是负责物理存储的进程,一般配置成和磁盘一一对应,一块磁盘启动一个OSD进程;
Managers:
Ceph Manager守护进程(ceph-mgr)负责跟踪运行时指标和Ceph集群的当前状态,包括存储利用率,当前性能指标和系统负载。Ceph Manager守护进程还托管基于python的插件来管理和公开Ceph集群信息,包括基于Web的Ceph Manager Dashboard和 REST API。高可用性通常至少需要两个管理器。
MDSs:
Ceph 元数据服务器( MDS )为 Ceph 文件系统存储元数据(也就是说,Ceph 块设备和 Ceph 对象存储不使用MDS )。元数据服务器使得 POSIX 文件系统的用户们,可以在不对 Ceph 存储集群造成负担的前提下,执行诸如 ls、find 等基本命令。
RGW
RGW为Rados Gateway的缩写,ceph通过RGW为互联网云服务提供商提供对象存储服务。RGW在librados之上向应用提供访问ceph集群的RestAPI, 支持Amazon S3和openstack swift两种接口。对RGW最直接的理解就是一个协议转换层,把从上层应用符合S3或Swift协议的请求转换成rados的请求, 将数据保存在rados集群中。
rbd
RBD : Ceph’s RADOS Block Devices , Ceph block devices are thin-provisioned, resizable and store data striped over multiple OSDs in a Ceph cluster.
上面是官方的阐述,简单的说就是:
RBD 就是 Ceph 里的块设备,一个 4T 的块设备的功能和一个 4T 的 SATA 类似,挂载的 RBD 就可以当磁盘用。
data striped:这个块在 Ceph里面是被切割成若干小块来保存,不然 1PB 的块怎么存的下。
thin-provisioned:精简置备,我认为的很容易被人误解的 RBD 的一个属性,1TB 的集群是能创建无数 1PB 的块的。说白了就是,块的大小和在 Ceph 中实际占用的大小是没有关系的,甚至,刚创建出来的块是不占空间的,今后用多大空间,才会在 Ceph 中占用多大空间。打个比方就是,你有一个 32G 的 U盘,存了一个2G的电影,那么 RBD 大小就类似于 32G,而 2G 就相当于在 Ceph 中占用的空间。
数据存储
Pool
是存储对象的逻辑分区,它规定了数据冗余的类型和对应的副本分布策略;
支持两种类型:副本(replicated)和 纠删码( Erasure Code);目前我们公司内部使用的Pool都是副本类型(3副本);
当前常见池使用类型有三种
CephFS uses the application name cephfs
RBD uses the application name rbd
RGW uses the application name rgw
PG( placement group)
是一个放置策略组,它是对象的集合,该集合里的所有对象都具有相同的放置策略;
简单点说就是相同PG内的对象都会放到相同的硬盘上;
PG是 ceph的核心概念, 服务端数据均衡和恢复的最小粒度就是PG;
OSD
是负责物理存储的进程,一般配置成和磁盘一一对应,一块磁盘启动一个OSD进程;
逻辑存储结构:下面这张图形象的描绘了POOL/PG/OBJECT/OSD之间的关系:
一个PG里包含一堆对象;一个对象只能属于一个PG;
PG有主从之分,一个PG分布在不同的OSD上(针对三副本类型)
物理存储结构:Crushmap/桶/隔离故障域/多root
snapshot与mirror
snapshot针对rgw/cephfs类型的pool
总结
上线 Ceph 前,先规划未来一年的预期使用量,为每个 pool 一次性设置 PG之后不再变更; 使用crushmap 设置故障域隔离,将磁盘故障后带来的数据平衡控制在一个小的范围之内。接口方面推荐只使用Ceph 提供的RGW 接口,不使用 librados原生接口。做好这些, 你的 Ceph 用起来会省心很多。
安装
前言
本篇来看看一个三结点的CEPH,在CoreOS上的自动化安装
版本:ceph mimic 13.2.2 CoreOS 1855.4
安装(以三结点为例)
CLONE三台CoreOS KVM, 各添加一块20G硬盘
kvm define coreosbase2.xml
验证
安装后会生成svc-ceph.html, 包含dashboard/grafana/prometheus等的页面链接,依次打开验证
修改grafana的datasource prometheus IP为node1的IP
dashboard
docker exec mgr ceph dashboard create-self-signed-cert
docker exec mgr ceph mgr module enable dashboard
docker exec mgr ceph dashboard set-login-credentials admin admin
docker exec mgr ceph config set mgr mgr/dashboard/server_addr 192.168.31.15
docker exec mgr ceph config set mgr mgr/dashboard/server_port 7000
docker exec mon ceph mgr dump
docker exec mgr ceph config set mgr mgr/dashboard/ssl false
docker exec mgr ceph mgr module disable dashboard
docker exec mgr ceph mgr module enable dashboard
dashboard-rgw
source ./ceph/CONFIG.ceph
docker exec mon radosgw-admin user create –uid=123 –display-name=rgw_adm –system
docker exec mon radosgw-admin user info –uid=123
a=(`docker exec mon radosgw-admin user info –uid=123|grep -Po “access_key\”:\K.*|secret_key\”:\K.*”|sed -e ‘s/”//g’ -e ‘s/,//’|xargs`)
# “access_key”: “V4J9G5OGVYCJWIRIGSL1”,
# “secret_key”: “zt6nLe7j4lukAXXm5rSqgAIZxZN6I6Ie6cC3SOaP”
#设定
docker exec mon ceph dashboard set-rgw-api-access-key ${a[0]}
docker exec mon ceph dashboard set-rgw-api-secret-key ${a[1]}
docker exec mon ceph dashboard set-rgw-api-host $NODE3_IP
docker exec mon ceph dashboard set-rgw-api-port 7480
# docker exec mon ceph set-rgw-api-scheme https
docker exec mon ceph dashboard set-rgw-api-user-id 123
# 查
docker exec mon ceph dashboard get-rgw-api-scheme
docker exec mon ceph dashboard get-rgw-api-host
docker exec mon ceph dashboard get-rgw-api-port
docker exec mon ceph dashboard get-rgw-api-user-id
docker exec mon ceph dashboard get-enable-browsable-api
重启dashboard
docker exec mgr ceph mgr module disable dashboard
docker exec mgr ceph mgr module enable dashboard
prometheus
ceph mgr module enable prometheus
docker exec mgr ceph mgr services
rgw s3
Ceph RGW – Rados网关:提供S3与Swift相容的API,存储数据至对象存储。
docker run -d –net=ceph-net -v ${DIR}/lib/ceph/:/var/lib/ceph/ -v ${DIR}/ceph:/etc/ceph -p 8080:8080 –name=rgw1 ceph/daemon rgw
curl -H “Content-Type: application/json” “http://127.0.0.1:8080”
wget “https://gist.githubusercontent.com/kairen/e0dec164fa6664f40784f303076233a5/raw/33add5a18cb7d6f18531d8d481562d017557747c/s3client”
docker exec -ti rgw1 radosgw-admin user create –uid=”test” –display-name=”I’m Test account” –email=”test@example.com”
./s3client upload files s3key.sh /
cephfs挂载
source ./ceph/CONFIG.ceph
mount -t ceph $NODE1_IP:6789,$NODE2_IP:6789,$NODE3_IP:6789:/ /mnt/mycephfs -o name=admin,secret=`ssh $NODE1_IP docker exec mon ceph auth get-key client.admin`
#注 :当有多网卡时,6789可能会挂在eth0的IP上
卡住:
fuser -m -k -i /mnt/mycephfs
k8s-cephfs
一,获取admin的密文
docker exec mon ceph-authtool –print-key /etc/ceph/ceph.client.admin.keyring
二,将之用base64编码
echo “sdfdsadfasdfasdf=” | base64
三,生成并应用k8s secret文件
kubectl apply -f ceph-secret
查询命令
C.查看 mon 相关信息
# ceph mon stat ##查看 mon 状态信息
e1: 3 mons at {ceph01=192.168.100.116:6789/0,ceph02=192.168.100.117:6789/0,ceph03=192.168.100.118:6789/0}, election epoch 10, leader 0 ceph01, quorum 0,1,2 ceph01,ceph02,ceph03
# ceph quorum_status ##查看 mon 的选举状态
# ceph mon dump ##查看 mon 映射信息
fsid afd8b41f-f9fa-41da-85dc-e68a1612eba9
last_changed 2018-07-27 21:35:33.405099
created 2018-07-27 21:35:33.405099
0: 192.168.100.116:6789/0 mon.ceph01
1: 192.168.100.117:6789/0 mon.ceph02
2: 192.168.100.118:6789/0 mon.ceph03
# ceph daemon mon.ceph01 mon_status ##查看 mon 详细状态
D.查看 osd 相关信息
# ceph osd stat ##查看 osd 运行状态
# ceph osd dump ##查看 osd 映射信息
# ceph osd df ##详细列出集群每块磁盘的使用情况
ID CLASS WEIGHT REWEIGHT SIZE USE AVAIL %USE VAR PGS
0 hdd 0.01949 1.00000 20 GiB 1.0 GiB 19 GiB 5.01 1.00 0
1 hdd 0.01949 1.00000 20 GiB 1.0 GiB 19 GiB 5.01 1.00 0
2 hdd 0.01949 1.00000 20 GiB 1.0 GiB 19 GiB 5.01 1.00 0
TOTAL 60 GiB 3.0 GiB 57 GiB 5.01
MIN/MAX VAR: 1.00/1.00 STDDEV: 0
# ceph osd tree ##查看 osd 目录树
# ceph osd getmaxosd ##查看最大 osd 的个数
E.查看 PG 信息
# ceph pg dump ##查看 PG 组的映射信息
# ceph pg stat ##查看 PG 状态
0 pgs: ; 0 B data, 3.0 GiB used, 57 GiB / 60 GiB avail
# ceph pg dump –format plain ##显示集群中的所有的 PG 统计,可用格式有纯文本plain(默认)和json
HDFS
CICD
概念:
CICD (Continue Integrated Continue Deployment)
gitlab-runner (gitlab的CICD工具,简单的说:作用是实时检查代码仓库的代码更新,执行动作由项目根目录的.gitlab-ci.yml文件定义,并将CICD动作的日志传回gitlab显示给用户)
使用过程为安装gitlab-runner、注册runner即可
1. 安装runner可以为在各系统平台上安装(linux、macos、windows、freebsd等)、docker安装、以及在kubernetes上安装等方式
2. 注册runner,注册命令会指定executor、docker-image、url、registration-token、description、tag-list、run-untagged、locked等。
其中,docker-image是使用docker或kubernetes方式执行build时的默认镜像,url为gitlab地址,registration-token为项目的注册token等
什么是executor
GitLab Runner实现了许多executor,可以在不同场景下使用指定的执行器来运行你的builds。若不确定要选择哪一个executor,可以参考 I am not sure 部分。可以查看 compatibility chart 部分了解每个executor所支持的特性。
SSH Executor
SSH executor只是为了完整,是所有executor中支持最少的. ssh executor可以使GitLab Runner连接外部服务并在外部运行builds。
Shell Executor
Shell 是最易配置的executor。builds所需的所有依赖都需要事先在runner所在服务器上手动安装。
Virtual Machine Executor
我们也提供了两个系统虚拟化选项:VirtualBox、 Parallels。这一类的executor允许你使用已经创建的虚拟机,可以用来clone也可以用来运行builds。由于该executor可以创建Windows, Linux, OSX or FreeBSD虚拟机,并且可以使用GitLab Runner访问虚拟机,在虚拟机上运行builds,因此你想要在不同的操作系统上运行,使用该executor正好可以满足,减少了基础构建所花费的代价。
Docker Executor
Docker可以清理build环境,方便依赖管理(building一个项目需要的所有依赖都可以放进docker image里)。Docker executor可以让你创建一个由services依赖比如说mysql这样的build环境更简单方便。
Docker Machine
Docker Machine 是Docker executor的一个特定版本,支持auto-scaling。工作模式与Docker executor类似,只是由Docker Machine创建本地的build。
kubernetes Executor
Kubernetes executor可以让你使用已有的Kubernetes cluster来运行你的builds。 executor会调用Kubernetes cluster API并且会为每一个GitLab CI job创建一个新的pod(用有build container和services container)
action runner (github的CICD工具)
gitlab私有代码仓库
docker run
–hostname gitlab.yunwei.edu \
-p 1443:443 -p 1180:80 -p 122:22 \
-v /opt/gitlab/config:/etc/gitlab \
-v /opt/gitlab/logs:/var/log/gitlab \
-v /opt/gitlab/data:/var/opt/gitlab \
docker compose.yml
image: ‘gitlab/gitlab-ce:latest’
hostname: ‘gitlab.example.com’
external_url ‘http://gitlab.example.com:9090’
gitlab_rails[‘gitlab_shell_ssh_port’] = 2224
– ‘/srv/gitlab/config:/etc/gitlab’
– ‘/srv/gitlab/logs:/var/log/gitlab’
– ‘/srv/gitlab/data:/var/opt/gitlab’
登陆与配置: gitlab.yunwei.edu
增加user/设置passwd/用户第一次登陆会要求改密码
使用客户端示例
git config –global user.name “Thomas”
git config –global user.email “168447636@qq.com”
git commit -m “add README”
git push -u origin master
mail设置:
vi /etc/gitlab/gitlab.rb
gitlab-runner:
在gitlab项目里
取得 runner token: gwHDYqzVVu6Spyvvc1Nu
安装runner:
linux版 https://docs.gitlab.com/runner/install/linux-manually.html
chmod +x /usr/local/bin/gitlab-runner
useradd –comment ‘GitLab Runner’ –create-home gitlab-runner –shell /bin/bash
gitlab-runner install –user=gitlab-runner –working-directory=/home/gitlab-runnersudo gitlab-runner start
usermod -aG docker gitlab-runner
sudo -u gitlab-runner -H docker info
gitlab-runner install –user=gitlab-runner –working-directory=/home/gitlab-runner
gitlab-CICD实例:
flask
step1 应用环境dockerfile.python
首先,需要一个docker的应用环境:
dockerfile:
https://raw.githubusercontent.com/Thomas-YangHT/python/master/python_gitlab_example/dockerfile.python
nginx配置:
https://raw.githubusercontent.com/Thomas-YangHT/python/master/python_gitlab_example/conf.d/uwsgi.cf
https://raw.githubusercontent.com/Thomas-YangHT/python/master/python_gitlab_example/conf.d/upstream.conf
uwsgi配置:
https://raw.githubusercontent.com/Thomas-YangHT/python/master/python_gitlab_example/testflk.ini
一段示例python程序:(下载后改名为testflk.py)
https://raw.githubusercontent.com/Thomas-YangHT/python/master/python_gitlab_example/testflk.py.hello
step2 编写python程序
一段python-flask-uwsgi程序,完成学生成绩和基本信息的查询:
需要导入mysql数据库,并修改python程序testflk.py中mysql相关的设定:
step3 将写好的.gitlab-ci.yml加到项目根目录
django
前言:
上一篇综合运用了gitlab/docker/python flask/nginx/uwsgi/mysql等工具和我们搭建的DEVOPS环境,完成了学生管理系统的CICD实例,本篇将flask改为django来完成相同的功能,继续熟悉使用我们搭建的CICD环境和django开发的基本方法
文中提到的程序和脚本见:
https://github.com/Thomas-YangHT/python/tree/master/django
步骤:
step1. 在gitlab页面中新建一个项目project
[group]–yunwei下新建[project]–django
step2. 准备django的应用环境
docker运行环境:dockerfile.django
django 1.18版
yum install -y python-django
问题:
django版本:
不同的版本上运行会导致启动失败,由于settings内容不同;
1.18版本来源于openstack-ocata源;
yum install -y python-django
其它应用版本:
nginx -V
nginx version: nginx/1.12.2
模板
改为jiaja2模板,兼容flask做的模板 settings.py
CSRF问题
或者在settings.py里注释掉:settings —> 找到MIDDLEWARE —> 注释掉
php
步骤:
step1. 在gitlab页面中新建一个项目project
[group]–yunwei下新建[project]–php_student
git clone <your_http_url> 克隆到本地
step2. 准备php的应用环境
编写docker运行环境:dockerfile.php.example
创建镜相image:docker-build.sh
运行一个实例container: docker-run.sh
kubernetes
前言
此篇,我们将【基础架构四-app2】中的django项目,配置到kubernetes里,使用k8s来运行runner, 使用kubernetes执行器,来体验k8s里进行CICD的过程
准备
kubernetes环境
后加节点:
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed ‘s/^.* //’
kubeadm join –token aa78f6.8b4cafc8ed26c34f –discovery-token-ca-cert-hash sha256:0fd95a9bc67a7bf0ef42da968a0d55d92e52898ec37c971bd77ee501d845b538 172.16.6.79:6443 –skip-preflight-checks
step1: 手动配置gitlab-runner for kubernetes
增加名空间:
kubectl create namespace gitlab-managed-apps # gitlab里kubernetes一键安装程序时用
kubectl create namespace gitlab
configmap
# 使用dashboard或kubectl apply -f <YAML>执行
# token内容应按后面注册后内容修改,可在生成的config.toml里查到,或在gitlab->项目->cicd->每一个runner编辑里查到
注册
kubectl get pods -n gitlab
kubectl exec -it gitlab-runner-《7f98cbb9dd-7q7pr》 -n gitlab /bin/bash #《》里内容为get pods输出结果
# 查/etc/gitlab-runner/config.toml 验证,回到configmap步骤修改token
step2: 设定权限与.gitlab-ci.yml
权限
kubectl create clusterrolebinding serviceaccounts-gitlab-admin \
–clusterrole=cluster-admin \
–serviceaccount=gitlab:default
# 用于设置gitlab页面里kubernetes的相关设置;以及.gitlab-ci.yml执行时的权限
配置gitlab页面->kubernetes的相关设置
略 # 因install helm时需要下载googlepis的镜相,国内网络问题无法下载,helm用的是2.7版本,暂时忽略不影响本篇实践内容;
step3: k8s中项目的deploy与service更新
student-deploy.json
“imagePullPolicy”: “Always”, # 便于更新
如何自动更新版本
方法一:专用的镜相?含ssh key,以便登陆到master执行kubectl apply命令 # 麻烦,未采用
方法二:在configmap里配置挂载主机的/usr/bin/kubectl和配置/etc/kubenetes/admin.conf,即可执行kubectl
kubectl set image deployment/student student=python:V$version -n default # 加到 .gitlab-ci.yml 最后
回滚到上一版本
kubectl rollout undo deployment/student -n default
扩展副本数量:
kubectl scale deployment/student –replicas=3 -n default
参考
kubernetes的帐号密码与权限:
https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
https://kubernetes.io/docs/reference/access-authn-authz/rbac/#service-account-permissions
横向自动扩展HPA
kubectl autoscale deployment student –cpu-percent=50 –min=1 –max=10
github的action runner实例
配置文件
位置名称:.github/workflows/action.yml 名字只要是yml结尾即可
不能通过Github Desktop上传修改,只能登陆github页面修改
阿里云免费build docker镜相
根据代码仓库里的dockerfile来自动打包应用image
好处是可以使用海外服务器构建,避免下载不到包的情形
git 使用
git 常用命令
git clone https://github.com/Thomas-YangHT/dockerfiles.git
git config –global user.email “168447636@qq.com”
gitlab-ci.yml example
build-beta-job:
– docker-compose -f docker-compose-beta.yml build –no-cache
– docker-compose -f docker-compose-beta.yml down -v
– docker-compose -f docker-compose-beta.yml up -d
build-release-job:
– docker-compose -f docker-compose-release.yml build –no-cache
– docker-compose -f docker-compose-release.yml down
– docker-compose -f docker-compose-release.yml up -d
deploy-product-job:
– docker build –no-cache -f Dockerfile-product -t 127.0.0.1:5000/web-product:latest .
– docker push 127.0.0.1:5000/web-product:latest
– docker stack deploy –compose-file docker-compose-product.yml web-product
svn-server
参考:
https://hub.docker.com/r/garethflowers/svn-server/
http://blog.csdn.net/wangyunzhong123/article/details/51559116
https://linux.cn/article-5160-1.html
jenkins
参考:
https://hub.docker.com/_/jenkins/
https://blog.csdn.net/littlechang/article/details/8642149
https://www.cnblogs.com/ceshisanren/p/5639869.html
https://www.cnblogs.com/zishengY/p/7170656.html
监控
Zabbix
安装:
基本概念架构
zabbix官网: https://www.zabbix.com
zabbix 主要由2部分构成 zabbix server和 zabbix agent
zabbix proxy是用来管理其他的agent,作为代理
Zabbix监控范畴
硬件监控 :Zabbix IPMI Interface
系统监控 :Zabbix Agent Interface
Java 监控:ZabbixJMX Interface
网络设备监抟:Zabbix SNMP Interface
应用服务监控:Zabbix Agent UserParameter
MySQL 数据库监控:percona-monitoring-pldlgins
server&web
server docker run
docker pull zabbix/zabbix-server-mysql
docker run –name zabbix_server –restart=always \
-e DB_SERVER_HOST=”mysql.yunwei.edu” \
-e MYSQL_DATABASE=”zabbix” \
-e MYSQL_PASSWORD=”zabbix” \
-v /etc/localtime:/etc/localtime:ro \
-v /opt/zabbix-scripts:/usr/lib/zabbix \
-v /opt/zabbix:/etc/zabbix \
-d zabbix/zabbix-server-mysql
web docker run
docker pull zabbix/zabbix-web-nginx-mysql
docker run –name zabbix_web –restart=always \
–link zabbix_server:zabbix_server \
-e DB_SERVER_HOST=”mysql.yunwei.edu” \
-e MYSQL_PASSWORD=”zabbix” \
-e MYSQL_DATABASE=”zabbix” \
-e ZBX_SERVER_HOST=”docker2.yunwei.edu” \
-e PHP_TZ=”Asia/Shanghai” \
-d zabbix/zabbix-web-nginx-mysql
docker-compose.yml
mkdir cmp_zabbix_srv;cd cmp_zabbix_srv
zbx_srv:
image: 192.168.254.211:5000/zabbix/zabbix-server-mysql
– DB_SERVER_HOST=192.168.254.110
– DB_SERVER_ROOT_USER=zabbix
– DB_SERVER_ROOT_PASS=zabbix
– /etc/localtime:/etc/localtime:ro
– /opt/zabbix-scripts:/usr/lib/zabbix
– /opt/zabbix:/etc/zabbix
# – ./docker-entrypoint.sh:/usr/bin/docker-entrypoint.sh
zbx_web:
image: 192.168.254.211:5000/zabbix/zabbix-web-nginx-mysql
– DB_SERVER_HOST=192.168.254.110
– ZBX_SERVER_HOST=192.168.254.113
# – ./docker-entrypoint.sh:/usr/bin/docker-entrypoint.sh
zabbix_web修改:
bash-4.3# tail -1 /usr/share/zabbix/include/defines.inc.php
define(‘X_FRAME_OPTIONS’, ‘adm.yunwei.edu,zabbix.yunwei.edu’);
agent
docker run
docker pull zabbix/zabbix-agent
docker run –name zabbix_agent –restart=always \
-e ZBX_HOSTNAME=”`hostname`” \
-e ZBX_SERVER_HOST=”docker2.yunwei.edu” \
-e ZBX_SERVER_PORT=10051 \
-v /opt/zabbix:/etc/zabbix \
docker-compose.yml
mkdir cmp_zabbix;cd cmp_zabbix
image: zabbix/zabbix-agent
– ZBX_HOSTNAME=”`hostname`”
– ZBX_SERVER_HOST=”docker2.yunwei.edu”
– /opt/zabbix:/etc/zabbix
参考:
https://hub.docker.com/r/zabbix/zabbix-server-mysql/
https://hub.docker.com/r/zabbix/zabbix-web-nginx-mysql/
https://hub.docker.com/r/zabbix/zabbix-agent/
配置页面
自定义监控项;
取得某个item值的方法
zabbix_get -s 127.0.0.1 -p 10050 -k “system.hw.macaddr[eth0]”
snmpget -c public -v2c 192.168.31.222 1.3.6.1.2.1.1.1.0
例:在snmp中添加自定义项目:
exec .1.3.6.1.4.1.2021.51 mytest /bin/sh /tmp/echo.sh
snmpget -c public -v2c 192.168.31.222 mytest
例:在zabbix_agent中添加MAC:
cat > /etc/zabbix/zabbix_agentd.d/userparameter_hw.conf <<EOF
UserParameter=eth0-mac,ifconfig eth0 |grep ether|awk ‘{print \$2}’
systemctl restart zabbix-agent
zabbix_get -s 127.0.0.1 -p 10050 -k “eth0-mac”
例:在windows系统中添加MAC:
edit zabbix_agentd.win.conf,add:
UserParameter=nic1-mac,wmic nic where name=”Qualcomm Atheros AR956x Wireless Network Adapter” get macaddress|c:\bin\sed -n ‘2p’
zabbix_get -s 192.168.31.111 -p 10050 -k “nic1-mac”
安全
http://blog.csdn.net/xiaoyu_0217/article/details/73500125
API接口和数据库
api接口使用(curl)
curl -i -X POST -H ‘Content-Type:application/json’ -d'{“jsonrpc”: “2.0”,”method”:”user.login”,”params”:{“user”:”Admin”,”password”:”zabbix”},”auth”: null,”id”:0}’ “http://10.0.0.61/zabbix/api_jsonrpc.php”
curl -i -X POST -H ‘Content-Type:application/json’ -d’
“auth”: “6a450a8fc3dce71fd310cfe338746578”
}’ “http://10.0.0.61/zabbix/api_jsonrpc.php”
详细:
https://www.zabbix.com/documentation/4.0/zh/manual/api
http://zabbix.org/wiki/Docs/api/libraries
mysql 数据库
参考资料:
zabbix3.0中文
https://www.cnblogs.com/clsn/p/7885990.html
zabbix官网:
https://www.zabbix.com/download?zabbix=3.4&os_distribution=centos&os_version=7&db=MySQL
granfana
介绍:
流行的前端展示图形和仪表备盘编辑、报警应用,支持多种数据源、插件,如:zabbix/open-falcon/mysql/elasticsearch/……
官网:
http://docs.grafana-zabbix.org/installation/
安装:
docker run
docker run –name grafana \
-v /opt/grafana/grafana:/var/lib/grafana \
-v /opt/grafana/grafana.ini:/etc/grafana/grafana.ini \
docker-compose.yml
mkdir /opt/cmp_grafana;cd /opt/cmp_grafana;
– ./grafana/grafana:/var/lib/grafana
– ./grafana/grafana.ini:/etc/grafana/grafana.ini
参考:
grafana+zabbix
http://blog.csdn.net/u010725670/article/details/50630760
http://blog.csdn.net/xiegh2014/article/details/53888507
http://www.wangjingfeng.com/656.html
grafana设置Alert阈值和邮件报警
http://blog.csdn.net/jailman/article/details/78920166
grafana 配置mysql做为数据源:
http://docs.grafana.org/features/datasources/mysql/
http://blog.csdn.net/sweatott/article/details/78278011
awstats
docker run –name awstats \
-v /opt/nginxlog:/var/log/nginx \
-v /opt/nginxawstats:/etc/nginx \
-v /opt/awstats:/etc/awstats \
-v /opt/awstatsdata:/var/lib/awstats \
-v /opt/cmp_awstats/cron.awstats:/var/spool/cron/root \
smokeping
docker run –name smokep \
-v /opt/nginxlog:/var/log/nginx \
-v /opt/nginxsmoke:/etc/nginx \
-v /opt/smokeping/Graphs.pm:/usr/share/smokeping/Smokeping/Graphs.pm \
-v /opt/smokeping/Smokeping.pm:/usr/share/smokeping/Smokeping.pm \
-v /opt/smokeping/config:/etc/smokeping/config \
-v /opt/smokeping/basepage.html:/etc/smokeping/basepage.html \
*日志收集与处理
ELK
elk
docker-compose.yml
mkdir /opt/cmp_elk;cd /opt/cmp_elk;
image: docker.io/elasticsearch
– ./esdata:/usr/share/elasticsearch/data
– transport.host=127.0.0.1
# – discovery.zen.minimum_master_nodes=1
– ELASTICSEARCH_URL=http://192.168.100.224:9200
image: docker.io/logstash
– ./logstash.conf:/etc/logstash.conf:ro
command: logstash -f /etc/logstash.conf
logstash.conf 示例
接收filebeat发来的web访问日志,存入elasticsearch中
“message” => “%{SYSLOGTIMESTAMP:syslog_timestamp} %{SYSLOGHOST:syslog_hostname} %{DATA:syslog_program}(?:\[%{POSINT:syslog_pid}\])?: %{GREEDYDATA:syslog_message}”
match => [ “syslog_timestamp”, “MMM d HH:mm:ss”, “MMM dd HH:mm:ss” ]
hosts => [“192.168.100.224:9200”]
index => “logstash-%{host}-%{+YYYY.MM.dd}”
参考
https://hub.docker.com/_/kibana/
https://hub.docker.com/_/elasticsearch/
https://hub.docker.com/_/logstash/
elk2
docker-compose.yml
mkdir /opt/cmp_elk2;cd /opt/cmp_elk2;
– ./logstash/conf.d:/etc/logstash/conf.d
– ./tls/logstash-beats.crt:/etc/pki/tls/certs/logstash-beats.crt
– ./tls/logstash-beats.key:/etc/pki/tls/private/logstash-beats.key
配置
docker run -p 5601:5601 -p 9200:9200 -p 5044:5044 -it –name elk sebp/elk
sysctl -w vm.max_map_count=262144
cd /opt/cmp_elk2; mkdir tls
openssl req -subj ‘/CN=elk.yunwei.edu/’ \
-batch -nodes -newkey rsa:2048 -keyout \
-out tls/logstash-beats.crt
参考
https://hub.docker.com/r/sebp/elk/
http://elk-docker.readthedocs.io/
filebeat
docker-compose.yml
# image: docker.io/prima/filebeat
image: docker.elastic.co/beats/filebeat:6.2.4
– ./filebeat/filebeat.yml:/usr/share/filebeat/filebeat.yml
– /var/log/nginx:/var/log/nginx
– /var/log/messages:/var/log/messages
# – ./logstash-beats.crt:/etc/pki/tls/certs/logstash-beats.crt
注意:挂载到filebeat里的文件目录的权限,因filebeat里是由filebeat用户执行的,推荐644.
配置
docker run docker.elastic.co/beats/filebeat:6.2.4 setup –template -E output.logstash.enabled=false -E ‘output.elasticsearch.hosts=[“192.168.100.224:9200”]’
path: ${path.config}/prospectors.d/*.yml
path: ${path.config}/modules.d/*.yml
var.paths: [“/var/log/nginx/*access.log”]
var.paths: [“/var/log/nginx/*error.log”]
var.paths: [“/var/log/messages*”]
# hosts: [‘elasticsearch:9200’]
hosts: [“elk.yunwei.edu:5044”]
参考
https://www.docker.elastic.co/
https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-6.2.4-x86_64.rpm
https://www.elastic.co/guide/en/beats/filebeat/6.2/filebeat-reference-yml.html
filebeat2
docker-compose.yml
image: docker.io/prima/filebeat
#image: docker.elastic.co/beats/filebeat:6.2.4
– ./filebeat/filebeat.yml:/usr/share/filebeat/filebeat.yml
– /var/log/nginx:/var/log/nginx
– /var/log/messages:/var/log/messages
# – ./logstash-beats.crt:/etc/pki/tls/certs/logstash-beats.crt
filebeat.yml
– /etc/pki/tls/certs/logstash-beats.crt
document_type: nginx-access
集群高可用
keepalived
二主结构:
三主结构
docker
docker run –net=host –privileged=true –name keepalived \
-v /opt/keepalived.1/keepalived.conf:/etc/keepalived/keepalived.conf \
-v /opt/keepalived.1/keep.sh:/etc/keepalived/keep.sh \
-v /opt/keepalived.1/chk_nginx.sh:/etc/keepalived/chk_nginx.sh \
-d 99cloud/centos-source-keepalived:4.0.2.1 bash /etc/keepalived/keep.sh
docker-compose
keepalived:
image: 192.168.254.211:5000/99cloud/centos-source-keepalived:4.0.2.1
# Required to load kernel NFS module
– ./keepalived.conf:/etc/keepalived/keepalived.conf
– ./keep.sh:/etc/keepalived/keep.sh
– ./chk_nfs.sh:/etc/keepalived/chk_nfs.sh
command: bash /etc/keepalived/keep.sh
问题解决:
2.虚拟机使用macvtap(bridge)方式连接主机eth0,虚IP在每台虚机上都存在,无法正常切换
原因是macvtap方式与主机连接有问题,换成eth0接br1网桥,虚拟接br1网桥解决;
3.用docker的方式启动keepalived,停止后虚IP还残留在接口上
暂时无法解决,建议主机上直接yum安装配置keepalived
docker-keepalived.sh
-e VIRTUAL_IP=”$VIP_IP” \
-e VIRTUAL_ROUTER_ID=52 \
-e STATE=`[ $HOSTNAME = “$NODE1_NAME” ] && echo MASTER || echo BACKUP` \
-e PRIORITY=`[ $HOSTNAME = “$NODE1_NAME” ] && echo 101 || echo 100` \
lvs
NAT
http://blog.csdn.net/nimasike/article/details/53783787
TUN
http://blog.csdn.net/nimasike/article/details/53893609
haproxy
haproxy
http://www.cnblogs.com/skyflask/p/6970151.html
http://www.cnblogs.com/skyflask/p/6970154.html
docker:
https://hub.docker.com/_/haproxy/
https://cbonte.github.io/haproxy-dconv/
https:
https://www.cnblogs.com/paul8339/p/8042776.html
#check 语法:
haproxy -c -f /usr/local/etc/haproxy/haproxy.cfg
#reload config:
docker kill -s HUP my-running-haproxy
其它常用负载均衡方式:
iptables
负载平衡传入的网络流量
使用iptables可以实现传入web流量的负载均衡,我们可以传入web流量负载平衡使用iptables防火墙规则。 例:使用iptables nth将HTTPS流量负载平衡至三个不同的ip地址。
iptables -A PREROUTING -i eth0 -p tcp –dport 443 -m state –state NEW -m nth –counter 0 –every 3 –packet 0 -j DNAT –to-destination 192.168.1.101:443
iptables -A PREROUTING -i eth0 -p tcp –dport 443 -m state –state NEW -m nth –counter 0 –every 3 –packet 1 -j DNAT –to-destination 192.168.1.102:443
iptables -A PREROUTING -i eth0 -p tcp –dport 443 -m state –state NEW -m nth –counter 0 –every 3 –packet 2 -j DNAT –to-destination 192.168.1.103:443
运维自动化工具
fabric
使用Fabric
参考:
https://www.liaoxuefeng.com/article/001373892650475818672edc83c4c978a45195eab8dc753000
http://fabric-chs.readthedocs.io/zh_CN/chs/usage/parallel.html
#用法
fab -P runs_in_parallel -z 5 -H host1,host2,host3
fab -H 192.168.31.213,192.168.31.222,192.168.1.1 -f test.py hello -e –colorize-errors –hide stdout
#给fabric加一个ansible类似的hosts功能;
fab -H `cat host|xargs |sed ‘s/ /,/g’` -f test.py upload -e –colorize-errors
例一:
def upload():
put(‘/root/collect.sh’,’/root/’)
def instcron():
run(‘echo “*/5 * * * * /usr/bin/bash /root/collect.sh” >>/var/spool/cron/root’)
def instiostat():
run(‘yum install sysstat -y’)
执行:root@localhost10:35:31~#fab -H 192.168.31.222,192.168.31.213 -f test.py upload execteit -e –colorize-errors –hide stdout -P
[192.168.31.222] Executing task ‘upload’
[192.168.31.213] Executing task ‘upload’
[192.168.31.222] put: /root/collect.sh -> /root/collect.sh
[192.168.31.213] put: /root/collect.sh -> /root/collect.sh
[192.168.31.222] Executing task ‘execteit’
[192.168.31.213] Executing task ‘execteit’
[192.168.31.213] run: sh collect.sh
[192.168.31.222] run: sh collect.sh
例二: 使用Fabric部署网站应用
以前一直用rsync同步代码到服务器,这种山寨方法用一次两次还可,每天部署10次就麻烦了,最近抽空研究了一下Fabric,发现这个东西部署起来简直太爽了。
Fabric是一个用Python开发的部署工具,最大特点是不用登录远程服务器,在本地运行远程命令,几行Python脚本就可以轻松部署。
花10分钟写了一个部署脚本fabfile.py(名字不能变),放到工程目录下:
from datetime import datetime
env.hosts = [‘www.example.com’] # 如果有多个主机,fabric会自动依次部署
def pack():
tar_files = [‘*.py’, ‘static/*’, ‘templates/*’, ‘favicon.ico’]
local(‘rm -f example.tar.gz’)
local(‘tar -czvf example.tar.gz –exclude=\’*.tar.gz\’ –exclude=\’fabfile.py\’ %s’ % ‘ ‘.join(tar_files))
def deploy():
remote_tmp_tar = ‘/tmp/example.tar.gz’
tag = datetime.now().strftime(‘%y.%m.%d_%H.%M.%S’)
run(‘rm -f %s’ % remote_tmp_tar)
put(‘shici.tar.gz’, remote_tmp_tar)
remote_dist_dir = ‘/srv/www.example.com@%s’ % tag
remote_dist_link = ‘/srv/www.example.com’
run(‘mkdir %s’ % remote_dist_dir)
with cd(remote_dist_dir):
run(‘tar -xzvf %s’ % remote_tmp_tar)
run(‘chown -R www-data:www-data %s’ % remote_dist_dir)
run(‘rm -f %s’ % remote_dist_link)
run(‘ln -s %s %s’ % (remote_dist_dir, remote_dist_link))
run(‘chown -R www-data:www-data %s’ % remote_dist_link)
fcgi = ‘/etc/init.d/py-fastcgi’
with settings(warn_only=True):
以上定义了pack和deploy两个任务,如果我们用Fabric部署,只需简单地输入两条命令:
Fabric提供几个简单的API来完成所有的部署,最常用的是local()和run(),分别在本地和远程执行命令,put()可以把本地文件上传到远程,当需要在远程指定当前目录时,只需用with cd(‘/path/to/dir/’):即可。
默认情况下,当命令执行失败时,Fabric会停止执行后续命令。有时,我们允许忽略失败的命令继续执行,比如run(‘rm /tmp/abc’)在文件不存在的时候有可能失败,这时可以用with settings(warn_only=True):执行命令,这样Fabric只会打出警告信息而不会中断执行。
Fabric是如何在远程执行命令的呢?其实Fabric所有操作都是基于SSH执行的,必要时它会提示输入口令,所以非常安全。更好的办法是在指定的部署服务器上用证书配置无密码的ssh连接。
如果是基于团队开发,可以让Fabric利用版本库自动检出代码,自动执行测试、打包、部署的任务。由于Fabric运行的命令都是基本的Linux命令,所以根本不需要用Fabric本身来扩展,会敲Linux命令就能用Fabric部署。
利用Fabric部署Python、Ruby、PHP这样的非编译型网站应用非常方便,而对于编译型的Java、C#等就麻烦了,编译本身就是一个极其复杂的大工程,需要依赖特定工具或者IDE,很难做到自动化。
测试
其它docker应用:
adm
-v /opt/nginxadm:/etc/nginxadm \
-v /opt/nginx:/etc/nginx \
-v /opt/bind/bind/etc:/etc/bind \
-v /opt/adm:/usr/share/nginx/html/adm \
-v /opt/admconf/sudoers:/etc/sudoers \
-v /opt/admconf/startadm.sh:/usr/bin/startadm.sh \
postfix-relay
docker-compose.yml
mkdir /opt/cmp_postfix; cd /opt/cmp_postfix
image: mwader/postfix-relay
– POSTFIX_myhostname=mail.yunwei.edu
mailhog
mkdir /opt/cmp_mailhog; cd /opt/cmp_mailhog
docker pull docker.io/mailhog/mailhog
docker run –name mailhog -p 1025:1025 -p 8025:8025 -d mailhog/mailhog
ovswitch
docker run
vi /etc/hosts #写好本机IP和主机名,否则会报错
docker run -itd –net=host –name ovswitch –cap-add NET_ADMIN socketplane/openvswitch
参考:
https://hub.docker.com/r/socketplane/openvswitch/
http://dockone.io/article/228
quagga
docker run
docker run –privileged –net=host -it –name quagga ewindisch/quagga
docker exec -i -t quagga /usr/bin/vtysh
参考:
https://hub.docker.com/r/ewindisch/quagga/
http://www.nongnu.org/quagga/docs.html
https://www.linuxidc.com/Linux/2015-07/120224.htm
swarm compose
配置
docker swarm init –advertise-addr 192.168.100.222:2377
docker swarm join \
–token SWMTKN-1-1t95833ah59660camreb1ekvtsoy8mczkp3qc5ol42kuzbsrek-6l7u2umi0lzxxitnpexx2obv8 \
docker network create –driver overlay skynet
docker run -itd -p 5000:8080 -e HOST=192.168.100.222 -v \
/var/run/docker.sock:/var/run/docker.sock dockersamples/visualizer
docker service create –name web –network skynet –publish 3000:3000 \
docker service scale web=6
docker service update web –image ninghao/node:hola
docker service update web –image ninghao/node –update-parallelism 2 –update-delay 6s
http://192.168.100.222:5000/
http://192.168.100.222:1000/
docker 1.13.1: swarm deploy: 支持到 service 3.0
docker stack deploy –compose-file docker-compose.yml portainer
参考
swarm
https://docs.docker.com/compose/swarm/
docker service:
https://blog.csdn.net/liushuiwuyizhe/article/details/78296028?locationNum=1&fps=1
示例:
https://www.jianshu.com/p/54b1b0a098c3
*
https://segmentfault.com/a/1190000010262178
rancher
1.6:
docker run -d –name rancher1 –restart=always -p 8080:8080 rancher/server
2.0: 只支持kubernetes
docker run -d –name rancher –restart=unless-stopped -p 80:80 -p 443:443 rancher/rancher:stable
参考:
https://blog.csdn.net/CSDN_duomaomao/article/details/79104314
http://blog.chinaunix.net/uid-29757900-id-5676591.html
https://hub.docker.com/r/rancher/rancher/
https://rancher.com/docs/rancher/v2.x/en/quick-start-guide/
weave scope
1. To begin run the following on each node:
chmod a+x /export/download/scope
chmod a+x /usr/local/bin/scope
2. Then on the first node launch scope with:
./scope launch -app.basicAuth -probe.basicAuth -app.http.address :4050 192.168.253.44:4050 192.168.253.45:4050 192.168.253.46:4050
docker run –name weavescope -p 4040:4040 -d weaveworks/scope:1.10.1 –mode app –probe.docker=true 192.168.253.44 192.168.253.45 192.168.253.46
3. And do the same for all of the other nodes in your cluster:
scope launch 192.168.254.110 192.168.254.111 192.168.254.112
scope launch 192.168.254.110 192.168.254.111 192.168.254.113
scope launch 192.168.254.110 192.198.254.112 192.168.254.113
portainer
docker-compose.yml
mkdir /opt/portainer; cd /opt/portainer
image: portainer/portainer
command: -H unix:///var/run/docker.sock
– /var/run/docker.sock:/var/run/docker.sock
配置
docker volume create portainer_data
docker run -d -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer
curl -L https://portainer.io/download/portainer-agent-stack.yml -o portainer-agent-stack.yml
docker stack deploy –compose-file=portainer-agent-stack.yml portainer
参考:
https://github.com/portainer/portainer
https://portainer.io/install.html
vagrant
https://www.jianshu.com/p/c88c8888b51a
kolla
kolla
http://www.chenshake.com/kolla-installation/#i-3
https://docs.openstack.org/project-deploy-guide/kolla-ansible/ocata/quickstart.html
http://www.chenshake.com/kolla-ocata-iso-release-notes/
https://www.cnblogs.com/SuperXJ/p/7900309.html
多结点
https://blog.csdn.net/leoe_/article/details/78702390
http://www.chenshake.com/kolla-centos-over-more-than-7-3-node-installation/
http://baijiahao.baidu.com/s?id=1595100978610939913&wfr=spider&for=pc
外网访问:
https://www.cnblogs.com/CloudMan6/p/5998198.html
coreos +k8s
https://coreos.com/tectonic/docs/latest/tutorials/kubernetes/getting-started.html
https://coreos.com/kubernetes/docs/1.6.1/deploy-master.html
https://coreos.com/tectonic/docs/latest/install/bare-metal/index.html
python相关
python做简单的ftp&http
python -m SimpleHTTPServer 8000
pip install pyftpdlib && python -m pyftpdlib -p 21
jinjia2示例
python -c “import jinja2”
<link rel=”stylesheet” href=”style.css”/>
<title>{% block title %}{% endblock %} – My Webpage</title>
<div id=”content”>{% block content %}{% endblock %}</div>
<script>This is javascript code </script>
from jinja2 import PackageLoader,Environment
env = Environment(loader=PackageLoader(‘python_project’,’templates’)) # 创建一个包加载器对象
template = env.get_template(‘bast.html’) # 获取一个模板文件
template.render(name=’daxin’,age=18) # 渲染
参考资料链接
docker-compose.yml
https://blog.csdn.net/wanghailong041/article/details/52162275
https://www.cnblogs.com/freefei/p/5311294.html
https://docs.docker.com/compose/compose-file/#compose-file-structure-and-examples
kubenetes image
https://hub.docker.com/r/ist0ne/kubedns-amd64/