k8s dashboard install

1
2
3
root@192:~/node# docker pull registry.cn-hangzhou.aliyuncs.com/kubernetes/kubernetes-dashboard-amd64:v1.4.1
root@192:~/node# docker tag registry.cn-hangzhou.aliyuncs.com/kubernetes/kubernetes-dashboard-amd64:v1.4.1 d.hub.io/kubernetes-dashboard-amd64:v1.4.1
root@192:~/node# docker run -it -d -p 9090:9090 d.hub.io/kubernetes-dashboard-amd64:v1.4.1 /dashboard --apiserver-host=http://192.168.15.114:8080

k8s registry install

  1. 安装nginx

    1
    2
    3
    4
    5
    6
    7
    8
    9
    root@192:~# apt-get install gcc make libpcre3 libpcre3-dev openssl libssl-dev
    root@192:~# apt-get install libauthen-htpasswd-perl libapache-htpasswd-perl apache2-utils
    root@192:~# useradd -s /usr/sbin/nologin nginx
    root@192:~# wget http://nginx.org/download/nginx-1.10.2.tar.gz
    root@192:~# tar xzf nginx-1.10.2.tar.gz
    root@192:~# cd nginx-1.10.2/
    root@192:~/nginx-1.10.2# ./configure --prefix=/opt/nginx --user=nginx --group=nginx --with-pcre --with-http_stub_status_module --with-http_ssl_module --with-http_addition_module --with-http_realip_module --with-http_flv_module
    root@192:~/nginx-1.10.2# make
    root@192:~/nginx-1.10.2# make install

    可以设置认证,但实际部署时不建议设置账号和密码,请看nginx配置文件

    1
    root@192:~# htpasswd -cb /opt/nginx/conf/.htpasswd admin admin
  2. 创建证书

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    root@192:~# mkdir -p /opt/nginx/ssl
    root@192:~# cd /opt/nginx/ssl/
    root@192:/opt/nginx/ssl# openssl req -newkey rsa:4096 -nodes -sha256 -keyout domain.key -x509 -days 365 -out domain.crt
    Generating a 4096 bit RSA private key
    ........++
    .........................................................................................................................................................................................................................................++
    writing new private key to \'domain.key\'
    \-----
    You are about to be asked to enter information that will be incorporated
    into your certificate request.
    What you are about to enter is what is called a Distinguished Name or a DN.
    There are quite a few fields but you can leave some blank
    For some fields there will be a default value,
    If you enter '.', the field will be left blank.
    \-----
    Country Name (2 letter code) [AU]:CN
    State or Province Name (full name) [Some-State]:BJ
    Locality Name (eg, city) []:bj
    Organization Name (eg, company) [Internet Widgits Pty Ltd]:zhonghui
    Organizational Unit Name (eg, section) []:
    Common Name (e.g. server FQDN or YOUR name) []:d.hub.io
    Email Address []:pengliu@brandwisdom.cn
  3. 拷贝CA证书到docker客户端

    1
    2
    root@192:~# mkdir -p /etc/docker/certs.d/d.hub.io
    root@192:~# cp /opt/nginx/ssl/domain.crt /etc/docker/certs.d/d.hub.io/ca.crt

    注意:将ca.crt 拷贝到所有的k8s node节点上:

    1
    2
    root@192:~# mkdir -p /etc/docker/certs.d/d.hub.io
    root@192:~# cp /opt/nginx/ssl/domain.crt /etc/docker/certs.d/d.hub.io/ca.crt
  4. 启动docker服务

    1
    2
    root@192:~# source /var/run/flannel/subnet.env
    root@192:~# /usr/bin/dockerd --bip=${FLANNEL_SUBNET} --mtu=${FLANNEL_MTU} &
  5. 启动docker registry容器

    1
    2
    3
    4
    root@192:~# docker pull index.alauda.cn/library/registry
    root@192:~# docker tag index.alauda.cn/library/registry:latest registry:latest
    root@192:~# mkdir -p /mnt/data/registry
    root@192:~# docker run -d -p 5000:5000 --restart=always --name registry -v /mnt/data/registry/:/var/lib/registry/ registry:latest
  6. 修改nginx配置文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    root@192:~# cat /opt/nginx/conf/nginx.conf
    user nginx nginx;
    worker_processes auto;

    error_log logs/error.log;
    pid logs/nginx.pid;
    worker_rlimit_nofile 51200;

    events {
    use epoll;
    worker_connections 51200;
    multi_accept on;
    }

    http {
    include mime.types;
    default_type application/octet-stream;

    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
    '$status $body_bytes_sent "$http_referer" '
    '"$http_user_agent" "$http_x_forwarded_for"';
    access_log logs/access.log main;

    server_names_hash_bucket_size 128;
    client_header_buffer_size 32k;
    large_client_header_buffers 4 32k;

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;

    upstream registry {
    server 192.168.15.114:5000;
    }

    server {
    listen 443;
    server_name d.hub.io;

    ssl on;
    ssl_certificate /opt/nginx/ssl/domain.crt;
    ssl_certificate_key /opt/nginx/ssl/domain.key;

    client_max_body_size 0;
    chunked_transfer_encoding on;
    location /v2/ {
    #auth_basic "Registry realm";
    #auth_basic_user_file /opt/nginx/conf/.htpasswd;
    add_header 'Docker-Distribution-Api-Version' 'registry/2.0' always;

    proxy_pass http://registry;
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_read_timeout 900;
    }

    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
    root html;
    }
    }
    }
  7. 启动nginx

    1
    2
    root@192:~# /opt/nginx/sbin/nginx -t -c /opt/nginx/conf/nginx.conf
    root@192:~# /opt/nginx/sbin/nginx -c /opt/nginx/conf/nginx.conf &
  8. 将域名加入hosts文件

    1
    root@192:/etc/docker/ssl# echo "192.168.15.114 d.hub.io" | tee -a  /etc/hosts
  9. 验证

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    root@192:~# curl -i -k -v https://d.hub.io/v2/
    * Trying 192.168.15.114...
    * Connected to d.hub.io (192.168.15.114) port 443 (#0)
    * found 173 certificates in /etc/ssl/certs/ca-certificates.crt
    * found 692 certificates in /etc/ssl/certs
    * ALPN, offering http/1.1
    * SSL connection using TLS1.2 / ECDHE_RSA_AES_128_GCM_SHA256
    * server certificate verification SKIPPED
    * server certificate status verification SKIPPED
    * common name: d.hub.io (matched)
    * server certificate expiration date OK
    * server certificate activation date OK
    * certificate public key: RSA
    * certificate version: #3
    * subject: C=CN,ST=BJ,L=bj,O=zhonghui,CN=d.hub.io,EMAIL=pengliu@brandwisdom.cn
    * start date: Mon, 19 Dec 2016 02:42:31 GMT
    * expire date: Tue, 19 Dec 2017 02:42:31 GMT
    * issuer: C=CN,ST=BJ,L=bj,O=zhonghui,CN=d.hub.io,EMAIL=pengliu@brandwisdom.cn
    * compression: NULL
    * ALPN, server accepted to use http/1.1
    * Server auth using Basic with user \'admin\'
    > GET /v2/ HTTP/1.1
    > Host: d.hub.io
    > Authorization: Basic YWRtaW46YWRtaW4=
    > User-Agent: curl/7.47.0
    > Accept: */*
    >
    < HTTP/1.1 200 OK
    HTTP/1.1 200 OK
    < Server: nginx/1.10.2
    Server: nginx/1.10.2
    < Date: Mon, 19 Dec 2016 02:57:43 GMT
    Date: Mon, 19 Dec 2016 02:57:43 GMT
    < Content-Type: application/json; charset=utf-8
    Content-Type: application/json; charset=utf-8
    < Content-Length: 2
    Content-Length: 2
    < Connection: keep-alive
    Connection: keep-alive
    < Docker-Distribution-Api-Version: registry/2.0
    Docker-Distribution-Api-Version: registry/2.0
    < X-Content-Type-Options: nosniff
    X-Content-Type-Options: nosniff
    < Docker-Distribution-Api-Version: registry/2.0
    Docker-Distribution-Api-Version: registry/2.0
    <
    * Connection #0 to host d.hub.io left intact
  10. 提交下载

    1
    2
    3
    root@192:~# docker tag 192.168.15.114:5000/node-web:latest d.hub.io/node-web:latest
    root@192:~# docker push d.hub.io/node-web:latest
    root@192:~# docker pull d.hub.io/node-web:latest
  11. 安装完docker 私有仓库后需要重启kubernetes minion上的dockerd服务

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    root@192:~# /usr/bin/dockerd --bip=${FLANNEL_SUBNET} --mtu=${FLANNEL_MTU} --insecure-registry=d.hub.io &
    root@192:~# docker tag ubuntu:latest 192.168.15.114:5000/ubuntu:latest
    root@192:~# docker images
    REPOSITORY TAG IMAGE ID CREATED SIZE
    192.168.15.114:5000/ubuntu latest 4ca3a192ff2a 10 days ago 128.2 MB
    ubuntu latest 4ca3a192ff2a 10 days ago 128.2 MB
    registry latest c9bd19d022f6 7 weeks ago 33.3 MB
    root@192:~# docker push 192.168.15.114:5000/ubuntu:latest
    0d45be5b95d8: Pushed
    18568efa7ad4: Pushed
    1c53295311c1: Pushed
    dfcc17ddae9e: Pushed
    d29d52f94ad5: Pushed
    latest: digest: sha256:3b64c309deae7ab0f7dbdd42b6b326261ccd6261da5d88396439353162703fb5 size: 1357

k8s install

Kubernets 是什么?

Kubernetes是Google开源的容器集群管理系统,其提供应用部署、维护、扩展机制等功能,利用Kubernetes能方便地管理跨机器运行容器化的应用。

Kubernets 主要功能:

  • 使用Docker对应用程序包装(package),实例化(instantiate),运行(run)
  • 以集群的方式运行,管理跨机器的容器
  • 解决Docker跨机器容器之间的通讯问题
  • Kubernetes的自我修复机制使得容器集群总是运行在用户期望的状态

Kubernets 搭建

名称 IP 说明
node.1 192.168.99.182 kubernets-minion
node.2 192.168.99.177 kubernets-minion
node.3 192.168.99.142 kubernets-master

基础安装

  1. 更新源

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    penn@ubuntu:~$ sudo su -
    root@ubuntu:~# cp /etc/apt/{sources.list,sources.list.bak}
    root@ubuntu:~# vim /etc/apt/sources.list
    deb-src http://archive.ubuntu.com/ubuntu xenial main restricted
    deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted
    deb-src http://mirrors.aliyun.com/ubuntu/ xenial main restricted multiverse universe
    deb http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted
    deb-src http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted multiverse universe
    deb http://mirrors.aliyun.com/ubuntu/ xenial universe
    deb http://mirrors.aliyun.com/ubuntu/ xenial-updates universe
    deb http://mirrors.aliyun.com/ubuntu/ xenial multiverse
    deb http://mirrors.aliyun.com/ubuntu/ xenial-updates multiverse
    deb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse
    deb-src http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse
    deb http://archive.canonical.com/ubuntu xenial partner
    deb-src http://archive.canonical.com/ubuntu xenial partner
    deb http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted
    deb-src http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted multiverse universe
    deb http://mirrors.aliyun.com/ubuntu/ xenial-security universe
    deb http://mirrors.aliyun.com/ubuntu/ xenial-security multiverse
    root@ubuntu:~# apt-get clean
    root@ubuntu:~# apt-get update
  2. 基础软件安装

    1
    2
    3
    4
    5
    root@ubuntu:~# apt-get -y install lrzsz curl wget dstat vim tree git
    root@ubuntu:~# apt-get -y install ntpdate
    root@ubuntu:~# cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
    root@ubuntu:~# crontab -e
    5 0 * * * /usr/sbin/ntpdate -s cn.pool.ntp.org >/dev/null 2>&1
  3. 修改主机名

    1
    2
    root@ubuntu:~# echo 192.168.99.177 > /etc/hostname
    root@ubuntu:~# hostname 192.168.99.17

docker install

1
2
3
4
5
6
7
8
9
10
11
12
penn@ubuntu:~$ sudo apt-get -y install apt-transport-https ca-certificates
penn@ubuntu:~$ sudo apt-key adv --keyserver hkp://ha.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
penn@ubuntu:~$ echo "deb https://apt.dockerproject.org/repo ubuntu-xenial main" | sudo tee /etc/apt/sources.list.d/docker.list
penn@ubuntu:~$ sudo apt-get update
penn@ubuntu:~$ apt-cache policy docker-engine
penn@ubuntu:~$ sudo apt-get -y install linux-image-extra-$(uname -r) linux-image-extra-virtual
penn@ubuntu:~$ apt-cache madison docker-engine
penn@ubuntu:~$ sudo apt-get -y install docker-engine
penn@ubuntu:~$ sudo systemctl enable docker
penn@ubuntu:~$ sudo systemctl restart docker.service
penn@ubuntu:~$ docker -v
Docker version 1.12.3, build 6b644ec

补充:

1
2
3
4
penn@ubuntu:~$ sudo apt-get -y upgrade docker-engine  更新
penn@ubuntu:~$ sudo apt-get -y purge docker-engine 卸载
penn@ubuntu:~$ sudo apt-get -y autoremove --purge docker-engine 卸载和依赖包
penn@ubuntu:~$ rm -rf /var/lib/docker


k8s binary download

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
penn@ubuntu:~$ tar xzf kubernetes.tar.gz
penn@ubuntu:~$ cd kubernetes
penn@ubuntu:~$ cd kubernetes/cluster/ubuntu/
penn@ubuntu:~/kubernetes/cluster/ubuntu$ vim download-release.sh
... ...
# flannel
FLANNEL_VERSION=${FLANNEL_VERSION:-"0.5.5"}
... ...
# ectd
ETCD_VERSION=${ETCD_VERSION:-"2.3.1"}
... ...
# k8s
function get_latest_version_number {
local -r latest_url="https://storage.googleapis.com/kubernetes-release/release/stable.txt"
if [[ $(which wget) ]]; then
wget -qO- ${latest_url}
elif [[ $(which curl) ]]; then
curl -Ss ${latest_url}
else
echo "Couldn't find curl or wget. Bailing out." >&2
exit 4
fi
}
if [ -z "$KUBE_VERSION" ]; then
KUBE_VERSION=$(get_latest_version_number | sed 's/^v//')
fi
penn@ubuntu:~/kubernetes/cluster/ubuntu$ sudo ./download-release.sh

k8s binary copy

  • master:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    penn@ubuntu:~$ sudo su -
    root@ubuntu:~# sudo mkdir /opt/bin
    root@ubuntu:~# cp kubernetes/cluster/ubuntu/binaries/master/* /opt/bin/
    root@ubuntu:~# cp kubernetes/cluster/ubuntu/binaries/kubectl /opt/bin/
    root@ubuntu:~# ls -l /opt/bin/
    total 487708
    -rwxr-xr-x 1 root root 16687744 Dec 7 03:21 etcd
    -rwxr-xr-x 1 root root 14347456 Dec 7 03:21 etcdctl
    -rwxr-xr-x 1 root root 16581152 Dec 7 03:21 flanneld
    -rwxr-x--- 1 root root 151001624 Dec 7 03:21 kube-apiserver
    -rwxr-x--- 1 root root 141028448 Dec 7 03:21 kube-controller-manager
    -rwxr-x--- 1 root root 79537832 Dec 7 03:26 kubectl
    -rwxr-x--- 1 root root 80201536 Dec 7 03:22 kube-scheduler
  • minion:

    1
    2
    3
    4
    5
    6
    7
    8
    penn@ubuntu:~$ sudo su -
    root@ubuntu:~# sudo mkdir /opt/bin
    root@ubuntu:~# cp kubernetes/cluster/ubuntu/binaries/minion/* /opt/bin/
    root@ubuntu:~# ls -l /opt/bin/
    total 212976
    -rwxr-xr-x 1 root root 16581152 Dec 7 03:23 flanneld
    -rwxr-x--- 1 root root 129126768 Dec 7 03:23 kubelet
    -rwxr-x--- 1 root root 72367392 Dec 7 03:23 kube-proxy

k8s deploy

  • master:

    1. 停止docker服务

      1
      root@ubuntu:~# systemctl stop docker.service
    2. 启动etcd服务并设置网段

      1
      2
      3
      root@ubuntu:~# mkdir -p  /opt/data/etcd
      root@ubuntu:~# /opt/bin/etcd --data-dir '/opt/data/etcd' --listen-peer-urls 'http://0.0.0.0:2380,http://0.0.0.0:7001' --listen-client-urls 'http://0.0.0.0:2379,http://0.0.0.0:4001' --initial-advertise-peer-urls 'http://0.0.0.0:2380,http://0.0.0.0:7001' --initial-cluster 'default=http://0.0.0.0:2380,default=http://0.0.0.0:7001' --advertise-client-urls 'http://0.0.0.0:2379,http://0.0.0.0:4001' &
      root@ubuntu:~# /opt/bin/etcdctl set /coreos.com/network/config '{"Network":"172.16.0.0/16"}'
    3. 启动flanneld

      1
      2
      3
      4
      5
      6
      root@ubuntu:~# /opt/bin/flanneld --etcd-endpoints="http://127.0.0.1:4001" -iface=enp0s3 &
      root@ubuntu:~# cat /run/flannel/subnet.env
      FLANNEL_NETWORK=172.16.0.0/16
      FLANNEL_SUBNET=172.16.24.1/24
      FLANNEL_MTU=1472
      FLANNEL_IPMASQ=false
    4. 重新初始化docker0网卡,启动docker

      1
      2
      3
      root@ubuntu:~# source /run/flannel/subnet.env
      root@ubuntu:~# ifconfig docker0 ${FLANNEL_SUBNET}
      root@ubuntu:~# /usr/bin/dockerd --bip=${FLANNEL_SUBNET} --mtu=${FLANNEL_MTU} &
    5. 启动kube-apiserver

      1
      root@ubuntu:~# /opt/bin/kube-apiserver --address=0.0.0.0 --port=8080 --etcd_servers=http://127.0.0.1:4001 --portal_net=172.16.1.0/24 --allow_privileged=false --kubelet_port=10250 --v=0  &
    6. 启动kube-controller-manager

      1
      root@ubuntu:~# /opt/bin/kube-controller-manager --address=0.0.0.0 --master=127.0.0.1:8080  --v=0 &
    7. 启动kube-scheduler

      1
      root@ubuntu:~# /opt/bin/kube-scheduler --address=0.0.0.0 --master=127.0.0.1:8080 --v=0 &
  • minion:

    1. 停止docker服务

      1
      root@ubuntu:~# systemctl stop docker.service
    2. 启动flanneld服务

      1
      2
      3
      4
      5
      6
      root@ubuntu:~# /opt/bin/flanneld --etcd-endpoints="http://192.168.99.142:4001" -iface=enp0s3 &
      root@ubuntu:~# cat /run/flannel/subnet.env
      FLANNEL_NETWORK=172.16.0.0/16
      FLANNEL_SUBNET=172.16.44.1/24
      FLANNEL_MTU=1472
      FLANNEL_IPMASQ=false
    3. 重新初始化docker0网卡,启动docker

      1
      2
      3
      root@ubuntu:~# source /run/flannel/subnet.env
      root@ubuntu:~# ifconfig docker0 ${FLANNEL_SUBNET}
      root@ubuntu:~# /usr/bin/dockerd --bip=${FLANNEL_SUBNET} --mtu=${FLANNEL_MTU} &
    4. 启动kubelet

      1
      root@ubuntu:~# /opt/bin/kubelet --address=0.0.0.0 --port=10250 --api_servers=http://192.168.99.142:8080 --enable_server=true --v=0 &
    5. 启动kube-proxy

      1
      root@ubuntu:~# /opt/bin/kube-proxy --master=http://192.168.99.142:8080 --v=0 &

k8s work test

1
root@ubuntu:~# /opt/bin/kubectl get nodes

vsftpd error

错误记录:

  • vsftpd start error

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    [root@localhost ~]# systemctl start vsftpd.service
    Job for vsftpd.service failed because the control process exited with error code. See "systemctl status vsftpd.service" and "journalctl -xe" for details.
    [root@localhost ~]# journalctl -xe
    [root@localhost ~]# journalctl -xe
    --
    -- Unit vsftpd.service has failed.
    --
    -- The result is failed.
    Nov 24 11:38:33 localhost.localdomain systemd[1]: Unit vsftpd.service entered failed state.
    Nov 24 11:38:33 localhost.localdomain systemd[1]: vsftpd.service failed.
    Nov 24 11:38:33 localhost.localdomain polkitd[503]: Unregistered Authentication Agent for unix-process:21102:6146111 (system bus name :1.53, object path /org/freede
    Nov 24 11:39:09 localhost.localdomain polkitd[503]: Registered Authentication Agent for unix-process:21111:6149749 (system bus name :1.54 [/usr/bin/pkttyagent --not
    Nov 24 11:39:09 localhost.localdomain systemd[1]: Starting Vsftpd ftp daemon...
    -- Subject: Unit vsftpd.service has begun start-up
    -- Defined-By: systemd
    -- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
    --
    -- Unit vsftpd.service has begun starting up.
    Nov 24 11:39:09 localhost.localdomain systemd[1]: vsftpd.service: control process exited, code=exited status=2
    Nov 24 11:39:09 localhost.localdomain systemd[1]: Failed to start Vsftpd ftp daemon.
    -- Subject: Unit vsftpd.service has failed
    -- Defined-By: systemd
    -- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
    --
    -- Unit vsftpd.service has failed.
    --
    -- The result is failed.

    解决方法:
    1.当前网络如果不支持IPV6
    [root@localhost ~]# vim /etc/vsftpd/vsftpd.conf
    listen_ipv6=NO
    [root@localhost ~]# systemctl start vsftpd.service
  • vsftp 553 error

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    是由于目录权限问题引起:
    [root@localhost ~]# ls -ld /mnt/ftpdata/
    drwxr-xr-x 4 root root 29 Jan 10 09:48 /mnt/ftpdata/

    [root@localhost ~]# ls -ld /mnt/ftpdata/ssp
    drwxr-xr-x 3 root root 21 Jan 10 10:13 /mnt/ftpdata/ssp

    [root@localhost ~]# ls -ld /mnt/ftpdata/ssp/20170110
    drwxrwxrwx 5 root root 41 Jan 10 10:12 /mnt/ftpdata/ssp/20170110

    [root@localhost ~]# ls -ld /mnt/ftpdata/ssp/20170110/*
    drwxr-xr-x 2 vsftpduser vsftpduser 6 Jan 10 10:12 /mnt/ftpdata/ssp/20170110/lttest
    drwxr-xr-x 2 vsftpduser vsftpduser 6 Jan 10 10:13 /mnt/ftpdata/ssp/20170110/prod
    drwxr-xr-x 2 vsftpduser vsftpduser 6 Jan 10 10:12 /mnt/ftpdata/ssp/20170110/test

vsftpd install

vsftpd安装

  1. 查看系统版本

    1
    2
    [root@localhost ~]# cat /etc/redhat-release
    CentOS Linux release 7.2.1511 (Core)
  2. 安装vsftpd

    1
    2
    3
    4
    [root@localhost ~]# yum -y install vsftpd* pam* db4*
    vsftp* //FTP服务
    pam* //可插入认证模块
    db4* //文件数据库
  3. 创建用户

    1
    2
    3
    4
    5
    //创建服务的宿主用户
    [root@localhost ~]# useradd -M -s /sbin/nologin vsftpd

    //创建虚拟宿主用户
    [root@localhost ~]# useradd -s /sbin/nologin vsftpduser

    说明:

    1
    2
    3
    4
    5
    6
    7
    8
    * Vsftpd服务宿主用户:
    默认的Vsftpd的服务宿主用户是root,但是这不符合安全性的需要.
    这里建立名字为vsftpd的用户,用他来作为支持Vsftpd的服务宿主用户.
    由于该用户仅用来支持Vsftpd服务用,因此没有许可他登陆系统的必要,并设定他为不能登陆系统的用户*
    * Vsftpd虚拟宿主用户:
    虚拟用户并不是系统用户,也就是说这些FTP的用户在系统中是不存在的
    他们的总体权限其实是集中寄托在一个在系统中的某一个用户身上的,所谓Vsftpd的虚拟宿主用户,就是这样一个支持着所有虚拟用户的宿主用户.
    由于他支撑了FTP的所有虚拟的用户,那么他本身的权限将会影响着这些虚拟的用户,因此,处于安全性的考虑,也要非常注意对该用户的权限的控制,该用户也绝对没有登陆系统的必要,这里也设定他为不能登陆系统的用户.
  4. 修改vsftpd配置文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    [root@localhost ~]# cp /etc/vsftpd/vsftpd.conf /etc/vsftpd/vsftpd.conf.bak
    [root@localhost ~]# vim /etc/vsftpd/vsftpd.conf
    #不允许匿名访问
    anonymous_enable=NO
    # 设定本地用户可以访问
    # 注意: 主要是为虚拟宿主用户,如果该项目设定为NO那么所有虚拟用户将无法访问
    local_enable=YES
    # 设定可以进行写操作
    write_enable=YES
    # 设定上传后文件的权限掩码
    local_umask=022
    # 禁止匿名用户上传
    anon_upload_enable=NO
    # 禁止匿名用户建立目录
    anon_mkdir_write_enable=NO
    # 设定开启目录标语功能
    dirmessage_enable=YES
    # 设定开启日志记录功能
    xferlog_enable=YES
    # 设定端口20进行数据连接
    connect_from_port_20=YES
    # 设定禁止上传文件更改宿主
    # 如果设定为YES,所有匿名上传的文件的所属用户将会被更改成chown_username
    chown_uploads=NO
    # 匿名上传文件所属用户名
    #chown_username=whoever
    # 设定Vsftpd的服务日志保存路径
    # 注意:该文件默认不存在,必须要手动touch出来,并且由于这里更改了Vsftpd的服务宿主用户为手动建立的Vsftpd.必须注意给与该用户对日志的写入权限,否则服务将启动失败
    xferlog_file=/var/log/vsftpd.log
    # 设定日志使用标准的记录格式
    xferlog_std_format=YES
    # 设定空闲连接超时时间,这里使用默认
    # 将具体数值留给每个具体用户具体指定,当然如果不指定的话,还是使用这里的默认值600,单位秒
    idle_session_timeout=600
    # 设定单次最大连续传输时间,这里使用默认
    # 将具体数值留给每个具体用户具体指定,当然如果不指定的话,还是使用这里的默认值120,单位秒
    data_connection_timeout=120
    # 定支撑Vsftpd服务的宿主用户为手动建立的Vsftpd用户
    # 注意:一旦做出更改宿主用户后,必须注意一起与该服务相关的读写文件的读写赋权问题:比如日志文件就必须给与该用户写入权限等
    nopriv_user=vsftpd
    # 设定支持异步传输功能
    async_abor_enable=YES
    # 设定支持ASCII模式的上传和下载功能
    ascii_upload_enable=YES
    ascii_download_enable=YES
    # 设定Vsftpd的登陆标语
    ftpd_banner=Welcome to zhonghui FTP service
    # 创建一个文件保存某些匿名电子邮件的黑名单,以防止这些人使用Dos攻击
    #deny_email_enable=YES
    # 当启用deny_email_enable功能时,所需的电子邮件黑名单保存路径
    #banned_email_file=/etc/vsftpd/banned_emails
    # 禁止用户登出自己的FTP主目录
    chroot_local_user=NO
    # 如果启动这项功能,则所有列在chroot_list_file之中的使用者不能更改根目录
    #chroot_list_enable=YES
    # 指定限制的用户文件
    #chroot_list_file=/etc/vsftpd/chroot_list
    # 禁止用户登陆FTP后使用"ls -R"的命令.该命令会对服务器性能造成巨大开销
    # 如果该项被允许,那么当多用户同时使用该命令时将会对该服务器造成威胁
    ls_recurse_enable=NO
    # 设定该Vsftpd服务工作在StandAlone模式下,谓StandAlone模式就是该服务拥有自己的守护进程支持,在"ps -A"命令下我们将可用看到vsftpd的守护进程名
    # 如果不想工作在StandAlone模式下,则可以选择SuperDaemon模式,在该模式下vsftpd将没有自己的守护进程,而是由超级守护进程Xinetd全权代理,与此同时,Vsftp服务的许多功能将得不到实现
    listen=YES
    listen_ipv6=YES
    # 设定PAM服务下Vsftpd的验证配置文件名.因此,PAM验证将参考/etc/pam.d/下的vsftpd文件配置
    pam_service_name=vsftpd
    # 设定userlist_file中的用户将不得使用FTP
    userlist_enable=YES
    # 设定支持TCP Wrappers
    # 如果启用,则vsftpd服务器会检查/etc/hosts.allow和/etc/hosts.deny中的设置,来决定请求连接的主机,是否允许访问该FTP服务器
    tcp_wrappers=YES
    # 设定启用虚拟用户功能
    guest_enable=YES
    # 指定虚拟用户的宿主用户
    guest_username=vsftpduser
    # 设定虚拟用户的权限符合他们的宿主用户
    virtual_use_local_privs=YES
    # 设定虚拟用户个人Vsftp的配置文件存放路径.也就是说,这个被指定的目录里,将存放每个Vsftp虚拟用户个性的配置文件,一个需要注意的地方就是这些配置文件名必须和虚拟用户名相同
    user_config_dir=/etc/vsftpd/vconf

    注意: 配置文件不能有空行,多余空格

  5. 创建vsftpd日志文件

    1
    2
    [root@localhost ~]# touch /var/log/vsftpd.log
    [root@localhost ~]# chown vsftpd.vsftpd /var/log/vsftpd.log
  6. 创建vsftpd存放虚拟用户目录

    1
    [root@localhost ~]# mkdir /etc/vsftpd/vconf
  7. 创建虚拟用户数据库文件

    1
    2
    3
    //创建虚拟用户名单文件
    //这个文件就是来记录vsftpd虚拟用户的用户名和口令的数据文件
    [root@localhost ~]# touch /etc/vsftpd/virtualuser
    1
    2
    3
    4
    5
    //创建虚拟用户账号
    //用户的用户名和口令信息,格式很简单:"一行用户名,一行口令"
    [root@localhost ~]# vim /etc/vsftpd/virtualuser
    penn
    ^zqJu,S|P
    1
    2
    3
    4
    5
    6
    //生成虚拟用户数据文件
    [root@localhost ~]# db_load -T -t hash -f /etc/vsftpd/virtualuser /etc/vsftpd/virtualuser.db

    说明:
    选项-T允许应用程序能够将文本文件转译载入进数据库.由于我们之后是将虚拟用户的信息以文件方式存储在文件里的,为了让Vsftpd这个应用程序能够通过文本来载入用户数据,必须要使用这个选项.
    如果指定了选项-T,那么一定要追跟子选项-t.子选项-t,用来指定转译载入的数据库类型(Btree、Hash、Queue和Recon数据库)
    1
    2
    3
    4
    5
    6
    7
    //查看数据库文件权限
    [root@localhost ~]# ls -l /etc/vsftpd/virtualuser.db
    -rw-r--r-- 1 root root 12288 Nov 24 10:45 /etc/vsftpd/virtualuser.db

    说明:
    需要特别注意的是,以后再要添加虚拟用户的时候,只需要按照"一行用户名,一行口令"的格式将新用户名和口令添加进虚拟用户名单文件
    但是光这样做还不够,不会生效!还要再执行一遍"db_load -T -t hash -f 虚拟用户名单文件 虚拟用户数据库文件.db"的命令使其生效才可以!
  8. 设定PAM验证文件,并指定虚拟用户数据库文件进行读取

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    [root@localhost ~]# cp /etc/pam.d/vsftpd /etc/pam.d/vsftpd.bak
    [root@localhost ~]# vim /etc/pam.d/vsftpd
    #%PAM-1.0
    auth sufficient /usr/lib64/security/pam_userdb.so db=/etc/vsftpd/virtualuser
    account sufficient /usr/lib64/security/pam_userdb.so db=/etc/vsftpd/virtualuser
    session optional pam_keyinit.so force revoke
    auth required pam_listfile.so item=user sense=deny file=/etc/vsftpd/ftpusers onerr=succeed
    auth required pam_shells.so
    auth include password-auth
    account include password-auth
    session required pam_loginuid.so
    session include password-auth

    说明:
    auth sufficient /usr/lib64/security/pam_userdb.so db=/etc/vsftpd/virtualuser.db
    account sufficient /usr/lib64/security/pam_userdb.so db=/etc/vsftpd/virtualuser.db

    auth是指对用户的用户名口令进行验证
    account是指对用户的帐户有哪些权限哪些限制进行验证
    sufficient表示充分条件,也就是说,一旦在这里通过了验证,那么也就不用经过下面剩下的验证步骤了.相反,如果没有通过的话,也不会被系统立即挡之门外,因为sufficient的失败不决定整个验证的失败,意味着用户还必须将经历剩下来的验证审核
    /usr/lib64/security/pam_userdb.so表示该条审核将调用pam_userdb.so这个库函数进行
    db=/etc/vsftpd/virtualuser.db指定了验证库函数将到这个指定的数据库中调用数据进行验证
  9. 虚拟用户配置

    1
    2
    3
    //创建vsftpd主数据目录
    [root@localhost ~]# mkdir -p /home/vsftpduser/ftpdata
    [root@localhost ~]# chown -R vsftpduser.vsftpduser /home/vsftpduser/ftpdata
    1
    2
    3
    //创建vsftpd项目目录
    [root@localhost ~]# mkdir -p /home/vsftpduser/ftpdata/ssp
    [root@localhost ~]# chown -R vsftpduser.vsftpduser /home/vsftpduser/ftpdata/ssp
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    //创建虚拟目录配置文件
    [root@localhost ~]# vim /etc/vsftpd/vconf/ssp.conf
    # 指定虚拟用户的具体主路径
    local_root=/home/vsftpduser/ftpdata/ssp
    # 设定不允许匿名用户访问
    anonymous_enable=NO
    # 设定允许写操作
    write_enable=YES
    # 设定上传文件权限掩码
    local_umask=022
    # 设定不允许匿名用户上传
    anon_upload_enable=NO
    # 设定不允许匿名用户建立目录
    anon_mkdir_write_enable=NO
    # 设定空闲连接超时时间
    idle_session_timeout=600
    # 设定单次连续传输最大时间
    data_connection_timeout=120
    # 设定并发客户端访问个数
    max_clients=20
    # 设定单个客户端的最大线程数,这个配置主要来照顾Flashget,迅雷等多线程下载软件
    max_per_ip=5
    # 设定该用户的最大传输速率,单位b/s。
    local_max_rate=5000000
  10. 启动服务

    1
    2
    3
    4
    5
    6
    [root@localhost ~]# systemctl start vsftpd.service
    [root@localhost ~]# systemctl status vsftpd.service

    [root@localhost ~]# systemctl enable vsftpd.service
    [root@localhost ~]# systemctl list-units --type=service |grep vsftpd
    vsftpd.service loaded active running Vsftpd ftp daemon
  11. 测试

    1
    2
    ftp -i -n 127.0.0.1 21
    > user {user} {pass}

设置权限:

  • 只能上传.不能下载、删除、重命名
    cmds_allowed=FEAT,REST,CWD,LIST,MDTM,MKD,NLST,PASS,PASV,PORT,PWD,QUIT,RMD,SIZE,STOR,TYPE,USER,ACCT,APPE,CDUP,HELP,MODE,NOOP,REIN,STAT,STOU,STRU,SYST
  • 只能下载.不能上传、删除、重命名
    write_enable=NO
  • 只能上传、删除、重命名.不能下载
    download_enable=NO
  • 只能下载、删除、重命名.不能上传
  • 只能下载上传,不能删除
    cmds_allowed=FEAT,REST,CWD,LIST,MDTM,MKD,NLST,PASS,PASV,PORT,PWD,QUIT,RMD,RNFR,RNTO,RETR,DELE,SIZE,TYPE,USER,ACCT,APPE,CDUP,HELP,MODE,NOOP,REIN,STAT,STOU,STRU,SYST

具体命令介绍如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
    CWD - change working directory 更改目录
LIST - list remote files 列目录
MKD - make a remote directory 新建文件
NLST - name list of remote directory
PWD - print working directory 显示当前工作目录
RETR - retrieve a remote file 下载文件
STOR - store a file on the remote host 上传文件
DELE - delete a remote file 删除文件
RMD - remove a remote directory 删除目录
RNFR - rename from 重命名
RNTO - rename to 重命名
参考:
# ABOR - abort a file transfer 取消文件传输
# CWD - change working directory 更改目录
# DELE - delete a remote file 删除文件
# LIST - list remote files 列目录
# MDTM - return the modification time of a file 返回文件的更新时间
# MKD - make a remote directory 新建文件夹
# NLST - name list of remote directory
# PASS - send password
# PASV - enter passive mode
# PORT - open a data port 打开一个传输端口
# PWD - print working directory 显示当前工作目录
# QUIT - terminate the connection 退出
# RETR - retrieve a remote file 下载文件
# RMD - remove a remote directory
# RNFR - rename from # RNTO - rename to
# SITE - site-specific commands
# SIZE - return the size of a file 返回文件大小
# STOR - store a file on the remote host 上传文件
# TYPE - set transfer type
# USER - send username
# less common commands:
# ACCT* - send account information
# APPE - append to a remote file
# CDUP - CWD to the parent of the current directory
# HELP - return help on using the server
# MODE - set transfer mode
# NOOP - do nothing
# REIN* - reinitialize the connection
# STAT - return server status
# STOU - store a file uniquely
# STRU - set file transfer structure
# SYST - return system type

java jvm optimize

1.堆大小设置

JVM中”最大堆”大小有三方面限制:

  1. 相关操作系统的数据模型限制(32位/64位)
  2. 系统的可用虚拟内存限制
  3. 系统的可用物理内存限制
    • linux:32位操作系统,一般限制在1.5-2G;64位操作系统对内存无限制
    • windows: 由于windows内存管理问题,JVM能用的内存会更少

2.典型设置:

1
java -Xmx1024m -Xms1024m -Xmn512m -Xss128k -XX:NewRatio=4 -XX:SurvivorRatio=4 -XX:MaxPermSize=64m -XX:MaxTenuringThreshold=0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
* -Xmx1024m: 设置JVM最大可用内存为1024m
* -Xms1024m: 设置JVM初始内存为1024m.此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存
* -Xmn512m: 设置年轻代大小为512m.整个"JVM内存大小 = 年轻代大小 + 年老代大小 + 持久代大小".
持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小.
此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8.我们的abtest在线系统,设置的是1/2,视场景不同而不同
* -Xss128k: 设置每个线程的堆栈大小.JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K.
更具应用的线程所需内存大小进行调整.在相同物理内存下,减小这个值能生成更多的线程.
但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右
* -XX:NewRatio=4: 设置年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代).
设置为4,则年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5
* -XX:SurvivorRatio=4: 设置年轻代中Eden区与Survivor区的大小比值.
设置为4,则两个Survivor区与一个Eden区的比值为2:4,一个Survivor区占整个年轻代的1/6
* -XX:MaxPermSize=64m: 设置持久代大小为64m
* -XX:MaxTenuringThreshold=0: 设置垃圾最大年龄.如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代.
对于年老代比较多的应用,可以提高效率.如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,
这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概论

3.回收器选择

JVM给了三种选择:串行收集器、并行收集器、并发收集器,但是串行收集器只适用于小数据量的情况,所以这里的选择主要针对”并行收集器”和”并发收集器””
默认情况下,JDK5.0以前都是使用串行收集器,如果想使用其他收集器需要在启动时加入相应参数.JDK5.0以后,JVM会根据当前系统配置进行判断

1.吞吐量优先的并行收集器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
并行收集器主要以到达一定的吞吐量为目标,适用于科学技术和后台处理等,例如:
1.java -Xmx1024m -Xms1024m -Xmn512m -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20
* -XX:+UseParallelGC: 选择垃圾收集器为并行收集器.
此配置仅对年轻代有效.即上述配置下,年轻代使用并发收集,而年老代仍旧使用串行收集
* -XX:ParallelGCThreads=20: 配置并行收集器的线程数,即:
同时多少个线程一起进行垃圾回收(此值最好配置与处理器数目相等)
2.java -Xmx1024m -Xms1024m -Xmn512m -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20 -XX:+UseParallelOldGC
* -XX:+UseParallelOldGC: 配置年老代垃圾收集方式为并行收集.
JDK6.0支持对年老代并行收集
3.java -Xmx1024m -Xms1024m -Xmn512m -Xss128k -XX:+UseParallelGC -XX:MaxGCPauseMillis=100
* -XX:MaxGCPauseMillis=100: 设置每次年轻代垃圾回收的最长时间,
如果无法满足此时间,JVM会自动调整年轻代大小,以满足此值
4.java -Xmx1024m -Xms1024m -Xmn512m -Xss128k -XX:+UseParallelGC -XX:MaxGCPauseMillis=100 -XX:+UseAdaptiveSizePolicy
* -XX:+UseAdaptiveSizePolicy: 设置此选项后,并行收集器会自动选择年轻代区大小和相应的Survivor区比例,
以达到目标系统规定的最低相应时间或者收集频率等,此值建议使用并行收集器时,一直打开

2.响应时间优先的并发收集器

1
2
3
4
5
6
7
8
9
10
并发收集器主要是保证系统的响应时间,减少垃圾收集时的停顿时间.适用于应用服务器,电信领域等,例如:
1.java -Xmx1024m -Xms1024m -Xmn512m -Xss128k -XX:ParallelGCThreads=20 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC
* -XX:+UseConcMarkSweepGC: 设置年老代为并发收集
* -XX:+UseParNewGC: 设置年轻代为并行收集,可与CMS收集同时使用.
JDK5.0以上,JVM会根据系统配置自行设置,所以无需再设置此值
2.java -Xmx1024m -Xms1024m -Xmn512m -Xss128k -XX:+UseConcMarkSweepGC -XX:CMSFullGCsBeforeCompaction=5 -XX:+UseCMSCompactAtFullCollection
* -XX:CMSFullGCsBeforeCompaction: 由于并发收集器不对内存空间进行压缩、整理,
所以运行一段时间以后会产生"碎片",使得运行效率降低.
此值设置运行多少次GC以后对内存空间进行压缩、整理
* -XX:+UseCMSCompactAtFullCollection: 打开对年老代的压缩.可能会影响性能,但是可以消除碎片

3.辅助信息

1
2
3
4
5
6
7
* -XX:+PrintGC: 输出gc信息
* -XX:+PrintGCDetails: 输出gc详细信息
* -XX:+PrintGCTimeStamps -XX:+PrintGC: PrintGCTimeStamps可与上面两个混合使用
* -XX:+PrintGCApplicationConcurrentTime: 打印每次垃圾回收前,程序未中断的执行时间.可与上面混合使用
* -XX:+PrintGCApplicationStoppedTime: 打印垃圾回收期间程序暂停的时间.可与上面混合使用
* -XX:PrintHeapAtGC: 打印GC前后的详细堆栈信息
* -Xloggc:filename: 与上面几个配合使用,把相关日志信息记录到文件以便分析

综上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
1.堆设置
* -Xms: 初始堆大小
* -Xmx: 最大堆大小
* -XX:NewSize=n: 设置年轻代大小
* -XX:NewRatio=n: 设置年轻代和年老代的比值.
如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4
* -XX:SurvivorRatio=n: 年轻代中Eden区与两个Survivor区的比值.
注意Survivor区有两个.如:3,表示Eden:Survivor=3:2,一个Survivor区占整个年轻代的1/5
* -XX:MaxPermSize=n: 设置持久代大小
2.收集器设置
* -XX:+UseSerialGC: 设置串行收集器
* -XX:+UseParallelGC: 设置并行收集器
* -XX:+UseParalledlOldGC: 设置并行年老代收集器
* -XX:+UseConcMarkSweepGC: 设置并发收集器
3.垃圾回收统计信息
* -XX:+PrintGC
* -XX:+PrintGCDetails
* -XX:+PrintGCTimeStamps
* -Xloggc:filename
4.并行收集器设置
* -XX:ParallelGCThreads=n: 设置并行收集器收集时使用的CPU数.并行收集线程数
* -XX:MaxGCPauseMillis=n:
* -XX:GCTimeRatio=n: 设置垃圾回收时间占程序运行时间的百分比.公式为1/(1+n)
5.并发收集器设置
* -XX:ParallelGCThreads=n:

调优总结:

  1. 年轻代大小选择
    1. 响应时间优先的应用
    2. 吞吐量优先的应用
      • 尽可能的设置大,可能到达Gbit的程度.
        因为对响应时间没有要求,垃圾收集可以并行进行,一般适合8CPU以上的应用
  2. 老年代大小选择
    1. 响应时间优先的应用
      • 年老代使用并发收集器,所以其大小需要小心设置,一般要考虑并发会话率和会话持续时间等一些参数
      • 如果堆设置小了,可以会造成内存碎片、高回收频率以及应用暂停而使用传统的标记清除方式
      • 如果堆大了,则需要较长的收集时间
      • 最优化的方案,一般需要参考以下数据获得:
        1. 并发垃圾收集信息
        2. 持久代并发收集次数
        3. 传统GC信息
        4. 花在年轻代和年老代回收上的时间比例
        5. 减少年轻代和年老代花费的时间,一般会提高应用的效率
    2. 吞吐量优先的应用
      • 一般吞吐量优先的应用都有一个很大的年轻代和一个较小的年老代
      • 原因是,这样可以尽可能回收掉大部分短期对象,减少中期的对象,而年老代尽存放长期存活对象

较小堆引起的碎片问题:

因为年老代的并发收集器使用标记、清除算法,所以不会对堆进行压缩
当收集器回收时,他会把相邻的空间进行合并,这样可以分配给较大的对象.
但是,当堆空间较小时,运行一段时间以后,就会出现”碎片”,如果并发收集器找不到足够的空间.
那么并发收集器将会停止,然后使用传统的标记、清除方式进行回收
如果出现”碎片,可能需要进行如下配置:
-XX:+UseCMSCompactAtFullCollection: 使用并发收集器时,开启对年老代的压缩
-XX:CMSFullGCsBeforeCompaction=0: 上面配置开启的情况下,这里设置多少次Full GC后,对年老代进行压缩

java jvm opts

1.堆大小设置

1
2
3
4
5
6
JVM中"最大堆"大小有三方面限制:
* 相关操作系统的数据模型限制(32位/64位)
* 系统的可用虚拟内存限制
* 系统的可用物理内存限制
* linux:32位操作系统,一般限制在1.5-2G;64位操作系统对内存无限制
* windows: 由于windows内存管理问题,JVM能用的内存会更少

2.典型设置:

1
java -Xmx1024m -Xms1024m -Xmn512m -Xss128k -XX:NewRatio=4 -XX:SurvivorRatio=4 -XX:MaxPermSize=64m -XX:MaxTenuringThreshold=0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
* -Xmx1024m: 设置JVM最大可用内存为1024m
* -Xms1024m: 设置JVM初始内存为1024m.此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存
* -Xmn512m: 设置年轻代大小为512m.整个"JVM内存大小 = 年轻代大小 + 年老代大小 + 持久代大小".
持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小.
此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8.我们的abtest在线系统,设置的是1/2,视场景不同而不同
* -Xss128k: 设置每个线程的堆栈大小.JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K.
更具应用的线程所需内存大小进行调整.在相同物理内存下,减小这个值能生成更多的线程.
但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右
* -XX:NewRatio=4: 设置年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代).
设置为4,则年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5
* -XX:SurvivorRatio=4: 设置年轻代中Eden区与Survivor区的大小比值.
设置为4,则两个Survivor区与一个Eden区的比值为2:4,一个Survivor区占整个年轻代的1/6
* -XX:MaxPermSize=64m: 设置持久代大小为64m
* -XX:MaxTenuringThreshold=0: 设置垃圾最大年龄.如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代.
对于年老代比较多的应用,可以提高效率.如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,
这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概论

3.回收器选择

1
2
JVM给了三种选择:串行收集器、并行收集器、并发收集器,但是串行收集器只适用于小数据量的情况,所以这里的选择主要针对"并行收集器"和"并发收集器""
默认情况下,JDK5.0以前都是使用串行收集器,如果想使用其他收集器需要在启动时加入相应参数.JDK5.0以后,JVM会根据当前系统配置进行判断

1.吞吐量优先的并行收集器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
并行收集器主要以到达一定的吞吐量为目标,适用于科学技术和后台处理等,例如:
1.java -Xmx1024m -Xms1024m -Xmn512m -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20
* -XX:+UseParallelGC: 选择垃圾收集器为并行收集器.
此配置仅对年轻代有效.即上述配置下,年轻代使用并发收集,而年老代仍旧使用串行收集
* -XX:ParallelGCThreads=20: 配置并行收集器的线程数,即:
同时多少个线程一起进行垃圾回收(此值最好配置与处理器数目相等)
2.java -Xmx1024m -Xms1024m -Xmn512m -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20 -XX:+UseParallelOldGC
* -XX:+UseParallelOldGC: 配置年老代垃圾收集方式为并行收集.
JDK6.0支持对年老代并行收集
3.java -Xmx1024m -Xms1024m -Xmn512m -Xss128k -XX:+UseParallelGC -XX:MaxGCPauseMillis=100
* -XX:MaxGCPauseMillis=100: 设置每次年轻代垃圾回收的最长时间,
如果无法满足此时间,JVM会自动调整年轻代大小,以满足此值
4.java -Xmx1024m -Xms1024m -Xmn512m -Xss128k -XX:+UseParallelGC -XX:MaxGCPauseMillis=100 -XX:+UseAdaptiveSizePolicy
* -XX:+UseAdaptiveSizePolicy: 设置此选项后,并行收集器会自动选择年轻代区大小和相应的Survivor区比例,
以达到目标系统规定的最低相应时间或者收集频率等,此值建议使用并行收集器时,一直打开

2.响应时间优先的并发收集器

1
2
3
4
5
6
7
8
9
10
并发收集器主要是保证系统的响应时间,减少垃圾收集时的停顿时间.适用于应用服务器,电信领域等,例如:
1.java -Xmx1024m -Xms1024m -Xmn512m -Xss128k -XX:ParallelGCThreads=20 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC
* -XX:+UseConcMarkSweepGC: 设置年老代为并发收集
* -XX:+UseParNewGC: 设置年轻代为并行收集,可与CMS收集同时使用.
JDK5.0以上,JVM会根据系统配置自行设置,所以无需再设置此值
2.java -Xmx1024m -Xms1024m -Xmn512m -Xss128k -XX:+UseConcMarkSweepGC -XX:CMSFullGCsBeforeCompaction=5 -XX:+UseCMSCompactAtFullCollection
* -XX:CMSFullGCsBeforeCompaction: 由于并发收集器不对内存空间进行压缩、整理,
所以运行一段时间以后会产生"碎片",使得运行效率降低.
此值设置运行多少次GC以后对内存空间进行压缩、整理
* -XX:+UseCMSCompactAtFullCollection: 打开对年老代的压缩.可能会影响性能,但是可以消除碎片

3.辅助信息

1
2
3
4
5
6
7
* -XX:+PrintGC: 输出gc信息
* -XX:+PrintGCDetails: 输出gc详细信息
* -XX:+PrintGCTimeStamps -XX:+PrintGC: PrintGCTimeStamps可与上面两个混合使用
* -XX:+PrintGCApplicationConcurrentTime: 打印每次垃圾回收前,程序未中断的执行时间.可与上面混合使用
* -XX:+PrintGCApplicationStoppedTime: 打印垃圾回收期间程序暂停的时间.可与上面混合使用
* -XX:PrintHeapAtGC: 打印GC前后的详细堆栈信息
* -Xloggc:filename: 与上面几个配合使用,把相关日志信息记录到文件以便分析

综上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
1.堆设置
* -Xms: 初始堆大小
* -Xmx: 最大堆大小
* -XX:NewSize=n: 设置年轻代大小
* -XX:NewRatio=n: 设置年轻代和年老代的比值.
如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4
* -XX:SurvivorRatio=n: 年轻代中Eden区与两个Survivor区的比值.
注意Survivor区有两个.如:3,表示Eden:Survivor=3:2,一个Survivor区占整个年轻代的1/5
* -XX:MaxPermSize=n: 设置持久代大小
2.收集器设置
* -XX:+UseSerialGC: 设置串行收集器
* -XX:+UseParallelGC: 设置并行收集器
* -XX:+UseParalledlOldGC: 设置并行年老代收集器
* -XX:+UseConcMarkSweepGC: 设置并发收集器
3.垃圾回收统计信息
* -XX:+PrintGC
* -XX:+PrintGCDetails
* -XX:+PrintGCTimeStamps
* -Xloggc:filename
4.并行收集器设置
* -XX:ParallelGCThreads=n: 设置并行收集器收集时使用的CPU数.并行收集线程数
* -XX:MaxGCPauseMillis=n:
* -XX:GCTimeRatio=n: 设置垃圾回收时间占程序运行时间的百分比.公式为1/(1+n)
5.并发收集器设置
* -XX:ParallelGCThreads=n:

调优总结:

  1. 年轻代大小选择
    1. 响应时间优先的应用
    2. 吞吐量优先的应用
      • 尽可能的设置大,可能到达Gbit的程度.
        因为对响应时间没有要求,垃圾收集可以并行进行,一般适合8CPU以上的应用
  2. 老年代大小选择
    1. 响应时间优先的应用
      • 年老代使用并发收集器,所以其大小需要小心设置,一般要考虑并发会话率和会话持续时间等一些参数
      • 如果堆设置小了,可以会造成内存碎片、高回收频率以及应用暂停而使用传统的标记清除方式
      • 如果堆大了,则需要较长的收集时间
      • 最优化的方案,一般需要参考以下数据获得:
        1. 并发垃圾收集信息
        2. 持久代并发收集次数
        3. 传统GC信息
        4. 花在年轻代和年老代回收上的时间比例
        5. 减少年轻代和年老代花费的时间,一般会提高应用的效率
    2. 吞吐量优先的应用
      • 一般吞吐量优先的应用都有一个很大的年轻代和一个较小的年老代
      • 原因是,这样可以尽可能回收掉大部分短期对象,减少中期的对象,而年老代尽存放长期存活对象

较小堆引起的碎片问题:

因为年老代的并发收集器使用标记、清除算法,所以不会对堆进行压缩
当收集器回收时,他会把相邻的空间进行合并,这样可以分配给较大的对象.
但是,当堆空间较小时,运行一段时间以后,就会出现”碎片”,如果并发收集器找不到足够的空间.
那么并发收集器将会停止,然后使用传统的标记、清除方式进行回收
如果出现”碎片,可能需要进行如下配置:
-XX:+UseCMSCompactAtFullCollection: 使用并发收集器时,开启对年老代的压缩
-XX:CMSFullGCsBeforeCompaction=0: 上面配置开启的情况下,这里设置多少次Full GC后,对年老代进行压缩

node install

  1. node install(方法一)

    1
    2
    3
    4
    5
    6
    7
    8
    1.安装nvm
    [root@dev app]# wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.32.1/install.sh | bash

    2.安装nodejs
    [root@dev app]# NVMW_NODEJS_ORG_MIRROR=https://npm.taobao.org/mirrors/node nvm install v6.9.1

    3.安装
    [root@dev app]# npm --registry=http://r.cnpmjs.org install -g hexo-cli
  2. node install(方法二)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    [root@dev app]# xz -d node-v8.1.3-linux-x64.tar.xz
    [root@dev app]# tar xf node-v8.1.3-linux-x64.tar
    [root@dev app]# mv node-v8.1.3-linux-x64 /mnt/app/node
    [root@dev app]# chown -R root.root /mnt/app/node

    [root@dev app]# echo 'NODE_HOME=/mnt/app/node' |tee /etc/profile.d/node.sh
    [root@dev app]# echo 'NODE_PATH=${NODE_HOME}/lib/node_modules' |tee -a /etc/profile.d/node.sh
    [root@dev app]# echo 'export PATH=${PATH}:${NODE_HOME}/bin' |tee -a /etc/profile.d/node.sh
    [root@dev app]# source /etc/profile

    [root@dev app]# node -v
    v8.1.3
  3. 修改npm源

    1
    2
    3
    4
    5
    6
    [root@dev app]# echo 'registry = https://registry.npm.taobao.org' > ~/.npmrc
    或者:
    [root@dev app]# npm --registry http://registry.cnpmjs.org info express

    [root@dev app]# npm -v
    5.0.3
  4. 补充说明

    1
    2
    3
    tar cf xxx.tar xxx
    xz -z xxx.tar
    xz -d xxx.tar.xz*
  5. windows安装nodejs

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    1.下载软件包并安装
    2.打开软件包位置,并创建两个目录"npm_global"和"npm_cache"
    3.打开git-cmd.ext,设置npm参数
    npm config set prefix "D:\Program Files\nodejs\npm_global"
    npm config set cache "D:\Program Files\nodejs\npm_cache"
    4.将"D:\Program Files\nodejs\npm_global"添加到环境变量
    D:\Program Files\nodejs\node_modules
    5.测试
    npm config get proxy
    npm config get https-proxy
    如果返回值不为null,继续执行:
    npm config set proxy null
    npm config set https-proxy null
    npm config set registry http://registry.cnpmjs.org/
    直接编辑c盘下的.npmrc文件,将registry的值修改为:
    registry = http://registry.cnpmjs.org

java env

java env

1
2
3
4
5
6
7
8
[root@localhost app]# tar xzf jdk-8u111-linux-x64.tar.gz
[root@localhost app]# mv jdk1.8.0_111 /mnt/app/java
[root@localhost app]# echo 'JAVA_HOME=/mnt/app/java' | tee /etc/profile.d/java.sh
[root@localhost app]# echo 'JRE_HOME=${JAVA_HOME}/jre' | tee -a /etc/profile.d/java.sh
[root@localhost app]# echo 'CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib' | tee -a /etc/profile.d/java.sh
[root@localhost app]# echo 'export PATH=${JAVA_HOME}/bin:$PATH' | tee -a /etc/profile.d/java.sh
[root@localhost app]# source /etc/profile
[root@localhost app]# java -version

git gogs

gogs install

  1. 查看系统版本

    1
    2
    [root@localhost ~]# cat /etc/redhat-release
    CentOS Linux release 7.3.1611 (Core)
  2. 设置主机名

    1
    2
    3
    [root@localhost ~]# hostname gogs && echo gogs | tee /etc/hostname
    [root@localhost ~]# echo '192.168.13.246 gogs' |tee -a /etc/hosts
    [root@localhost ~]# $SHELL
  3. 硬盘格式化挂载

    1
    2
    3
    [root@gogs ~]# mkfs.xfs /dev/vdb
    [root@gogs ~]# echo '/dev/vdb /mnt xfs defaults 0 0' | tee -a /etc/fstab
    [root@gogs ~]# mount -a
  4. 设置打开最大文件数

    1
    2
    3
    [root@gogs ~]# echo '* - nproc  65535' | tee -a /etc/security/limits.conf
    [root@gogs ~]# echo '* - nofile 65535' | tee -a /etc/security/limits.conf
    [root@gogs ~]# ls /etc/security/limits.d/*|xargs rm -f
  5. 设置yum源

    1
    2
    3
    4
    5
    6
    [root@gogs ~]# mkdir /etc/yum.repos.d/backup && mv /etc/yum.repos.d/{*,backup}
    [root@gogs ~]# rpm --import http://yum.ops.com/epel/RPM-GPG-KEY-EPEL-7
    [root@gogs ~]# curl -o /etc/yum.repos.d/epel.repo http://yum.ops.com/epel-7.repo
    [root@gogs ~]# rpm --import http://yum.ops.com/centos/RPM-GPG-KEY-CentOS-7
    [root@gogs ~]# curl -o /etc/yum.repos.d/CentOS-Base.repo http://yum.ops.com/centos-7.repo
    [root@gogs ~]# yum clean all && yum makecache
  6. 安装基础依赖库和常用工具包

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    [root@gogs ~]# yum -y groupinstall "Development Tools"
    [root@gogs ~]# yum -y install \
    make cmake \
    bison-devel \
    bzip2-devel \
    zlib zlib-devel \
    openssl openssl-devel openssl-libs openssl-static \
    pcre pcre-devel pcre-static \
    ncurses ncurses-devel ncurses-libs \
    mariadb mariadb-devel\
    curl-devel \
    expat-devel \
    gettext-devel \
    openldap openldap-devel \
    readline readline-devel readline-static \
    libssh2 libssh2-devel \
    unixODBC unixODBC-devel \
    sqlite sqlite-devel \
    tcl tcl-devel \
    perl-Digest-SHA1 \
    python-libs python-devel python2-pip python-crypto \
    perl-libs \
    perl-ExtUtils-MakeMaker \
    GeoIP GeoIP-devel \
    gperftools gperftools-devel gperftools-libs \
    libatomic_ops-devel \
    gtest gtest-devel \
    gdk-pixbuf2 gdk-pixbuf2-deve \
    libffi libffi-devel \
    libcurl libcurl-devel \
    http-parser http-parser-devel \
    libxml2* \
    libmcrypt* \
    libtool-ltdl-devel*
    [root@gogs ~]# yum -y install bash-completion fop lftp ntp ntpdate vim wget telnet dstat tree lrzsz net-tools nmap-ncat nmap sysstat dmidecode bc
  7. 关闭selinux

    1
    2
    [root@gogs ~]# setenforce 0
    [root@gogs ~]# sed -i s/'SELINUX=enforcing'/'SELINUX=disabled'/g /etc/selinux/config
  8. 关闭防火墙

    1
    [root@gogs ~]# systemctl stop firewalld && systemctl disable firewalld
  9. 设置系统时区

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    [root@gogs ~]# [ -f /etc/localtime ] && cp -f /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
    [root@gogs ~]# [ -f /etc/sysconfig/clock ] && echo 'ZONE="Asia/Shanghai"' | tee /etc/sysconfig/clock
    [root@gogs ~]# [ -f /etc/timezone ] && echo 'Asia/Shanghai' | tee /etc/timezone
    [root@gogs ~]# [ -f /etc/sysconfig/ntpd ] && echo 'SYNC_HWCLOCK=yes' | tee -a /etc/sysconfig/ntpd

    [root@gogs ~]# ntpdate cn.pool.ntp.org

    [root@gogs ~]# cp -f /etc/{ntp.conf,ntp.conf.bak}
    [root@gogs ~]# cat > /etc/ntp.conf <<EOF
    driftfile /var/lib/ntp/drift
    restrict default nomodify notrap nopeer noquery
    restrict 127.0.0.1
    restrict ::1
    server cn.pool.ntp.org prefer
    server 0.centos.pool.ntp.org iburst
    server 1.centos.pool.ntp.org iburst
    server 2.centos.pool.ntp.org iburst
    server 3.centos.pool.ntp.org iburst
    includefile /etc/ntp/crypto/pw
    keys /etc/ntp/keys
    disable monitor
    EOF

    [root@gogs ~]# cp -f /etc/ntp/{step-tickers,step-tickers.bak}
    [root@gogs ~]# cat > /etc/ntp/step-tickers <<EOF
    cn.pool.ntp.org
    0.centos.pool.ntp.org
    1.centos.pool.ntp.org
    2.centos.pool.ntp.org
    3.centos.pool.ntp.org
    EOF

    [root@gogs ~]# systemctl start ntpd && systemctl enable ntpd

    [root@gogs ~]# iptables -I INPUT -p udp --dport 123 -j ACCEPT
  10. 安装python,并设置python源

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    [root@gogs ~]# git clone https://github.com/yyuu/pyenv.git /usr/local/pyenv

    [root@gogs ~]# echo 'export PYENV_ROOT="/usr/local/pyenv"' | tee /etc/profile.d/pyenv.sh
    [root@gogs ~]# echo 'export PATH="$PYENV_ROOT/bin:$PATH"' | tee -a /etc/profile.d/pyenv.sh
    [root@gogs ~]# echo 'eval "$(pyenv init -)"' | tee -a /etc/profile.d/pyenv.sh
    [root@gogs ~]# source /etc/profile

    [root@gogs ~]# mkdir -p ${PYENV_ROOT}/cache
    [root@gogs ~]# ls ${PYENV_ROOT}/cache/Python-2.7.13.tar.xz 将源码包放到这里
    [root@gogs ~]# pyenv install 2.7.13
    [root@gogs ~]# pyenv local 2.7.13

    [root@gogs ~]# mkdir ~/.pip
    [root@gogs ~]# cat > ~/.pip/pip.conf <<EOF
    [global]
    trusted-host=mirrors.aliyun.com
    index-url=http://mirrors.aliyun.com/pypi/simple/
    [list]
    format=columns
    EOF
  11. 设置开机启动文件权限

    1
    [root@gogs ~]# chmod +x /etc/rc.d/rc.local
  12. 创建常见目录

    1
    [root@gogs ~]# mkdir -p /mnt/{app,data,log,web,ops/{app,data,cron}}

  1. 创建用户

    1
    [root@gogs app]# useradd -s /sbin/nologin git
  2. golang install

    1
    2
    3
    4
    5
    6
    7
    [root@gogs app]# tar xzf go1.8.4.linux-amd64.tar.gz -C /mnt/app/
    [root@gogs app]# chown -R git.git /mnt/app/go

    [root@gogs app]# echo 'export GOROOT=/mnt/app/go' |tee /etc/profile.d/go.sh
    [root@gogs app]# echo 'export GOPATH=$HOME/work' |tee -a /etc/profile.d/go.sh
    [root@gogs app]# echo 'export PATH=$GOROOT/bin:$PATH' |tee -a /etc/profile.d/go.sh
    [root@gogs app]# source /etc/profile
  3. mysql install

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    [root@gogs app]# yum -y install mariadb-server mariadb
    [root@gogs app]# cat > /etc/my.cnf <<EOF
    [mysqld]
    datadir=/var/lib/mysql
    socket=/var/lib/mysql/mysql.sock
    symbolic-links=0
    default-storage-engine=INNODB
    character_set_server = utf8
    [mysqld_safe]
    log-error=/var/log/mariadb/mariadb.log
    pid-file=/var/run/mariadb/mariadb.pid
    !includedir /etc/my.cnf.d
    EOF

    [root@gogs app]# systemctl start mariadb
    [root@gogs app]# systemctl enable mariadb

    [root@gogs app]# mysql
    MariaDB [(none)]> CREATE DATABASE `gogs` DEFAULT CHARACTER SET utf8mb4;
    MariaDB [(none)]> GRANT ALL PRIVILEGES ON gogs.* TO 'gogs'@'localhost' IDENTIFIED BY 'gogs123';
    MariaDB [(none)]> FLUSH PRIVILEGES;
  4. gogs install

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    [root@gogs app]# tar xzf linux_amd64.tar.gz -C /mnt/app/

    [root@gogs app]# cd /mnt/app/gogs/
    [root@gogs gogs]# mkdir -p custom/conf log data
    [root@gogs gogs]# cat > custom/conf/app.ini <<EOF
    APP_NAME = Gogs
    RUN_USER = git
    RUN_MODE = prod

    [database]
    DB_TYPE = mysql
    HOST = 127.0.0.1:3306
    NAME = gogs
    USER = gogs
    PASSWD = gogs
    SSL_MODE = disable
    PATH = data/gogs.db

    [repository]
    ROOT = /mnt/data/gogs.repo

    [server]
    DOMAIN = {gogs.ops.com}
    HTTP_PORT = 3000
    ROOT_URL = https://{gogs.ops.com}
    DISABLE_SSH = false
    SSH_PORT = 22
    START_SSH_SERVER = false
    OFFLINE_MODE = false

    [mailer]
    ENABLED = true
    HOST = smtp.exmail.qq.com:465
    FROM = gogs@{a.com}
    USER = gogs@{a.com}
    PASSWD = {mail passwd}

    [service]
    REGISTER_EMAIL_CONFIRM = true
    ENABLE_NOTIFY_MAIL = true
    DISABLE_REGISTRATION = true
    ENABLE_CAPTCHA = false
    REQUIRE_SIGNIN_VIEW = true

    [picture]
    DISABLE_GRAVATAR = false
    ENABLE_FEDERATED_AVATAR = true

    [session]
    PROVIDER = file

    [log]
    MODE = file
    LEVEL = Info
    ROOT_PATH = /mnt/app/gogs/log

    [security]
    INSTALL_LOCK = true
    SECRET_KEY = 30EYn8NSl5dadf
    EOF

    [root@gogs app]# mkdir -p /mnt/data/gogs.repo
    [root@gogs app]# chown -R git.git /mnt/app/gogs/
    [root@gogs app]# chown -R git.git /mnt/data/gogs.repo

    [root@gogs app]# cat > /usr/lib/systemd/system/gogs.service <<EOF
    [Unit]
    Description=Gogs
    After=syslog.target
    After=network.target
    After=mariadb.service mysqld.service postgresql.service memcached.service redis.service

    [Service]
    LimitMEMLOCK=infinity
    LimitNOFILE=65535
    Type=simple
    User=git
    Group=git
    WorkingDirectory=/mnt/app/gogs
    ExecStart=/mnt/app/gogs/gogs web
    Restart=always
    Environment=USER=git HOME=/home/git

    [Install]
    WantedBy=multi-user.target
    EOF
    [root@gogs app]# systemctl daemon-reload
    [root@gogs app]# systemctl start gogs
    [root@gogs app]# systemctl enable gogs